Creazione di nodi di output

Un nodo di output rappresenta un sink di flusso in un sink multimediale. Esistono due modi per inizializzare un nodo di output:

  • Da un puntatore al sink del flusso.
  • Da un puntatore a un oggetto attivazione per il sink multimediale.

Se si intende caricare la topologia all'interno del percorso multimediale protetto , è necessario usare un oggetto attivazione, in modo che il sink multimediale possa essere creato all'interno del processo protetto. Il primo approccio (usando un puntatore al sink del flusso) non funziona con il pmp.

Creazione di un nodo di output da un sink di flusso

Per creare un nodo di output da un sink di flusso, eseguire le operazioni seguenti:

  1. Creare un'istanza del sink multimediale.
  2. Usare l'interfaccia IMFMediaSink del sink multimediale per ottenere un puntatore al sink di flusso desiderato. L'interfaccia IMFMediaSink ha diversi metodi che restituiscono puntatori a un sink di flusso.
  3. Chiamare MFCreateTopologyNode con il flag MF_TOPOLOGY_OUTPUT_NODE per creare il nodo di output.
  4. Chiamare IMFTopologyNode::SetObject e passare un puntatore all'interfaccia IMFStreamSink del sink di flusso.
  5. Impostare l'attributo MF_TOPONODE_NOSHUTDOWN_ON_REMOVE su FALSE (facoltativo ma consigliato).
  6. Chiamare IMFTopology::AddNode per aggiungere il nodo alla topologia.

Nell'esempio seguente viene creato e inizializzato un nodo di output da un sink di flusso.

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

Quando l'applicazione arresta la sessione multimediale, la sessione multimediale arresta automaticamente il sink multimediale. Pertanto, non è possibile riutilizzare il sink multimediale con un'altra istanza della sessione multimediale.

Creazione di un nodo di output da un oggetto attivazione

Qualsiasi sink multimediale attendibile deve fornire un oggetto di attivazione, in modo che il sink multimediale possa essere creato all'interno del processo protetto. Per altre informazioni, vedere Oggetti attivazione. La funzione specifica che crea l'oggetto attivazione dipenderà dal sink multimediale.

Per creare un nodo di output da un oggetto di attivazione, eseguire le operazioni seguenti:

  1. Creare l'oggetto attivazione e ottenere un puntatore all'interfaccia IMFActivate dell'oggetto attivazione.
  2. Chiamare MFCreateTopologyNode con il flag MF_TOPOLOGY_OUTPUT_NODE per creare il nodo di output.
  3. Facoltativamente, impostare l'attributo MF_TOPONODE_STREAMID nel nodo per specificare l'identificatore del flusso del sink di flusso. Se si omette questo attributo, per impostazione predefinita il nodo usa il sink di flusso 0.
  4. Impostare l'attributo MF_TOPONODE_NOSHUTDOWN_ON_REMOVE su TRUE (facoltativo ma consigliato).
  5. Chiamare IMFTopologyNode::SetObject e passare il puntatore IMFActivate .
  6. Chiamare IMFTopology::AddNode per aggiungere il nodo alla topologia.

Nell'esempio seguente viene creato e inizializzato un nodo di output da un oggetto attivazione.

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

Creazione di topologie

Sink multimediali

Topologie