출력 노드를 미디어 싱크에 바인딩
이 항목에서는 미디어 세션 외부에서 토폴로지 로더를 사용하는 경우 토폴로지에서 출력 노드를 초기화하는 방법을 설명합니다. 출력 노드는 처음에 다음 중 하나를 포함합니다.
- IMFStreamSink 포인터입니다.
- IMFActivate 포인터입니다.
후자의 경우 토폴로지 로더가 토폴로지를 확인하기 전에 IMFActivate 포인터를 IMFStreamSink 포인터로 변환해야 합니다. 대부분의 시나리오에서 프로세스는 다음과 같이 작동합니다.
- 애플리케이션은 미디어 세션에서 부분 토폴로지를 큐에 대기합니다.
- 모든 출력 노드에 대해 미디어 세션은 IMFActivate 포인터를 IMFStreamSink 포인터로 변환합니다. 이 프로세스를 미디어 싱크에 출력 노드 바인딩 이라고 합니다.
- 미디어 세션은 수정된 토폴로지를 IMFTopoLoader::Load 메서드로 보냅니다.
그러나 토폴로지 로더를 직접 사용하는 경우(미디어 sesssion 외부에서) 애플리케이션은 IMFTopoLoader::Load를 호출하기 전에 출력 노드를 바인딩해야 합니다. 출력 노드를 바인딩하려면 다음을 수행합니다.
- IMFTopologyNode::GetObject를 호출하여 노드의 개체 포인터를 가져옵니다.
- IMFStreamSink 인터페이스에 대한 개체 포인터를 쿼리합니다. 이 호출이 성공하면 더 이상 수행할 작업이 없으므로 나머지 단계를 건너뜁니다.
- 이전 단계가 실패한 경우 IMFActivate 인터페이스에 대한 개체 포인터를 쿼리합니다.
- IMFActivate::ActivateObject를 호출하여 미디어 싱크를 만듭니다. 미디어 싱크의 IMFMediaSink 인터페이스에 대한 포인터를 가져올 IID_IMFMediaSink 지정합니다.
- 노드에서 MF_TOPONODE_STREAMID 특성을 쿼리합니다. 이 특성의 값은 이 노드에 대한 스트림 싱크의 식별자입니다. MF_TOPONODE_STREAMID 특성이 설정되지 않은 경우 기본 스트림 식별자는 0입니다.
- 미디어 싱크에 적절한 스트림 싱크가 이미 있을 수 있습니다. 검사 미디어 싱크에서 IMFMediaSink::GetStreamSinkById를 호출합니다. 스트림 싱크가 있는 경우 메서드는 해당 IMFStreamSink 인터페이스에 대한 포인터를 반환합니다. 이 호출이 실패하면 IMFMediaSink::AddStreamSink를 호출하여 새 스트림 싱크를 추가합니다. 두 호출이 모두 실패하면 미디어 싱크가 요청된 스트림 식별자를 지원하지 않으며 이 토폴로지 노드가 올바르게 구성되지 않음을 의미합니다. 오류 코드를 반환하고 다음 단계를 건너뜁니다.
- IMFTopologyNode::SetObject를 호출하여 이전 단계의 IMFStreamSink 포인터를 전달합니다. 이 호출은 노드의 개체 포인터를 대체하여 노드가 활성화 개체에 대한 포인터 대신 스트림 싱크에 대한 포인터를 포함하도록 합니다.
다음 코드는 출력 노드를 바인딩하는 방법을 보여줍니다.
// BindOutputNode
// Sets the IMFStreamSink pointer on an output node.
HRESULT BindOutputNode(IMFTopologyNode *pNode)
{
IUnknown *pNodeObject = NULL;
IMFActivate *pActivate = NULL;
IMFStreamSink *pStream = NULL;
IMFMediaSink *pSink = NULL;
// Get the node's object pointer.
HRESULT hr = pNode->GetObject(&pNodeObject);
if (FAILED(hr))
{
return hr;
}
// The object pointer should be one of the following:
// 1. An activation object for the media sink.
// 2. The stream sink.
// If it's #2, then we're already done.
// First, check if it's an activation object.
hr = pNodeObject->QueryInterface(IID_PPV_ARGS(&pActivate));
if (SUCCEEDED(hr))
{
DWORD dwStreamID = 0;
// The object pointer is an activation object.
// Try to create the media sink.
hr = pActivate->ActivateObject(IID_PPV_ARGS(&pSink));
// Look up the stream ID. (Default to zero.)
if (SUCCEEDED(hr))
{
dwStreamID = MFGetAttributeUINT32(pNode, MF_TOPONODE_STREAMID, 0);
}
// Now try to get or create the stream sink.
// Check if the media sink already has a stream sink with the requested ID.
if (SUCCEEDED(hr))
{
hr = pSink->GetStreamSinkById(dwStreamID, &pStream);
if (FAILED(hr))
{
// Try to add a new stream sink.
hr = pSink->AddStreamSink(dwStreamID, NULL, &pStream);
}
}
// Replace the node's object pointer with the stream sink.
if (SUCCEEDED(hr))
{
hr = pNode->SetObject(pStream);
}
}
else
{
// Not an activation object. Is it a stream sink?
hr = pNodeObject->QueryInterface(IID_PPV_ARGS(&pStream));
}
SafeRelease(&pNodeObject);
SafeRelease(&pActivate);
SafeRelease(&pStream);
SafeRelease(&pSink);
return hr;
}
참고
이 예제에서는 SafeRelease 함수를 사용하여 인터페이스 포인터를 해제합니다.
다음 예제에서는 토폴로지의 모든 출력 노드를 바인딩하는 방법을 보여 줍니다. 이 예제에서는 IMFTopology::GetOutputNodeCollection 메서드를 사용하여 토폴로지에서 출력 노드 컬렉션을 가져옵니다. 그런 다음, 각 노드의 이전 예제에 표시된 함수를 차례로 호출합니다.
// BindOutputNodes
// Sets the IMFStreamSink pointers on all of the output nodes in a topology.
HRESULT BindOutputNodes(IMFTopology *pTopology)
{
DWORD cNodes = 0;
IMFCollection *pCol = NULL;
IUnknown *pUnk = NULL;
IMFTopologyNode *pNode = NULL;
// Get the collection of output nodes.
HRESULT hr = pTopology->GetOutputNodeCollection(&pCol);
// Enumerate all of the nodes in the collection.
if (SUCCEEDED(hr))
{
hr = pCol->GetElementCount(&cNodes);
}
if (SUCCEEDED(hr))
{
for (DWORD i = 0; i < cNodes; i++)
{
hr = pCol->GetElement(i, &pUnk);
if (FAILED(hr)) { break; }
hr = pUnk->QueryInterface(IID_IMFTopologyNode, (void**)&pNode);
if (FAILED(hr)) { break; }
// Bind this node.
hr = BindOutputNode(pNode);
if (FAILED(hr)) { break; }
}
}
SafeRelease(&pCol);
SafeRelease(&pUnk);
SafeRelease(&pNode);
return hr;
}
관련 항목