// Create the topology. HRESULT CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo) { IMFTopology *pTopology = NULL; IMFPresentationDescriptor *pPD = NULL; IMFStreamDescriptor *pSD = NULL; IMFMediaTypeHandler *pHandler = NULL; IMFTopologyNode *pNode1 = NULL; IMFTopologyNode *pNode2 = NULL; HRESULT hr = S_OK; DWORD cStreams = 0; CHECK_HR(hr = MFCreateTopology(&pTopology)); CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD)); CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams)); for (DWORD i = 0; i < cStreams; i++) { // In this example, we look for audio streams and connect them to the sink. BOOL fSelected = FALSE; GUID majorType; CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &pSD)); CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler)); CHECK_HR(hr = pHandler->GetMajorType(&majorType)); if (majorType == MFMediaType_Video && fSelected) { CHECK_HR(hr = AddSourceNode(pTopology, pSource, pPD, pSD, &pNode1)); CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivate, 0, &pNode2)); CHECK_HR(hr = pNode1->ConnectOutput(0, pNode2, 0)); break; } else { CHECK_HR(hr = pPD->DeselectStream(i)); } SafeRelease(&pSD); SafeRelease(&pHandler); } *ppTopo = pTopology; (*ppTopo)->AddRef(); done: SafeRelease(&pTopology); SafeRelease(&pNode1); SafeRelease(&pNode2); SafeRelease(&pPD); SafeRelease(&pSD); SafeRelease(&pHandler); return hr; }
HRESULT CTedMediaFileRenderer::CreatePartialTopology(IMFTopology** ppPartialTopology) { HRESULT hr; IMFTopology* pPartialTopology; CComPtr<IMFMediaSource> spSource; IFC( MFCreateTopology(&pPartialTopology) ); IFC( CreateSource(&spSource) ); IFC( BuildTopologyFromSource(pPartialTopology, spSource) ); *ppPartialTopology = pPartialTopology; Cleanup: return hr; }
/** 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::CreateTopologyFromSource(IMFTopology **ppTopology) { TRACE((L"CPlayer::CreateTopologyFromSource\n")); assert(m_pSession != NULL); assert(m_pSource != NULL); HRESULT hr = S_OK; IMFTopology *pTopology = NULL; IMFPresentationDescriptor* pSourcePD = NULL; DWORD cSourceStreams = 0; // Create a new topology. CHECK_HR(hr = MFCreateTopology(&pTopology)); // Create the presentation descriptor for the media source. CHECK_HR(hr = m_pSource->CreatePresentationDescriptor(&pSourcePD)); // Get the number of streams in the media source. CHECK_HR(hr = pSourcePD->GetStreamDescriptorCount(&cSourceStreams)); TRACE((L"Stream count: %d\n", cSourceStreams)); // For each stream, create the topology nodes and add them to the topology. for (DWORD i = 0; i < cSourceStreams; i++) { CHECK_HR(hr = AddBranchToPartialTopology(pTopology, pSourcePD, i)); } // Return the IMFTopology pointer to the caller. if (SUCCEEDED(hr)) { *ppTopology = pTopology; (*ppTopology)->AddRef(); } done: SAFE_RELEASE(pTopology); SAFE_RELEASE(pSourcePD); return hr; }
// Create a playback topology from a media source. // Receives a pointer to the topology. IMFTopologyPtr CreatePlaybackTopology( IMFMediaSourcePtr pSource, // Media source. IMFPresentationDescriptorPtr pPD, // Presentation descriptor. HWND hVideoWnd // Video window. ) { IMFTopologyPtr pTopology; DWORD cSourceStreams = 0; // Create a new topology. THROW_IF_ERR(MFCreateTopology(&pTopology)); // Get the number of streams in the media source. THROW_IF_ERR(pPD->GetStreamDescriptorCount(&cSourceStreams)); // For each stream, create the topology nodes and add them to the topology. for (DWORD i = 0; i < cSourceStreams; i++) { AddBranchToPartialTopology(pTopology, pSource, pPD, i, hVideoWnd); } // Return the IMFTopology pointer to the caller. return pTopology; }
HRESULT tTVPMFPlayer::CreateVideoPlayer() { if( MediaSession.p ) { return S_OK; // 既に作成済み } HRESULT hr = CreateChildWindow(); if( hr != S_OK ) return hr; HWND hWnd = GetChildWindow(); if( hWnd == NULL || hWnd == INVALID_HANDLE_VALUE ) return E_FAIL; if( FAILED(hr = MFCreateMediaSession( NULL, &MediaSession )) ) { TVPThrowExceptionMessage(L"Faild to create Media session."); } if( FAILED(hr = MediaSession->BeginGetEvent( PlayerCallback, NULL )) ) { TVPThrowExceptionMessage(L"Faild to begin get event."); } CComPtr<IMFSourceResolver> pSourceResolver; if( FAILED(hr = MFCreateSourceResolver(&pSourceResolver)) ) { TVPThrowExceptionMessage(L"Faild to create source resolver."); } MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID; CComPtr<IUnknown> pSource; if( FAILED(hr = pSourceResolver->CreateObjectFromByteStream( ByteStream, StreamName.c_str(), MF_RESOLUTION_MEDIASOURCE, NULL, &ObjectType, (IUnknown**)&pSource )) ) { //if( FAILED(hr = pSourceResolver->CreateObjectFromURL( L"C:\\krkrz\\bin\\win32\\data\\test.mp4", // MF_RESOLUTION_MEDIASOURCE, NULL, &ObjectType, (IUnknown**)&pSource)) ) { TVPThrowExceptionMessage(L"Faild to open stream."); } if( ObjectType != MF_OBJECT_MEDIASOURCE ) { TVPThrowExceptionMessage(L"Invalid media source."); } //CComPtr<IMFMediaSource> pMediaSource; if( FAILED(hr = pSource.QueryInterface(&MediaSource)) ) { TVPThrowExceptionMessage(L"Faild to query Media source."); } if( FAILED(hr = MFCreateTopology(&Topology)) ) { TVPThrowExceptionMessage(L"Faild to create Topology."); } CComPtr<IMFPresentationDescriptor> pPresentationDescriptor; if( FAILED(hr = MediaSource->CreatePresentationDescriptor(&pPresentationDescriptor)) ) { TVPThrowExceptionMessage(L"Faild to create Presentation Descriptor."); } DWORD streamCount; if( FAILED(hr = pPresentationDescriptor->GetStreamDescriptorCount(&streamCount)) ) { TVPThrowExceptionMessage(L"Faild to get stream count."); } if( streamCount < 1 ) { TVPThrowExceptionMessage(L"Not found media stream."); } for( DWORD i = 0; i < streamCount; i++ ) { if( FAILED(hr = AddBranchToPartialTopology(Topology, MediaSource, pPresentationDescriptor, i, hWnd)) ) { TVPThrowExceptionMessage(L"Faild to add nodes."); } } pPresentationDescriptor->GetUINT64(MF_PD_DURATION, (UINT64*)&HnsDuration); if( FAILED(hr = MediaSession->SetTopology( 0, Topology )) ) { TVPThrowExceptionMessage(L"Faild to set topology."); } return hr; }
HRESULT CreateTopology(IMFMediaSource *pSource, IMFMediaSink *pSink, IMFTopology **ppTopology) { CComPtr<IMFTopology> pTopology; CComPtr<IMFPresentationDescriptor> pPD; CComPtr<IMFStreamDescriptor> pSD; HRESULT hr = S_OK; DWORD cStreams = 0; hr = MFCreateTopology(&pTopology); if (SUCCEEDED(hr)) { hr = pSource->CreatePresentationDescriptor(&pPD); } if (SUCCEEDED(hr)) { hr = pPD->GetStreamDescriptorCount(&cStreams); } BOOL fConnected = FALSE; if (SUCCEEDED(hr)) { GUID majorType = GUID_NULL; BOOL fSelected = FALSE; for (DWORD iStream = 0; iStream < cStreams; iStream++) { hr = pPD->GetStreamDescriptorByIndex(iStream, &fSelected, &pSD); if (FAILED(hr)) { break; } // If the stream is not selected by default, ignore it. if (!fSelected) { continue; } // Get the major media type. hr = GetStreamMajorType(pSD, &majorType); if (FAILED(hr)) { break; } // If it's not audio, deselect it and continue. if (majorType != MFMediaType_Audio) { // Deselect this stream hr = pPD->DeselectStream(iStream); if (FAILED(hr)) { break; } else { continue; } } // It's an audio stream, so try to create the topology branch. hr = CreateTopologyBranch(pTopology, pSource, pPD, pSD, pSink); // Set our status flag. if (SUCCEEDED(hr)) { fConnected = TRUE; } // At this point we have reached the first audio stream in the // source, so we can stop looking (whether we succeeded or failed). break; } } if (SUCCEEDED(hr)) { // Even if we succeeded, if we didn't connect any streams, it's a failure. // (For example, it might be a video-only source. if (!fConnected) { hr = E_FAIL; } } if (SUCCEEDED(hr)) { *ppTopology = pTopology; (*ppTopology)->AddRef(); } return hr; }