硬件编解码(六)Intel提供的QuickSync使用样例(3)编码器初始化

编码器的初始化



    初始化的流程如下:

    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;
}


<think>好的,我现在需要帮助用户解决“无法初始化视频写入器”的问题。首先,我需要理解这个问题的可能原因。根据用户提供的引用内容,尤其是引用[1]中提到Qt程序无法找到第三方库的DLL文件,导致程序异常结束,这可能是一个关键点。视频写入器通常依赖于像FFmpeg这的第三方库,所以缺少相关DLL可能是问题所在。 接下来,我应该考虑其他可能的原因。如,用户是否正确安装了所需的编解码器?视频写入器可能需要特定的编码器,比如H.264或MPEG-4,如果这些编解码器没有正确安装或配置,初始化可能会失败。此外,权限问题也可能导致无法写入目标目录,特别是当程序没有管理员权限时,可能无法访问某些路径。 然后,检查文件路径是否正确也很重要。如果输出路径包含特殊字符或过长,或者目标文件夹不存在,都可能导致初始化失败。用户需要确保路径是有效的,并且程序有权限写入该目录。 另外,硬件兼容性也不能忽视。某些视频编码器可能需要特定的硬件加速支持,比如NVIDIA的NVENC或Intel的Quick Sync。如果用户的硬件不支持这些技术,或者驱动程序过时,也可能引发问题。 接下来,我应该根据这些可能的原因,逐步给出解决方案。首先检查FFmpeg等库的DLL是否存在,并确保它们位于系统路径或程序目录中。然后,验证编解码器的安装情况,确保所需的编码器可用。接着,检查输出路径的权限和有效性,必要时以管理员身份运行程序。如果问题依然存在,可能需要更新显卡驱动或检查硬件兼容性。 最后,用户可能还有其他问题,比如如何安装FFmpeg,如何配置Qt项目的依赖库路径,或者如何测试视频写入功能。因此,生成相关问题有助于用户进一步排查和解决问题。</think>要解决视频写入器初始化失败的问题,可以按照以下步骤排查和修复: ### 1. 检查第三方库依赖(如FFmpeg) - **确认DLL文件位置**:确保视频编码器依赖的第三方库(如FFmpeg的`avcodec-xx.dll`、`avformat-xx.dll`)已正确放置在以下位置: - 程序运行目录的`bin`或`lib`文件夹内 - 系统环境变量`PATH`包含的路径中 - Qt项目配置文件`.pro`中指定的库路径 - **验证库版本**:检查库的32/64位是否与程序编译平台一致[^1] ```python # 示:通过Python检测文件是否存在 import os dll_list = ["avcodec-59.dll", "avformat-59.dll"] for dll in dll_list: if not os.path.exists(dll): print(f"缺失关键文件:{dll}") ``` ### 2. 验证编解码器配置 - **检查支持的编码格式**:使用`ffmpeg -codecs`命令确认已安装目标编码器 - **设置正确的编码参数**: ```cpp // Qt示:设置H.264编码参数 QVideoEncoderSettings settings; settings.setCodec("video/H264"); settings.setResolution(1280, 720); settings.setFrameRate(30.0); ``` ### 3. 检查文件写入权限 - **目标目录权限**:确保程序有权限写入目标路径 - **路径规范验证**: - 使用绝对路径(如`D:/output/video.mp4`) - 避免特殊字符(`*?:<>|`) - 路径长度不超过260字符 ### 4. 硬件兼容性检查 | 检查项 | 验证方法 | |---------------------|----------------------------| | 显卡驱动版本 | 设备管理器查看显示适配器版本 | | 硬件加速支持 | FFmpeg命令`ffmpeg -hwaccels`| | 显存可用空间 | GPU-Z工具监测 | ### 5. 调试工具使用 - **附加调试器**:通过Visual Studio附加到进程调试[^3] - **日志输出**: ```cpp qDebug() << "视频写入器状态:" << mediaRecorder.status(); qDebug() << "错误信息:" << mediaRecorder.errorString(); ``` ### 6. 系统环境修复 - 通过注册表修改桌面路径后,可能需要重启生效[^2] - 执行系统初始化时保留应用程序配置(若使用品牌商恢复系统)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值