Tworzenie węzłów wyjściowych
Węzeł wyjściowy reprezentuje odbiornik strumienia w odbiorniku multimedialnym. Istnieją dwa sposoby inicjowania węzła wyjściowego:
- Od wskaźnika do ujścia strumienia.
- Wskaźnik do obiektu aktywacji dla odbiornika multimediów.
Jeśli zamierzasz załadować topologię wewnątrz ścieżki ochrony multimediów (PMP), musisz użyć obiektu aktywacji, tak, aby można było utworzyć wyjście danych multimedialnych wewnątrz chronionego procesu. Pierwsze podejście (użycie wskaźnika do ujścia strumienia) nie działa z PMP.
Tworzenie węzła wyjściowego na podstawie ujścia strumienia
Aby utworzyć węzeł wyjściowy na podstawie ujścia strumienia, wykonaj następujące czynności:
- Utwórz wystąpienie odbiornika multimediów.
- Użyj interfejsu IMFMediaSink, aby uzyskać wskaźnik do żądanego ujścia strumienia. (Interfejs IMFMediaSink ma kilka metod, które zwracają wskaźniki do ujścia strumienia).
- Wywołaj MFCreateTopologyNode z flagą MF_TOPOLOGY_OUTPUT_NODE, aby utworzyć węzeł wyjściowy.
- Wywołaj IMFTopologyNode::SetObject i przekaż wskaźnik do interfejsu ujścia strumienia IMFStreamSink.
- Ustaw atrybut MF_TOPONODE_NOSHUTDOWN_ON_REMOVE na wartość FALSE (opcjonalne, ale zalecane).
- Wywołaj IMFTopology::AddNode, aby dodać węzeł do topologii.
Poniższy przykład tworzy i inicjuje węzeł wyjściowy z ujścia strumienia.
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;
}
Gdy aplikacja zamknie sesję multimediów, sesja mediów automatycznie zamyka odbiornik mediów. W związku z tym nie można ponownie użyć wyjścia multimediów z innym wystąpieniem sesji multimedialnej.
Tworzenie węzła wyjściowego na podstawie obiektu aktywacji
Każdy zaufany odbiornik mediów musi dostarczyć obiekt aktywacji, aby można było utworzyć odbiornik mediów wewnątrz chronionego procesu. Aby uzyskać więcej informacji, zobacz Obiekty Aktywacji. Funkcja tworząca obiekt aktywacji zależy od odbiornika multimediów.
Aby utworzyć węzeł wyjściowy na podstawie obiektu aktywacji, wykonaj następujące czynności:
- Utwórz obiekt aktywacji i pobierz wskaźnik do interfejsu IMFActivate obiektu aktywacji.
- Wywołaj MFCreateTopologyNode z flagą MF_TOPOLOGY_OUTPUT_NODE, aby utworzyć węzeł wyjściowy.
- Opcjonalnie ustaw atrybut MF_TOPONODE_STREAMID w węźle, aby określić identyfikator odbiornika strumienia. Jeśli ten atrybut zostanie pominięty, węzeł domyślnie używa ujścia strumienia 0.
- Ustaw atrybut MF_TOPONODE_NOSHUTDOWN_ON_REMOVE na wartość TRUE (opcjonalne, ale zalecane).
- Wywołaj IMFTopologyNode::SetObject i przekaż wskaźnik IMFActivate.
- Wywołaj IMFTopology::AddNode, aby dodać węzeł do topologii.
Poniższy przykład tworzy i inicjuje węzeł wyjściowy z obiektu aktywacji.
// 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;
}
Tematy pokrewne