📄 filter.cpp
字号:
};/* IPin methods */STDMETHODIMP CapturePin::Connect( IPin * pReceivePin, const AM_MEDIA_TYPE *pmt ){ if( State_Running == p_filter->state ) { msg_Dbg( p_input, "CapturePin::Connect [not stopped]" ); return VFW_E_NOT_STOPPED; } if( p_connected_pin ) { msg_Dbg( p_input, "CapturePin::Connect [already connected]" ); return VFW_E_ALREADY_CONNECTED; } if( !pmt ) return S_OK; if( GUID_NULL != pmt->majortype && media_types[0].majortype != pmt->majortype ) { msg_Dbg( p_input, "CapturePin::Connect [media major type mismatch]" ); return S_FALSE; } if( GUID_NULL != pmt->subtype && !GetFourCCFromMediaType(*pmt) ) { msg_Dbg( p_input, "CapturePin::Connect [media subtype type " "not supported]" ); return S_FALSE; } if( pmt->pbFormat && pmt->majortype == MEDIATYPE_Video ) { if( !((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biHeight || !((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biWidth ) { msg_Dbg( p_input, "CapturePin::Connect " "[video width/height == 0 ]" ); return S_FALSE; } } msg_Dbg( p_input, "CapturePin::Connect [OK]" ); return S_OK;}STDMETHODIMP CapturePin::ReceiveConnection( IPin * pConnector, const AM_MEDIA_TYPE *pmt ){ if( State_Stopped != p_filter->state ) { msg_Dbg( p_input, "CapturePin::ReceiveConnection [not stopped]" ); return VFW_E_NOT_STOPPED; } if( !pConnector || !pmt ) { msg_Dbg( p_input, "CapturePin::ReceiveConnection [null pointer]" ); return E_POINTER; } if( p_connected_pin ) { msg_Dbg( p_input, "CapturePin::ReceiveConnection [already connected]"); return VFW_E_ALREADY_CONNECTED; } if( S_OK != QueryAccept(pmt) ) { msg_Dbg( p_input, "CapturePin::ReceiveConnection " "[media type not accepted]" ); return VFW_E_TYPE_NOT_ACCEPTED; } msg_Dbg( p_input, "CapturePin::ReceiveConnection [OK]" ); p_connected_pin = pConnector; p_connected_pin->AddRef(); FreeMediaType( cx_media_type ); return CopyMediaType( &cx_media_type, pmt );}STDMETHODIMP CapturePin::Disconnect(){ if( ! p_connected_pin ) { msg_Dbg( p_input, "CapturePin::Disconnect [not connected]" ); return S_FALSE; } msg_Dbg( p_input, "CapturePin::Disconnect [OK]" ); /* samples_queue was already flushed in EndFlush() */ p_connected_pin->Release(); p_connected_pin = NULL; //FreeMediaType( cx_media_type ); //cx_media_type.subtype = GUID_NULL; return S_OK;}STDMETHODIMP CapturePin::ConnectedTo( IPin **pPin ){ if( !p_connected_pin ) { msg_Dbg( p_input, "CapturePin::ConnectedTo [not connected]" ); return VFW_E_NOT_CONNECTED; } p_connected_pin->AddRef(); *pPin = p_connected_pin; msg_Dbg( p_input, "CapturePin::ConnectedTo [OK]" ); return S_OK;}STDMETHODIMP CapturePin::ConnectionMediaType( AM_MEDIA_TYPE *pmt ){ if( !p_connected_pin ) { msg_Dbg( p_input, "CapturePin::ConnectionMediaType [not connected]" ); return VFW_E_NOT_CONNECTED; } return CopyMediaType( pmt, &cx_media_type );}STDMETHODIMP CapturePin::QueryPinInfo( PIN_INFO * pInfo ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::QueryPinInfo" );#endif pInfo->pFilter = p_filter; if( p_filter ) p_filter->AddRef(); memcpy(pInfo->achName, PIN_NAME, sizeof(PIN_NAME)); pInfo->dir = PINDIR_INPUT; return NOERROR;}STDMETHODIMP CapturePin::QueryDirection( PIN_DIRECTION * pPinDir ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::QueryDirection" );#endif *pPinDir = PINDIR_INPUT; return NOERROR;}STDMETHODIMP CapturePin::QueryId( LPWSTR * Id ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::QueryId" );#endif *Id = L"VideoLAN Capture Pin"; return S_OK;}STDMETHODIMP CapturePin::QueryAccept( const AM_MEDIA_TYPE *pmt ){ if( State_Stopped != p_filter->state ) { msg_Dbg( p_input, "CapturePin::QueryAccept [not stopped]" ); return S_FALSE; } if( media_types[0].majortype != pmt->majortype ) { msg_Dbg( p_input, "CapturePin::QueryAccept [media type mismatch]" ); return S_FALSE; } int i_fourcc = GetFourCCFromMediaType(*pmt); if( !i_fourcc ) { msg_Dbg( p_input, "CapturePin::QueryAccept " "[media type not supported]" ); return S_FALSE; } if( pmt->majortype == MEDIATYPE_Video ) { if( pmt->pbFormat && ( (((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biHeight == 0) || (((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biWidth == 0) ) ) { msg_Dbg( p_input, "CapturePin::QueryAccept [video size wxh == 0]"); return S_FALSE; } msg_Dbg( p_input, "CapturePin::QueryAccept [OK] " "(width=%ld, height=%ld, chroma=%4.4s, fps=%f)", ((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biWidth, ((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biHeight, (char *)&i_fourcc, 10000000.0f/((float)((VIDEOINFOHEADER *)pmt->pbFormat)->AvgTimePerFrame) ); } else if( pmt->majortype == MEDIATYPE_Audio ) { msg_Dbg( p_input, "CapturePin::QueryAccept [OK] (channels=%d, " "samples/sec=%lu, bits/samples=%d, format=%4.4s)", ((WAVEFORMATEX *)pmt->pbFormat)->nChannels, ((WAVEFORMATEX *)pmt->pbFormat)->nSamplesPerSec, ((WAVEFORMATEX *)pmt->pbFormat)->wBitsPerSample, (char *)&i_fourcc ); } else { msg_Dbg( p_input, "CapturePin::QueryAccept [OK] (stream format=%4.4s)", (char *)&i_fourcc ); } if( p_connected_pin ) { FreeMediaType( cx_media_type ); CopyMediaType( &cx_media_type, pmt ); } return S_OK;}STDMETHODIMP CapturePin::EnumMediaTypes( IEnumMediaTypes **ppEnum ){#ifdef DEBUG_DSHOW_L1 msg_Dbg( p_input, "CapturePin::EnumMediaTypes" );#endif *ppEnum = new CaptureEnumMediaTypes( p_input, this, NULL ); if( *ppEnum == NULL ) return E_OUTOFMEMORY; return NOERROR;}STDMETHODIMP CapturePin::QueryInternalConnections( IPin* *apPin, ULONG *nPin ){#ifdef DEBUG_DSHOW_L1 msg_Dbg( p_input, "CapturePin::QueryInternalConnections" );#endif return E_NOTIMPL;}STDMETHODIMP CapturePin::EndOfStream( void ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::EndOfStream" );#endif return S_OK;}STDMETHODIMP CapturePin::BeginFlush( void ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::BeginFlush" );#endif return S_OK;}STDMETHODIMP CapturePin::EndFlush( void ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::EndFlush" );#endif VLCMediaSample vlc_sample; vlc_mutex_lock( &p_sys->lock ); while( samples_queue.size() ) { vlc_sample = samples_queue.back(); samples_queue.pop_back(); vlc_sample.p_sample->Release(); } vlc_mutex_unlock( &p_sys->lock ); return S_OK;}STDMETHODIMP CapturePin::NewSegment( REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::NewSegment" );#endif return S_OK;}/* IMemInputPin methods */STDMETHODIMP CapturePin::GetAllocator( IMemAllocator **ppAllocator ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::GetAllocator" );#endif return VFW_E_NO_ALLOCATOR;}STDMETHODIMP CapturePin::NotifyAllocator( IMemAllocator *pAllocator, BOOL bReadOnly ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::NotifyAllocator" );#endif return S_OK;}STDMETHODIMP CapturePin::GetAllocatorRequirements( ALLOCATOR_PROPERTIES *pProps ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::GetAllocatorRequirements" );#endif return E_NOTIMPL;}STDMETHODIMP CapturePin::Receive( IMediaSample *pSample ){#if 0 //def DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::Receive" );#endif pSample->AddRef(); mtime_t i_timestamp = mdate() * 10; VLCMediaSample vlc_sample = {pSample, i_timestamp}; vlc_mutex_lock( &p_sys->lock ); samples_queue.push_front( vlc_sample ); /* Make sure we don't cache too many samples */ if( samples_queue.size() > 10 ) { vlc_sample = samples_queue.back(); samples_queue.pop_back(); msg_Dbg( p_input, "CapturePin::Receive trashing late input sample" ); vlc_sample.p_sample->Release(); } vlc_cond_signal( &p_sys->wait ); vlc_mutex_unlock( &p_sys->lock ); return S_OK;}STDMETHODIMP CapturePin::ReceiveMultiple( IMediaSample **pSamples, long nSamples, long *nSamplesProcessed ){ HRESULT hr = S_OK; *nSamplesProcessed = 0; while( nSamples-- > 0 ) { hr = Receive( pSamples[*nSamplesProcessed] ); if( hr != S_OK ) break; (*nSamplesProcessed)++; } return hr;}STDMETHODIMP CapturePin::ReceiveCanBlock( void ){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CapturePin::ReceiveCanBlock" );#endif return S_FALSE; /* Thou shalt not block */}/**************************************************************************** * Implementation of our dummy directshow filter class ****************************************************************************/CaptureFilter::CaptureFilter( vlc_object_t *_p_input, access_sys_t *p_sys, AM_MEDIA_TYPE *mt, size_t mt_count ) : p_input( _p_input ), p_pin( new CapturePin( _p_input, p_sys, this, mt, mt_count ) ), state( State_Stopped ), i_ref( 1 ){}CaptureFilter::~CaptureFilter(){#ifdef DEBUG_DSHOW msg_Dbg( p_input, "CaptureFilter::~CaptureFilter" );#endif p_pin->Release();}/* IUnknown methods */STDMETHODIMP CaptureFilter::QueryInterface( REFIID riid, void **ppv ){#ifdef DEBUG_DSHOW_L1 msg_Dbg( p_input, "CaptureFilter::QueryInterface" );#endif if( riid == IID_IUnknown ) { AddRef(); *ppv = (IUnknown *)this; return NOERROR; } if( riid == IID_IPersist ) { AddRef(); *ppv = (IPersist *)this; return NOERROR; } if( riid == IID_IMediaFilter ) { AddRef(); *ppv = (IMediaFilter *)this; return NOERROR; } if( riid == IID_IBaseFilter ) { AddRef(); *ppv = (IBaseFilter *)this; return NOERROR; } else {#ifdef DEBUG_DSHOW_L1 msg_Dbg( p_input, "CaptureFilter::QueryInterface() failed for: " "%04X-%02X-%02X-%02X%02X%02X%02X%02X%02X%02X%02X", (int)riid.Data1, (int)riid.Data2, (int)riid.Data3, static_cast<int>(riid.Data4[0]), (int)riid.Data4[1], (int)riid.Data4[2], (int)riid.Data4[3], (int)riid.Data4[4], (int)riid.Data4[5], (int)riid.Data4[6], (int)riid.Data4[7] );#endif *ppv = NULL; return E_NOINTERFACE; }};STDMETHODIMP_(ULONG) CaptureFilter::AddRef(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -