使用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组件。
具体修复步骤
启用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); }调整输入媒体类型为编码器兼容格式
MSS2的DirectShow版本通常不直接支持RGB32输入,需将输入类型改为YUV格式(如MFVideoFormat_YUY2),Media Foundation会自动添加RGB32到YUY2的转换:// 修改输入媒体类型的SUBTYPE hr |= pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2);确保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
相关产品推荐
相关产品推荐

