// ConnectFilters is called from BuildGraph // to enumerate and connect pins HRESULT CDShowCtrl::DisconnectFilter( IGraphBuilder* pGraphBuilder, IBaseFilter* pFilter ) { HRESULT hr = E_FAIL; // grab upstream filter's enumerator CComPtr <IEnumPins> pIEnumPins; hr = pFilter->EnumPins(&pIEnumPins); if(FAILED(hr)) { return hr; } IPin* pIPin = NULL; // iterate through upstream filter's pins while (pIEnumPins->Next (1, &pIPin, 0) == S_OK) { IPin* pIPinConnection = NULL; hr = pIPin->ConnectedTo(&pIPinConnection); if(FAILED(hr)) { SAFE_RELEASE(pIPin); continue; } hr = pGraphBuilder->Disconnect(pIPin); hr = pGraphBuilder->Disconnect(pIPinConnection); SAFE_RELEASE(pIPinConnection); SAFE_RELEASE(pIPin); } return S_OK; }
HRESULT GetUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin) { *ppPin = 0; IEnumPins *pEnum = 0; IPin *pPin = 0; HRESULT hr = pFilter->EnumPins(&pEnum); if (FAILED(hr)) { return hr; } while (pEnum->Next(1, &pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin->QueryDirection(&ThisPinDir); if (ThisPinDir == PinDir) { IPin *pTmp = 0; hr = pPin->ConnectedTo(&pTmp); if (SUCCEEDED(hr)) { pTmp->Release(); } else { pEnum->Release(); *ppPin = pPin; return S_OK; } } pPin->Release(); } pEnum->Release(); return E_FAIL; }
// // CFilePlayer::IsOvMConnected(): Private method to detect if the video stream // is passing through the Overlay Mixer (i.e, is it connected?). // BOOL CFilePlayer::IsOvMConnected(IBaseFilter *pOvM) { DbgLog((LOG_TRACE, 5, TEXT("CFilePlayer::IsOvMConnected() entered"))) ; IEnumPins *pEnumPins ; IPin *pPin ; IPin *pPin2 ; ULONG ul ; HRESULT hr ; BOOL bConnected = FALSE ; pOvM->EnumPins(&pEnumPins) ; while (S_OK == pEnumPins->Next(1, &pPin, &ul) && 1 == ul) { hr = pPin->ConnectedTo(&pPin2) ; if (SUCCEEDED(hr) && pPin2) { DbgLog((LOG_TRACE, 3, TEXT("Found pin %s connected to pin %s"), (LPCTSTR)CDisp(pPin), (LPCTSTR)CDisp(pPin2))) ; bConnected = TRUE ; pPin2->Release() ; } pPin->Release() ; } pEnumPins->Release() ; return bConnected ; }
// Function name : CVMR9Graph::GetPin // Description : return the desired pin // Return type : IPin* // Argument : IBaseFilter *pFilter // Argument : PIN_DIRECTION PinDir IPin* CVMR9Graph::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir) { BOOL bFound = FALSE; IEnumPins *pEnum; IPin *pPin; pFilter->EnumPins(&pEnum); while(pEnum->Next(1, &pPin, 0) == S_OK) { PIN_DIRECTION PinDirThis; pPin->QueryDirection(&PinDirThis); if (PinDir == PinDirThis) { IPin *pTmp = 0; if (SUCCEEDED(pPin->ConnectedTo(&pTmp))) // Already connected, not the pin we want. { pTmp->Release(); } else // Unconnected, this is the pin we want. { bFound = true; break; } } pPin->Release(); } pEnum->Release(); return (bFound ? pPin : 0); }
// helper functions HRESULT GetUnconnectedPin(IBaseFilter *pFilter,PIN_DIRECTION PinDir, IPin **ppPin) { *ppPin = 0; IEnumPins *pEnum = 0; IPin *pPin = 0; HRESULT hr = pFilter->EnumPins(&pEnum); if (FAILED(hr)) { return hr; } while (pEnum->Next(1, &pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin->QueryDirection(&ThisPinDir); if (ThisPinDir == PinDir) { IPin *pTmp = 0; hr = pPin->ConnectedTo(&pTmp); if (SUCCEEDED(hr)) // Already connected, not the pin we want. { pTmp->Release(); } else // Unconnected, this is the pin we want. { pEnum->Release(); *ppPin = pPin; return S_OK; } } pPin->Release(); } pEnum->Release(); // Did not find a matching pin. return E_FAIL; }
IBaseFilter *DirectShowPlayerService::getConnected( IBaseFilter *filter, PIN_DIRECTION direction) const { IBaseFilter *connected = 0; IEnumPins *pins = 0; if (SUCCEEDED(filter->EnumPins(&pins))) { for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { PIN_DIRECTION dir; if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) { IPin *peer = 0; if (SUCCEEDED(pin->ConnectedTo(&peer))) { PIN_INFO info; if (SUCCEEDED(peer->QueryPinInfo(&info))) { if (connected) { qWarning("DirectShowPlayerService::getConnected: " "Multiple connected filters"); connected->Release(); } connected = info.pFilter; } peer->Release(); } } } pins->Release(); } return connected; }
bool ConnectPins(IGraphBuilder *filterGraph, IBaseFilter* outputFilter, unsigned int outputNum, IBaseFilter* inputFilter, unsigned int inputNum) { IPin *inputPin = 0; IPin *outputPin = 0; if (!outputFilter || !inputFilter) { return false; } FindPin(outputFilter, PINDIR_OUTPUT, outputNum, &outputPin); FindPin(inputFilter, PINDIR_INPUT, inputNum, &inputPin); bool ret = false; if (inputPin && outputPin) { IPin *tmp = 0; outputPin->ConnectedTo (&tmp); if (tmp) { outputPin->Disconnect (); tmp->Release(); } inputPin->ConnectedTo (&tmp); if (tmp) { inputPin->Disconnect (); tmp->Release(); } HRESULT hr = filterGraph->Connect (outputPin, inputPin); ret = SUCCEEDED(hr); } if (inputPin) { inputPin->Release(); } if (outputPin) { outputPin->Release(); } return ret; }
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 CDShowUtility::GetFirstUnConnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin) { *ppPin = NULL; IEnumPins *pEnum = NULL; IPin *pPin = NULL; HRESULT hr = pFilter->EnumPins(&pEnum); if (FAILED(hr)) { return hr; } pEnum->Reset(); while (pEnum->Next(1, &pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin->QueryDirection(&ThisPinDir); if (PinDir == ThisPinDir) { IPin *pTmp = 0; hr = pPin->ConnectedTo(&pTmp); if (NULL != pTmp) { pTmp->Release(); } if (SUCCEEDED(hr)) { //已经连接了 pPin->Release(); continue; } else { pEnum->Release(); *ppPin = pPin; return S_OK; } } pPin->Release(); } pEnum->Release(); return E_FAIL; }
// 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; }
// 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; }
// Tear down everything downstream of a given filter void __fastcall NukeDownstream(IBaseFilter * pf, IGraphBuilder * pGB) { IPin *pP = 0; IPin *pTo = 0; ULONG u; IEnumPins *pins = NULL; PIN_INFO pininfo; if (!pf) return; // Enumerate all filter pins HRESULT hr = pf->EnumPins(&pins); // Go to beginning of enumeration pins->Reset(); while(hr == NOERROR) { hr = pins->Next(1, &pP, &u); if(hr == S_OK && pP) { pP->ConnectedTo(&pTo); if(pTo) { hr = pTo->QueryPinInfo(&pininfo); if(hr == NOERROR) { if(pininfo.dir == PINDIR_INPUT) { NukeDownstream(pininfo.pFilter, pGB); pGB->Disconnect(pTo); pGB->Disconnect(pP); pGB->RemoveFilter(pininfo.pFilter); } pininfo.pFilter->Release(); pininfo.pFilter = NULL; } pTo->Release(); pTo = NULL; } pP->Release(); pP = NULL; } } if(pins) { pins->Release(); pins = NULL; } }
//------------------------------------------------------------------------------------------------- // 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; }
//得到Filter上未连接Pin BOOL GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION pinDir, IPin** ppPin) { if(!pFilter || ppPin) return FALSE; ASSERT(pinDir == PINDIR_INPUT || PINDIR_INPUT == PINDIR_OUTPUT); *ppPin = NULL; IEnumPins* pEnumPin = NULL; IPin* pPin = NULL; HRESULT hr = pFilter->EnumPins(&pEnumPin); if(FAILED(hr)) return FALSE; while(pEnumPin->Next(1,&pPin,NULL) == S_OK) { PIN_DIRECTION pinDirThis; hr = pPin->QueryDirection(&pinDirThis); if(FAILED(hr)) { pPin->Release(); pEnumPin->Release(); return FALSE; } if(pinDir == pinDirThis) { IPin* pPinConnected = NULL; hr = pPin->ConnectedTo(&pPinConnected); if(SUCCEEDED(hr)) { pPinConnected->Release(); } else { pEnumPin->Release(); *ppPin = pPin; return TRUE; } } pPin->Release(); } pEnumPin->Release(); return FALSE; }
BOOL GetConnectedFilter(IBaseFilter* pFilter, PIN_DIRECTION pinDir, IBaseFilter** ppFilterConnected) { if(!pFilter || !ppFilterConnected) return FALSE; IEnumPins* pEnumPin = NULL; if(FAILED(pFilter->EnumPins(&pEnumPin))) return FALSE; HRESULT hr = E_FAIL; IPin* pPin = NULL; while(S_OK == pEnumPin->Next(1,&pPin,NULL)) { PIN_DIRECTION pinDirThis; hr = pPin->QueryDirection(&pinDirThis); if(FAILED(hr)) { pPin->Release(); pEnumPin->Release(); return FALSE; } if(pinDirThis == pinDir) { IPin* pPinConnected; hr = pPin->ConnectedTo(&pPinConnected); if(SUCCEEDED(hr)) { PIN_INFO pinInfo; hr = pPinConnected->QueryPinInfo(&pinInfo); pPinConnected->Release(); pPin->Release(); pEnumPin->Release(); if(FAILED(hr) || pinInfo.pFilter == NULL) { return FALSE; } *ppFilterConnected = pinInfo.pFilter; return TRUE; } } pPin->Release(); } pEnumPin->Release(); return FALSE; }
HRESULT FindConnectedFilter( IBaseFilter *pSrc, // Pointer to the starting filter PIN_DIRECTION PinDir, // Directtion to look (input = upstream, output = downstream) IBaseFilter **ppConnected) // Returns a pointer to the filter that is connected to pSrc { if (!pSrc || !ppConnected) return E_FAIL; *ppConnected = NULL; IEnumPins *pEnum = 0; IPin *pPin = 0; HRESULT hr = pSrc->EnumPins(&pEnum); if (FAILED(hr)) { return hr; } while (pEnum->Next(1, &pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin->QueryDirection(&ThisPinDir); if (ThisPinDir == PinDir) { IPin *pTmp = 0; hr = pPin->ConnectedTo(&pTmp); if (SUCCEEDED(hr) && pTmp) { // Return the filter that owns this pin. PIN_INFO PinInfo; pTmp->QueryPinInfo(&PinInfo); pTmp->Release(); pEnum->Release(); if (PinInfo.pFilter == NULL) { // Inconsistent pin state. Something is wrong... return E_UNEXPECTED; } else { *ppConnected = PinInfo.pFilter; return S_OK; } } } pPin->Release(); } pEnum->Release(); 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; }
HRESULT __fastcall GetUnconnectedPin( IBaseFilter *pFilter, // Pointer to the filter. PIN_DIRECTION PinDir, // Direction of the pin to find. IPin **ppPin) // Receives a pointer to the pin. { IEnumPins *pEnum = NULL; IPin *pPin = NULL; if (!ppPin) return E_POINTER; *ppPin = NULL; // Get a pin enumerator HRESULT hr = pFilter->EnumPins(&pEnum); if (FAILED(hr)) return hr; // Look for the first unconnected pin PIN_DIRECTION ThisPinDir; while (pEnum->Next(1, &pPin, NULL) == S_OK) { pPin->QueryDirection(&ThisPinDir); if (ThisPinDir == PinDir) { IPin *pTmp = NULL; hr = pPin->ConnectedTo(&pTmp); if (SUCCEEDED(hr)) // Already connected, not the pin we want. { pTmp->Release(); } else // Unconnected, this is the pin we want. { pEnum->Release(); *ppPin = pPin; return S_OK; } } pPin->Release(); } // Release the enumerator pEnum->Release(); // Did not find a matching pin return E_FAIL; }
// Tear down everything upstream of a given filter void NukeUpstream(IGraphBuilder * inGraph, IBaseFilter * inFilter) { if (inGraph && inFilter) { IEnumPins * pinEnum = 0; if (SUCCEEDED(inFilter->EnumPins(&pinEnum))) { pinEnum->Reset(); IPin * pin = 0; ULONG cFetched = 0; bool pass = true; while (pass && SUCCEEDED(pinEnum->Next(1, &pin, &cFetched))) { if (pin && cFetched) { IPin * connectedPin = 0; pin->ConnectedTo(&connectedPin); if(connectedPin) { PIN_INFO pininfo; if (SUCCEEDED(connectedPin->QueryPinInfo(&pininfo))) { if(pininfo.dir == PINDIR_OUTPUT) { NukeUpstream(inGraph, pininfo.pFilter); inGraph->Disconnect(connectedPin); inGraph->Disconnect(pin); inGraph->RemoveFilter(pininfo.pFilter); } pininfo.pFilter->Release(); } connectedPin->Release(); } pin->Release(); } else { pass = false; } } pinEnum->Release(); } } }
//----------------------------------------------------------------------------- // DisconnectAllPins // Disconnect all the pins of the filters in a graph HRESULT CDSUtils::DisconnectAllPins(IGraphBuilder* pGraph) { HRESULT hr = S_OK; if (pGraph) { CComPtr<IEnumFilters> pIEnumFilters = NULL; hr = pGraph->EnumFilters(&pIEnumFilters); if (SUCCEEDED(hr)) { IBaseFilter* pFilter = NULL; while (S_OK == pIEnumFilters->Next(1, &pFilter, NULL)) { CComPtr<IEnumPins> pIEnumPins = NULL; hr = pFilter->EnumPins(&pIEnumPins); if (SUCCEEDED(hr)) { IPin* pIPin = NULL; while (S_OK == pIEnumPins->Next(1, &pIPin, NULL)) { IPin* pIPinConnection = NULL; if (S_OK == pIPin->ConnectedTo(&pIPinConnection)) { // pins are connected, to disconnect filters, both pins must be disconnected hr = pGraph->Disconnect(pIPin); hr = pGraph->Disconnect(pIPinConnection); SAFE_RELEASE(pIPinConnection); } SAFE_RELEASE(pIPin); } } SAFE_RELEASE(pFilter); } } } else { hr = E_INVALIDARG; } return hr; }
HRESULT RecordGraph::GetUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin, GUID MediaType) { *ppPin = 0; IEnumPins *pEnum = 0; IPin *pPin = 0; HRESULT hr = pFilter->EnumPins(&pEnum); if(FAILED(hr)) return hr; while (pEnum->Next(1, &pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin->QueryDirection(&ThisPinDir); if (ThisPinDir == PinDir) { IPin *pTmp = 0; hr = pPin->ConnectedTo(&pTmp); if (SUCCEEDED(hr)) pTmp->Release(); else { IEnumMediaTypes *pEnumMediaType = NULL; hr = pPin->EnumMediaTypes(&pEnumMediaType); if (MediaType == MEDIATYPE_NULL) { pEnum->Release(); *ppPin = pPin; pPin->Release(); return S_OK; }else if(SUCCEEDED(this->CheckMediaType(pEnumMediaType, MediaType))) { pEnum->Release(); *ppPin = pPin; pPin->Release(); return S_OK; } pEnumMediaType->Release(); } } pPin->Release(); } pEnum->Release(); return E_FAIL; }
int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const { QVarLengthArray<IBaseFilter *, 16> filters; source->AddRef(); filters.append(source); int streamTypes = 0; while (!filters.isEmpty()) { IEnumPins *pins = 0; IBaseFilter *filter = filters[filters.size() - 1]; filters.removeLast(); if (SUCCEEDED(filter->EnumPins(&pins))) { for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { PIN_DIRECTION direction; if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) { AM_MEDIA_TYPE connectionType; if (SUCCEEDED(pin->ConnectionMediaType(&connectionType))) { IPin *peer = 0; if (connectionType.majortype == MEDIATYPE_Audio) { streamTypes |= AudioStream; } else if (connectionType.majortype == MEDIATYPE_Video) { streamTypes |= VideoStream; } else if (SUCCEEDED(pin->ConnectedTo(&peer))) { PIN_INFO peerInfo; if (SUCCEEDED(peer->QueryPinInfo(&peerInfo))) filters.append(peerInfo.pFilter); peer->Release(); } } else { streamTypes |= findStreamType(pin); } } } } filter->Release(); } return streamTypes; }
HRESULT RemoveFilter(IGraphBuilder* pGraphBuilder, IBaseFilter* pBaseFilter) { CheckPointer(pGraphBuilder, E_POINTER); CheckPointer(pBaseFilter, E_PENDING); IEnumPins *pEnumPins = NULL; HRESULT hr = pBaseFilter->EnumPins(&pEnumPins); if (FAILED(hr)) return hr; pEnumPins->Reset(); IPin *pPinFrom = 0, *pPinTo = 0; while ((hr = pEnumPins->Next(1, &pPinFrom, NULL)) == S_OK) { if (SUCCEEDED(hr)) { hr = pPinFrom->ConnectedTo(&pPinTo); if (SUCCEEDED(hr)) { PIN_INFO info; hr = pPinTo->QueryPinInfo(&info); if (SUCCEEDED(hr)) { if (info.dir == PINDIR_INPUT) { RemoveFilter(pGraphBuilder, info.pFilter); pGraphBuilder->Disconnect(pPinTo); pGraphBuilder->Disconnect(pPinFrom); pGraphBuilder->RemoveFilter(info.pFilter); } info.pFilter->Release(); } pPinTo->Release(); } pPinFrom->Release(); } } pEnumPins->Release(); return S_OK; }
HRESULT GetFreePin(IBaseFilter* filter, IPin*& result, PIN_DIRECTION dir) { HRESULT hr = S_OK; IEnumPins *enumPins; hr = filter->EnumPins(&enumPins); if(FAILED(hr)) { ErrorPrint("Enum pins error"); return hr; } ComReleaser enumPinsReleaser(enumPins); IPin *pin; while (S_OK == enumPins->Next(1, &pin, NULL)) { PIN_INFO pinInfo; hr = pin->QueryPinInfo(&pinInfo); if(FAILED(hr)) { ErrorPrint("Query pin info error"); pin->Release(); continue; } if(pinInfo.dir == dir) { IPin* connectedPin; pin->ConnectedTo(&connectedPin); if(connectedPin == NULL) { result = pin; return S_OK; } } pin->Release(); } return E_FAIL; }
bool DirectShowPlayerService::isConnected(IBaseFilter *filter, PIN_DIRECTION direction) const { bool connected = false; IEnumPins *pins = 0; if (SUCCEEDED(filter->EnumPins(&pins))) { for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { PIN_DIRECTION dir; if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) { IPin *peer = 0; if (SUCCEEDED(pin->ConnectedTo(&peer))) { connected = true; peer->Release(); } } } pins->Release(); } return connected; }
/******************************Public*Routine******************************\ * CheckOutConnection \**************************************************************************/ HRESULT CVMR9Subgraph::CheckConnection(IBaseFilter* ft) { HRESULT hr = S_OK; bool bConnected = false; IEnumPins*pEnum = 0; IPin* pPin = 0; if( !ft ) return E_UNEXPECTED; hr = ft->EnumPins( &pEnum ); if( FAILED(hr)) return hr; hr = pEnum->Next( 1, &pPin, NULL); while( SUCCEEDED(hr) && pPin) { IPin* pConnectedPin = 0; hr = pPin->ConnectedTo( &pConnectedPin ); if( SUCCEEDED(hr) && pConnectedPin ) { bConnected = true; RELEASE(pConnectedPin); break; } RELEASE(pPin); RELEASE(pConnectedPin); hr = pEnum->Next( 1, &pPin, NULL); }// while hr = (true == bConnected) ? S_OK : E_FAIL; RELEASE(pEnum); RELEASE(pPin); return hr; }
HRESULT CTMReceiverGraph::GetUnconnectedPin(CComPtr<IBaseFilter> pFilter, PIN_DIRECTION PinDir, IPin **ppPin, GUID MediaType) { *ppPin = 0; CComPtr<IEnumPins> pEnum = 0; IPin* pPin = 0; HRESULT hr = pFilter->EnumPins(&pEnum); if(FAILED(hr)) return hr; while (pEnum->Next(1, &pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin->QueryDirection(&ThisPinDir); if (ThisPinDir == PinDir) { CComPtr<IPin> pTmp = 0; hr = pPin->ConnectedTo(&pTmp); if (SUCCEEDED(hr)) {} else { CComPtr<IEnumMediaTypes> pEnumMediaType = NULL; hr = pPin->EnumMediaTypes(&pEnumMediaType); if (MediaType == MEDIATYPE_NULL) { *ppPin = pPin; return S_OK; }else if(SUCCEEDED(this->CheckMediaType(pEnumMediaType, MediaType))) { *ppPin = pPin; return S_OK; } } } } return E_FAIL; }
HRESULT DirectShowVideoWrapper::ConnectSampleGrabber(void) { HRESULT hr = S_OK; TCHAR szErr[MAX_ERROR_TEXT_LEN]; // Register the graph in the Running Object Table (for debug purposes) AddGraphToROT(_pGraphBuilder, &dwROT); // Create the Sample Grabber which we will use // To take each frame for texture generation if(_pSampleGrabberFilter == NULL) { hr = _pSampleGrabberFilter.CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Could not create SampleGrabberFilter, error: " << szErr << std::endl; return hr; } } _pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, reinterpret_cast<void**>(&_pSampleGrabber)); // We have to set the 24-bit RGB desire here // So that the proper conversion filters // Are added automatically. AM_MEDIA_TYPE desiredType; memset(&desiredType, 0, sizeof(desiredType)); desiredType.majortype = MEDIATYPE_Video; //desiredType.subtype = MEDIASUBTYPE_RGB565; desiredType.subtype = MEDIASUBTYPE_RGB24; //desiredType.subtype = GUID_NULL; desiredType.formattype = GUID(); //desiredType.formattype = FORMAT_VideoInfo; _pSampleGrabber->SetMediaType(&desiredType); _pSampleGrabber->SetBufferSamples(TRUE); // A Null Renderer does not display the video // But it allows the Sample Grabber to run // And it will keep proper playback timing // Unless specified otherwise. if(_pVideoRenderer == NULL) { hr = _pVideoRenderer.CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Unable to create Null Renderer, error: " << szErr << std::endl; return hr; } } //Get Input pins to VideoRenderer IPin* _VideoRendererIntputPin; if (FAILED(hr = _pVideoRenderer->FindPin(L"In", &_VideoRendererIntputPin))) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Could not find VideoRenderer Intput Pin, error: " << szErr << std::endl; return hr; } IBaseFilter* pVidRenderer = NULL; hr = FindVideoRenderer(_pGraphBuilder,&pVidRenderer); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return hr; } if(pVidRenderer) { SLOG << "Removing default video renderer" << std::endl; //get input pin of video renderer IPin* ipin; hr = GetPin(pVidRenderer, PINDIR_INPUT, 0, &ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Get Vidio Renderer in pin, error: " << szErr << std::endl; return hr; } IPin* opin = NULL; //find out who the renderer is connected to and disconnect from them hr = ipin->ConnectedTo(&opin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return hr; } //Get the filter of the opin PIN_INFO OpinInfo; opin->QueryPinInfo(&OpinInfo); IBaseFilter* LastFilter(OpinInfo.pFilter); FILTER_INFO LastFilterInfo; LastFilter->QueryFilterInfo(&LastFilterInfo); CLSID LastFilterClassID; LastFilter->GetClassID(&LastFilterClassID); SLOG << "Last filter name: " << LastFilterInfo.achName << ", ClassID " << LastFilterClassID.Data1 << "-" << LastFilterClassID.Data2 << "-" << LastFilterClassID.Data3 << "-" << LastFilterClassID.Data4 << std::endl; LPWSTR *VendorInfo; LastFilter->QueryVendorInfo(VendorInfo); if(VendorInfo) { SLOG << "Last filter vendor: " << *VendorInfo << std::endl; } hr = ipin->Disconnect(); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return hr; } hr = opin->Disconnect(); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return hr; } //SAFE_RELEASE(ipin); //remove the default renderer from the graph hr = _pGraphBuilder->RemoveFilter(pVidRenderer); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return hr; } //SAFE_RELEASE(pVidRenderer); //see if the video renderer was originally connected to //a color space converter _pGraphBuilder->FindFilterByName(L"Color Space Converter", &_pCSCFilter); if(_pCSCFilter == NULL) { // Create the Color Space filter hr = _pCSCFilter.CoCreateInstance(CLSID_Colour, NULL, CLSCTX_INPROC_SERVER); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Could not create Color Space Converter Filter, error: " << szErr << std::endl; return hr; } hr = _pGraphBuilder->AddFilter(_pCSCFilter, L"Color Space Converter"); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Could not add Color Space Converter Filter, error: " << szErr << std::endl; return hr; } //get the output pin of the last filter hr = GetPin(LastFilter, PINDIR_OUTPUT, 0, &opin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Get Last filter out pin, error: " << szErr << std::endl; return hr; } //get the input pin of the Color Space Converter hr = GetPin(_pCSCFilter, PINDIR_INPUT, 0, &ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Get Color Space Converter In Pin, error: " << szErr << std::endl; return hr; } //connect the filter that was originally connected to the default renderer //to the Color Space Converter SLOG << "Attaching Color Space Converter Filter. " << opin << " -> " << ipin << std::endl; hr = _pGraphBuilder->Connect(opin, ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Could not attach Color Space Converter Filter so it won't be used, error: " << szErr << std::endl; //return hr; } else { LastFilter = _pCSCFilter; } } hr = _pGraphBuilder->AddFilter(_pSampleGrabberFilter, L"Video Sample Grabber"); //get the input pin of the Sample Grabber hr = GetPin(_pSampleGrabberFilter, PINDIR_INPUT, 0, &ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Get Sample Grabber In Pin, error: " << szErr << std::endl; return hr; } //get the output pin of the last filter in the graph hr = GetPin(LastFilter, PINDIR_OUTPUT, 0, &opin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Get Color Space Converter out pin, error: " << szErr << std::endl; return hr; } SLOG << "Attaching video sample grabber filter." << std::endl; hr = _pGraphBuilder->Connect(opin, ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return hr; } //SAFE_RELEASE(ipin); //SAFE_RELEASE(opin); //get output pin of sample grabber hr = GetPin(_pSampleGrabberFilter, PINDIR_OUTPUT, 0, &opin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Get Sample Grabber out pin, error: " << szErr << std::endl; return hr; } SLOG << "Attaching Video Null Renderer." << std::endl; hr = _pGraphBuilder->AddFilter(_pVideoRenderer, L"Video Null Renderer"); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Unable to add Renderer to filter graph, error: " << szErr << std::endl; return hr; } //get input pin of null renderer hr = GetPin(_pVideoRenderer, PINDIR_INPUT, 0, &ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Get Null Renderer in pin, error: " << szErr << std::endl; return hr; } //connect them SLOG << "Attaching null video renderer." << std::endl; hr = _pGraphBuilder->Connect(opin, ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Unable to connect Renderer to sample grabber, error: " << szErr << std::endl; return hr; } //SAFE_RELEASE(ipin); //SAFE_RELEASE(opin); } // Just a little trick so that we don't have to know // The video resolution when calling this method. bool mediaConnected = false; AM_MEDIA_TYPE connectedType; if (SUCCEEDED(hr = _pSampleGrabber->GetConnectedMediaType(&connectedType))) { if (connectedType.formattype == FORMAT_VideoInfo) { VIDEOINFOHEADER* infoHeader = (VIDEOINFOHEADER*)connectedType.pbFormat; _VideoWidth = infoHeader->bmiHeader.biWidth; _VideoHeight = infoHeader->bmiHeader.biHeight; mediaConnected = true; } else if (connectedType.formattype == FORMAT_VideoInfo2) { VIDEOINFOHEADER* infoHeader = (VIDEOINFOHEADER*)connectedType.pbFormat; _VideoWidth = infoHeader->bmiHeader.biWidth; _VideoHeight = infoHeader->bmiHeader.biHeight; mediaConnected = true; } else { SWARNING << "Unable to get the media type connected to the sample grabber." << std::endl; } SLOG << "Video Dimensions: " << _VideoWidth << " x " << _VideoHeight << std::endl; CoTaskMemFree(connectedType.pbFormat); } else { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Unable to get connected media type, error: " << szErr << std::endl; return hr; } /*if (!mediaConnected) { uninitVideo(); return false; }*/ return hr; }
void DirectShowVideoWrapper::disableAudio(void) { if(isInitialized() && hasAudio()) { HRESULT hr; TCHAR szErr[MAX_ERROR_TEXT_LEN]; IBaseFilter* pAudioRenderer = NULL; hr = FindAudioRenderer(_pGraphBuilder,&pAudioRenderer); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Failed to find audio renderer, error: " << szErr << std::endl; return; } if(pAudioRenderer != NULL) { stop(); //Remove the Renderer IPin* ipin; hr = GetPin(pAudioRenderer, PINDIR_INPUT, 0, &ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Get Audio Renderer in pin, error: " << szErr << std::endl; return; } IPin* opin = NULL; //find out who the renderer is connected to and disconnect from them hr = ipin->ConnectedTo(&opin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return; } hr = ipin->Disconnect(); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return; } hr = opin->Disconnect(); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return; } //Remove the Renderer hr = _pGraphBuilder->RemoveFilter(pAudioRenderer); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return; } //Connect an NULL Audio renderer hr = _pGraphBuilder->AddFilter(_pNullAudioFilter, L"NULL Audio Renderer"); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return; } //get the input pin of the Color Space Converter hr = GetPin(_pNullAudioFilter, PINDIR_INPUT, 0, &ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Get Null Audio in pin, error: " << szErr << std::endl; return; } //Connect an Audio renderer hr = _pGraphBuilder->Connect(opin, ipin); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "error: " << szErr << std::endl; return; } } } }
void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel) { if( !pGraph ) { return; } IEnumFilters *pFilters; DbgLog((LOG_TRACE,dwLevel,TEXT("DumpGraph [%x]"), pGraph)); if (FAILED(pGraph->EnumFilters(&pFilters))) { DbgLog((LOG_TRACE,dwLevel,TEXT("EnumFilters failed!"))); } IBaseFilter *pFilter; ULONG n; while (pFilters->Next(1, &pFilter, &n) == S_OK) { FILTER_INFO info; if (FAILED(pFilter->QueryFilterInfo(&info))) { DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] -- failed QueryFilterInfo"), pFilter)); } else { QueryFilterInfoReleaseGraph(info); // !!! should QueryVendorInfo here! DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] '%ls'"), pFilter, info.achName)); IEnumPins *pins; if (FAILED(pFilter->EnumPins(&pins))) { DbgLog((LOG_TRACE,dwLevel,TEXT("EnumPins failed!"))); } else { IPin *pPin; while (pins->Next(1, &pPin, &n) == S_OK) { PIN_INFO info; if (FAILED(pPin->QueryPinInfo(&info))) { DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] -- failed QueryPinInfo"), pPin)); } else { QueryPinInfoReleaseFilter(info); IPin *pPinConnected = NULL; HRESULT hr = pPin->ConnectedTo(&pPinConnected); if (pPinConnected) { DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] '%ls' [%sput]") TEXT(" Connected to pin [%x]"), pPin, info.achName, info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"), pPinConnected)); pPinConnected->Release(); // perhaps we should really dump the type both ways as a sanity // check? if (info.dir == PINDIR_OUTPUT) { AM_MEDIA_TYPE mt; hr = pPin->ConnectionMediaType(&mt); if (SUCCEEDED(hr)) { DisplayType(TEXT("Connection type"), &mt); FreeMediaType(mt); } } } else { DbgLog((LOG_TRACE,dwLevel, TEXT(" Pin [%x] '%ls' [%sput]"), pPin, info.achName, info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"))); } } pPin->Release(); } pins->Release(); } } pFilter->Release(); } pFilters->Release(); }