Media Foundation using C instead of C++

2019-03-06 08:49发布

问题:

I am learning to use the Media Foundation API from sample code shown in Microsoft website using C instead of C++. The sample code is shown below.

HRESULT CreateVideoCaptureDevice(IMFMediaSource **ppSource)
{
    *ppSource = NULL;

    UINT32 count = 0;

    IMFAttributes *pConfig = NULL;
    IMFActivate **ppDevices = NULL;

    // Create an attribute store to hold the search criteria.
    HRESULT hr = MFCreateAttributes(&pConfig, 1);

    // Request video capture devices.
    if (SUCCEEDED(hr))
    {
        hr = pConfig->SetGUID(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, 
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
            );
    }

    // Enumerate the devices,
    if (SUCCEEDED(hr))
    {
        hr = MFEnumDeviceSources(pConfig, &ppDevices, &count);
    }

    // Create a media source for the first device in the list.
    if (SUCCEEDED(hr))
    {
        if (count > 0)
        {
            hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(ppSource));
        }
        else
        {
            hr = MF_E_NOT_FOUND;
        }
    }

    for (DWORD i = 0; i < count; i++)
    {
        ppDevices[i]->Release();
    }
    CoTaskMemFree(ppDevices);
    return hr;
}

When I tried to build the sample code, I always get the following error:

error C2039: 'ActivateObject': is not a member of 'IMFActivate' error C2039: 'Release': is not a member of 'IMFActivate' error C2039: 'SetGUID': is not a member of 'IMFAttributes'

I explored the definition of IMFActivate and IMFAttributes (in mfidl.h) and I notice it have a C style interface.

May I know if anyone can show an example of how to use the interface ?

回答1:

You should be using COM interfaces defined "C style", using virtual method table pointer:

IMFActivate* pMfActivate = ...
IMFMediaSource* pMfMediaSource;
pMfActivate->lpVtbl->ActivateObject(
    pMfActivate, &IID_IMFMediaSource, (IUnknown**) &pMfMediaSource);

where C++ style is

IMFActivate* pMfActivate = ...
IMFMediaSource* pMfMediaSource;
pMfActivate->ActivateObject(
    __uuidof(IMFMediaSource), (IUnknown**) &pMfMediaSource);