HRESULT GetPin( IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin) { CComPtr< IEnumPins > pEnum; *ppPin = NULL; HRESULT hr = pFilter->EnumPins(&pEnum); if(FAILED(hr)) return hr; ULONG ulFound; IPin *pPin; hr = E_FAIL; while(S_OK == pEnum->Next(1, &pPin, &ulFound)) { PIN_DIRECTION pindir = (PIN_DIRECTION)3; pPin->QueryDirection(&pindir); if(pindir == dirrequired) { if(iNum == 0) { *ppPin = pPin; // Found requested pin, so clear error hr = S_OK; break; } iNum--; } pPin->Release(); } return hr; }
gboolean gst_dshow_get_pin_from_filter (IBaseFilter * filter, PIN_DIRECTION pindir, IPin ** pin) { gboolean ret = FALSE; IEnumPins *enumpins = NULL; IPin *pintmp = NULL; HRESULT hres; *pin = NULL; hres = filter->EnumPins (&enumpins); if (FAILED (hres)) { return ret; } while (enumpins->Next (1, &pintmp, NULL) == S_OK) { PIN_DIRECTION pindirtmp; hres = pintmp->QueryDirection (&pindirtmp); if (hres == S_OK && pindir == pindirtmp) { *pin = pintmp; ret = TRUE; break; } pintmp->Release (); } enumpins->Release (); return ret; }
HRESULT CountTotalFilterPins(IBaseFilter *pFilter, ULONG *pulPins) { HRESULT hr; IEnumPins *pEnum=0; ULONG ulFound; IPin *pPin; // Verify input if (!pFilter || !pulPins) return E_POINTER; // Clear number of pins found *pulPins = 0; // Get pin enumerator hr = pFilter->EnumPins(&pEnum); if(FAILED(hr)) return hr; // Count every pin on the filter, ignoring direction while(S_OK == pEnum->Next(1, &pPin, &ulFound)) { (*pulPins)++; pPin->Release(); } pEnum->Release(); return hr; }
// ConnectFilters // Connects a pin of an upstream filter to the pDest downstream filter HRESULT ConnectFilters( IGraphBuilder *pGraph, // Filter Graph Manager. IPin *pOut, // Output pin on the upstream filter. IBaseFilter *pDest) // Downstream filter. { if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL)) { return E_POINTER; } #ifdef debug PIN_DIRECTION PinDir; pOut->QueryDirection(&PinDir); _ASSERTE(PinDir == PINDIR_OUTPUT); #endif // Find an input pin on the downstream filter. IPin *pIn = 0; HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn); if (FAILED(hr)) { return hr; } // Try to connect them. hr = pGraph->Connect(pOut, pIn); pIn->Release(); return hr; }
//----------------------------------------------------------------------------- // GetPin // Find the pin of the specified format type on the given filter // This method leaves an outstanding reference on the pin if successful HRESULT CDSUtils::GetPin(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter && pFormat && ppPin) { CComPtr<IEnumPins> pIEnumPins = NULL; hr = pFilter->EnumPins(&pIEnumPins); if (SUCCEEDED(hr)) { // find the pin with the specified format IPin* pIPin = NULL; while (S_OK == pIEnumPins->Next(1, &pIPin, NULL)) { // match the pin direction PIN_DIRECTION pinDir; pIPin->QueryDirection(&pinDir); if (pinDir == PinDir) { // match pin direction check the first media type returned from the upstream pin CComPtr<IEnumMediaTypes> pIEnumMT = NULL; hr = pIPin->EnumMediaTypes(&pIEnumMT); if (SUCCEEDED(hr)) { AM_MEDIA_TYPE* pmt = NULL; hr = pIEnumMT->Next(1, &pmt, NULL); if (S_OK == hr) { if (pmt->majortype == *pFormat) { // found the pin with the specified format *ppPin = pIPin; DeleteMediaType(pmt); break; } else { DeleteMediaType(pmt); } } } } SAFE_RELEASE(pIPin); } if (NULL == *ppPin) { // failed to find the named pin hr = E_FAIL; } } } else { hr = E_INVALIDARG; } return hr; }
HRESULT recChannel_t::set_rate(float FR) { __CONTEXT("recChannel_t::set_rate"); if (FR<1) { return S_OK; } float factorRate = FR/30; int hr = 0; if (factorRate<0.1) factorRate = 0.1; frameRate = factorRate; IAMStreamConfig *pConfig = NULL; if ((camInfo->getKind() == SHARED || camInfo->getKind() == CAM) && actualFormat.pbFormat != NULL) { VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*) actualFormat.pbFormat; double newFR = 10000000.0/FR; pVih->AvgTimePerFrame = newFR; camInfo->setRate(pVih->AvgTimePerFrame); if (camInfo->getKind() == CAM) { IPin * pInput = NULL; get_camInfo()->output->ConnectedTo(&pInput); if (mapping) { pControl->Stop(); } if (pInput) { get_camInfo()->output->Disconnect(); pInput->Disconnect(); } hr = get_camInfo()->output->QueryInterface(IID_IAMStreamConfig, (void**)&pConfig); if (pConfig) { int hr = pConfig->SetFormat(&actualFormat); errorCheck(hr); pConfig->Release(); } if (pInput) { hr = pGraph->Connect(get_camInfo()->output,pInput); errorCheck(hr); } errorCheck(hr); if (mapping) { pControl->Run(); } } } return hr; }
void CCaptureDevice::SetCaptureBufferSize(void) { IPin * pCapturePin = GetPin(); if (pCapturePin) { DWORD dwBytesPerSec = 0; AM_MEDIA_TYPE * pmt = {0}; IAMStreamConfig * pCfg = NULL; HRESULT hr = pCapturePin->QueryInterface(IID_IAMStreamConfig, (void **)&pCfg); if ( hr==S_OK ) { hr = pCfg->GetFormat(&pmt); if ( hr==S_OK ) { WAVEFORMATEX *pWF = (WAVEFORMATEX *) pmt->pbFormat; dwBytesPerSec = pWF->nAvgBytesPerSec; pWF->nChannels = 1; pWF->wBitsPerSample = 8; pWF->nSamplesPerSec = 11025; pWF->nAvgBytesPerSec = pWF->nSamplesPerSec * pWF->nChannels * pWF->wBitsPerSample / 8; pWF->nBlockAlign = 1; /* info.cbSize = sizeof(WAVEFORMATEX); info.wFormatTag = 1; info.nChannels = 2; info.nSamplesPerSec = 44100; //info.nSamplesPerSec = 22050; 11025 info.wBitsPerSample = 16; info.nAvgBytesPerSec = info.nSamplesPerSec * info.nChannels * info.wBitsPerSample / 8; info.nBlockAlign = 4; */ pCfg->SetFormat( pmt ); DeleteMediaType(pmt); } pCfg->Release(); } /* if (dwBytesPerSec) { IAMBufferNegotiation * pNeg = NULL; hr = pCapturePin->QueryInterface(IID_IAMBufferNegotiation, (void **)&pNeg); if (SUCCEEDED(hr)) { ALLOCATOR_PROPERTIES AllocProp; AllocProp.cbAlign = -1; // -1 means no preference. AllocProp.cbBuffer = dwBytesPerSec * dwLatencyInMilliseconds / 1000; AllocProp.cbPrefix = -1; AllocProp.cBuffers = -1; hr = pNeg->SuggestAllocatorProperties(&AllocProp); pNeg->Release(); } }*/ } }
IPin* FindDecoderSubpictureOutputPin(IBaseFilter* pFilter) { IEnumPins* pEnum = NULL; HRESULT hr = pFilter->EnumPins(&pEnum); if (hr != NOERROR) return NULL; ULONG ulFound; IPin *pPin = NULL; hr = E_FAIL; while(S_OK == pEnum->Next(1, &pPin, &ulFound)) { PIN_INFO PinInfo; // // grab this, so we can examine its name field // hr = pPin->QueryPinInfo(&PinInfo); if(SUCCEEDED(hr)) { PinInfo.pFilter->Release(); // // check direction // if (PinInfo.dir == PINDIR_OUTPUT) { // Make sure its not connected yet and its a video type. IPin* dummyPin = NULL; hr = pPin->ConnectedTo(&dummyPin); SAFE_RELEASE(dummyPin); if (hr == VFW_E_NOT_CONNECTED) { IEnumMediaTypes *mtEnum = NULL; pPin->EnumMediaTypes(&mtEnum); AM_MEDIA_TYPE *pMT = NULL; while (S_OK == mtEnum->Next(1, &pMT, NULL)) { if (pMT->majortype == MEDIATYPE_Video) { DeleteMediaType(pMT); SAFE_RELEASE(mtEnum); SAFE_RELEASE(pEnum); return pPin; } DeleteMediaType(pMT); } SAFE_RELEASE(mtEnum); } } } pPin->Release(); } SAFE_RELEASE(pEnum); return NULL; }
HRESULT FindSourceFilter(IFilterGraph* filterGraph,IBaseFilter*& result) { HRESULT hr; IEnumFilters *enumFilters; hr = filterGraph->EnumFilters(&enumFilters); if (FAILED(hr)) { ErrorPrint("Get enum filters error",hr); return hr; } ComReleaser enumFilterReleaser(enumFilters); IBaseFilter* filter; while (S_OK == enumFilters->Next(1, &filter, NULL)) { ComReleaser filterReleaser(filter); IEnumPins *enumPins; hr = filter->EnumPins(&enumPins); if (FAILED(hr)) { ErrorPrint("Get enum pins error",hr); return hr; } ComReleaser enumPinsReleaser(enumPins); IPin* pin; bool isSourceFilter = true; while (S_OK == enumPins->Next(1, &pin, NULL)) { ComReleaser pinReleaser(pin); PIN_INFO pinInfo; hr = pin->QueryPinInfo(&pinInfo); if (FAILED(hr)) { ErrorPrint("Get pin info error",hr); continue; } if (pinInfo.dir == PINDIR_INPUT) //认为没有输入pin的就是source filter,这其实是有些问题的,特别是当捕获(如声卡的音频)的filter有时候有很多输入PIN { isSourceFilter = false; break; } } if (isSourceFilter) { filter->AddRef(); //存在一个资源管理的释放类,必须增加一个引用,否则会被释放掉 result = filter; return S_OK; } } return E_FAIL; }
HRESULT movieConnectFilters(IGraphBuilder *pGraph, IBaseFilter *pFirst, IBaseFilter *pSecond) { IPin *pOut = NULL; IPin *pIn = NULL; // Find the first output pin on the first filter HRESULT RetVal = movieGetPin(pFirst, PINDIR_OUTPUT, &pOut); if (RetVal != S_OK) { return RetVal; } if (NULL == pOut) { return E_FAIL; } // Find the first input pin on the second filter RetVal = movieGetPin(pSecond, PINDIR_INPUT, &pIn); if (RetVal != S_OK) { return RetVal; } if (NULL == pIn) { return E_FAIL; } if (RetVal != S_OK) { pOut->Release(); return E_FAIL; } // Attempt to connect the two pins. RetVal = pGraph->Connect(pOut, pIn); // A filter having audio and video will return a VFW_S_PARTIAL_RENDER when attempting // to connect to a filter only having video (ie. the SampleGrabber filter) if (VFW_S_PARTIAL_RENDER == RetVal) { return S_OK; } // Release the pins pIn->Release(); pOut->Release(); return RetVal; }
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; }
HRESULT CKTVDlg::EnumPinsOnFilter( IBaseFilter *pFilter, PIN_DIRECTION PinDir , int index) { HRESULT r; IEnumPins *pEnum = NULL; IPin *pPin = NULL; // Verify filter interface if (!pFilter) return E_NOINTERFACE; // Get pin enumerator r = pFilter->EnumPins(&pEnum); if (FAILED(r)) return r; pEnum->Reset(); // Enumerate all pins on this filter while((r = pEnum->Next(1, &pPin, 0)) == S_OK) { PIN_DIRECTION PinDirThis; r = pPin->QueryDirection(&PinDirThis); if (FAILED(r)) { pPin->Release(); continue; } // Does the pin's direction match the requested direction? if (PinDir == PinDirThis) { PIN_INFO pininfo={0}; // Direction matches, so add pin name to listbox r = pPin->QueryPinInfo(&pininfo); if (SUCCEEDED(r)) { wstring str = pininfo.achName; m_captureFilterVec[index].PinVec.push_back(str); } // The pininfo structure contains a reference to an IBaseFilter, // so you must release its reference to prevent resource a leak. pininfo.pFilter->Release(); } pPin->Release(); } pEnum->Release(); return r; }
//------------------------------------------------------------------------------------------------- // GetUnconnectedPin // Attemptes to locate an unconnected pin on filter HRESULT CDSUtils::GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter && ppPin) { CComPtr<IEnumPins> pEnum = NULL; IPin* pPin = NULL; hr = pFilter->EnumPins(&pEnum); if (SUCCEEDED(hr)) { while (pEnum->Next(1, &pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin->QueryDirection(&ThisPinDir); if (ThisPinDir == PinDir) { IPin* pPinTemp = NULL; hr = pPin->ConnectedTo(&pPinTemp); if (SUCCEEDED(hr)) { SAFE_RELEASE(pPinTemp); } else { // unconnected, return this pin *ppPin = pPin; hr = S_OK; break; } } SAFE_RELEASE(pPin); } } if (NULL == *ppPin) { // failed to find an unconnected pin hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; }
HRESULT TffdshowDecAudioInputPin::CompleteConnect(IPin* pReceivePin) { HRESULT hr = __super::CompleteConnect(pReceivePin); if (FAILED(hr)) { return hr; } m_hNotifyEvent = NULL; // Some source filters are not multithreaded, in that case we must not use the blocking mode unsigned int numstreams = filter->inpins.getNumConnectedInpins(); bool noBlock = false; for (unsigned int i = 0; i < numstreams; i++) { TffdshowDecAudioInputPin *inpin = filter->inpins[i]; if (noBlock) { inpin->m_useBlock = false; continue; } IPin *pPin = NULL; inpin->ConnectedTo(&pPin); if (!pPin) { continue; } PIN_INFO pinInfo; if (SUCCEEDED(pPin->QueryPinInfo(&pinInfo))) { CLSID clsid; if (pinInfo.pFilter && SUCCEEDED(pinInfo.pFilter->GetClassID(&clsid))) { if (clsid == CLSID_AviSplitter || clsid == CLSID_MPC_OggSplitter || clsid == CLSID_MPC_AC3DTSSourceFilter) { DPRINTF(_l("TffdshowDecAudioInputPin::CompleteConnect Use blocking mode on pin %u"), this); m_useBlock = true; } /* Damm it, Haali is monothreaded (all pins are managed in the same thread), so we cannot use the blocking mode even if another source filter needs it (DTS/AC3 source filter). This is annoying because we can't use Haali with an external AC3/DTS file (albain) */ else if (clsid == CLSID_HaaliMediaSplitter) { DPRINTF(_l("TffdshowDecAudioInputPin::CompleteConnect Disable all blocking modes, source filter is monothreaded on pin %u"), this); noBlock = true; i = 0; } } SAFE_RELEASE(pPin); SAFE_RELEASE(pinInfo.pFilter); } } return S_OK; }
//------------------------------------------------------------------------------ // Name: RenderOutputPins() // Desc: Renders every output pin on a specified filter. // // pGB: Pointer to the Filter Graph Manager. // pFilter: Pointer to the filter. //------------------------------------------------------------------------------ HRESULT RenderOutputPins(IGraphBuilder *pGB, IBaseFilter *pFilter) { HRESULT hr = S_OK; IEnumPins * pEnumPin = NULL; IPin * pConnectedPin = NULL, * pPin; PIN_DIRECTION PinDirection; ULONG ulFetched; // Enumerate all the pins on the filter. hr = pFilter->EnumPins( &pEnumPin ); if(SUCCEEDED(hr)) { // Step through every pin, looking for the output pins. while (S_OK == (hr = pEnumPin->Next( 1L, &pPin, &ulFetched))) { // Check whether this pin is already connected. If so, ignore it. hr = pPin->ConnectedTo(&pConnectedPin); if (pConnectedPin) { // Release the IPin interface on the connected pin. pConnectedPin->Release(); pConnectedPin = NULL; } if (VFW_E_NOT_CONNECTED == hr) { // This pin is not connected to another filter yet. Check // whether it is an output pin. If so, use the Filter Graph // Manager's Render() method to render the pin. hr = pPin->QueryDirection( &PinDirection ); if ( ( S_OK == hr ) && ( PinDirection == PINDIR_OUTPUT ) ) { hr = pGB->Render(pPin); } } pPin->Release(); // If there was an error, stop enumerating. if (FAILED(hr)) break; } } // Release the pin enumerator object. pEnumPin->Release(); return hr; }
static IPin* ds_get_pin(IBaseFilter* filter, const char* pin_name) { com_t<IEnumPins> enum_pins; IPin* pin = null; if_failed_return(filter->EnumPins(&enum_pins), null); while (enum_pins->Next(1, &pin, 0) == S_OK) { PIN_INFO pin_info = {0}; pin->QueryPinInfo(&pin_info); com_release(pin_info.pFilter); if (stricmp(pin_name, wcs2str(pin_info.achName)) == 0) { return pin; } com_release(pin); } return null; }
/* * Class: sage_DShowMediaPlayer * Method: setVideoHWND0 * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_sage_DShowMediaPlayer_setVideoHWND0 (JNIEnv *env, jobject jo, jlong dataPtr, jlong vhwnd) { CPlayerData* playData = (CPlayerData*) dataPtr; IGraphBuilder* pGraph = playData->GetGraph(); IVideoWindow* pVW = NULL; HRESULT hr = pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVW); if (SUCCEEDED(hr)) { slog((env, "DShowPlayer setVideoHWND(%d)\r\n", (int) vhwnd)); pVW->put_AutoShow(OAFALSE); pVW->put_Owner((OAHWND)vhwnd); pVW->put_MessageDrain((OAHWND)vhwnd); pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); pVW->put_Visible(OATRUE); // We do all of our own aspect ratio control, so don't let DShow do any for us // by setting the aspect ratio mode on the video rendering filter's pin IEnumFilters *pEnum = NULL; hr = pGraph->EnumFilters(&pEnum); if (SUCCEEDED(hr)) { IBaseFilter *currFilt = NULL; while (pEnum->Next(1, &currFilt, NULL) == S_OK) { IPin *overlayPin = NULL; hr = currFilt->FindPin(L"Input0", &overlayPin); if (SUCCEEDED(hr)) { // Right pin name, let's see if it's overlay IMixerPinConfig *pOverlayMix = NULL; hr = overlayPin->QueryInterface(IID_IMixerPinConfig, (void**)&pOverlayMix); if (SUCCEEDED(hr)) { pOverlayMix->SetAspectRatioMode(AM_ARMODE_STRETCHED); SAFE_RELEASE(pOverlayMix); } SAFE_RELEASE(overlayPin); } SAFE_RELEASE(currFilt); } SAFE_RELEASE(pEnum); hr = S_OK; } SAFE_RELEASE(pVW); } HTESTPRINT(hr); }
HRESULT CDShowControl::CreateMoviePlayGraph(HWND hWnd, CString fileName) { HRESULT hr; CComPtr<IEnumPins> pEnumPins, pEnumPins2; IPin *pPin = NULL; PIN_DIRECTION direction; BOOL isSuccess = FALSE; CComPtr<IBaseFilter> pWMVReader; ReleaseMoviePlayGraph(); RETURNIF(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)); RETURNIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_moviePlayGraph)); CoUninitialize(); RETURNIF(CreateFilter(L"WM ASF Reader",&pWMVReader,FILTERCG_DSHOW)); CComQIPtr<IFileSourceFilter> pFileSrcFilter(pWMVReader); pFileSrcFilter->Load(fileName.AllocSysString(),NULL); RETURNIF(m_moviePlayGraph->AddFilter(pWMVReader,L"WMVReader")); RETURNIF(pWMVReader->EnumPins(&pEnumPins)); while (pEnumPins->Next(1, &pPin, 0) == S_OK) { RETURNIF(pPin->QueryDirection(&direction)); if (direction == PINDIR_OUTPUT) { m_moviePlayGraph->Render(pPin); } SAFE_RELEASE(pPin); } CComQIPtr<IVideoWindow>pVW(m_moviePlayGraph); if (pVW != NULL) { CComQIPtr<IBasicVideo> pBV(m_moviePlayGraph); CRect rect,videoRect; RETURNIF(pVW->put_Owner((OAHWND)hWnd)); RETURNIF(pVW->put_WindowStyle(WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS)); RETURNIF(pVW->put_MessageDrain((long)hWnd)); CRect ClientRect; ::GetClientRect(hWnd, &ClientRect); pVW->SetWindowPosition(0, 0, ClientRect.Width(), ClientRect.Height()); pVW->put_AutoShow(OATRUE); pVW->put_Visible(OATRUE); } 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; }
static HRESULT ConnectTwoFilters(IGraphBuilder *pGraph, IBaseFilter *pFirst, IBaseFilter *pSecond) { IPin *pOut = NULL, *pIn = NULL; HRESULT hr = GetPin(pFirst, PINDIR_OUTPUT, &pOut); if (FAILED(hr)) return hr; hr = GetPin(pSecond, PINDIR_INPUT, &pIn); if (FAILED(hr)) { pOut->Release(); return E_FAIL; } hr = pGraph->Connect(pOut, pIn); pIn->Release(); pOut->Release(); return hr; }
// Get the first upstream or downstream filter HRESULT GetNextFilter( IBaseFilter *pFilter, // Pointer to the starting filter PIN_DIRECTION Dir, // Direction to search (upstream or downstream) IBaseFilter **ppNext) // Receives a pointer to the next filter. { if (!pFilter || !ppNext) return E_POINTER; IEnumPins *pEnum = 0; IPin *pPin = 0; HRESULT hr = pFilter->EnumPins(&pEnum); if (FAILED(hr)) return hr; while (S_OK == pEnum->Next(1, &pPin, 0)) { // See if this pin matches the specified direction. PIN_DIRECTION ThisPinDir; hr = pPin->QueryDirection(&ThisPinDir); if (FAILED(hr)) { // Something strange happened. hr = E_UNEXPECTED; pPin->Release(); break; } if (ThisPinDir == Dir) { // Check if the pin is connected to another pin. IPin *pPinNext = 0; hr = pPin->ConnectedTo(&pPinNext); if (SUCCEEDED(hr)) { // Get the filter that owns that pin. PIN_INFO PinInfo; hr = pPinNext->QueryPinInfo(&PinInfo); pPinNext->Release(); pPin->Release(); pEnum->Release(); if (FAILED(hr) || (PinInfo.pFilter == NULL)) { // Something strange happened. return E_UNEXPECTED; } // This is the filter we're looking for. *ppNext = PinInfo.pFilter; // Client must release. return S_OK; } } pPin->Release(); } pEnum->Release(); // Did not find a matching filter. return E_FAIL; }
HRESULT GetNextFilter(IBaseFilter* filter, PIN_DIRECTION dir, IBaseFilter*& nextFilter) { IEnumPins *enumPins; IPin* pin; HRESULT hr; hr = filter->EnumPins(&enumPins); if(FAILED(hr)) { ErrorPrint("Get enum pins error", hr); return hr; } ComReleaser enumPinsReleaser(enumPins); while (enumPins->Next(1, &pin, NULL) == S_OK) { ComReleaser pinReleaser(pin); PIN_DIRECTION thisDir; hr = pin->QueryDirection(&thisDir); if(FAILED(hr)) { ErrorPrint("Query direction error", hr); return hr; } if(thisDir == dir) { IPin *nextPin; hr = pin->ConnectedTo(&nextPin); if(SUCCEEDED(hr)) { ComReleaser nextPinReleaser(nextPin); PIN_INFO nextPinInfo; hr = nextPin->QueryPinInfo(&nextPinInfo); if(SUCCEEDED(hr)) { nextFilter = nextPinInfo.pFilter; return S_OK; } else { return E_UNEXPECTED; } } } } return E_FAIL; }
// // Does not AddRef the returned *Pin // HRESULT CCrossbar::GetCrossbarIPinAtIndex( IAMCrossbar *pXbar, LONG PinIndex, BOOL IsInputPin, IPin ** ppPin) { LONG cntInPins, cntOutPins; IPin *pP = 0; IBaseFilter *pFilter = NULL; IEnumPins *pins=0; ULONG n; HRESULT hr; if (!pXbar || !ppPin) return E_POINTER; *ppPin = 0; if(S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins)) return E_FAIL; LONG TrueIndex = IsInputPin ? PinIndex : PinIndex + cntInPins; hr = pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter); if (hr == S_OK) { if(SUCCEEDED(pFilter->EnumPins(&pins))) { LONG i=0; while(pins->Next(1, &pP, &n) == S_OK) { pP->Release(); if (i == TrueIndex) { *ppPin = pP; break; } i++; } pins->Release(); } pFilter->Release(); } return *ppPin ? S_OK : E_FAIL; }
// Find all the immediate upstream or downstream peers of a filter. HRESULT GetPeerFilters( IBaseFilter *pFilter, // Pointer to the starting filter PIN_DIRECTION Dir, // Direction to search (upstream or downstream) CFilterList &FilterList) // Collect the results in this list. { if (!pFilter) return E_POINTER; IEnumPins *pEnum = 0; IPin *pPin = 0; HRESULT hr = pFilter->EnumPins(&pEnum); if (FAILED(hr)) return hr; while (S_OK == pEnum->Next(1, &pPin, 0)) { // See if this pin matches the specified direction. PIN_DIRECTION ThisPinDir; hr = pPin->QueryDirection(&ThisPinDir); if (FAILED(hr)) { // Something strange happened. hr = E_UNEXPECTED; pPin->Release(); break; } if (ThisPinDir == Dir) { // Check if the pin is connected to another pin. IPin *pPinNext = 0; hr = pPin->ConnectedTo(&pPinNext); if (SUCCEEDED(hr)) { // Get the filter that owns that pin. PIN_INFO PinInfo; hr = pPinNext->QueryPinInfo(&PinInfo); pPinNext->Release(); if (FAILED(hr) || (PinInfo.pFilter == NULL)) { // Something strange happened. pPin->Release(); pEnum->Release(); return E_UNEXPECTED; } // Insert the filter into the list. AddFilterUnique(FilterList, PinInfo.pFilter); PinInfo.pFilter->Release(); } } pPin->Release(); } pEnum->Release(); return S_OK; }
// // Find corresponding index of an IPin on a crossbar // HRESULT CCrossbar::GetCrossbarIndexFromIPin ( IAMCrossbar * pXbar, LONG * PinIndex, BOOL IsInputPin, IPin * pPin) { LONG cntInPins, cntOutPins; IPin *pP = 0; IBaseFilter *pFilter = NULL; IEnumPins *pins = 0; ULONG n; BOOL fOK = FALSE; HRESULT hr; if (!pXbar || !PinIndex || !pPin) return E_POINTER; if(S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins)) return E_FAIL; hr = pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter); if (hr == S_OK) { if(SUCCEEDED(pFilter->EnumPins(&pins))) { LONG i=0; while(pins->Next(1, &pP, &n) == S_OK) { pP->Release(); if (pPin == pP) { *PinIndex = IsInputPin ? i : i - cntInPins; fOK = TRUE; break; } i++; } pins->Release(); } pFilter->Release(); } return fOK ? S_OK : E_FAIL; }
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; }
// Connect two filters together with the Filter Graph Manager. // Again, stolen from the DX9 SDK. // This is an overloaded version. HRESULT CBoxView::ConnectFilters(IGraphBuilder *pGraph, IBaseFilter *pSrc, IBaseFilter *pDest) { if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL)) { return E_POINTER; } // Find an output pin on the first filter. IPin *pOut = 0; HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut); if (FAILED(hr)) { return hr; } hr = ConnectFilters(pGraph, pOut, pDest); pOut->Release(); return hr; }
HRESULT RecordGraph::ConnectFilters(IGraphBuilder *pGraph, IBaseFilter *pSrc, IBaseFilter *pDest, GUID MediaType) { if(pGraph == NULL || pSrc == NULL || pDest == NULL) return E_POINTER; IPin *pOut = 0; HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut, MediaType); if (FAILED(hr)) return hr; IPin *pIn = 0; hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn, MediaType); if (FAILED(hr)) return hr; hr = pGraph->Connect(pOut, pIn); pOut->Release(); pIn->Release(); return hr; }
IPin* getPin(IBaseFilter* filter, PIN_DIRECTION direct) { IEnumPins* enumPins; filter->EnumPins(&enumPins); IPin* pin = NULL; PIN_DIRECTION pd; while(SUCCEEDED(enumPins->Next(1, &pin, 0))) { if (SUCCEEDED(pin->QueryDirection(&pd)) && pd == direct) { break; } pin->Release(); } enumPins->Release(); return pin; }