创建输出节点

输出节点表示媒体接收器上的流接收器。 可通过两种方式初始化输出节点:

  • 从指向流接收器的指针。
  • 从指向媒体接收器的激活对象的指针。

如果要将拓扑加载到受保护媒体路径 (PMP) ,则必须使用激活对象,以便可以在受保护进程中创建媒体接收器。 第一种方法 (使用指向流接收器的指针) 不适用于 PMP。

从流接收器创建输出节点

若要从流接收器创建输出节点,请执行以下操作:

  1. 创建媒体接收器的实例。
  2. 使用媒体接收器的 IMFMediaSink 接口获取指向所需流接收器的指针。 (IMFMediaSink 接口有多个方法,这些方法返回指向流接收器的指针。)
  3. 使用MF_TOPOLOGY_OUTPUT_NODE标志调用 MFCreateTopologyNode 以创建输出节点。
  4. 调用 IMFTopologyNode::SetObject ,并传入指向流接收器 的 IMFStreamSink 接口的指针。
  5. MF_TOPONODE_NOSHUTDOWN_ON_REMOVE 属性设置为 FALSE (可选,但建议) 。
  6. 调用 IMFTopology::AddNode 将节点添加到拓扑。

以下示例从流接收器创建和初始化输出节点。

HRESULT AddOutputNode(
    IMFTopology *pTopology,     // Topology.
    IMFStreamSink *pStreamSink, // Stream sink.
    IMFTopologyNode **ppNode    // Receives the node pointer.
    )
{
    IMFTopologyNode *pNode = NULL;
    HRESULT hr = S_OK;
    
    // Create the node.
    hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode);

    // Set the object pointer.
    if (SUCCEEDED(hr))
    {
        hr = pNode->SetObject(pStreamSink);
    }

    // Add the node to the topology.
    if (SUCCEEDED(hr))
    {
        hr = pTopology->AddNode(pNode);
    }

    if (SUCCEEDED(hr))
    {
        hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, TRUE);
    }

    // Return the pointer to the caller.
    if (SUCCEEDED(hr))
    {
        *ppNode = pNode;
        (*ppNode)->AddRef();
    }

    if (pNode)
    {
        pNode->Release();
    }
    return hr;
}

当应用程序关闭媒体会话时,媒体会话会自动关闭媒体接收器。 因此,不能将媒体接收器与媒体会话的另一个实例重复使用。

从激活对象创建输出节点

任何受信任的媒体接收器都必须提供激活对象,以便可以在受保护的进程中创建媒体接收器。 有关详细信息,请参阅 激活对象。 创建激活对象的特定函数将取决于媒体接收器。

若要从激活对象创建输出节点,请执行以下操作:

  1. 创建激活对象并获取指向激活对象的 IMFActivate 接口的指针。
  2. 使用MF_TOPOLOGY_OUTPUT_NODE标志调用 MFCreateTopologyNode 以创建输出节点。
  3. (可选)在节点上设置 MF_TOPONODE_STREAMID 属性,以指定流接收器的流标识符。 如果省略此属性,节点默认使用流接收器 0。
  4. MF_TOPONODE_NOSHUTDOWN_ON_REMOVE 属性设置为 TRUE (可选,但建议) 。
  5. 调用 IMFTopologyNode::SetObject 并传入 IMFActivate 指针。
  6. 调用 IMFTopology::AddNode 将节点添加到拓扑。

以下示例从激活对象创建和初始化输出节点。

// Add an output node to a topology.
HRESULT AddOutputNode(
    IMFTopology *pTopology,     // Topology.
    IMFActivate *pActivate,     // Media sink activation object.
    DWORD dwId,                 // Identifier of the stream sink.
    IMFTopologyNode **ppNode)   // Receives the node pointer.
{
    IMFTopologyNode *pNode = NULL;

    // Create the node.
    HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode);
    if (FAILED(hr))
    {
        goto done;
    }

    // Set the object pointer.
    hr = pNode->SetObject(pActivate);
    if (FAILED(hr))
    {
        goto done;
    }

    // Set the stream sink ID attribute.
    hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE);
    if (FAILED(hr))
    {
        goto done;
    }

    // Add the node to the topology.
    hr = pTopology->AddNode(pNode);
    if (FAILED(hr))
    {
        goto done;
    }

    // Return the pointer to the caller.
    *ppNode = pNode;
    (*ppNode)->AddRef();

done:
    SafeRelease(&pNode);
    return hr;
}

IMFTopologyNode

创建拓扑

媒体接收器

拓扑