编码器的初始化
初始化的流程如下:
1、文件读取器初始化
2、判断filereader是否可以把颜色格式从yv12转换成nv12,如果可以那么不需要创建视频预处理,否则的话需要创建视频预处理器来进行处理
3、初始化FileWriter
4、视频会话初始化
5、版本检查
6、用户自定义的滤镜(也就是插件,plugin)的初始化
7、创建内存分配器
8、初始化编码器参数
9、初始化vpp(视频预处理)参数
10、创建编码器对象MFXVideoENCODE,这是由Intel Media sdk提供的
11、如果有需要,那么就创建视频预处理器
12、其他处理
mfxStatus CEncodingPipeline::Init(sInputParams *pParams)
{
MSDK_CHECK_POINTER(pParams, MFX_ERR_NULL_PTR);
mfxStatus sts = MFX_ERR_NONE;
#if defined ENABLE_V4L2_SUPPORT
isV4L2InputEnabled = pParams->isV4L2InputEnabled;
#endif
if (!isV4L2InputEnabled)
{
// prepare input file reader
sts = m_FileReader.Init(pParams->InputFiles,
pParams->FileInputFourCC );
MSDK_CHECK_STATUS(sts, "m_FileReader.Init failed");
}
m_MVCflags = pParams->MVC_flags;
// FileReader can convert yv12->nv12 without vpp
// 文件读取器是否可以把颜色格式yv12转换成nv12,如果不可以那么需要创建视频预处理器,用他来进行处理
m_InputFourCC = (pParams->FileInputFourCC == MFX_FOURCC_YV12) ? MFX_FOURCC_NV12 : pParams->FileInputFourCC;
m_nTimeout = pParams->nTimeout;
sts = InitFileWriters(pParams);
MSDK_CHECK_STATUS(sts, "InitFileWriters failed");
mfxInitParam initPar;
mfxVersion version; // real API version with which library is initialized
MSDK_ZERO_MEMORY(initPar);
// we set version to 1.0 and later we will query actual version of the library which will got leaded
initPar.Version.Major = 1;
initPar.Version.Minor = 0;
initPar.GPUCopy = pParams->gpuCopy;
// Init session
if (pParams->bUseHWLib) {
// try searching on all display adapters
initPar.Implementation = MFX_IMPL_HARDWARE_ANY;
// if d3d11 surfaces are used ask the library to run acceleration through D3D11
// feature may be unsupported due to OS or MSDK API version
if (D3D11_MEMORY == pParams->memType)
initPar.Implementation |= MFX_IMPL_VIA_D3D11;
sts = m_mfxSession.InitEx(initPar);
// MSDK API version may not support multiple adapters - then try initialize on the default
if (MFX_ERR_NONE != sts) {
initPar.Implementation = (initPar.Implementation & !MFX_IMPL_HARDWARE_ANY) | MFX_IMPL_HARDWARE;
sts = m_mfxSession.InitEx(initPar);
}
} else {
initPar.Implementation = MFX_IMPL_SOFTWARE;
sts = m_mfxSession.InitEx(initPar);
}
MSDK_CHECK_STATUS(sts, "m_mfxSession.InitEx failed");
sts = MFXQueryVersion(m_mfxSession , &version); // get real API version of the loaded library
MSDK_CHECK_STATUS(sts, "MFXQueryVersion failed");
if ((pParams->MVC_flags & MVC_ENABLED) != 0 && !CheckVersion(&version, MSDK_FEATURE_MVC)) {
msdk_printf(MSDK_STRING("error: MVC is not supported in the %d.%d API version\n"),
version.Major, version.Minor);
return MFX_ERR_UNSUPPORTED;
}
if ((pParams->MVC_flags & MVC_VIEWOUTPUT) != 0 && !CheckVersion(&version, MSDK_FEATURE_MVC_VIEWOUTPUT)) {
msdk_printf(MSDK_STRING("error: MVC Viewoutput is not supported in the %d.%d API version\n"),
version.Major, version.Minor);
return MFX_ERR_UNSUPPORTED;
}
if ((pParams->CodecId == MFX_CODEC_JPEG) && !CheckVersion(&version, MSDK_FEATURE_JPEG_ENCODE)) {
msdk_printf(MSDK_STRING("error: Jpeg is not supported in the %d.%d API version\n"),
version.Major, version.Minor);
return MFX_ERR_UNSUPPORTED;
}
if ((pParams->nRateControlMethod == MFX_RATECONTROL_LA) && !CheckVersion(&version, MSDK_FEATURE_LOOK_AHEAD)) {
msdk_printf(MSDK_STRING("error: Look ahead is not supported in the %d.%d API version\n"),
version.Major, version.Minor);
return MFX_ERR_UNSUPPORTED;
}
if (CheckVersion(&version, MSDK_FEATURE_PLUGIN_API)) {
/* Here we actually define the following codec initialization scheme:
* 1. If plugin path or guid is specified: we load user-defined plugin (example: HEVC encoder plugin)
* 2. If plugin path not specified:
* 2.a) we check if codec is distributed as a mediasdk plugin and load it if yes
* 2.b) if codec is not in the list of mediasdk plugins, we assume, that it is supported inside mediasdk library
*/
if (pParams->pluginParams.type == MFX_PLUGINLOAD_TYPE_FILE && msdk_strnlen(pParams->pluginParams.strPluginPath,sizeof(pParams->pluginParams.strPluginPath)))
{
m_pUserModule.reset(new MFXVideoUSER(m_mfxSession));
m_pPlugin.reset(LoadPlugin(MFX_PLUGINTYPE_VIDEO_ENCODE, m_mfxSession, pParams->pluginParams.pluginGuid, 1, pParams->pluginParams.strPluginPath, (mfxU32)msdk_strnlen(pParams->pluginParams.strPluginPath,sizeof(pParams->pluginParams.strPluginPath))));
if (m_pPlugin.get() == NULL) sts = MFX_ERR_UNSUPPORTED;
}
else
{
if (AreGuidsEqual(pParams->pluginParams.pluginGuid, MSDK_PLUGINGUID_NULL))
{
mfxIMPL impl = pParams->bUseHWLib ? MFX_IMPL_HARDWARE : MFX_IMPL_SOFTWARE;
pParams->pluginParams.pluginGuid = msdkGetPluginUID(impl, MSDK_VENCODE, pParams->CodecId);
}
if (!AreGuidsEqual(pParams->pluginParams.pluginGuid, MSDK_PLUGINGUID_NULL))
{
m_pPlugin.reset(LoadPlugin(MFX_PLUGINTYPE_VIDEO_ENCODE, m_mfxSession, pParams->pluginParams.pluginGuid, 1));
if (m_pPlugin.get() == NULL) sts = MFX_ERR_UNSUPPORTED;
}
if(sts==MFX_ERR_UNSUPPORTED)
{
msdk_printf(MSDK_STRING("Default plugin cannot be loaded (possibly you have to define plugin explicitly)\n"));
}
}
MSDK_CHECK_STATUS(sts, "LoadPlugin failed");
}
// set memory type
m_memType = pParams->memType;
m_nMemBuffer = pParams->nMemBuf;
// create and init frame allocator
// 创建内存分配器
sts = CreateAllocator();
MSDK_CHECK_STATUS(sts, "CreateAllocator failed");
// 初始化编码器参数
sts = InitMfxEncParams(pParams);
MSDK_CHECK_STATUS(sts, "InitMfxEncParams failed");
// 初始化vpp(视频预处理)参数
sts = InitMfxVppParams(pParams);
MSDK_CHECK_STATUS(sts, "InitMfxVppParams failed");
// MVC specific options
if (MVC_ENABLED & m_MVCflags)
{
sts = AllocAndInitMVCSeqDesc();
MSDK_CHECK_STATUS(sts, "AllocAndInitMVCSeqDesc failed");
}
// create encoder
// 创建编码器对象
m_pmfxENC = new MFXVideoENCODE(m_mfxSession);
MSDK_CHECK_POINTER(m_pmfxENC, MFX_ERR_MEMORY_ALLOC);
// create preprocessor if resizing was requested from command line
// or if different FourCC is set in InitMfxVppParams
// 是否要进行预处理(格式转换什么的)
if (pParams->nWidth != pParams->nDstWidth ||
pParams->nHeight != pParams->nDstHeight ||
m_mfxVppParams.vpp.In.FourCC != m_mfxVppParams.vpp.Out.FourCC)
{
m_pmfxVPP = new MFXVideoVPP(m_mfxSession);
MSDK_CHECK_POINTER(m_pmfxVPP, MFX_ERR_MEMORY_ALLOC);
}
sts = ResetMFXComponents(pParams);
MSDK_CHECK_STATUS(sts, "ResetMFXComponents failed");
InitV4L2Pipeline(pParams);
m_nFramesToProcess = pParams->nNumFrames;
// If output isn't specified work in performance mode and do not insert idr
m_bCutOutput = pParams->dstFileBuff.size() ? !pParams->bUncut : false;
return MFX_ERR_NONE;
}