调用CoCreateInstance创建H.264解码器遇链接错误及MFTEnum问题求助
问题描述
尝试使用H.264视频解码器创建MP4解码器时,调用CoCreateInstance()使用CLSID_CMSH264DecoderMFT出现链接错误:
unresolved external symbol CLSID_CMSH264DecoderMFT
系统C:\Windows\System32目录下存在msmpeg2vdec.dll,尝试替换该文件未成功。
当前链接的库:
Urlmon.lib Mfreadwrite.lib mf.lib mfplat.lib mfuuid.lib strmiids.lib Ole32.lib Uuid.lib
当前包含的头文件:
#include <windows.h> #include <mfapi.h> #include <mfplay.h> #include <mfobjects.h> #include <mfidl.h> #include <mfreadwrite.h> #include <d3d9.h> #include <objbase.h> #include <iostream> #include <vector> #include <dshow.h> #include <initguid.h> #include <wmcodecdsp.h> // <- contains CLSID_CMSH264DecoderMFT #include <stdio.h>
已尝试操作
- 执行
regsvr32 MSMPEG2VDEC.DLL - 修改链接库配置
- 使用
MFTEnum查找解码器,但调用IMFTransform::SetOutputType时失败
使用MFTEnum的代码(最后一行cout触发失败):
MFT_REGISTER_TYPE_INFO tyin = {}; tyin.guidMajorType = MFMediaType_Video; tyin.guidSubtype = MFVideoFormat_H264; MFT_REGISTER_TYPE_INFO tyout = {}; tyout.guidMajorType = MFMediaType_Video; tyout.guidSubtype = MFVideoFormat_NV12; CLSID* clsid_arr=0; UINT32 clsid_arr_count; hr = MFTEnum( MFT_CATEGORY_VIDEO_DECODER, 0, &tyin, &tyout, 0, &clsid_arr, &clsid_arr_count ); // finds 1 IMFTransform* pDecoder=0; CoCreateInstance(clsid_arr[0], NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDecoder)); IMFMediaType* type = 0; MFCreateMediaType(&type); type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); hr = pDecoder->SetInputType(0, type, 0); IMFMediaType* pOutputAttributes = 0; MFCreateMediaType(&pOutputAttributes); pOutputAttributes->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); pOutputAttributes->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12); hr = pDecoder->SetOutputType(0, pOutputAttributes, 0); if (FAILED(hr)) { std::cout << "Failed SetOutputType\n"; }
解决方案
一、解决CLSID_CMSH264DecoderMFT链接错误
- 添加缺失的链接库:
CLSID_CMSH264DecoderMFT的定义在wmcodecdsp.lib中,当前链接库列表未包含该文件,需将wmcodecdsp.lib加入链接依赖。 - 停止替换系统DLL:第三方网站下载的DLL会导致兼容性问题,甚至系统故障,直接使用系统自带的
msmpeg2vdec.dll即可——该组件是MFT,无需注册,regsvr32操作无效。 - 确认头文件顺序:你的代码中
<initguid.h>已经在<wmcodecdsp.h>之前包含,这一步没问题,该顺序会生成GUID的定义而非声明,避免链接报错。
二、解决SetOutputType失败问题
SetOutputType失败通常是因为输入媒体类型缺少关键参数,解码器无法确定匹配的输出格式,修正步骤如下:
- 补充完整的输入媒体类型:仅指定主类型和子类型不够,需添加视频分辨率、帧率、SPS/PPS等H.264必要参数,示例代码:
// 设置输入类型关键参数(替换为实际视频的参数) type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); // 设置分辨率(以1920x1080为例) MFSetAttributeSize(type, MF_MT_FRAME_SIZE, 1920, 1080); // 设置帧率(以30fps为例) MFSetAttributeRatio(type, MF_MT_FRAME_RATE, 30, 1); // 设置H.264的SPS/PPS数据(从实际码流中提取) BYTE sps_pps[] = { /* 此处填入实际的SPS和PPS字节数据 */ }; type->SetBlob(MF_MT_MPEG_SEQUENCE_HEADER, sps_pps, sizeof(sps_pps)); hr = pDecoder->SetInputType(0, type, 0); if (FAILED(hr)) { /* 处理输入类型设置错误 */ }
- 让解码器协商输出类型:不要直接指定输出类型,而是调用
GetOutputAvailableType获取解码器支持的输出类型后再设置,示例:
IMFMediaType* pOutputType = nullptr; hr = pDecoder->GetOutputAvailableType(0, 0, &pOutputType); if (SUCCEEDED(hr)) { hr = pDecoder->SetOutputType(0, pOutputType, 0); pOutputType->Release(); } if (FAILED(hr)) { std::cout << "Failed SetOutputType\n"; }
- 调整MFTEnum参数:调用
MFTEnum时可将输出类型参数设为NULL,避免过滤掉潜在支持的解码器,再根据实际需求选择合适的CLSID。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

