HRESULT tTVPMFPlayer::AddSourceNode( IMFTopology *pTopology, IMFMediaSource *pSource, IMFPresentationDescriptor *pPD, IMFStreamDescriptor *pSD, IMFTopologyNode **ppNode ) { HRESULT hr; // Create the node. CComPtr<IMFTopologyNode> pNode; if( FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode)) ) { TVPThrowExceptionMessage(L"Faild to create source node."); } // Set the attributes. if( FAILED(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource) ) ) { TVPThrowExceptionMessage(L"Faild to set source node."); } if( FAILED(hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD) ) ) { TVPThrowExceptionMessage(L"Faild to set presentation desc."); } if( FAILED(hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD)) ) { TVPThrowExceptionMessage(L"Faild to set stream desc."); } // Add the node to the topology. if( FAILED(hr = pTopology->AddNode(pNode)) ) { TVPThrowExceptionMessage(L"Faild to add source node to topology."); } // Return the pointer to the caller. *ppNode = pNode; (*ppNode)->AddRef(); return hr; }
HRESULT CreateSourceStreamNode( IMFMediaSource *pSource, IMFPresentationDescriptor *pSourcePD, IMFStreamDescriptor *pSourceSD, IMFTopologyNode **ppNode ) { if (!pSource || !pSourcePD || !pSourceSD || !ppNode) { return E_POINTER; } IMFTopologyNode *pNode = NULL; HRESULT hr = S_OK; // Create the source-stream node. CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode)); // Set attribute: Pointer to the media source. CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource)); // Set attribute: Pointer to the presentation descriptor. CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pSourcePD)); // Set attribute: Pointer to the stream descriptor. CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSourceSD)); // Return the IMFTopologyNode pointer to the caller. *ppNode = pNode; (*ppNode)->AddRef(); done: SAFE_RELEASE(pNode); return hr; }
HRESULT tTVPMFPlayer::AddOutputNode( IMFTopology *pTopology, IMFActivate *pActivate, DWORD dwId, IMFTopologyNode **ppNode ) { HRESULT hr; // Create the node. CComPtr<IMFTopologyNode> pNode; if( FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode)) ){ TVPThrowExceptionMessage(L"Faild to create output node."); } // Set the object pointer. if( FAILED(hr = pNode->SetObject(pActivate)) ) { TVPThrowExceptionMessage(L"Faild to set activate."); } // Set the stream sink ID attribute. if( FAILED(hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId)) ) { TVPThrowExceptionMessage(L"Faild to set stream id."); } if( FAILED(hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE)) ) { TVPThrowExceptionMessage(L"Faild to set no shutdown on remove."); } // Add the node to the topology. if( FAILED(hr = pTopology->AddNode(pNode)) ) { TVPThrowExceptionMessage(L"Faild to add ouput node to topology."); } // Return the pointer to the caller. *ppNode = pNode; (*ppNode)->AddRef(); return hr; }
HRESULT CreateOutputNode(IMFMediaSink *pSink, DWORD iStream, IMFTopologyNode **ppNode) { CComPtr<IMFTopologyNode> pNode = NULL; CComPtr<IMFStreamSink> pStream = NULL; HRESULT hr = S_OK; hr = pSink->GetStreamSinkByIndex(iStream, &pStream); if (SUCCEEDED(hr)) { hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode); } if (SUCCEEDED(hr)) { hr = pNode->SetObject(pStream); } if (SUCCEEDED(hr)) { *ppNode = pNode; (*ppNode)->AddRef(); } return hr; }
IMFTopologyNode* MediaSource::CreateTopologySourceNode() { IMFTopologyNode* mfTopologyNode = nullptr; IMFStreamDescriptor* mfStreamDescriptor = nullptr; HRESULT hr; DWORD streamDescriptorCount; BOOL isSelected; do { // Iterate through the source streams to find the currently selected one if (!SUCCEEDED(hr = _mfPresentationDescriptor->GetStreamDescriptorCount(&streamDescriptorCount))) break; for (DWORD i = 0; i < streamDescriptorCount; i++) { if (!SUCCEEDED(hr = _mfPresentationDescriptor->GetStreamDescriptorByIndex(i, &isSelected, &mfStreamDescriptor))) break; if (isSelected) { break; } else { mfStreamDescriptor->Release(); mfStreamDescriptor = nullptr; } } if (FAILED(hr) || !mfStreamDescriptor) { throw std::exception("Could not find selected stream in MediaSource"); } // otherwise, we're in good shape :-) if (!SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &mfTopologyNode))) break; if (!SUCCEEDED(hr = mfTopologyNode->SetUnknown(MF_TOPONODE_SOURCE, _mfMediaSource))) break; if (!SUCCEEDED(hr = mfTopologyNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, _mfPresentationDescriptor))) break; if (!SUCCEEDED(hr = mfTopologyNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, mfStreamDescriptor))) break; } while (0); if (FAILED(hr)) { throw std::exception("Could not create topology source node"); } mfStreamDescriptor->Release(); return mfTopologyNode; }
// Given a source, connect each stream to a renderer for its media type HRESULT CTedMediaFileRenderer::BuildTopologyFromSource(IMFTopology* pTopology, IMFMediaSource* pSource) { HRESULT hr; CComPtr<IMFPresentationDescriptor> spPD; IFC( pSource->CreatePresentationDescriptor(&spPD) ); DWORD cSourceStreams = 0; IFC( spPD->GetStreamDescriptorCount(&cSourceStreams) ); for(DWORD i = 0; i < cSourceStreams; i++) { CComPtr<IMFStreamDescriptor> spSD; CComPtr<IMFTopologyNode> spNode; CComPtr<IMFTopologyNode> spRendererNode; BOOL fSelected = FALSE; IFC( spPD->GetStreamDescriptorByIndex(i, &fSelected, &spSD) ); IFC( MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &spNode) ); IFC( spNode->SetUnknown(MF_TOPONODE_SOURCE, pSource) ); IFC( spNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, spPD) ); IFC( spNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, spSD) ); IFC( pTopology->AddNode(spNode) ); IFC( CreateRendererForStream(spSD, &spRendererNode) ); IFC( spNode->ConnectOutput(0, spRendererNode, 0) ); IFC( pTopology->AddNode(spRendererNode) ); } Cleanup: return hr; }
// Add an output node to a topology. IMFTopologyNodePtr AddOutputNode( IMFTopologyPtr pTopology, // Topology. IMFActivatePtr pActivate, // Media sink activation object. DWORD dwId // Identifier of the stream sink. ) { IMFTopologyNodePtr pNode; // Create the node. THROW_IF_ERR(MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode)); // Set the object pointer. THROW_IF_ERR(pNode->SetObject(pActivate.Get())); // Set the stream sink ID attribute. THROW_IF_ERR(pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId)); THROW_IF_ERR(pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE)); // Add the node to the topology. THROW_IF_ERR(pTopology->AddNode(pNode.Get())); return pNode; }
HRESULT CreateOutputNode( IMFStreamDescriptor *pSourceSD, HWND hwndVideo, IMFTopologyNode **ppNode ) { IMFTopologyNode *pNode = NULL; IMFMediaTypeHandler *pHandler = NULL; IMFActivate *pRendererActivate = NULL; GUID guidMajorType = GUID_NULL; HRESULT hr = S_OK; // Get the stream ID. DWORD streamID = 0; pSourceSD->GetStreamIdentifier(&streamID); // Just for debugging, ignore any failures. // Get the media type handler for the stream. CHECK_HR(hr = pSourceSD->GetMediaTypeHandler(&pHandler)); // Get the major media type. CHECK_HR(hr = pHandler->GetMajorType(&guidMajorType)); // Create a downstream node. CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode)); // Create an IMFActivate object for the renderer, based on the media type. if (MFMediaType_Audio == guidMajorType) { // Create the audio renderer. TRACE((L"Stream %d: audio stream\n", streamID)); CHECK_HR(hr = MFCreateAudioRendererActivate(&pRendererActivate)); } else if (MFMediaType_Video == guidMajorType) { // Create the video renderer. TRACE((L"Stream %d: video stream\n", streamID)); CHECK_HR(hr = MFCreateVideoRendererActivate(hwndVideo, &pRendererActivate)); } else { TRACE((L"Stream %d: Unknown format\n", streamID)); CHECK_HR(hr = E_FAIL); } // Set the IActivate object on the output node. CHECK_HR(hr = pNode->SetObject(pRendererActivate)); // Return the IMFTopologyNode pointer to the caller. *ppNode = pNode; (*ppNode)->AddRef(); done: SAFE_RELEASE(pNode); SAFE_RELEASE(pHandler); SAFE_RELEASE(pRendererActivate); return hr; }
HRESULT CreateSourceNode( IMFMediaSource *pSource, // Media source. IMFPresentationDescriptor *pPD, // Presentation descriptor. IMFStreamDescriptor *pSD, // Stream descriptor. IMFTopologyNode **ppNode // Receives the node pointer. ) { CComPtr<IMFTopologyNode> pNode; HRESULT hr = S_OK; // Create the node. hr = MFCreateTopologyNode( MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode); // Set the attributes. if (SUCCEEDED(hr)) { hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource); } if (SUCCEEDED(hr)) { hr = pNode->SetUnknown( MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD); } if (SUCCEEDED(hr)) { hr = pNode->SetUnknown( MF_TOPONODE_STREAM_DESCRIPTOR, pSD); } // Return the pointer to the caller. if (SUCCEEDED(hr)) { *ppNode = pNode; (*ppNode)->AddRef(); } return hr; }
// Create a renderer for the media type on the given stream descriptor HRESULT CTedMediaFileRenderer::CreateRendererForStream(IMFStreamDescriptor* pSD, IMFTopologyNode** ppRendererNode) { HRESULT hr; CComPtr<IMFMediaTypeHandler> spMediaTypeHandler; CComPtr<IMFActivate> spRendererActivate; CComPtr<IMFMediaSink> spRendererSink; CComPtr<IMFStreamSink> spRendererStreamSink; IMFTopologyNode* pRendererNode; GUID gidMajorType; IFC( MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pRendererNode) ); IFC( pSD->GetMediaTypeHandler( &spMediaTypeHandler ) ); IFC( spMediaTypeHandler->GetMajorType( &gidMajorType ) ); if(MFMediaType_Audio == gidMajorType) { IFC( MFCreateAudioRendererActivate(&spRendererActivate) ); IFC( spRendererActivate->ActivateObject(IID_IMFMediaSink, (void**) &spRendererSink) ); IFC( spRendererSink->GetStreamSinkById(0, &spRendererStreamSink) ); IFC( pRendererNode->SetObject(spRendererStreamSink) ); } else if(MFMediaType_Video == gidMajorType) { HWND hVideoWindow; IFC( m_spVideoWindowHandler->GetVideoWindow((LONG_PTR*) &hVideoWindow) ); IFC( MFCreateVideoRendererActivate(hVideoWindow, &spRendererActivate) ); IFC( spRendererActivate->ActivateObject(IID_IMFMediaSink, (void**) &spRendererSink) ); IFC( spRendererSink->GetStreamSinkById(0, &spRendererStreamSink) ); IFC( pRendererNode->SetObject(spRendererStreamSink) ); } else { // Do not have renderers for any other major types } *ppRendererNode = pRendererNode; Cleanup: return hr; }
IMFTopologyNode* MediaSink::CreateTopologyOutputNode(WORD streamNumber) { IMFTopologyNode* mfTopologyNode = nullptr; IMFStreamSink* mfStreamSink = nullptr; HRESULT hr; do { // Get the stream sink based on the supplied streamNumber if (!SUCCEEDED(hr = _mfMediaSink->GetStreamSinkById(streamNumber, &mfStreamSink))) break; // Create the node. if (!SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &mfTopologyNode))) break; // Set the object pointer. if (!SUCCEEDED(hr = mfTopologyNode->SetObject(mfStreamSink))) break; /* Doesn't seem like the following is needed? I set it to arandom stream number, didn't appear to change anything // Set the stream sink ID attribute. if (!SUCCEEDED(hr = mfTopologyNode->SetUINT32(MF_TOPONODE_STREAMID, streamNumber))) break; */ if (!SUCCEEDED(hr = mfTopologyNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE))) break; } while (0); if (FAILED(hr)) throw std::exception("Unable to create topology output node"); return mfTopologyNode; }
// 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; HRESULT hr = S_OK; CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode)); CHECK_HR(hr = pNode->SetObject(pActivate)); CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId)); CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE)); CHECK_HR(hr = pTopology->AddNode(pNode)); // Return the pointer to the caller. *ppNode = pNode; (*ppNode)->AddRef(); done: SafeRelease(&pNode); return hr; }
// Add a source node to a topology. HRESULT AddSourceNode( IMFTopology *pTopology, // Topology. IMFMediaSource *pSource, // Media source. IMFPresentationDescriptor *pPD, // Presentation descriptor. IMFStreamDescriptor *pSD, // Stream descriptor. IMFTopologyNode **ppNode) // Receives the node pointer. { IMFTopologyNode *pNode = NULL; HRESULT hr = S_OK; CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode)); CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource)); CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD)); CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD)); CHECK_HR(hr = pTopology->AddNode(pNode)); // Return the pointer to the caller. *ppNode = pNode; (*ppNode)->AddRef(); done: SafeRelease(&pNode); return hr; }
// Add a source node to a topology. IMFTopologyNodePtr AddSourceNode( IMFTopologyPtr pTopology, // Topology. IMFMediaSourcePtr pSource, // Media source. IMFPresentationDescriptorPtr pPD, // Presentation descriptor. IMFStreamDescriptorPtr pSD) // Stream descriptor. { IMFTopologyNodePtr pNode; // Create the node. THROW_IF_ERR(MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, pNode.GetAddressOf())); // Set the attributes. THROW_IF_ERR(pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource.Get())); THROW_IF_ERR(pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD.Get())); THROW_IF_ERR(pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD.Get())); // Add the node to the topology. THROW_IF_ERR(pTopology->AddNode(pNode.Get())); // Return the pointer to the caller. return pNode; }
/** Add stream to topology */ FIntPoint FImfVideoPlayer::AddStreamToTopology( IMFTopology* Topology, IMFPresentationDescriptor* PresentationDesc, IMFStreamDescriptor* StreamDesc, FImfSampleGrabberCallback* SampleGrabberCallback ) { FIntPoint OutDimensions = FIntPoint( ForceInit ); HRESULT HResult = S_OK; IMFActivate* SinkActivate = NULL; { IMFMediaTypeHandler* Handler = NULL; HResult = StreamDesc->GetMediaTypeHandler( &Handler ); check( SUCCEEDED( HResult ) ); GUID MajorType; HResult = Handler->GetMajorType( &MajorType ); check( SUCCEEDED( HResult ) ); /* Audio stream */ if( MajorType == MFMediaType_Audio ) { /* No audio required */ Handler->Release( ); return FIntPoint( ForceInit ); } /* Video stream */ else if( MajorType == MFMediaType_Video ) { IMFMediaType* OutputType = NULL; HResult = Handler->GetCurrentMediaType( &OutputType ); check( SUCCEEDED( HResult ) ); IMFMediaType* InputType = NULL; HResult = MFCreateMediaType( &InputType ); UINT32 Width = 0, Height = 0; HResult = MFGetAttributeSize( OutputType, MF_MT_FRAME_SIZE, &Width, &Height ); check( SUCCEEDED( HResult ) ); HResult = InputType->SetGUID( MF_MT_MAJOR_TYPE, MFMediaType_Video ); check( SUCCEEDED( HResult ) ); HResult = InputType->SetGUID( MF_MT_SUBTYPE, MFVideoFormat_RGB32 ); check( SUCCEEDED( HResult ) ); HResult = InputType->SetUINT32( MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE ); check( SUCCEEDED( HResult ) ); HResult = MFCreateSampleGrabberSinkActivate( InputType, SampleGrabberCallback, &SinkActivate ); check( SUCCEEDED( HResult ) ); InputType->Release( ); OutputType->Release( ); OutDimensions = FIntPoint( Width, Height ); } Handler->Release( ); } IMFTopologyNode* SourceNode = NULL; { HResult = MFCreateTopologyNode( MF_TOPOLOGY_SOURCESTREAM_NODE, &SourceNode ); check( SUCCEEDED( HResult ) ); HResult = SourceNode->SetUnknown( MF_TOPONODE_SOURCE, MediaSource ); check( SUCCEEDED( HResult ) ); HResult = SourceNode->SetUnknown( MF_TOPONODE_PRESENTATION_DESCRIPTOR, PresentationDesc ); check( SUCCEEDED( HResult ) ); HResult = SourceNode->SetUnknown( MF_TOPONODE_STREAM_DESCRIPTOR, StreamDesc ); check( SUCCEEDED( HResult ) ); HResult = Topology->AddNode( SourceNode ); check( SUCCEEDED( HResult ) ); } IMFTopologyNode* OutputNode = NULL; { HResult = MFCreateTopologyNode( MF_TOPOLOGY_OUTPUT_NODE, &OutputNode ); check( SUCCEEDED( HResult ) ); HResult = OutputNode->SetObject( SinkActivate ); check( SUCCEEDED( HResult ) ); HResult = OutputNode->SetUINT32( MF_TOPONODE_STREAMID, 0 ); check( SUCCEEDED( HResult ) ); HResult = OutputNode->SetUINT32( MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, 0 ); check( SUCCEEDED( HResult ) ); HResult = Topology->AddNode( OutputNode ); check( SUCCEEDED( HResult ) ); } HResult = SourceNode->ConnectOutput( 0, OutputNode, 0 ); check( SUCCEEDED( HResult ) ); SourceNode->Release( ); OutputNode->Release( ); SinkActivate->Release( ); return OutDimensions; }