HRESULT Inpin::ReceiveConnection( IPin* pin, const AM_MEDIA_TYPE* pmt) { if (pin == 0) return E_INVALIDARG; if (pmt == 0) return E_INVALIDARG; Filter::Lock lock; HRESULT hr = lock.Seize(m_pFilter); if (FAILED(hr)) return hr; if (m_pFilter->m_state != State_Stopped) return VFW_E_NOT_STOPPED; if (bool(m_pPinConnection)) return VFW_E_ALREADY_CONNECTED; m_connection_mtv.Clear(); hr = QueryAccept(pmt); if (hr != S_OK) return VFW_E_TYPE_NOT_ACCEPTED; const AM_MEDIA_TYPE& mt = *pmt; hr = m_connection_mtv.Add(mt); if (FAILED(hr)) return hr; m_pPinConnection = pin; //TODO: init decompressor here? m_pFilter->m_outpin.OnInpinConnect(mt); return S_OK; }
STDMETHODIMP CapturePin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) { if(filter->state != State_Stopped) return VFW_E_NOT_STOPPED; if(!pConnector || !pmt) return E_POINTER; if(connectedPin) return VFW_E_ALREADY_CONNECTED; if(QueryAccept(pmt) != S_OK) return VFW_E_TYPE_NOT_ACCEPTED; connectedPin = pConnector; connectedPin->AddRef(); FreeMediaType(connectedMediaType); return CopyMediaType(&connectedMediaType, pmt); }
STDMETHODIMP CapturePin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) { PrintFunc(L"CapturePin::ReceiveConnection"); if (filter->state != State_Stopped) return VFW_E_NOT_STOPPED; if (!pConnector || !pmt) return E_POINTER; if (connectedPin) return VFW_E_ALREADY_CONNECTED; if (QueryAccept(pmt) != S_OK) return VFW_E_TYPE_NOT_ACCEPTED; connectedPin = pConnector; connectedMediaType = pmt; return S_OK; }
STDMETHODIMP SampleCapturePin::ReceiveConnection( IPin * pConnector, const AM_MEDIA_TYPE *pmt ) { if( State_Stopped != p_filter->state ) { ATLTRACE( "SampleCapturePin::ReceiveConnection [not stopped]" ); return VFW_E_NOT_STOPPED; } if( !pConnector || !pmt ) { ATLTRACE( "SampleCapturePin::ReceiveConnection [null pointer]" ); return E_POINTER; } if( p_connected_pin ) { ATLTRACE( "SampleCapturePin::ReceiveConnection [already connected]"); return VFW_E_ALREADY_CONNECTED; } if( S_OK != QueryAccept(pmt) ) { ATLTRACE( "SampleCapturePin::ReceiveConnection " "[media type not accepted]" ); return VFW_E_TYPE_NOT_ACCEPTED; } ATLTRACE( "SampleCapturePin::ReceiveConnection [OK]" ); p_connected_pin = pConnector; p_connected_pin->AddRef(); FreeMediaType( cx_media_type ); return CopyMediaType( &cx_media_type, pmt ); }
HRESULT Outpin::Connect(IPin* pin, const AM_MEDIA_TYPE* pmt) { if (pin == 0) return E_POINTER; GraphUtil::IMemInputPinPtr pInputPin; HRESULT hr = pin->QueryInterface(&pInputPin); if (hr != S_OK) return hr; Filter::Lock lock; hr = lock.Seize(m_pFilter); if (FAILED(hr)) return hr; if (m_pFilter->GetStateLocked() != State_Stopped) return VFW_E_NOT_STOPPED; if (bool(m_pPinConnection)) return VFW_E_ALREADY_CONNECTED; if (!bool(m_pFilter->m_inpin.m_pPinConnection)) return VFW_E_NO_TYPES; // VFW_E_NOT_CONNECTED? m_connection_mtv.Clear(); if (pmt) { hr = QueryAccept(pmt); if (hr != S_OK) return VFW_E_TYPE_NOT_ACCEPTED; if ((pmt->formattype == FORMAT_VideoInfo) || (pmt->formattype == FORMAT_VideoInfo2)) { hr = pin->ReceiveConnection(this, pmt); if (FAILED(hr)) return hr; m_connection_mtv.Add(*pmt); } else { // partial media type const ULONG n = m_preferred_mtv.Size(); LONG idx = -1; for (ULONG i = 0; i < n; ++i) { const AM_MEDIA_TYPE& mt = m_preferred_mtv[i]; if (pmt->subtype == mt.subtype) { idx = i; break; } } if (idx < 0) // weird return VFW_E_TYPE_NOT_ACCEPTED; const AM_MEDIA_TYPE& mt = m_preferred_mtv[idx]; hr = pin->ReceiveConnection(this, &mt); if (FAILED(hr)) return hr; m_connection_mtv.Add(mt); } } else { ULONG i = 0; const ULONG j = m_preferred_mtv.Size(); while (i < j) { const AM_MEDIA_TYPE& mt = m_preferred_mtv[i]; hr = pin->ReceiveConnection(this, &mt); if (SUCCEEDED(hr)) break; ++i; } if (i >= j) return VFW_E_NO_ACCEPTABLE_TYPES; const AM_MEDIA_TYPE& mt = m_preferred_mtv[i]; m_connection_mtv.Add(mt); } GraphUtil::IMemAllocatorPtr pAllocator; hr = pInputPin->GetAllocator(&pAllocator); if (FAILED(hr)) { // hr = CMemAllocator::CreateInstance(&m_sample_factory, &pAllocator); hr = CMediaSample::CreateAllocator(&pAllocator); if (FAILED(hr)) return VFW_E_NO_ALLOCATOR; } assert(bool(pAllocator)); ALLOCATOR_PROPERTIES props, actual; props.cBuffers = -1; // number of buffers props.cbBuffer = -1; // size of each buffer, excluding prefix props.cbAlign = -1; // applies to prefix, too props.cbPrefix = -1; // imediasample::getbuffer does NOT include prefix hr = pInputPin->GetAllocatorRequirements(&props); if (props.cBuffers <= 0) props.cBuffers = 1; LONG w, h; GetConnectionDimensions(w, h); const long cbBuffer = 2 * w * h; if (props.cbBuffer < cbBuffer) props.cbBuffer = cbBuffer; if (props.cbAlign <= 0) props.cbAlign = 1; if (props.cbPrefix < 0) props.cbPrefix = 0; hr = pAllocator->SetProperties(&props, &actual); if (FAILED(hr)) return hr; hr = pInputPin->NotifyAllocator(pAllocator, 0); // allow writes if (FAILED(hr) && (hr != E_NOTIMPL)) return hr; m_pPinConnection = pin; m_pAllocator = pAllocator; m_pInputPin = pInputPin; return S_OK; }
STDMETHODIMP CStreamSwitcherInputPin::DynamicQueryAccept(const AM_MEDIA_TYPE* pmt) { return QueryAccept(pmt); }
HRESULT Inpin::ReceiveConnection( IPin* pin, const AM_MEDIA_TYPE* pmt) { if (pin == 0) return E_INVALIDARG; GraphUtil::IAsyncReaderPtr pReader; HRESULT hr = pin->QueryInterface(&pReader); if (hr != S_OK) return hr; Filter::Lock lock; hr = lock.Seize(m_pFilter); if (FAILED(hr)) return hr; if (m_pFilter->m_state != State_Stopped) return VFW_E_NOT_STOPPED; if (bool(m_pPinConnection)) return VFW_E_ALREADY_CONNECTED; m_connection_mtv.Clear(); if ((pmt != 0) && (pmt->majortype != GUID_NULL)) { hr = QueryAccept(pmt); if (hr != S_OK) return VFW_E_TYPE_NOT_ACCEPTED; } hr = m_connection_mtv.Add(*pmt); if (FAILED(hr)) return hr; hr = m_reader.SetSource(pReader); if (FAILED(hr)) return hr; m_reader.m_sync_read = true; #if 1 hr = m_pFilter->Open(); #else for (;;) { hr = m_pFilter->Open(); if (SUCCEEDED(hr)) break; if (hr != VFW_E_BUFFER_UNDERFLOW) break; LONGLONG total, avail; const int status = m_reader.Length(&total, &avail); if (status < 0) { hr = VFW_E_RUNTIME_ERROR; break; } if (avail >= total) continue; hr = m_reader.Wait(*m_pFilter, avail, 1, 5000); if (FAILED(hr)) break; } #endif if (FAILED(hr)) { m_reader.SetSource(0); return hr; } m_reader.m_sync_read = false; m_pPinConnection = pin; return S_OK; }
STDMETHODIMP TffdshowDecAudioInputPin::DynamicQueryAccept(const AM_MEDIA_TYPE* pmt) { return QueryAccept(pmt); }