ErrorCode BasePinImpl::AgreeMediaType(IPin *pReceivePin, MediaType* mt) { ErrorCode hr = Error; // Assume failure at first // TODO #if 0 if (mt && FALSE) // The mediatype is fully specified { ErrorCode hr = AttemptConnection(pReceivePin, mt); if (FAILED(hr)) return hr; } #endif // Try the input pins preferred types IEnumMediaTypes* pEnumIn = pReceivePin->EnumMediaTypes(); if (pEnumIn) { hr = TryMediaTypes(pReceivePin, mt, pEnumIn); if (hr >= 0) return hr; } // Try the output pins preferred types IEnumMediaTypes* pEnumOut = EnumMediaTypes(); if (pEnumOut) { hr = TryMediaTypes(pReceivePin, mt, pEnumOut); if (hr >= 0) return hr; } return hr; }
// This pin attempts to connect to |aPin| with media type |aMediaType|. // If |aMediaType| is fully specified, we must attempt to connect with // that, else we just enumerate our types, then the other pin's type and // try them, filtering them using |aMediaType| if it's paritally // specificed. Used by Connect(). STDMETHODIMP BasePin::Connect(IPin * aPin, const AM_MEDIA_TYPE* aMediaType) { if (!aPin) return E_POINTER; CriticalSectionAutoEnter monitor(*mLock); if (IsConnected()) return VFW_E_ALREADY_CONNECTED; // Can't connect when filter is not stopped. if (!IsStopped()) return VFW_E_NOT_STOPPED; // Find a muatually acceptable media type. First try the media type // suggested, then try our media types, then the other pin's media types. const MediaType* mediaType = reinterpret_cast<const MediaType*>(aMediaType); if (aMediaType && !mediaType->IsPartiallySpecified()) { // Media type is supplied and not partially specified, we must try to // connect with that. return AttemptConnection(aPin, mediaType); } // Try this pin's media types... IEnumMediaTypesPtr enumMediaTypes; HRESULT hr = EnumMediaTypes(&enumMediaTypes); assert(SUCCEEDED(hr)); if (enumMediaTypes) { hr = TryMediaTypes(aPin, mediaType, enumMediaTypes); if (SUCCEEDED(hr)) return S_OK; } // Can't connect with our media types, try other pins types... enumMediaTypes = NULL; hr = aPin->EnumMediaTypes(&enumMediaTypes); assert(SUCCEEDED(hr)); if (enumMediaTypes) { hr = TryMediaTypes(aPin, mediaType, enumMediaTypes); if (SUCCEEDED(hr)) return S_OK; } // Nothing connects. return VFW_E_NO_ACCEPTABLE_TYPES; }
HRESULT CBasePin::AgreeMediaType( IPin *pReceivePin, const CMediaType *pmt) { ASSERT(pReceivePin); IEnumMediaTypes *pEnumMediaTypes = NULL; // if the media type is fully specified then use that if ( (pmt != NULL) && (!pmt->IsPartiallySpecified())) { // if this media type fails, then we must fail the connection // since if pmt is nonnull we are only allowed to connect // using a type that matches it. return AttemptConnection(pReceivePin, pmt); } /* Try the other pin's enumerator */ HRESULT hrFailure = VFW_E_NO_ACCEPTABLE_TYPES; for (int i = 0; i < 2; i++) { HRESULT hr; if (i == (int)m_bTryMyTypesFirst) { hr = pReceivePin->EnumMediaTypes(&pEnumMediaTypes); } else { hr = EnumMediaTypes(&pEnumMediaTypes); } if (SUCCEEDED(hr)) { ASSERT(pEnumMediaTypes); hr = TryMediaTypes(pReceivePin,pmt,pEnumMediaTypes); pEnumMediaTypes->Release(); if (SUCCEEDED(hr)) { return NOERROR; } else { // try to remember specific error codes if there are any if ((hr != E_FAIL) && (hr != E_INVALIDARG) && (hr != VFW_E_TYPE_NOT_ACCEPTED)) { hrFailure = hr; } } } } return hrFailure; }