创建输出节点
输出节点表示媒体接收器上的流接收器。 可通过两种方式初始化输出节点:
- 从指向流接收器的指针。
- 从指向媒体接收器的激活对象的指针。
如果要将拓扑加载到受保护媒体路径 (PMP) ,则必须使用激活对象,以便可以在受保护进程中创建媒体接收器。 第一种方法 (使用指向流接收器的指针) 不适用于 PMP。
从流接收器创建输出节点
若要从流接收器创建输出节点,请执行以下操作:
- 创建媒体接收器的实例。
- 使用媒体接收器的 IMFMediaSink 接口获取指向所需流接收器的指针。 (IMFMediaSink 接口有多个方法,这些方法返回指向流接收器的指针。)
- 使用MF_TOPOLOGY_OUTPUT_NODE标志调用 MFCreateTopologyNode 以创建输出节点。
- 调用 IMFTopologyNode::SetObject ,并传入指向流接收器 的 IMFStreamSink 接口的指针。
- 将 MF_TOPONODE_NOSHUTDOWN_ON_REMOVE 属性设置为 FALSE (可选,但建议) 。
- 调用 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;
}
当应用程序关闭媒体会话时,媒体会话会自动关闭媒体接收器。 因此,不能将媒体接收器与媒体会话的另一个实例重复使用。
从激活对象创建输出节点
任何受信任的媒体接收器都必须提供激活对象,以便可以在受保护的进程中创建媒体接收器。 有关详细信息,请参阅 激活对象。 创建激活对象的特定函数将取决于媒体接收器。
若要从激活对象创建输出节点,请执行以下操作:
- 创建激活对象并获取指向激活对象的 IMFActivate 接口的指针。
- 使用MF_TOPOLOGY_OUTPUT_NODE标志调用 MFCreateTopologyNode 以创建输出节点。
- (可选)在节点上设置 MF_TOPONODE_STREAMID 属性,以指定流接收器的流标识符。 如果省略此属性,节点默认使用流接收器 0。
- 将 MF_TOPONODE_NOSHUTDOWN_ON_REMOVE 属性设置为 TRUE (可选,但建议) 。
- 调用 IMFTopologyNode::SetObject 并传入 IMFActivate 指针。
- 调用 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;
}
相关主题