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

时间:2018-06-04 16:42:41

标签: ms-media-foundation

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

1 个答案:

答案 0 :(得分:1)

只有在Invoke处理程序中收到MESessionTopologySet后才应分析拓扑。

在调用IMFMediaSession::SetTopology后媒体会话创建完整拓扑时发送此事件