HRESULT ISampleCaptureGraphBuilder::FindAudioPin( IBaseFilter *pFilter, IPin **ppPin ) { if( !pFilter ) { return E_POINTER; } SmartPtr<IEnumPins> pEnumPins; HRESULT hr = pFilter->EnumPins( &pEnumPins ); if( FAILED( hr ) ) { return hr; } SmartPtr<IPin> pTempPin; ULONG fetched; hr = pEnumPins->Reset( ); while( pTempPin.Release(), S_OK == pEnumPins->Next( 1, &pTempPin, &fetched ) ) { if( IsAudioPin( pTempPin ) ) { (*ppPin) = pTempPin.Detach(); return S_OK; } } return E_FAIL; }
HRESULT CSampleCGB::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 cFetched; HRESULT hr; while(pFilter.Release(),pMoniker.Release(),pEncoders->Next(1,&pMoniker,&cFetched)) { hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(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; }
// // search the encoder that has this special medium // video == TRUE -- look for a video pin // video == FALSE -- look for a audio pin // HRESULT ISampleCaptureGraphBuilder::FindPin( IBaseFilter *pFilter, const REGPINMEDIUM& regPinMedium, PIN_DIRECTION direction, BOOL video, IPin **ppPin) { if( !pFilter ) { return E_POINTER; } SmartPtr<IEnumPins> pEnumPins; HRESULT hr = pFilter->EnumPins( &pEnumPins ); if( FAILED( hr ) ) { return hr; } SmartPtr<IPin> pTempPin; ULONG fetched; REGPINMEDIUM regPinMediumTemp; PIN_DIRECTION dir; hr = pEnumPins->Reset( ); while( pTempPin.Release(), S_OK == pEnumPins->Next( 1, &pTempPin, &fetched ) ) { ASSERT( pTempPin ); hr = pTempPin->QueryDirection( &dir ); if( FAILED( hr ) || dir != direction ) { continue; } hr = GetMedium( pTempPin, regPinMediumTemp ); if( FAILED( hr ) ) { continue; } if( !IsVideoPin( pTempPin ) ) { continue; } if( ::IsEqualGUID( regPinMediumTemp.clsMedium, regPinMedium.clsMedium ) && regPinMediumTemp.dw1 == regPinMedium.dw1 ) { (*ppPin) = pTempPin.Detach(); return S_OK; } } return E_FAIL; }
HRESULT ISampleCaptureGraphBuilder::FindEncoder( IEnumMoniker *pEncoders, REGPINMEDIUM pinMedium, IBaseFilter **ppEncoder ) { if( ! pEncoders ) { return E_INVALIDARG; } if( IsEqualGUID( pinMedium.clsMedium, GUID_NULL ) || IsEqualGUID( pinMedium.clsMedium, KSMEDIUMSETID_Standard ) ) { return E_INVALIDARG; } HRESULT hr; SmartPtr<IBaseFilter> pFilter; SmartPtr<IMoniker> pMoniker; ULONG fetched; SmartPtr<IPin> pPin; 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 = FindPin( pFilter, pinMedium, PINDIR_INPUT, TRUE, &pPin ); if( SUCCEEDED( hr ) ) { *ppEncoder = pFilter.Detach(); return hr; } } return E_FAIL; }
HRESULT CSampleCGB::ConnectPin( IPin *pPin, IBaseFilter *pFilter ) { if(!pPin || !pFilter)return E_INVALIDARG; PIN_DIRECTION pinDirection; HRESULT hr = pPin->QueryDirection(&pinDirection); if(FAILED(hr) || PINDIR_INPUT == pinDirection)return E_FAIL; //Add the filter to the graph BOOL bConnected = FALSE; ULONG cFetched = 0; SmartPtr<IPin> pDownFilterPin; // // Loop through every input pin from downstream filter // and try to connect the pin // SmartPtr<IEnumPins> pEnumDownFiltersPins; hr = pFilter->EnumPins(&pEnumDownFiltersPins); if(FAILED(hr))return hr; while(pDownFilterPin.Release(),pEnumDownFiltersPins->Next(1,&pDownFilterPin,&cFetched)) { hr = pDownFilterPin->QueryDirection(&pinDirection); if(FAILED(hr)) { continue; } if(pinDirection == PINDIR_OUTPUT) { continue; } hr = graph_->ConnectDirect(pPin,pDownFilterPin,NULL); if(SUCCEEDED(hr)) { bConnected = TRUE; break; } } if(!bConnected) { graph_->RemoveFilter(pFilter); return E_FAIL; } return S_OK; }
// // looks for an MPEG2 pin // HRESULT ISampleCaptureGraphBuilder::FindMPEG2Pin( IBaseFilter *pFilter, IPin **ppPin ) { if( !pFilter ) { return E_POINTER; } SmartPtr<IEnumPins> pEnumPins; HRESULT hr = pFilter->EnumPins( &pEnumPins ); if( FAILED( hr ) ) { return hr; } SmartPtr<IPin> pTempPin; ULONG fetched; PIN_DIRECTION dir; hr = pEnumPins->Reset( ); while( pTempPin.Release(), S_OK == pEnumPins->Next( 1, &pTempPin, &fetched ) ) { hr = pTempPin->QueryDirection( &dir ); if( FAILED( hr ) || PINDIR_INPUT == dir ) { continue; } if( IsMPEG2Pin( pTempPin ) ) { (*ppPin) = pTempPin.Detach(); return S_OK; } } return E_FAIL; }
HRESULT CSampleCGB::FindAudioPin( IBaseFilter *pFilter, IPin **ppPin ) { if(!pFilter)return E_POINTER; SmartPtr<IEnumPins> pEnumPins; HRESULT hr = pFilter->EnumPins(&pEnumPins); if(FAILED(hr))return hr; SmartPtr<IPin> pTempPin; ULONG cFetched; hr = pEnumPins->Reset(); if(FAILED(hr))return hr; while(pTempPin.Release(),pEnumPins->Next(1,&pTempPin,&cFetched)) { if(IsAudioPin(pTempPin)) { *ppPin = pTempPin.Detach(); return S_OK; } } return E_FAIL; }
HRESULT ISampleCaptureGraphBuilder::ConnectFilters(IBaseFilter *pUpFilter, IBaseFilter *pDownFilter) { if( !pUpFilter || !pDownFilter ) { return E_INVALIDARG; } // All the need pin & pin enumerator pointers SmartPtr<IEnumPins> pEnumUpFilterPins , pEnumDownFilterPins; SmartPtr<IPin> pUpFilterPin , pDownFilterPin; HRESULT hr = S_OK; // Get the pin enumerators for both the filtera hr = pUpFilter->EnumPins(&pEnumUpFilterPins); if( FAILED( hr ) ) { return hr; } hr= pDownFilter->EnumPins(&pEnumDownFilterPins); if( FAILED( hr ) ) { return hr; } // Loop on every pin on the Upstream Filter BOOL bConnected = FALSE; PIN_DIRECTION pinDir; ULONG nFetched = 0; while(pUpFilterPin.Release( ), S_OK == pEnumUpFilterPins->Next(1, &pUpFilterPin, &nFetched) ) { // Make sure that we have the output pin of the upstream filter hr = pUpFilterPin->QueryDirection( &pinDir ); if( FAILED( hr ) || PINDIR_INPUT == pinDir ) { continue; } // // I have an output pin; loop on every pin on the Downstream Filter // while(pDownFilterPin.Release( ), S_OK == pEnumDownFilterPins->Next(1, &pDownFilterPin, &nFetched) ) { hr = pDownFilterPin->QueryDirection( &pinDir ); if( FAILED( hr ) || PINDIR_OUTPUT == pinDir ) { continue; } // Try to connect them and exit if u can else loop more until you can if(SUCCEEDED(graph_->ConnectDirect(pUpFilterPin, pDownFilterPin, NULL))) { bConnected = TRUE; break; } } hr = pEnumDownFilterPins->Reset(); if( FAILED( hr ) ) { return hr; } } if( !bConnected ) { return E_FAIL; } 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; }