/***************************************************************************** * v4l2.c : Video4Linux2 input module for vlc ***************************************************************************** * Copyright (C) 2002-2009 the VideoLAN team * $Id$ * * Authors: Benjamin Pracht * Richard Hosking * Antoine Cellerier * Dennis Lou * * 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. *****************************************************************************/ /* * Sections based on the reference V4L2 capture example at * http://v4l2spec.bytesex.org/spec/capture-example.html */ /***************************************************************************** * Preamble *****************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_ALSA # define ALSA_PCM_NEW_HW_PARAMS_API # define ALSA_PCM_NEW_SW_PARAMS_API # include #endif #include #ifdef HAVE_LIBV4L2 # include #else # define v4l2_close close # define v4l2_dup dup # define v4l2_ioctl ioctl # define v4l2_read read # define v4l2_mmap mmap # define v4l2_munmap munmap #endif /***************************************************************************** * Module descriptior *****************************************************************************/ static int DemuxOpen ( vlc_object_t * ); static void DemuxClose( vlc_object_t * ); static int AccessOpen ( vlc_object_t * ); static void AccessClose( vlc_object_t * ); #define STANDARD_TEXT N_( "Standard" ) #define STANDARD_LONGTEXT N_( \ "Video standard (Default, SECAM, PAL, or NTSC)." ) #define CHROMA_TEXT N_("Video input chroma format") #define CHROMA_LONGTEXT N_( \ "Force the Video4Linux2 video device to use a specific chroma format " \ "(eg. I420 or I422 for raw images, MJPG for M-JPEG compressed input) " \ "(Complete list: GREY, I240, RV16, RV15, RV24, RV32, YUY2, YUYV, UYVY, " \ "I41N, I422, I420, I411, I410, MJPG)") #define INPUT_TEXT N_( "Input" ) #define INPUT_LONGTEXT N_( \ "Input of the card to use (see debug)." ) #define AUDIO_INPUT_TEXT N_( "Audio input" ) #define AUDIO_INPUT_LONGTEXT N_( \ "Audio input of the card to use (see debug)." ) #define IOMETHOD_TEXT N_( "IO Method" ) #define IOMETHOD_LONGTEXT N_( \ "IO Method (READ, MMAP, USERPTR)." ) #define WIDTH_TEXT N_( "Width" ) #define WIDTH_LONGTEXT N_( \ "Force width (-1 for autodetect, 0 for driver default)." ) #define HEIGHT_TEXT N_( "Height" ) #define HEIGHT_LONGTEXT N_( \ "Force height (-1 for autodetect, 0 for driver default)." ) #define FPS_TEXT N_( "Framerate" ) #define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \ "(0 for autodetect)." ) #define CTRL_RESET_TEXT N_( "Reset v4l2 controls" ) #define CTRL_RESET_LONGTEXT N_( \ "Reset controls to defaults provided by the v4l2 driver." ) #define BRIGHTNESS_TEXT N_( "Brightness" ) #define BRIGHTNESS_LONGTEXT N_( \ "Brightness of the video input (if supported by the v4l2 driver)." ) #define CONTRAST_TEXT N_( "Contrast" ) #define CONTRAST_LONGTEXT N_( \ "Contrast of the video input (if supported by the v4l2 driver)." ) #define SATURATION_TEXT N_( "Saturation" ) #define SATURATION_LONGTEXT N_( \ "Saturation of the video input (if supported by the v4l2 driver)." ) #define HUE_TEXT N_( "Hue" ) #define HUE_LONGTEXT N_( \ "Hue of the video input (if supported by the v4l2 driver)." ) #define BLACKLEVEL_TEXT N_( "Black level" ) #define BLACKLEVEL_LONGTEXT N_( \ "Black level of the video input (if supported by the v4l2 driver)." ) #define AUTOWHITEBALANCE_TEXT N_( "Auto white balance" ) #define AUTOWHITEBALANCE_LONGTEXT N_( \ "Automatically set the white balance of the video input " \ "(if supported by the v4l2 driver)." ) #define DOWHITEBALANCE_TEXT N_( "Do white balance" ) #define DOWHITEBALANCE_LONGTEXT N_( \ "Trigger a white balancing action, useless if auto white balance is " \ "activated (if supported by the v4l2 driver)." ) #define REDBALANCE_TEXT N_( "Red balance" ) #define REDBALANCE_LONGTEXT N_( \ "Red balance of the video input (if supported by the v4l2 driver)." ) #define BLUEBALANCE_TEXT N_( "Blue balance" ) #define BLUEBALANCE_LONGTEXT N_( \ "Blue balance of the video input (if supported by the v4l2 driver)." ) #define GAMMA_TEXT N_( "Gamma" ) #define GAMMA_LONGTEXT N_( \ "Gamma of the video input (if supported by the v4l2 driver)." ) #define EXPOSURE_TEXT N_( "Exposure" ) #define EXPOSURE_LONGTEXT N_( \ "Exposure of the video input (if supported by the v4L2 driver)." ) #define AUTOGAIN_TEXT N_( "Auto gain" ) #define AUTOGAIN_LONGTEXT N_( \ "Automatically set the video input's gain (if supported by the " \ "v4l2 driver)." ) #define GAIN_TEXT N_( "Gain" ) #define GAIN_LONGTEXT N_( \ "Video input's gain (if supported by the v4l2 driver)." ) #define HFLIP_TEXT N_( "Horizontal flip" ) #define HFLIP_LONGTEXT N_( \ "Flip the video horizontally (if supported by the v4l2 driver)." ) #define VFLIP_TEXT N_( "Vertical flip" ) #define VFLIP_LONGTEXT N_( \ "Flip the video vertically (if supported by the v4l2 driver)." ) #define HCENTER_TEXT N_( "Horizontal centering" ) #define HCENTER_LONGTEXT N_( \ "Set the camera's horizontal centering (if supported by the v4l2 driver)." ) #define VCENTER_TEXT N_( "Vertical centering" ) #define VCENTER_LONGTEXT N_( \ "Set the camera's vertical centering (if supported by the v4l2 driver)." ) #define AUDIO_VOLUME_TEXT N_( "Volume" ) #define AUDIO_VOLUME_LONGTEXT N_( \ "Volume of the audio input (if supported by the v4l2 driver)." ) #define AUDIO_BALANCE_TEXT N_( "Balance" ) #define AUDIO_BALANCE_LONGTEXT N_( \ "Balance of the audio input (if supported by the v4l2 driver)." ) #define AUDIO_MUTE_TEXT N_( "Mute" ) #define AUDIO_MUTE_LONGTEXT N_( \ "Mute audio input (if supported by the v4l2 driver)." ) #define AUDIO_BASS_TEXT N_( "Bass" ) #define AUDIO_BASS_LONGTEXT N_( \ "Bass level of the audio input (if supported by the v4l2 driver)." ) #define AUDIO_TREBLE_TEXT N_( "Treble" ) #define AUDIO_TREBLE_LONGTEXT N_( \ "Treble level of the audio input (if supported by the v4l2 driver)." ) #define AUDIO_LOUDNESS_TEXT N_( "Loudness" ) #define AUDIO_LOUDNESS_LONGTEXT N_( \ "Loudness of the audio input (if supported by the v4l2 driver)." ) #define CACHING_TEXT N_("Caching value in ms") #define CACHING_LONGTEXT N_( \ "Caching value for V4L2 captures. This " \ "value should be set in milliseconds." ) #define S_CTRLS_TEXT N_("v4l2 driver controls") #define S_CTRLS_LONGTEXT N_( \ "Set the v4l2 driver controls to the values specified using a comma " \ "separated list optionally encapsulated by curly braces " \ "(e.g.: {video_bitrate=6000000,audio_crc=0,stream_type=3} ). " \ "To list available controls, increase verbosity (-vvv) " \ "or use the v4l2-ctl application." ) #define TUNER_TEXT N_("Tuner id") #define TUNER_LONGTEXT N_( \ "Tuner id (see debug output)." ) #define FREQUENCY_TEXT N_("Frequency") #define FREQUENCY_LONGTEXT N_( \ "Tuner frequency in Hz or kHz (see debug output)" ) #define TUNER_AUDIO_MODE_TEXT N_("Audio mode") #define TUNER_AUDIO_MODE_LONGTEXT N_( \ "Tuner audio mono/stereo and track selection." ) #define AUDIO_DEPRECATED_ERROR N_( \ "Alsa or OSS audio capture in the v4l2 access is deprecated. " \ "please use 'v4l2:/""/ :input-slave=alsa:/""/' or " \ "'v4l2:/""/ :input-slave=oss:/""/' instead." ) typedef enum { IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR, } io_method; static const int i_standards_list[] = { V4L2_STD_UNKNOWN, V4L2_STD_SECAM, V4L2_STD_PAL, V4L2_STD_NTSC }; static const char *const psz_standards_list_text[] = { N_("Default"), N_("SECAM"), N_("PAL"), N_("NTSC") }; static const int i_iomethod_list[] = { IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR }; static const char *const psz_iomethod_list_text[] = { N_("READ"), N_("MMAP"), N_("USERPTR") }; static const int i_tuner_audio_modes_list[] = { V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO, V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2, V4L2_TUNER_MODE_SAP, V4L2_TUNER_MODE_LANG1_LANG2 }; static const char *const psz_tuner_audio_modes_list_text[] = { N_( "Mono" ), N_( "Stereo" ), N_( "Primary language (Analog TV tuners only)" ), N_( "Secondary language (Analog TV tuners only)" ), N_( "Second audio program (Analog TV tuners only)" ), N_( "Primary language left, Secondary language right" ) }; #define V4L2_DEFAULT "/dev/video0" #define CFG_PREFIX "v4l2-" vlc_module_begin () set_shortname( N_("Video4Linux2") ) set_description( N_("Video4Linux2 input") ) set_category( CAT_INPUT ) set_subcategory( SUBCAT_INPUT_ACCESS ) set_section( N_( "Video input" ), NULL ) add_integer( CFG_PREFIX "standard", 0, NULL, STANDARD_TEXT, STANDARD_LONGTEXT, false ); change_integer_list( i_standards_list, psz_standards_list_text, NULL ); add_string( CFG_PREFIX "chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, true ); add_integer( CFG_PREFIX "input", 0, NULL, INPUT_TEXT, INPUT_LONGTEXT, true ); add_integer( CFG_PREFIX "audio-input", 0, NULL, AUDIO_INPUT_TEXT, AUDIO_INPUT_LONGTEXT, true ); add_integer( CFG_PREFIX "io", IO_METHOD_MMAP, NULL, IOMETHOD_TEXT, IOMETHOD_LONGTEXT, true ); change_integer_list( i_iomethod_list, psz_iomethod_list_text, NULL ); add_integer( CFG_PREFIX "width", -1, NULL, WIDTH_TEXT, WIDTH_LONGTEXT, true ); add_integer( CFG_PREFIX "height", -1, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT, true ); add_float( CFG_PREFIX "fps", 0, NULL, FPS_TEXT, FPS_LONGTEXT, true ) add_integer( CFG_PREFIX "caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, true ); set_section( N_( "Tuner" ), NULL ) add_integer( CFG_PREFIX "tuner", 0, NULL, TUNER_TEXT, TUNER_LONGTEXT, true ); add_integer( CFG_PREFIX "tuner-frequency", -1, NULL, FREQUENCY_TEXT, FREQUENCY_LONGTEXT, true ); add_integer( CFG_PREFIX "tuner-audio-mode", -1, NULL, TUNER_AUDIO_MODE_TEXT, TUNER_AUDIO_MODE_LONGTEXT, true ); change_integer_list( i_tuner_audio_modes_list, psz_tuner_audio_modes_list_text, 0 ); set_section( N_( "Controls" ), N_( "v4l2 driver controls, if supported by your v4l2 driver." ) ); add_bool( CFG_PREFIX "controls-reset", false, NULL, CTRL_RESET_TEXT, CTRL_RESET_LONGTEXT, true ); add_integer( CFG_PREFIX "brightness", -1, NULL, BRIGHTNESS_TEXT, BRIGHTNESS_LONGTEXT, true ); add_integer( CFG_PREFIX "contrast", -1, NULL, CONTRAST_TEXT, CONTRAST_LONGTEXT, true ); add_integer( CFG_PREFIX "saturation", -1, NULL, SATURATION_TEXT, SATURATION_LONGTEXT, true ); add_integer( CFG_PREFIX "hue", -1, NULL, HUE_TEXT, HUE_LONGTEXT, true ); add_integer( CFG_PREFIX "black-level", -1, NULL, BLACKLEVEL_TEXT, BLACKLEVEL_LONGTEXT, true ); add_integer( CFG_PREFIX "auto-white-balance", -1, NULL, AUTOWHITEBALANCE_TEXT, AUTOWHITEBALANCE_LONGTEXT, true ); add_integer( CFG_PREFIX "do-white-balance", -1, NULL, DOWHITEBALANCE_TEXT, DOWHITEBALANCE_LONGTEXT, true ); add_integer( CFG_PREFIX "red-balance", -1, NULL, REDBALANCE_TEXT, REDBALANCE_LONGTEXT, true ); add_integer( CFG_PREFIX "blue-balance", -1, NULL, BLUEBALANCE_TEXT, BLUEBALANCE_LONGTEXT, true ); add_integer( CFG_PREFIX "gamma", -1, NULL, GAMMA_TEXT, GAMMA_LONGTEXT, true ); add_integer( CFG_PREFIX "exposure", -1, NULL, EXPOSURE_TEXT, EXPOSURE_LONGTEXT, true ); add_integer( CFG_PREFIX "autogain", -1, NULL, AUTOGAIN_TEXT, AUTOGAIN_LONGTEXT, true ); add_integer( CFG_PREFIX "gain", -1, NULL, GAIN_TEXT, GAIN_LONGTEXT, true ); add_integer( CFG_PREFIX "hflip", -1, NULL, HFLIP_TEXT, HFLIP_LONGTEXT, true ); add_integer( CFG_PREFIX "vflip", -1, NULL, VFLIP_TEXT, VFLIP_LONGTEXT, true ); add_integer( CFG_PREFIX "hcenter", -1, NULL, HCENTER_TEXT, HCENTER_LONGTEXT, true ); add_integer( CFG_PREFIX "vcenter", -1, NULL, VCENTER_TEXT, VCENTER_LONGTEXT, true ); add_integer( CFG_PREFIX "audio-volume", -1, NULL, AUDIO_VOLUME_TEXT, AUDIO_VOLUME_LONGTEXT, true ); add_integer( CFG_PREFIX "audio-balance", -1, NULL, AUDIO_BALANCE_TEXT, AUDIO_BALANCE_LONGTEXT, true ); add_bool( CFG_PREFIX "audio-mute", false, NULL, AUDIO_MUTE_TEXT, AUDIO_MUTE_LONGTEXT, true ); add_integer( CFG_PREFIX "audio-bass", -1, NULL, AUDIO_BASS_TEXT, AUDIO_BASS_LONGTEXT, true ); add_integer( CFG_PREFIX "audio-treble", -1, NULL, AUDIO_TREBLE_TEXT, AUDIO_TREBLE_LONGTEXT, true ); add_integer( CFG_PREFIX "audio-loudness", -1, NULL, AUDIO_LOUDNESS_TEXT, AUDIO_LOUDNESS_LONGTEXT, true ); add_string( CFG_PREFIX "set-ctrls", NULL, NULL, S_CTRLS_TEXT, S_CTRLS_LONGTEXT, true ); add_obsolete_string( CFG_PREFIX "dev" ); add_obsolete_string( CFG_PREFIX "adev" ); add_obsolete_integer( CFG_PREFIX "audio-method" ); add_obsolete_bool( CFG_PREFIX "stereo" ); add_obsolete_integer( CFG_PREFIX "samplerate" ); add_shortcut( "v4l2" ) set_capability( "access_demux", 10 ) set_callbacks( DemuxOpen, DemuxClose ) add_submodule () add_shortcut( "v4l2c" ) set_description( N_("Video4Linux2 Compressed A/V") ) set_capability( "access", 0 ) /* use these when open as access_demux fails; VLC will use another demux */ set_callbacks( AccessOpen, AccessClose ) vlc_module_end () /***************************************************************************** * Access: local prototypes *****************************************************************************/ static void CommonClose( vlc_object_t *, demux_sys_t * ); static void ParseMRL( demux_sys_t *, char *, vlc_object_t * ); static void GetV4L2Params( demux_sys_t *, vlc_object_t * ); static void SetAvailControlsByString( vlc_object_t *, demux_sys_t *, int ); static int DemuxControl( demux_t *, int, va_list ); static int AccessControl( access_t *, int, va_list ); static int Demux( demux_t * ); static ssize_t AccessRead( access_t *, uint8_t *, size_t ); static block_t* GrabVideo( demux_t *p_demux ); static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame, size_t ); static bool IsPixelFormatSupported( demux_t *p_demux, unsigned int i_pixelformat ); static int OpenVideoDev( vlc_object_t *, demux_sys_t *, bool ); static bool ProbeVideoDev( vlc_object_t *, demux_sys_t *, const char *psz_device ); static int ControlList( vlc_object_t *, int , bool, bool ); static int Control( vlc_object_t *, int i_fd, const char *psz_name, int i_cid, int i_value ); static int DemuxControlCallback( vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ); static int DemuxControlResetCallback( vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ); static int AccessControlCallback( vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ); static int AccessControlResetCallback( vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ); static const struct { unsigned int i_v4l2; int i_fourcc; int i_rmask; int i_gmask; int i_bmask; } v4l2chroma_to_fourcc[] = { /* Raw data types */ { V4L2_PIX_FMT_GREY, VLC_FOURCC('G','R','E','Y'), 0, 0, 0 }, { V4L2_PIX_FMT_HI240, VLC_FOURCC('I','2','4','0'), 0, 0, 0 }, { V4L2_PIX_FMT_RGB555, VLC_FOURCC('R','V','1','5'), 0x001f,0x03e0,0x7c00 }, { V4L2_PIX_FMT_RGB565, VLC_FOURCC('R','V','1','6'), 0x001f,0x07e0,0xf800 }, /* Won't work since we don't know how to handle such gmask values * correctly { V4L2_PIX_FMT_RGB555X, VLC_FOURCC('R','V','1','5'), 0x007c,0xe003,0x1f00 }, { V4L2_PIX_FMT_RGB565X, VLC_FOURCC('R','V','1','6'), 0x00f8,0xe007,0x1f00 }, */ { V4L2_PIX_FMT_BGR24, VLC_FOURCC('R','V','2','4'), 0xff0000,0xff00,0xff }, { V4L2_PIX_FMT_RGB24, VLC_FOURCC('R','V','2','4'), 0xff,0xff00,0xff0000 }, { V4L2_PIX_FMT_BGR32, VLC_FOURCC('R','V','3','2'), 0xff0000,0xff00,0xff }, { V4L2_PIX_FMT_RGB32, VLC_FOURCC('R','V','3','2'), 0xff,0xff00,0xff0000 }, { V4L2_PIX_FMT_YUYV, VLC_FOURCC('Y','U','Y','2'), 0, 0, 0 }, { V4L2_PIX_FMT_YUYV, VLC_FOURCC('Y','U','Y','V'), 0, 0, 0 }, { V4L2_PIX_FMT_UYVY, VLC_FOURCC('U','Y','V','Y'), 0, 0, 0 }, { V4L2_PIX_FMT_Y41P, VLC_FOURCC('I','4','1','N'), 0, 0, 0 }, { V4L2_PIX_FMT_YUV422P, VLC_FOURCC('I','4','2','2'), 0, 0, 0 }, { V4L2_PIX_FMT_YVU420, VLC_FOURCC('Y','V','1','2'), 0, 0, 0 }, { V4L2_PIX_FMT_YUV411P, VLC_FOURCC('I','4','1','1'), 0, 0, 0 }, { V4L2_PIX_FMT_YUV410, VLC_FOURCC('I','4','1','0'), 0, 0, 0 }, /* Raw data types, not in V4L2 spec but still in videodev2.h and supported * by VLC */ { V4L2_PIX_FMT_YUV420, VLC_FOURCC('I','4','2','0'), 0, 0, 0 }, /* FIXME { V4L2_PIX_FMT_RGB444, VLC_FOURCC('R','V','3','2') }, */ /* Compressed data types */ { V4L2_PIX_FMT_MJPEG, VLC_FOURCC('M','J','P','G'), 0, 0, 0 }, #if 0 { V4L2_PIX_FMT_JPEG, VLC_FOURCC('J','P','E','G') }, { V4L2_PIX_FMT_DV, VLC_FOURCC('?','?','?','?') }, { V4L2_PIX_FMT_MPEG, VLC_FOURCC('?','?','?','?') }, #endif { 0, 0, 0, 0, 0 } }; /** * List of V4L2 chromas were confident enough to use as fallbacks if the * user hasn't provided a --v4l2-chroma value. * * Try YUV chromas first, then RGB little endian and MJPEG as last resort. */ static const __u32 p_chroma_fallbacks[] = { V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YVU420, V4L2_PIX_FMT_YUV422P, V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_BGR24, V4L2_PIX_FMT_BGR32, V4L2_PIX_FMT_MJPEG }; static const struct { const char *psz_name; unsigned int i_cid; } controls[] = { { "brightness", V4L2_CID_BRIGHTNESS }, { "contrast", V4L2_CID_CONTRAST }, { "saturation", V4L2_CID_SATURATION }, { "hue", V4L2_CID_HUE }, { "audio-volume", V4L2_CID_AUDIO_VOLUME }, { "audio-balance", V4L2_CID_AUDIO_BALANCE }, { "audio-bass", V4L2_CID_AUDIO_BASS }, { "audio-treble", V4L2_CID_AUDIO_TREBLE }, { "audio-mute", V4L2_CID_AUDIO_MUTE }, { "audio-loudness", V4L2_CID_AUDIO_LOUDNESS }, { "black-level", V4L2_CID_BLACK_LEVEL }, { "auto-white-balance", V4L2_CID_AUTO_WHITE_BALANCE }, { "do-white-balance", V4L2_CID_DO_WHITE_BALANCE }, { "red-balance", V4L2_CID_RED_BALANCE }, { "blue-balance", V4L2_CID_BLUE_BALANCE }, { "gamma", V4L2_CID_GAMMA }, { "exposure", V4L2_CID_EXPOSURE }, { "autogain", V4L2_CID_AUTOGAIN }, { "gain", V4L2_CID_GAIN }, { "hflip", V4L2_CID_HFLIP }, { "vflip", V4L2_CID_VFLIP }, { "hcenter", V4L2_CID_HCENTER }, { "vcenter", V4L2_CID_VCENTER }, { NULL, 0 } }; struct buffer_t { void * start; size_t length; }; struct demux_sys_t { char *psz_device; /* Main device from MRL */ int i_fd; char *psz_requested_chroma; /* Video */ io_method io; int i_cache; struct v4l2_capability dev_cap; int i_input; struct v4l2_input *p_inputs; int i_selected_input; int i_standard; struct v4l2_standard *p_standards; v4l2_std_id i_selected_standard_id; int i_audio; /* V4L2 devices cannot have more than 32 audio inputs */ struct v4l2_audio p_audios[32]; int i_selected_audio_input; int i_tuner; struct v4l2_tuner *p_tuners; int i_codec; struct v4l2_fmtdesc *p_codecs; struct buffer_t *p_buffers; unsigned int i_nbuffers; int i_width; int i_height; float f_fps; /* <= 0.0 mean to grab at full rate */ mtime_t i_video_pts; /* only used when f_fps > 0 */ int i_fourcc; es_out_id_t *p_es; /* Tuner */ int i_cur_tuner; int i_frequency; int i_audio_mode; /* Controls */ char *psz_set_ctrls; }; static int FindMainDevice( vlc_object_t *p_this, demux_sys_t *p_sys, bool b_demux ) { /* TODO: if using default device, loop through all /dev/video* until * one works */ msg_Dbg( p_this, "opening device '%s'", p_sys->psz_device ); if( ProbeVideoDev( p_this, p_sys, p_sys->psz_device ) ) { msg_Dbg( p_this, "'%s' is a video device", p_sys->psz_device ); p_sys->i_fd = OpenVideoDev( p_this, p_sys, b_demux ); } if( p_sys->i_fd < 0 ) return VLC_EGENERIC; return VLC_SUCCESS; } /***************************************************************************** * DemuxOpen: opens v4l2 device, access_demux callback ***************************************************************************** * * url: