Erstellen von Ausgabeknoten

Ein Ausgabeknoten stellt eine Streamsenke auf einer Mediensenke dar. Es gibt zwei Möglichkeiten, einen Ausgabeknoten zu initialisieren:

  • Von einem Zeiger auf die Streamsenke.
  • Von einem Zeiger auf ein Aktivierungsobjekt für die Mediensenke.

Wenn Sie die Topologie in den geschützten Medienpfad (Protected Media Path, PMP) laden möchten, müssen Sie ein Aktivierungsobjekt verwenden, damit die Mediensenke innerhalb des geschützten Prozesses erstellt werden kann. Der erste Ansatz (mithilfe eines Zeigers auf die Streamsenke) funktioniert nicht mit dem PMP.

Erstellen eines Ausgabeknotens aus einer Streamsenke

Gehen Sie wie folgt vor, um einen Ausgabeknoten aus einer Streamsenke zu erstellen:

  1. Erstellen Sie eine instance der Mediensenke.
  2. Verwenden Sie die IMFMediaSink-Schnittstelle der Mediensenke, um einen Zeiger auf die gewünschte Streamsenke zu erhalten. (Die IMFMediaSink-Schnittstelle verfügt über mehrere Methoden, die Zeiger auf eine Streamsenke zurückgeben.)
  3. Rufen Sie MFCreateTopologyNode mit dem flag MF_TOPOLOGY_OUTPUT_NODE auf, um den Ausgabeknoten zu erstellen.
  4. Rufen Sie IMFTopologyNode::SetObject auf, und übergeben Sie einen Zeiger auf die IMFStreamSink-Schnittstelle der Streamsenke.
  5. Legen Sie das attribut MF_TOPONODE_NOSHUTDOWN_ON_REMOVE auf FALSE fest (optional, aber empfohlen).
  6. Rufen Sie IMFTopology::AddNode auf, um den Knoten der Topologie hinzuzufügen.

Im folgenden Beispiel wird ein Ausgabeknoten aus einer Streamsenke erstellt und initialisiert.

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

Wenn die Anwendung die Mediensitzung herunterfährt, wird die Mediensitzung automatisch heruntergefahren. Daher können Sie die Mediensenke nicht mit einem anderen instance der Mediensitzung erneut verwenden.

Erstellen eines Ausgabeknotens aus einem Aktivierungsobjekt

Jede vertrauenswürdige Mediensenke muss ein Aktivierungsobjekt bereitstellen, damit die Mediensenke innerhalb des geschützten Prozesses erstellt werden kann. Weitere Informationen finden Sie unter Aktivierungsobjekte. Die bestimmte Funktion, die das Aktivierungsobjekt erstellt, hängt von der Mediensenke ab.

Gehen Sie wie folgt vor, um einen Ausgabeknoten aus einem Aktivierungsobjekt zu erstellen:

  1. Erstellen Sie das Aktivierungsobjekt, und rufen Sie einen Zeiger auf die IMFActivate-Schnittstelle des Aktivierungsobjekts ab.
  2. Rufen Sie MFCreateTopologyNode mit dem flag MF_TOPOLOGY_OUTPUT_NODE auf, um den Ausgabeknoten zu erstellen.
  3. Legen Sie optional das attribut MF_TOPONODE_STREAMID auf dem Knoten fest, um den Streambezeichner der Streamsenke anzugeben. Wenn Sie dieses Attribut weglassen, verwendet der Knoten standardmäßig die Streamsenke 0.
  4. Legen Sie das MF_TOPONODE_NOSHUTDOWN_ON_REMOVE-Attribut auf TRUE fest (optional, aber empfohlen).
  5. Rufen Sie IMFTopologyNode::SetObject auf , und übergeben Sie den IMFActivate-Zeiger .
  6. Rufen Sie IMFTopology::AddNode auf, um den Knoten der Topologie hinzuzufügen.

Im folgenden Beispiel wird ein Ausgabeknoten aus einem Aktivierungsobjekt erstellt und initialisiert.

// 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

Erstellen von Topologien

Mediensenken

Topologien