Search code examples
winapidll

Linker error trying to create H.264 decoder with CoCreateInstance()


Problem

I'm trying to create an MP4 decoder using the H.264 Video Decoder. I can not use CLSID_CMSH264DecoderMFT in my call to CoCreateInstance() because I get a linker error:

unresolved external symbol CLSID_CMSH264DecoderMFT

Inside C:\Windows\System32 I do have msmpeg2vdec.dll. I tried downloading another one from here but I can't replace the original, it doesn't let me.

These are the libraries I link with:

Urlmon.lib
Mfreadwrite.lib
mf.lib
mfplat.lib
mfuuid.lib
strmiids.lib
Ole32.lib
Uuid.lib

These are my includes:

#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>

What I tried

  • regsvr32 MSMPEG2VDEC.DLL
  • modifying my linked libraries
  • Using MFTEnum to find decoders, but it fails on IMFTransform::SetOutputType

This is the code when using MFTEnum that fails on the last 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";
}

Solution

  • CLSID_CMSH264DecoderMFT is declared as extern in wmcodecdsp.h. The linker is complaining that it can't find a definition of that CLSID value anywhere, such as in a .lib file, hence the error.

    In this situation, you need to link with wmcodecdspuuid.lib.

    Alternatively, you can simply define the value directly in your own code, eg:

    const CLSID CLSID_CMSH264DecoderMFT = {0x62CE7E72, 0x4C71, 0x4d20, {0xB1, 0x5D, 0x45, 0x28, 0x31, 0xA8, 0x7D, 0x9D}};