bool MSDKBase::CreateSessionAllocator(VADisplay* pVaDpy) { mfxStatus sts = MFX_ERR_NONE; GeneralAllocator* pAllocator = new GeneralAllocator; if (!pAllocator) { FRMW_TRACE_ERROR("Create allocator failed\n"); return false; } sts = pAllocator->Init(pVaDpy); if (MFX_ERR_NONE != sts) { FRMW_TRACE_ERROR("Init allocator failed\n"); delete pAllocator; return false; } MFXVideoSession* pSession = CreateSession(*pVaDpy); if (!pSession) { FRMW_TRACE_ERROR("Init session failed\n"); delete pAllocator; return false; } sts = pSession->SetFrameAllocator(pAllocator); if (MFX_ERR_NONE != sts) { FRMW_TRACE_ERROR("Set frame allocator failed\n"); delete pAllocator; CloseSession(pSession); return false; } m_pSession = pSession; m_pMfxAllocator = pAllocator; FRMW_TRACE_INFO("------Create session and set its initialized MFXFrameAllocator.\n"); return true; }
mfxStatus Launcher::Init(int argc, msdk_char *argv[]) { mfxStatus sts; mfxU32 i = 0; SafetySurfaceBuffer* pBuffer = NULL; mfxU32 BufCounter = 0; mfxHDL hdl = NULL; sInputParams InputParams; //parent transcode pipeline CTranscodingPipeline *pParentPipeline = NULL; // source transcode pipeline use instead parent in heterogeneous pipeline CTranscodingPipeline *pSinkPipeline = NULL; // parse input par file sts = m_parser.ParseCmdLine(argc, argv); MSDK_CHECK_PARSE_RESULT(sts, MFX_ERR_NONE, sts); // get parameters for each session from parser while(m_parser.GetNextSessionParams(InputParams)) { m_InputParamsArray.push_back(InputParams); InputParams.Reset(); } // check correctness of input parameters sts = VerifyCrossSessionsOptions(); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); #if defined(_WIN32) || defined(_WIN64) if (m_eDevType == MFX_HANDLE_D3D9_DEVICE_MANAGER) { m_pAllocParam.reset(new D3DAllocatorParams); m_hwdev.reset(new CD3D9Device()); /* The last param set in vector always describe VPP+ENCODE or Only VPP * So, if we want to do rendering we need to do pass HWDev to CTranscodingPipeline */ if (m_InputParamsArray[m_InputParamsArray.size() -1].eModeExt == VppCompOnly) { /* Rendering case */ sts = m_hwdev->Init(NULL, 1, MSDKAdapter::GetNumber() ); m_InputParamsArray[m_InputParamsArray.size() -1].m_hwdev = m_hwdev.get(); } else /* NO RENDERING*/ { sts = m_hwdev->Init(NULL, 0, MSDKAdapter::GetNumber() ); } MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); sts = m_hwdev->GetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER, (mfxHDL*)&hdl); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); // set Device Manager to external dx9 allocator D3DAllocatorParams *pD3DParams = dynamic_cast<D3DAllocatorParams*>(m_pAllocParam.get()); pD3DParams->pManager =(IDirect3DDeviceManager9*)hdl; } #if MFX_D3D11_SUPPORT else if (m_eDevType == MFX_HANDLE_D3D11_DEVICE) { m_pAllocParam.reset(new D3D11AllocatorParams); m_hwdev.reset(new CD3D11Device()); /* The last param set in vector always describe VPP+ENCODE or Only VPP * So, if we want to do rendering we need to do pass HWDev to CTranscodingPipeline */ if (m_InputParamsArray[m_InputParamsArray.size() -1].eModeExt == VppCompOnly) { /* Rendering case */ sts = m_hwdev->Init(NULL, 1, MSDKAdapter::GetNumber() ); m_InputParamsArray[m_InputParamsArray.size() -1].m_hwdev = m_hwdev.get(); } else /* NO RENDERING*/ { sts = m_hwdev->Init(NULL, 0, MSDKAdapter::GetNumber() ); } MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); sts = m_hwdev->GetHandle(MFX_HANDLE_D3D11_DEVICE, (mfxHDL*)&hdl); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); // set Device to external dx11 allocator D3D11AllocatorParams *pD3D11Params = dynamic_cast<D3D11AllocatorParams*>(m_pAllocParam.get()); pD3D11Params->pDevice =(ID3D11Device*)hdl; } #endif #elif defined(LIBVA_X11_SUPPORT) || defined(LIBVA_DRM_SUPPORT) if (m_eDevType == MFX_HANDLE_VA_DISPLAY) { m_pAllocParam.reset(new vaapiAllocatorParams); vaapiAllocatorParams *pVAAPIParams = dynamic_cast<vaapiAllocatorParams*>(m_pAllocParam.get()); /* The last param set in vector always describe VPP+ENCODE or Only VPP * So, if we want to do rendering we need to do pass HWDev to CTranscodingPipeline */ if (m_InputParamsArray[m_InputParamsArray.size() -1].eModeExt == VppCompOnly) { sInputParams& params = m_InputParamsArray[m_InputParamsArray.size() -1]; /* Rendering case */ m_hwdev.reset(CreateVAAPIDevice(params.libvaBackend)); if(!m_hwdev.get()) { msdk_printf(MSDK_STRING("error: failed to initialize VAAPI device\n")); return MFX_ERR_DEVICE_FAILED; } sts = m_hwdev->Init(¶ms.monitorType, 1, MSDKAdapter::GetNumber() ); if (params.libvaBackend == MFX_LIBVA_DRM_MODESET) { CVAAPIDeviceDRM* drmdev = dynamic_cast<CVAAPIDeviceDRM*>(m_hwdev.get()); pVAAPIParams->m_export_mode = vaapiAllocatorParams::CUSTOM_FLINK; pVAAPIParams->m_exporter = dynamic_cast<vaapiAllocatorParams::Exporter*>(drmdev->getRenderer()); } params.m_hwdev = m_hwdev.get(); } else /* NO RENDERING*/ { m_hwdev.reset(CreateVAAPIDevice()); if(!m_hwdev.get()) { msdk_printf(MSDK_STRING("error: failed to initialize VAAPI device\n")); return MFX_ERR_DEVICE_FAILED; } sts = m_hwdev->Init(NULL, 0, MSDKAdapter::GetNumber()); } MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); sts = m_hwdev->GetHandle(MFX_HANDLE_VA_DISPLAY, (mfxHDL*)&hdl); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); // set Device to external vaapi allocator pVAAPIParams->m_dpy =(VADisplay)hdl; } #endif if (!m_pAllocParam.get()) { m_pAllocParam.reset(new SysMemAllocatorParams); } // each pair of source and sink has own safety buffer sts = CreateSafetyBuffers(); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); /* One more hint. Example you have 3 dec + 1 enc sessions * (enc means vpp_comp call invoked. m_InputParamsArray.size() is 4. * You don't need take vpp comp params from last one session as it is enc session. * But you need process {0, 1, 2} sessions - totally 3. * So, you need start from 0 and end at 2. * */ for(mfxI32 jj = 0; jj<(mfxI32)m_InputParamsArray.size() - 1; jj++) { /* Save params for VPP composition */ sVppCompDstRect tempDstRect; tempDstRect.DstX = m_InputParamsArray[jj].nVppCompDstX; tempDstRect.DstY = m_InputParamsArray[jj].nVppCompDstY; tempDstRect.DstW = m_InputParamsArray[jj].nVppCompDstW; tempDstRect.DstH = m_InputParamsArray[jj].nVppCompDstH; m_VppDstRects.push_back(tempDstRect); } // create sessions, allocators for (i = 0; i < m_InputParamsArray.size(); i++) { GeneralAllocator* pAllocator = new GeneralAllocator; sts = pAllocator->Init(m_pAllocParam.get()); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); m_pAllocArray.push_back(pAllocator); std::auto_ptr<ThreadTranscodeContext> pThreadPipeline(new ThreadTranscodeContext); // extend BS processing init m_InputParamsArray[i].nTimeout == 0 ? m_pExtBSProcArray.push_back(new FileBitstreamProcessor) : m_pExtBSProcArray.push_back(new FileBitstreamProcessor_WithReset); pThreadPipeline->pPipeline.reset(CreatePipeline()); pThreadPipeline->pBSProcessor = m_pExtBSProcArray.back(); if (Sink == m_InputParamsArray[i].eMode) { /* N_to_1 mode */ if ((VppComp == m_InputParamsArray[i].eModeExt) || (VppCompOnly == m_InputParamsArray[i].eModeExt)) { // Taking buffers from tail because they are stored in m_pBufferArray in reverse order // So, by doing this we'll fill buffers properly according to order from par file pBuffer = m_pBufferArray[m_pBufferArray.size()-1-BufCounter]; BufCounter++; } else /* 1_to_N mode*/ { pBuffer = m_pBufferArray[m_pBufferArray.size() - 1]; } pSinkPipeline = pThreadPipeline->pPipeline.get(); sts = m_pExtBSProcArray.back()->Init(m_InputParamsArray[i].strSrcFile, NULL); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); } else if (Source == m_InputParamsArray[i].eMode) { /* N_to_1 mode */ if ((VppComp == m_InputParamsArray[i].eModeExt) || (VppCompOnly == m_InputParamsArray[i].eModeExt)) { pBuffer = m_pBufferArray[m_pBufferArray.size() - 1]; } else /* 1_to_N mode*/ { pBuffer = m_pBufferArray[BufCounter]; BufCounter++; } sts = m_pExtBSProcArray.back()->Init(NULL, m_InputParamsArray[i].strDstFile); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); } else { sts = m_pExtBSProcArray.back()->Init(m_InputParamsArray[i].strSrcFile, m_InputParamsArray[i].strDstFile); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); pBuffer = NULL; } /**/ /* Vector stored linearly in the memory !*/ m_InputParamsArray[i].pVppCompDstRects = m_VppDstRects.empty() ? NULL : &m_VppDstRects[0]; // if session has VPP plus ENCODE only (-i::source option) // use decode source session as input sts = MFX_ERR_MORE_DATA; if (Source == m_InputParamsArray[i].eMode) { sts = pThreadPipeline->pPipeline->Init(&m_InputParamsArray[i], m_pAllocArray[i], hdl, pSinkPipeline, pBuffer, m_pExtBSProcArray.back()); } else { sts = pThreadPipeline->pPipeline->Init(&m_InputParamsArray[i], m_pAllocArray[i], hdl, pParentPipeline, pBuffer, m_pExtBSProcArray.back()); } MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); if (!pParentPipeline && m_InputParamsArray[i].bIsJoin) pParentPipeline = pThreadPipeline->pPipeline.get(); // set the session's start status (like it is waiting) pThreadPipeline->startStatus = MFX_WRN_DEVICE_BUSY; // set other session's parameters pThreadPipeline->implType = m_InputParamsArray[i].libType; m_pSessionArray.push_back(pThreadPipeline.release()); mfxVersion ver = {{0, 0}}; sts = m_pSessionArray[i]->pPipeline->QueryMFXVersion(&ver); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); PrintInfo(i, &m_InputParamsArray[i], &ver); } for (i = 0; i < m_InputParamsArray.size(); i++) { sts = m_pSessionArray[i]->pPipeline->CompleteInit(); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); if (m_pSessionArray[i]->pPipeline->GetJoiningFlag()) msdk_printf(MSDK_STRING("Session %d was joined with other sessions\n"), i); else msdk_printf(MSDK_STRING("Session %d was NOT joined with other sessions\n"), i); } msdk_printf(MSDK_STRING("\n")); return sts; } // mfxStatus Launcher::Init()