PinPtr CaptureDShow::findUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir) const { IEnumPins *pEnum = NULL; if (FAILED(pFilter->EnumPins(&pEnum))) return PinPtr(); PinPtr matchedPin; IPin *pPin = NULL; while (pEnum->Next(1, &pPin, NULL) == S_OK) { PIN_DIRECTION pinDir; if (FAILED(pPin->QueryDirection(&pinDir)) || pinDir != PinDir) continue; bool ok; bool connected = this->isPinConnected(pPin, &ok); if (!ok || connected) continue; matchedPin = PinPtr(pPin, this->deletePin); pPin->AddRef(); break; } pEnum->Release(); return matchedPin; }
STDMETHODIMP CapturePin::ConnectedTo(IPin **pPin) { PrintFunc(L"CapturePin::ConnectedTo"); if (!connectedPin) return VFW_E_NOT_CONNECTED; IPin *pin = connectedPin; pin->AddRef(); *pPin = pin; return S_OK; }
void DisplayView::OnDumpStream() { if (!current_pin) return ; // now create an instance of this filter CComPtr<IBaseFilter> instance; HRESULT hr; hr = CoCreateInstance(DSUtil::CLSID_Dump, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&instance); if (FAILED(hr)) { // try our internal Dump Filter as an alternative CMonoDump *dump = new CMonoDump(NULL, &hr); hr = dump->NonDelegatingQueryInterface(IID_IBaseFilter, (void**)&instance); } if (SUCCEEDED(hr)) { // now check for a few interfaces int ret = ConfigureInsertedFilter(instance); if (ret < 0) { instance = NULL; } if (instance) { IPin *outpin = current_pin->pin; outpin->AddRef(); // add the filter to graph hr = graph.AddFilter(instance, _T("Dump")); if (FAILED(hr)) { // display error message } else { // connect the pin to the renderer hr = DSUtil::ConnectPin(graph.gb, outpin, instance); graph.RefreshFilters(); graph.SmartPlacement(); graph.Dirty(); Invalidate(); } outpin->Release(); } } instance = NULL; current_pin = NULL; }
void DisplayView::OnFileWriterStream() { if (!current_pin) return ; // now create an instance of this filter CComPtr<IBaseFilter> instance; HRESULT hr; hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&instance); if (FAILED(hr)) { return ; } if (SUCCEEDED(hr)) { // now check for a few interfaces int ret = ConfigureInsertedFilter(instance); if (ret < 0) { instance = NULL; } if (instance) { IPin *outpin = current_pin->pin; outpin->AddRef(); // add the filter to graph hr = graph.AddFilter(instance, _T("File Writer")); if (FAILED(hr)) { // display error message } else { // connect the pin to the renderer hr = DSUtil::ConnectPin(graph.gb, outpin, instance); graph.RefreshFilters(); graph.SmartPlacement(); graph.Dirty(); Invalidate(); } outpin->Release(); } } instance = NULL; current_pin = NULL; }
// IEnumPins STDMETHODIMP CaptureEnumPins::Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched) { UINT nFetched = 0; if(curPin == 0 && cPins > 0) { IPin *pPin = filter->GetCapturePin(); *ppPins = pPin; pPin->AddRef(); nFetched = 1; curPin++; } if(pcFetched) *pcFetched = nFetched; return (nFetched == cPins) ? S_OK : S_FALSE; }
//取设备输出Pin IPin* CGraphBuilder::GetPin(PIN_DIRECTION PinDirection) { IPin * foundPin = NULL; if( m_pBaseFilter ) { //创建枚举 IEnumPins * pinEnum = NULL; if ( m_pBaseFilter->EnumPins(&pinEnum)==S_OK ) { //复位 pinEnum->Reset(); //循环每个PIN ULONG fetchCount = 0; IPin * pin = NULL; while ( !foundPin && S_OK==(pinEnum->Next(1, &pin, &fetchCount)) && fetchCount ) { if (pin) { //得到PIN信息 PIN_INFO pinInfo; if ( S_OK==pin->QueryPinInfo(&pinInfo) ) { //检测是否是输出PIN if (pinInfo.dir == PinDirection) { pin->AddRef(); //加一引用 foundPin = pin; //返回PIN } pinInfo.pFilter->Release(); } pin->Release(); } } pinEnum->Release(); } } if (foundPin) { foundPin->Release(); } return foundPin; }
/* IEnumPins */ STDMETHODIMP SampleCaptureEnumPins::Next( ULONG cPins, IPin ** ppPins, ULONG * pcFetched ) { #ifdef DEBUG_DSHOW_L1 ATLTRACE( "SampleCaptureEnumPins::Next" ); #endif unsigned int i_fetched = 0; if( i_position < 1 && cPins > 0 ) { IPin *pPin = p_filter->CustomGetPin(); *ppPins = pPin; pPin->AddRef(); i_fetched = 1; i_position++; } if( pcFetched ) *pcFetched = i_fetched; return (i_fetched == cPins) ? S_OK : S_FALSE; };
/* Return an AddRef()'d pointer to the connected pin if there is one */ STDMETHODIMP CBasePin::ConnectedTo( IPin **ppPin ) { CheckPointer(ppPin,E_POINTER); ValidateReadWritePtr(ppPin,sizeof(IPin *)); // // It's pointless to lock here. // The caller should ensure integrity. // IPin *pPin = m_Connected; *ppPin = pPin; if (pPin != NULL) { pPin->AddRef(); return S_OK; } else { ASSERT(*ppPin == NULL); return VFW_E_NOT_CONNECTED; } }
void gui::dx::audio_playerX::initialize_speedup_filter() { if (speedup_filter_available_valid && !speedup_filter_available) { // We don't seem to have the filter. Too bad. return; } // Either the filter exists or we haven't tried yet. Let's try to create // it and remember whether it worked. IBaseFilter *pNewFilter = NULL; HRESULT res; res = CoCreateInstance(CLSID_TPBVupp69, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pNewFilter); if (res != S_OK) { traceX("dx_audio_player: Speedup filter not available, error 0x%x", res); speedup_filter_available = false; speedup_filter_available_valid = true; return; } res = m_graph_builder->AddFilter(pNewFilter, NULL); if (res != S_OK) { traceX("dx_audio_player: AddFilter(Speedup filter): error 0x%x", res); pNewFilter->Release(); return; } speedup_filter_available = true; speedup_filter_available_valid = true; // AM_DBG lib::debugX("dx_audio_player: added speedup filter to graph"); // Next step: find out where we want to add the filter to the graph. // We iterate over the filter graph, then for each item in the graph // we iterate over the connected output pins util we find one we like. IPin *pOutputPin = NULL; IPin *pInputPin = NULL; IEnumFilters *pEnumFilters = NULL; res = m_graph_builder->EnumFilters(&pEnumFilters); if (res != S_OK) { traceX("dx_audio_filter: EnumFilters: error 0x%x", res); return; } IBaseFilter *pCurFilter; while (pOutputPin == NULL && (res=pEnumFilters->Next(1, &pCurFilter, NULL)) == S_OK) { AM_DBG { FILTER_INFO info; LPWSTR vendorInfo; res = pCurFilter->QueryFilterInfo(&info); if (res != S_OK) info.achName[0] = 0; res = pCurFilter->QueryVendorInfo(&vendorInfo); if (res != S_OK) vendorInfo = L""; //ambulant::lib::textptr tInfo(info.achName); //ambulant::lib::textptr tVendorInfo(vendorInfo); //lib::debugX("dx_audio_filter: filter found: '%s' vendor '%s'", tInfo.c_str(), tVendorInfo.c_str()); } IEnumPins *pEnumPins; res = pCurFilter->EnumPins(&pEnumPins); IPin *pCurPin; while (pOutputPin == NULL && (res=pEnumPins->Next(1, &pCurPin, NULL)) == S_OK) { AM_MEDIA_TYPE mediaType; PIN_DIRECTION curPinDir; res = pCurPin->QueryDirection(&curPinDir); HRESULT res2 = pCurPin->ConnectionMediaType(&mediaType); if (res == S_OK && res2 == S_OK && curPinDir == PINDIR_OUTPUT && mediaType.majortype == MEDIATYPE_Audio&& mediaType.subtype == MEDIASUBTYPE_PCM){ pOutputPin = pCurPin; res = pOutputPin->ConnectedTo(&pInputPin); if (res != S_OK) { // This output pin was the correct type, but not connected. // So it cannot be the one we're looking for. pOutputPin = pInputPin = NULL; } else { // Found it! pOutputPin->AddRef(); pInputPin->AddRef(); } } if (res2 == S_OK) { if (mediaType.cbFormat != 0) { CoTaskMemFree((PVOID)mediaType.pbFormat); } } pCurPin->Release(); } if (res != S_FALSE && res != S_OK) traceX("dx_audio_filter: enumerating pins: error 0x%x", res); pEnumPins->Release(); pCurFilter->Release(); } if (res != S_FALSE && res != S_OK) traceX("dx_audio_filter: enumerating filters: error 0x%x", res); pEnumFilters->Release(); // We have the correct pins now. if (pOutputPin) { traceX("dx_audio_filter: found the right pins!"); } else { traceX("dx_audio_filter: could not find a good pin"); pOutputPin->Release(); pInputPin->Release(); return; } // Now we need to find the pins on our speedup filter. IPin *pFilterInputPin = NULL; IPin *pFilterOutputPin = NULL; IEnumPins *pEnumPins; res = pNewFilter->EnumPins(&pEnumPins); IPin *pCurPin; while (res=pEnumPins->Next(1, &pCurPin, NULL) == S_OK) { PIN_DIRECTION pinDir; res = pCurPin->QueryDirection(&pinDir); //assert(res == S_OK); if (pinDir == PINDIR_INPUT) { if (pFilterInputPin) { traceX("dx_audio_filter: multiple input pins on filter"); goto bad; } pFilterInputPin = pCurPin; pFilterInputPin->AddRef(); } else { if (pFilterOutputPin) { traceX("dx_audio_filter: multiple output pins on filter"); goto bad; } pFilterOutputPin = pCurPin; pFilterOutputPin->AddRef(); } } if (!pFilterInputPin) { traceX("dx_audio_filter: no input pin on filter"); goto bad; } if (!pFilterOutputPin) { traceX("dx_audio_filter: no output pin on filter"); goto bad; } // We have everything. Sever the old connection and insert the filter. res = m_graph_builder->Disconnect(pOutputPin); if (res) { traceX("dx_audio_filter: Severing old connection: error 0x%x", res); goto bad; } res = m_graph_builder->Disconnect(pInputPin); if (res) { traceX("dx_audio_filter: Severing old connection: error 0x%x", res); goto bad; } res = m_graph_builder->Connect(pOutputPin, pFilterInputPin); if (res) { traceX("dx_audio_filter: Creating filter input connection: error 0x%x", res); goto bad; } res = m_graph_builder->Connect(pFilterOutputPin, pInputPin); if (res) { traceX("dx_audio_filter: Creating filter output connection: error 0x%x", res); goto bad; } // Finally remember the interface to set speedup/slowdown, and register ourselves // in the global pool (so Amis can change our speed). res = pNewFilter->QueryInterface(IID_IVuppInterface, (void**) &m_audio_speedup); if (res != S_OK) { traceX("dx_audio_filter: filter does not provide IVuppInterface"); goto bad; } set_rate(s_current_playback_rate); bad: if (pOutputPin) pOutputPin->Release(); if (pInputPin) pInputPin->Release(); if (pFilterOutputPin) pFilterOutputPin->Release(); if (pFilterInputPin) pFilterInputPin->Release(); return; }
HRESULT CFLVConverter::AssembeAudioBranch(const CParameters & param, IPin* pSrc, IPin* pDest) { HRESULT hr=S_OK; IPin* pEndPin = NULL; AM_MEDIA_TYPE mtSrc; AM_MEDIA_TYPE *pmtWrp = NULL; WE_WAVEFORMATEX* pwfxSrc = NULL; WE_WAVEFORMATEX* pwfxWrp = NULL; ULONG ulFetched = 0; if(!pSrc || !pDest) return E_POINTER; m_wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; m_wfx.nChannels = 1; m_wfx.nSamplesPerSec = 11025; m_wfx.wBitsPerSample = 0; m_wfx.nBlockAlign = 1; m_wfx.nAvgBytesPerSec = 2500; m_wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES; MPEGLAYER3WAVEFORMAT* pMp3Format = (MPEGLAYER3WAVEFORMAT*) &m_wfx; pMp3Format->wID = MPEGLAYER3_ID_MPEG; pMp3Format->fdwFlags = MPEGLAYER3_FLAG_PADDING_ON;//MPEGLAYER3_FLAG_PADDING_OFF; pMp3Format->nBlockSize = 132; pMp3Format->nFramesPerBlock = 1; pMp3Format->nCodecDelay = 1393; CComPtr<IMediaSeeking> cpMediaSeeking; hr = pSrc->QueryInterface(IID_IMediaSeeking, (void **)&cpMediaSeeking); if(SUCCEEDED(hr)) { hr = cpMediaSeeking->SetTimeFormat(&TIME_FORMAT_SAMPLE); if(SUCCEEDED(hr)) { cpMediaSeeking->GetDuration(&m_llAudioSamplesCount); } } pEndPin = pSrc; pEndPin->AddRef(); CComPtr<IBaseFilter> cpAudioSkipFilter; hr = CreateAndInsertFilter(pGB, CLSID_CAudioSkipper, &cpAudioSkipFilter, L"AudioSkipper"); if(SUCCEEDED(hr)) { hr = JoinFilterToChain(pGB, cpAudioSkipFilter, &pEndPin); CComPtr<IAudioSkip> cpAudioSkip; hr = cpAudioSkipFilter->QueryInterface(IID_IAudioSkip, (void**) &cpAudioSkip); if(SUCCEEDED(hr)) { cpAudioSkip->SetSamplesCount(m_llVideoFramesCount, m_llAudioSamplesCount); cpAudioSkip->SetIntervals((void*)param.GetAllDeletedInterval(), (void*)param.GetAudioDeletedInterval()); } } if(FAILED(hr)) { SAFE_RELEASE(pEndPin); return hr; } hr = pSrc->ConnectionMediaType(&mtSrc); if(SUCCEEDED(hr)) { pwfxSrc = (WE_WAVEFORMATEX*) mtSrc.pbFormat; if((pwfxSrc->wFormatTag!=m_wfx.wFormatTag) || (pwfxSrc->nSamplesPerSec!=m_wfx.nSamplesPerSec)) { CComPtr<IBaseFilter> cpAcmWrapper = NULL; hr = CoCreateInstance(CLSID_ACMWrapper, NULL, CLSCTX_INPROC, IID_IBaseFilter, (LPVOID *)&cpAcmWrapper); if(SUCCEEDED(hr)) { hr = JoinFilterToChain(pGB, cpAcmWrapper, L"ACM Wrapper", &pEndPin); if(SUCCEEDED(hr)) { CComPtr<IAMStreamConfig> cpAudioStreamConfig; hr = pEndPin->QueryInterface(IID_IAMStreamConfig,(void **)&cpAudioStreamConfig); if(SUCCEEDED(hr)) { hr = cpAudioStreamConfig->GetFormat(&pmtWrp); if(SUCCEEDED(hr)) { pwfxWrp = (WE_WAVEFORMATEX*) pmtWrp->pbFormat; if(WAVE_FORMAT_PCM!=m_wfx.wFormatTag) { WAVEFORMATEX wfxSrs; wfxSrs.nChannels = m_wfx.nChannels; wfxSrs.wFormatTag = WAVE_FORMAT_PCM; MMRESULT mmr = acmFormatSuggest(NULL, &m_wfx, &wfxSrs, sizeof(wfxSrs),ACM_FORMATSUGGESTF_NCHANNELS| ACM_FORMATSUGGESTF_WFORMATTAG); if(MMSYSERR_NOERROR==mmr) { pwfxWrp->nChannels = wfxSrs.nChannels; pwfxWrp->nSamplesPerSec = wfxSrs.nSamplesPerSec; pwfxWrp->nAvgBytesPerSec = wfxSrs.nAvgBytesPerSec; pwfxWrp->nBlockAlign = wfxSrs.nBlockAlign; pwfxWrp->wBitsPerSample = wfxSrs.wBitsPerSample; } } else { pwfxWrp->nChannels = m_wfx.nChannels; pwfxWrp->nSamplesPerSec = m_wfx.nSamplesPerSec; pwfxWrp->nAvgBytesPerSec = m_wfx.nAvgBytesPerSec; pwfxWrp->nBlockAlign = m_wfx.nBlockAlign; pwfxWrp->wBitsPerSample = m_wfx.wBitsPerSample; } hr = cpAudioStreamConfig->SetFormat(pmtWrp); DeleteMediaType(pmtWrp); } } } } if(WAVE_FORMAT_PCM!=m_wfx.wFormatTag) { CComPtr<IBaseFilter> cpAComp; hr = CreateAudioCompressor(&m_wfx, &cpAComp); if(S_OK==hr) { hr = JoinFilterToChain(pGB, cpAComp, L"Audio compressor", &pEndPin); if(SUCCEEDED(hr)) { CComPtr<IBaseFilter> cpTimeRemover; hr = CoCreateInstance(CLSID_CTimeRemover, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&cpTimeRemover); if(SUCCEEDED(hr)) { //this filter needs as workaround for 0x80040228 error code generated by some //audio compressors: hr = JoinFilterToChain(pGB, cpTimeRemover, L"TimeStamp remover", &pEndPin); } } } } } } hr = pGB->Connect(pDest, pEndPin); FreeMediaType(mtSrc); SAFE_RELEASE(pEndPin); return hr; }