mfxStatus IntelDecoder::FlushDecoderAndRender() { mfxStatus sts = MFX_ERR_NONE; mfxGetTime(&tStart); // // Stage 2: Retrieve the buffered decoded frames // while (MFX_ERR_NONE <= sts || MFX_ERR_MORE_SURFACE == sts) { if (MFX_WRN_DEVICE_BUSY == sts) MSDK_SLEEP(1); // Wait if device is busy, then repeat the same call to DecodeFrameAsync nIndex = GetFreeSurfaceIndex(pmfxSurfaces, numSurfaces); // Find free frame surface MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, nIndex, MFX_ERR_MEMORY_ALLOC); // Decode a frame asychronously (returns immediately) sts = mfxDEC->DecodeFrameAsync(NULL, pmfxSurfaces[nIndex], &pmfxOutSurface, &syncp); // Ignore warnings if output is available, // if no output and no action required just repeat the DecodeFrameAsync call if (MFX_ERR_NONE < sts && syncp) sts = MFX_ERR_NONE; if (MFX_ERR_NONE == sts) sts = pSession->SyncOperation(syncp, 60000); // Synchronize. Waits until decoded frame is ready if (MFX_ERR_NONE == sts) { ++nFrame; if (impl_type == MFX_IMPL_SOFTWARE) { outMan.Render(pmfxOutSurface); } else { // Surface locking required when read/write D3D surfaces sts = pMfxAllocator->Lock(pMfxAllocator->pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)); MSDK_BREAK_ON_ERROR(sts); outMan.Render(pmfxOutSurface); sts = pMfxAllocator->Unlock(pMfxAllocator->pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)); } printf("Frame number: %d\r", nFrame); fflush(stdout); } } // MFX_ERR_MORE_DATA indicates that all buffers has been fetched, exit in case of other errors MSDK_IGNORE_MFX_STS(sts, MFX_ERR_MORE_DATA); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); mfxGetTime(&tEnd); elapsed += TimeDiffMsec(tEnd, tStart) / 1000; double fps = ((double)nFrame / elapsed); printf("\nExecution time: %3.2f s (%3.2f fps)\n", elapsed, fps); return sts; }
mfxStatus Rotate::FreeResources(mfxThreadTask task, mfxStatus sts) { MSDK_CHECK_ERROR(m_bInited, false, MFX_ERR_NOT_INITIALIZED); MSDK_CHECK_POINTER(m_pmfxCore, MFX_ERR_NOT_INITIALIZED); RotateTask *current_task = (RotateTask *)task; m_pmfxCore->DecreaseReference(m_pmfxCore->pthis, &(current_task->In->Data)); m_pmfxCore->DecreaseReference(m_pmfxCore->pthis, &(current_task->Out->Data)); MSDK_SAFE_DELETE(current_task->pProcessor); current_task->bBusy = false; return MFX_ERR_NONE; }
mfxStatus Rotate::Execute(mfxThreadTask task, mfxU32 uid_p, mfxU32 uid_a) { MSDK_CHECK_ERROR(m_bInited, false, MFX_ERR_NOT_INITIALIZED); MSDK_CHECK_POINTER(m_pmfxCore, MFX_ERR_NOT_INITIALIZED); mfxStatus sts = MFX_ERR_NONE; RotateTask *current_task = (RotateTask *)task; if (uid_a < 1) { // there's data to process sts = current_task->pProcessor->Process(&m_pChunks[uid_a]); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); } return MFX_TASK_DONE; }
mfxStatus CRendererPipeline::Run(unsigned char*pData, int nLen) { mfxStatus sts = MFX_ERR_NONE; mfxFrameSurface1* pSurf = NULL; // dispatching pointer mfxU16 nEncSurfIdx = 0; // index of free surface for encoder input (vpp output) sts = MFX_ERR_NONE; nEncSurfIdx = GetFreeSurface(m_pEncSurfaces, m_EncResponse.NumFrameActual); MSDK_CHECK_ERROR(nEncSurfIdx, MSDK_INVALID_SURF_IDX, MFX_ERR_MEMORY_ALLOC); // point pSurf to encoder surface pSurf = &m_pEncSurfaces[nEncSurfIdx]; { // get YUV pointers sts = m_pMFXAllocator->Lock(m_pMFXAllocator->pthis, pSurf->Data.MemId, &(pSurf->Data)); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); } pSurf->Info.FrameId.ViewId = 0; sts = LoadNextFrame(pSurf, pData, nLen); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); // ... after we're done call Unlock { sts = m_pMFXAllocator->Unlock(m_pMFXAllocator->pthis, pSurf->Data.MemId, &(pSurf->Data)); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); } if (D3D11_MEMORY != m_memType) { RenderFrame(pSurf, m_pMFXAllocator); } return sts; }
mfxStatus IntelDecoder::RunDecodeAndRender() { mfxStatus sts = MFX_ERR_NONE; // =============================================================== // Start decoding the frames from the stream // mfxGetTime(&tStart); pmfxOutSurface = NULL; pmfxOutSurface_sw = NULL; nIndex = 0; nIndex2 = 0; nFrame = 0; // // Stage 1: Main decoding loop // while (MFX_ERR_NONE <= sts || MFX_ERR_MORE_DATA == sts || MFX_ERR_MORE_SURFACE == sts) { if (MFX_WRN_DEVICE_BUSY == sts) MSDK_SLEEP(1); // Wait if device is busy, then repeat the same call to DecodeFrameAsync if (MFX_ERR_MORE_DATA == sts) { sts = ReadBitStreamData(&mfxBS, fSource); // Read more data into input bit stream MSDK_BREAK_ON_ERROR(sts); } if (MFX_ERR_MORE_SURFACE == sts || MFX_ERR_NONE == sts) { nIndex = GetFreeSurfaceIndex(pmfxSurfaces, numSurfaces); // Find free frame surface MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, nIndex, 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 sts = mfxDEC->DecodeFrameAsync(&mfxBS, pmfxSurfaces[nIndex], &pmfxOutSurface, &syncp); // Ignore warnings if output is available, // if no output and no action required just repeat the DecodeFrameAsync call if (MFX_ERR_NONE < sts && syncp) sts = MFX_ERR_NONE; if (MFX_ERR_NONE == sts) sts = pSession->SyncOperation(syncp, 60000); // Synchronize. Wait until decoded frame is ready if (MFX_ERR_NONE == sts) { ++nFrame; if (impl_type == MFX_IMPL_SOFTWARE) { outMan.Render(pmfxOutSurface); } else { // Surface locking required when read/write video surfaces sts = pMfxAllocator->Lock(pMfxAllocator->pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)); MSDK_BREAK_ON_ERROR(sts); outMan.Render(pmfxOutSurface); sts = pMfxAllocator->Unlock(pMfxAllocator->pthis, pmfxOutSurface->Data.MemId, &(pmfxOutSurface->Data)); MSDK_BREAK_ON_ERROR(sts); } printf("Frame number: %d\r", nFrame); fflush(stdout); } } // MFX_ERR_MORE_DATA means that file has ended, need to go to buffering loop, exit in case of other errors MSDK_IGNORE_MFX_STS(sts, MFX_ERR_MORE_DATA); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); mfxGetTime(&tEnd); elapsed = TimeDiffMsec(tEnd, tStart) / 1000; double fps = ((double)nFrame / elapsed); printf("\nExecution time: %3.2f s (%3.2f fps)\n", elapsed, fps); return sts; }
mfxStatus Rotate::Submit(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task) { MSDK_CHECK_POINTER(in, MFX_ERR_NULL_PTR); MSDK_CHECK_POINTER(out, MFX_ERR_NULL_PTR); MSDK_CHECK_POINTER(*in, MFX_ERR_NULL_PTR); MSDK_CHECK_POINTER(*out, MFX_ERR_NULL_PTR); MSDK_CHECK_POINTER(task, MFX_ERR_NULL_PTR); MSDK_CHECK_NOT_EQUAL(in_num, 1, MFX_ERR_UNSUPPORTED); MSDK_CHECK_NOT_EQUAL(out_num, 1, MFX_ERR_UNSUPPORTED); MSDK_CHECK_POINTER(m_pmfxCore, MFX_ERR_NOT_INITIALIZED); MSDK_CHECK_ERROR(m_bInited, false, MFX_ERR_NOT_INITIALIZED); mfxFrameSurface1 *surface_in = (mfxFrameSurface1 *)in[0]; mfxFrameSurface1 *surface_out = (mfxFrameSurface1 *)out[0]; mfxFrameSurface1 *real_surface_in = surface_in; mfxFrameSurface1 *real_surface_out = surface_out; mfxStatus sts = MFX_ERR_NONE; if (m_bIsInOpaque) { sts = m_pmfxCore->GetRealSurface(m_pmfxCore->pthis, surface_in, &real_surface_in); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, MFX_ERR_MEMORY_ALLOC); } if (m_bIsOutOpaque) { sts = m_pmfxCore->GetRealSurface(m_pmfxCore->pthis, surface_out, &real_surface_out); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, MFX_ERR_MEMORY_ALLOC); } // check validity of parameters sts = CheckInOutFrameInfo(&real_surface_in->Info, &real_surface_out->Info); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); mfxU32 ind = FindFreeTaskIdx(); if (ind >= m_MaxNumTasks) { return MFX_WRN_DEVICE_BUSY; // currently there are no free tasks available } m_pmfxCore->IncreaseReference(m_pmfxCore->pthis, &(real_surface_in->Data)); m_pmfxCore->IncreaseReference(m_pmfxCore->pthis, &(real_surface_out->Data)); m_pTasks[ind].In = real_surface_in; m_pTasks[ind].Out = real_surface_out; m_pTasks[ind].bBusy = true; switch (m_Param.Angle) { case 180: if (m_bOpenCLSurfaceSharing) { m_pTasks[ind].pProcessor = new OpenCLFilterRotator180(m_OpenCLFilter.get()); } else { m_pTasks[ind].pProcessor = new OpenCLRotator180(m_pOpenCLRotator180Context.get()); } MSDK_CHECK_POINTER(m_pTasks[ind].pProcessor, MFX_ERR_MEMORY_ALLOC); break; default: return MFX_ERR_UNSUPPORTED; } m_pTasks[ind].pProcessor->SetAllocator(m_pAlloc); m_pTasks[ind].pProcessor->Init(real_surface_in, real_surface_out); *task = (mfxThreadTask)&m_pTasks[ind]; return MFX_ERR_NONE; }