📄 dshow.cpp
字号:
/***************************************************************************** * dshow.cpp : DirectShow access module for vlc ***************************************************************************** * Copyright (C) 2002, 2003 the VideoLAN team * $Id: dbbe31be9238e4447908942ed7084b9a1e125ea4 $ * * Author: Gildas Bazin <gbazin@videolan.org> * Damien Fouilleul <damienf@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#define __STDC_FORMAT_MACROS 1#include <inttypes.h>#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_input.h>#include <vlc_access.h>#include <vlc_demux.h>#include <vlc_vout.h>#include <vlc_interface.h>#include "common.h"#include "filter.h"/***************************************************************************** * Access: local prototypes *****************************************************************************/static block_t *ReadCompressed( access_t * );static int AccessControl ( access_t *, int, va_list );static int Demux ( demux_t * );static int DemuxControl( demux_t *, int, va_list );static int OpenDevice( vlc_object_t *, access_sys_t *, string, bool );static IBaseFilter *FindCaptureDevice( vlc_object_t *, string *, list<string> *, bool );static size_t EnumDeviceCaps( vlc_object_t *, IBaseFilter *, int, int, int, int, int, int, AM_MEDIA_TYPE *mt, size_t );static bool ConnectFilters( vlc_object_t *, access_sys_t *, IBaseFilter *, CaptureFilter * );static int FindDevicesCallback( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );static int ConfigDevicesCallback( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );static void ShowPropertyPage( IUnknown * );static void ShowDeviceProperties( vlc_object_t *, ICaptureGraphBuilder2 *, IBaseFilter *, bool );static void ShowTunerProperties( vlc_object_t *, ICaptureGraphBuilder2 *, IBaseFilter *, bool );static void ConfigTuner( vlc_object_t *, ICaptureGraphBuilder2 *, IBaseFilter * );/***************************************************************************** * Module descriptor *****************************************************************************/static const char *const ppsz_vdev[] = { "", "none" };static const char *const ppsz_vdev_text[] = { N_("Default"), N_("None") };static const char *const ppsz_adev[] = { "", "none" };static const char *const ppsz_adev_text[] = { N_("Default"), N_("None") };static const int pi_tuner_input[] = { 0, 1, 2 };static const char *const ppsz_tuner_input_text[] = {N_("Default"), N_("Cable"), N_("Antenna")};static const int pi_amtuner_mode[] = { AMTUNER_MODE_DEFAULT, AMTUNER_MODE_TV, AMTUNER_MODE_FM_RADIO, AMTUNER_MODE_AM_RADIO, AMTUNER_MODE_DSS };static const char *const ppsz_amtuner_mode_text[] = { N_("Default"), N_("TV"), N_("FM radio"), N_("AM radio"), N_("DSS") };#define CACHING_TEXT N_("Caching value in ms")#define CACHING_LONGTEXT N_( \ "Caching value for DirectShow streams. " \ "This value should be set in millisecondss." )#define VDEV_TEXT N_("Video device name")#define VDEV_LONGTEXT N_( \ "Name of the video device that will be used by the " \ "DirectShow plugin. If you don't specify anything, the default device " \ "will be used.")#define ADEV_TEXT N_("Audio device name")#define ADEV_LONGTEXT N_( \ "Name of the audio device that will be used by the " \ "DirectShow plugin. If you don't specify anything, the default device " \ "will be used. ")#define SIZE_TEXT N_("Video size")#define SIZE_LONGTEXT N_( \ "Size of the video that will be displayed by the " \ "DirectShow plugin. If you don't specify anything the default size for " \ "your device will be used. You can specify a standard size (cif, d1, ...) or <width>x<height>.")#define CHROMA_TEXT N_("Video input chroma format")#define CHROMA_LONGTEXT N_( \ "Force the DirectShow video input to use a specific chroma format " \ "(eg. I420 (default), RV24, etc.)")#define FPS_TEXT N_("Video input frame rate")#define FPS_LONGTEXT N_( \ "Force the DirectShow video input to use a specific frame rate" \ "(eg. 0 means default, 25, 29.97, 50, 59.94, etc.)")#define CONFIG_TEXT N_("Device properties")#define CONFIG_LONGTEXT N_( \ "Show the properties dialog of the selected device before starting the " \ "stream.")#define TUNER_TEXT N_("Tuner properties")#define TUNER_LONGTEXT N_( \ "Show the tuner properties [channel selection] page." )#define CHANNEL_TEXT N_("Tuner TV Channel")#define CHANNEL_LONGTEXT N_( \ "Set the TV channel the tuner will set to " \ "(0 means default)." )#define COUNTRY_TEXT N_("Tuner country code")#define COUNTRY_LONGTEXT N_( \ "Set the tuner country code that establishes the current " \ "channel-to-frequency mapping (0 means default)." )#define TUNER_INPUT_TEXT N_("Tuner input type")#define TUNER_INPUT_LONGTEXT N_( \ "Select the tuner input type (Cable/Antenna)." )#define VIDEO_IN_TEXT N_("Video input pin")#define VIDEO_IN_LONGTEXT N_( \ "Select the video input source, such as composite, s-video, " \ "or tuner. Since these settings are hardware-specific, you should find good " \ "settings in the \"Device config\" area, and use those numbers here. -1 " \ "means that settings will not be changed.")#define AUDIO_IN_TEXT N_("Audio input pin")#define AUDIO_IN_LONGTEXT N_( \ "Select the audio input source. See the \"video input\" option." )#define VIDEO_OUT_TEXT N_("Video output pin")#define VIDEO_OUT_LONGTEXT N_( \ "Select the video output type. See the \"video input\" option." )#define AUDIO_OUT_TEXT N_("Audio output pin")#define AUDIO_OUT_LONGTEXT N_( \ "Select the audio output type. See the \"video input\" option." )#define AMTUNER_MODE_TEXT N_("AM Tuner mode")#define AMTUNER_MODE_LONGTEXT N_( \ "AM Tuner mode. Can be one of Default (0), TV (1)," \ "AM Radio (2), FM Radio (3) or DSS (4).")#define AUDIO_CHANNELS_TEXT N_("Number of audio channels")#define AUDIO_CHANNELS_LONGTEXT N_( \ "Select audio input format with the given number of audio channels (if non 0)" )#define AUDIO_SAMPLERATE_TEXT N_("Audio sample rate")#define AUDIO_SAMPLERATE_LONGTEXT N_( \ "Select audio input format with the given sample rate (if non 0)" )#define AUDIO_BITSPERSAMPLE_TEXT N_("Audio bits per sample")#define AUDIO_BITSPERSAMPLE_LONGTEXT N_( \ "Select audio input format with the given bits/sample (if non 0)" )static int CommonOpen ( vlc_object_t *, access_sys_t *, bool );static void CommonClose( vlc_object_t *, access_sys_t * );static int AccessOpen ( vlc_object_t * );static void AccessClose( vlc_object_t * );static int DemuxOpen ( vlc_object_t * );static void DemuxClose ( vlc_object_t * );vlc_module_begin(); set_shortname( N_("DirectShow") ); set_description( N_("DirectShow input") ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_ACCESS ); add_integer( "dshow-caching", (mtime_t)(0.2*CLOCK_FREQ) / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, true ); add_string( "dshow-vdev", NULL, NULL, VDEV_TEXT, VDEV_LONGTEXT, false); change_string_list( ppsz_vdev, ppsz_vdev_text, FindDevicesCallback ); change_action_add( FindDevicesCallback, N_("Refresh list") ); change_action_add( ConfigDevicesCallback, N_("Configure") ); add_string( "dshow-adev", NULL, NULL, ADEV_TEXT, ADEV_LONGTEXT, false); change_string_list( ppsz_adev, ppsz_adev_text, FindDevicesCallback ); change_action_add( FindDevicesCallback, N_("Refresh list") ); change_action_add( ConfigDevicesCallback, N_("Configure") ); add_string( "dshow-size", NULL, NULL, SIZE_TEXT, SIZE_LONGTEXT, false); add_string( "dshow-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, true ); add_float( "dshow-fps", 0.0f, NULL, FPS_TEXT, FPS_LONGTEXT, true ); add_bool( "dshow-config", false, NULL, CONFIG_TEXT, CONFIG_LONGTEXT, true ); add_bool( "dshow-tuner", false, NULL, TUNER_TEXT, TUNER_LONGTEXT, true ); add_integer( "dshow-tuner-channel", 0, NULL, CHANNEL_TEXT, CHANNEL_LONGTEXT, true ); add_integer( "dshow-tuner-country", 0, NULL, COUNTRY_TEXT, COUNTRY_LONGTEXT, true ); add_integer( "dshow-tuner-input", 0, NULL, TUNER_INPUT_TEXT, TUNER_INPUT_LONGTEXT, true ); change_integer_list( pi_tuner_input, ppsz_tuner_input_text, NULL ); add_integer( "dshow-video-input", -1, NULL, VIDEO_IN_TEXT, VIDEO_IN_LONGTEXT, true ); add_integer( "dshow-audio-input", -1, NULL, AUDIO_IN_TEXT, AUDIO_IN_LONGTEXT, true ); add_integer( "dshow-video-output", -1, NULL, VIDEO_OUT_TEXT, VIDEO_OUT_LONGTEXT, true ); add_integer( "dshow-audio-output", -1, NULL, AUDIO_OUT_TEXT, AUDIO_OUT_LONGTEXT, true ); add_integer( "dshow-amtuner-mode", AMTUNER_MODE_TV, NULL, AMTUNER_MODE_TEXT, AMTUNER_MODE_LONGTEXT, false); change_integer_list( pi_amtuner_mode, ppsz_amtuner_mode_text, NULL ); add_integer( "dshow-audio-channels", 0, NULL, AUDIO_CHANNELS_TEXT, AUDIO_CHANNELS_LONGTEXT, true ); add_integer( "dshow-audio-samplerate", 0, NULL, AUDIO_SAMPLERATE_TEXT, AUDIO_SAMPLERATE_LONGTEXT, true ); add_integer( "dshow-audio-bitspersample", 0, NULL, AUDIO_BITSPERSAMPLE_TEXT, AUDIO_BITSPERSAMPLE_LONGTEXT, true ); add_shortcut( "dshow" ); set_capability( "access_demux", 0 ); set_callbacks( DemuxOpen, DemuxClose ); add_submodule(); set_description( N_("DirectShow input") ); set_capability( "access", 0 ); set_callbacks( AccessOpen, AccessClose );vlc_module_end();/***************************************************************************** * DirectShow elementary stream descriptor *****************************************************************************/typedef struct dshow_stream_t{ string devicename; IBaseFilter *p_device_filter; CaptureFilter *p_capture_filter; AM_MEDIA_TYPE mt; union { VIDEOINFOHEADER video; WAVEFORMATEX audio; } header; int i_fourcc; es_out_id_t *p_es; bool b_pts;} dshow_stream_t;/***************************************************************************** * DirectShow utility functions *****************************************************************************/static void CreateDirectShowGraph( access_sys_t *p_sys ){ p_sys->i_crossbar_route_depth = 0; /* Create directshow filter graph */ if( SUCCEEDED( CoCreateInstance( CLSID_FilterGraph, 0, CLSCTX_INPROC, (REFIID)IID_IFilterGraph, (void **)&p_sys->p_graph) ) ) { /* Create directshow capture graph builder if available */ if( SUCCEEDED( CoCreateInstance( CLSID_CaptureGraphBuilder2, 0, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder2, (void **)&p_sys->p_capture_graph_builder2 ) ) ) { p_sys->p_capture_graph_builder2-> SetFiltergraph((IGraphBuilder *)p_sys->p_graph); } p_sys->p_graph->QueryInterface( IID_IMediaControl, (void **)&p_sys->p_control ); }}static void DeleteDirectShowGraph( access_sys_t *p_sys ){ DeleteCrossbarRoutes( p_sys ); /* Remove filters from graph */ for( int i = 0; i < p_sys->i_streams; i++ ) { p_sys->p_graph->RemoveFilter( p_sys->pp_streams[i]->p_capture_filter ); p_sys->p_graph->RemoveFilter( p_sys->pp_streams[i]->p_device_filter ); p_sys->pp_streams[i]->p_capture_filter->Release(); p_sys->pp_streams[i]->p_device_filter->Release(); } /* Release directshow objects */ if( p_sys->p_control ) { p_sys->p_control->Release(); p_sys->p_control = NULL; } if( p_sys->p_capture_graph_builder2 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -