📄 bdagraph.cpp
字号:
* Connect is called from Build to enumerate and connect pins*****************************************************************************/HRESULT BDAGraph::Connect( IBaseFilter* p_upstream, IBaseFilter* p_downstream ){ HRESULT hr = E_FAIL; class localComPtr { public: IPin* p_pin_upstream; IPin* p_pin_downstream; IEnumPins* p_pin_upstream_enum; IEnumPins* p_pin_downstream_enum; IPin* p_pin_temp; localComPtr(): p_pin_upstream(NULL), p_pin_downstream(NULL), p_pin_upstream_enum(NULL), p_pin_downstream_enum(NULL), p_pin_temp(NULL) { }; ~localComPtr() { if( p_pin_upstream ) p_pin_upstream->Release(); if( p_pin_downstream ) p_pin_downstream->Release(); if( p_pin_upstream_enum ) p_pin_upstream_enum->Release(); if( p_pin_downstream_enum ) p_pin_downstream_enum->Release(); if( p_pin_temp ) p_pin_temp->Release(); } } l; PIN_INFO pin_info_upstream; PIN_INFO pin_info_downstream; hr = p_upstream->EnumPins( &l.p_pin_upstream_enum ); if( FAILED( hr ) ) { msg_Warn( p_access, "Connect: "\ "Cannot get upstream filter enumerator: hr=0x%8lx", hr ); return hr; } while( l.p_pin_upstream_enum->Next( 1, &l.p_pin_upstream, 0 ) == S_OK ) { hr = l.p_pin_upstream->QueryPinInfo( &pin_info_upstream ); if( FAILED( hr ) ) { msg_Warn( p_access, "Connect: "\ "Cannot get upstream filter pin information: hr=0x%8lx", hr ); return hr; } hr = l.p_pin_upstream->ConnectedTo( &l.p_pin_downstream ); if( hr == S_OK ) l.p_pin_downstream->Release(); if(FAILED( hr ) && hr != VFW_E_NOT_CONNECTED ) { msg_Warn( p_access, "Connect: "\ "Cannot check upstream filter connection: hr=0x%8lx", hr ); return hr; } if(( pin_info_upstream.dir == PINDIR_OUTPUT ) && ( hr == VFW_E_NOT_CONNECTED ) ) { /* The upstream pin is not yet connected so check each pin on the * downstream filter */ hr = p_downstream->EnumPins( &l.p_pin_downstream_enum ); if( FAILED( hr ) ) { msg_Warn( p_access, "Connect: Cannot get "\ "downstream filter enumerator: hr=0x%8lx", hr ); return hr; } while( l.p_pin_downstream_enum->Next( 1, &l.p_pin_downstream, 0 ) == S_OK ) { hr = l.p_pin_downstream->QueryPinInfo( &pin_info_downstream ); if( FAILED( hr ) ) { msg_Warn( p_access, "Connect: Cannot get "\ "downstream filter pin information: hr=0x%8lx", hr ); return hr; } hr = l.p_pin_downstream->ConnectedTo( &l.p_pin_temp ); if( hr == S_OK ) l.p_pin_temp->Release(); if( hr != VFW_E_NOT_CONNECTED ) { if( FAILED( hr ) ) { msg_Warn( p_access, "Connect: Cannot check "\ "downstream filter connection: hr=0x%8lx", hr ); return hr; } } if(( pin_info_downstream.dir == PINDIR_INPUT ) && ( hr == VFW_E_NOT_CONNECTED ) ) { hr = p_filter_graph->ConnectDirect( l.p_pin_upstream, l.p_pin_downstream, NULL ); if( SUCCEEDED( hr ) ) { pin_info_downstream.pFilter->Release(); pin_info_upstream.pFilter->Release(); return S_OK; } } /* If we fall out here it means this downstream pin was not * suitable so try the next downstream pin */ l.p_pin_downstream = NULL; pin_info_downstream.pFilter->Release(); } } /* If we fall out here it means we did not find any suitable downstream * pin so try the next upstream pin */ l.p_pin_upstream = NULL; pin_info_upstream.pFilter->Release(); } /* If we fall out here it means we did not find any pair of suitable pins */ return E_FAIL;}/****************************************************************************** Start uses MediaControl to start the graph*****************************************************************************/HRESULT BDAGraph::Start(){ HRESULT hr = S_OK; OAFilterState i_state; /* State_Stopped, State_Paused, State_Running */ if( !p_media_control ) { msg_Dbg( p_access, "Start: Media Control has not been created" ); return E_FAIL; } hr = p_media_control->Run(); if( hr == S_OK ) return hr; /* Query the state of the graph - timeout after 100 milliseconds */ while( hr = p_media_control->GetState( 100, &i_state ) != S_OK ) { if( FAILED( hr ) ) { msg_Warn( p_access, "Start: Cannot get Graph state: hr=0x%8lx", hr ); return hr; } } if( i_state == State_Running ) return hr; /* The Graph is not running so stop it and return an error */ msg_Warn( p_access, "Start: Graph not started: %d", i_state ); hr = p_media_control->Stop(); if( FAILED( hr ) ) { msg_Warn( p_access, "Start: Cannot stop Graph after Run failed: hr=0x%8lx", hr ); return hr; } return E_FAIL;}/****************************************************************************** Read the stream of data - query the buffer size required*****************************************************************************/long BDAGraph::GetBufferSize(){ long l_buffer_size = 0; long l_queue_size; b_ready = true; for( int i_timer = 0; queue_sample.empty() && i_timer < 200; i_timer++ ) Sleep( 10 ); l_queue_size = queue_sample.size(); if( l_queue_size <= 0 ) { msg_Warn( p_access, "BDA GetBufferSize: Timed Out waiting for sample" ); return -1; } /* Establish the length of the queue as it grows quickly. If the queue * size is checked dynamically there is a risk of not exiting the loop */ for( long l_queue_count=0; l_queue_count < l_queue_size; l_queue_count++ ) { l_buffer_size += queue_sample.front()->GetActualDataLength(); queue_buffer.push( queue_sample.front() ); queue_sample.pop(); } return l_buffer_size;}/****************************************************************************** Read the stream of data - Retrieve from the buffer queue******************************************************************************/long BDAGraph::ReadBuffer( long* pl_buffer_len, BYTE* p_buffer ){ HRESULT hr = S_OK; *pl_buffer_len = 0; BYTE *p_buff_temp; while( !queue_buffer.empty() ) { queue_buffer.front()->GetPointer( &p_buff_temp ); hr = queue_buffer.front()->IsDiscontinuity(); if( hr == S_OK ) msg_Warn( p_access, "BDA ReadBuffer: Sample Discontinuity. 0x%8lx", hr ); memcpy( p_buffer + *pl_buffer_len, p_buff_temp, queue_buffer.front()->GetActualDataLength() ); *pl_buffer_len += queue_buffer.front()->GetActualDataLength(); queue_buffer.front()->Release(); queue_buffer.pop(); } return *pl_buffer_len;}/******************************************************************************* SampleCB - Callback when the Sample Grabber has a sample******************************************************************************/STDMETHODIMP BDAGraph::SampleCB( double d_time, IMediaSample *p_sample ){ if( b_ready ) { p_sample->AddRef(); queue_sample.push( p_sample ); } else { msg_Warn( p_access, "BDA SampleCB: Not ready - dropped sample" ); } return S_OK;}STDMETHODIMP BDAGraph::BufferCB( double d_time, BYTE* p_buffer, long l_buffer_len ){ return E_FAIL;}/******************************************************************************* removes each filter from the graph******************************************************************************/HRESULT BDAGraph::Destroy(){ HRESULT hr = S_OK; if( p_media_control ) hr = p_media_control->Stop(); if( p_transport_info ) { p_filter_graph->RemoveFilter( p_transport_info ); p_transport_info->Release(); p_transport_info = NULL; } if( p_mpeg_demux ) { p_filter_graph->RemoveFilter( p_mpeg_demux ); p_mpeg_demux->Release(); p_mpeg_demux = NULL; } if( p_sample_grabber ) { p_filter_graph->RemoveFilter( p_sample_grabber ); p_sample_grabber->Release(); p_sample_grabber = NULL; } if( p_capture_device ) { p_filter_graph->RemoveFilter( p_capture_device ); p_capture_device->Release(); p_capture_device = NULL; } if( p_tuner_device ) { p_filter_graph->RemoveFilter( p_tuner_device ); p_tuner_device->Release(); p_tuner_device = NULL; } if( p_network_provider ) { p_filter_graph->RemoveFilter( p_network_provider ); p_network_provider->Release(); p_network_provider = NULL; } if( p_scanning_tuner ) { p_scanning_tuner->Release(); p_scanning_tuner = NULL; } if( p_media_control ) { p_media_control->Release(); p_media_control = NULL; } if( p_filter_graph ) { p_filter_graph->Release(); p_filter_graph = NULL; } if( d_graph_register ) { Deregister(); } return S_OK;}/****************************************************************************** Add/Remove a DirectShow filter graph to/from the Running Object Table.* Allows GraphEdit to "spy" on a remote filter graph.******************************************************************************/HRESULT BDAGraph::Register(){ class localComPtr { public: IMoniker* p_moniker; IRunningObjectTable* p_ro_table; localComPtr(): p_moniker(NULL), p_ro_table(NULL) {}; ~localComPtr() { if( p_moniker ) p_moniker->Release(); if( p_ro_table ) p_ro_table->Release(); } } l; WCHAR psz_w_graph_name[128]; HRESULT hr; hr = ::GetRunningObjectTable( 0, &l.p_ro_table ); if( FAILED( hr ) ) { msg_Warn( p_access, "Register: Cannot get ROT: hr=0x%8lx", hr ); return hr; } wsprintfW( psz_w_graph_name, L"VLC BDA Graph %08x Pid %08x", (DWORD_PTR) p_filter_graph, ::GetCurrentProcessId() ); hr = CreateItemMoniker( L"!", psz_w_graph_name, &l.p_moniker ); if( FAILED( hr ) ) { msg_Warn( p_access, "Register: Cannot Create Moniker: hr=0x%8lx", hr ); return hr; } hr = l.p_ro_table->Register( ROTFLAGS_REGISTRATIONKEEPSALIVE, p_filter_graph, l.p_moniker, &d_graph_register ); if( FAILED( hr ) ) { msg_Warn( p_access, "Register: Cannot Register Graph: hr=0x%8lx", hr ); return hr; } msg_Dbg( p_access, "Register: registered Graph: %S", psz_w_graph_name ); return hr;}void BDAGraph::Deregister(){ HRESULT hr; IRunningObjectTable* p_ro_table; hr = ::GetRunningObjectTable( 0, &p_ro_table ); if( SUCCEEDED( hr ) ) p_ro_table->Revoke( d_graph_register ); d_graph_register = 0; p_ro_table->Release();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -