HRESULT CSampleCGB::BuildMPEG2Segment( IBaseFilter *pFilter ) { if(!pFilter)return E_POINTER; HRESULT hr = AddMPEG2Demux(); if(FAILED(hr))return hr; //在filter上查找MPEG2 pin SmartPtr<IPin> pPin; hr = FindMPEG2Pin(pFilter,&pPin); if(SUCCEEDED(hr)) { hr = ConnectPin(pPin,pMPEG2Demux_); if(FAILED(hr)) { graph_->RemoveFilter(pMPEG2Demux_); return E_FAIL; } return S_OK; } // // no pins that streams directly MPEG2 stream // hr = FindVideoPin(pFilter,&pPin); if(FAILED(hr)) { graph_->RemoveFilter(pMPEG2Demux_); return hr;// no video pin } return hr; }
HRESULT ISampleCaptureGraphBuilder::RenderToMPEG2Demux( IPin *pPin, IEnumMoniker *pEncoders) { if( !pPin || !pEncoders ) { return E_INVALIDARG; } REGPINMEDIUM pinMedium ; pinMedium.clsMedium = GUID_NULL; pinMedium.dw1 = 0; pinMedium.dw2 = 0; SmartPtr<IBaseFilter> pFilter; SmartPtr<IMoniker> pMoniker; ULONG fetched; HRESULT hr; while( pFilter.Release(), pMoniker.Release(), S_OK == pEncoders->Next( 1, &pMoniker, &fetched ) ) { hr = pMoniker->BindToObject( 0, 0, IID_IBaseFilter, reinterpret_cast<void **>( &pFilter ) ); if( FAILED( hr ) ) { continue; } hr = graph_->AddFilter( pFilter, L"Encoder" ); if( FAILED( hr ) ) { continue; } hr = ConnectPin( pPin, pFilter ); if( FAILED( hr ) ) { graph_->RemoveFilter( pFilter ); continue; } hr = ConnectEncoderToMPEG2Demux( pFilter, pinMedium ); if( SUCCEEDED( hr ) ) { pEncoder_ = pFilter; return S_OK; } graph_->RemoveFilter( pFilter ); } return E_FAIL; }
HRESULT ISampleCaptureGraphBuilder::RenderToMPEG2Demux( IPin *pPin, const REGPINMEDIUM& pinMedium, IEnumMoniker *pEncoders ) { // // The pin has a special medium, // there shold be an encoder with the same // medium // SmartPtr< IBaseFilter > pEncoder; HRESULT hr = FindEncoder( pEncoders, pinMedium, &pEncoder ); if( FAILED( hr ) ) { return hr; } hr = graph_->AddFilter( pEncoder, L"Encoder" ); if( FAILED( hr ) ) { return hr; } hr = ConnectPin( pPin, pEncoder ); if( FAILED( hr ) ) { hr = graph_->RemoveFilter( pEncoder ); return hr; } // // the video pin was rendered to the same // ( hardware? ) encoder with the same mediu // hr = ConnectEncoderToMPEG2Demux( pEncoder, pinMedium ); if( FAILED( hr ) ) { hr = graph_->RemoveFilter( pEncoder ); return hr; } pEncoder_ = pEncoder; return S_OK; }
HRESULT ISampleCaptureGraphBuilder::ConnectAudioPinToMultiplexer( IPin *pPin, IBaseFilter *pMultiplexer) { if( !pPin || !pMultiplexer ) { return E_INVALIDARG; } REGPINMEDIUM pinMedium; HRESULT hr = GetMedium( pPin, pinMedium ); if( FAILED( hr ) ) { return hr; } SmartPtr<IBaseFilter> pEncoder; SmartPtr<IEnumMoniker> pEncoders; if( FALSE == ::IsEqualGUID( pinMedium.clsMedium, GUID_NULL ) ) { // // search through encoders category; identify // the encoder using the medium // hr = GetEncodersByCategory( &pEncoders ); if( FAILED( hr ) ) { return hr; } hr = FindEncoder( pEncoders, pinMedium, &pEncoder ); if( SUCCEEDED( hr ) ) { hr = graph_->AddFilter( pEncoder, L"Audio Encoder" ); if( SUCCEEDED( hr ) && SUCCEEDED( ConnectPin( pPin, pEncoder ) ) && SUCCEEDED( ConnectFilters( pEncoder, pMultiplexer ) ) ) { return S_OK; } } pEncoders = NULL; hr = GetEncodersByEnumerating( pPin, pinMedium, &pEncoders ); if( FAILED( hr ) ) { return hr; } hr = FindEncoder( pEncoders, pinMedium, &pEncoder ); if( SUCCEEDED( hr ) ) { hr = graph_->AddFilter( pEncoder, L"Audio Encoder" ); if( SUCCEEDED( hr ) && SUCCEEDED( ConnectPin( pPin, pEncoder ) ) && SUCCEEDED( ConnectFilters( pEncoder, pMultiplexer ) ) ) { return S_OK; } } return E_FAIL; } // // Search throgh the codec category // hr = GetEncodersByCategory( &pEncoders ); if( FAILED( hr ) ) { return hr; } SmartPtr<IBaseFilter> pFilter; SmartPtr<IMoniker> pMoniker; ULONG fetched; while( pFilter.Release(), pMoniker.Release(), S_OK == pEncoders->Next( 1, &pMoniker, &fetched ) ) { hr = pMoniker->BindToObject( 0, 0, IID_IBaseFilter, reinterpret_cast<void **>( &pFilter ) ); if( FAILED( hr ) ) { continue; } hr = graph_->AddFilter( pFilter, L"Audio Encoder" ); if( FAILED( hr ) ) { continue; } hr = ConnectPin( pPin, pFilter ); if( FAILED( hr ) ) { graph_->RemoveFilter( pFilter ); continue; } hr = ConnectFilters( pFilter, pMultiplexer ); if( SUCCEEDED( hr ) ) { return S_OK; } graph_->RemoveFilter( pFilter ); } return E_FAIL; }
HRESULT ISampleCaptureGraphBuilder::BuildMPEG2Segment(IBaseFilter *pFilter) { if( ! pFilter ) { return E_FAIL; } HRESULT hr = AddMPEG2Demux( ); if( FAILED( hr ) ) { return hr; } // // Search a MPEG2 pin on the // filter // SmartPtr<IPin> pPin; hr = FindMPEG2Pin( pFilter, &pPin ); if( SUCCEEDED( hr ) ) { hr = ConnectPin( pPin, pMPEG2Demux_ ); if( FAILED( hr ) ) { graph_->RemoveFilter( pMPEG2Demux_ ); return E_FAIL; } return S_OK; } // // no pins that streams directly MPEG2 stream // hr = FindVideoPin( pFilter, &pPin ); if( FAILED( hr ) ) { graph_->RemoveFilter( pMPEG2Demux_ ); return hr; // no video pin } hr = RenderToMPEG2Demux( pPin ); if( FAILED( hr ) ) { graph_->RemoveFilter( pMPEG2Demux_ ); return hr; } SmartPtr<IPin> pAudioPin; hr = FindAudioPin( pFilter, &pAudioPin ); if( FAILED( hr ) ) { // // don't bother with audio // return S_OK; } // // try to connect the audio pin directly to encoder // if this is not possible, then try to find an encoder // and connect it to the multiplexer // ASSERT( pEncoder_ ); hr = ConnectPin( pAudioPin, pEncoder_ ); if( FAILED( hr ) ) { hr = ConnectAudioPinToMultiplexer( pAudioPin, pMultiplexer_ ); } return S_OK; }