Share via


出力ノードの作成

出力ノードは、メディア シンク上のストリーム シンクを表します。 出力ノードを初期化するには、次の 2 つの方法があります。

  • ストリーム シンクへのポインターから。
  • メディア シンクのアクティブ化オブジェクトへのポインターから。

保護されたメディア パス (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

トポロジの作成

メディア シンク

トポロジ