ormike
ormike

Reputation: 13

MS Media Foundation - can't get IMFTransform interface to a H264 Encoder MFT object?

I'm getting started with MS Media Foundation and so I just entered in the code from Tutorial: Encoding an MP4 File. This uses the Source Resolver to create a media source and the MFCreateTranscodeTopology() function to create a topology including an H.264 encoder, as described in the reference.

Then I wanted to test my new understanding of the Media Foundation structures by analyzing the topology. I created the following function which I call from the example code immediately before their call to StartEncodingSession() in the tutorial.

HRESULT GetTopologyInfo(IMFTopology *pTopology)
{
    HRESULT hr = 0;
    WORD num_nodes = 0;

    hr = pTopology->GetNodeCount(&num_nodes);

    if (SUCCEEDED(hr))
    {
        for (WORD i = 0; i < num_nodes; i++)
        {

            IMFTopologyNode *pNode = NULL;
            IUnknown *pNodeObject = NULL;
            IMFAttributes  *pAttribute = NULL;
            IMFTransform *pTransform = NULL;
            MF_TOPOLOGY_TYPE type;
            hr = pTopology->GetNode(i, &pNode);

            if (SUCCEEDED(hr))
            {
                hr = pNode->GetNodeType(&type);

                // Get the node object's pointer.
                hr = pNode->GetObject(&pNodeObject);
                if (SUCCEEDED(hr))
                {
                    hr = pNodeObject->QueryInterface(IID_PPV_ARGS(&pAttribute));
                    if (SUCCEEDED(hr))
                    {
                        GUID guid;
                        LPWSTR szGuid = NULL;
                        LPWSTR szFriendlyName = NULL;
                        hr = pAttribute->GetGUID(MFT_TRANSFORM_CLSID_Attribute, &guid);
                        if (SUCCEEDED(hr))
                        {
                            hr = StringFromIID(guid, &szGuid);
                            std::wcout << szGuid << std::endl;
                        }
                        hr = pAttribute->GetAllocatedString(MFT_FRIENDLY_NAME_Attribute, &szFriendlyName, NULL);
                        if (SUCCEEDED(hr))
                        {
                            std::wcout << szFriendlyName << std::endl;
                        }
                    }

                    hr = pNodeObject->QueryInterface(IID_PPV_ARGS(&pTransform));
                    if (SUCCEEDED(hr))
                    {
                        std::cout << "got transform interface" << std::endl;
                    }
                    else
                    {
                        std::cout << std::hex << hr << std::endl;
                    }
                }
            }
        }
    }
    return hr;
}

This function finds 3 nodes in the topology: a MF_TOPOLOGY_SOURCESTREAM_NODE, a MF_TOPOLOGY_TRANSFORM_NODE, and a MF_TOPOLOGY_OUTPUT_NODE.

This function raises a lot of questions about things that don't seem to work correctly.

Foremost,

  1. The QueryInterface() call to get the IMFTransform interface on the middle node (which has type MF_TOPOLOGY_TRANSFORM_NODE) fails with error E_NOINTERFACE. Yet, when I query the CLSID and name of the transform from the IMFAttributes interface I get "H264 Encoder MFT". This transform is supposed to expose the IMFTransform interface per H.264 Video Encoder documentation. Can anyone see what I'm doing wrong?

Further questions: the output from this function is

{6CA50344-051A-4DED-9779-A43305165E35}
H264 Encoder MFT
80004002
80004002
  1. The call to GetObject fails for the first node (which has type MF_TOPOLOGY_SOURCESTREAM_NODE). How can a topology node fail to return a node object?
  2. The QueryInterface() call to get the IMFAttributes interface also fails on the third node (which has type MF_TOPOLOGY_OUTPUT_NODE). Shouldn't every node expose the IMFAttributes interface?
  3. Where is the H.264 decoder in this topology? The source file is an MP4 file with a single H.264 video elementary stream

Asking generally, are there any good references that explain Media Foundation? The online resources don't seem to tell the complete story. So far Media Foundation seems opaque to me. Thanks for any help you can offer.

Using:

Visual Studio 2017 (v141) (but same behavior with Visual Studio 2010)

Windows SDK Version 10.0.17134.0

Windows 7 Home Premium, Service Pack 1

Upvotes: 1

Views: 782

Answers (1)

VuVirt
VuVirt

Reputation: 1917

You should analyze the topology only after MESessionTopologySet is received in the Invoke handler.

This event is sent when the full topology is created by the Media Session after a call to IMFMediaSession::SetTopology

Upvotes: 1

Related Questions