/** Set playback topology */ FIntPoint FImfVideoPlayer::SetPlaybackTopology( FImfSampleGrabberCallback* SampleGrabberCallback ) { FIntPoint OutDimensions = FIntPoint( ForceInit ); HRESULT HResult = S_OK; IMFPresentationDescriptor* PresentationDesc = NULL; HResult = MediaSource->CreatePresentationDescriptor( &PresentationDesc ); check( SUCCEEDED( HResult ) ); IMFTopology* Topology = NULL; HResult = MFCreateTopology( &Topology ); check( SUCCEEDED( HResult ) ); DWORD StreamCount = 0; HResult = PresentationDesc->GetStreamDescriptorCount( &StreamCount ); check( SUCCEEDED( HResult ) ); for( uint32 i = 0; i < StreamCount; i++ ) { BOOL bSelected = 0; IMFStreamDescriptor* StreamDesc = NULL; HResult = PresentationDesc->GetStreamDescriptorByIndex( i, &bSelected, &StreamDesc ); check( SUCCEEDED( HResult ) ); if( bSelected ) { FIntPoint VideoDimensions = AddStreamToTopology( Topology, PresentationDesc, StreamDesc, SampleGrabberCallback ); if( VideoDimensions != FIntPoint( ForceInit ) ) OutDimensions = VideoDimensions; } StreamDesc->Release( ); } HResult = MediaSession->SetTopology( 0, Topology ); check( SUCCEEDED( HResult ) ); Topology->Release( ); PresentationDesc->Release( ); return OutDimensions; }
HRESULT CPlayer::HandleEvent(UINT_PTR pEventPtr) { HRESULT hrStatus = S_OK; HRESULT hr = S_OK; MediaEventType meType = MEUnknown; IMFMediaEvent *pEvent = (IMFMediaEvent*)pEventPtr; if (pEvent == NULL) { return E_POINTER; } // Get the event type. hr = pEvent->GetType(&meType); CHECK_HR( hr ); // Get the event status. If the operation that triggered the event // did not succeed, the status is a failure code. hr = pEvent->GetStatus(&hrStatus); // Check if the async operation succeeded. if (SUCCEEDED(hr) && FAILED(hrStatus)) { hr = hrStatus; } CHECK_HR( hr ); switch(meType) { case MESessionTopologyStatus: hr = OnTopologyStatus(pEvent); break; case MEEndOfPresentation: hr = OnPresentationEnded(pEvent); CI_LOG_V("Presentation Ended"); break; case MENewPresentation: hr = OnNewPresentation(pEvent); CI_LOG_V( "New Presentation" ); break; case MESessionTopologySet: IMFTopology * topology; GetEventObject<IMFTopology> (pEvent,&topology); WORD nodeCount; topology->GetNodeCount(&nodeCount); CI_LOG_V( "Topo set and we have " << nodeCount << " nodes" ); //cout << "Topo set and we have " << nodeCount << " nodes" << endl; SafeRelease(&topology); break; case MESessionStarted: CI_LOG_V( "Started Session" ); break; case MEBufferingStarted: CI_LOG_I( "Buffering..." ); break; case MEBufferingStopped: CI_LOG_I( "Finished Buffering..." ); break; default: hr = OnSessionEvent(pEvent, meType); break; } done: SafeRelease(&pEvent); return hr; }
CTedPlayer::~CTedPlayer() { HRESULT hr; if(m_pCPM) { m_pCPM->Release(); } for(size_t i = 0; i < m_aTopologies.GetCount(); i++) { CComPtr<IMFCollection> spSourceNodeCollection; IMFTopology* pTopology = m_aTopologies.GetAt(i); hr = pTopology->GetSourceNodeCollection(&spSourceNodeCollection); if(FAILED(hr)) { pTopology->Release(); continue; } DWORD cElements = 0; spSourceNodeCollection->GetElementCount(&cElements); for(DWORD j = 0; j < cElements; j++) { CComPtr<IUnknown> spSourceNodeUnk; CComPtr<IMFTopologyNode> spSourceNode; CComPtr<IMFMediaSource> spSource; hr = spSourceNodeCollection->GetElement(j, &spSourceNodeUnk); if(FAILED(hr)) continue; hr = spSourceNodeUnk->QueryInterface(IID_IMFTopologyNode, (void**) &spSourceNode); if(FAILED(hr)) continue; hr = spSourceNode->GetUnknown(MF_TOPONODE_SOURCE, IID_IMFMediaSource, (void**) &spSource); if(FAILED(hr)) continue; spSource->Shutdown(); } CComPtr<IMFCollection> spOutputNodeCollection; hr = pTopology->GetOutputNodeCollection(&spOutputNodeCollection); if(FAILED(hr)) { pTopology->Release(); continue; } cElements = 0; spOutputNodeCollection->GetElementCount(&cElements); for(DWORD j = 0; j < cElements; j++) { CComPtr<IUnknown> spSinkNodeUnk; CComPtr<IMFTopologyNode> spSinkNode; CComPtr<IUnknown> spStreamSinkUnk; CComPtr<IMFStreamSink> spStreamSink; CComPtr<IMFMediaSink> spSink; hr = spOutputNodeCollection->GetElement(j, &spSinkNodeUnk); if(FAILED(hr)) continue; hr = spSinkNodeUnk->QueryInterface(IID_IMFTopologyNode, (void**) &spSinkNode); if(FAILED(hr)) continue; hr = spSinkNode->GetObject(&spStreamSinkUnk); if(FAILED(hr)) continue; hr = spStreamSinkUnk->QueryInterface(IID_IMFStreamSink, (void**) &spStreamSink); if(FAILED(hr)) continue; hr = spStreamSink->GetMediaSink(&spSink); if(FAILED(hr)) continue; spSink->Shutdown(); } pTopology->Release(); } if(m_spClearSession) { m_spClearSession->Shutdown(); } if(m_spProtectedSession) { m_spProtectedSession->Shutdown(); } }