X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Faccess%2Fv4l2.c;h=4188421b9d79db14609ea05d2126b04d0b94da83;hb=c29fd5f90efcb3435cd3821842448a2ad2dd0637;hp=f5a3293132ea2095a3025f558cf1ced5564b7ca8;hpb=0f7683443fd8c690a59804e9adc3185a6dcc922b;p=vlc diff --git a/modules/access/v4l2.c b/modules/access/v4l2.c index f5a3293132..4188421b9d 100644 --- a/modules/access/v4l2.c +++ b/modules/access/v4l2.c @@ -1,7 +1,7 @@ /***************************************************************************** * v4l2.c : Video4Linux2 input module for vlc ***************************************************************************** - * Copyright (C) 2002-2007 the VideoLAN team + * Copyright (C) 2002-2009 the VideoLAN team * $Id$ * * Authors: Benjamin Pracht @@ -27,45 +27,35 @@ /* * Sections based on the reference V4L2 capture example at * http://v4l2spec.bytesex.org/spec/capture-example.html - * - * ALSA support based on parts of - * http://www.equalarea.com/paul/alsa-audio.html - * and hints taken from alsa-utils (aplay/arecord) - * http://www.alsa-project.org - */ - -/* - * TODO: Tuner partial implementation. - * TODO: Add more MPEG stream params */ /***************************************************************************** * Preamble *****************************************************************************/ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#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 +#ifdef HAVE_LIBV4L2 +# include #endif -#include - /***************************************************************************** * Module descriptior *****************************************************************************/ @@ -75,75 +65,143 @@ static void DemuxClose( vlc_object_t * ); static int AccessOpen ( vlc_object_t * ); static void AccessClose( vlc_object_t * ); -#define DEV_TEXT N_("Device name") -#define DEV_LONGTEXT N_( \ - "Name of the device to use. " \ - "If you don't specify anything, /dev/video0 will be used.") #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, MJPEG for M-JPEG compressed input) " \ + "(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 (Usually, 0 = tuner, " \ - "1 = composite, 2 = svideo)." ) + "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)." ) + "Force width (-1 for autodetect, 0 for driver default)." ) #define HEIGHT_TEXT N_( "Height" ) #define HEIGHT_LONGTEXT N_( \ - "Force height (-1 for autodetect)." ) + "Force height (-1 for autodetect, 0 for driver default)." ) #define FPS_TEXT N_( "Framerate" ) #define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \ - "(-1 for autodetect)." ) + "(0 for autodetect)." ) + +#ifdef HAVE_LIBV4L2 +#define LIBV4L2_TEXT N_( "Use libv4l2" ) +#define LIBV4L2_LONGTEXT N_( \ + "Force usage of the libv4l2 wrapper." ) +#endif #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 v4l2 driver)." ) + "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 v4l2 driver)." ) + "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 v4l2 driver)." ) + "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 v4l2 driver)." ) + "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 v4l2 driver)." ) - -#define ADEV_TEXT N_("Audio device name") -#define ADEV_LONGTEXT N_( \ - "Name of the audio device to use. " \ - "If you don't specify anything, \"/dev/dsp\" will be used for OSS, " \ - "\"default\" for Alsa (if Alsa support is enabled).") -#define AUDIO_METHOD_TEXT N_( "Audio method" ) -#define AUDIO_METHOD_LONGTEXT N_( \ - "Audio method to use: 1 for OSS, 2 for ALSA, 3 for ALSA or OSS " \ - "(ALSA is prefered)." ) -#define STEREO_TEXT N_( "Stereo" ) -#define STEREO_LONGTEXT N_( \ - "Capture the audio stream in stereo." ) -#define SAMPLERATE_TEXT N_( "Samplerate" ) -#define SAMPLERATE_LONGTEXT N_( \ - "Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100, 48000)" ) + "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, @@ -151,90 +209,143 @@ typedef enum { IO_METHOD_USERPTR, } io_method; -static int i_standards_list[] = +static const int i_standards_list[] = { V4L2_STD_UNKNOWN, V4L2_STD_SECAM, V4L2_STD_PAL, V4L2_STD_NTSC }; -static const char *psz_standards_list_text[] = +static const char *const psz_standards_list_text[] = { N_("Default"), N_("SECAM"), N_("PAL"), N_("NTSC") }; -static int i_iomethod_list[] = +static const int i_iomethod_list[] = { IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR }; -static const char *psz_iomethod_list_text[] = +static const char *const psz_iomethod_list_text[] = { N_("READ"), N_("MMAP"), N_("USERPTR") }; -#define FIND_VIDEO 1 -#define FIND_AUDIO 2 - -#define AUDIO_METHOD_OSS 1 -#define OSS_DEFAULT "/dev/dsp" -#define AUDIO_METHOD_ALSA 2 -#define ALSA_DEFAULT "default" +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( _("Video4Linux2") ); - set_description( _("Video4Linux2 input") ); - set_category( CAT_INPUT ); - set_subcategory( SUBCAT_INPUT_ACCESS ); +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_string( CFG_PREFIX "dev", "/dev/video0", 0, DEV_TEXT, DEV_LONGTEXT, - VLC_FALSE ); + set_section( N_( "Video input" ), NULL ) add_integer( CFG_PREFIX "standard", 0, NULL, STANDARD_TEXT, - STANDARD_LONGTEXT, VLC_FALSE ); - change_integer_list( i_standards_list, psz_standards_list_text, 0 ); + 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, - VLC_TRUE ); + true ) add_integer( CFG_PREFIX "input", 0, NULL, INPUT_TEXT, INPUT_LONGTEXT, - VLC_TRUE ); + 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, VLC_TRUE ); - change_integer_list( i_iomethod_list, psz_iomethod_list_text, 0 ); - add_integer( CFG_PREFIX "width", 0, NULL, WIDTH_TEXT, - WIDTH_LONGTEXT, VLC_TRUE ); - add_integer( CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT, - HEIGHT_LONGTEXT, VLC_TRUE ); - add_float( CFG_PREFIX "fps", 0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_TRUE ); - - set_section( N_( "Audio input" ), NULL ); - add_string( CFG_PREFIX "adev", NULL, 0, ADEV_TEXT, ADEV_LONGTEXT, - VLC_FALSE ); -#ifdef HAVE_ALSA - add_integer( CFG_PREFIX "audio-method", AUDIO_METHOD_OSS|AUDIO_METHOD_ALSA, - NULL, AUDIO_METHOD_TEXT, AUDIO_METHOD_LONGTEXT, VLC_TRUE ); -#endif - add_bool( CFG_PREFIX "stereo", VLC_TRUE, NULL, STEREO_TEXT, STEREO_LONGTEXT, - VLC_TRUE ); - add_integer( CFG_PREFIX "samplerate", 48000, NULL, SAMPLERATE_TEXT, - SAMPLERATE_LONGTEXT, VLC_TRUE ); + 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, VLC_TRUE ); + CACHING_TEXT, CACHING_LONGTEXT, true ) +#ifdef HAVE_LIBV4L2 + add_bool( CFG_PREFIX "use-libv4l2", false, NULL, LIBV4L2_TEXT, LIBV4L2_LONGTEXT, true ); +#endif - set_section( N_( "Controls" ), N_( "v4l2 driver controls" ) ); - add_bool( CFG_PREFIX "controls-reset", VLC_FALSE, NULL, CTRL_RESET_TEXT, - CTRL_RESET_LONGTEXT, VLC_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, VLC_TRUE ); + BRIGHTNESS_LONGTEXT, true ) add_integer( CFG_PREFIX "contrast", -1, NULL, CONTRAST_TEXT, - CONTRAST_LONGTEXT, VLC_TRUE ); + CONTRAST_LONGTEXT, true ) add_integer( CFG_PREFIX "saturation", -1, NULL, SATURATION_TEXT, - SATURATION_LONGTEXT, VLC_TRUE ); + SATURATION_LONGTEXT, true ) add_integer( CFG_PREFIX "hue", -1, NULL, HUE_TEXT, - HUE_LONGTEXT, VLC_TRUE ); + 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, VLC_TRUE ); - - - add_shortcut( "v4l2" ); - set_capability( "access_demux", 10 ); - set_callbacks( DemuxOpen, DemuxClose ); - - add_submodule(); - set_description( _("Video4Linux2 Compressed A/V") ); - set_capability( "access2", 0 ); + 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 ); + set_callbacks( AccessOpen, AccessClose ) -vlc_module_end(); +vlc_module_end () /***************************************************************************** * Access: local prototypes @@ -243,6 +354,7 @@ vlc_module_end(); 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 ); @@ -252,21 +364,16 @@ 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 block_t* GrabAudio( demux_t *p_demux ); -static vlc_bool_t IsPixelFormatSupported( demux_t *p_demux, +static bool IsPixelFormatSupported( demux_t *p_demux, unsigned int i_pixelformat ); -static char* ResolveALSADeviceName( const char *psz_device ); -static int OpenVideoDev( vlc_object_t *, demux_sys_t *, vlc_bool_t ); -static int OpenAudioDev( vlc_object_t *, demux_sys_t *, vlc_bool_t ); -static vlc_bool_t ProbeVideoDev( vlc_object_t *, demux_sys_t *, - char *psz_device ); -static vlc_bool_t ProbeAudioDev( vlc_object_t *, demux_sys_t *, - char *psz_device ); +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 , vlc_bool_t, vlc_bool_t ); -static int Control( vlc_object_t *, int i_fd, +static int ControlList( vlc_object_t *, demux_sys_t *, int , bool, bool ); +static int Control( vlc_object_t *, demux_sys_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, @@ -282,38 +389,65 @@ static int AccessControlResetCallback( vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ); -static struct +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') }, - { V4L2_PIX_FMT_HI240, VLC_FOURCC('I','2','4','0') }, - { V4L2_PIX_FMT_RGB565, VLC_FOURCC('R','V','1','6') }, - { V4L2_PIX_FMT_RGB555, VLC_FOURCC('R','V','1','5') }, - { V4L2_PIX_FMT_BGR24, VLC_FOURCC('R','V','2','4') }, - { V4L2_PIX_FMT_BGR32, VLC_FOURCC('R','V','3','2') }, - { V4L2_PIX_FMT_YUYV, VLC_FOURCC('Y','U','Y','2') }, - { V4L2_PIX_FMT_YUYV, VLC_FOURCC('Y','U','Y','V') }, - { V4L2_PIX_FMT_UYVY, VLC_FOURCC('U','Y','V','Y') }, - { V4L2_PIX_FMT_Y41P, VLC_FOURCC('I','4','1','N') }, - { V4L2_PIX_FMT_YUV422P, VLC_FOURCC('I','4','2','2') }, - { V4L2_PIX_FMT_YVU420, VLC_FOURCC('I','4','2','0') }, - { V4L2_PIX_FMT_YUV411P, VLC_FOURCC('I','4','1','1') }, - { V4L2_PIX_FMT_YUV410, VLC_FOURCC('I','4','1','0') }, + { 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') }, + { 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, 0, 0 } }; -static struct +/** + * 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; @@ -349,25 +483,19 @@ struct buffer_t { void * start; size_t length; - void * orig_userp; }; struct demux_sys_t { - char *psz_device; /* Main device from MRL, can be video or audio */ - - char *psz_vdev; - int i_fd_video; - - char *psz_adev; - int i_fd_audio; + char *psz_device; /* Main device from MRL */ + int i_fd; char *psz_requested_chroma; /* Video */ io_method io; - int i_pts; + int i_cache; struct v4l2_capability dev_cap; @@ -382,6 +510,7 @@ struct demux_sys_t 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; @@ -398,116 +527,80 @@ struct demux_sys_t mtime_t i_video_pts; /* only used when f_fps > 0 */ int i_fourcc; - es_out_id_t *p_es_video; + es_out_id_t *p_es; + + /* Tuner */ + int i_cur_tuner; + int i_frequency; + int i_audio_mode; - /* Audio */ - unsigned int i_sample_rate; - vlc_bool_t b_stereo; - int i_audio_max_frame_size; - block_t *p_block_audio; - es_out_id_t *p_es_audio; + /* Controls */ + char *psz_set_ctrls; - int i_audio_method; -#ifdef HAVE_ALSA - /* ALSA Audio */ - snd_pcm_t *p_alsa_pcm; - int i_alsa_frame_size; - int i_alsa_chunk_size; +#ifdef HAVE_LIBV4L2 + /* */ + int (*pf_close)( int ); + int (*pf_dup)( int ); + int (*pf_ioctl)( int, unsigned long int, ... ); + ssize_t (*pf_read)( int, void *, size_t ); + void *(*pf_mmap)( void *, size_t, int, int, int, off_t ); + int (*pf_munmap)( void *, size_t ); + bool b_libv4l2; #endif }; -static int FindMainDevice( vlc_object_t *p_this, demux_sys_t *p_sys, - int i_flags, vlc_bool_t b_demux, - vlc_bool_t b_forced ) +#ifdef HAVE_LIBV4L2 +static void use_kernel_v4l2( demux_sys_t *p_sys ) { - /* Find main device (video or audio) */ - if( p_sys->psz_device && *p_sys->psz_device ) - { - msg_Dbg( p_this, "main device='%s'", p_sys->psz_device ); - - /* Try to open as video device */ - if( i_flags & FIND_VIDEO ) - { - msg_Dbg( p_this, "trying device '%s' as video", 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 ); - /* Device was a video device */ - if( p_sys->psz_vdev ) free( p_sys->psz_vdev ); - p_sys->psz_vdev = p_sys->psz_device; - p_sys->psz_device = NULL; - p_sys->i_fd_video = OpenVideoDev( p_this, p_sys, b_demux ); - if( p_sys->i_fd_video < 0 ) - return VLC_EGENERIC; - return VLC_SUCCESS; - } - } - - if( i_flags & FIND_AUDIO ) - { - /* Try to open as audio device */ - msg_Dbg( p_this, "trying device '%s' as audio", p_sys->psz_device ); - if( ProbeAudioDev( p_this, p_sys, p_sys->psz_device ) ) - { - msg_Dbg( p_this, "'%s' is an audio device", p_sys->psz_device ); - /* Device was an audio device */ - free( p_sys->psz_adev ); - p_sys->psz_adev = p_sys->psz_device; - p_sys->psz_device = NULL; - p_sys->i_fd_audio = OpenAudioDev( p_this, p_sys, b_demux ); - if( p_sys->i_fd_audio < 0 ) - return VLC_EGENERIC; - return VLC_SUCCESS; - } - } - } - - /* If no device opened, only continue if the access was forced */ - if( b_forced == VLC_FALSE - && !( ( i_flags & FIND_VIDEO && p_sys->i_fd_video >= 0 ) - || ( i_flags & FIND_AUDIO && p_sys->i_fd_audio >= 0 ) ) ) - { - return VLC_EGENERIC; - } + p_sys->pf_close = close; + p_sys->pf_dup = dup; + p_sys->pf_ioctl = ioctl; + p_sys->pf_read = read; + p_sys->pf_mmap = mmap; + p_sys->pf_munmap = munmap; + p_sys->b_libv4l2 = false; +} - /* Find video device */ - if( i_flags & FIND_VIDEO && p_sys->i_fd_video < 0 ) - { - if( !p_sys->psz_vdev || !*p_sys->psz_vdev ) - { - if( p_sys->psz_vdev ) free( p_sys->psz_vdev ); - p_sys->psz_vdev = var_CreateGetString( p_this, "v4l2-dev" ); - } +static void use_libv4l2( demux_sys_t *p_sys ) +{ + p_sys->pf_close = v4l2_close; + p_sys->pf_dup = v4l2_dup; + p_sys->pf_ioctl = v4l2_ioctl; + p_sys->pf_read = v4l2_read; + p_sys->pf_mmap = v4l2_mmap; + p_sys->pf_munmap = v4l2_munmap; + p_sys->b_libv4l2 = true; +} - msg_Dbg( p_this, "opening '%s' as video", p_sys->psz_vdev ); - if( p_sys->psz_vdev && *p_sys->psz_vdev - && ProbeVideoDev( p_this, p_sys, p_sys->psz_vdev ) ) - { - p_sys->i_fd_video = OpenVideoDev( p_this, p_sys, b_demux ); - } - } +# define v4l2_close (p_sys->pf_close) +# define v4l2_dup (p_sys->pf_dup) +# define v4l2_ioctl (p_sys->pf_ioctl) +# define v4l2_read (p_sys->pf_read) +# define v4l2_mmap (p_sys->pf_mmap) +# define v4l2_munmap (p_sys->pf_munmap) +#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 - /* Find audio device */ - if( i_flags & FIND_AUDIO && p_sys->i_fd_audio < 0 ) +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 ) ) { - if( !p_sys->psz_adev ) - { - p_sys->psz_adev = var_CreateGetNonEmptyString( p_this, "v4l2-adev" ); - } - - msg_Dbg( p_this, "opening '%s' as audio", p_sys->psz_adev ); - if( ProbeAudioDev( p_this, p_sys, p_sys->psz_adev ) ) - { - p_sys->i_fd_audio = OpenAudioDev( p_this, p_sys, b_demux ); - } + 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( !( ( i_flags & FIND_VIDEO && p_sys->i_fd_video >= 0 ) - || ( i_flags & FIND_AUDIO && p_sys->i_fd_audio >= 0 ) ) ) - { - return VLC_EGENERIC; - } + if( p_sys->i_fd < 0 ) return VLC_EGENERIC; return VLC_SUCCESS; } @@ -524,7 +617,8 @@ static int DemuxOpen( vlc_object_t *p_this ) demux_sys_t *p_sys; /* Only when selected */ - if( *p_demux->psz_access == '\0' ) return VLC_EGENERIC; + if( strcmp( p_demux->psz_access, "v4l2" ) ) + return VLC_EGENERIC; /* Set up p_demux */ p_demux->pf_control = DemuxControl; @@ -540,19 +634,23 @@ static int DemuxOpen( vlc_object_t *p_this ) ParseMRL( p_sys, p_demux->psz_path, (vlc_object_t *) p_demux ); -#ifdef HAVE_ALSA - /* Alsa support available? */ - msg_Dbg( p_demux, "ALSA input support available" ); -#endif - - if( FindMainDevice( p_this, p_sys, FIND_VIDEO|FIND_AUDIO, - VLC_TRUE, !strcmp( p_demux->psz_access, "v4l2" ) ) != VLC_SUCCESS ) +#ifdef HAVE_LIBV4L2 + if( !config_GetInt( p_this, CFG_PREFIX "use-libv4l2" ) ) { - DemuxClose( p_this ); - return VLC_EGENERIC; + msg_Dbg( p_this, "Trying direct kernel v4l2" ); + use_kernel_v4l2( p_sys ); + if( FindMainDevice( p_this, p_sys, true ) == VLC_SUCCESS) + return VLC_SUCCESS; } - return VLC_SUCCESS; + msg_Dbg( p_this, "Trying libv4l2 wrapper" ); + use_libv4l2( p_sys ); +#endif + if( FindMainDevice( p_this, p_sys, true ) == VLC_SUCCESS) + return VLC_SUCCESS; + + DemuxClose( p_this ); + return VLC_EGENERIC; } /***************************************************************************** @@ -566,34 +664,31 @@ static void GetV4L2Params( demux_sys_t *p_sys, vlc_object_t *p_obj ) i_standards_list[var_CreateGetInteger( p_obj, "v4l2-standard" )]; p_sys->i_selected_input = var_CreateGetInteger( p_obj, "v4l2-input" ); + p_sys->i_selected_audio_input = + var_CreateGetInteger( p_obj, "v4l2-audio-input" ); p_sys->io = var_CreateGetInteger( p_obj, "v4l2-io" ); p_sys->i_width = var_CreateGetInteger( p_obj, "v4l2-width" ); p_sys->i_height = var_CreateGetInteger( p_obj, "v4l2-height" ); - var_CreateGetBool( p_obj, "v4l2-controls-reset" ); + var_Create( p_obj, "v4l2-controls-reset", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); p_sys->f_fps = var_CreateGetFloat( p_obj, "v4l2-fps" ); - p_sys->i_sample_rate = var_CreateGetInteger( p_obj, "v4l2-samplerate" ); p_sys->psz_requested_chroma = var_CreateGetString( p_obj, "v4l2-chroma" ); -#ifdef HAVE_ALSA - p_sys->i_audio_method = var_CreateGetInteger( p_obj, "v4l2-audio-method" ); -#else - p_sys->i_audio_method = AUDIO_METHOD_OSS; -#endif + p_sys->i_cache = var_CreateGetInteger( p_obj, "v4l2-caching" ); - p_sys->b_stereo = var_CreateGetBool( p_obj, "v4l2-stereo" ); + p_sys->i_cur_tuner = var_CreateGetInteger( p_obj, "v4l2-tuner" ); + p_sys->i_frequency = var_CreateGetInteger( p_obj, "v4l2-tuner-frequency" ); + p_sys->i_audio_mode = var_CreateGetInteger( p_obj, "v4l2-tuner-audio-mode" ); - p_sys->i_pts = var_CreateGetInteger( p_obj, "v4l2-caching" ); + p_sys->psz_set_ctrls = var_CreateGetString( p_obj, "v4l2-set-ctrls" ); - p_sys->psz_device = p_sys->psz_vdev = p_sys->psz_adev = NULL; - p_sys->i_fd_video = -1; - p_sys->i_fd_audio = -1; + p_sys->psz_device = NULL; + p_sys->i_fd = -1; - p_sys->p_es_video = p_sys->p_es_audio = 0; - p_sys->p_block_audio = 0; + p_sys->p_es = NULL; } /***************************************************************************** @@ -616,30 +711,7 @@ static void ParseMRL( demux_sys_t *p_sys, char *psz_path, vlc_object_t *p_obj ) { *psz_parser++ = '\0'; - if( !strncmp( psz_parser, "adev=", strlen( "adev=" ) ) ) - { - int i_len; - - psz_parser += strlen( "adev=" ); - if( strchr( psz_parser, ':' ) ) - { - i_len = strchr( psz_parser, ':' ) - psz_parser; - } - else - { - i_len = strlen( psz_parser ); - } - - p_sys->psz_adev = strndup( psz_parser, i_len ); - if( !*p_sys->psz_adev ) - { - free( p_sys->psz_adev ); - p_sys->psz_adev = NULL; - } - - psz_parser += i_len; - } - else if( !strncmp( psz_parser, "standard=", strlen( "standard=" ) ) ) + if( !strncmp( psz_parser, "standard=", strlen( "standard=" ) ) ) { psz_parser += strlen( "standard=" ); if( !strncmp( psz_parser, "pal", strlen( "pal" ) ) ) @@ -681,7 +753,7 @@ static void ParseMRL( demux_sys_t *p_sys, char *psz_path, vlc_object_t *p_obj ) i_len = strlen( psz_parser ); } - if( p_sys->psz_requested_chroma ) free( p_sys->psz_requested_chroma ); + free( p_sys->psz_requested_chroma ); p_sys->psz_requested_chroma = strndup( psz_parser, i_len ); psz_parser += i_len; @@ -691,6 +763,11 @@ static void ParseMRL( demux_sys_t *p_sys, char *psz_path, vlc_object_t *p_obj ) p_sys->i_selected_input = strtol( psz_parser + strlen( "input=" ), &psz_parser, 0 ); } + else if( !strncmp( psz_parser, "audio-input=", strlen( "audio-input=" ) ) ) + { + p_sys->i_selected_audio_input = strtol( psz_parser + strlen( "audio-input=" ), + &psz_parser, 0 ); + } else if( !strncmp( psz_parser, "fps=", strlen( "fps=" ) ) ) { p_sys->f_fps = strtof( psz_parser + strlen( "fps=" ), @@ -736,7 +813,7 @@ static void ParseMRL( demux_sys_t *p_sys, char *psz_path, vlc_object_t *p_obj ) else if( !strncmp( psz_parser, "controls-reset", strlen( "controls-reset" ) ) ) { - var_SetBool( p_obj, "v4l2-controls-reset", VLC_TRUE ); + var_SetBool( p_obj, "v4l2-controls-reset", true ); psz_parser += strlen( "controls-reset" ); } #if 0 @@ -776,39 +853,72 @@ static void ParseMRL( demux_sys_t *p_sys, char *psz_path, vlc_object_t *p_obj ) &psz_parser, 0 ) ); } #endif - else if( !strncmp( psz_parser, "samplerate=", - strlen( "samplerate=" ) ) ) + else if( !strncmp( psz_parser, "caching=", strlen( "caching=" ) ) ) { - p_sys->i_sample_rate = - strtol( psz_parser + strlen( "samplerate=" ), - &psz_parser, 0 ); + p_sys->i_cache = strtol( psz_parser + strlen( "caching=" ), + &psz_parser, 0 ); } -#ifdef HAVE_ALSA - else if( !strncmp( psz_parser, "audio-method", strlen( "audio-method" ) ) ) + else if( !strncmp( psz_parser, "tuner=", strlen( "tuner=" ) ) ) { - p_sys->i_audio_method = - strtol( psz_parser + strlen( "audio-method" ), - &psz_parser, 0 ); + p_sys->i_cur_tuner = strtol( psz_parser + strlen( "tuner=" ), + &psz_parser, 0 ); } -#endif - else if( !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) ) + else if( !strncmp( psz_parser, "tuner-frequency=", strlen( "tuner-frequency=" ) ) ) { - psz_parser += strlen( "stereo" ); - p_sys->b_stereo = VLC_TRUE; + p_sys->i_frequency = strtol( psz_parser + + strlen( "tuner-frequency=" ), + &psz_parser, 0 ); } - else if( !strncmp( psz_parser, "mono", strlen( "mono" ) ) ) + else if( !strncmp( psz_parser, "tuner-audio-mode=", strlen( "tuner-audio-mode=" ) ) ) { - psz_parser += strlen( "mono" ); - p_sys->b_stereo = VLC_FALSE; + p_sys->i_audio_mode = strtol( psz_parser + + strlen( "tuner-audio-mode=" ), + &psz_parser, 0 ); } - else if( !strncmp( psz_parser, "caching=", strlen( "caching=" ) ) ) + else if( !strncmp( psz_parser, "set-ctrls=", strlen( "set-ctrls=" )) ) { - p_sys->i_pts = strtol( psz_parser + strlen( "caching=" ), - &psz_parser, 0 ); + int i_len; + + psz_parser += strlen( "set-ctrls=" ); + if( strchr( psz_parser, ':' ) ) + { + i_len = strchr( psz_parser, ':' ) - psz_parser; + } + else + { + i_len = strlen( psz_parser ); + } + + p_sys->psz_set_ctrls = strndup( psz_parser, i_len ); + + psz_parser += i_len; + } + else if( !strncmp( psz_parser, "adev=", strlen( "adev=" ) ) + || !strncmp( psz_parser, "samplerate=", strlen( "samplerate=" ) ) + || !strncmp( psz_parser, "audio-method", strlen( "audio-method" ) ) + || !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) + || !strncmp( psz_parser, "mono", strlen( "mono" ) ) ) + { + if( strchr( psz_parser, ':' ) ) + { + psz_parser = strchr( psz_parser, ':' ); + } + else + { + psz_parser += strlen( psz_parser ); + } + + msg_Err( p_obj, AUDIO_DEPRECATED_ERROR ); } else { - msg_Warn( p_obj, "unknown option" ); + char *psz_unk = strchr( psz_parser, ':' ); + if (psz_unk) + psz_unk = strndup( psz_parser, psz_unk - psz_parser ); + else + psz_unk = strdup( psz_parser); + msg_Warn( p_obj, "unknown option %s", psz_unk ); + free (psz_unk); } while( *psz_parser && *psz_parser != ':' ) @@ -825,10 +935,10 @@ static void ParseMRL( demux_sys_t *p_sys, char *psz_path, vlc_object_t *p_obj ) /* Main device */ if( *psz_dup ) - { p_sys->psz_device = strdup( psz_dup ); - } - if( psz_dup ) free( psz_dup ); + else + p_sys->psz_device = strdup( V4L2_DEFAULT ); + free( psz_dup ); } /***************************************************************************** @@ -852,7 +962,7 @@ static void DemuxClose( vlc_object_t *p_this ) demux_sys_t *p_sys = p_demux->p_sys; /* Stop video capture */ - if( p_sys->i_fd_video >= 0 ) + if( p_sys->i_fd >= 0 ) { switch( p_sys->io ) { @@ -869,11 +979,11 @@ static void DemuxClose( vlc_object_t *p_this ) buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = ( p_sys->io == IO_METHOD_USERPTR ) ? V4L2_MEMORY_USERPTR : V4L2_MEMORY_MMAP; - ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ); /* ignore result */ + v4l2_ioctl( p_sys->i_fd, VIDIOC_DQBUF, &buf ); /* ignore result */ } buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if( ioctl( p_sys->i_fd_video, VIDIOC_STREAMOFF, &buf_type ) < 0 ) { + if( v4l2_ioctl( p_sys->i_fd, VIDIOC_STREAMOFF, &buf_type ) < 0 ) { msg_Err( p_this, "VIDIOC_STREAMOFF failed" ); } @@ -892,7 +1002,7 @@ static void DemuxClose( vlc_object_t *p_this ) case IO_METHOD_MMAP: for( i = 0; i < p_sys->i_nbuffers; ++i ) { - if( munmap( p_sys->p_buffers[i].start, p_sys->p_buffers[i].length ) ) + if( v4l2_munmap( p_sys->p_buffers[i].start, p_sys->p_buffers[i].length ) ) { msg_Err( p_this, "munmap failed" ); } @@ -902,7 +1012,7 @@ static void DemuxClose( vlc_object_t *p_this ) case IO_METHOD_USERPTR: for( i = 0; i < p_sys->i_nbuffers; ++i ) { - free( p_sys->p_buffers[i].orig_userp ); + free( p_sys->p_buffers[i].start ); } break; } @@ -914,28 +1024,22 @@ static void DemuxClose( vlc_object_t *p_this ) static void CommonClose( vlc_object_t *p_this, demux_sys_t *p_sys ) { + (void)p_this; /* Close */ - if( p_sys->i_fd_video >= 0 ) close( p_sys->i_fd_video ); -#ifdef HAVE_ALSA - if( p_sys->p_alsa_pcm ) snd_pcm_close( p_sys->p_alsa_pcm ); -#endif - if( p_sys->i_fd_audio >= 0 ) close( p_sys->i_fd_audio ); - - if( p_sys->p_block_audio ) block_Release( p_sys->p_block_audio ); + if( p_sys->i_fd >= 0 ) v4l2_close( p_sys->i_fd ); free( p_sys->psz_device ); - free( p_sys->psz_vdev ); - free( p_sys->psz_adev ); free( p_sys->p_standards ); free( p_sys->p_inputs ); free( p_sys->p_tuners ); free( p_sys->p_codecs ); free( p_sys->psz_requested_chroma ); + free( p_sys->psz_set_ctrls ); free( p_sys ); } /***************************************************************************** - * AccessOpen: opens v4l2 device, access2 callback + * AccessOpen: opens v4l2 device, access callback ***************************************************************************** * * url: