summaryrefslogtreecommitdiffstats
path: root/tinyDAV/src/codecs/h264/tdav_codec_h264_intel.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tinyDAV/src/codecs/h264/tdav_codec_h264_intel.cxx')
-rwxr-xr-xtinyDAV/src/codecs/h264/tdav_codec_h264_intel.cxx3383
1 files changed, 1593 insertions, 1790 deletions
diff --git a/tinyDAV/src/codecs/h264/tdav_codec_h264_intel.cxx b/tinyDAV/src/codecs/h264/tdav_codec_h264_intel.cxx
index 49f9e1c..7ef6b2c 100755
--- a/tinyDAV/src/codecs/h264/tdav_codec_h264_intel.cxx
+++ b/tinyDAV/src/codecs/h264/tdav_codec_h264_intel.cxx
@@ -76,9 +76,9 @@
static mfxIMPL __IntelDefaultImpl = MFX_IMPL_AUTO_ANY
#if INTEL_DX11_D3D
-| MFX_IMPL_VIA_D3D11
+ | MFX_IMPL_VIA_D3D11
#endif
-;
+ ;
static mfxVersion __IntelDefaultVer = { 0, 1 };
// TODO: Test against FFmpeg, CUDA, OpenH264 and Microsoft implementations
@@ -87,40 +87,39 @@ static mfxVersion __IntelDefaultVer = { 0, 1 };
class IntelCodecEncoder;
class IntelCodecDecoder;
-typedef struct tdav_codec_h264_intel_s
-{
- TDAV_DECLARE_CODEC_H264_COMMON;
+typedef struct tdav_codec_h264_intel_s {
+ TDAV_DECLARE_CODEC_H264_COMMON;
- MFXVideoSession* mfxSession;
+ MFXVideoSession* mfxSession;
- // DX11_D3D
+ // DX11_D3D
#if INTEL_DX11_D3D
- mfxFrameAllocResponse D3D11SavedAllocResponses[2/*Encode=0, Decode=1*/];
- mfxFrameAllocator D3D11Allocator;
-
- CComPtr<ID3D11Device> pD3D11Device;
- CComPtr<ID3D11DeviceContext> pD3D11Ctx;
- CComPtr<IDXGIAdapter>pAdapter;
- CComPtr<IDXGIFactory1> pDXGIFactory;
- CComPtr<IDXGIAdapter> hAdapter;
+ mfxFrameAllocResponse D3D11SavedAllocResponses[2/*Encode=0, Decode=1*/];
+ mfxFrameAllocator D3D11Allocator;
+
+ CComPtr<ID3D11Device> pD3D11Device;
+ CComPtr<ID3D11DeviceContext> pD3D11Ctx;
+ CComPtr<IDXGIAdapter>pAdapter;
+ CComPtr<IDXGIFactory1> pDXGIFactory;
+ CComPtr<IDXGIAdapter> hAdapter;
#endif
- // Encoder
- struct{
- IntelCodecEncoder *pInst;
- int64_t frame_count;
- tsk_bool_t force_idr;
- int rotation;
- int neg_width;
- int neg_height;
- int neg_fps;
- int max_bitrate_bps;
- } encoder;
-
- // decoder
- struct{
- IntelCodecDecoder *pInst;
- } decoder;
+ // Encoder
+ struct {
+ IntelCodecEncoder *pInst;
+ int64_t frame_count;
+ tsk_bool_t force_idr;
+ int rotation;
+ int neg_width;
+ int neg_height;
+ int neg_fps;
+ int max_bitrate_bps;
+ } encoder;
+
+ // decoder
+ struct {
+ IntelCodecDecoder *pInst;
+ } decoder;
}
tdav_codec_h264_intel_t;
@@ -140,19 +139,19 @@ static int tdav_codec_h264_intel_close_decoder(tdav_codec_h264_intel_t* self);
#define D3D11_WILL_WRITE 0x2000
typedef struct {
- mfxMemId memId;
- mfxMemId memIdStage;
- mfxU16 rw;
+ mfxMemId memId;
+ mfxMemId memIdStage;
+ mfxU16 rw;
} CustomMemId;
const struct {
- mfxIMPL impl; // actual implementation
- mfxU32 adapterID; // device adapter number
+ mfxIMPL impl; // actual implementation
+ mfxU32 adapterID; // device adapter number
} implTypes[] = {
- { MFX_IMPL_HARDWARE, 0 },
- { MFX_IMPL_HARDWARE2, 1 },
- { MFX_IMPL_HARDWARE3, 2 },
- { MFX_IMPL_HARDWARE4, 3 }
+ { MFX_IMPL_HARDWARE, 0 },
+ { MFX_IMPL_HARDWARE2, 1 },
+ { MFX_IMPL_HARDWARE3, 2 },
+ { MFX_IMPL_HARDWARE4, 3 }
};
static mfxStatus D3D11_CreateHWDevice(mfxHDL pthis, mfxSession session, mfxHDL* deviceHandle, HWND hWnd);
@@ -174,245 +173,225 @@ static mfxStatus D3D11_SimpleFree(mfxHDL pthis, mfxFrameAllocResponse *response)
class IntelCodec
{
protected:
- IntelCodec(MFXVideoSession* pSession)
- : m_bOpened(false)
- , m_pSession(pSession)
- , n_nNumSurfaces(0)
- , m_nSurfaceWidth(0)
- , m_nSurfaceHeight(0)
- , m_nSurfaceBitsPerPixel(0)
- , m_nSurfaceSize(0)
- , m_pSurfaceBuffers(NULL)
- , m_ppSurfacePtrs(NULL)
- {
- memset(&m_sBitstream, 0, sizeof(m_sBitstream));
- memset(&m_sParamReq, 0, sizeof(m_sParamReq));
- memset(&m_sParamSel, 0, sizeof(m_sParamSel));
- memset(&m_sAllocRequest, 0, sizeof(m_sAllocRequest));
- }
+ IntelCodec(MFXVideoSession* pSession)
+ : m_bOpened(false)
+ , m_pSession(pSession)
+ , n_nNumSurfaces(0)
+ , m_nSurfaceWidth(0)
+ , m_nSurfaceHeight(0)
+ , m_nSurfaceBitsPerPixel(0)
+ , m_nSurfaceSize(0)
+ , m_pSurfaceBuffers(NULL)
+ , m_ppSurfacePtrs(NULL) {
+ memset(&m_sBitstream, 0, sizeof(m_sBitstream));
+ memset(&m_sParamReq, 0, sizeof(m_sParamReq));
+ memset(&m_sParamSel, 0, sizeof(m_sParamSel));
+ memset(&m_sAllocRequest, 0, sizeof(m_sAllocRequest));
+ }
public:
- virtual ~IntelCodec()
- {
- Close();
- }
- virtual mfxStatus Open(struct tdav_codec_h264_intel_s* pWrappedCodec) = 0;
+ virtual ~IntelCodec() {
+ Close();
+ }
+ virtual mfxStatus Open(struct tdav_codec_h264_intel_s* pWrappedCodec) = 0;
- virtual mfxStatus Close()
- {
- DeAllocSurfaces();
- DeAllocateBitstream();
+ virtual mfxStatus Close() {
+ DeAllocSurfaces();
+ DeAllocateBitstream();
- memset(&m_sAllocRequest, 0, sizeof(m_sAllocRequest));
+ memset(&m_sAllocRequest, 0, sizeof(m_sAllocRequest));
- m_bOpened = false;
+ m_bOpened = false;
- return MFX_ERR_NONE;
- }
+ return MFX_ERR_NONE;
+ }
protected:
- int GetFreeSurfaceIndex()
- {
- if (m_ppSurfacePtrs)
- {
- for (mfxU16 i = 0; i < n_nNumSurfaces; i++)
- {
- if (0 == m_ppSurfacePtrs[i]->Data.Locked)
- {
- return i;
- }
- }
- }
- return MFX_ERR_NOT_FOUND;
- }
-
- mfxStatus ReadPlaneData(mfxU16 w, mfxU16 h, mfxU8 *buf, mfxU8 *ptr, mfxU16 pitch, mfxU16 offset, const mfxU8* &src)
- {
- for (mfxU16 i = 0; i < h; i++)
- {
- memcpy(buf, src, w);
- src += w;
-
- for (mfxU16 j = 0; j < w; j++)
- ptr[i * pitch + j * 2 + offset] = buf[j];
- }
- return MFX_ERR_NONE;
- }
-
- mfxStatus LoadRawFrame(int nSurfaceIndex, const mfxU8* src)
- {
- mfxFrameSurface1* pSurface = (m_ppSurfacePtrs && nSurfaceIndex >= 0 && nSurfaceIndex < n_nNumSurfaces) ? m_ppSurfacePtrs[nSurfaceIndex] : NULL;
- if (!pSurface)
- {
- INTEL_DEBUG_ERROR("Failed to find surface at index=%d", nSurfaceIndex);
- return MFX_ERR_NOT_FOUND;
- }
-
- mfxStatus sts = MFX_ERR_NONE;
- mfxU16 w, h, i, pitch;
- mfxU8 *ptr;
- mfxFrameInfo* pInfo = &pSurface->Info;
- mfxFrameData* pData = &pSurface->Data;
-
- if (pInfo->CropH > 0 && pInfo->CropW > 0) {
- w = pInfo->CropW;
- h = pInfo->CropH;
- }
- else {
- w = pInfo->Width;
- h = pInfo->Height;
- }
-
- pitch = pData->Pitch;
- ptr = pData->Y + pInfo->CropX + pInfo->CropY * pData->Pitch;
-
- // read luminance plane
- for (i = 0; i < h; i++)
- {
- memcpy(ptr + i * pitch, src, w);
- src += w;
- }
-
- mfxU8 buf[2048]; // maximum supported chroma width for nv12
- w /= 2;
- h /= 2;
- ptr = pData->UV + pInfo->CropX + (pInfo->CropY / 2) * pitch;
- if (w > 2048)
- return MFX_ERR_UNSUPPORTED;
-
- // load U
- sts = ReadPlaneData(w, h, buf, ptr, pitch, 0, src);
- if (MFX_ERR_NONE != sts) return sts;
- // load V
- sts = ReadPlaneData(w, h, buf, ptr, pitch, 1, src);
- if (MFX_ERR_NONE != sts) return sts;
-
- return MFX_ERR_NONE;
- }
-
- virtual mfxStatus AllocSurfaces(mfxU16 nNumSurfaces, mfxU16 nSurfaceWidth, mfxU16 nSurfaceHeight, const mfxFrameInfo* pcFrameInfo)
- {
- mfxStatus status = MFX_ERR_UNKNOWN;
-
- INTEL_DEBUG_INFO("Alloc surfaces: num=%u, width=%u, height=%u", nNumSurfaces, nSurfaceWidth, nSurfaceHeight);
-
- DeAllocSurfaces();
-
- n_nNumSurfaces = nNumSurfaces;
- m_nSurfaceWidth = (mfxU16)INTEL_ALIGN32(nSurfaceWidth);
- m_nSurfaceHeight = (mfxU16)INTEL_ALIGN32(nSurfaceHeight);
- m_nSurfaceBitsPerPixel = 12; // NV12 format is a 12 bits per pixel format
- m_nSurfaceSize = m_nSurfaceWidth * m_nSurfaceHeight * m_nSurfaceBitsPerPixel / 8;
+ int GetFreeSurfaceIndex() {
+ if (m_ppSurfacePtrs) {
+ for (mfxU16 i = 0; i < n_nNumSurfaces; i++) {
+ if (0 == m_ppSurfacePtrs[i]->Data.Locked) {
+ return i;
+ }
+ }
+ }
+ return MFX_ERR_NOT_FOUND;
+ }
+
+ mfxStatus ReadPlaneData(mfxU16 w, mfxU16 h, mfxU8 *buf, mfxU8 *ptr, mfxU16 pitch, mfxU16 offset, const mfxU8* &src) {
+ for (mfxU16 i = 0; i < h; i++) {
+ memcpy(buf, src, w);
+ src += w;
+
+ for (mfxU16 j = 0; j < w; j++) {
+ ptr[i * pitch + j * 2 + offset] = buf[j];
+ }
+ }
+ return MFX_ERR_NONE;
+ }
+
+ mfxStatus LoadRawFrame(int nSurfaceIndex, const mfxU8* src) {
+ mfxFrameSurface1* pSurface = (m_ppSurfacePtrs && nSurfaceIndex >= 0 && nSurfaceIndex < n_nNumSurfaces) ? m_ppSurfacePtrs[nSurfaceIndex] : NULL;
+ if (!pSurface) {
+ INTEL_DEBUG_ERROR("Failed to find surface at index=%d", nSurfaceIndex);
+ return MFX_ERR_NOT_FOUND;
+ }
+
+ mfxStatus sts = MFX_ERR_NONE;
+ mfxU16 w, h, i, pitch;
+ mfxU8 *ptr;
+ mfxFrameInfo* pInfo = &pSurface->Info;
+ mfxFrameData* pData = &pSurface->Data;
+
+ if (pInfo->CropH > 0 && pInfo->CropW > 0) {
+ w = pInfo->CropW;
+ h = pInfo->CropH;
+ }
+ else {
+ w = pInfo->Width;
+ h = pInfo->Height;
+ }
+
+ pitch = pData->Pitch;
+ ptr = pData->Y + pInfo->CropX + pInfo->CropY * pData->Pitch;
+
+ // read luminance plane
+ for (i = 0; i < h; i++) {
+ memcpy(ptr + i * pitch, src, w);
+ src += w;
+ }
+
+ mfxU8 buf[2048]; // maximum supported chroma width for nv12
+ w /= 2;
+ h /= 2;
+ ptr = pData->UV + pInfo->CropX + (pInfo->CropY / 2) * pitch;
+ if (w > 2048) {
+ return MFX_ERR_UNSUPPORTED;
+ }
+
+ // load U
+ sts = ReadPlaneData(w, h, buf, ptr, pitch, 0, src);
+ if (MFX_ERR_NONE != sts) {
+ return sts;
+ }
+ // load V
+ sts = ReadPlaneData(w, h, buf, ptr, pitch, 1, src);
+ if (MFX_ERR_NONE != sts) {
+ return sts;
+ }
+
+ return MFX_ERR_NONE;
+ }
+
+ virtual mfxStatus AllocSurfaces(mfxU16 nNumSurfaces, mfxU16 nSurfaceWidth, mfxU16 nSurfaceHeight, const mfxFrameInfo* pcFrameInfo) {
+ mfxStatus status = MFX_ERR_UNKNOWN;
+
+ INTEL_DEBUG_INFO("Alloc surfaces: num=%u, width=%u, height=%u", nNumSurfaces, nSurfaceWidth, nSurfaceHeight);
+
+ DeAllocSurfaces();
+
+ n_nNumSurfaces = nNumSurfaces;
+ m_nSurfaceWidth = (mfxU16)INTEL_ALIGN32(nSurfaceWidth);
+ m_nSurfaceHeight = (mfxU16)INTEL_ALIGN32(nSurfaceHeight);
+ m_nSurfaceBitsPerPixel = 12; // NV12 format is a 12 bits per pixel format
+ m_nSurfaceSize = m_nSurfaceWidth * m_nSurfaceHeight * m_nSurfaceBitsPerPixel / 8;
#if !INTEL_DX11_D3D
- if (!(m_pSurfaceBuffers = (mfxU8 *)new mfxU8[m_nSurfaceSize * n_nNumSurfaces]))
- {
- INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
- }
+ if (!(m_pSurfaceBuffers = (mfxU8 *)new mfxU8[m_nSurfaceSize * n_nNumSurfaces])) {
+ INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
+ }
#endif
- if (!(m_ppSurfacePtrs = new mfxFrameSurface1*[n_nNumSurfaces]))
- {
- INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
- }
- for (mfxU16 i = 0; i < n_nNumSurfaces; i++)
- {
- if (!(m_ppSurfacePtrs[i] = new mfxFrameSurface1))
- {
- INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
- }
- memset(m_ppSurfacePtrs[i], 0, sizeof(mfxFrameSurface1));
- memcpy(&(m_ppSurfacePtrs[i]->Info), pcFrameInfo, sizeof(mfxFrameInfo));
+ if (!(m_ppSurfacePtrs = new mfxFrameSurface1*[n_nNumSurfaces])) {
+ INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
+ }
+ for (mfxU16 i = 0; i < n_nNumSurfaces; i++) {
+ if (!(m_ppSurfacePtrs[i] = new mfxFrameSurface1)) {
+ INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
+ }
+ memset(m_ppSurfacePtrs[i], 0, sizeof(mfxFrameSurface1));
+ memcpy(&(m_ppSurfacePtrs[i]->Info), pcFrameInfo, sizeof(mfxFrameInfo));
#if INTEL_DX11_D3D
- m_ppSurfacePtrs[i]->Data.MemId = m_sD3D11Response.mids[i]; // MID (memory id) represent one D3D NV12 surface
+ m_ppSurfacePtrs[i]->Data.MemId = m_sD3D11Response.mids[i]; // MID (memory id) represent one D3D NV12 surface
#else
- m_ppSurfacePtrs[i]->Data.Y = &m_pSurfaceBuffers[m_nSurfaceSize * i];
- m_ppSurfacePtrs[i]->Data.U = m_ppSurfacePtrs[i]->Data.Y + m_nSurfaceWidth * m_nSurfaceHeight;
- m_ppSurfacePtrs[i]->Data.V = m_ppSurfacePtrs[i]->Data.U + 1;
- m_ppSurfacePtrs[i]->Data.Pitch = m_nSurfaceWidth;
+ m_ppSurfacePtrs[i]->Data.Y = &m_pSurfaceBuffers[m_nSurfaceSize * i];
+ m_ppSurfacePtrs[i]->Data.U = m_ppSurfacePtrs[i]->Data.Y + m_nSurfaceWidth * m_nSurfaceHeight;
+ m_ppSurfacePtrs[i]->Data.V = m_ppSurfacePtrs[i]->Data.U + 1;
+ m_ppSurfacePtrs[i]->Data.Pitch = m_nSurfaceWidth;
#endif
- }
+ }
- return MFX_ERR_NONE;
+ return MFX_ERR_NONE;
- bail:
- DeAllocSurfaces();
- return status;
- }
+bail:
+ DeAllocSurfaces();
+ return status;
+ }
- mfxStatus AllocateBitstream(mfxU32 nMaxLength)
- {
- DeAllocateBitstream();
+ mfxStatus AllocateBitstream(mfxU32 nMaxLength) {
+ DeAllocateBitstream();
- m_sBitstream.MaxLength = nMaxLength;
- if (!(m_sBitstream.Data = new mfxU8[nMaxLength]))
- {
- INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
- }
+ m_sBitstream.MaxLength = nMaxLength;
+ if (!(m_sBitstream.Data = new mfxU8[nMaxLength])) {
+ INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
+ }
- return MFX_ERR_NONE;
+ return MFX_ERR_NONE;
- bail:
- return MFX_ERR_MEMORY_ALLOC;
- }
+bail:
+ return MFX_ERR_MEMORY_ALLOC;
+ }
private:
- mfxStatus DeAllocSurfaces()
- {
- if (m_ppSurfacePtrs)
- {
- for (mfxU16 i = 0; i < n_nNumSurfaces; i++)
- {
- if (m_ppSurfacePtrs[i])
- {
- delete m_ppSurfacePtrs[i];
- }
- }
- delete[] m_ppSurfacePtrs;
- m_ppSurfacePtrs = NULL;
- }
- n_nNumSurfaces = 0;
-
- if (m_pSurfaceBuffers)
- {
- delete[] m_pSurfaceBuffers;
- m_pSurfaceBuffers = NULL;
- }
-
- m_nSurfaceWidth = 0;
- m_nSurfaceHeight = 0;
- m_nSurfaceBitsPerPixel = 0;
- m_nSurfaceSize = 0;
-
- return MFX_ERR_NONE;
- }
-
- mfxStatus DeAllocateBitstream()
- {
- if (m_sBitstream.Data)
- {
- delete[]m_sBitstream.Data;
- }
- memset(&m_sBitstream, 0, sizeof(m_sBitstream));
-
- return MFX_ERR_NONE;
- }
+ mfxStatus DeAllocSurfaces() {
+ if (m_ppSurfacePtrs) {
+ for (mfxU16 i = 0; i < n_nNumSurfaces; i++) {
+ if (m_ppSurfacePtrs[i]) {
+ delete m_ppSurfacePtrs[i];
+ }
+ }
+ delete[] m_ppSurfacePtrs;
+ m_ppSurfacePtrs = NULL;
+ }
+ n_nNumSurfaces = 0;
+
+ if (m_pSurfaceBuffers) {
+ delete[] m_pSurfaceBuffers;
+ m_pSurfaceBuffers = NULL;
+ }
+
+ m_nSurfaceWidth = 0;
+ m_nSurfaceHeight = 0;
+ m_nSurfaceBitsPerPixel = 0;
+ m_nSurfaceSize = 0;
+
+ return MFX_ERR_NONE;
+ }
+
+ mfxStatus DeAllocateBitstream() {
+ if (m_sBitstream.Data) {
+ delete[]m_sBitstream.Data;
+ }
+ memset(&m_sBitstream, 0, sizeof(m_sBitstream));
+
+ return MFX_ERR_NONE;
+ }
protected:
- bool m_bOpened;
- MFXVideoSession* m_pSession;
- mfxU16 n_nNumSurfaces;
- mfxU16 m_nSurfaceWidth;
- mfxU16 m_nSurfaceHeight;
- mfxU8 m_nSurfaceBitsPerPixel;
- mfxU32 m_nSurfaceSize;
- mfxU8* m_pSurfaceBuffers; // mfxU8[];
- mfxFrameSurface1** m_ppSurfacePtrs; // mfxFrameSurface1[]
- mfxBitstream m_sBitstream;
- mfxVideoParam m_sParamReq; // requested params
- mfxVideoParam m_sParamSel; // selected params
- mfxFrameAllocRequest m_sAllocRequest;
+ bool m_bOpened;
+ MFXVideoSession* m_pSession;
+ mfxU16 n_nNumSurfaces;
+ mfxU16 m_nSurfaceWidth;
+ mfxU16 m_nSurfaceHeight;
+ mfxU8 m_nSurfaceBitsPerPixel;
+ mfxU32 m_nSurfaceSize;
+ mfxU8* m_pSurfaceBuffers; // mfxU8[];
+ mfxFrameSurface1** m_ppSurfacePtrs; // mfxFrameSurface1[]
+ mfxBitstream m_sBitstream;
+ mfxVideoParam m_sParamReq; // requested params
+ mfxVideoParam m_sParamSel; // selected params
+ mfxFrameAllocRequest m_sAllocRequest;
#if INTEL_DX11_D3D
- mfxFrameAllocResponse m_sD3D11Response;
+ mfxFrameAllocResponse m_sD3D11Response;
#endif
};
@@ -423,349 +402,315 @@ protected:
class IntelCodecEncoder : public IntelCodec
{
public:
- IntelCodecEncoder(MFXVideoSession* pSession)
- : IntelCodec(pSession)
- , m_Inst(*pSession)
- {
- memset(&m_sFrameCtrl, 0, sizeof(m_sFrameCtrl));
- }
- virtual ~IntelCodecEncoder()
- {
- Close();
- }
-
- virtual mfxStatus Close()
- {
- m_Inst.Close();
- memset(&m_sFrameCtrl, 0, sizeof(m_sFrameCtrl));
- return IntelCodec::Close();
- }
-
- mfxStatus Reset()
- {
- if (m_bOpened)
- {
- return m_Inst.Reset(&m_sParamSel);
- }
- return MFX_ERR_NONE;
- }
-
- mfxStatus Open(struct tdav_codec_h264_intel_s* pWrappedCodec)
- {
- int32_t max_bw_kpbs;
- tdav_codec_h264_common_t* pWrappedCodecCommon = (tdav_codec_h264_common_t*)pWrappedCodec;
- mfxStatus status = MFX_ERR_UNKNOWN;
- mfxU16 uSelWidth, uSelHeight;
-
- pWrappedCodec->encoder.neg_width = (pWrappedCodec->encoder.rotation == 90 || pWrappedCodec->encoder.rotation == 270) ? TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.height : TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.width;
- pWrappedCodec->encoder.neg_height = (pWrappedCodec->encoder.rotation == 90 || pWrappedCodec->encoder.rotation == 270) ? TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.width : TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.height;
- pWrappedCodec->encoder.neg_fps = TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.fps;
- max_bw_kpbs = TSK_CLAMP(
- 0,
- tmedia_get_video_bandwidth_kbps_2(pWrappedCodec->encoder.neg_width, pWrappedCodec->encoder.neg_height, pWrappedCodec->encoder.neg_fps),
- TMEDIA_CODEC(pWrappedCodec)->bandwidth_max_upload
- );
- pWrappedCodec->encoder.max_bitrate_bps = (max_bw_kpbs * 1024);
-
- INTEL_DEBUG_INFO("neg_width=%d, neg_height=%d, neg_fps=%d, max_bitrate_bps=%d",
- pWrappedCodec->encoder.neg_width,
- pWrappedCodec->encoder.neg_height,
- pWrappedCodec->encoder.neg_fps,
- pWrappedCodec->encoder.max_bitrate_bps
- );
-
- // Initialize encoder parameters
- memset(&m_sParamReq, 0, sizeof(m_sParamReq));
- m_sParamReq.mfx.CodecId = MFX_CODEC_AVC;
- m_sParamReq.mfx.CodecProfile = pWrappedCodecCommon->profile == profile_idc_main ? MFX_PROFILE_AVC_MAIN : MFX_PROFILE_AVC_BASELINE;
- m_sParamReq.mfx.CodecLevel = (mfxU16)pWrappedCodecCommon->level;
- // TODO: Update "CodecProfile" based on "common->profile_iop"
- m_sParamReq.mfx.TargetUsage = MFX_TARGETUSAGE_BALANCED;
- m_sParamReq.mfx.TargetKbps = max_bw_kpbs;
- m_sParamReq.mfx.RateControlMethod = MFX_RATECONTROL_CBR;
- m_sParamReq.mfx.IdrInterval = (pWrappedCodec->encoder.neg_fps * INTEL_H264_GOP_SIZE_IN_SECONDS);
- m_sParamReq.mfx.FrameInfo.FrameRateExtN = pWrappedCodec->encoder.neg_fps;
- m_sParamReq.mfx.FrameInfo.FrameRateExtD = 1;
- m_sParamReq.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
- m_sParamReq.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
- m_sParamReq.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
- m_sParamReq.mfx.FrameInfo.CropX = 0;
- m_sParamReq.mfx.FrameInfo.CropY = 0;
- m_sParamReq.mfx.FrameInfo.CropW = pWrappedCodec->encoder.neg_width;
- m_sParamReq.mfx.FrameInfo.CropH = pWrappedCodec->encoder.neg_height;
- m_sParamReq.mfx.FrameInfo.Width = INTEL_ALIGN16(pWrappedCodec->encoder.neg_width); // must be a multiple of 16
- m_sParamReq.mfx.FrameInfo.Height = INTEL_ALIGN16(pWrappedCodec->encoder.neg_height); // must be a multiple of 16
+ IntelCodecEncoder(MFXVideoSession* pSession)
+ : IntelCodec(pSession)
+ , m_Inst(*pSession) {
+ memset(&m_sFrameCtrl, 0, sizeof(m_sFrameCtrl));
+ }
+ virtual ~IntelCodecEncoder() {
+ Close();
+ }
+
+ virtual mfxStatus Close() {
+ m_Inst.Close();
+ memset(&m_sFrameCtrl, 0, sizeof(m_sFrameCtrl));
+ return IntelCodec::Close();
+ }
+
+ mfxStatus Reset() {
+ if (m_bOpened) {
+ return m_Inst.Reset(&m_sParamSel);
+ }
+ return MFX_ERR_NONE;
+ }
+
+ mfxStatus Open(struct tdav_codec_h264_intel_s* pWrappedCodec) {
+ int32_t max_bw_kpbs;
+ tdav_codec_h264_common_t* pWrappedCodecCommon = (tdav_codec_h264_common_t*)pWrappedCodec;
+ mfxStatus status = MFX_ERR_UNKNOWN;
+ mfxU16 uSelWidth, uSelHeight;
+
+ pWrappedCodec->encoder.neg_width = (pWrappedCodec->encoder.rotation == 90 || pWrappedCodec->encoder.rotation == 270) ? TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.height : TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.width;
+ pWrappedCodec->encoder.neg_height = (pWrappedCodec->encoder.rotation == 90 || pWrappedCodec->encoder.rotation == 270) ? TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.width : TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.height;
+ pWrappedCodec->encoder.neg_fps = TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.fps;
+ max_bw_kpbs = TSK_CLAMP(
+ 0,
+ tmedia_get_video_bandwidth_kbps_2(pWrappedCodec->encoder.neg_width, pWrappedCodec->encoder.neg_height, pWrappedCodec->encoder.neg_fps),
+ TMEDIA_CODEC(pWrappedCodec)->bandwidth_max_upload
+ );
+ pWrappedCodec->encoder.max_bitrate_bps = (max_bw_kpbs * 1024);
+
+ INTEL_DEBUG_INFO("neg_width=%d, neg_height=%d, neg_fps=%d, max_bitrate_bps=%d",
+ pWrappedCodec->encoder.neg_width,
+ pWrappedCodec->encoder.neg_height,
+ pWrappedCodec->encoder.neg_fps,
+ pWrappedCodec->encoder.max_bitrate_bps
+ );
+
+ // Initialize encoder parameters
+ memset(&m_sParamReq, 0, sizeof(m_sParamReq));
+ m_sParamReq.mfx.CodecId = MFX_CODEC_AVC;
+ m_sParamReq.mfx.CodecProfile = pWrappedCodecCommon->profile == profile_idc_main ? MFX_PROFILE_AVC_MAIN : MFX_PROFILE_AVC_BASELINE;
+ m_sParamReq.mfx.CodecLevel = (mfxU16)pWrappedCodecCommon->level;
+ // TODO: Update "CodecProfile" based on "common->profile_iop"
+ m_sParamReq.mfx.TargetUsage = MFX_TARGETUSAGE_BALANCED;
+ m_sParamReq.mfx.TargetKbps = max_bw_kpbs;
+ m_sParamReq.mfx.RateControlMethod = MFX_RATECONTROL_CBR;
+ m_sParamReq.mfx.IdrInterval = (pWrappedCodec->encoder.neg_fps * INTEL_H264_GOP_SIZE_IN_SECONDS);
+ m_sParamReq.mfx.FrameInfo.FrameRateExtN = pWrappedCodec->encoder.neg_fps;
+ m_sParamReq.mfx.FrameInfo.FrameRateExtD = 1;
+ m_sParamReq.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
+ m_sParamReq.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
+ m_sParamReq.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
+ m_sParamReq.mfx.FrameInfo.CropX = 0;
+ m_sParamReq.mfx.FrameInfo.CropY = 0;
+ m_sParamReq.mfx.FrameInfo.CropW = pWrappedCodec->encoder.neg_width;
+ m_sParamReq.mfx.FrameInfo.CropH = pWrappedCodec->encoder.neg_height;
+ m_sParamReq.mfx.FrameInfo.Width = INTEL_ALIGN16(pWrappedCodec->encoder.neg_width); // must be a multiple of 16
+ m_sParamReq.mfx.FrameInfo.Height = INTEL_ALIGN16(pWrappedCodec->encoder.neg_height); // must be a multiple of 16
#if INTEL_DX11_D3D
- m_sParamReq.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
+ m_sParamReq.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
#else
- m_sParamReq.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
+ m_sParamReq.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
#endif
- memset(&m_sOpt2MaxFrameSize, 0, sizeof(m_sOpt2MaxFrameSize));
- m_sOpt2MaxFrameSize.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
- m_sOpt2MaxFrameSize.Header.BufferSz = sizeof(m_sOpt2MaxFrameSize);
- m_sOpt2MaxFrameSize.MaxSliceSize = (H264_RTP_PAYLOAD_SIZE - 100);
- m_sOpt2MaxFrameSize.RepeatPPS = MFX_CODINGOPTION_OFF;
- m_pExtendedBuffers[0] = (mfxExtBuffer*)&m_sOpt2MaxFrameSize;
+ memset(&m_sOpt2MaxFrameSize, 0, sizeof(m_sOpt2MaxFrameSize));
+ m_sOpt2MaxFrameSize.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
+ m_sOpt2MaxFrameSize.Header.BufferSz = sizeof(m_sOpt2MaxFrameSize);
+ m_sOpt2MaxFrameSize.MaxSliceSize = (H264_RTP_PAYLOAD_SIZE - 100);
+ m_sOpt2MaxFrameSize.RepeatPPS = MFX_CODINGOPTION_OFF;
+ m_pExtendedBuffers[0] = (mfxExtBuffer*)&m_sOpt2MaxFrameSize;
#if INTEL_ENABLE_REALTIME
- m_sParamReq.AsyncDepth = 1; // limits internal frame buffering
- m_sParamReq.mfx.GopRefDist = 1; // No B-Frames
- m_sParamReq.mfx.NumRefFrame = 1;
- memset(&m_sOptLowLatency, 0, sizeof(m_sOptLowLatency));
- m_sOptLowLatency.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
- m_sOptLowLatency.Header.BufferSz = sizeof(m_sOptLowLatency);
- m_sOptLowLatency.MaxDecFrameBuffering = 1;
- m_pExtendedBuffers[1] = (mfxExtBuffer*)&m_sOptLowLatency;
- m_sParamReq.NumExtParam = 2;
+ m_sParamReq.AsyncDepth = 1; // limits internal frame buffering
+ m_sParamReq.mfx.GopRefDist = 1; // No B-Frames
+ m_sParamReq.mfx.NumRefFrame = 1;
+ memset(&m_sOptLowLatency, 0, sizeof(m_sOptLowLatency));
+ m_sOptLowLatency.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
+ m_sOptLowLatency.Header.BufferSz = sizeof(m_sOptLowLatency);
+ m_sOptLowLatency.MaxDecFrameBuffering = 1;
+ m_pExtendedBuffers[1] = (mfxExtBuffer*)&m_sOptLowLatency;
+ m_sParamReq.NumExtParam = 2;
#else
- m_sParamReq.NumExtParam = 1;
+ m_sParamReq.NumExtParam = 1;
#endif
- m_sParamReq.ExtParam = m_pExtendedBuffers;
-
- // Check parameters
- status = m_Inst.Query(&m_sParamReq, &m_sParamReq);
- if (status != MFX_ERR_NONE && status != MFX_WRN_INCOMPATIBLE_VIDEO_PARAM /* Best one will be selected by the encoder */) {
- INTEL_CHECK_STATUS(status);
- }
- if (m_sOpt2MaxFrameSize.MaxSliceSize == 0)
- {
- INTEL_DEBUG_INFO("The encoder doesn't support setting 'MaxSliceSize' :(");
- }
-
- // Query number required surfaces for encoder
- memset(&m_sAllocRequest, 0, sizeof(m_sAllocRequest));
- INTEL_CHECK_STATUS(status = m_Inst.QueryIOSurf(&m_sParamReq, &m_sAllocRequest));
- INTEL_DEBUG_INFO("nEncSurfNum = %hu", m_sAllocRequest.NumFrameSuggested);
+ m_sParamReq.ExtParam = m_pExtendedBuffers;
+
+ // Check parameters
+ status = m_Inst.Query(&m_sParamReq, &m_sParamReq);
+ if (status != MFX_ERR_NONE && status != MFX_WRN_INCOMPATIBLE_VIDEO_PARAM /* Best one will be selected by the encoder */) {
+ INTEL_CHECK_STATUS(status);
+ }
+ if (m_sOpt2MaxFrameSize.MaxSliceSize == 0) {
+ INTEL_DEBUG_INFO("The encoder doesn't support setting 'MaxSliceSize' :(");
+ }
+
+ // Query number required surfaces for encoder
+ memset(&m_sAllocRequest, 0, sizeof(m_sAllocRequest));
+ INTEL_CHECK_STATUS(status = m_Inst.QueryIOSurf(&m_sParamReq, &m_sAllocRequest));
+ INTEL_DEBUG_INFO("nEncSurfNum = %hu", m_sAllocRequest.NumFrameSuggested);
#if INTEL_DX11_D3D
- m_sAllocRequest.Type |= D3D11_WILL_WRITE; // Hint to DX11 memory handler that application will write data to input surfaces
+ m_sAllocRequest.Type |= D3D11_WILL_WRITE; // Hint to DX11 memory handler that application will write data to input surfaces
#endif
- // Allocate surfaces for encoder
+ // Allocate surfaces for encoder
#if INTEL_DX11_D3D
- INTEL_CHECK_STATUS(status = pWrappedCodec->D3D11Allocator.Alloc(pWrappedCodec->D3D11Allocator.pthis, &m_sAllocRequest, &m_sD3D11Response));
- if (m_sD3D11Response.NumFrameActual == 0)
- {
- INTEL_CHECK_STATUS(status = MFX_ERR_UNKNOWN);
- }
- INTEL_CHECK_STATUS(status = AllocSurfaces(m_sD3D11Response.NumFrameActual, m_sAllocRequest.Info.Width, m_sAllocRequest.Info.Height, &m_sParamReq.mfx.FrameInfo));
+ INTEL_CHECK_STATUS(status = pWrappedCodec->D3D11Allocator.Alloc(pWrappedCodec->D3D11Allocator.pthis, &m_sAllocRequest, &m_sD3D11Response));
+ if (m_sD3D11Response.NumFrameActual == 0) {
+ INTEL_CHECK_STATUS(status = MFX_ERR_UNKNOWN);
+ }
+ INTEL_CHECK_STATUS(status = AllocSurfaces(m_sD3D11Response.NumFrameActual, m_sAllocRequest.Info.Width, m_sAllocRequest.Info.Height, &m_sParamReq.mfx.FrameInfo));
#else
- INTEL_CHECK_STATUS(status = AllocSurfaces(m_sAllocRequest.NumFrameSuggested, m_sAllocRequest.Info.Width, m_sAllocRequest.Info.Height, &m_sParamReq.mfx.FrameInfo));
+ INTEL_CHECK_STATUS(status = AllocSurfaces(m_sAllocRequest.NumFrameSuggested, m_sAllocRequest.Info.Width, m_sAllocRequest.Info.Height, &m_sParamReq.mfx.FrameInfo));
#endif
- // Initialize the Media SDK encoder
- status = m_Inst.Init(&m_sParamReq);
- if (status != MFX_ERR_NONE && status != MFX_WRN_PARTIAL_ACCELERATION) {
- INTEL_CHECK_STATUS(status);
- }
- INTEL_DEBUG_INFO("Encoder->Init() returned: %d", status);
-
- // Retrieve video parameters selected by encoder.
- memset(&m_sParamSel, 0, sizeof(m_sParamSel));
- INTEL_CHECK_STATUS(status = m_Inst.GetVideoParam(&m_sParamSel));
- INTEL_DEBUG_INFO("sel_width=%u.crop=%u, sel_height=%u.crop=%u, sel_fps=%u/%u",
- m_sParamSel.mfx.FrameInfo.Width, m_sParamSel.mfx.FrameInfo.CropW,
- m_sParamSel.mfx.FrameInfo.Height, m_sParamSel.mfx.FrameInfo.CropH,
- m_sParamReq.mfx.FrameInfo.FrameRateExtN,
- m_sParamReq.mfx.FrameInfo.FrameRateExtD
- );
- if (m_sParamSel.mfx.FrameInfo.CropW > 0 && m_sParamSel.mfx.FrameInfo.CropH > 0)
- {
- uSelWidth = m_sParamSel.mfx.FrameInfo.CropW;
- uSelHeight = m_sParamSel.mfx.FrameInfo.CropH;
- }
- else
- {
- uSelWidth = m_sParamSel.mfx.FrameInfo.Width;
- uSelHeight = m_sParamSel.mfx.FrameInfo.Height;
- }
- if (pWrappedCodec->encoder.neg_width != uSelWidth || pWrappedCodec->encoder.neg_height != uSelHeight) {
- INTEL_DEBUG_INFO("Encoder neg size <> sel size: %dx%d<>%dx%d", pWrappedCodec->encoder.neg_width, pWrappedCodec->encoder.neg_height, uSelWidth, uSelHeight);
- pWrappedCodec->encoder.neg_width = uSelWidth;
- pWrappedCodec->encoder.neg_height = uSelHeight;
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.width = pWrappedCodec->encoder.neg_width;
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.height = pWrappedCodec->encoder.neg_height;
- }
-
- // Allocate BitStream
- INTEL_CHECK_STATUS(status = AllocateBitstream(m_sParamSel.mfx.BufferSizeInKB * 1000));
-
- m_bOpened = true;
- return MFX_ERR_NONE;
-
- bail:
- Close();
- return status;
- }
-
- mfxStatus UpdateBandwidth(bool bUp, mfxU16 max)
- {
- if (bUp)
- {
- m_sParamSel.mfx.TargetKbps = TSK_CLAMP(0, (mfxU16)((m_sParamSel.mfx.TargetKbps * 3) >> 1), max);
- }
- else
- {
- m_sParamSel.mfx.TargetKbps = TSK_CLAMP(0, (mfxU16)((m_sParamSel.mfx.TargetKbps << 1) / 3), max);
- }
- m_sParamReq.mfx.TargetKbps = m_sParamSel.mfx.TargetKbps;
- INTEL_DEBUG_INFO("Setting new target bandwidth to %ukbps", m_sParamSel.mfx.TargetKbps);
- return m_Inst.Reset(&m_sParamSel);
- }
-
- mfxStatus SetMaxBandwidth(mfxU16 max)
- {
- m_sParamSel.mfx.TargetKbps = TSK_CLAMP(0, m_sParamSel.mfx.TargetKbps, max);
- m_sParamReq.mfx.TargetKbps = m_sParamSel.mfx.TargetKbps;
- INTEL_DEBUG_INFO("Setting new target bandwidth to %ukbps", m_sParamSel.mfx.TargetKbps);
- return m_Inst.Reset(&m_sParamSel);
- }
-
- mfxStatus Encode(struct tmedia_codec_s* pWrappedCodec, const mfxU8* pcInDataPtr, mfxU32 nInDataSize)
- {
- tdav_codec_h264_intel_t* pWrappedCodecH264 = (tdav_codec_h264_intel_t*)pWrappedCodec;
- tdav_codec_h264_common_t* pWrappedCodecCommon = (tdav_codec_h264_common_t*)pWrappedCodec;
- mfxU32 nInDataXSize;
- tsk_bool_t bSendIDR;
- int nEncSurfIdx = 0;
- mfxSyncPoint syncp;
- mfxStatus status = MFX_ERR_UNKNOWN;
-
- if (!pWrappedCodec || !pcInDataPtr || !nInDataSize) {
- INTEL_CHECK_STATUS(MFX_ERR_NULL_PTR);
- }
-
- if (!m_bOpened) {
- INTEL_CHECK_STATUS(MFX_ERR_NOT_INITIALIZED);
- }
-
- nInDataXSize = (pWrappedCodecH264->encoder.neg_width * pWrappedCodecH264->encoder.neg_height * 3) >> 1;
- if (nInDataXSize != nInDataSize)
- {
- /* guard */
- INTEL_DEBUG_ERROR("Invalid size: %u<>%u", nInDataXSize, nInDataSize);
- goto bail;
- }
-
- bSendIDR = (pWrappedCodecH264->encoder.frame_count++ == 0 || pWrappedCodecH264->encoder.force_idr);
-
- nEncSurfIdx = GetFreeSurfaceIndex();
- if (MFX_ERR_NOT_FOUND == nEncSurfIdx)
- {
- INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
- }
-
- // Surface locking required when read/write D3D surfaces
+ // Initialize the Media SDK encoder
+ status = m_Inst.Init(&m_sParamReq);
+ if (status != MFX_ERR_NONE && status != MFX_WRN_PARTIAL_ACCELERATION) {
+ INTEL_CHECK_STATUS(status);
+ }
+ INTEL_DEBUG_INFO("Encoder->Init() returned: %d", status);
+
+ // Retrieve video parameters selected by encoder.
+ memset(&m_sParamSel, 0, sizeof(m_sParamSel));
+ INTEL_CHECK_STATUS(status = m_Inst.GetVideoParam(&m_sParamSel));
+ INTEL_DEBUG_INFO("sel_width=%u.crop=%u, sel_height=%u.crop=%u, sel_fps=%u/%u",
+ m_sParamSel.mfx.FrameInfo.Width, m_sParamSel.mfx.FrameInfo.CropW,
+ m_sParamSel.mfx.FrameInfo.Height, m_sParamSel.mfx.FrameInfo.CropH,
+ m_sParamReq.mfx.FrameInfo.FrameRateExtN,
+ m_sParamReq.mfx.FrameInfo.FrameRateExtD
+ );
+ if (m_sParamSel.mfx.FrameInfo.CropW > 0 && m_sParamSel.mfx.FrameInfo.CropH > 0) {
+ uSelWidth = m_sParamSel.mfx.FrameInfo.CropW;
+ uSelHeight = m_sParamSel.mfx.FrameInfo.CropH;
+ }
+ else {
+ uSelWidth = m_sParamSel.mfx.FrameInfo.Width;
+ uSelHeight = m_sParamSel.mfx.FrameInfo.Height;
+ }
+ if (pWrappedCodec->encoder.neg_width != uSelWidth || pWrappedCodec->encoder.neg_height != uSelHeight) {
+ INTEL_DEBUG_INFO("Encoder neg size <> sel size: %dx%d<>%dx%d", pWrappedCodec->encoder.neg_width, pWrappedCodec->encoder.neg_height, uSelWidth, uSelHeight);
+ pWrappedCodec->encoder.neg_width = uSelWidth;
+ pWrappedCodec->encoder.neg_height = uSelHeight;
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.width = pWrappedCodec->encoder.neg_width;
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->out.height = pWrappedCodec->encoder.neg_height;
+ }
+
+ // Allocate BitStream
+ INTEL_CHECK_STATUS(status = AllocateBitstream(m_sParamSel.mfx.BufferSizeInKB * 1000));
+
+ m_bOpened = true;
+ return MFX_ERR_NONE;
+
+bail:
+ Close();
+ return status;
+ }
+
+ mfxStatus UpdateBandwidth(bool bUp, mfxU16 max) {
+ if (bUp) {
+ m_sParamSel.mfx.TargetKbps = TSK_CLAMP(0, (mfxU16)((m_sParamSel.mfx.TargetKbps * 3) >> 1), max);
+ }
+ else {
+ m_sParamSel.mfx.TargetKbps = TSK_CLAMP(0, (mfxU16)((m_sParamSel.mfx.TargetKbps << 1) / 3), max);
+ }
+ m_sParamReq.mfx.TargetKbps = m_sParamSel.mfx.TargetKbps;
+ INTEL_DEBUG_INFO("Setting new target bandwidth to %ukbps", m_sParamSel.mfx.TargetKbps);
+ return m_Inst.Reset(&m_sParamSel);
+ }
+
+ mfxStatus SetMaxBandwidth(mfxU16 max) {
+ m_sParamSel.mfx.TargetKbps = TSK_CLAMP(0, m_sParamSel.mfx.TargetKbps, max);
+ m_sParamReq.mfx.TargetKbps = m_sParamSel.mfx.TargetKbps;
+ INTEL_DEBUG_INFO("Setting new target bandwidth to %ukbps", m_sParamSel.mfx.TargetKbps);
+ return m_Inst.Reset(&m_sParamSel);
+ }
+
+ mfxStatus Encode(struct tmedia_codec_s* pWrappedCodec, const mfxU8* pcInDataPtr, mfxU32 nInDataSize) {
+ tdav_codec_h264_intel_t* pWrappedCodecH264 = (tdav_codec_h264_intel_t*)pWrappedCodec;
+ tdav_codec_h264_common_t* pWrappedCodecCommon = (tdav_codec_h264_common_t*)pWrappedCodec;
+ mfxU32 nInDataXSize;
+ tsk_bool_t bSendIDR;
+ int nEncSurfIdx = 0;
+ mfxSyncPoint syncp;
+ mfxStatus status = MFX_ERR_UNKNOWN;
+
+ if (!pWrappedCodec || !pcInDataPtr || !nInDataSize) {
+ INTEL_CHECK_STATUS(MFX_ERR_NULL_PTR);
+ }
+
+ if (!m_bOpened) {
+ INTEL_CHECK_STATUS(MFX_ERR_NOT_INITIALIZED);
+ }
+
+ nInDataXSize = (pWrappedCodecH264->encoder.neg_width * pWrappedCodecH264->encoder.neg_height * 3) >> 1;
+ if (nInDataXSize != nInDataSize) {
+ /* guard */
+ INTEL_DEBUG_ERROR("Invalid size: %u<>%u", nInDataXSize, nInDataSize);
+ goto bail;
+ }
+
+ bSendIDR = (pWrappedCodecH264->encoder.frame_count++ == 0 || pWrappedCodecH264->encoder.force_idr);
+
+ nEncSurfIdx = GetFreeSurfaceIndex();
+ if (MFX_ERR_NOT_FOUND == nEncSurfIdx) {
+ INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
+ }
+
+ // Surface locking required when read/write D3D surfaces
#if INTEL_DX11_D3D
- INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Lock(pWrappedCodecH264->D3D11Allocator.pthis, m_ppSurfacePtrs[nEncSurfIdx]->Data.MemId, &(m_ppSurfacePtrs[nEncSurfIdx]->Data)));
+ INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Lock(pWrappedCodecH264->D3D11Allocator.pthis, m_ppSurfacePtrs[nEncSurfIdx]->Data.MemId, &(m_ppSurfacePtrs[nEncSurfIdx]->Data)));
#endif
- INTEL_CHECK_STATUS(status = LoadRawFrame(nEncSurfIdx, pcInDataPtr));
+ INTEL_CHECK_STATUS(status = LoadRawFrame(nEncSurfIdx, pcInDataPtr));
#if INTEL_DX11_D3D
- INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Unlock(pWrappedCodecH264->D3D11Allocator.pthis, m_ppSurfacePtrs[nEncSurfIdx]->Data.MemId, &(m_ppSurfacePtrs[nEncSurfIdx]->Data)));
+ INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Unlock(pWrappedCodecH264->D3D11Allocator.pthis, m_ppSurfacePtrs[nEncSurfIdx]->Data.MemId, &(m_ppSurfacePtrs[nEncSurfIdx]->Data)));
#endif
- m_sFrameCtrl.FrameType = bSendIDR ? (MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF | MFX_FRAMETYPE_IDR) : MFX_FRAMETYPE_UNKNOWN;
-
- //
- // Stage 1: Main encoding loop
- //
- do
- {
- for (;;)
- {
- // Encode a frame asychronously (returns immediately)
- status = m_Inst.EncodeFrameAsync(&m_sFrameCtrl, m_ppSurfacePtrs[nEncSurfIdx], &m_sBitstream, &syncp);
-
- if (MFX_ERR_NONE < status && !syncp) // Repeat the call if warning and no output
- {
- if (MFX_WRN_DEVICE_BUSY == status)
- {
- tsk_thread_sleep(1); // Wait if device is busy, then repeat the same call
- }
- }
- else if (MFX_ERR_NONE < status && syncp)
- {
- status = MFX_ERR_NONE; // Ignore warnings if output is available
- break;
- }
- else if (MFX_ERR_NOT_ENOUGH_BUFFER == status)
- {
- // Allocate more bitstream buffer memory here if needed...
- break;
- }
- else
- {
- if (status != MFX_ERR_MORE_DATA)
- {
- INTEL_CHECK_STATUS(status);
- }
- break;
- }
- }
- if (MFX_ERR_NONE == status)
- {
- INTEL_CHECK_STATUS(m_pSession->SyncOperation(syncp, 60000)); // Synchronize. Wait until encoded frame is ready
- if (m_sBitstream.DataLength > 0)
- {
- tdav_codec_h264_rtp_encap(pWrappedCodecCommon, (const uint8_t*)(m_sBitstream.Data + m_sBitstream.DataOffset), (tsk_size_t)m_sBitstream.DataLength);
- m_sBitstream.DataLength = 0;
- pWrappedCodecH264->encoder.force_idr = tsk_false; // reset
- }
- }
- } while (0);
-
- //
- // Stage 2: Retrieve the buffered encoded frames
- //
- while (MFX_ERR_NONE <= status)
- {
- for (;;)
- {
- // Encode a frame asychronously (returns immediately)
- status = m_Inst.EncodeFrameAsync(&m_sFrameCtrl, NULL, &m_sBitstream, &syncp);
-
- if (MFX_ERR_NONE < status && !syncp) // Repeat the call if warning and no output
- {
- if (MFX_WRN_DEVICE_BUSY == status)
- {
- tsk_thread_sleep(1); // Wait if device is busy, then repeat the same call
- }
- }
- else if (MFX_ERR_NONE < status && syncp)
- {
- status = MFX_ERR_NONE; // Ignore warnings if output is available
- break;
- }
- else
- {
- break;
- }
- }
-
- if (MFX_ERR_NONE == status)
- {
- INTEL_CHECK_STATUS(m_pSession->SyncOperation(syncp, 60000)); // Synchronize. Wait until encoded frame is
- if (m_sBitstream.DataLength > 0)
- {
- tdav_codec_h264_rtp_encap(pWrappedCodecCommon, (const uint8_t*)(m_sBitstream.Data + m_sBitstream.DataOffset), (tsk_size_t)m_sBitstream.DataLength);
- m_sBitstream.DataLength = 0;
- pWrappedCodecH264->encoder.force_idr = tsk_false; // reset
- }
- }
- }
-
- bail:
- return MFX_ERR_NONE;
- }
+ m_sFrameCtrl.FrameType = bSendIDR ? (MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF | MFX_FRAMETYPE_IDR) : MFX_FRAMETYPE_UNKNOWN;
+
+ //
+ // Stage 1: Main encoding loop
+ //
+ do {
+ for (;;) {
+ // Encode a frame asychronously (returns immediately)
+ status = m_Inst.EncodeFrameAsync(&m_sFrameCtrl, m_ppSurfacePtrs[nEncSurfIdx], &m_sBitstream, &syncp);
+
+ if (MFX_ERR_NONE < status && !syncp) { // Repeat the call if warning and no output
+ if (MFX_WRN_DEVICE_BUSY == status) {
+ tsk_thread_sleep(1); // Wait if device is busy, then repeat the same call
+ }
+ }
+ else if (MFX_ERR_NONE < status && syncp) {
+ status = MFX_ERR_NONE; // Ignore warnings if output is available
+ break;
+ }
+ else if (MFX_ERR_NOT_ENOUGH_BUFFER == status) {
+ // Allocate more bitstream buffer memory here if needed...
+ break;
+ }
+ else {
+ if (status != MFX_ERR_MORE_DATA) {
+ INTEL_CHECK_STATUS(status);
+ }
+ break;
+ }
+ }
+ if (MFX_ERR_NONE == status) {
+ INTEL_CHECK_STATUS(m_pSession->SyncOperation(syncp, 60000)); // Synchronize. Wait until encoded frame is ready
+ if (m_sBitstream.DataLength > 0) {
+ tdav_codec_h264_rtp_encap(pWrappedCodecCommon, (const uint8_t*)(m_sBitstream.Data + m_sBitstream.DataOffset), (tsk_size_t)m_sBitstream.DataLength);
+ m_sBitstream.DataLength = 0;
+ pWrappedCodecH264->encoder.force_idr = tsk_false; // reset
+ }
+ }
+ }
+ while (0);
+
+ //
+ // Stage 2: Retrieve the buffered encoded frames
+ //
+ while (MFX_ERR_NONE <= status) {
+ for (;;) {
+ // Encode a frame asychronously (returns immediately)
+ status = m_Inst.EncodeFrameAsync(&m_sFrameCtrl, NULL, &m_sBitstream, &syncp);
+
+ if (MFX_ERR_NONE < status && !syncp) { // Repeat the call if warning and no output
+ if (MFX_WRN_DEVICE_BUSY == status) {
+ tsk_thread_sleep(1); // Wait if device is busy, then repeat the same call
+ }
+ }
+ else if (MFX_ERR_NONE < status && syncp) {
+ status = MFX_ERR_NONE; // Ignore warnings if output is available
+ break;
+ }
+ else {
+ break;
+ }
+ }
+
+ if (MFX_ERR_NONE == status) {
+ INTEL_CHECK_STATUS(m_pSession->SyncOperation(syncp, 60000)); // Synchronize. Wait until encoded frame is
+ if (m_sBitstream.DataLength > 0) {
+ tdav_codec_h264_rtp_encap(pWrappedCodecCommon, (const uint8_t*)(m_sBitstream.Data + m_sBitstream.DataOffset), (tsk_size_t)m_sBitstream.DataLength);
+ m_sBitstream.DataLength = 0;
+ pWrappedCodecH264->encoder.force_idr = tsk_false; // reset
+ }
+ }
+ }
+
+bail:
+ return MFX_ERR_NONE;
+ }
private:
- MFXVideoENCODE m_Inst;
- mfxEncodeCtrl m_sFrameCtrl;
- mfxExtCodingOption m_sOptLowLatency;
- mfxExtCodingOption2 m_sOpt2MaxFrameSize;
- mfxExtBuffer* m_pExtendedBuffers[2]; // Not allocated
+ MFXVideoENCODE m_Inst;
+ mfxEncodeCtrl m_sFrameCtrl;
+ mfxExtCodingOption m_sOptLowLatency;
+ mfxExtCodingOption2 m_sOpt2MaxFrameSize;
+ mfxExtBuffer* m_pExtendedBuffers[2]; // Not allocated
};
@@ -775,253 +720,222 @@ private:
class IntelCodecDecoder : public IntelCodec
{
public:
- IntelCodecDecoder(MFXVideoSession* pSession)
- : IntelCodec(pSession)
- , m_Inst(*pSession)
- , m_pAccumulatorPtr(NULL)
- , m_nAccumulatorSize(0)
- , m_nAccumulatorPos(0)
- , m_bInit(false)
- {
-
- }
- virtual ~IntelCodecDecoder()
- {
- Close();
- }
-
- virtual mfxStatus Close()
- {
- m_Inst.Close();
- TSK_FREE(m_pAccumulatorPtr);
- m_nAccumulatorSize = 0;
- m_nAccumulatorPos = 0;
- m_bInit = false;
- return IntelCodec::Close();
- }
-
- mfxStatus Open(struct tdav_codec_h264_intel_s* pWrappedCodec)
- {
- tdav_codec_h264_common_t* pWrappedCodecCommon = (tdav_codec_h264_common_t*)pWrappedCodec;
-
- INTEL_DEBUG_INFO("Decoder.Open width=%d, height=%d, fps=%d",
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.width,
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.height,
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.fps
- );
-
- // Allocation will be done each time we decode the SPS:PPS header
-
- m_bOpened = true;
- return MFX_ERR_NONE;
- }
-
- mfxU32 Decode(struct tmedia_codec_s* pWrappedCodec, const mfxU8* pcInDataPtr, mfxU32 nInDataSize, void **ppOutDataPtr, tsk_size_t *pOutDataMaxSize, const trtp_rtp_header_t* pcRtpHdr)
- {
- mfxU32 nRetSize = 0, nOutXSize;
- mfxStatus status = MFX_ERR_NONE;
- tsk_bool_t append_scp, end_of_unit;
- tsk_bool_t sps_or_pps;
- const uint8_t* pay_ptr = tsk_null;
- tsk_size_t pay_size = 0, size_to_copy = 0;
- bool bGotFrame = false;
- mfxFrameSurface1* pmfxOutSurface = NULL;
- static const tsk_size_t xmax_size = (3840 * 2160 * 3) >> 3; // >>3 instead of >>1 (not an error)
- static tsk_size_t start_code_prefix_size = sizeof(H264_START_CODE_PREFIX);
-
- tdav_codec_h264_intel_t* pWrappedCodecH264 = (tdav_codec_h264_intel_t*)pWrappedCodec;
- tdav_codec_h264_common_t* pWrappedCodecCommon = (tdav_codec_h264_common_t*)pWrappedCodec;
-
- if (!pWrappedCodec || !pcInDataPtr || !nInDataSize || !ppOutDataPtr)
- {
- INTEL_CHECK_STATUS(MFX_ERR_NULL_PTR);
- }
- //INTEL_DEBUG_INFO("Size=%u", nInDataSize);
- if (!m_bOpened)
- {
- INTEL_CHECK_STATUS(MFX_ERR_NOT_INITIALIZED);
- }
-
-
- /* 5.3. NAL Unit Octet Usage
- +---------------+
- |0|1|2|3|4|5|6|7|
- +-+-+-+-+-+-+-+-+
- |F|NRI| Type |
- +---------------+
- */
- if (pcInDataPtr[0] & 0x80) // F ?== 1
- {
- /* reset accumulator */
- m_nAccumulatorPos = 0;
- INTEL_CHECK_STATUS(status = MFX_ERR_UNDEFINED_BEHAVIOR);
- }
-
- // New frame?
- if (m_nLastRtpTimestamp != pcRtpHdr->timestamp)
- {
- m_nAccumulatorPos = 0;
- m_nLastRtpTimestamp = pcRtpHdr->timestamp;
- }
-
- /* get payload */
- if ((tdav_codec_h264_get_pay(pcInDataPtr, nInDataSize, (const void**)&pay_ptr, &pay_size, &append_scp, &end_of_unit) != 0) || !pay_ptr || !pay_size)
- {
- INTEL_BREAK("Depayloader failed to get H.264 content");
- }
+ IntelCodecDecoder(MFXVideoSession* pSession)
+ : IntelCodec(pSession)
+ , m_Inst(*pSession)
+ , m_pAccumulatorPtr(NULL)
+ , m_nAccumulatorSize(0)
+ , m_nAccumulatorPos(0)
+ , m_bInit(false) {
+
+ }
+ virtual ~IntelCodecDecoder() {
+ Close();
+ }
+
+ virtual mfxStatus Close() {
+ m_Inst.Close();
+ TSK_FREE(m_pAccumulatorPtr);
+ m_nAccumulatorSize = 0;
+ m_nAccumulatorPos = 0;
+ m_bInit = false;
+ return IntelCodec::Close();
+ }
+
+ mfxStatus Open(struct tdav_codec_h264_intel_s* pWrappedCodec) {
+ tdav_codec_h264_common_t* pWrappedCodecCommon = (tdav_codec_h264_common_t*)pWrappedCodec;
+
+ INTEL_DEBUG_INFO("Decoder.Open width=%d, height=%d, fps=%d",
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.width,
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.height,
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.fps
+ );
+
+ // Allocation will be done each time we decode the SPS:PPS header
+
+ m_bOpened = true;
+ return MFX_ERR_NONE;
+ }
+
+ mfxU32 Decode(struct tmedia_codec_s* pWrappedCodec, const mfxU8* pcInDataPtr, mfxU32 nInDataSize, void **ppOutDataPtr, tsk_size_t *pOutDataMaxSize, const trtp_rtp_header_t* pcRtpHdr) {
+ mfxU32 nRetSize = 0, nOutXSize;
+ mfxStatus status = MFX_ERR_NONE;
+ tsk_bool_t append_scp, end_of_unit;
+ tsk_bool_t sps_or_pps;
+ const uint8_t* pay_ptr = tsk_null;
+ tsk_size_t pay_size = 0, size_to_copy = 0;
+ bool bGotFrame = false;
+ mfxFrameSurface1* pmfxOutSurface = NULL;
+ static const tsk_size_t xmax_size = (3840 * 2160 * 3) >> 3; // >>3 instead of >>1 (not an error)
+ static tsk_size_t start_code_prefix_size = sizeof(H264_START_CODE_PREFIX);
+
+ tdav_codec_h264_intel_t* pWrappedCodecH264 = (tdav_codec_h264_intel_t*)pWrappedCodec;
+ tdav_codec_h264_common_t* pWrappedCodecCommon = (tdav_codec_h264_common_t*)pWrappedCodec;
+
+ if (!pWrappedCodec || !pcInDataPtr || !nInDataSize || !ppOutDataPtr) {
+ INTEL_CHECK_STATUS(MFX_ERR_NULL_PTR);
+ }
+ //INTEL_DEBUG_INFO("Size=%u", nInDataSize);
+ if (!m_bOpened) {
+ INTEL_CHECK_STATUS(MFX_ERR_NOT_INITIALIZED);
+ }
+
+
+ /* 5.3. NAL Unit Octet Usage
+ +---------------+
+ |0|1|2|3|4|5|6|7|
+ +-+-+-+-+-+-+-+-+
+ |F|NRI| Type |
+ +---------------+
+ */
+ if (pcInDataPtr[0] & 0x80) { // F ?== 1
+ /* reset accumulator */
+ m_nAccumulatorPos = 0;
+ INTEL_CHECK_STATUS(status = MFX_ERR_UNDEFINED_BEHAVIOR);
+ }
+
+ // New frame?
+ if (m_nLastRtpTimestamp != pcRtpHdr->timestamp) {
+ m_nAccumulatorPos = 0;
+ m_nLastRtpTimestamp = pcRtpHdr->timestamp;
+ }
+
+ /* get payload */
+ if ((tdav_codec_h264_get_pay(pcInDataPtr, nInDataSize, (const void**)&pay_ptr, &pay_size, &append_scp, &end_of_unit) != 0) || !pay_ptr || !pay_size) {
+ INTEL_BREAK("Depayloader failed to get H.264 content");
+ }
#if 1 // TODO: MSDK cannot decode slices
- end_of_unit = pcRtpHdr->marker;
+ end_of_unit = pcRtpHdr->marker;
#endif
- //append_scp = tsk_true;
- size_to_copy = pay_size + (append_scp ? start_code_prefix_size : 0);
- // whether it's SPS or PPS (append_scp is false for subsequent FUA chuncks)
- sps_or_pps = append_scp && pay_ptr && ((pay_ptr[0] & 0x1F) == 7 || (pay_ptr[0] & 0x1F) == 8);
-
- // start-accumulator
- if (!m_pAccumulatorPtr)
- {
- if (size_to_copy > xmax_size)
- {
- INTEL_DEBUG_ERROR("%u too big to contain valid encoded data. xmax_size=%u", size_to_copy, xmax_size);
- m_nAccumulatorPos = 0;
- return 0;
- }
- if (!(m_pAccumulatorPtr = (mfxU8*)tsk_calloc(size_to_copy, sizeof(mfxU8))))
- {
- INTEL_DEBUG_ERROR("Failed to allocated new buffer");
- m_nAccumulatorPos = 0;
- return 0;
- }
- m_nAccumulatorSize = (mfxU32)size_to_copy;
- }
- if ((m_nAccumulatorPos + size_to_copy) >= xmax_size)
- {
- INTEL_DEBUG_ERROR("BufferOverflow");
- m_nAccumulatorPos = 0;
- return 0;
- }
- if ((m_nAccumulatorPos + size_to_copy) > m_nAccumulatorSize)
- {
- if (!(m_pAccumulatorPtr = (mfxU8*)tsk_realloc(m_pAccumulatorPtr, (m_nAccumulatorPos + size_to_copy))))
- {
- INTEL_DEBUG_ERROR("Failed to reallocated new buffer");
- m_nAccumulatorPos = 0;
- m_nAccumulatorSize = 0;
- return 0;
- }
- m_nAccumulatorSize = (mfxU32)(m_nAccumulatorPos + size_to_copy);
- }
-
- if (append_scp)
- {
- memcpy(&m_pAccumulatorPtr[m_nAccumulatorPos], H264_START_CODE_PREFIX, start_code_prefix_size);
- m_nAccumulatorPos += (mfxU32)start_code_prefix_size;
- }
- memcpy(&m_pAccumulatorPtr[m_nAccumulatorPos], pay_ptr, pay_size);
- m_nAccumulatorPos += (mfxU32)pay_size;
- // end-accumulator
-
- if (/*rtp_hdr->marker*/end_of_unit)
- {
- /* decode the picture */
- mfxU32 nOutWidth, nOutHeight;
-
- // Decode a Unit
- status = DecodeFrame(pWrappedCodecH264, m_pAccumulatorPtr, m_nAccumulatorPos, !!sps_or_pps, &pmfxOutSurface, bGotFrame);
- if (status != MFX_ERR_NONE)
- {
- INTEL_DEBUG_WARN("DecodeFrame failed: %d", status);
- goto bail;
- }
-
- // Do we have a complete frame?
- if (!bGotFrame || !pmfxOutSurface)
- {
- goto bail;
- }
+ //append_scp = tsk_true;
+ size_to_copy = pay_size + (append_scp ? start_code_prefix_size : 0);
+ // whether it's SPS or PPS (append_scp is false for subsequent FUA chuncks)
+ sps_or_pps = append_scp && pay_ptr && ((pay_ptr[0] & 0x1F) == 7 || (pay_ptr[0] & 0x1F) == 8);
+
+ // start-accumulator
+ if (!m_pAccumulatorPtr) {
+ if (size_to_copy > xmax_size) {
+ INTEL_DEBUG_ERROR("%u too big to contain valid encoded data. xmax_size=%u", size_to_copy, xmax_size);
+ m_nAccumulatorPos = 0;
+ return 0;
+ }
+ if (!(m_pAccumulatorPtr = (mfxU8*)tsk_calloc(size_to_copy, sizeof(mfxU8)))) {
+ INTEL_DEBUG_ERROR("Failed to allocated new buffer");
+ m_nAccumulatorPos = 0;
+ return 0;
+ }
+ m_nAccumulatorSize = (mfxU32)size_to_copy;
+ }
+ if ((m_nAccumulatorPos + size_to_copy) >= xmax_size) {
+ INTEL_DEBUG_ERROR("BufferOverflow");
+ m_nAccumulatorPos = 0;
+ return 0;
+ }
+ if ((m_nAccumulatorPos + size_to_copy) > m_nAccumulatorSize) {
+ if (!(m_pAccumulatorPtr = (mfxU8*)tsk_realloc(m_pAccumulatorPtr, (m_nAccumulatorPos + size_to_copy)))) {
+ INTEL_DEBUG_ERROR("Failed to reallocated new buffer");
+ m_nAccumulatorPos = 0;
+ m_nAccumulatorSize = 0;
+ return 0;
+ }
+ m_nAccumulatorSize = (mfxU32)(m_nAccumulatorPos + size_to_copy);
+ }
+
+ if (append_scp) {
+ memcpy(&m_pAccumulatorPtr[m_nAccumulatorPos], H264_START_CODE_PREFIX, start_code_prefix_size);
+ m_nAccumulatorPos += (mfxU32)start_code_prefix_size;
+ }
+ memcpy(&m_pAccumulatorPtr[m_nAccumulatorPos], pay_ptr, pay_size);
+ m_nAccumulatorPos += (mfxU32)pay_size;
+ // end-accumulator
+
+ if (/*rtp_hdr->marker*/end_of_unit) {
+ /* decode the picture */
+ mfxU32 nOutWidth, nOutHeight;
+
+ // Decode a Unit
+ status = DecodeFrame(pWrappedCodecH264, m_pAccumulatorPtr, m_nAccumulatorPos, !!sps_or_pps, &pmfxOutSurface, bGotFrame);
+ if (status != MFX_ERR_NONE) {
+ INTEL_DEBUG_WARN("DecodeFrame failed: %d", status);
+ goto bail;
+ }
+
+ // Do we have a complete frame?
+ if (!bGotFrame || !pmfxOutSurface) {
+ goto bail;
+ }
#if INTEL_DX11_D3D
- INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Lock(pWrappedCodecH264->D3D11Allocator.pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)));
+ INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Lock(pWrappedCodecH264->D3D11Allocator.pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)));
#endif
- if (!pmfxOutSurface->Data.Y || !pmfxOutSurface->Data.U || !pmfxOutSurface->Data.V)
- {
+ if (!pmfxOutSurface->Data.Y || !pmfxOutSurface->Data.U || !pmfxOutSurface->Data.V) {
#if INTEL_DX11_D3D
- INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Unlock(pWrappedCodecH264->D3D11Allocator.pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)));
+ INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Unlock(pWrappedCodecH264->D3D11Allocator.pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)));
#endif
- goto bail;
- }
-
- if (pmfxOutSurface->Info.CropW > 0 && pmfxOutSurface->Info.CropH > 0)
- {
- nOutWidth = pmfxOutSurface->Info.CropW;
- nOutHeight = pmfxOutSurface->Info.CropH;
- }
- else
- {
- nOutWidth = pmfxOutSurface->Info.Width;
- nOutHeight = pmfxOutSurface->Info.Height;
- }
-
- nOutXSize = (nOutWidth * nOutHeight * 3) >> 1; // I420
- /* IDR ? */
- if (((pay_ptr[0] & 0x1F) == 0x05) && TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.callback)
- {
- INTEL_DEBUG_INFO("Decoded H.264 IDR");
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result.type = tmedia_video_decode_result_type_idr;
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result.proto_hdr = pcRtpHdr;
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.callback(&TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result);
- }
- /* fill out */
- if (*pOutDataMaxSize < nOutXSize)
- {
- if ((*ppOutDataPtr = tsk_realloc(*ppOutDataPtr, nOutXSize)))
- {
- *pOutDataMaxSize = nOutXSize;
- }
- else
- {
- *pOutDataMaxSize = 0;
- return 0;
- }
- }
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.width = nOutWidth;
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.height = nOutHeight;
-
- /* layout picture */
- INTEL_CHECK_STATUS(status = IntelCodecDecoder::LayoutPicture(pmfxOutSurface, (mfxU8 *)*ppOutDataPtr));
- nRetSize = nOutXSize;
+ goto bail;
+ }
+
+ if (pmfxOutSurface->Info.CropW > 0 && pmfxOutSurface->Info.CropH > 0) {
+ nOutWidth = pmfxOutSurface->Info.CropW;
+ nOutHeight = pmfxOutSurface->Info.CropH;
+ }
+ else {
+ nOutWidth = pmfxOutSurface->Info.Width;
+ nOutHeight = pmfxOutSurface->Info.Height;
+ }
+
+ nOutXSize = (nOutWidth * nOutHeight * 3) >> 1; // I420
+ /* IDR ? */
+ if (((pay_ptr[0] & 0x1F) == 0x05) && TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.callback) {
+ INTEL_DEBUG_INFO("Decoded H.264 IDR");
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result.type = tmedia_video_decode_result_type_idr;
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result.proto_hdr = pcRtpHdr;
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.callback(&TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result);
+ }
+ /* fill out */
+ if (*pOutDataMaxSize < nOutXSize) {
+ if ((*ppOutDataPtr = tsk_realloc(*ppOutDataPtr, nOutXSize))) {
+ *pOutDataMaxSize = nOutXSize;
+ }
+ else {
+ *pOutDataMaxSize = 0;
+ return 0;
+ }
+ }
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.width = nOutWidth;
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.height = nOutHeight;
+
+ /* layout picture */
+ INTEL_CHECK_STATUS(status = IntelCodecDecoder::LayoutPicture(pmfxOutSurface, (mfxU8 *)*ppOutDataPtr));
+ nRetSize = nOutXSize;
#if INTEL_DX11_D3D
- INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Unlock(pWrappedCodecH264->D3D11Allocator.pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)));
+ INTEL_CHECK_STATUS(status = pWrappedCodecH264->D3D11Allocator.Unlock(pWrappedCodecH264->D3D11Allocator.pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)));
#endif
- } // else if(rtp_hdr->marker)
-
- bail:
- if (end_of_unit)
- {
- /* reset accumulator */
- m_nAccumulatorPos = 0;
- }
-
- if (status != MFX_ERR_NONE)
- {
- INTEL_DEBUG_INFO("Failed to decode the buffer with error code =%d, size=%u, append=%s", status, m_nAccumulatorPos, append_scp ? "yes" : "no");
- if (TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.callback)
- {
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result.type = tmedia_video_decode_result_type_error;
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result.proto_hdr = pcRtpHdr;
- TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.callback(&TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result);
- }
- }
- return nRetSize;
- }
+ } // else if(rtp_hdr->marker)
+
+bail:
+ if (end_of_unit) {
+ /* reset accumulator */
+ m_nAccumulatorPos = 0;
+ }
+
+ if (status != MFX_ERR_NONE) {
+ INTEL_DEBUG_INFO("Failed to decode the buffer with error code =%d, size=%u, append=%s", status, m_nAccumulatorPos, append_scp ? "yes" : "no");
+ if (TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.callback) {
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result.type = tmedia_video_decode_result_type_error;
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result.proto_hdr = pcRtpHdr;
+ TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.callback(&TMEDIA_CODEC_VIDEO(pWrappedCodec)->in.result);
+ }
+ }
+ return nRetSize;
+ }
private:
#if 0
- static mfxStatus WriteSection(mfxU8* plane, mfxU16 factor, mfxU16 chunksize, mfxFrameInfo *pInfo, mfxFrameData *pData, mfxU32 i, mfxU32 j, mfxU8 *pDstPtr)
- {
- memcpy(pDstPtr, plane + (pInfo->CropY * pData->Pitch / factor + pInfo->CropX) + i * pData->Pitch + j, chunksize);
- return MFX_ERR_NONE;
- }
+ static mfxStatus WriteSection(mfxU8* plane, mfxU16 factor, mfxU16 chunksize, mfxFrameInfo *pInfo, mfxFrameData *pData, mfxU32 i, mfxU32 j, mfxU8 *pDstPtr) {
+ memcpy(pDstPtr, plane + (pInfo->CropY * pData->Pitch / factor + pInfo->CropX) + i * pData->Pitch + j, chunksize);
+ return MFX_ERR_NONE;
+ }
#else
#define WriteSection(_plane, _factor, _chunksize, _pInfo, _pData, _i, _j, _pDstPtr) \
memcpy((_pDstPtr), (_plane) + ((_pInfo)->CropY * (_pData)->Pitch / (_factor) + (_pInfo)->CropX) + (_i) * (_pData)->Pitch + (_j), (_chunksize))
@@ -1029,447 +943,391 @@ private:
*(_pDstPtr) = *((_plane) + ((_pInfo)->CropY * (_pData)->Pitch / (_factor) + (_pInfo)->CropX) + (_i) * (_pData)->Pitch + (_j));
#endif
- static mfxStatus LayoutPicture(mfxFrameSurface1 *pSurface, mfxU8 *pDstPtr)
- {
+ static mfxStatus LayoutPicture(mfxFrameSurface1 *pSurface, mfxU8 *pDstPtr) {
#if 1 // ->YUV420
- mfxFrameInfo *pInfo = &pSurface->Info;
- mfxFrameData *pData = &pSurface->Data;
- mfxU32 i, j, h, w;
-
- if (pSurface->Info.CropW > 0 && pSurface->Info.CropH > 0)
- {
- w = pSurface->Info.CropW;
- h = pSurface->Info.CropH;
- }
- else
- {
- w = pSurface->Info.Width;
- h = pSurface->Info.Height;
- }
-
- for (i = 0; i < h; i++)
- {
- WriteSection(pData->Y, 1, w, pInfo, pData, i, 0, pDstPtr);
- pDstPtr += w;
- }
-
- h >>= 1;
- for (i = 0; i < h; i++)
- {
- for (j = 0; j < w; j += 2)
- {
- WriteSection1(pData->UV, 2, pInfo, pData, i, j, pDstPtr);
- pDstPtr += 1;
- }
- }
-
- for (i = 0; i < h; i++)
- {
- for (j = 1; j < w; j += 2)
- {
- WriteSection1(pData->UV, 2, pInfo, pData, i, j, pDstPtr);
- pDstPtr += 1;
- }
- }
+ mfxFrameInfo *pInfo = &pSurface->Info;
+ mfxFrameData *pData = &pSurface->Data;
+ mfxU32 i, j, h, w;
+
+ if (pSurface->Info.CropW > 0 && pSurface->Info.CropH > 0) {
+ w = pSurface->Info.CropW;
+ h = pSurface->Info.CropH;
+ }
+ else {
+ w = pSurface->Info.Width;
+ h = pSurface->Info.Height;
+ }
+
+ for (i = 0; i < h; i++) {
+ WriteSection(pData->Y, 1, w, pInfo, pData, i, 0, pDstPtr);
+ pDstPtr += w;
+ }
+
+ h >>= 1;
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j += 2) {
+ WriteSection1(pData->UV, 2, pInfo, pData, i, j, pDstPtr);
+ pDstPtr += 1;
+ }
+ }
+
+ for (i = 0; i < h; i++) {
+ for (j = 1; j < w; j += 2) {
+ WriteSection1(pData->UV, 2, pInfo, pData, i, j, pDstPtr);
+ pDstPtr += 1;
+ }
+ }
#elif 1 // ->NV12
- mfxFrameInfo *pInfo = &pSurface->Info;
- mfxFrameData *pData = &pSurface->Data;
- mfxU32 i, j, h, w;
-
- if (pSurface->Info.CropW > 0 && pSurface->Info.CropH > 0)
- {
- w = pSurface->Info.CropW;
- h = pSurface->Info.CropH;
- }
- else
- {
- w = pSurface->Info.Width;
- h = pSurface->Info.Height;
- }
-
- for (i = 0; i < h; i++)
- {
- WriteSection(pData->Y, 1, w, pInfo, pData, i, 0, pDstPtr);
- pDstPtr += w;
- }
-
- h >>= 1;
- for (i = 0; i < h; i++)
- {
- for (j = 0; j < w; j += 2)
- {
- WriteSection1(pData->UV, 2, pInfo, pData, i, j, &pDstPtr[0]);
- WriteSection1(pData->UV, 2, pInfo, pData, i, j + 1, &pDstPtr[1]);
- pDstPtr += 2;
- }
- }
+ mfxFrameInfo *pInfo = &pSurface->Info;
+ mfxFrameData *pData = &pSurface->Data;
+ mfxU32 i, j, h, w;
+
+ if (pSurface->Info.CropW > 0 && pSurface->Info.CropH > 0) {
+ w = pSurface->Info.CropW;
+ h = pSurface->Info.CropH;
+ }
+ else {
+ w = pSurface->Info.Width;
+ h = pSurface->Info.Height;
+ }
+
+ for (i = 0; i < h; i++) {
+ WriteSection(pData->Y, 1, w, pInfo, pData, i, 0, pDstPtr);
+ pDstPtr += w;
+ }
+
+ h >>= 1;
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j += 2) {
+ WriteSection1(pData->UV, 2, pInfo, pData, i, j, &pDstPtr[0]);
+ WriteSection1(pData->UV, 2, pInfo, pData, i, j + 1, &pDstPtr[1]);
+ pDstPtr += 2;
+ }
+ }
#endif
- return MFX_ERR_NONE;
- }
-
- mfxStatus DecodeFrame(struct tdav_codec_h264_intel_s* pWrappedCodec, const mfxU8* pcInDataPtr, mfxU32 nInDataSize, bool bSpsOrPps, mfxFrameSurface1** ppmfxOutSurface, bool &bGotFrame)
- {
- mfxStatus status = MFX_ERR_NONE;
- int nSurfaceIndex;
- mfxSyncPoint syncp;
- bGotFrame = false;
- *ppmfxOutSurface = NULL;
- mfxFrameSurface1* pmfxOutSurface = NULL;
-
-#if 0
- if (!bSpsOrPps && !m_bInit)
- {
- INTEL_CHECK_STATUS(status = MFX_ERR_NOT_INITIALIZED);
- }
+ return MFX_ERR_NONE;
+ }
+
+ mfxStatus DecodeFrame(struct tdav_codec_h264_intel_s* pWrappedCodec, const mfxU8* pcInDataPtr, mfxU32 nInDataSize, bool bSpsOrPps, mfxFrameSurface1** ppmfxOutSurface, bool &bGotFrame) {
+ mfxStatus status = MFX_ERR_NONE;
+ int nSurfaceIndex;
+ mfxSyncPoint syncp;
+ bGotFrame = false;
+ *ppmfxOutSurface = NULL;
+ mfxFrameSurface1* pmfxOutSurface = NULL;
+
+#if 0
+ if (!bSpsOrPps && !m_bInit) {
+ INTEL_CHECK_STATUS(status = MFX_ERR_NOT_INITIALIZED);
+ }
#endif
- if (m_sBitstream.DataLength < nInDataSize)
- {
- INTEL_CHECK_STATUS(status = AllocateBitstream(nInDataSize));
- }
- memcpy(m_sBitstream.Data, pcInDataPtr, nInDataSize);
- m_sBitstream.DataOffset = 0;
- m_sBitstream.DataLength = nInDataSize;
- m_sBitstream.DataFlag = MFX_BITSTREAM_COMPLETE_FRAME;
-
- if (bSpsOrPps || !m_bInit)
- {
- memset(&m_sParamReq, 0, sizeof(m_sParamReq));
- m_sParamReq.mfx.CodecId = MFX_CODEC_AVC;
- m_sParamReq.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
- m_sParamReq.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
+ if (m_sBitstream.DataLength < nInDataSize) {
+ INTEL_CHECK_STATUS(status = AllocateBitstream(nInDataSize));
+ }
+ memcpy(m_sBitstream.Data, pcInDataPtr, nInDataSize);
+ m_sBitstream.DataOffset = 0;
+ m_sBitstream.DataLength = nInDataSize;
+ m_sBitstream.DataFlag = MFX_BITSTREAM_COMPLETE_FRAME;
+
+ if (bSpsOrPps || !m_bInit) {
+ memset(&m_sParamReq, 0, sizeof(m_sParamReq));
+ m_sParamReq.mfx.CodecId = MFX_CODEC_AVC;
+ m_sParamReq.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
+ m_sParamReq.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
#if INTEL_DX11_D3D
- m_sParamReq.IOPattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
+ m_sParamReq.IOPattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
#else
- m_sParamReq.IOPattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
+ m_sParamReq.IOPattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
#endif
- m_sParamReq.AsyncDepth = 1; // Low latency: limits internal frame buffering
-
- status = m_Inst.DecodeHeader(&m_sBitstream, &m_sParamReq);
- if (status == MFX_WRN_PARTIAL_ACCELERATION)
- {
- status = MFX_ERR_NONE;
- }
- INTEL_CHECK_STATUS(status);
-
- memcpy(&m_sParamSel, &m_sParamReq, sizeof(m_sParamSel));
-
- // Check parameters
- status = m_Inst.Query(&m_sParamReq, &m_sParamReq);
- if (status != MFX_ERR_NONE && status != MFX_WRN_INCOMPATIBLE_VIDEO_PARAM /* Best one will be selected by the encoder */)
- {
- INTEL_CHECK_STATUS(status);
- }
-
- // Query number required surfaces for encoder
- memset(&m_sAllocRequest, 0, sizeof(m_sAllocRequest));
- INTEL_CHECK_STATUS(status = m_Inst.QueryIOSurf(&m_sParamReq, &m_sAllocRequest));
+ m_sParamReq.AsyncDepth = 1; // Low latency: limits internal frame buffering
+
+ status = m_Inst.DecodeHeader(&m_sBitstream, &m_sParamReq);
+ if (status == MFX_WRN_PARTIAL_ACCELERATION) {
+ status = MFX_ERR_NONE;
+ }
+ INTEL_CHECK_STATUS(status);
+
+ memcpy(&m_sParamSel, &m_sParamReq, sizeof(m_sParamSel));
+
+ // Check parameters
+ status = m_Inst.Query(&m_sParamReq, &m_sParamReq);
+ if (status != MFX_ERR_NONE && status != MFX_WRN_INCOMPATIBLE_VIDEO_PARAM /* Best one will be selected by the encoder */) {
+ INTEL_CHECK_STATUS(status);
+ }
+
+ // Query number required surfaces for encoder
+ memset(&m_sAllocRequest, 0, sizeof(m_sAllocRequest));
+ INTEL_CHECK_STATUS(status = m_Inst.QueryIOSurf(&m_sParamReq, &m_sAllocRequest));
#if INTEL_DX11_D3D
- m_sAllocRequest.Type |= D3D11_WILL_READ; // Hint to DX11 memory handler that application will read data from output surfaces
+ m_sAllocRequest.Type |= D3D11_WILL_READ; // Hint to DX11 memory handler that application will read data from output surfaces
#endif
- // Allocate surfaces for decoder
+ // Allocate surfaces for decoder
#if INTEL_DX11_D3D
- INTEL_CHECK_STATUS(status = pWrappedCodec->D3D11Allocator.Alloc(pWrappedCodec->D3D11Allocator.pthis, &m_sAllocRequest, &m_sD3D11Response));
- if (m_sD3D11Response.NumFrameActual == 0)
- {
- INTEL_CHECK_STATUS(status = MFX_ERR_UNKNOWN);
- }
- INTEL_DEBUG_INFO("nEncSurfNum = %hu", m_sD3D11Response.NumFrameActual);
- INTEL_CHECK_STATUS(status = AllocSurfaces(m_sD3D11Response.NumFrameActual, m_sAllocRequest.Info.Width, m_sAllocRequest.Info.Height, &m_sParamReq.mfx.FrameInfo));
+ INTEL_CHECK_STATUS(status = pWrappedCodec->D3D11Allocator.Alloc(pWrappedCodec->D3D11Allocator.pthis, &m_sAllocRequest, &m_sD3D11Response));
+ if (m_sD3D11Response.NumFrameActual == 0) {
+ INTEL_CHECK_STATUS(status = MFX_ERR_UNKNOWN);
+ }
+ INTEL_DEBUG_INFO("nEncSurfNum = %hu", m_sD3D11Response.NumFrameActual);
+ INTEL_CHECK_STATUS(status = AllocSurfaces(m_sD3D11Response.NumFrameActual, m_sAllocRequest.Info.Width, m_sAllocRequest.Info.Height, &m_sParamReq.mfx.FrameInfo));
#else
- INTEL_DEBUG_INFO("nEncSurfNum = %hu", m_sAllocRequest.NumFrameSuggested);
- INTEL_CHECK_STATUS(status = AllocSurfaces(m_sAllocRequest.NumFrameSuggested, m_sAllocRequest.Info.Width, m_sAllocRequest.Info.Height, &m_sParamReq.mfx.FrameInfo));
-#endif
- // Initialize the Media SDK decoder
- status = m_Inst.Init(&m_sParamReq);
- if (status != MFX_ERR_NONE && status != MFX_WRN_PARTIAL_ACCELERATION)
- {
- INTEL_CHECK_STATUS(status);
- }
- INTEL_DEBUG_INFO("Decoder->Init() returned: %d", status);
-
- m_bInit = true;
- }
-
- //
- // Stage 1: Main decoding loop
- //
- while (MFX_ERR_NONE <= status || MFX_ERR_MORE_DATA == status || MFX_ERR_MORE_SURFACE == status)
- {
- if (MFX_WRN_DEVICE_BUSY == status)
- {
- tsk_thread_sleep(1); // Wait if device is busy, then repeat the same call to DecodeFrameAsync
- }
-
- if (MFX_ERR_MORE_DATA == status)
- {
- return MFX_ERR_NONE;
- }
-
- if (MFX_ERR_MORE_SURFACE == status || MFX_ERR_NONE == status)
- {
- nSurfaceIndex = GetFreeSurfaceIndex(); // Find free frame surface
- if (MFX_ERR_NOT_FOUND == nSurfaceIndex)
- {
- INTEL_CHECK_STATUS((status = MFX_ERR_MEMORY_ALLOC));
- }
- }
-
- // Decode a frame asychronously (returns immediately)
- // - If input bitstream contains multiple frames DecodeFrameAsync will start decoding multiple frames, and remove them from bitstream
- status = m_Inst.DecodeFrameAsync(&m_sBitstream, m_ppSurfacePtrs[nSurfaceIndex], &pmfxOutSurface, &syncp);
-
- // Ignore warnings if output is available,
- // if no output and no action required just repeat the DecodeFrameAsync call
- if (MFX_ERR_NONE < status && syncp)
- {
- status = MFX_ERR_NONE;
- }
-
- if (MFX_ERR_NONE == status)
- {
- status = m_pSession->SyncOperation(syncp, 60000); // Synchronize. Wait until decoded frame is ready
- }
-
- if (MFX_ERR_NONE == status)
- {
- bGotFrame = true;
- if (pmfxOutSurface)
- {
- *ppmfxOutSurface = pmfxOutSurface;
- }
- }
- }
-
- //
- // Stage 2: Retrieve the buffered decoded frames
- //
- while (MFX_ERR_NONE <= status || MFX_ERR_MORE_SURFACE == status)
- {
- if (MFX_WRN_DEVICE_BUSY == status)
- {
- tsk_thread_sleep(1); // Wait if device is busy, then repeat the same call to DecodeFrameAsync
- }
-
- nSurfaceIndex = GetFreeSurfaceIndex(); // Find free frame surface
- if (MFX_ERR_NOT_FOUND == nSurfaceIndex)
- {
- INTEL_CHECK_STATUS((status = MFX_ERR_MEMORY_ALLOC));
- }
-
- // Decode a frame asychronously (returns immediately)
- status = m_Inst.DecodeFrameAsync(NULL, m_ppSurfacePtrs[nSurfaceIndex], ppmfxOutSurface, &syncp);
-
- // Ignore warnings if output is available,
- // if no output and no action required just repeat the DecodeFrameAsync call
- if (MFX_ERR_NONE < status && syncp)
- {
- status = MFX_ERR_NONE;
- }
-
- if (MFX_ERR_NONE == status)
- {
- status = m_pSession->SyncOperation(syncp, 60000); // Synchronize. Waits until decoded frame is ready
- }
-
- if (MFX_ERR_NONE == status)
- {
- bGotFrame = true;
- if (pmfxOutSurface)
- {
- *ppmfxOutSurface = pmfxOutSurface;
- }
- }
- }
-
- status = MFX_ERR_NONE;
-
- bail:
- return status;
- }
+ INTEL_DEBUG_INFO("nEncSurfNum = %hu", m_sAllocRequest.NumFrameSuggested);
+ INTEL_CHECK_STATUS(status = AllocSurfaces(m_sAllocRequest.NumFrameSuggested, m_sAllocRequest.Info.Width, m_sAllocRequest.Info.Height, &m_sParamReq.mfx.FrameInfo));
+#endif
+ // Initialize the Media SDK decoder
+ status = m_Inst.Init(&m_sParamReq);
+ if (status != MFX_ERR_NONE && status != MFX_WRN_PARTIAL_ACCELERATION) {
+ INTEL_CHECK_STATUS(status);
+ }
+ INTEL_DEBUG_INFO("Decoder->Init() returned: %d", status);
+
+ m_bInit = true;
+ }
+
+ //
+ // Stage 1: Main decoding loop
+ //
+ while (MFX_ERR_NONE <= status || MFX_ERR_MORE_DATA == status || MFX_ERR_MORE_SURFACE == status) {
+ if (MFX_WRN_DEVICE_BUSY == status) {
+ tsk_thread_sleep(1); // Wait if device is busy, then repeat the same call to DecodeFrameAsync
+ }
+
+ if (MFX_ERR_MORE_DATA == status) {
+ return MFX_ERR_NONE;
+ }
+
+ if (MFX_ERR_MORE_SURFACE == status || MFX_ERR_NONE == status) {
+ nSurfaceIndex = GetFreeSurfaceIndex(); // Find free frame surface
+ if (MFX_ERR_NOT_FOUND == nSurfaceIndex) {
+ INTEL_CHECK_STATUS((status = MFX_ERR_MEMORY_ALLOC));
+ }
+ }
+
+ // Decode a frame asychronously (returns immediately)
+ // - If input bitstream contains multiple frames DecodeFrameAsync will start decoding multiple frames, and remove them from bitstream
+ status = m_Inst.DecodeFrameAsync(&m_sBitstream, m_ppSurfacePtrs[nSurfaceIndex], &pmfxOutSurface, &syncp);
+
+ // Ignore warnings if output is available,
+ // if no output and no action required just repeat the DecodeFrameAsync call
+ if (MFX_ERR_NONE < status && syncp) {
+ status = MFX_ERR_NONE;
+ }
+
+ if (MFX_ERR_NONE == status) {
+ status = m_pSession->SyncOperation(syncp, 60000); // Synchronize. Wait until decoded frame is ready
+ }
+
+ if (MFX_ERR_NONE == status) {
+ bGotFrame = true;
+ if (pmfxOutSurface) {
+ *ppmfxOutSurface = pmfxOutSurface;
+ }
+ }
+ }
+
+ //
+ // Stage 2: Retrieve the buffered decoded frames
+ //
+ while (MFX_ERR_NONE <= status || MFX_ERR_MORE_SURFACE == status) {
+ if (MFX_WRN_DEVICE_BUSY == status) {
+ tsk_thread_sleep(1); // Wait if device is busy, then repeat the same call to DecodeFrameAsync
+ }
+
+ nSurfaceIndex = GetFreeSurfaceIndex(); // Find free frame surface
+ if (MFX_ERR_NOT_FOUND == nSurfaceIndex) {
+ INTEL_CHECK_STATUS((status = MFX_ERR_MEMORY_ALLOC));
+ }
+
+ // Decode a frame asychronously (returns immediately)
+ status = m_Inst.DecodeFrameAsync(NULL, m_ppSurfacePtrs[nSurfaceIndex], ppmfxOutSurface, &syncp);
+
+ // Ignore warnings if output is available,
+ // if no output and no action required just repeat the DecodeFrameAsync call
+ if (MFX_ERR_NONE < status && syncp) {
+ status = MFX_ERR_NONE;
+ }
+
+ if (MFX_ERR_NONE == status) {
+ status = m_pSession->SyncOperation(syncp, 60000); // Synchronize. Waits until decoded frame is ready
+ }
+
+ if (MFX_ERR_NONE == status) {
+ bGotFrame = true;
+ if (pmfxOutSurface) {
+ *ppmfxOutSurface = pmfxOutSurface;
+ }
+ }
+ }
+
+ status = MFX_ERR_NONE;
+
+bail:
+ return status;
+ }
private:
- mfxU8 *m_pAccumulatorPtr;
- mfxU32 m_nAccumulatorSize;
- mfxU32 m_nAccumulatorPos;
- mfxU32 m_nLastRtpTimestamp;
- MFXVideoDECODE m_Inst;
- bool m_bInit;
+ mfxU8 *m_pAccumulatorPtr;
+ mfxU32 m_nAccumulatorSize;
+ mfxU32 m_nAccumulatorPos;
+ mfxU32 m_nLastRtpTimestamp;
+ MFXVideoDECODE m_Inst;
+ bool m_bInit;
};
/* ============ H.264 Base/Main Profile X.X Plugin interface functions ================= */
static int tdav_codec_h264_intel_set(tmedia_codec_t* self, const tmedia_param_t* param)
{
- tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
- if (param->value_type == tmedia_pvt_int32)
- {
- if (tsk_striequals(param->key, "action"))
- {
- tmedia_codec_action_t action = (tmedia_codec_action_t)TSK_TO_INT32((uint8_t*)param->value);
- switch (action) {
- case tmedia_codec_action_encode_idr:
- {
- h264->encoder.force_idr = tsk_true;
- return 0;
- }
- case tmedia_codec_action_bw_up:
- case tmedia_codec_action_bw_down:
- {
- if (self->opened)
- {
- INTEL_CHECK_STATUS(h264->encoder.pInst->UpdateBandwidth(action == tmedia_codec_action_bw_up, TMEDIA_CODEC(h264)->bandwidth_max_upload));
- }
- break;
- }
- }
- }
- else if (tsk_striequals(param->key, "bw_kbps")) // both up and down (from the SDP)
- {
- int32_t max_bw_userdefine = tmedia_defaults_get_bandwidth_video_upload_max();
- int32_t max_bw_new = *((int32_t*)param->value);
- if (max_bw_userdefine > 0)
- {
- // do not use more than what the user defined in it's configuration
- TMEDIA_CODEC(h264)->bandwidth_max_upload = TSK_MIN(max_bw_new, max_bw_userdefine);
- }
- else
- {
- TMEDIA_CODEC(h264)->bandwidth_max_upload = max_bw_new;
- }
- INTEL_DEBUG_INFO("bandwidth-max-upload=%d", TMEDIA_CODEC(h264)->bandwidth_max_upload);
- if (self->opened)
- {
- INTEL_CHECK_STATUS(h264->encoder.pInst->SetMaxBandwidth(TMEDIA_CODEC(h264)->bandwidth_max_upload));
- }
- return 0;
- }
- else if (tsk_striequals(param->key, "bandwidth-max-upload"))
- {
- int32_t bw_max_upload = *((int32_t*)param->value);
- TSK_DEBUG_INFO("OpenH264 codec: bandwidth-max-upload=%d", bw_max_upload);
- TMEDIA_CODEC(h264)->bandwidth_max_upload = bw_max_upload;
- if (self->opened)
- {
- INTEL_CHECK_STATUS(h264->encoder.pInst->SetMaxBandwidth(TMEDIA_CODEC(h264)->bandwidth_max_upload));
- }
- return 0;
- }
- else if (tsk_striequals(param->key, "rotation"))
- {
- int rotation = *((int32_t*)param->value);
- if (h264->encoder.rotation != rotation)
- {
- if (self->opened)
- {
- int ret;
- h264->encoder.rotation = rotation;
- if ((ret = tdav_codec_h264_intel_close_encoder(h264)))
- {
- return ret;
- }
- if ((ret = tdav_codec_h264_intel_open_encoder(h264)))
- {
- return ret;
- }
- }
- }
- return 0;
- }
- }
+ tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
+ if (param->value_type == tmedia_pvt_int32) {
+ if (tsk_striequals(param->key, "action")) {
+ tmedia_codec_action_t action = (tmedia_codec_action_t)TSK_TO_INT32((uint8_t*)param->value);
+ switch (action) {
+ case tmedia_codec_action_encode_idr: {
+ h264->encoder.force_idr = tsk_true;
+ return 0;
+ }
+ case tmedia_codec_action_bw_up:
+ case tmedia_codec_action_bw_down: {
+ if (self->opened) {
+ INTEL_CHECK_STATUS(h264->encoder.pInst->UpdateBandwidth(action == tmedia_codec_action_bw_up, TMEDIA_CODEC(h264)->bandwidth_max_upload));
+ }
+ break;
+ }
+ }
+ }
+ else if (tsk_striequals(param->key, "bw_kbps")) { // both up and down (from the SDP)
+ int32_t max_bw_userdefine = tmedia_defaults_get_bandwidth_video_upload_max();
+ int32_t max_bw_new = *((int32_t*)param->value);
+ if (max_bw_userdefine > 0) {
+ // do not use more than what the user defined in it's configuration
+ TMEDIA_CODEC(h264)->bandwidth_max_upload = TSK_MIN(max_bw_new, max_bw_userdefine);
+ }
+ else {
+ TMEDIA_CODEC(h264)->bandwidth_max_upload = max_bw_new;
+ }
+ INTEL_DEBUG_INFO("bandwidth-max-upload=%d", TMEDIA_CODEC(h264)->bandwidth_max_upload);
+ if (self->opened) {
+ INTEL_CHECK_STATUS(h264->encoder.pInst->SetMaxBandwidth(TMEDIA_CODEC(h264)->bandwidth_max_upload));
+ }
+ return 0;
+ }
+ else if (tsk_striequals(param->key, "bandwidth-max-upload")) {
+ int32_t bw_max_upload = *((int32_t*)param->value);
+ TSK_DEBUG_INFO("OpenH264 codec: bandwidth-max-upload=%d", bw_max_upload);
+ TMEDIA_CODEC(h264)->bandwidth_max_upload = bw_max_upload;
+ if (self->opened) {
+ INTEL_CHECK_STATUS(h264->encoder.pInst->SetMaxBandwidth(TMEDIA_CODEC(h264)->bandwidth_max_upload));
+ }
+ return 0;
+ }
+ else if (tsk_striequals(param->key, "rotation")) {
+ int rotation = *((int32_t*)param->value);
+ if (h264->encoder.rotation != rotation) {
+ if (self->opened) {
+ int ret;
+ h264->encoder.rotation = rotation;
+ if ((ret = tdav_codec_h264_intel_close_encoder(h264))) {
+ return ret;
+ }
+ if ((ret = tdav_codec_h264_intel_open_encoder(h264))) {
+ return ret;
+ }
+ }
+ }
+ return 0;
+ }
+ }
bail:
- return -1;
+ return -1;
}
static int tdav_codec_h264_intel_open(tmedia_codec_t* self)
{
- int ret;
- tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
+ int ret;
+ tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
- if (!h264) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!h264) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- /* the caller (base class) already checked that the codec is not opened */
+ /* the caller (base class) already checked that the codec is not opened */
- // Encoder
- if ((ret = tdav_codec_h264_intel_open_encoder(h264))) {
- return ret;
- }
+ // Encoder
+ if ((ret = tdav_codec_h264_intel_open_encoder(h264))) {
+ return ret;
+ }
- // Decoder
- if ((ret = tdav_codec_h264_intel_open_decoder(h264))) {
- return ret;
- }
+ // Decoder
+ if ((ret = tdav_codec_h264_intel_open_decoder(h264))) {
+ return ret;
+ }
- return 0;
+ return 0;
}
static int tdav_codec_h264_intel_close(tmedia_codec_t* self)
{
- tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
+ tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
- if (!h264)
- {
- INTEL_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!h264) {
+ INTEL_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- /* the caller (base class) alreasy checked that the codec is opened */
+ /* the caller (base class) alreasy checked that the codec is opened */
- // Encoder
- tdav_codec_h264_intel_close_encoder(h264);
+ // Encoder
+ tdav_codec_h264_intel_close_encoder(h264);
- // Decoder
- tdav_codec_h264_intel_close_decoder(h264);
+ // Decoder
+ tdav_codec_h264_intel_close_decoder(h264);
- return 0;
+ return 0;
}
static tsk_size_t tdav_codec_h264_intel_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
{
- tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
- (void)(out_data);
- (void)(out_max_size);
-
- if (!h264 || !h264->encoder.pInst)
- {
- INTEL_CHECK_STATUS(MFX_ERR_NULL_PTR);
- }
- INTEL_CHECK_STATUS(h264->encoder.pInst->Encode(self, (const mfxU8*)in_data, (mfxU32)in_size));
+ tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
+ (void)(out_data);
+ (void)(out_max_size);
+
+ if (!h264 || !h264->encoder.pInst) {
+ INTEL_CHECK_STATUS(MFX_ERR_NULL_PTR);
+ }
+ INTEL_CHECK_STATUS(h264->encoder.pInst->Encode(self, (const mfxU8*)in_data, (mfxU32)in_size));
bail:
- return 0;
+ return 0;
}
static tsk_size_t tdav_codec_h264_intel_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
{
- tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
+ tdav_codec_h264_intel_t* h264 = (tdav_codec_h264_intel_t*)self;
- if (!h264 || !h264->decoder.pInst)
- {
- INTEL_CHECK_STATUS(MFX_ERR_NULL_PTR);
- }
- return (tsk_size_t)h264->decoder.pInst->Decode(self, (const mfxU8*)in_data, (mfxU32)in_size, out_data, out_max_size, (const trtp_rtp_header_t*)proto_hdr);
+ if (!h264 || !h264->decoder.pInst) {
+ INTEL_CHECK_STATUS(MFX_ERR_NULL_PTR);
+ }
+ return (tsk_size_t)h264->decoder.pInst->Decode(self, (const mfxU8*)in_data, (mfxU32)in_size, out_data, out_max_size, (const trtp_rtp_header_t*)proto_hdr);
bail:
- return 0;
+ return 0;
}
static tsk_bool_t tdav_codec_h264_intel_sdp_att_match(const tmedia_codec_t* self, const char* att_name, const char* att_value)
{
- return tdav_codec_h264_common_sdp_att_match((tdav_codec_h264_common_t*)self, att_name, att_value);
+ return tdav_codec_h264_common_sdp_att_match((tdav_codec_h264_common_t*)self, att_name, att_value);
}
static char* tdav_codec_h264_intel_sdp_att_get(const tmedia_codec_t* self, const char* att_name)
{
- char* att = tdav_codec_h264_common_sdp_att_get((const tdav_codec_h264_common_t*)self, att_name);
- if (att && tsk_striequals(att_name, "fmtp")) {
- tsk_strcat(&att, "; impl=intel");
- }
- return att;
+ char* att = tdav_codec_h264_common_sdp_att_get((const tdav_codec_h264_common_t*)self, att_name);
+ if (att && tsk_striequals(att_name, "fmtp")) {
+ tsk_strcat(&att, "; impl=intel");
+ }
+ return att;
}
/* ============ H.264 Base Profile Plugin interface ================= */
@@ -1477,63 +1335,61 @@ static char* tdav_codec_h264_intel_sdp_att_get(const tmedia_codec_t* self, const
/* constructor */
static tsk_object_t* tdav_codec_h264_intel_base_ctor(tsk_object_t * self, va_list * app)
{
- tdav_codec_h264_intel_t *h264 = (tdav_codec_h264_intel_t*)self;
- if (h264) {
- /* init base: called by tmedia_codec_create() */
- /* init self */
- if (tdav_codec_h264_intel_init(h264, profile_idc_baseline) != 0) {
- return tsk_null;
- }
- }
- return self;
+ tdav_codec_h264_intel_t *h264 = (tdav_codec_h264_intel_t*)self;
+ if (h264) {
+ /* init base: called by tmedia_codec_create() */
+ /* init self */
+ if (tdav_codec_h264_intel_init(h264, profile_idc_baseline) != 0) {
+ return tsk_null;
+ }
+ }
+ return self;
}
/* destructor */
static tsk_object_t* tdav_codec_h264_intel_base_dtor(tsk_object_t * self)
{
- tdav_codec_h264_intel_t *h264 = (tdav_codec_h264_intel_t*)self;
- if (h264) {
- /* deinit base */
- tdav_codec_h264_common_deinit(TDAV_CODEC_H264_COMMON(self));
- /* deinit self */
- tdav_codec_h264_intel_deinit(h264);
- }
-
- return self;
+ tdav_codec_h264_intel_t *h264 = (tdav_codec_h264_intel_t*)self;
+ if (h264) {
+ /* deinit base */
+ tdav_codec_h264_common_deinit(TDAV_CODEC_H264_COMMON(self));
+ /* deinit self */
+ tdav_codec_h264_intel_deinit(h264);
+ }
+
+ return self;
}
/* object definition */
-static const tsk_object_def_t tdav_codec_h264_intel_base_def_s =
-{
- sizeof(tdav_codec_h264_intel_t),
- tdav_codec_h264_intel_base_ctor,
- tdav_codec_h264_intel_base_dtor,
- tmedia_codec_cmp,
+static const tsk_object_def_t tdav_codec_h264_intel_base_def_s = {
+ sizeof(tdav_codec_h264_intel_t),
+ tdav_codec_h264_intel_base_ctor,
+ tdav_codec_h264_intel_base_dtor,
+ tmedia_codec_cmp,
};
/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_h264_intel_base_plugin_def_s =
-{
- &tdav_codec_h264_intel_base_def_s,
-
- tmedia_video,
- tmedia_codec_id_h264_bp,
- "H264",
- "H264 Base Profile (Intel Media SDK)",
- TMEDIA_CODEC_FORMAT_H264_BP,
- tsk_true,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video (width, height, fps) */
- { 176, 144, 0 }, // fps is @deprecated
-
- tdav_codec_h264_intel_set,
- tdav_codec_h264_intel_open,
- tdav_codec_h264_intel_close,
- tdav_codec_h264_intel_encode,
- tdav_codec_h264_intel_decode,
- tdav_codec_h264_intel_sdp_att_match,
- tdav_codec_h264_intel_sdp_att_get
+static const tmedia_codec_plugin_def_t tdav_codec_h264_intel_base_plugin_def_s = {
+ &tdav_codec_h264_intel_base_def_s,
+
+ tmedia_video,
+ tmedia_codec_id_h264_bp,
+ "H264",
+ "H264 Base Profile (Intel Media SDK)",
+ TMEDIA_CODEC_FORMAT_H264_BP,
+ tsk_true,
+ 90000, // rate
+
+ /* audio */
+ { 0 },
+
+ /* video (width, height, fps) */
+ { 176, 144, 0 }, // fps is @deprecated
+
+ tdav_codec_h264_intel_set,
+ tdav_codec_h264_intel_open,
+ tdav_codec_h264_intel_close,
+ tdav_codec_h264_intel_encode,
+ tdav_codec_h264_intel_decode,
+ tdav_codec_h264_intel_sdp_att_match,
+ tdav_codec_h264_intel_sdp_att_get
};
const tmedia_codec_plugin_def_t *tdav_codec_h264_intel_base_plugin_def_t = &tdav_codec_h264_intel_base_plugin_def_s;
@@ -1543,64 +1399,61 @@ const tmedia_codec_plugin_def_t *tdav_codec_h264_intel_base_plugin_def_t = &tdav
/* constructor */
static tsk_object_t* tdav_codec_h264_intel_main_ctor(tsk_object_t * self, va_list * app)
{
- tdav_codec_h264_intel_t *h264 = (tdav_codec_h264_intel_t*)self;
- if (h264) {
- /* init main: called by tmedia_codec_create() */
- /* init self */
- if (tdav_codec_h264_intel_init(h264, profile_idc_main) != 0) {
- return tsk_null;
- }
- }
- return self;
+ tdav_codec_h264_intel_t *h264 = (tdav_codec_h264_intel_t*)self;
+ if (h264) {
+ /* init main: called by tmedia_codec_create() */
+ /* init self */
+ if (tdav_codec_h264_intel_init(h264, profile_idc_main) != 0) {
+ return tsk_null;
+ }
+ }
+ return self;
}
/* destructor */
static tsk_object_t* tdav_codec_h264_intel_main_dtor(tsk_object_t * self)
{
- tdav_codec_h264_intel_t *h264 = (tdav_codec_h264_intel_t*)self;
- if (h264)
- {
- /* deinit main */
- tdav_codec_h264_common_deinit(TDAV_CODEC_H264_COMMON(self));
- /* deinit self */
- tdav_codec_h264_intel_deinit(h264);
- }
-
- return self;
+ tdav_codec_h264_intel_t *h264 = (tdav_codec_h264_intel_t*)self;
+ if (h264) {
+ /* deinit main */
+ tdav_codec_h264_common_deinit(TDAV_CODEC_H264_COMMON(self));
+ /* deinit self */
+ tdav_codec_h264_intel_deinit(h264);
+ }
+
+ return self;
}
/* object definition */
-static const tsk_object_def_t tdav_codec_h264_intel_main_def_s =
-{
- sizeof(tdav_codec_h264_intel_t),
- tdav_codec_h264_intel_main_ctor,
- tdav_codec_h264_intel_main_dtor,
- tmedia_codec_cmp,
+static const tsk_object_def_t tdav_codec_h264_intel_main_def_s = {
+ sizeof(tdav_codec_h264_intel_t),
+ tdav_codec_h264_intel_main_ctor,
+ tdav_codec_h264_intel_main_dtor,
+ tmedia_codec_cmp,
};
/* plugin definition*/
-static const tmedia_codec_plugin_def_t tdav_codec_h264_intel_main_plugin_def_s =
-{
- &tdav_codec_h264_intel_main_def_s,
-
- tmedia_video,
- tmedia_codec_id_h264_mp,
- "H264",
- "H264 main Profile (Intel Media SDK)",
- TMEDIA_CODEC_FORMAT_H264_MP,
- tsk_true,
- 90000, // rate
-
- /* audio */
- { 0 },
-
- /* video (width, height, fps) */
- { 176, 144, 0 }, // fps is @deprecated
-
- tdav_codec_h264_intel_set,
- tdav_codec_h264_intel_open,
- tdav_codec_h264_intel_close,
- tdav_codec_h264_intel_encode,
- tdav_codec_h264_intel_decode,
- tdav_codec_h264_intel_sdp_att_match,
- tdav_codec_h264_intel_sdp_att_get
+static const tmedia_codec_plugin_def_t tdav_codec_h264_intel_main_plugin_def_s = {
+ &tdav_codec_h264_intel_main_def_s,
+
+ tmedia_video,
+ tmedia_codec_id_h264_mp,
+ "H264",
+ "H264 main Profile (Intel Media SDK)",
+ TMEDIA_CODEC_FORMAT_H264_MP,
+ tsk_true,
+ 90000, // rate
+
+ /* audio */
+ { 0 },
+
+ /* video (width, height, fps) */
+ { 176, 144, 0 }, // fps is @deprecated
+
+ tdav_codec_h264_intel_set,
+ tdav_codec_h264_intel_open,
+ tdav_codec_h264_intel_close,
+ tdav_codec_h264_intel_encode,
+ tdav_codec_h264_intel_decode,
+ tdav_codec_h264_intel_sdp_att_match,
+ tdav_codec_h264_intel_sdp_att_get
};
const tmedia_codec_plugin_def_t *tdav_codec_h264_intel_main_plugin_def_t = &tdav_codec_h264_intel_main_plugin_def_s;
@@ -1608,171 +1461,158 @@ const tmedia_codec_plugin_def_t *tdav_codec_h264_intel_main_plugin_def_t = &tdav
static int tdav_codec_h264_intel_open_encoder(tdav_codec_h264_intel_t* self)
{
- if (self->encoder.pInst)
- {
- INTEL_BREAK("Already initialized");
- }
+ if (self->encoder.pInst) {
+ INTEL_BREAK("Already initialized");
+ }
- if (!(self->encoder.pInst = new IntelCodecEncoder(self->mfxSession)))
- {
- INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
- }
- INTEL_CHECK_STATUS(self->encoder.pInst->Open(self));
+ if (!(self->encoder.pInst = new IntelCodecEncoder(self->mfxSession))) {
+ INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
+ }
+ INTEL_CHECK_STATUS(self->encoder.pInst->Open(self));
- return 0;
+ return 0;
bail:
- if (self->encoder.pInst)
- {
- delete self->encoder.pInst, self->encoder.pInst = NULL;
- }
- return -1;
+ if (self->encoder.pInst) {
+ delete self->encoder.pInst, self->encoder.pInst = NULL;
+ }
+ return -1;
}
static int tdav_codec_h264_intel_close_encoder(tdav_codec_h264_intel_t* self)
{
- if (self)
- {
- if (self->encoder.pInst)
- {
- delete self->encoder.pInst;
- self->encoder.pInst = NULL;
- }
- self->encoder.frame_count = 0;
- }
- return 0;
+ if (self) {
+ if (self->encoder.pInst) {
+ delete self->encoder.pInst;
+ self->encoder.pInst = NULL;
+ }
+ self->encoder.frame_count = 0;
+ }
+ return 0;
}
int tdav_codec_h264_intel_open_decoder(tdav_codec_h264_intel_t* self)
{
- if (self->decoder.pInst)
- {
- INTEL_BREAK("Already initialized");
- }
+ if (self->decoder.pInst) {
+ INTEL_BREAK("Already initialized");
+ }
- if (!(self->decoder.pInst = new IntelCodecDecoder(self->mfxSession)))
- {
- INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
- }
- INTEL_CHECK_STATUS(self->decoder.pInst->Open(self));
+ if (!(self->decoder.pInst = new IntelCodecDecoder(self->mfxSession))) {
+ INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
+ }
+ INTEL_CHECK_STATUS(self->decoder.pInst->Open(self));
- return 0;
+ return 0;
bail:
- if (self->decoder.pInst)
- {
- delete self->decoder.pInst, self->decoder.pInst = NULL;
- }
- return -1;
+ if (self->decoder.pInst) {
+ delete self->decoder.pInst, self->decoder.pInst = NULL;
+ }
+ return -1;
}
static int tdav_codec_h264_intel_close_decoder(tdav_codec_h264_intel_t* self)
{
- if (self)
- {
- if (self->decoder.pInst)
- {
- delete self->decoder.pInst;
- self->decoder.pInst = NULL;
- }
- }
- return 0;
+ if (self) {
+ if (self->decoder.pInst) {
+ delete self->decoder.pInst;
+ self->decoder.pInst = NULL;
+ }
+ }
+ return 0;
}
static int tdav_codec_h264_intel_init(tdav_codec_h264_intel_t* self, profile_idc_t profile)
{
- int ret = -1;
- level_idc_t level;
- tdav_codec_h264_common_t* common = (tdav_codec_h264_common_t*)self;
+ int ret = -1;
+ level_idc_t level;
+ tdav_codec_h264_common_t* common = (tdav_codec_h264_common_t*)self;
#if INTEL_DX11_D3D
- mfxHDL deviceHandle = NULL;
+ mfxHDL deviceHandle = NULL;
#endif
- if (!self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- goto bail;
- }
-
- if ((ret = tdav_codec_h264_common_init(common))) {
- TSK_DEBUG_ERROR("tdav_codec_h264_intel_common_init() faile with error code=%d", ret);
- goto bail;
- }
-
- if ((ret = tdav_codec_h264_common_level_from_size(TMEDIA_CODEC_VIDEO(self)->out.width, TMEDIA_CODEC_VIDEO(self)->out.height, &level))) {
- TSK_DEBUG_ERROR("Failed to find level for size=[%u, %u]", TMEDIA_CODEC_VIDEO(self)->out.width, TMEDIA_CODEC_VIDEO(self)->out.height);
- goto bail;
- }
-
- if (/*MFUtils::IsLowLatencyH264SupportsMaxSliceSize()*/0) { // TODO: MSDK doesn't support PM=0. Neg. PM=1 but try to do the best to produce SingleNalUnits
- common->pack_mode_local = H264_PACKETIZATION_MODE;
- }
- else {
- common->pack_mode_local = Non_Interleaved_Mode;
- }
- common->profile = profile;
- common->level = level;
+ if (!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ goto bail;
+ }
+
+ if ((ret = tdav_codec_h264_common_init(common))) {
+ TSK_DEBUG_ERROR("tdav_codec_h264_intel_common_init() faile with error code=%d", ret);
+ goto bail;
+ }
+
+ if ((ret = tdav_codec_h264_common_level_from_size(TMEDIA_CODEC_VIDEO(self)->out.width, TMEDIA_CODEC_VIDEO(self)->out.height, &level))) {
+ TSK_DEBUG_ERROR("Failed to find level for size=[%u, %u]", TMEDIA_CODEC_VIDEO(self)->out.width, TMEDIA_CODEC_VIDEO(self)->out.height);
+ goto bail;
+ }
+
+ if (/*MFUtils::IsLowLatencyH264SupportsMaxSliceSize()*/0) { // TODO: MSDK doesn't support PM=0. Neg. PM=1 but try to do the best to produce SingleNalUnits
+ common->pack_mode_local = H264_PACKETIZATION_MODE;
+ }
+ else {
+ common->pack_mode_local = Non_Interleaved_Mode;
+ }
+ common->profile = profile;
+ common->level = level;
#if 0
- // A.2.1.1 Constrained Baseline profile
- // Conformance of a bitstream to the Constrained Baseline profile is indicated by profile_idc being equal to 66 with
- // constraint_set1_flag being equal to 1.
- common->profile_iop = 0xe0; // "constraint_set0_flag=1 and constraint_set1_flag=1" -> Constrained Baseline profile
+ // A.2.1.1 Constrained Baseline profile
+ // Conformance of a bitstream to the Constrained Baseline profile is indicated by profile_idc being equal to 66 with
+ // constraint_set1_flag being equal to 1.
+ common->profile_iop = 0xe0; // "constraint_set0_flag=1 and constraint_set1_flag=1" -> Constrained Baseline profile
#endif
- TMEDIA_CODEC_VIDEO(self)->in.max_mbps = TMEDIA_CODEC_VIDEO(self)->out.max_mbps = H264_MAX_MBPS * 1000;
- TMEDIA_CODEC_VIDEO(self)->in.max_br = TMEDIA_CODEC_VIDEO(self)->out.max_br = H264_MAX_BR * 1000;
+ TMEDIA_CODEC_VIDEO(self)->in.max_mbps = TMEDIA_CODEC_VIDEO(self)->out.max_mbps = H264_MAX_MBPS * 1000;
+ TMEDIA_CODEC_VIDEO(self)->in.max_br = TMEDIA_CODEC_VIDEO(self)->out.max_br = H264_MAX_BR * 1000;
- TMEDIA_CODEC_VIDEO(self)->in.chroma = tmedia_chroma_yuv420p; // decoded
- TMEDIA_CODEC_VIDEO(self)->out.chroma = tmedia_chroma_yuv420p; // encoded
+ TMEDIA_CODEC_VIDEO(self)->in.chroma = tmedia_chroma_yuv420p; // decoded
+ TMEDIA_CODEC_VIDEO(self)->out.chroma = tmedia_chroma_yuv420p; // encoded
- if (!self->mfxSession && !(self->mfxSession = new MFXVideoSession()))
- {
- INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
- }
- INTEL_CHECK_STATUS(self->mfxSession->Init(__IntelDefaultImpl, &__IntelDefaultVer));
+ if (!self->mfxSession && !(self->mfxSession = new MFXVideoSession())) {
+ INTEL_CHECK_STATUS(MFX_ERR_MEMORY_ALLOC);
+ }
+ INTEL_CHECK_STATUS(self->mfxSession->Init(__IntelDefaultImpl, &__IntelDefaultVer));
#if INTEL_DX11_D3D
- // Create DirectX device context
- INTEL_CHECK_STATUS(D3D11_CreateHWDevice(self, *self->mfxSession, &deviceHandle, NULL));
-
- // Provide device manager to Media SDK
- INTEL_CHECK_STATUS(self->mfxSession->SetHandle(MFX_HANDLE_D3D11_DEVICE, deviceHandle));
-
- self->D3D11Allocator.Alloc = D3D11_SimpleAlloc;
- self->D3D11Allocator.Free = D3D11_SimpleFree;
- self->D3D11Allocator.Lock = D3D11_SimpleLock;
- self->D3D11Allocator.Unlock = D3D11_SimpleUnlock;
- self->D3D11Allocator.GetHDL = D3D11_SimpleGethdl;
- self->D3D11Allocator.pthis = self;
-
- // Since we are using video memory we must provide Media SDK with an external allocator
- INTEL_CHECK_STATUS(self->mfxSession->SetFrameAllocator(&self->D3D11Allocator));
+ // Create DirectX device context
+ INTEL_CHECK_STATUS(D3D11_CreateHWDevice(self, *self->mfxSession, &deviceHandle, NULL));
+
+ // Provide device manager to Media SDK
+ INTEL_CHECK_STATUS(self->mfxSession->SetHandle(MFX_HANDLE_D3D11_DEVICE, deviceHandle));
+
+ self->D3D11Allocator.Alloc = D3D11_SimpleAlloc;
+ self->D3D11Allocator.Free = D3D11_SimpleFree;
+ self->D3D11Allocator.Lock = D3D11_SimpleLock;
+ self->D3D11Allocator.Unlock = D3D11_SimpleUnlock;
+ self->D3D11Allocator.GetHDL = D3D11_SimpleGethdl;
+ self->D3D11Allocator.pthis = self;
+
+ // Since we are using video memory we must provide Media SDK with an external allocator
+ INTEL_CHECK_STATUS(self->mfxSession->SetFrameAllocator(&self->D3D11Allocator));
#endif /* INTEL_DX11_D3D */
- ret = 0;
+ ret = 0;
bail:
- return ret;
+ return ret;
}
static int tdav_codec_h264_intel_deinit(tdav_codec_h264_intel_t* self)
{
- if (!self)
- {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tdav_codec_h264_intel_close((tmedia_codec_t*)self);
+ tdav_codec_h264_intel_close((tmedia_codec_t*)self);
- if (self->mfxSession)
- {
- delete self->mfxSession, self->mfxSession = NULL;
- }
+ if (self->mfxSession) {
+ delete self->mfxSession, self->mfxSession = NULL;
+ }
#if INTEL_DX11_D3D
- D3D11_CleanupHWDevice(self);
+ D3D11_CleanupHWDevice(self);
#endif /* INTEL_DX11_D3D */
- return 0;
+ return 0;
}
@@ -1780,40 +1620,36 @@ static int tdav_codec_h264_intel_deinit(tdav_codec_h264_intel_t* self)
static IDXGIAdapter* D3D11_GetIntelDeviceAdapterHandle(mfxHDL _pthis, mfxSession session)
{
- mfxU32 adapterNum = 0;
- mfxIMPL impl;
- tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
-
- MFXQueryIMPL(session, &impl);
-
- mfxIMPL baseImpl = MFX_IMPL_BASETYPE(impl); // Extract Media SDK base implementation type
-
- // get corresponding adapter number
- for (mfxU8 i = 0; i < sizeof(implTypes) / sizeof(implTypes[0]); i++)
- {
- if (implTypes[i].impl == baseImpl)
- {
- adapterNum = implTypes[i].adapterID;
- break;
- }
- }
-
- HRESULT hres = CreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)(&pthis->pDXGIFactory));
- if (FAILED(hres))
- {
- INTEL_DEBUG_ERROR("CreateDXGIFactory failed: %ld", hres);
- return NULL;
- }
-
- IDXGIAdapter* adapter = NULL;
- hres = pthis->pDXGIFactory->EnumAdapters(adapterNum, &adapter);
- if (FAILED(hres))
- {
- INTEL_DEBUG_ERROR("EnumAdapters failed: %ld", hres);
- return NULL;
- }
-
- return adapter;
+ mfxU32 adapterNum = 0;
+ mfxIMPL impl;
+ tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
+
+ MFXQueryIMPL(session, &impl);
+
+ mfxIMPL baseImpl = MFX_IMPL_BASETYPE(impl); // Extract Media SDK base implementation type
+
+ // get corresponding adapter number
+ for (mfxU8 i = 0; i < sizeof(implTypes) / sizeof(implTypes[0]); i++) {
+ if (implTypes[i].impl == baseImpl) {
+ adapterNum = implTypes[i].adapterID;
+ break;
+ }
+ }
+
+ HRESULT hres = CreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)(&pthis->pDXGIFactory));
+ if (FAILED(hres)) {
+ INTEL_DEBUG_ERROR("CreateDXGIFactory failed: %ld", hres);
+ return NULL;
+ }
+
+ IDXGIAdapter* adapter = NULL;
+ hres = pthis->pDXGIFactory->EnumAdapters(adapterNum, &adapter);
+ if (FAILED(hres)) {
+ INTEL_DEBUG_ERROR("EnumAdapters failed: %ld", hres);
+ return NULL;
+ }
+
+ return adapter;
}
// Create DirectX 11 device context
@@ -1826,394 +1662,361 @@ static IDXGIAdapter* D3D11_GetIntelDeviceAdapterHandle(mfxHDL _pthis, mfxSession
// - For switchable graphics solutions (mobile) make sure that Intel device is the active device
static mfxStatus D3D11_CreateHWDevice(mfxHDL _pthis, mfxSession session, mfxHDL* deviceHandle, HWND hWnd)
{
- hWnd; // Window handle not required by DX11 since we do not showcase rendering.
-
- HRESULT hres = S_OK;
- tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
-
- static D3D_FEATURE_LEVEL FeatureLevels[] = {
- D3D_FEATURE_LEVEL_11_1,
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0
- };
- D3D_FEATURE_LEVEL pFeatureLevelsOut;
-
- pthis->hAdapter = D3D11_GetIntelDeviceAdapterHandle(_pthis, session);
- if (NULL == pthis->hAdapter)
- {
- INTEL_DEBUG_ERROR("D3D11_GetIntelDeviceAdapterHandle failed");
- return MFX_ERR_DEVICE_FAILED;
- }
-
- hres = D3D11CreateDevice(pthis->hAdapter,
- D3D_DRIVER_TYPE_UNKNOWN,
- NULL,
- 0,
- FeatureLevels,
- (sizeof(FeatureLevels) / sizeof(FeatureLevels[0])),
- D3D11_SDK_VERSION,
- &pthis->pD3D11Device,
- &pFeatureLevelsOut,
- &pthis->pD3D11Ctx);
- if (FAILED(hres))
- {
- INTEL_DEBUG_ERROR("D3D11CreateDevice failed: %ld", hres);
- return MFX_ERR_DEVICE_FAILED;
- }
-
- // turn on multithreading for the DX11 cntext
- CComQIPtr<ID3D10Multithread> p_mt(pthis->pD3D11Ctx);
- if (p_mt)
- {
- p_mt->SetMultithreadProtected(true);
- }
- else
- {
- INTEL_DEBUG_ERROR("Failed to create ID3D10Multithread object");
- return MFX_ERR_DEVICE_FAILED;
- }
-
- *deviceHandle = (mfxHDL)pthis->pD3D11Device;
- return MFX_ERR_NONE;
+ hWnd; // Window handle not required by DX11 since we do not showcase rendering.
+
+ HRESULT hres = S_OK;
+ tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
+
+ static D3D_FEATURE_LEVEL FeatureLevels[] = {
+ D3D_FEATURE_LEVEL_11_1,
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0
+ };
+ D3D_FEATURE_LEVEL pFeatureLevelsOut;
+
+ pthis->hAdapter = D3D11_GetIntelDeviceAdapterHandle(_pthis, session);
+ if (NULL == pthis->hAdapter) {
+ INTEL_DEBUG_ERROR("D3D11_GetIntelDeviceAdapterHandle failed");
+ return MFX_ERR_DEVICE_FAILED;
+ }
+
+ hres = D3D11CreateDevice(pthis->hAdapter,
+ D3D_DRIVER_TYPE_UNKNOWN,
+ NULL,
+ 0,
+ FeatureLevels,
+ (sizeof(FeatureLevels) / sizeof(FeatureLevels[0])),
+ D3D11_SDK_VERSION,
+ &pthis->pD3D11Device,
+ &pFeatureLevelsOut,
+ &pthis->pD3D11Ctx);
+ if (FAILED(hres)) {
+ INTEL_DEBUG_ERROR("D3D11CreateDevice failed: %ld", hres);
+ return MFX_ERR_DEVICE_FAILED;
+ }
+
+ // turn on multithreading for the DX11 cntext
+ CComQIPtr<ID3D10Multithread> p_mt(pthis->pD3D11Ctx);
+ if (p_mt) {
+ p_mt->SetMultithreadProtected(true);
+ }
+ else {
+ INTEL_DEBUG_ERROR("Failed to create ID3D10Multithread object");
+ return MFX_ERR_DEVICE_FAILED;
+ }
+
+ *deviceHandle = (mfxHDL)pthis->pD3D11Device;
+ return MFX_ERR_NONE;
}
static void D3D11_CleanupHWDevice(mfxHDL _pthis)
{
- tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
- pthis->pD3D11Device = NULL;
- pthis->pDXGIFactory = NULL;
- pthis->pD3D11Ctx = NULL;
- pthis->hAdapter = NULL;
- pthis->pAdapter = NULL;
+ tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
+ pthis->pD3D11Device = NULL;
+ pthis->pDXGIFactory = NULL;
+ pthis->pD3D11Ctx = NULL;
+ pthis->hAdapter = NULL;
+ pthis->pAdapter = NULL;
}
static void D3D11_SetHWDeviceContext(mfxHDL _pthis, CComPtr<ID3D11DeviceContext> devCtx)
{
- tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
- pthis->pD3D11Ctx = devCtx;
- devCtx->GetDevice(&pthis->pD3D11Device);
+ tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
+ pthis->pD3D11Ctx = devCtx;
+ devCtx->GetDevice(&pthis->pD3D11Device);
}
// Intel Media SDK memory allocator entrypoints....
// - A slightly different allocation procedure is used for encode, decode and VPP
static mfxStatus _D3D11_SimpleAlloc(mfxHDL _pthis, mfxFrameAllocRequest *request, mfxFrameAllocResponse *response)
{
- HRESULT hRes;
- tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
-
- // Determine surface format (current simple implementation only supports NV12 and RGB4(32))
- DXGI_FORMAT format;
- if (MFX_FOURCC_NV12 == request->Info.FourCC)
- {
- format = DXGI_FORMAT_NV12;
- }
- else if (MFX_FOURCC_RGB4 == request->Info.FourCC)
- {
- format = DXGI_FORMAT_B8G8R8A8_UNORM;
- }
- else
- {
- format = DXGI_FORMAT_P8;
- }
-
- // Allocate custom container to keep texture and stage buffers for each surface
- // Container also stores the intended read and/or write operation.
- CustomMemId** mids = new CustomMemId *[request->NumFrameSuggested];
- if (!mids) return MFX_ERR_MEMORY_ALLOC;
- for (int i = 0; i < request->NumFrameSuggested; i++)
- {
- mids[i] = new CustomMemId;
- memset(mids[i], 0, sizeof(CustomMemId));
- mids[i]->rw = request->Type & 0xF000; // Set intended read/write operation
- }
-
- request->Type = request->Type & 0x0FFF;
-
- // because P8 data (bitstream) for h264 encoder should be allocated by CreateBuffer()
- // but P8 data (MBData) for MPEG2 encoder should be allocated by CreateTexture2D()
- if (request->Info.FourCC == MFX_FOURCC_P8)
- {
- D3D11_BUFFER_DESC desc = { 0 };
-
- desc.ByteWidth = request->Info.Width * request->Info.Height;
- desc.Usage = D3D11_USAGE_STAGING;
- desc.BindFlags = 0;
- desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
- desc.MiscFlags = 0;
- desc.StructureByteStride = 0;
-
- ID3D11Buffer * buffer = 0;
- hRes = pthis->pD3D11Device->CreateBuffer(&desc, 0, &buffer);
- if (FAILED(hRes))
- {
- INTEL_DEBUG_ERROR("CreateBuffer failed:%ld", hRes);
- return MFX_ERR_MEMORY_ALLOC;
- }
-
- mids[0]->memId = reinterpret_cast<ID3D11Texture2D *>(buffer);
- }
- else
- {
- D3D11_TEXTURE2D_DESC desc = { 0 };
-
- desc.Width = request->Info.Width;
- desc.Height = request->Info.Height;
- desc.MipLevels = 1;
- desc.ArraySize = 1; // number of subresources is 1 in this case
- desc.Format = format;
- desc.SampleDesc.Count = 1;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = D3D11_BIND_DECODER;
- desc.MiscFlags = 0;
-
- if ((MFX_MEMTYPE_FROM_VPPIN & request->Type) &&
- (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format))
- {
- desc.BindFlags = D3D11_BIND_RENDER_TARGET;
- if (desc.ArraySize > 2)
- return MFX_ERR_MEMORY_ALLOC;
- }
-
- if ((MFX_MEMTYPE_FROM_VPPOUT & request->Type) ||
- (MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET & request->Type))
- {
- desc.BindFlags = D3D11_BIND_RENDER_TARGET;
- if (desc.ArraySize > 2)
- {
- return MFX_ERR_MEMORY_ALLOC;
- }
- }
-
- if (DXGI_FORMAT_P8 == desc.Format)
- desc.BindFlags = 0;
-
- ID3D11Texture2D* pTexture2D;
-
- // Create surface textures
- for (size_t i = 0; i < request->NumFrameSuggested / desc.ArraySize; i++)
- {
- hRes = pthis->pD3D11Device->CreateTexture2D(&desc, NULL, &pTexture2D);
-
- if (FAILED(hRes))
- {
- INTEL_DEBUG_ERROR("CreateTexture2D failed:%ld", hRes);
- return MFX_ERR_MEMORY_ALLOC;
- }
-
- mids[i]->memId = pTexture2D;
- }
-
- desc.ArraySize = 1;
- desc.Usage = D3D11_USAGE_STAGING;
- desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ /*| D3D11_CPU_ACCESS_WRITE*/;
- desc.BindFlags = 0;
- desc.MiscFlags = 0;
-
- // Create surface staging textures
- for (size_t i = 0; i < request->NumFrameSuggested; i++)
- {
- hRes = pthis->pD3D11Device->CreateTexture2D(&desc, NULL, &pTexture2D);
-
- if (FAILED(hRes))
- {
- INTEL_DEBUG_ERROR("CreateTexture2D failed:%ld", hRes);
- return MFX_ERR_MEMORY_ALLOC;
- }
-
- mids[i]->memIdStage = pTexture2D;
- }
- }
-
- response->mids = (mfxMemId*)mids;
- response->NumFrameActual = request->NumFrameSuggested;
-
- return MFX_ERR_NONE;
+ HRESULT hRes;
+ tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
+
+ // Determine surface format (current simple implementation only supports NV12 and RGB4(32))
+ DXGI_FORMAT format;
+ if (MFX_FOURCC_NV12 == request->Info.FourCC) {
+ format = DXGI_FORMAT_NV12;
+ }
+ else if (MFX_FOURCC_RGB4 == request->Info.FourCC) {
+ format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ }
+ else {
+ format = DXGI_FORMAT_P8;
+ }
+
+ // Allocate custom container to keep texture and stage buffers for each surface
+ // Container also stores the intended read and/or write operation.
+ CustomMemId** mids = new CustomMemId *[request->NumFrameSuggested];
+ if (!mids) {
+ return MFX_ERR_MEMORY_ALLOC;
+ }
+ for (int i = 0; i < request->NumFrameSuggested; i++) {
+ mids[i] = new CustomMemId;
+ memset(mids[i], 0, sizeof(CustomMemId));
+ mids[i]->rw = request->Type & 0xF000; // Set intended read/write operation
+ }
+
+ request->Type = request->Type & 0x0FFF;
+
+ // because P8 data (bitstream) for h264 encoder should be allocated by CreateBuffer()
+ // but P8 data (MBData) for MPEG2 encoder should be allocated by CreateTexture2D()
+ if (request->Info.FourCC == MFX_FOURCC_P8) {
+ D3D11_BUFFER_DESC desc = { 0 };
+
+ desc.ByteWidth = request->Info.Width * request->Info.Height;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.BindFlags = 0;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ desc.MiscFlags = 0;
+ desc.StructureByteStride = 0;
+
+ ID3D11Buffer * buffer = 0;
+ hRes = pthis->pD3D11Device->CreateBuffer(&desc, 0, &buffer);
+ if (FAILED(hRes)) {
+ INTEL_DEBUG_ERROR("CreateBuffer failed:%ld", hRes);
+ return MFX_ERR_MEMORY_ALLOC;
+ }
+
+ mids[0]->memId = reinterpret_cast<ID3D11Texture2D *>(buffer);
+ }
+ else {
+ D3D11_TEXTURE2D_DESC desc = { 0 };
+
+ desc.Width = request->Info.Width;
+ desc.Height = request->Info.Height;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1; // number of subresources is 1 in this case
+ desc.Format = format;
+ desc.SampleDesc.Count = 1;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_DECODER;
+ desc.MiscFlags = 0;
+
+ if ((MFX_MEMTYPE_FROM_VPPIN & request->Type) &&
+ (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format)) {
+ desc.BindFlags = D3D11_BIND_RENDER_TARGET;
+ if (desc.ArraySize > 2) {
+ return MFX_ERR_MEMORY_ALLOC;
+ }
+ }
+
+ if ((MFX_MEMTYPE_FROM_VPPOUT & request->Type) ||
+ (MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET & request->Type)) {
+ desc.BindFlags = D3D11_BIND_RENDER_TARGET;
+ if (desc.ArraySize > 2) {
+ return MFX_ERR_MEMORY_ALLOC;
+ }
+ }
+
+ if (DXGI_FORMAT_P8 == desc.Format) {
+ desc.BindFlags = 0;
+ }
+
+ ID3D11Texture2D* pTexture2D;
+
+ // Create surface textures
+ for (size_t i = 0; i < request->NumFrameSuggested / desc.ArraySize; i++) {
+ hRes = pthis->pD3D11Device->CreateTexture2D(&desc, NULL, &pTexture2D);
+
+ if (FAILED(hRes)) {
+ INTEL_DEBUG_ERROR("CreateTexture2D failed:%ld", hRes);
+ return MFX_ERR_MEMORY_ALLOC;
+ }
+
+ mids[i]->memId = pTexture2D;
+ }
+
+ desc.ArraySize = 1;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ /*| D3D11_CPU_ACCESS_WRITE*/;
+ desc.BindFlags = 0;
+ desc.MiscFlags = 0;
+
+ // Create surface staging textures
+ for (size_t i = 0; i < request->NumFrameSuggested; i++) {
+ hRes = pthis->pD3D11Device->CreateTexture2D(&desc, NULL, &pTexture2D);
+
+ if (FAILED(hRes)) {
+ INTEL_DEBUG_ERROR("CreateTexture2D failed:%ld", hRes);
+ return MFX_ERR_MEMORY_ALLOC;
+ }
+
+ mids[i]->memIdStage = pTexture2D;
+ }
+ }
+
+ response->mids = (mfxMemId*)mids;
+ response->NumFrameActual = request->NumFrameSuggested;
+
+ return MFX_ERR_NONE;
}
static mfxStatus D3D11_SimpleAlloc(mfxHDL _pthis, mfxFrameAllocRequest *request, mfxFrameAllocResponse *response)
{
- tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
- mfxStatus sts = MFX_ERR_NONE;
- int idx = (MFX_MEMTYPE_FROM_DECODE & request->Type) ? 1 : 0;
-
- if (request->NumFrameSuggested <= pthis->D3D11SavedAllocResponses[idx].NumFrameActual &&
- MFX_MEMTYPE_EXTERNAL_FRAME & request->Type &&
- MFX_MEMTYPE_FROM_DECODE & request->Type &&
- pthis->D3D11SavedAllocResponses[idx].NumFrameActual != 0)
- {
- // Memory for this request was already allocated during manual allocation stage. Return saved response
- // When decode acceleration device (DXVA) is created it requires a list of d3d surfaces to be passed.
- // Therefore Media SDK will ask for the surface info/mids again at Init() stage, thus requiring us to return the saved response
- // (No such restriction applies to Encode or VPP)
-
- *response = pthis->D3D11SavedAllocResponses[idx];
- }
- else
- {
- sts = _D3D11_SimpleAlloc(_pthis, request, response);
- pthis->D3D11SavedAllocResponses[idx] = *response;
- }
-
- return sts;
+ tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
+ mfxStatus sts = MFX_ERR_NONE;
+ int idx = (MFX_MEMTYPE_FROM_DECODE & request->Type) ? 1 : 0;
+
+ if (request->NumFrameSuggested <= pthis->D3D11SavedAllocResponses[idx].NumFrameActual &&
+ MFX_MEMTYPE_EXTERNAL_FRAME & request->Type &&
+ MFX_MEMTYPE_FROM_DECODE & request->Type &&
+ pthis->D3D11SavedAllocResponses[idx].NumFrameActual != 0) {
+ // Memory for this request was already allocated during manual allocation stage. Return saved response
+ // When decode acceleration device (DXVA) is created it requires a list of d3d surfaces to be passed.
+ // Therefore Media SDK will ask for the surface info/mids again at Init() stage, thus requiring us to return the saved response
+ // (No such restriction applies to Encode or VPP)
+
+ *response = pthis->D3D11SavedAllocResponses[idx];
+ }
+ else {
+ sts = _D3D11_SimpleAlloc(_pthis, request, response);
+ pthis->D3D11SavedAllocResponses[idx] = *response;
+ }
+
+ return sts;
}
static mfxStatus D3D11_SimpleLock(mfxHDL _pthis, mfxMemId mid, mfxFrameData *ptr)
{
- HRESULT hRes = S_OK;
- tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
-
- D3D11_TEXTURE2D_DESC desc = { 0 };
- D3D11_MAPPED_SUBRESOURCE lockedRect = { 0 };
-
- CustomMemId* memId = (CustomMemId*)mid;
- ID3D11Texture2D* pSurface = (ID3D11Texture2D *)memId->memId;
- ID3D11Texture2D* pStage = (ID3D11Texture2D *)memId->memIdStage;
-
- D3D11_MAP mapType = D3D11_MAP_READ;
- UINT mapFlags = D3D11_MAP_FLAG_DO_NOT_WAIT;
-
- if (NULL == pStage)
- {
- hRes = pthis->pD3D11Ctx->Map(pSurface, 0, mapType, mapFlags, &lockedRect);
- desc.Format = DXGI_FORMAT_P8;
- }
- else
- {
- pSurface->GetDesc(&desc);
-
- // copy data only in case of user wants o read from stored surface
- if (memId->rw & D3D11_WILL_READ)
- {
- pthis->pD3D11Ctx->CopySubresourceRegion(pStage, 0, 0, 0, 0, pSurface, 0, NULL);
- }
-
- do
- {
- hRes = pthis->pD3D11Ctx->Map(pStage, 0, mapType, mapFlags, &lockedRect);
- if (S_OK != hRes && DXGI_ERROR_WAS_STILL_DRAWING != hRes)
- {
- return MFX_ERR_LOCK_MEMORY;
- }
- } while (DXGI_ERROR_WAS_STILL_DRAWING == hRes);
- }
-
- if (FAILED(hRes))
- {
- return MFX_ERR_LOCK_MEMORY;
- }
-
- switch (desc.Format)
- {
- case DXGI_FORMAT_NV12:
- ptr->Pitch = (mfxU16)lockedRect.RowPitch;
- ptr->Y = (mfxU8 *)lockedRect.pData;
- ptr->U = (mfxU8 *)lockedRect.pData + desc.Height * lockedRect.RowPitch;
- ptr->V = ptr->U + 1;
- break;
- case DXGI_FORMAT_B8G8R8A8_UNORM:
- ptr->Pitch = (mfxU16)lockedRect.RowPitch;
- ptr->B = (mfxU8 *)lockedRect.pData;
- ptr->G = ptr->B + 1;
- ptr->R = ptr->B + 2;
- ptr->A = ptr->B + 3;
- break;
- case DXGI_FORMAT_P8:
- ptr->Pitch = (mfxU16)lockedRect.RowPitch;
- ptr->Y = (mfxU8 *)lockedRect.pData;
- ptr->U = 0;
- ptr->V = 0;
- break;
- default:
- return MFX_ERR_LOCK_MEMORY;
- }
-
- return MFX_ERR_NONE;
+ HRESULT hRes = S_OK;
+ tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
+
+ D3D11_TEXTURE2D_DESC desc = { 0 };
+ D3D11_MAPPED_SUBRESOURCE lockedRect = { 0 };
+
+ CustomMemId* memId = (CustomMemId*)mid;
+ ID3D11Texture2D* pSurface = (ID3D11Texture2D *)memId->memId;
+ ID3D11Texture2D* pStage = (ID3D11Texture2D *)memId->memIdStage;
+
+ D3D11_MAP mapType = D3D11_MAP_READ;
+ UINT mapFlags = D3D11_MAP_FLAG_DO_NOT_WAIT;
+
+ if (NULL == pStage) {
+ hRes = pthis->pD3D11Ctx->Map(pSurface, 0, mapType, mapFlags, &lockedRect);
+ desc.Format = DXGI_FORMAT_P8;
+ }
+ else {
+ pSurface->GetDesc(&desc);
+
+ // copy data only in case of user wants o read from stored surface
+ if (memId->rw & D3D11_WILL_READ) {
+ pthis->pD3D11Ctx->CopySubresourceRegion(pStage, 0, 0, 0, 0, pSurface, 0, NULL);
+ }
+
+ do {
+ hRes = pthis->pD3D11Ctx->Map(pStage, 0, mapType, mapFlags, &lockedRect);
+ if (S_OK != hRes && DXGI_ERROR_WAS_STILL_DRAWING != hRes) {
+ return MFX_ERR_LOCK_MEMORY;
+ }
+ }
+ while (DXGI_ERROR_WAS_STILL_DRAWING == hRes);
+ }
+
+ if (FAILED(hRes)) {
+ return MFX_ERR_LOCK_MEMORY;
+ }
+
+ switch (desc.Format) {
+ case DXGI_FORMAT_NV12:
+ ptr->Pitch = (mfxU16)lockedRect.RowPitch;
+ ptr->Y = (mfxU8 *)lockedRect.pData;
+ ptr->U = (mfxU8 *)lockedRect.pData + desc.Height * lockedRect.RowPitch;
+ ptr->V = ptr->U + 1;
+ break;
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ ptr->Pitch = (mfxU16)lockedRect.RowPitch;
+ ptr->B = (mfxU8 *)lockedRect.pData;
+ ptr->G = ptr->B + 1;
+ ptr->R = ptr->B + 2;
+ ptr->A = ptr->B + 3;
+ break;
+ case DXGI_FORMAT_P8:
+ ptr->Pitch = (mfxU16)lockedRect.RowPitch;
+ ptr->Y = (mfxU8 *)lockedRect.pData;
+ ptr->U = 0;
+ ptr->V = 0;
+ break;
+ default:
+ return MFX_ERR_LOCK_MEMORY;
+ }
+
+ return MFX_ERR_NONE;
}
static mfxStatus D3D11_SimpleUnlock(mfxHDL _pthis, mfxMemId mid, mfxFrameData *ptr)
{
- tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
-
- CustomMemId* memId = (CustomMemId*)mid;
- ID3D11Texture2D* pSurface = (ID3D11Texture2D *)memId->memId;
- ID3D11Texture2D* pStage = (ID3D11Texture2D *)memId->memIdStage;
-
- if (NULL == pStage)
- {
- pthis->pD3D11Ctx->Unmap(pSurface, 0);
- }
- else
- {
- pthis->pD3D11Ctx->Unmap(pStage, 0);
- // copy data only in case of user wants to write to stored surface
- if (memId->rw & D3D11_WILL_WRITE)
- {
- pthis->pD3D11Ctx->CopySubresourceRegion(pSurface, 0, 0, 0, 0, pStage, 0, NULL);
- }
- }
-
- if (ptr)
- {
- ptr->Pitch = 0;
- ptr->U = ptr->V = ptr->Y = 0;
- ptr->A = ptr->R = ptr->G = ptr->B = 0;
- }
-
- return MFX_ERR_NONE;
+ tdav_codec_h264_intel_t* pthis = (tdav_codec_h264_intel_t*)_pthis;
+
+ CustomMemId* memId = (CustomMemId*)mid;
+ ID3D11Texture2D* pSurface = (ID3D11Texture2D *)memId->memId;
+ ID3D11Texture2D* pStage = (ID3D11Texture2D *)memId->memIdStage;
+
+ if (NULL == pStage) {
+ pthis->pD3D11Ctx->Unmap(pSurface, 0);
+ }
+ else {
+ pthis->pD3D11Ctx->Unmap(pStage, 0);
+ // copy data only in case of user wants to write to stored surface
+ if (memId->rw & D3D11_WILL_WRITE) {
+ pthis->pD3D11Ctx->CopySubresourceRegion(pSurface, 0, 0, 0, 0, pStage, 0, NULL);
+ }
+ }
+
+ if (ptr) {
+ ptr->Pitch = 0;
+ ptr->U = ptr->V = ptr->Y = 0;
+ ptr->A = ptr->R = ptr->G = ptr->B = 0;
+ }
+
+ return MFX_ERR_NONE;
}
static mfxStatus D3D11_SimpleGethdl(mfxHDL _pthis, mfxMemId mid, mfxHDL *handle)
{
- _pthis;
- if (NULL == handle)
- {
- return MFX_ERR_INVALID_HANDLE;
- }
+ _pthis;
+ if (NULL == handle) {
+ return MFX_ERR_INVALID_HANDLE;
+ }
- mfxHDLPair* pPair = (mfxHDLPair*)handle;
- CustomMemId* memId = (CustomMemId*)mid;
+ mfxHDLPair* pPair = (mfxHDLPair*)handle;
+ CustomMemId* memId = (CustomMemId*)mid;
- pPair->first = memId->memId; // surface texture
- pPair->second = 0;
+ pPair->first = memId->memId; // surface texture
+ pPair->second = 0;
- return MFX_ERR_NONE;
+ return MFX_ERR_NONE;
}
static mfxStatus D3D11_SimpleFree(mfxHDL _pthis, mfxFrameAllocResponse *response)
{
- _pthis;
- if (NULL == response)
- {
- return MFX_ERR_NULL_PTR;
- }
-
- if (response->mids)
- {
- for (mfxU32 i = 0; i < response->NumFrameActual; i++)
- {
- if (response->mids[i])
- {
- CustomMemId* mid = (CustomMemId*)response->mids[i];
- ID3D11Texture2D* pSurface = (ID3D11Texture2D *)mid->memId;
- ID3D11Texture2D* pStage = (ID3D11Texture2D *)mid->memIdStage;
- if (pSurface)
- {
- pSurface->Release();
- }
- if (pStage)
- {
- pStage->Release();
- }
- delete mid;
- }
- }
- }
-
- delete[] response->mids;
- response->mids = 0;
-
- return MFX_ERR_NONE;
+ _pthis;
+ if (NULL == response) {
+ return MFX_ERR_NULL_PTR;
+ }
+
+ if (response->mids) {
+ for (mfxU32 i = 0; i < response->NumFrameActual; i++) {
+ if (response->mids[i]) {
+ CustomMemId* mid = (CustomMemId*)response->mids[i];
+ ID3D11Texture2D* pSurface = (ID3D11Texture2D *)mid->memId;
+ ID3D11Texture2D* pStage = (ID3D11Texture2D *)mid->memIdStage;
+ if (pSurface) {
+ pSurface->Release();
+ }
+ if (pStage) {
+ pStage->Release();
+ }
+ delete mid;
+ }
+ }
+ }
+
+ delete[] response->mids;
+ response->mids = 0;
+
+ return MFX_ERR_NONE;
}
#endif /* INTEL_DX11_D3D */
OpenPOWER on IntegriCloud