You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Media Foundation的MSS2编码器编码RGB32帧遇0xc00d5212错误求助

问题

使用Media Foundation的SinkWriter,通过Windows Media Video 9 Screen Encoder(MSS2)编码RGB32屏幕帧时,调用IMFSinkWriter::SetInputMediaType返回错误0xc00d5212(无合适的转换用于编码/解码内容)。已确认:

  • 包含必要头文件与库
  • System32目录存在WMVSENCD.DLL
  • 相同代码适配H264编码器与MP4容器时可正常运行

原始代码:

HRESULT MediaFoundationScreenRecorder::InitializeSinkWriter(IMFSinkWriter** ppWriter, DWORD* pStreamIndex)
{
    *ppWriter = NULL;
    *pStreamIndex = NULL;

    IMFSinkWriter* pSinkWriter = NULL;
    IMFMediaType* pMediaTypeOut = NULL;
    IMFMediaType* pMediaTypeIn = NULL;
    DWORD streamIndex;

    HRESULT hr = MFCreateSinkWriterFromURL(L"mfoutput.wmv", NULL, NULL, &pSinkWriter);

    hr |= MFCreateMediaType(&pMediaTypeOut);
    hr |= pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
    hr |= pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, MEDIASUBTYPE_MSS2);
    hr |= pMediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, 800000);
    hr |= pMediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
    hr |= MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, SCALED_VIDEO_WIDTH, SCALED_VIDEO_HEIGHT);
    hr |= MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, VIDEO_FPS, 1);
    hr |= MFSetAttributeRatio(pMediaTypeOut, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);

    hr |= pSinkWriter->AddStream(pMediaTypeOut, &streamIndex);

    hr |= MFCreateMediaType(&pMediaTypeIn);
    hr |= pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
    hr |= pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
    hr |= pMediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
    hr |= MFSetAttributeSize(pMediaTypeIn, MF_MT_FRAME_SIZE, SCALED_VIDEO_WIDTH, SCALED_VIDEO_HEIGHT);
    hr |= MFSetAttributeRatio(pMediaTypeIn, MF_MT_FRAME_RATE, VIDEO_FPS, 1);
    hr |= MFSetAttributeRatio(pMediaTypeIn, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);

    hr |= pSinkWriter->SetInputMediaType(streamIndex, pMediaTypeIn, NULL);

    hr |= pSinkWriter->BeginWriting();

    if (SUCCEEDED(hr))
    {
        *ppWriter = pSinkWriter;
        (*ppWriter)->AddRef();
        *pStreamIndex = streamIndex;
    }

    SafeRelease(&pSinkWriter);
    SafeRelease(&pMediaTypeOut);
    SafeRelease(&pMediaTypeIn);
    return hr;
}
解决办法

问题根源

MSS2编码器(WMVSENCD.DLL)本质是DirectShow架构组件,Media Foundation默认不会自动启用DirectShow与MF的桥接转换,导致无法匹配RGB32输入与MSS2编码器的需求,也无法正确识别该编码器作为MF组件。

具体修复步骤

  1. 启用Media Foundation的DirectShow桥接
    在创建SinkWriter前,配置属性存储以允许使用DirectShow编码器,修改MFCreateSinkWriterFromURL的调用逻辑:

    IMFAttributes* pAttrs = NULL;
    HRESULT hr = MFCreateAttributes(&pAttrs, 1);
    if (SUCCEEDED(hr))
    {
        hr = pAttrs->SetUINT32(MF_SINK_WRITER_ALLOW_DIRECTSHOW_ENCODERS, TRUE);
        if (SUCCEEDED(hr))
        {
            hr = MFCreateSinkWriterFromURL(L"mfoutput.wmv", NULL, pAttrs, &pSinkWriter);
        }
        SafeRelease(&pAttrs);
    }
    
  2. 调整输入媒体类型为编码器兼容格式
    MSS2的DirectShow版本通常不直接支持RGB32输入,需将输入类型改为YUV格式(如MFVideoFormat_YUY2),Media Foundation会自动添加RGB32到YUY2的转换:

    // 修改输入媒体类型的SUBTYPE
    hr |= pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2);
    
  3. 确保Media Foundation初始化正确
    程序启动时调用MFStartup,指定完整初始化模式:

    HRESULT hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
    

修改后的完整示例代码

HRESULT MediaFoundationScreenRecorder::InitializeSinkWriter(IMFSinkWriter** ppWriter, DWORD* pStreamIndex)
{
    *ppWriter = NULL;
    *pStreamIndex = NULL;

    IMFSinkWriter* pSinkWriter = NULL;
    IMFMediaType* pMediaTypeOut = NULL;
    IMFMediaType* pMediaTypeIn = NULL;
    IMFAttributes* pAttrs = NULL;
    DWORD streamIndex;
    HRESULT hr = S_OK;

    // 创建SinkWriter配置属性,允许DirectShow编码器
    hr = MFCreateAttributes(&pAttrs, 1);
    if (FAILED(hr)) goto done;

    hr = pAttrs->SetUINT32(MF_SINK_WRITER_ALLOW_DIRECTSHOW_ENCODERS, TRUE);
    if (FAILED(hr)) goto done;

    hr = MFCreateSinkWriterFromURL(L"mfoutput.wmv", NULL, pAttrs, &pSinkWriter);
    if (FAILED(hr)) goto done;

    // 配置输出媒体类型(MSS2)
    hr = MFCreateMediaType(&pMediaTypeOut);
    if (FAILED(hr)) goto done;

    hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
    hr |= pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, MEDIASUBTYPE_MSS2);
    hr |= pMediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, 800000);
    hr |= pMediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
    hr |= MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, SCALED_VIDEO_WIDTH, SCALED_VIDEO_HEIGHT);
    hr |= MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, VIDEO_FPS, 1);
    hr |= MFSetAttributeRatio(pMediaTypeOut, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
    if (FAILED(hr)) goto done;

    hr = pSinkWriter->AddStream(pMediaTypeOut, &streamIndex);
    if (FAILED(hr)) goto done;

    // 配置输入媒体类型(YUY2,替代RGB32)
    hr = MFCreateMediaType(&pMediaTypeIn);
    if (FAILED(hr)) goto done;

    hr = pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
    hr |= pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2); // 修改为YUY2
    hr |= pMediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
    hr |= MFSetAttributeSize(pMediaTypeIn, MF_MT_FRAME_SIZE, SCALED_VIDEO_WIDTH, SCALED_VIDEO_HEIGHT);
    hr |= MFSetAttributeRatio(pMediaTypeIn, MF_MT_FRAME_RATE, VIDEO_FPS, 1);
    hr |= MFSetAttributeRatio(pMediaTypeIn, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
    if (FAILED(hr)) goto done;

    hr = pSinkWriter->SetInputMediaType(streamIndex, pMediaTypeIn, NULL);
    if (FAILED(hr)) goto done;

    hr = pSinkWriter->BeginWriting();
    if (FAILED(hr)) goto done;

    // 输出结果
    *ppWriter = pSinkWriter;
    (*ppWriter)->AddRef();
    *pStreamIndex = streamIndex;

done:
    SafeRelease(&pAttrs);
    SafeRelease(&pSinkWriter);
    SafeRelease(&pMediaTypeOut);
    SafeRelease(&pMediaTypeIn);
    return hr;
}

内容的提问来源于stack exchange,提问作者m3tler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:08:11