MS Media Foundation - 无法获取 H264 编码器 MFT 对象的 IMFTransform 接口?

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

我正在开始使用 MS Media Foundation,所以我刚刚输入了来自 Tutorial: Encoding an MP4 File 的代码。这使用源解析器创建媒体源,并使用 MFCreateTranscodeTopology() 函数创建包括 H.264 编码器的拓扑,如参考中所述。

然后我想通过分析拓扑来测试我对媒体基础结构的新理解。我创建了以下函数,我在教程中调用 StartEncodingSession() 之前立即从示例代码中调用了该函数。

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;
}

此函数在拓扑中找到 3 个节点:MF_TOPOLOGY_SOURCESTREAM_NODE、MF_TOPOLOGY_TRANSFORM_NODE 和 MF_TOPOLOGY_OUTPUT_NODE。

此功能引发了很多关于似乎无法正常工作的问题。

首先,

  1. 获取中间节点(类型 MF_TOPOLOGY_TRANSFORM_NODE)上的 IMFTransform 接口的 QueryInterface() 调用失败,错误为 E_NOINTERFACE。然而,当我从 IMFAttributes 接口查询转换的 CLSID 和名称时,我得到 "H264 Encoder MFT"。此转换应该根据 H.264 Video Encoder documentation 公开 IMFTransform 接口。谁能看出我做错了什么?

更多问题: 这个函数的输出是

{6CA50344-051A-4DED-9779-A43305165E35}
H264 Encoder MFT
80004002
80004002
  1. 第一个节点(其类型为 MF_TOPOLOGY_SOURCESTREAM_NODE)对 GetObject 的调用失败。拓扑节点如何无法 return 节点对象?
  2. 用于获取 IMFAttributes 接口的 QueryInterface() 调用在第三个节点(类型为 MF_TOPOLOGY_OUTPUT_NODE)上也失败。不应该每个节点都公开 IMFAttributes 接口吗?
  3. 此拓扑中的 H.264 解码器在哪里?源文件是带有单个 H.264 视频基本流的 MP4 文件

泛泛而谈,有没有很好的解释媒体基础的参考资料?在线资源似乎并没有讲述完整的故事。到目前为止,媒体基金会对我来说似乎是不透明的。感谢您提供的任何帮助。

使用:

Visual Studio 2017 (v141)(但与 Visual Studio 2010 的行为相同)

Windows SDK 版本 10.0.17134.0

Windows 7 家庭高级版,Service Pack 1

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

调用 IMFMediaSession::SetTopology

后媒体会话创建完整拓扑时发送此事件