]> git.sesse.net Git - vlc/blob - modules/access/v4l2.c
Enable --v4l2-audio-method even if ALSA isn't available (makes it possible to disable...
[vlc] / modules / access / v4l2.c
1 /*****************************************************************************
2  * v4l2.c : Video4Linux2 input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2002-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Benjamin Pracht <bigben at videolan dot org>
8  *          Richard Hosking <richard at hovis dot net>
9  *          Antoine Cellerier <dionoea at videolan d.t org>
10  *          Dennis Lou <dlou99 at yahoo dot com>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25  *****************************************************************************/
26
27 /*
28  * Sections based on the reference V4L2 capture example at
29  * http://v4l2spec.bytesex.org/spec/capture-example.html
30  *
31  * ALSA support based on parts of
32  * http://www.equalarea.com/paul/alsa-audio.html
33  * and hints taken from alsa-utils (aplay/arecord)
34  * http://www.alsa-project.org
35  */
36
37 /*
38  * TODO: Tuner partial implementation.
39  * TODO: Add more MPEG stream params
40  */
41
42 /*****************************************************************************
43  * Preamble
44  *****************************************************************************/
45
46 #include <vlc/vlc.h>
47 #include <vlc_access.h>
48 #include <vlc_demux.h>
49 #include <vlc_input.h>
50 #include <vlc_vout.h>
51
52 #include <fcntl.h>
53 #include <unistd.h>
54 #include <sys/ioctl.h>
55 #include <sys/mman.h>
56
57 #include <linux/videodev2.h>
58
59 #include <sys/soundcard.h>
60
61 #ifdef HAVE_ALSA
62 #   define ALSA_PCM_NEW_HW_PARAMS_API
63 #   define ALSA_PCM_NEW_SW_PARAMS_API
64 #   include <alsa/asoundlib.h>
65 #endif
66
67 #include <poll.h>
68
69 /*****************************************************************************
70  * Module descriptior
71  *****************************************************************************/
72
73 static int  DemuxOpen ( vlc_object_t * );
74 static void DemuxClose( vlc_object_t * );
75 static int  AccessOpen ( vlc_object_t * );
76 static void AccessClose( vlc_object_t * );
77
78 #define DEV_TEXT N_("Device name")
79 #define DEV_LONGTEXT N_( \
80     "Name of the device to use. " \
81     "If you don't specify anything, /dev/video0 will be used.")
82 #define STANDARD_TEXT N_( "Standard" )
83 #define STANDARD_LONGTEXT N_( \
84     "Video standard (Default, SECAM, PAL, or NTSC)." )
85 #define CHROMA_TEXT N_("Video input chroma format")
86 #define CHROMA_LONGTEXT N_( \
87     "Force the Video4Linux2 video device to use a specific chroma format " \
88     "(eg. I420 or I422 for raw images, MJPEG for M-JPEG compressed input) " \
89     "(Complete list: GREY, I240, RV16, RV15, RV24, RV32, YUY2, YUYV, UYVY, " \
90     "I41N, I422, I420, I411, I410, MJPG)")
91 #define INPUT_TEXT N_( "Input" )
92 #define INPUT_LONGTEXT N_( \
93     "Input of the card to use (Usually, 0 = tuner, " \
94     "1 = composite, 2 = svideo)." )
95 #define IOMETHOD_TEXT N_( "IO Method" )
96 #define IOMETHOD_LONGTEXT N_( \
97     "IO Method (READ, MMAP, USERPTR)." )
98 #define WIDTH_TEXT N_( "Width" )
99 #define WIDTH_LONGTEXT N_( \
100     "Force width (-1 for autodetect)." )
101 #define HEIGHT_TEXT N_( "Height" )
102 #define HEIGHT_LONGTEXT N_( \
103     "Force height (-1 for autodetect)." )
104 #define FPS_TEXT N_( "Framerate" )
105 #define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \
106     "(-1 for autodetect)." )
107
108 #define CTRL_RESET_TEXT N_( "Reset v4l2 controls" )
109 #define CTRL_RESET_LONGTEXT N_( \
110     "Reset controls to defaults provided by the v4l2 driver." )
111 #define BRIGHTNESS_TEXT N_( "Brightness" )
112 #define BRIGHTNESS_LONGTEXT N_( \
113     "Brightness of the video input (if supported by v4l2 driver)." )
114 #define CONTRAST_TEXT N_( "Contrast" )
115 #define CONTRAST_LONGTEXT N_( \
116     "Contrast of the video input (if supported by v4l2 driver)." )
117 #define SATURATION_TEXT N_( "Saturation" )
118 #define SATURATION_LONGTEXT N_( \
119     "Saturation of the video input (if supported by v4l2 driver)." )
120 #define HUE_TEXT N_( "Hue" )
121 #define HUE_LONGTEXT N_( \
122     "Hue of the video input (if supported by v4l2 driver)." )
123 #define GAMMA_TEXT N_( "Gamma" )
124 #define GAMMA_LONGTEXT N_( \
125     "Gamma of the video input (if supported by v4l2 driver)." )
126
127 #define ADEV_TEXT N_("Audio device name")
128 #ifndef HAVE_ALSA
129 #define ADEV_LONGTEXT N_( \
130     "Name of the audio device to use. " \
131     "If you don't specify anything, \"/dev/dsp\" will be used for OSS.")
132 #else
133 #define ADEV_LONGTEXT N_( \
134     "Name of the audio device to use. " \
135     "If you don't specify anything, \"/dev/dsp\" will be used for OSS, " \
136     "\"default\" for Alsa.")
137 #endif
138 #define AUDIO_METHOD_TEXT N_( "Audio method" )
139 #ifndef HAVE_ALSA
140 #define AUDIO_METHOD_LONGTEXT N_( \
141     "Audio method to use: 0 to disable audio, 1 for OSS." )
142 #else
143 #define AUDIO_METHOD_LONGTEXT N_( \
144     "Audio method to use: 0 to disable audio, 1 for OSS, 2 for ALSA, " \
145     "3 for ALSA or OSS (ALSA is prefered)." )
146 #endif
147 #define STEREO_TEXT N_( "Stereo" )
148 #define STEREO_LONGTEXT N_( \
149     "Capture the audio stream in stereo." )
150 #define SAMPLERATE_TEXT N_( "Samplerate" )
151 #define SAMPLERATE_LONGTEXT N_( \
152     "Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100, 48000)" )
153
154 #define CACHING_TEXT N_("Caching value in ms")
155 #define CACHING_LONGTEXT N_( \
156     "Caching value for V4L2 captures. This " \
157     "value should be set in milliseconds." )
158
159 typedef enum {
160     IO_METHOD_READ,
161     IO_METHOD_MMAP,
162     IO_METHOD_USERPTR,
163 } io_method;
164
165 static int i_standards_list[] =
166     { V4L2_STD_UNKNOWN, V4L2_STD_SECAM, V4L2_STD_PAL, V4L2_STD_NTSC };
167 static const char *psz_standards_list_text[] =
168     { N_("Default"), N_("SECAM"), N_("PAL"),  N_("NTSC") };
169
170 static int i_iomethod_list[] =
171     { IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR };
172 static const char *psz_iomethod_list_text[] =
173     { N_("READ"), N_("MMAP"),  N_("USERPTR") };
174
175 #define FIND_VIDEO 1
176 #define FIND_AUDIO 2
177
178 #define AUDIO_METHOD_OSS 1
179 #define OSS_DEFAULT "/dev/dsp"
180 #define AUDIO_METHOD_ALSA 2
181 #define ALSA_DEFAULT "default"
182 #define CFG_PREFIX "v4l2-"
183
184 vlc_module_begin();
185     set_shortname( _("Video4Linux2") );
186     set_description( _("Video4Linux2 input") );
187     set_category( CAT_INPUT );
188     set_subcategory( SUBCAT_INPUT_ACCESS );
189
190     set_section( N_( "Video input" ), NULL );
191     add_string( CFG_PREFIX "dev", "/dev/video0", 0, DEV_TEXT, DEV_LONGTEXT,
192                 VLC_FALSE );
193     add_integer( CFG_PREFIX "standard", 0, NULL, STANDARD_TEXT,
194                  STANDARD_LONGTEXT, VLC_FALSE );
195         change_integer_list( i_standards_list, psz_standards_list_text, 0 );
196     add_string( CFG_PREFIX "chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT,
197                 VLC_TRUE );
198     add_integer( CFG_PREFIX "input", 0, NULL, INPUT_TEXT, INPUT_LONGTEXT,
199                 VLC_TRUE );
200     add_integer( CFG_PREFIX "io", IO_METHOD_MMAP, NULL, IOMETHOD_TEXT,
201                  IOMETHOD_LONGTEXT, VLC_TRUE );
202         change_integer_list( i_iomethod_list, psz_iomethod_list_text, 0 );
203     add_integer( CFG_PREFIX "width", 0, NULL, WIDTH_TEXT,
204                 WIDTH_LONGTEXT, VLC_TRUE );
205     add_integer( CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
206                 HEIGHT_LONGTEXT, VLC_TRUE );
207     add_float( CFG_PREFIX "fps", 0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_TRUE );
208
209     set_section( N_( "Audio input" ), NULL );
210     add_string( CFG_PREFIX "adev", NULL, 0, ADEV_TEXT, ADEV_LONGTEXT,
211                 VLC_FALSE );
212     add_integer( CFG_PREFIX "audio-method", AUDIO_METHOD_OSS|AUDIO_METHOD_ALSA,
213                  NULL, AUDIO_METHOD_TEXT, AUDIO_METHOD_LONGTEXT, VLC_TRUE );
214     add_bool( CFG_PREFIX "stereo", VLC_TRUE, NULL, STEREO_TEXT, STEREO_LONGTEXT,
215                 VLC_TRUE );
216     add_integer( CFG_PREFIX "samplerate", 48000, NULL, SAMPLERATE_TEXT,
217                 SAMPLERATE_LONGTEXT, VLC_TRUE );
218     add_integer( CFG_PREFIX "caching", DEFAULT_PTS_DELAY / 1000, NULL,
219                 CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
220
221     set_section( N_( "Controls" ), N_( "v4l2 driver controls" ) );
222     add_bool( CFG_PREFIX "controls-reset", VLC_FALSE, NULL, CTRL_RESET_TEXT,
223               CTRL_RESET_LONGTEXT, VLC_TRUE );
224     add_integer( CFG_PREFIX "brightness", -1, NULL, BRIGHTNESS_TEXT,
225                 BRIGHTNESS_LONGTEXT, VLC_TRUE );
226     add_integer( CFG_PREFIX "contrast", -1, NULL, CONTRAST_TEXT,
227                 CONTRAST_LONGTEXT, VLC_TRUE );
228     add_integer( CFG_PREFIX "saturation", -1, NULL, SATURATION_TEXT,
229                 SATURATION_LONGTEXT, VLC_TRUE );
230     add_integer( CFG_PREFIX "hue", -1, NULL, HUE_TEXT,
231                 HUE_LONGTEXT, VLC_TRUE );
232     add_integer( CFG_PREFIX "gamma", -1, NULL, GAMMA_TEXT,
233                 GAMMA_LONGTEXT, VLC_TRUE );
234
235
236     add_shortcut( "v4l2" );
237     set_capability( "access_demux", 10 );
238     set_callbacks( DemuxOpen, DemuxClose );
239
240     add_submodule();
241     set_description( _("Video4Linux2 Compressed A/V") );
242     set_capability( "access2", 0 );
243     /* use these when open as access_demux fails; VLC will use another demux */
244     set_callbacks( AccessOpen, AccessClose );
245
246 vlc_module_end();
247
248 /*****************************************************************************
249  * Access: local prototypes
250  *****************************************************************************/
251
252 static void CommonClose( vlc_object_t *, demux_sys_t * );
253 static void ParseMRL( demux_sys_t *, char *, vlc_object_t * );
254 static void GetV4L2Params( demux_sys_t *, vlc_object_t * );
255
256 static int DemuxControl( demux_t *, int, va_list );
257 static int AccessControl( access_t *, int, va_list );
258
259 static int Demux( demux_t * );
260 static ssize_t AccessRead( access_t *, uint8_t *, size_t );
261
262 static block_t* GrabVideo( demux_t *p_demux );
263 static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame, size_t );
264 static block_t* GrabAudio( demux_t *p_demux );
265
266 static vlc_bool_t IsPixelFormatSupported( demux_t *p_demux,
267                                           unsigned int i_pixelformat );
268
269 #ifdef HAVE_ALSA
270 static char* ResolveALSADeviceName( const char *psz_device );
271 #endif
272 static int OpenVideoDev( vlc_object_t *, demux_sys_t *, vlc_bool_t );
273 static int OpenAudioDev( vlc_object_t *, demux_sys_t *, vlc_bool_t );
274 static vlc_bool_t ProbeVideoDev( vlc_object_t *, demux_sys_t *,
275                                  char *psz_device );
276 static vlc_bool_t ProbeAudioDev( vlc_object_t *, demux_sys_t *,
277                                  char *psz_device );
278
279 static int ControlList( vlc_object_t *, int , vlc_bool_t, vlc_bool_t );
280 static int Control( vlc_object_t *, int i_fd,
281                     const char *psz_name, int i_cid, int i_value );
282
283 static int DemuxControlCallback( vlc_object_t *p_this, const char *psz_var,
284                                  vlc_value_t oldval, vlc_value_t newval,
285                                  void *p_data );
286 static int DemuxControlResetCallback( vlc_object_t *p_this, const char *psz_var,
287                                       vlc_value_t oldval, vlc_value_t newval,
288                                       void *p_data );
289 static int AccessControlCallback( vlc_object_t *p_this, const char *psz_var,
290                                   vlc_value_t oldval, vlc_value_t newval,
291                                   void *p_data );
292 static int AccessControlResetCallback( vlc_object_t *p_this,
293                                        const char *psz_var, vlc_value_t oldval,
294                                        vlc_value_t newval, void *p_data );
295
296 static struct
297 {
298     unsigned int i_v4l2;
299     int i_fourcc;
300 } v4l2chroma_to_fourcc[] =
301 {
302     /* Raw data types */
303     { V4L2_PIX_FMT_GREY,    VLC_FOURCC('G','R','E','Y') },
304     { V4L2_PIX_FMT_HI240,   VLC_FOURCC('I','2','4','0') },
305     { V4L2_PIX_FMT_RGB565,  VLC_FOURCC('R','V','1','6') },
306     { V4L2_PIX_FMT_RGB555,  VLC_FOURCC('R','V','1','5') },
307     { V4L2_PIX_FMT_BGR24,   VLC_FOURCC('R','V','2','4') },
308     { V4L2_PIX_FMT_BGR32,   VLC_FOURCC('R','V','3','2') },
309     { V4L2_PIX_FMT_YUYV,    VLC_FOURCC('Y','U','Y','2') },
310     { V4L2_PIX_FMT_YUYV,    VLC_FOURCC('Y','U','Y','V') },
311     { V4L2_PIX_FMT_UYVY,    VLC_FOURCC('U','Y','V','Y') },
312     { V4L2_PIX_FMT_Y41P,    VLC_FOURCC('I','4','1','N') },
313     { V4L2_PIX_FMT_YUV422P, VLC_FOURCC('I','4','2','2') },
314     { V4L2_PIX_FMT_YVU420,  VLC_FOURCC('I','4','2','0') },
315     { V4L2_PIX_FMT_YUV411P, VLC_FOURCC('I','4','1','1') },
316     { V4L2_PIX_FMT_YUV410,  VLC_FOURCC('I','4','1','0') },
317     /* Compressed data types */
318     { V4L2_PIX_FMT_MJPEG,   VLC_FOURCC('M','J','P','G') },
319 #if 0
320     { V4L2_PIX_FMT_JPEG,    VLC_FOURCC('J','P','E','G') },
321     { V4L2_PIX_FMT_DV,      VLC_FOURCC('?','?','?','?') },
322     { V4L2_PIX_FMT_MPEG,    VLC_FOURCC('?','?','?','?') },
323 #endif
324     { 0, 0 }
325 };
326
327 static struct
328 {
329     const char *psz_name;
330     unsigned int i_cid;
331 } controls[] =
332 {
333     { "brightness", V4L2_CID_BRIGHTNESS },
334     { "contrast", V4L2_CID_CONTRAST },
335     { "saturation", V4L2_CID_SATURATION },
336     { "hue", V4L2_CID_HUE },
337     { "audio-volume", V4L2_CID_AUDIO_VOLUME },
338     { "audio-balance", V4L2_CID_AUDIO_BALANCE },
339     { "audio-bass", V4L2_CID_AUDIO_BASS },
340     { "audio-treble", V4L2_CID_AUDIO_TREBLE },
341     { "audio-mute", V4L2_CID_AUDIO_MUTE },
342     { "audio-loudness", V4L2_CID_AUDIO_LOUDNESS },
343     { "black-level", V4L2_CID_BLACK_LEVEL },
344     { "auto-white-balance", V4L2_CID_AUTO_WHITE_BALANCE },
345     { "do-white-balance", V4L2_CID_DO_WHITE_BALANCE },
346     { "red-balance", V4L2_CID_RED_BALANCE },
347     { "blue-balance", V4L2_CID_BLUE_BALANCE },
348     { "gamma", V4L2_CID_GAMMA },
349     { "exposure", V4L2_CID_EXPOSURE },
350     { "autogain", V4L2_CID_AUTOGAIN },
351     { "gain", V4L2_CID_GAIN },
352     { "hflip", V4L2_CID_HFLIP },
353     { "vflip", V4L2_CID_VFLIP },
354     { "hcenter", V4L2_CID_HCENTER },
355     { "vcenter", V4L2_CID_VCENTER },
356     { NULL, 0 }
357 };
358
359 struct buffer_t
360 {
361     void *  start;
362     size_t  length;
363     void *  orig_userp;
364 };
365
366 struct demux_sys_t
367 {
368     char *psz_device;  /* Main device from MRL, can be video or audio */
369
370     char *psz_vdev;
371     int  i_fd_video;
372
373     char *psz_adev;
374     int  i_fd_audio;
375
376     char *psz_requested_chroma;
377
378     /* Video */
379     io_method io;
380
381     int i_pts;
382
383     struct v4l2_capability dev_cap;
384
385     int i_input;
386     struct v4l2_input *p_inputs;
387     int i_selected_input;
388
389     int i_standard;
390     struct v4l2_standard *p_standards;
391     v4l2_std_id i_selected_standard_id;
392
393     int i_audio;
394     /* V4L2 devices cannot have more than 32 audio inputs */
395     struct v4l2_audio p_audios[32];
396
397     int i_tuner;
398     struct v4l2_tuner *p_tuners;
399
400     int i_codec;
401     struct v4l2_fmtdesc *p_codecs;
402
403     struct buffer_t *p_buffers;
404     unsigned int i_nbuffers;
405
406     int i_width;
407     int i_height;
408     float f_fps;            /* <= 0.0 mean to grab at full rate */
409     mtime_t i_video_pts;    /* only used when f_fps > 0 */
410     int i_fourcc;
411
412     es_out_id_t *p_es_video;
413
414     /* Audio */
415     unsigned int i_sample_rate;
416     vlc_bool_t b_stereo;
417     size_t i_audio_max_frame_size;
418     block_t *p_block_audio;
419     es_out_id_t *p_es_audio;
420
421     int i_audio_method;
422
423 #ifdef HAVE_ALSA
424     /* ALSA Audio */
425     snd_pcm_t *p_alsa_pcm;
426     size_t i_alsa_frame_size;
427     int i_alsa_chunk_size;
428 #endif
429 };
430
431 static int FindMainDevice( vlc_object_t *p_this, demux_sys_t *p_sys,
432                            int i_flags, vlc_bool_t b_demux,
433                            vlc_bool_t b_forced )
434 {
435     /* Find main device (video or audio) */
436     if( p_sys->psz_device && *p_sys->psz_device )
437     {
438         msg_Dbg( p_this, "main device='%s'", p_sys->psz_device );
439
440         vlc_bool_t b_maindevice_is_video = VLC_FALSE;
441
442         /* Try to open as video device */
443         if( i_flags & FIND_VIDEO )
444         {
445             msg_Dbg( p_this, "trying device '%s' as video", p_sys->psz_device );
446             if( ProbeVideoDev( p_this, p_sys, p_sys->psz_device ) )
447             {
448                 msg_Dbg( p_this, "'%s' is a video device", p_sys->psz_device );
449                 /* Device was a video device */
450                 if( p_sys->psz_vdev ) free( p_sys->psz_vdev );
451                 p_sys->psz_vdev = p_sys->psz_device;
452                 p_sys->psz_device = NULL;
453                 p_sys->i_fd_video = OpenVideoDev( p_this, p_sys, b_demux );
454                 if( p_sys->i_fd_video < 0 )
455                     return VLC_EGENERIC;
456                 b_maindevice_is_video = VLC_TRUE;
457                 /* If successful we carry on to try the audio if access is forced */
458             }
459         }
460
461         /* Try to open as audio device only if main device was not detected as video above */
462         if( i_flags & FIND_AUDIO && !b_maindevice_is_video )
463         {
464             msg_Dbg( p_this, "trying device '%s' as audio", p_sys->psz_device );
465             if( ProbeAudioDev( p_this, p_sys, p_sys->psz_device ) )
466             {
467                 msg_Dbg( p_this, "'%s' is an audio device", p_sys->psz_device );
468                 /* Device was an audio device */
469                 free( p_sys->psz_adev );
470                 p_sys->psz_adev = p_sys->psz_device;
471                 p_sys->psz_device = NULL;
472                 p_sys->i_fd_audio = OpenAudioDev( p_this, p_sys, b_demux );
473                 if( p_sys->i_fd_audio < 0 )
474                     return VLC_EGENERIC;
475                 /* If successful we carry on to try the video if access is forced */
476             }
477         }
478     }
479
480     /* If no device opened, only continue if the access was forced */
481     if( b_forced == VLC_FALSE
482         && !( ( i_flags & FIND_VIDEO && p_sys->i_fd_video >= 0 )
483            || ( i_flags & FIND_AUDIO && p_sys->i_fd_audio >= 0 ) ) )
484     {
485         return VLC_EGENERIC;
486     }
487
488     /* Find video device */
489     if( i_flags & FIND_VIDEO && p_sys->i_fd_video < 0 )
490     {
491         if( !p_sys->psz_vdev || !*p_sys->psz_vdev )
492         {
493             if( p_sys->psz_vdev ) free( p_sys->psz_vdev );
494             p_sys->psz_vdev = var_CreateGetString( p_this, "v4l2-dev" );
495         }
496
497         msg_Dbg( p_this, "opening '%s' as video", p_sys->psz_vdev );
498         if( p_sys->psz_vdev && *p_sys->psz_vdev
499          && ProbeVideoDev( p_this, p_sys, p_sys->psz_vdev ) )
500         {
501             p_sys->i_fd_video = OpenVideoDev( p_this, p_sys, b_demux );
502         }
503     }
504
505     /* Find audio device */
506     if( i_flags & FIND_AUDIO && p_sys->i_fd_audio < 0 )
507     {
508         if( !p_sys->psz_adev )
509         {
510             p_sys->psz_adev = var_CreateGetNonEmptyString( p_this, "v4l2-adev" );
511         }
512
513         msg_Dbg( p_this, "opening '%s' as audio", p_sys->psz_adev );
514         if( ProbeAudioDev( p_this, p_sys, p_sys->psz_adev ) )
515         {
516             p_sys->i_fd_audio = OpenAudioDev( p_this, p_sys, b_demux );
517         }
518     }
519
520     if( !( ( i_flags & FIND_VIDEO && p_sys->i_fd_video >= 0 )
521         || ( i_flags & FIND_AUDIO && p_sys->i_fd_audio >= 0 ) ) )
522     {
523         return VLC_EGENERIC;
524     }
525     return VLC_SUCCESS;
526 }
527
528 /*****************************************************************************
529  * DemuxOpen: opens v4l2 device, access_demux callback
530  *****************************************************************************
531  *
532  * url: <video device>::::
533  *
534  *****************************************************************************/
535 static int DemuxOpen( vlc_object_t *p_this )
536 {
537     demux_t     *p_demux = (demux_t*)p_this;
538     demux_sys_t *p_sys;
539
540     /* Only when selected */
541     if( *p_demux->psz_access == '\0' ) return VLC_EGENERIC;
542
543     /* Set up p_demux */
544     p_demux->pf_control = DemuxControl;
545     p_demux->pf_demux = Demux;
546     p_demux->info.i_update = 0;
547     p_demux->info.i_title = 0;
548     p_demux->info.i_seekpoint = 0;
549
550     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
551     if( p_sys == NULL ) return VLC_ENOMEM;
552
553     GetV4L2Params(p_sys, (vlc_object_t *) p_demux);
554
555     ParseMRL( p_sys, p_demux->psz_path, (vlc_object_t *) p_demux );
556
557 #ifdef HAVE_ALSA
558     /* Alsa support available? */
559     msg_Dbg( p_demux, "ALSA input support available" );
560 #endif
561
562     if( FindMainDevice( p_this, p_sys, FIND_VIDEO|FIND_AUDIO,
563         VLC_TRUE, !strcmp( p_demux->psz_access, "v4l2" ) ) != VLC_SUCCESS )
564     {
565         DemuxClose( p_this );
566         return VLC_EGENERIC;
567     }
568
569     return VLC_SUCCESS;
570 }
571
572 /*****************************************************************************
573  * GetV4L2Params: fill in p_sys parameters (shared by DemuxOpen and AccessOpen)
574  *****************************************************************************/
575 static void GetV4L2Params( demux_sys_t *p_sys, vlc_object_t *p_obj )
576 {
577     p_sys->i_video_pts = -1;
578
579     p_sys->i_selected_standard_id =
580         i_standards_list[var_CreateGetInteger( p_obj, "v4l2-standard" )];
581
582     p_sys->i_selected_input = var_CreateGetInteger( p_obj, "v4l2-input" );
583
584     p_sys->io = var_CreateGetInteger( p_obj, "v4l2-io" );
585
586     p_sys->i_width = var_CreateGetInteger( p_obj, "v4l2-width" );
587     p_sys->i_height = var_CreateGetInteger( p_obj, "v4l2-height" );
588
589     var_CreateGetBool( p_obj, "v4l2-controls-reset" );
590
591     p_sys->f_fps = var_CreateGetFloat( p_obj, "v4l2-fps" );
592     p_sys->i_sample_rate = var_CreateGetInteger( p_obj, "v4l2-samplerate" );
593     p_sys->psz_requested_chroma = var_CreateGetString( p_obj, "v4l2-chroma" );
594
595     p_sys->i_audio_method = var_CreateGetInteger( p_obj, "v4l2-audio-method" );
596
597     p_sys->b_stereo = var_CreateGetBool( p_obj, "v4l2-stereo" );
598
599     p_sys->i_pts = var_CreateGetInteger( p_obj, "v4l2-caching" );
600
601     p_sys->psz_device = p_sys->psz_vdev = p_sys->psz_adev = NULL;
602     p_sys->i_fd_video = -1;
603     p_sys->i_fd_audio = -1;
604
605     p_sys->p_es_video = p_sys->p_es_audio = 0;
606     p_sys->p_block_audio = 0;
607 }
608
609 /*****************************************************************************
610  * ParseMRL: parse the options contained in the MRL
611  *****************************************************************************/
612 static void ParseMRL( demux_sys_t *p_sys, char *psz_path, vlc_object_t *p_obj )
613 {
614     char *psz_dup = strdup( psz_path );
615     char *psz_parser = psz_dup;
616
617     while( *psz_parser && *psz_parser != ':' )
618     {
619         psz_parser++;
620     }
621
622     if( *psz_parser == ':' )
623     {
624         /* read options */
625         for( ;; )
626         {
627             *psz_parser++ = '\0';
628
629             if( !strncmp( psz_parser, "adev=", strlen( "adev=" ) ) )
630             {
631                 int  i_len;
632
633                 psz_parser += strlen( "adev=" );
634                 if( strchr( psz_parser, ':' ) )
635                 {
636                     i_len = strchr( psz_parser, ':' ) - psz_parser;
637                 }
638                 else
639                 {
640                     i_len = strlen( psz_parser );
641                 }
642
643                 p_sys->psz_adev = strndup( psz_parser, i_len );
644                 if( !*p_sys->psz_adev )
645                 {
646                     free( p_sys->psz_adev );
647                     p_sys->psz_adev = NULL;
648                 }
649
650                 psz_parser += i_len;
651             }
652             else if( !strncmp( psz_parser, "standard=", strlen( "standard=" ) ) )
653             {
654                 psz_parser += strlen( "standard=" );
655                 if( !strncmp( psz_parser, "pal", strlen( "pal" ) ) )
656                 {
657                     p_sys->i_selected_standard_id = V4L2_STD_PAL;
658                     psz_parser += strlen( "pal" );
659                 }
660                 else if( !strncmp( psz_parser, "ntsc", strlen( "ntsc" ) ) )
661                 {
662                     p_sys->i_selected_standard_id = V4L2_STD_NTSC;
663                     psz_parser += strlen( "ntsc" );
664                 }
665                 else if( !strncmp( psz_parser, "secam", strlen( "secam" ) ) )
666                 {
667                     p_sys->i_selected_standard_id = V4L2_STD_SECAM;
668                     psz_parser += strlen( "secam" );
669                 }
670                 else if( !strncmp( psz_parser, "default", strlen( "default" ) ) )
671                 {
672                     p_sys->i_selected_standard_id = V4L2_STD_UNKNOWN;
673                     psz_parser += strlen( "default" );
674                 }
675                 else
676                 {
677                     p_sys->i_selected_standard_id = i_standards_list[strtol( psz_parser, &psz_parser, 0 )];
678                 }
679             }
680             else if( !strncmp( psz_parser, "chroma=", strlen( "chroma=" ) ) )
681             {
682                 int  i_len;
683
684                 psz_parser += strlen( "chroma=" );
685                 if( strchr( psz_parser, ':' ) )
686                 {
687                     i_len = strchr( psz_parser, ':' ) - psz_parser;
688                 }
689                 else
690                 {
691                     i_len = strlen( psz_parser );
692                 }
693
694                 if( p_sys->psz_requested_chroma ) free( p_sys->psz_requested_chroma );
695                 p_sys->psz_requested_chroma = strndup( psz_parser, i_len );
696
697                 psz_parser += i_len;
698             }
699             else if( !strncmp( psz_parser, "input=", strlen( "input=" ) ) )
700             {
701                 p_sys->i_selected_input = strtol( psz_parser + strlen( "input=" ),
702                                        &psz_parser, 0 );
703             }
704             else if( !strncmp( psz_parser, "fps=", strlen( "fps=" ) ) )
705             {
706                 p_sys->f_fps = strtof( psz_parser + strlen( "fps=" ),
707                                        &psz_parser );
708             }
709             else if( !strncmp( psz_parser, "io=", strlen( "io=" ) ) )
710             {
711                 psz_parser += strlen( "io=" );
712                 if( !strncmp( psz_parser, "read", strlen( "read" ) ) )
713                 {
714                     p_sys->io = IO_METHOD_READ;
715                     psz_parser += strlen( "read" );
716                 }
717                 else if( !strncmp( psz_parser, "mmap", strlen( "mmap" ) ) )
718                 {
719                     p_sys->io = IO_METHOD_MMAP;
720                     psz_parser += strlen( "mmap" );
721                 }
722                 else if( !strncmp( psz_parser, "userptr", strlen( "userptr" ) ) )
723                 {
724                     p_sys->io = IO_METHOD_USERPTR;
725                     psz_parser += strlen( "userptr" );
726                 }
727                 else
728                 {
729                     p_sys->io = strtol( psz_parser, &psz_parser, 0 );
730                 }
731             }
732             else if( !strncmp( psz_parser, "width=",
733                                strlen( "width=" ) ) )
734             {
735                 p_sys->i_width =
736                     strtol( psz_parser + strlen( "width=" ),
737                             &psz_parser, 0 );
738             }
739             else if( !strncmp( psz_parser, "height=",
740                                strlen( "height=" ) ) )
741             {
742                 p_sys->i_height =
743                     strtol( psz_parser + strlen( "height=" ),
744                             &psz_parser, 0 );
745             }
746             else if( !strncmp( psz_parser, "controls-reset",
747                                strlen( "controls-reset" ) ) )
748             {
749                 var_SetBool( p_obj, "v4l2-controls-reset", VLC_TRUE );
750                 psz_parser += strlen( "controls-reset" );
751             }
752 #if 0
753             else if( !strncmp( psz_parser, "brightness=",
754                                strlen( "brightness=" ) ) )
755             {
756                 var_SetInteger( p_obj, "brightness",
757                     strtol( psz_parser + strlen( "brightness=" ),
758                             &psz_parser, 0 ) );
759             }
760             else if( !strncmp( psz_parser, "contrast=",
761                                strlen( "contrast=" ) ) )
762             {
763                 var_SetInteger( p_obj, "contrast",
764                     strtol( psz_parser + strlen( "contrast=" ),
765                             &psz_parser, 0 ) );
766             }
767             else if( !strncmp( psz_parser, "saturation=",
768                                strlen( "saturation=" ) ) )
769             {
770                 var_SetInteger( p_obj, "saturation",
771                     strtol( psz_parser + strlen( "saturation=" ),
772                             &psz_parser, 0 ) );
773             }
774             else if( !strncmp( psz_parser, "hue=",
775                                strlen( "hue=" ) ) )
776             {
777                 var_SetInteger( p_obj, "hue",
778                     strtol( psz_parser + strlen( "hue=" ),
779                             &psz_parser, 0 ) );
780             }
781             else if( !strncmp( psz_parser, "gamma=",
782                                strlen( "gamma=" ) ) )
783             {
784                 var_SetInteger( p_obj, "gamma",
785                     strtol( psz_parser + strlen( "gamma=" ),
786                             &psz_parser, 0 ) );
787             }
788 #endif
789             else if( !strncmp( psz_parser, "samplerate=",
790                                strlen( "samplerate=" ) ) )
791             {
792                 p_sys->i_sample_rate =
793                     strtol( psz_parser + strlen( "samplerate=" ),
794                             &psz_parser, 0 );
795             }
796             else if( !strncmp( psz_parser, "audio-method", strlen( "audio-method" ) ) )
797             {
798                 p_sys->i_audio_method =
799                     strtol( psz_parser + strlen( "audio-method" ),
800                             &psz_parser, 0 );
801             }
802             else if( !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) )
803             {
804                 psz_parser += strlen( "stereo" );
805                 p_sys->b_stereo = VLC_TRUE;
806             }
807             else if( !strncmp( psz_parser, "mono", strlen( "mono" ) ) )
808             {
809                 psz_parser += strlen( "mono" );
810                 p_sys->b_stereo = VLC_FALSE;
811             }
812             else if( !strncmp( psz_parser, "caching=", strlen( "caching=" ) ) )
813             {
814                 p_sys->i_pts = strtol( psz_parser + strlen( "caching=" ),
815                                        &psz_parser, 0 );
816             }
817             else
818             {
819                 msg_Warn( p_obj, "unknown option" );
820             }
821
822             while( *psz_parser && *psz_parser != ':' )
823             {
824                 psz_parser++;
825             }
826
827             if( *psz_parser == '\0' )
828             {
829                 break;
830             }
831         }
832     }
833
834     /* Main device */
835     if( *psz_dup )
836     {
837         p_sys->psz_device = strdup( psz_dup );
838     }
839     if( psz_dup ) free( psz_dup );
840 }
841
842 /*****************************************************************************
843  * Close: close device, free resources
844  *****************************************************************************/
845 static void AccessClose( vlc_object_t *p_this )
846 {
847     access_t    *p_access = (access_t *)p_this;
848     demux_sys_t *p_sys   = (demux_sys_t *) p_access->p_sys;
849
850     CommonClose( p_this, p_sys );
851 }
852
853 static void DemuxClose( vlc_object_t *p_this )
854 {
855     struct v4l2_buffer buf;
856     enum v4l2_buf_type buf_type;
857     unsigned int i;
858
859     demux_t     *p_demux = (demux_t *)p_this;
860     demux_sys_t *p_sys   = p_demux->p_sys;
861
862     /* Stop video capture */
863     if( p_sys->i_fd_video >= 0 )
864     {
865         switch( p_sys->io )
866         {
867         case IO_METHOD_READ:
868             /* Nothing to do */
869             break;
870
871         case IO_METHOD_MMAP:
872         case IO_METHOD_USERPTR:
873             /* Some drivers 'hang' internally if this is not done before streamoff */
874             for( unsigned int i = 0; i < p_sys->i_nbuffers; i++ )
875             {
876                 memset( &buf, 0, sizeof(buf) );
877                 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
878                 buf.memory = ( p_sys->io == IO_METHOD_USERPTR ) ?
879                     V4L2_MEMORY_USERPTR : V4L2_MEMORY_MMAP;
880                 ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ); /* ignore result */
881             }
882
883             buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
884             if( ioctl( p_sys->i_fd_video, VIDIOC_STREAMOFF, &buf_type ) < 0 ) {
885                 msg_Err( p_this, "VIDIOC_STREAMOFF failed" );
886             }
887
888             break;
889         }
890     }
891
892     /* Free Video Buffers */
893     if( p_sys->p_buffers ) {
894         switch( p_sys->io )
895         {
896         case IO_METHOD_READ:
897             free( p_sys->p_buffers[0].start );
898             break;
899
900         case IO_METHOD_MMAP:
901             for( i = 0; i < p_sys->i_nbuffers; ++i )
902             {
903                 if( munmap( p_sys->p_buffers[i].start, p_sys->p_buffers[i].length ) )
904                 {
905                     msg_Err( p_this, "munmap failed" );
906                 }
907             }
908             break;
909
910         case IO_METHOD_USERPTR:
911             for( i = 0; i < p_sys->i_nbuffers; ++i )
912             {
913                free( p_sys->p_buffers[i].orig_userp );
914             }
915             break;
916         }
917         free( p_sys->p_buffers );
918     }
919
920     CommonClose( p_this, p_sys );
921 }
922
923 static void CommonClose( vlc_object_t *p_this, demux_sys_t *p_sys )
924 {
925     /* Close */
926     if( p_sys->i_fd_video >= 0 ) close( p_sys->i_fd_video );
927 #ifdef HAVE_ALSA
928     if( p_sys->p_alsa_pcm ) 
929     {
930         snd_pcm_close( p_sys->p_alsa_pcm );
931         p_sys->i_fd_audio = -1;
932     }
933 #endif
934     if( p_sys->i_fd_audio >= 0 ) close( p_sys->i_fd_audio );
935
936     if( p_sys->p_block_audio ) block_Release( p_sys->p_block_audio );
937     free( p_sys->psz_device );
938     free( p_sys->psz_vdev );
939     free( p_sys->psz_adev );
940     free( p_sys->p_standards );
941     free( p_sys->p_inputs );
942     free( p_sys->p_tuners );
943     free( p_sys->p_codecs );
944     free( p_sys->psz_requested_chroma );
945
946     free( p_sys );
947 }
948
949 /*****************************************************************************
950  * AccessOpen: opens v4l2 device, access2 callback
951  *****************************************************************************
952  *
953  * url: <video device>::::
954  *
955  *****************************************************************************/
956 static int AccessOpen( vlc_object_t * p_this )
957 {
958     access_t *p_access = (access_t*) p_this;
959     demux_sys_t * p_sys;
960
961     /* Only when selected */
962     if( *p_access->psz_access == '\0' ) return VLC_EGENERIC;
963
964     p_access->pf_read = AccessRead;
965     p_access->pf_block = NULL;
966     p_access->pf_seek = NULL;
967     p_access->pf_control = AccessControl;
968     p_access->info.i_update = 0;
969     p_access->info.i_size = 0;
970     p_access->info.i_pos = 0;
971     p_access->info.b_eof = VLC_FALSE;
972     p_access->info.i_title = 0;
973     p_access->info.i_seekpoint = 0;
974
975     p_sys = calloc( 1, sizeof( demux_sys_t ) );
976     p_access->p_sys = (access_sys_t *) p_sys;
977     if( p_sys == NULL ) return VLC_ENOMEM;
978
979     GetV4L2Params( p_sys, (vlc_object_t *) p_access );
980
981     ParseMRL( p_sys, p_access->psz_path, (vlc_object_t *) p_access );
982
983     if( FindMainDevice( p_this, p_sys, FIND_VIDEO,
984         VLC_FALSE, !strcmp( p_access->psz_access, "v4l2" ) ) != VLC_SUCCESS )
985     {
986         AccessClose( p_this );
987         return VLC_EGENERIC;
988     }
989
990     return VLC_SUCCESS;
991 }
992
993 /*****************************************************************************
994  * DemuxControl:
995  *****************************************************************************/
996 static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
997 {
998     demux_sys_t *p_sys = p_demux->p_sys;
999     vlc_bool_t *pb;
1000     int64_t    *pi64;
1001
1002     switch( i_query )
1003     {
1004         /* Special for access_demux */
1005         case DEMUX_CAN_PAUSE:
1006         case DEMUX_CAN_SEEK:
1007         case DEMUX_SET_PAUSE_STATE:
1008         case DEMUX_CAN_CONTROL_PACE:
1009             pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
1010             *pb = VLC_FALSE;
1011             return VLC_SUCCESS;
1012
1013         case DEMUX_GET_PTS_DELAY:
1014             pi64 = (int64_t*)va_arg( args, int64_t * );
1015             *pi64 = (int64_t)p_sys->i_pts * 1000;
1016             return VLC_SUCCESS;
1017
1018         case DEMUX_GET_TIME:
1019             pi64 = (int64_t*)va_arg( args, int64_t * );
1020             *pi64 = mdate();
1021             return VLC_SUCCESS;
1022
1023         /* TODO implement others */
1024         default:
1025             return VLC_EGENERIC;
1026     }
1027
1028     return VLC_EGENERIC;
1029 }
1030
1031 /*****************************************************************************
1032  * AccessControl: access2 callback
1033  *****************************************************************************/
1034 static int AccessControl( access_t *p_access, int i_query, va_list args )
1035 {
1036     vlc_bool_t   *pb_bool;
1037     int          *pi_int;
1038     int64_t      *pi_64;
1039     demux_sys_t  *p_sys = (demux_sys_t *) p_access->p_sys;
1040
1041     switch( i_query )
1042     {
1043         /* */
1044         case ACCESS_CAN_SEEK:
1045         case ACCESS_CAN_FASTSEEK:
1046             pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
1047             *pb_bool = VLC_FALSE;
1048             break;
1049         case ACCESS_CAN_PAUSE:
1050             pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
1051             *pb_bool = VLC_FALSE;
1052             break;
1053         case ACCESS_CAN_CONTROL_PACE:
1054             pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
1055             *pb_bool = VLC_FALSE;
1056             break;
1057
1058         /* */
1059         case ACCESS_GET_MTU:
1060             pi_int = (int*)va_arg( args, int * );
1061             *pi_int = 0;
1062             break;
1063
1064         case ACCESS_GET_PTS_DELAY:
1065             pi_64 = (int64_t*)va_arg( args, int64_t * );
1066             *pi_64 = (int64_t) p_sys->i_pts * 1000;
1067             break;
1068
1069         /* */
1070         case ACCESS_SET_PAUSE_STATE:
1071             /* Nothing to do */
1072             break;
1073
1074         case ACCESS_GET_TITLE_INFO:
1075         case ACCESS_SET_TITLE:
1076         case ACCESS_SET_SEEKPOINT:
1077         case ACCESS_SET_PRIVATE_ID_STATE:
1078         case ACCESS_GET_CONTENT_TYPE:
1079         case ACCESS_GET_META:
1080             return VLC_EGENERIC;
1081
1082         default:
1083             msg_Warn( p_access, "Unimplemented query in control(%d).", i_query);
1084             return VLC_EGENERIC;
1085
1086     }
1087     return VLC_SUCCESS;
1088 }
1089
1090 /*****************************************************************************
1091  * AccessRead: access2 callback
1092  ******************************************************************************/
1093 static ssize_t AccessRead( access_t * p_access, uint8_t * p_buffer, size_t i_len )
1094 {
1095     demux_sys_t *p_sys = (demux_sys_t *) p_access->p_sys;
1096     struct pollfd ufd;
1097     int i_ret;
1098
1099     ufd.fd = p_sys->i_fd_video;
1100     ufd.events = POLLIN;
1101
1102     if( p_access->info.b_eof )
1103         return 0;
1104
1105     do
1106     {
1107         if( p_access->b_die )
1108             return 0;
1109
1110         ufd.revents = 0;
1111     }
1112     while( ( i_ret = poll( &ufd, 1, 500 ) ) == 0 );
1113
1114     if( i_ret < 0 )
1115     {
1116         msg_Err( p_access, "Polling error (%m)." );
1117         return -1;
1118     }
1119
1120     i_ret = read( p_sys->i_fd_video, p_buffer, i_len );
1121     if( i_ret == 0 )
1122     {
1123         p_access->info.b_eof = VLC_TRUE;
1124     }
1125     else if( i_ret > 0 )
1126     {
1127         p_access->info.i_pos += i_ret;
1128     }
1129
1130     return i_ret;
1131 }
1132
1133 /*****************************************************************************
1134  * Demux: Processes the audio or video frame
1135  *****************************************************************************/
1136 static int Demux( demux_t *p_demux )
1137 {
1138     demux_sys_t *p_sys = p_demux->p_sys;
1139     es_out_id_t *p_es = p_sys->p_es_audio;
1140     block_t *p_block = NULL;
1141
1142     /* Try grabbing audio frames first */
1143     if( p_sys->i_fd_audio < 0 || !( p_block = GrabAudio( p_demux ) ) )
1144     {
1145         /* Try grabbing video frame */
1146         p_es = p_sys->p_es_video;
1147         if( p_sys->i_fd_video > 0 ) p_block = GrabVideo( p_demux );
1148     }
1149
1150     if( !p_block )
1151     {
1152         /* Sleep so we do not consume all the cpu, 10ms seems
1153          * like a good value (100fps) */
1154         msleep( 10 );
1155         return 1;
1156     }
1157
1158     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
1159     es_out_Send( p_demux->out, p_es, p_block );
1160
1161     return 1;
1162 }
1163
1164 /*****************************************************************************
1165  * GrabVideo: Grab a video frame
1166  *****************************************************************************/
1167 static block_t* GrabVideo( demux_t *p_demux )
1168 {
1169     demux_sys_t *p_sys = p_demux->p_sys;
1170
1171     block_t *p_block = NULL;
1172     struct v4l2_buffer buf;
1173     ssize_t i_ret;
1174
1175     if( p_sys->f_fps >= 0.1 && p_sys->i_video_pts > 0 )
1176     {
1177         mtime_t i_dur = (mtime_t)((double)1000000 / (double)p_sys->f_fps);
1178
1179         /* Did we wait long enough ? (frame rate reduction) */
1180         if( p_sys->i_video_pts + i_dur > mdate() ) return 0;
1181     }
1182
1183     /* Grab Video Frame */
1184     switch( p_sys->io )
1185     {
1186     case IO_METHOD_READ:
1187         i_ret = read( p_sys->i_fd_video, p_sys->p_buffers[0].start, p_sys->p_buffers[0].length );
1188         if( i_ret == -1 )
1189         {
1190             switch( errno )
1191             {
1192             case EAGAIN:
1193                 return 0;
1194             case EIO:
1195                 /* Could ignore EIO, see spec. */
1196                 /* fall through */
1197             default:
1198                 msg_Err( p_demux, "Failed to read frame" );
1199                 return 0;
1200                }
1201         }
1202
1203         p_block = ProcessVideoFrame( p_demux, (uint8_t*)p_sys->p_buffers[0].start, i_ret );
1204         if( !p_block ) return 0;
1205
1206         break;
1207
1208     case IO_METHOD_MMAP:
1209         memset( &buf, 0, sizeof(buf) );
1210         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1211         buf.memory = V4L2_MEMORY_MMAP;
1212
1213         /* Wait for next frame */
1214         if (ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ) < 0 )
1215         {
1216             switch( errno )
1217             {
1218             case EAGAIN:
1219                 return 0;
1220             case EIO:
1221                 /* Could ignore EIO, see spec. */
1222                 /* fall through */
1223             default:
1224                 msg_Err( p_demux, "Failed to wait (VIDIOC_DQBUF)" );
1225                 return 0;
1226                }
1227         }
1228
1229         if( buf.index >= p_sys->i_nbuffers ) {
1230             msg_Err( p_demux, "Failed capturing new frame as i>=nbuffers" );
1231             return 0;
1232         }
1233
1234         p_block = ProcessVideoFrame( p_demux, p_sys->p_buffers[buf.index].start, buf.bytesused );
1235         if( !p_block ) return 0;
1236
1237         /* Unlock */
1238         if( ioctl( p_sys->i_fd_video, VIDIOC_QBUF, &buf ) < 0 )
1239         {
1240             msg_Err (p_demux, "Failed to unlock (VIDIOC_QBUF)");
1241             return 0;
1242         }
1243
1244         break;
1245
1246     case IO_METHOD_USERPTR:
1247         memset( &buf, 0, sizeof(buf) );
1248         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1249         buf.memory = V4L2_MEMORY_USERPTR;
1250
1251         /* Wait for next frame */
1252         if (ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ) < 0 )
1253         {
1254             switch( errno )
1255             {
1256             case EAGAIN:
1257                 return 0;
1258             case EIO:
1259                 /* Could ignore EIO, see spec. */
1260                 /* fall through */
1261             default:
1262                 msg_Err( p_demux, "Failed to wait (VIDIOC_DQBUF)" );
1263                 return 0;
1264             }
1265         }
1266
1267         /* Find frame? */
1268         unsigned int i;
1269         for( i = 0; i < p_sys->i_nbuffers; i++ )
1270         {
1271             if( buf.m.userptr == (unsigned long)p_sys->p_buffers[i].start &&
1272                 buf.length == p_sys->p_buffers[i].length ) break;
1273         }
1274
1275         if( i >= p_sys->i_nbuffers )
1276         {
1277             msg_Err( p_demux, "Failed capturing new frame as i>=nbuffers" );
1278             return 0;
1279         }
1280
1281         p_block = ProcessVideoFrame( p_demux, (uint8_t*)buf.m.userptr, buf.bytesused );
1282         if( !p_block ) return 0;
1283
1284         /* Unlock */
1285         if( ioctl( p_sys->i_fd_video, VIDIOC_QBUF, &buf ) < 0 )
1286         {
1287             msg_Err (p_demux, "Failed to unlock (VIDIOC_QBUF)");
1288             return 0;
1289         }
1290
1291         break;
1292
1293     }
1294
1295     /* Timestamp */
1296     p_sys->i_video_pts = p_block->i_pts = p_block->i_dts = mdate();
1297
1298     return p_block;
1299 }
1300
1301 /*****************************************************************************
1302  * ProcessVideoFrame: Helper function to take a buffer and copy it into
1303  * a new block
1304  *****************************************************************************/
1305 static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame, size_t i_size )
1306 {
1307     block_t *p_block;
1308
1309     if( !p_frame ) return 0;
1310
1311     /* New block */
1312     if( !( p_block = block_New( p_demux, i_size ) ) )
1313     {
1314         msg_Warn( p_demux, "Cannot get new block" );
1315         return 0;
1316     }
1317
1318     /* Copy frame */
1319     memcpy( p_block->p_buffer, p_frame, i_size );
1320
1321     return p_block;
1322 }
1323
1324 /*****************************************************************************
1325  * GrabAudio: Grab an audio frame
1326  *****************************************************************************/
1327 static block_t* GrabAudio( demux_t *p_demux )
1328 {
1329     demux_sys_t *p_sys = p_demux->p_sys;
1330     struct audio_buf_info buf_info;
1331     int i_read = 0, i_correct;
1332     block_t *p_block;
1333
1334     if( p_sys->p_block_audio ) p_block = p_sys->p_block_audio;
1335     else p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
1336
1337     if( !p_block )
1338     {
1339         msg_Warn( p_demux, "cannot get block" );
1340         return 0;
1341     }
1342
1343     p_sys->p_block_audio = p_block;
1344
1345 #ifdef HAVE_ALSA
1346     if( p_sys->i_audio_method & AUDIO_METHOD_ALSA )
1347     {
1348         /* ALSA */
1349         i_read = snd_pcm_readi( p_sys->p_alsa_pcm, p_block->p_buffer, p_sys->i_alsa_chunk_size );
1350         if( i_read <= 0 )
1351         {
1352             int i_resume;
1353             switch( i_read )
1354             {
1355                 case -EAGAIN:
1356                     break;
1357                 case -EPIPE:
1358                     /* xrun */
1359                     snd_pcm_prepare( p_sys->p_alsa_pcm );
1360                     break;
1361                 case -ESTRPIPE:
1362                     /* suspend */
1363                     i_resume = snd_pcm_resume( p_sys->p_alsa_pcm );
1364                     if( i_resume < 0 && i_resume != -EAGAIN ) snd_pcm_prepare( p_sys->p_alsa_pcm );
1365                     break;
1366                 default:
1367                     msg_Err( p_demux, "Failed to read alsa frame (%s)", snd_strerror( i_read ) );
1368                     return 0;
1369             }
1370         }
1371         else
1372         {
1373             /* convert from frames to bytes */
1374             i_read *= p_sys->i_alsa_frame_size;
1375         }
1376     }
1377     else
1378 #endif
1379     if( p_sys->i_audio_method & AUDIO_METHOD_OSS )
1380     {
1381         /* OSS */
1382         i_read = read( p_sys->i_fd_audio, p_block->p_buffer,
1383                     p_sys->i_audio_max_frame_size );
1384     }
1385
1386     if( i_read <= 0 ) return 0;
1387
1388     p_block->i_buffer = i_read;
1389     p_sys->p_block_audio = 0;
1390
1391     /* Correct the date because of kernel buffering */
1392     i_correct = i_read;
1393     if( p_sys->i_audio_method & AUDIO_METHOD_OSS )
1394     {
1395         /* OSS */
1396         if( ioctl( p_sys->i_fd_audio, SNDCTL_DSP_GETISPACE, &buf_info ) == 0 )
1397         {
1398             i_correct += buf_info.bytes;
1399         }
1400     }
1401 #ifdef HAVE_ALSA
1402     else if( p_sys->i_audio_method & AUDIO_METHOD_ALSA )
1403     {
1404         /* ALSA */
1405         int i_err;
1406         snd_pcm_sframes_t delay = 0;
1407         if( ( i_err = snd_pcm_delay( p_sys->p_alsa_pcm, &delay ) ) >= 0 )
1408         {
1409             size_t i_correction_delta = delay * p_sys->i_alsa_frame_size;
1410             /* Test for overrun */
1411             if( i_correction_delta > p_sys->i_audio_max_frame_size )
1412             {
1413                 msg_Warn( p_demux, "ALSA read overrun (%d > %d)",
1414                           i_correction_delta, p_sys->i_audio_max_frame_size );
1415                 i_correction_delta = p_sys->i_audio_max_frame_size;
1416                 snd_pcm_prepare( p_sys->p_alsa_pcm );
1417             }
1418             i_correct += i_correction_delta;
1419         }
1420         else
1421         {
1422             /* delay failed so reset */
1423             msg_Warn( p_demux, "ALSA snd_pcm_delay failed (%s)", snd_strerror( i_err ) );
1424             snd_pcm_prepare( p_sys->p_alsa_pcm );
1425         }
1426     }
1427 #endif
1428
1429     /* Timestamp */
1430     p_block->i_pts = p_block->i_dts =
1431         mdate() - I64C(1000000) * (mtime_t)i_correct /
1432         2 / ( p_sys->b_stereo ? 2 : 1) / p_sys->i_sample_rate;
1433
1434     return p_block;
1435 }
1436
1437 /*****************************************************************************
1438  * Helper function to initalise video IO using the Read method
1439  *****************************************************************************/
1440 static int InitRead( demux_t *p_demux, int i_fd, unsigned int i_buffer_size )
1441 {
1442     demux_sys_t *p_sys = p_demux->p_sys;
1443
1444     p_sys->p_buffers = calloc( 1, sizeof( *p_sys->p_buffers ) );
1445     if( !p_sys->p_buffers )
1446     {
1447         msg_Err( p_demux, "Out of memory" );
1448         goto open_failed;
1449     }
1450
1451     p_sys->p_buffers[0].length = i_buffer_size;
1452     p_sys->p_buffers[0].start = malloc( i_buffer_size );
1453     if( !p_sys->p_buffers[0].start )
1454     {
1455         msg_Err( p_demux, "Out of memory" );
1456         goto open_failed;
1457     }
1458
1459     return VLC_SUCCESS;
1460
1461 open_failed:
1462     return VLC_EGENERIC;
1463
1464 }
1465
1466 /*****************************************************************************
1467  * Helper function to initalise video IO using the mmap method
1468  *****************************************************************************/
1469 static int InitMmap( demux_t *p_demux, int i_fd )
1470 {
1471     demux_sys_t *p_sys = p_demux->p_sys;
1472     struct v4l2_requestbuffers req;
1473
1474     memset( &req, 0, sizeof(req) );
1475     req.count = 4;
1476     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1477     req.memory = V4L2_MEMORY_MMAP;
1478
1479     if( ioctl( i_fd, VIDIOC_REQBUFS, &req ) < 0 )
1480     {
1481         msg_Err( p_demux, "device does not support mmap i/o" );
1482         goto open_failed;
1483     }
1484
1485     if( req.count < 2 )
1486     {
1487         msg_Err( p_demux, "Insufficient buffer memory" );
1488         goto open_failed;
1489     }
1490
1491     p_sys->p_buffers = calloc( req.count, sizeof( *p_sys->p_buffers ) );
1492     if( !p_sys->p_buffers )
1493     {
1494         msg_Err( p_demux, "Out of memory" );
1495         goto open_failed;
1496     }
1497
1498     for( p_sys->i_nbuffers = 0; p_sys->i_nbuffers < req.count; ++p_sys->i_nbuffers )
1499     {
1500         struct v4l2_buffer buf;
1501
1502         memset( &buf, 0, sizeof(buf) );
1503         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1504         buf.memory = V4L2_MEMORY_MMAP;
1505         buf.index = p_sys->i_nbuffers;
1506
1507         if( ioctl( i_fd, VIDIOC_QUERYBUF, &buf ) < 0 )
1508         {
1509             msg_Err( p_demux, "VIDIOC_QUERYBUF" );
1510             goto open_failed;
1511         }
1512
1513         p_sys->p_buffers[p_sys->i_nbuffers].length = buf.length;
1514         p_sys->p_buffers[p_sys->i_nbuffers].start =
1515             mmap( NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, i_fd, buf.m.offset );
1516
1517         if( p_sys->p_buffers[p_sys->i_nbuffers].start == MAP_FAILED )
1518         {
1519             msg_Err( p_demux, "mmap failed (%m)" );
1520             goto open_failed;
1521         }
1522     }
1523
1524     return VLC_SUCCESS;
1525
1526 open_failed:
1527     return VLC_EGENERIC;
1528
1529 }
1530
1531 /*****************************************************************************
1532  * Helper function to initalise video IO using the userbuf method
1533  *****************************************************************************/
1534 static int InitUserP( demux_t *p_demux, int i_fd, unsigned int i_buffer_size )
1535 {
1536     demux_sys_t *p_sys = p_demux->p_sys;
1537     struct v4l2_requestbuffers req;
1538     unsigned int i_page_size;
1539
1540     i_page_size = getpagesize();
1541     i_buffer_size = ( i_buffer_size + i_page_size - 1 ) & ~( i_page_size - 1);
1542
1543     memset( &req, 0, sizeof(req) );
1544     req.count = 4;
1545     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1546     req.memory = V4L2_MEMORY_USERPTR;
1547
1548     if( ioctl( i_fd, VIDIOC_REQBUFS, &req ) < 0 )
1549     {
1550         msg_Err( p_demux, "device does not support user pointer i/o" );
1551         goto open_failed;
1552     }
1553
1554     p_sys->p_buffers = calloc( 4, sizeof( *p_sys->p_buffers ) );
1555     if( !p_sys->p_buffers )
1556     {
1557         msg_Err( p_demux, "Out of memory" );
1558         goto open_failed;
1559     }
1560
1561     for( p_sys->i_nbuffers = 0; p_sys->i_nbuffers < 4; ++p_sys->i_nbuffers )
1562     {
1563         p_sys->p_buffers[p_sys->i_nbuffers].length = i_buffer_size;
1564         p_sys->p_buffers[p_sys->i_nbuffers].start =
1565             vlc_memalign( &p_sys->p_buffers[p_sys->i_nbuffers].orig_userp,
1566                 /* boundary */ i_page_size, i_buffer_size );
1567
1568         if( !p_sys->p_buffers[p_sys->i_nbuffers].start )
1569         {
1570             msg_Err( p_demux, "out of memory" );
1571             goto open_failed;
1572         }
1573     }
1574
1575     return VLC_SUCCESS;
1576
1577 open_failed:
1578     return VLC_EGENERIC;
1579
1580 }
1581
1582 /*****************************************************************************
1583  * IsPixelFormatSupported: returns true if the specified V4L2 pixel format is
1584  * in the array of supported formats returned by the driver
1585  *****************************************************************************/
1586 static vlc_bool_t IsPixelFormatSupported( demux_t *p_demux, unsigned int i_pixelformat )
1587 {
1588     demux_sys_t *p_sys = p_demux->p_sys;
1589
1590     for( int i_index = 0; i_index < p_sys->i_codec; i_index++ )
1591     {
1592         if( p_sys->p_codecs[i_index].pixelformat == i_pixelformat ) return VLC_TRUE;
1593     }
1594
1595     return VLC_FALSE;
1596 }
1597
1598 /*****************************************************************************
1599  * OpenVideoDev: open and set up the video device and probe for capabilities
1600  *****************************************************************************/
1601 static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, vlc_bool_t b_demux )
1602 {
1603     int i_fd;
1604     struct v4l2_cropcap cropcap;
1605     struct v4l2_crop crop;
1606     struct v4l2_format fmt;
1607     unsigned int i_min;
1608     enum v4l2_buf_type buf_type;
1609     char *psz_device = p_sys->psz_vdev;
1610
1611     if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 )
1612     {
1613         msg_Err( p_obj, "cannot open device (%m)" );
1614         goto open_failed;
1615     }
1616
1617     /* Select standard */
1618
1619     if( p_sys->i_selected_standard_id != V4L2_STD_UNKNOWN )
1620     {
1621         if( ioctl( i_fd, VIDIOC_S_STD, &p_sys->i_selected_standard_id ) < 0 )
1622         {
1623             msg_Err( p_obj, "cannot set standard (%m)" );
1624             goto open_failed;
1625         }
1626         msg_Dbg( p_obj, "Set standard" );
1627     }
1628
1629     /* Select input */
1630
1631     if( p_sys->i_selected_input > p_sys->i_input )
1632     {
1633         msg_Warn( p_obj, "invalid input. Using the default one" );
1634         p_sys->i_selected_input = 0;
1635     }
1636
1637     if( ioctl( i_fd, VIDIOC_S_INPUT, &p_sys->i_selected_input ) < 0 )
1638     {
1639         msg_Err( p_obj, "cannot set input (%m)" );
1640         goto open_failed;
1641     }
1642
1643     /* TODO: Move the resolution stuff up here */
1644     /* if MPEG encoder card, no need to do anything else after this */
1645     ControlList( p_obj, i_fd,
1646                   var_GetBool( p_obj, "v4l2-controls-reset" ), b_demux );
1647     if( VLC_FALSE == b_demux)
1648     {
1649         return i_fd;
1650     }
1651
1652     demux_t *p_demux = (demux_t *) p_obj;
1653
1654     /* Verify device support for the various IO methods */
1655     switch( p_sys->io )
1656     {
1657         case IO_METHOD_READ:
1658             if( !(p_sys->dev_cap.capabilities & V4L2_CAP_READWRITE) )
1659             {
1660                 msg_Err( p_demux, "device does not support read i/o" );
1661                 goto open_failed;
1662             }
1663             break;
1664
1665         case IO_METHOD_MMAP:
1666         case IO_METHOD_USERPTR:
1667             if( !(p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING) )
1668             {
1669                 msg_Err( p_demux, "device does not support streaming i/o" );
1670                 goto open_failed;
1671             }
1672             break;
1673
1674         default:
1675             msg_Err( p_demux, "io method not supported" );
1676             goto open_failed;
1677     }
1678
1679     /* Reset Cropping */
1680     memset( &cropcap, 0, sizeof(cropcap) );
1681     cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1682     if( ioctl( i_fd, VIDIOC_CROPCAP, &cropcap ) >= 0 )
1683     {
1684         crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1685         crop.c = cropcap.defrect; /* reset to default */
1686         if( ioctl( i_fd, VIDIOC_S_CROP, &crop ) < 0 )
1687         {
1688             switch( errno )
1689             {
1690                 case EINVAL:
1691                     /* Cropping not supported. */
1692                     break;
1693                 default:
1694                     /* Errors ignored. */
1695                     break;
1696             }
1697         }
1698     }
1699
1700     /* Try and find default resolution if not specified */
1701     memset( &fmt, 0, sizeof(fmt) );
1702     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1703
1704     if( p_sys->i_width <= 0 || p_sys->i_height <= 0 )
1705     {
1706         if( ioctl( i_fd, VIDIOC_G_FMT, &fmt ) < 0 )
1707         {
1708             msg_Err( p_demux, "Cannot get default width and height." );
1709             goto open_failed;
1710         }
1711
1712         p_sys->i_width = fmt.fmt.pix.width;
1713         p_sys->i_height = fmt.fmt.pix.height;
1714
1715         if( fmt.fmt.pix.field == V4L2_FIELD_ALTERNATE )
1716         {
1717             p_sys->i_height = p_sys->i_height * 2;
1718         }
1719     }
1720     else
1721     {
1722         msg_Dbg( p_demux, "trying specified size %dx%d", p_sys->i_width, p_sys->i_height );
1723     }
1724
1725     fmt.fmt.pix.width = p_sys->i_width;
1726     fmt.fmt.pix.height = p_sys->i_height;
1727     fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
1728
1729     /* Test and set Chroma */
1730     fmt.fmt.pix.pixelformat = 0;
1731     if( p_sys->psz_requested_chroma && strlen( p_sys->psz_requested_chroma ) > 0 )
1732     {
1733         /* User specified chroma */
1734         if( strlen( p_sys->psz_requested_chroma ) >= 4 )
1735         {
1736             int i_requested_fourcc = VLC_FOURCC(
1737                 p_sys->psz_requested_chroma[0], p_sys->psz_requested_chroma[1],
1738                 p_sys->psz_requested_chroma[2], p_sys->psz_requested_chroma[3] );
1739             for( int i = 0; v4l2chroma_to_fourcc[i].i_v4l2 != 0; i++ )
1740             {
1741                 if( v4l2chroma_to_fourcc[i].i_fourcc == i_requested_fourcc )
1742                 {
1743                     fmt.fmt.pix.pixelformat = v4l2chroma_to_fourcc[i].i_v4l2;
1744                     break;
1745                 }
1746             }
1747         }
1748         /* Try and set user chroma */
1749         if( !IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ) || ( fmt.fmt.pix.pixelformat && ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 ) )
1750         {
1751             msg_Warn( p_demux, "Driver is unable to use specified chroma %s. Trying defaults.", p_sys->psz_requested_chroma );
1752             fmt.fmt.pix.pixelformat = 0;
1753         }
1754     }
1755
1756     /* If no user specified chroma, find best */
1757     /* This also decides if MPEG encoder card or not */
1758     if( !fmt.fmt.pix.pixelformat )
1759     {
1760         fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
1761         if( !IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ) || ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 )
1762         {
1763             fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
1764             if( !IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ) || ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 )
1765             {
1766                 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1767                 if( !IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ) || ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 )
1768                 {
1769                     msg_Warn( p_demux, "Could not select any of the default chromas; attempting to open as MPEG encoder card (access2)" );
1770                     goto open_failed;
1771                 }
1772             }
1773         }
1774     }
1775
1776     /* Reassign width, height and chroma incase driver override */
1777     p_sys->i_width = fmt.fmt.pix.width;
1778     p_sys->i_height = fmt.fmt.pix.height;
1779
1780     /* Look up final fourcc */
1781     p_sys->i_fourcc = 0;
1782     for( int i = 0; v4l2chroma_to_fourcc[i].i_fourcc != 0; i++ )
1783     {
1784         if( v4l2chroma_to_fourcc[i].i_v4l2 == fmt.fmt.pix.pixelformat )
1785         {
1786             p_sys->i_fourcc = v4l2chroma_to_fourcc[i].i_fourcc;
1787             break;
1788         }
1789     }
1790
1791     /* Buggy driver paranoia */
1792     i_min = fmt.fmt.pix.width * 2;
1793     if( fmt.fmt.pix.bytesperline < i_min )
1794         fmt.fmt.pix.bytesperline = i_min;
1795     i_min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
1796     if( fmt.fmt.pix.sizeimage < i_min )
1797         fmt.fmt.pix.sizeimage = i_min;
1798
1799 #ifdef VIDIOC_ENUM_FRAMEINTERVALS
1800     /* This is new in Linux 2.6.19 */
1801     /* List supported frame rates */
1802     struct v4l2_frmivalenum frmival;
1803     frmival.index = 0;
1804     frmival.pixel_format = fmt.fmt.pix.pixelformat;
1805     frmival.width = p_sys->i_width;
1806     frmival.height = p_sys->i_height;
1807     if( ioctl( i_fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival ) >= 0 )
1808     {
1809         char sz_fourcc[5];
1810         memset( &sz_fourcc, 0, sizeof( sz_fourcc ) );
1811         vlc_fourcc_to_char( p_sys->i_fourcc, &sz_fourcc );
1812         msg_Dbg( p_demux, "supported frame intervals for %4s, %dx%d:",
1813                  sz_fourcc, frmival.width, frmival.height );
1814         switch( frmival.type )
1815         {
1816             case V4L2_FRMIVAL_TYPE_DISCRETE:
1817                 do
1818                 {
1819                     msg_Dbg( p_demux, "    supported frame interval: %d/%d",
1820                              frmival.discrete.numerator,
1821                              frmival.discrete.denominator );
1822                     frmival.index++;
1823                 } while( ioctl( i_fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival ) >= 0 );
1824                 break;
1825             case V4L2_FRMIVAL_TYPE_STEPWISE:
1826                 msg_Dbg( p_demux, "    supported frame intervals: %d/%d to "
1827                          "%d/%d using %d/%d increments",
1828                          frmival.stepwise.min.numerator,
1829                          frmival.stepwise.min.denominator,
1830                          frmival.stepwise.max.numerator,
1831                          frmival.stepwise.max.denominator,
1832                          frmival.stepwise.step.numerator,
1833                          frmival.stepwise.step.denominator );
1834                 break;
1835             case V4L2_FRMIVAL_TYPE_CONTINUOUS:
1836                 msg_Dbg( p_demux, "    supported frame intervals: %d/%d to %d/%d",
1837                          frmival.stepwise.min.numerator,
1838                          frmival.stepwise.min.denominator,
1839                          frmival.stepwise.max.numerator,
1840                          frmival.stepwise.max.denominator );
1841                 break;
1842         }
1843     }
1844 #endif
1845
1846     /* Init IO method */
1847     switch( p_sys->io )
1848     {
1849     case IO_METHOD_READ:
1850         if( InitRead( p_demux, i_fd, fmt.fmt.pix.sizeimage ) != VLC_SUCCESS ) goto open_failed;
1851         break;
1852
1853     case IO_METHOD_MMAP:
1854         if( InitMmap( p_demux, i_fd ) != VLC_SUCCESS ) goto open_failed;
1855         break;
1856
1857     case IO_METHOD_USERPTR:
1858         if( InitUserP( p_demux, i_fd, fmt.fmt.pix.sizeimage ) != VLC_SUCCESS ) goto open_failed;
1859         break;
1860
1861     }
1862
1863     /* Add */
1864     es_format_t es_fmt;
1865     es_format_Init( &es_fmt, VIDEO_ES, p_sys->i_fourcc );
1866     es_fmt.video.i_width  = p_sys->i_width;
1867     es_fmt.video.i_height = p_sys->i_height;
1868     es_fmt.video.i_aspect = 4 * VOUT_ASPECT_FACTOR / 3;
1869
1870     /* Setup rgb mask for RGB formats */
1871     if( p_sys->i_fourcc == VLC_FOURCC( 'R','V','2','4' ) )
1872     {
1873         /* This is in BGR format */
1874         es_fmt.video.i_bmask = 0x00ff0000;
1875         es_fmt.video.i_gmask = 0x0000ff00;
1876         es_fmt.video.i_rmask = 0x000000ff;
1877     }
1878
1879     msg_Dbg( p_demux, "added new video es %4.4s %dx%d",
1880         (char*)&es_fmt.i_codec, es_fmt.video.i_width, es_fmt.video.i_height );
1881     p_sys->p_es_video = es_out_Add( p_demux->out, &es_fmt );
1882
1883     /* Start Capture */
1884
1885     switch( p_sys->io )
1886     {
1887     case IO_METHOD_READ:
1888         /* Nothing to do */
1889         break;
1890
1891     case IO_METHOD_MMAP:
1892         for (unsigned int i = 0; i < p_sys->i_nbuffers; ++i)
1893         {
1894             struct v4l2_buffer buf;
1895
1896             memset( &buf, 0, sizeof(buf) );
1897             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1898             buf.memory = V4L2_MEMORY_MMAP;
1899             buf.index = i;
1900
1901             if( ioctl( i_fd, VIDIOC_QBUF, &buf ) < 0 )
1902             {
1903                 msg_Err( p_demux, "VIDIOC_QBUF failed" );
1904                 goto open_failed;
1905             }
1906         }
1907
1908         buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1909         if( ioctl( i_fd, VIDIOC_STREAMON, &buf_type ) < 0 )
1910         {
1911             msg_Err( p_demux, "VIDIOC_STREAMON failed" );
1912             goto open_failed;
1913         }
1914
1915         break;
1916
1917     case IO_METHOD_USERPTR:
1918         for( unsigned int i = 0; i < p_sys->i_nbuffers; ++i )
1919         {
1920             struct v4l2_buffer buf;
1921
1922             memset( &buf, 0, sizeof(buf) );
1923             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1924             buf.memory = V4L2_MEMORY_USERPTR;
1925             buf.index = i;
1926             buf.m.userptr = (unsigned long)p_sys->p_buffers[i].start;
1927             buf.length = p_sys->p_buffers[i].length;
1928
1929             if( ioctl( i_fd, VIDIOC_QBUF, &buf ) < 0 )
1930             {
1931                 msg_Err( p_demux, "VIDIOC_QBUF failed" );
1932                 goto open_failed;
1933             }
1934         }
1935
1936         buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1937         if( ioctl( i_fd, VIDIOC_STREAMON, &buf_type ) < 0 )
1938         {
1939             msg_Err( p_demux, "VIDIOC_STREAMON failed" );
1940             goto open_failed;
1941         }
1942
1943         break;
1944     }
1945
1946     /* report fps */
1947     if( p_sys->f_fps >= 0.1 )
1948     {
1949         msg_Dbg( p_demux, "User set fps=%f", p_sys->f_fps );
1950     }
1951
1952     return i_fd;
1953
1954 open_failed:
1955     if( i_fd >= 0 ) close( i_fd );
1956     return -1;
1957
1958 }
1959
1960 #ifdef HAVE_ALSA
1961 /*****************************************************************************
1962  * ResolveALSADeviceName: Change any . to : in the ALSA device name
1963  *****************************************************************************/
1964 static char *ResolveALSADeviceName( const char *psz_device )
1965 {
1966     char* psz_alsa_name = strdup( psz_device );
1967     for( unsigned int i = 0; i < strlen( psz_device ); i++ )
1968     {
1969         if( psz_alsa_name[i] == '.' ) psz_alsa_name[i] = ':';
1970     }
1971     return psz_alsa_name;
1972 }
1973 #endif
1974
1975 /*****************************************************************************
1976  * OpenAudioDev: open and set up the audio device and probe for capabilities
1977  *****************************************************************************/
1978 #ifdef HAVE_ALSA
1979 static int OpenAudioDevAlsa( vlc_object_t *p_this, demux_sys_t *p_sys,
1980                              vlc_bool_t b_demux )
1981 {
1982     char *psz_device = p_sys->psz_adev;
1983     int i_fd = 0;
1984     p_sys->p_alsa_pcm = NULL;
1985     char* psz_alsa_device_name = NULL;
1986     snd_pcm_hw_params_t *p_hw_params = NULL;
1987     snd_pcm_uframes_t buffer_size;
1988     snd_pcm_uframes_t chunk_size;
1989
1990     /* ALSA */
1991     int i_err;
1992     psz_alsa_device_name =
1993         ResolveALSADeviceName( psz_device?: ALSA_DEFAULT );
1994
1995     if( ( i_err = snd_pcm_open( &p_sys->p_alsa_pcm, psz_alsa_device_name,
1996         SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK ) ) < 0)
1997     {
1998         msg_Err( p_this, "Cannot open ALSA audio device %s (%s)",
1999                  psz_alsa_device_name, snd_strerror( i_err ) );
2000         goto adev_fail;
2001     }
2002
2003     if( ( i_err = snd_pcm_nonblock( p_sys->p_alsa_pcm, 1 ) ) < 0)
2004     {
2005         msg_Err( p_this, "Cannot set ALSA nonblock (%s)",
2006                  snd_strerror( i_err ) );
2007         goto adev_fail;
2008     }
2009
2010     /* Begin setting hardware parameters */
2011
2012     if( ( i_err = snd_pcm_hw_params_malloc( &p_hw_params ) ) < 0 )
2013     {
2014         msg_Err( p_this,
2015                  "ALSA: cannot allocate hardware parameter structure (%s)",
2016                  snd_strerror( i_err ) );
2017         goto adev_fail;
2018     }
2019
2020     if( ( i_err = snd_pcm_hw_params_any( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
2021     {
2022         msg_Err( p_this,
2023                 "ALSA: cannot initialize hardware parameter structure (%s)",
2024                  snd_strerror( i_err ) );
2025         goto adev_fail;
2026     }
2027
2028     /* Set Interleaved access */
2029     if( ( i_err = snd_pcm_hw_params_set_access( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
2030     {
2031         msg_Err( p_this, "ALSA: cannot set access type (%s)",
2032                  snd_strerror( i_err ) );
2033         goto adev_fail;
2034     }
2035
2036     /* Set 16 bit little endian */
2037     if( ( i_err = snd_pcm_hw_params_set_format( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_FORMAT_S16_LE ) ) < 0 )
2038     {
2039         msg_Err( p_this, "ALSA: cannot set sample format (%s)",
2040                  snd_strerror( i_err ) );
2041         goto adev_fail;
2042     }
2043
2044     /* Set sample rate */
2045 #ifdef HAVE_ALSA_NEW_API
2046     i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, &p_sys->i_sample_rate, NULL );
2047 #else
2048     i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, p_sys->i_sample_rate, NULL );
2049 #endif
2050     if( i_err < 0 )
2051     {
2052         msg_Err( p_this, "ALSA: cannot set sample rate (%s)",
2053                  snd_strerror( i_err ) );
2054         goto adev_fail;
2055     }
2056
2057     /* Set channels */
2058     unsigned int channels = p_sys->b_stereo ? 2 : 1;
2059     if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
2060     {
2061         channels = ( channels==1 ) ? 2 : 1;
2062         msg_Warn( p_this, "ALSA: cannot set channel count (%s). "
2063                   "Trying with channels=%d",
2064                   snd_strerror( i_err ),
2065                   channels );
2066         if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
2067         {
2068             msg_Err( p_this, "ALSA: cannot set channel count (%s)",
2069                      snd_strerror( i_err ) );
2070             goto adev_fail;
2071         }
2072         p_sys->b_stereo = ( channels == 2 );
2073     }
2074
2075     /* Set metrics for buffer calculations later */
2076     unsigned int buffer_time;
2077     if( ( i_err = snd_pcm_hw_params_get_buffer_time_max(p_hw_params, &buffer_time, 0) ) < 0 )
2078     {
2079         msg_Err( p_this, "ALSA: cannot get buffer time max (%s)",
2080                  snd_strerror( i_err ) );
2081         goto adev_fail;
2082     }
2083     if (buffer_time > 500000) buffer_time = 500000;
2084
2085     /* Set period time */
2086     unsigned int period_time = buffer_time / 4;
2087 #ifdef HAVE_ALSA_NEW_API
2088     i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, &period_time, 0 );
2089 #else
2090     i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, period_time, 0 );
2091 #endif
2092     if( i_err < 0 )
2093     {
2094         msg_Err( p_this, "ALSA: cannot set period time (%s)",
2095                  snd_strerror( i_err ) );
2096         goto adev_fail;
2097     }
2098
2099     /* Set buffer time */
2100 #ifdef HAVE_ALSA_NEW_API
2101     i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, &buffer_time, 0 );
2102 #else
2103     i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, buffer_time, 0 );
2104 #endif
2105     if( i_err < 0 )
2106     {
2107         msg_Err( p_this, "ALSA: cannot set buffer time (%s)",
2108                  snd_strerror( i_err ) );
2109         goto adev_fail;
2110     }
2111
2112     /* Apply new hardware parameters */
2113     if( ( i_err = snd_pcm_hw_params( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
2114     {
2115         msg_Err( p_this, "ALSA: cannot set hw parameters (%s)",
2116                  snd_strerror( i_err ) );
2117         goto adev_fail;
2118     }
2119
2120     /* Get various buffer metrics */
2121     snd_pcm_hw_params_get_period_size( p_hw_params, &chunk_size, 0 );
2122     snd_pcm_hw_params_get_buffer_size( p_hw_params, &buffer_size );
2123     if( chunk_size == buffer_size )
2124     {
2125         msg_Err( p_this,
2126                  "ALSA: period cannot equal buffer size (%lu == %lu)",
2127                  chunk_size, buffer_size);
2128         goto adev_fail;
2129     }
2130
2131     int bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE);
2132     int bits_per_frame = bits_per_sample * channels;
2133
2134     p_sys->i_alsa_chunk_size = chunk_size;
2135     p_sys->i_alsa_frame_size = bits_per_frame / 8;
2136     p_sys->i_audio_max_frame_size = chunk_size * bits_per_frame / 8;
2137
2138     snd_pcm_hw_params_free( p_hw_params );
2139     p_hw_params = NULL;
2140
2141     /* Prep device */
2142     if( ( i_err = snd_pcm_prepare( p_sys->p_alsa_pcm ) ) < 0 )
2143     {
2144         msg_Err( p_this,
2145                  "ALSA: cannot prepare audio interface for use (%s)",
2146                  snd_strerror( i_err ) );
2147         goto adev_fail;
2148     }
2149
2150     /* Return a fake handle so other tests work */
2151     i_fd = 1;
2152
2153     free( psz_alsa_device_name );
2154
2155     if( !p_sys->psz_adev )
2156         p_sys->psz_adev = strdup( ALSA_DEFAULT );
2157     return i_fd;
2158
2159  adev_fail:
2160
2161     if( i_fd >= 0 ) close( i_fd );
2162
2163     if( p_hw_params ) snd_pcm_hw_params_free( p_hw_params );
2164     if( p_sys->p_alsa_pcm ) snd_pcm_close( p_sys->p_alsa_pcm );
2165     free( psz_alsa_device_name );
2166
2167     return -1;
2168
2169 }
2170 #endif
2171
2172 static int OpenAudioDevOss( vlc_object_t *p_this, demux_sys_t *p_sys,
2173                             vlc_bool_t b_demux )
2174 {
2175     char *psz_device = p_sys->psz_adev;
2176     int i_fd = 0;
2177     int i_format;
2178     /* OSS */
2179     if( !psz_device ) psz_device = strdup( OSS_DEFAULT ); /* FIXME leak */
2180
2181     if( (i_fd = open( psz_device, O_RDONLY | O_NONBLOCK )) < 0 )
2182     {
2183         msg_Err( p_this, "cannot open OSS audio device (%m)" );
2184         goto adev_fail;
2185     }
2186
2187     i_format = AFMT_S16_LE;
2188     if( ioctl( i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0
2189         || i_format != AFMT_S16_LE )
2190     {
2191         msg_Err( p_this,
2192                  "cannot set audio format (16b little endian) (%m)" );
2193         goto adev_fail;
2194     }
2195
2196     if( ioctl( i_fd, SNDCTL_DSP_STEREO,
2197                &p_sys->b_stereo ) < 0 )
2198     {
2199         msg_Err( p_this, "cannot set audio channels count (%m)" );
2200         goto adev_fail;
2201     }
2202
2203     if( ioctl( i_fd, SNDCTL_DSP_SPEED,
2204                &p_sys->i_sample_rate ) < 0 )
2205     {
2206         msg_Err( p_this, "cannot set audio sample rate (%m)" );
2207         goto adev_fail;
2208     }
2209
2210     p_sys->i_audio_max_frame_size = 6 * 1024;
2211
2212     if( !p_sys->psz_adev )
2213         p_sys->psz_adev = strdup( OSS_DEFAULT );
2214     return i_fd;
2215
2216  adev_fail:
2217
2218     if( i_fd >= 0 ) close( i_fd );
2219     return -1;
2220
2221 }
2222
2223 static int OpenAudioDev( vlc_object_t *p_this, demux_sys_t *p_sys,
2224                          vlc_bool_t b_demux )
2225 {
2226     char *psz_device;
2227     int i_fd = -1;
2228
2229 #ifdef HAVE_ALSA
2230     if( ( p_sys->i_audio_method & AUDIO_METHOD_ALSA ) && i_fd < 0 )
2231         i_fd  = OpenAudioDevAlsa( p_this, p_sys, b_demux );
2232 #endif
2233
2234     if( ( p_sys->i_audio_method & AUDIO_METHOD_OSS ) && i_fd < 0 )
2235         i_fd = OpenAudioDevOss( p_this, p_sys, b_demux );
2236
2237     if( i_fd < 0 )
2238         return i_fd;
2239
2240     psz_device = p_sys->psz_adev;
2241
2242     msg_Dbg( p_this, "opened adev=`%s' %s %dHz",
2243              psz_device, p_sys->b_stereo ? "stereo" : "mono",
2244              p_sys->i_sample_rate );
2245
2246     es_format_t fmt;
2247     es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );
2248
2249     fmt.audio.i_channels = p_sys->b_stereo ? 2 : 1;
2250     fmt.audio.i_rate = p_sys->i_sample_rate;
2251     fmt.audio.i_bitspersample = 16;
2252     fmt.audio.i_blockalign = fmt.audio.i_channels * fmt.audio.i_bitspersample / 8;
2253     fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate * fmt.audio.i_bitspersample;
2254
2255     msg_Dbg( p_this, "new audio es %d channels %dHz",
2256              fmt.audio.i_channels, fmt.audio.i_rate );
2257
2258     if( b_demux )
2259     {
2260         demux_t *p_demux = (demux_t *)p_this;
2261         p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
2262     }
2263
2264     return i_fd;
2265 }
2266
2267 /*****************************************************************************
2268  * ProbeVideoDev: probe video for capabilities
2269  *****************************************************************************/
2270 static vlc_bool_t ProbeVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys,
2271                                  char *psz_device )
2272 {
2273     int i_index;
2274     int i_standard;
2275
2276     int i_fd;
2277
2278     if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 )
2279     {
2280         msg_Err( p_obj, "cannot open video device (%m)" );
2281         goto open_failed;
2282     }
2283
2284     /* Get device capabilites */
2285
2286     if( ioctl( i_fd, VIDIOC_QUERYCAP, &p_sys->dev_cap ) < 0 )
2287     {
2288         msg_Err( p_obj, "cannot get video capabilities (%m)" );
2289         goto open_failed;
2290     }
2291
2292     msg_Dbg( p_obj, "V4L2 device: %s using driver: %s (version: %u.%u.%u) on %s",
2293                             p_sys->dev_cap.card,
2294                             p_sys->dev_cap.driver,
2295                             (p_sys->dev_cap.version >> 16) & 0xFF,
2296                             (p_sys->dev_cap.version >> 8) & 0xFF,
2297                             p_sys->dev_cap.version & 0xFF,
2298                             p_sys->dev_cap.bus_info );
2299
2300     msg_Dbg( p_obj, "the device has the capabilities: (%c) Video Capure, "
2301                                                        "(%c) Audio, "
2302                                                        "(%c) Tuner",
2303              ( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE  ? 'X':' '),
2304              ( p_sys->dev_cap.capabilities & V4L2_CAP_AUDIO  ? 'X':' '),
2305              ( p_sys->dev_cap.capabilities & V4L2_CAP_TUNER  ? 'X':' ') );
2306
2307     msg_Dbg( p_obj, "supported I/O methods are: (%c) Read/Write, "
2308                                                  "(%c) Streaming, "
2309                                                  "(%c) Asynchronous",
2310             ( p_sys->dev_cap.capabilities & V4L2_CAP_READWRITE ? 'X':' ' ),
2311             ( p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING ? 'X':' ' ),
2312             ( p_sys->dev_cap.capabilities & V4L2_CAP_ASYNCIO ? 'X':' ' ) );
2313
2314     /* Now, enumerate all the video inputs. This is useless at the moment
2315        since we have no way to present that info to the user except with
2316        debug messages */
2317
2318     if( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
2319     {
2320         struct v4l2_input t_input;
2321         t_input.index = 0;
2322         while( ioctl( i_fd, VIDIOC_ENUMINPUT, &t_input ) >= 0 )
2323         {
2324             p_sys->i_input++;
2325             t_input.index = p_sys->i_input;
2326         }
2327
2328         p_sys->p_inputs = calloc( 1, p_sys->i_input * sizeof( struct v4l2_input ) );
2329         if( !p_sys->p_inputs ) goto open_failed;
2330
2331         for( i_index = 0; i_index < p_sys->i_input; i_index++ )
2332         {
2333             p_sys->p_inputs[i_index].index = i_index;
2334
2335             if( ioctl( i_fd, VIDIOC_ENUMINPUT, &p_sys->p_inputs[i_index] ) )
2336             {
2337                 msg_Err( p_obj, "cannot get video input characteristics (%m)" );
2338                 goto open_failed;
2339             }
2340             msg_Dbg( p_obj, "video input %i (%s) has type: %s",
2341                                 i_index,
2342                                 p_sys->p_inputs[i_index].name,
2343                                 p_sys->p_inputs[i_index].type
2344                                         == V4L2_INPUT_TYPE_TUNER ?
2345                                         "Tuner adapter" :
2346                                         "External analog input" );
2347         }
2348     }
2349
2350     /* Probe video standards */
2351     if( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
2352     {
2353         struct v4l2_standard t_standards;
2354         t_standards.index = 0;
2355         while( ioctl( i_fd, VIDIOC_ENUMSTD, &t_standards ) >=0 )
2356         {
2357             p_sys->i_standard++;
2358             t_standards.index = p_sys->i_standard;
2359         }
2360
2361         p_sys->p_standards = calloc( 1, p_sys->i_standard * sizeof( struct v4l2_standard ) );
2362         if( !p_sys->p_standards ) goto open_failed;
2363
2364         for( i_standard = 0; i_standard < p_sys->i_standard; i_standard++ )
2365         {
2366             p_sys->p_standards[i_standard].index = i_standard;
2367
2368             if( ioctl( i_fd, VIDIOC_ENUMSTD, &p_sys->p_standards[i_standard] ) )
2369             {
2370                 msg_Err( p_obj, "cannot get video input standards (%m)" );
2371                 goto open_failed;
2372             }
2373             msg_Dbg( p_obj, "video standard %i is: %s",
2374                                 i_standard,
2375                                 p_sys->p_standards[i_standard].name);
2376         }
2377     }
2378
2379     /* initialize the structures for the ioctls */
2380     for( i_index = 0; i_index < 32; i_index++ )
2381     {
2382         p_sys->p_audios[i_index].index = i_index;
2383     }
2384
2385     /* Probe audio inputs */
2386     if( p_sys->dev_cap.capabilities & V4L2_CAP_AUDIO )
2387     {
2388         while( p_sys->i_audio < 32 &&
2389                ioctl( i_fd, VIDIOC_S_AUDIO, &p_sys->p_audios[p_sys->i_audio] ) >= 0 )
2390         {
2391             if( ioctl( i_fd, VIDIOC_G_AUDIO, &p_sys->p_audios[ p_sys->i_audio] ) < 0 )
2392             {
2393                 msg_Err( p_obj, "cannot get audio input characteristics (%m)" );
2394                 goto open_failed;
2395             }
2396
2397             msg_Dbg( p_obj, "audio device %i (%s) is %s",
2398                                 p_sys->i_audio,
2399                                 p_sys->p_audios[p_sys->i_audio].name,
2400                                 p_sys->p_audios[p_sys->i_audio].capability &
2401                                                     V4L2_AUDCAP_STEREO ?
2402                                         "Stereo" : "Mono" );
2403
2404             p_sys->i_audio++;
2405         }
2406     }
2407
2408     /* List tuner caps */
2409     if( p_sys->dev_cap.capabilities & V4L2_CAP_TUNER )
2410     {
2411         struct v4l2_tuner tuner;
2412         memset( &tuner, 0, sizeof(tuner) );
2413         while( ioctl( i_fd, VIDIOC_G_TUNER, &tuner ) >= 0 )
2414         {
2415             p_sys->i_tuner++;
2416             memset( &tuner, 0, sizeof(tuner) );
2417             tuner.index = p_sys->i_tuner;
2418         }
2419
2420         p_sys->p_tuners = calloc( 1, p_sys->i_tuner * sizeof( struct v4l2_tuner ) );
2421         if( !p_sys->p_tuners ) goto open_failed;
2422
2423         for( i_index = 0; i_index < p_sys->i_tuner; i_index++ )
2424         {
2425             p_sys->p_tuners[i_index].index = i_index;
2426
2427             if( ioctl( i_fd, VIDIOC_G_TUNER, &p_sys->p_tuners[i_index] ) )
2428             {
2429                 msg_Err( p_obj, "cannot get tuner characteristics (%m)" );
2430                 goto open_failed;
2431             }
2432             msg_Dbg( p_obj, "tuner %i (%s) has type: %s, "
2433                               "frequency range: %.1f %s -> %.1f %s",
2434                                 i_index,
2435                                 p_sys->p_tuners[i_index].name,
2436                                 p_sys->p_tuners[i_index].type
2437                                         == V4L2_TUNER_RADIO ?
2438                                         "Radio" : "Analog TV",
2439                                 p_sys->p_tuners[i_index].rangelow * 62.5,
2440                                 p_sys->p_tuners[i_index].capability &
2441                                         V4L2_TUNER_CAP_LOW ?
2442                                         "Hz" : "kHz",
2443                                 p_sys->p_tuners[i_index].rangehigh * 62.5,
2444                                 p_sys->p_tuners[i_index].capability &
2445                                         V4L2_TUNER_CAP_LOW ?
2446                                         "Hz" : "kHz" );
2447         }
2448     }
2449
2450     /* Probe for available chromas */
2451     if( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
2452     {
2453         struct v4l2_fmtdesc codec;
2454
2455         i_index = 0;
2456         memset( &codec, 0, sizeof(codec) );
2457         codec.index = i_index;
2458         codec.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2459
2460         while( ioctl( i_fd, VIDIOC_ENUM_FMT, &codec ) >= 0 )
2461         {
2462             i_index++;
2463             codec.index = i_index;
2464         }
2465
2466         p_sys->i_codec = i_index;
2467
2468         p_sys->p_codecs = calloc( 1, p_sys->i_codec * sizeof( struct v4l2_fmtdesc ) );
2469
2470         for( i_index = 0; i_index < p_sys->i_codec; i_index++ )
2471         {
2472             p_sys->p_codecs[i_index].index = i_index;
2473             p_sys->p_codecs[i_index].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2474
2475             if( ioctl( i_fd, VIDIOC_ENUM_FMT, &p_sys->p_codecs[i_index] ) < 0 )
2476             {
2477                 msg_Err( p_obj, "cannot get codec description (%m)" );
2478                 goto open_failed;
2479             }
2480
2481             /* only print if vlc supports the format */
2482             vlc_bool_t b_codec_supported = VLC_FALSE;
2483             for( int i = 0; v4l2chroma_to_fourcc[i].i_v4l2 != 0; i++ )
2484             {
2485                 if( v4l2chroma_to_fourcc[i].i_v4l2 == p_sys->p_codecs[i_index].pixelformat )
2486                 {
2487                     b_codec_supported = VLC_TRUE;
2488
2489                     char sz_fourcc[5];
2490                     memset( &sz_fourcc, 0, sizeof( sz_fourcc ) );
2491                     vlc_fourcc_to_char( v4l2chroma_to_fourcc[i].i_fourcc, &sz_fourcc );
2492                     msg_Dbg( p_obj, "device supports chroma %4s [%s]",
2493                                 sz_fourcc,
2494                                 p_sys->p_codecs[i_index].description );
2495
2496 #ifdef VIDIOC_ENUM_FRAMESIZES
2497                     /* This is new in Linux 2.6.19 */
2498                     /* List valid frame sizes for this format */
2499                     struct v4l2_frmsizeenum frmsize;
2500                     frmsize.index = 0;
2501                     frmsize.pixel_format = p_sys->p_codecs[i_index].pixelformat;
2502                     if( ioctl( i_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize ) < 0 )
2503                     {
2504                         /* Not all devices support this ioctl */
2505                         msg_Warn( p_obj, "Unable to query for frame sizes" );
2506                     }
2507                     else
2508                     {
2509                         switch( frmsize.type )
2510                         {
2511                             case V4L2_FRMSIZE_TYPE_DISCRETE:
2512                                 do
2513                                 {
2514                                     msg_Dbg( p_obj,
2515                 "    device supports size %dx%d",
2516                 frmsize.discrete.width, frmsize.discrete.height );
2517                                     frmsize.index++;
2518                                 } while( ioctl( i_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize ) >= 0 );
2519                                 break;
2520                             case V4L2_FRMSIZE_TYPE_STEPWISE:
2521                                 msg_Dbg( p_obj,
2522                 "    device supports sizes %dx%d to %dx%d using %dx%d increments",
2523                 frmsize.stepwise.min_width, frmsize.stepwise.min_height,
2524                 frmsize.stepwise.max_width, frmsize.stepwise.max_height,
2525                 frmsize.stepwise.step_width, frmsize.stepwise.step_height );
2526                                 break;
2527                             case V4L2_FRMSIZE_TYPE_CONTINUOUS:
2528                                 msg_Dbg( p_obj,
2529                 "    device supports all sizes %dx%d to %dx%d",
2530                 frmsize.stepwise.min_width, frmsize.stepwise.min_height,
2531                 frmsize.stepwise.max_width, frmsize.stepwise.max_height );
2532                                 break;
2533                         }
2534                     }
2535 #endif
2536                 }
2537             }
2538             if( !b_codec_supported )
2539             {
2540                     char psz_fourcc[5];
2541                     memset( &psz_fourcc, 0, sizeof( psz_fourcc ) );
2542                     vlc_fourcc_to_char( p_sys->p_codecs[i_index].pixelformat,
2543                                         &psz_fourcc );
2544                     msg_Dbg( p_obj,
2545                          "device codec %4s (%s) not supported as access_demux",
2546                          psz_fourcc, p_sys->p_codecs[i_index].description );
2547             }
2548
2549         }
2550     }
2551
2552
2553     if( i_fd >= 0 ) close( i_fd );
2554     return VLC_TRUE;
2555
2556 open_failed:
2557
2558     if( i_fd >= 0 ) close( i_fd );
2559     return VLC_FALSE;
2560
2561 }
2562
2563 /*****************************************************************************
2564  * ProbeAudioDev: probe audio for capabilities
2565  *****************************************************************************/
2566 #ifdef HAVE_ALSA
2567 static vlc_bool_t ProbeAudioDevAlsa( vlc_object_t *p_this, demux_sys_t *p_sys,
2568                                      char *psz_device )
2569 {
2570     int i_err;
2571     snd_pcm_t *p_alsa_pcm;
2572     char* psz_alsa_device_name = ResolveALSADeviceName( psz_device ?: ALSA_DEFAULT );
2573
2574     if( ( i_err = snd_pcm_open( &p_alsa_pcm, psz_alsa_device_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK ) ) < 0 )
2575     {
2576         msg_Err( p_this, "cannot open device %s for ALSA audio (%s)", psz_alsa_device_name, snd_strerror( i_err ) );
2577         free( psz_alsa_device_name );
2578         return VLC_FALSE;
2579     }
2580
2581     snd_pcm_close( p_alsa_pcm );
2582     free( psz_alsa_device_name );
2583
2584     return VLC_TRUE;
2585 }
2586 #endif
2587
2588 static vlc_bool_t ProbeAudioDevOss( vlc_object_t *p_this, demux_sys_t *p_sys,
2589                                     char *psz_device )
2590 {
2591     int i_fd = 0;
2592     int i_caps;
2593     if( !psz_device ) psz_device = strdup( OSS_DEFAULT ); /* FIXME leak */
2594
2595     if( ( i_fd = open( psz_device, O_RDONLY | O_NONBLOCK ) ) < 0 )
2596     {
2597         msg_Err( p_this, "cannot open device %s for OSS audio (%m)", psz_device );
2598         goto open_failed;
2599     }
2600
2601     /* this will fail if the device is video */
2602     if( ioctl( i_fd, SNDCTL_DSP_GETCAPS, &i_caps ) < 0 )
2603     {
2604         msg_Err( p_this, "cannot get audio caps (%m)" );
2605         goto open_failed;
2606     }
2607
2608     if( i_fd >= 0 ) close( i_fd );
2609
2610     return VLC_TRUE;
2611
2612 open_failed:
2613     if( i_fd >= 0 ) close( i_fd );
2614     return VLC_FALSE;
2615 }
2616
2617 static vlc_bool_t ProbeAudioDev( vlc_object_t *p_this, demux_sys_t *p_sys,
2618                                  char *psz_device )
2619 {
2620 #ifdef HAVE_ALSA
2621     if( ( p_sys->i_audio_method & AUDIO_METHOD_ALSA )
2622      && ProbeAudioDevAlsa( p_this, p_sys, psz_device ) )
2623     {
2624         p_sys->i_audio_method = AUDIO_METHOD_ALSA;
2625         return VLC_TRUE;
2626     }
2627 #endif
2628
2629     if( ( p_sys->i_audio_method & AUDIO_METHOD_OSS )
2630      && ProbeAudioDevOss( p_this, p_sys, psz_device ) )
2631     {
2632         p_sys->i_audio_method = AUDIO_METHOD_OSS;
2633         return VLC_TRUE;
2634     }
2635
2636     p_sys->i_audio_method = 0;
2637     return VLC_FALSE;
2638 }
2639
2640 /*****************************************************************************
2641  * Print a user-class v4l2 control's details, create the relevant variable,
2642  * change the value if needed.
2643  *****************************************************************************/
2644 static void ControlListPrint( vlc_object_t *p_obj, int i_fd,
2645                               struct v4l2_queryctrl queryctrl,
2646                               vlc_bool_t b_reset, vlc_bool_t b_demux )
2647 {
2648     struct v4l2_querymenu querymenu;
2649     unsigned int i_mid;
2650
2651     int i;
2652     int i_val;
2653
2654     char *psz_name;
2655     vlc_value_t val, val2;
2656
2657     if( queryctrl.flags & V4L2_CTRL_FLAG_GRABBED )
2658         msg_Dbg( p_obj, "    control is busy" );
2659     if( queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY )
2660         msg_Dbg( p_obj, "    control is read-only" );
2661
2662     for( i = 0; controls[i].psz_name != NULL; i++ )
2663         if( controls[i].i_cid == queryctrl.id ) break;
2664
2665     if( controls[i].psz_name )
2666     {
2667         psz_name = strdup( controls[i].psz_name );
2668         char psz_cfg_name[40];
2669         sprintf( psz_cfg_name, CFG_PREFIX "%s", psz_name );
2670         i_val = var_CreateGetInteger( p_obj, psz_cfg_name );
2671         var_Destroy( p_obj, psz_cfg_name );
2672     }
2673     else
2674     {
2675         char *psz_buf;
2676         psz_name = strdup( (const char *)queryctrl.name );
2677         for( psz_buf = psz_name; *psz_buf; psz_buf++ )
2678         {
2679             if( *psz_buf == ' ' ) *psz_buf = '-';
2680         }
2681         i_val = -1;
2682     }
2683
2684     switch( queryctrl.type )
2685     {
2686         case V4L2_CTRL_TYPE_INTEGER:
2687             msg_Dbg( p_obj, "    integer control" );
2688             msg_Dbg( p_obj,
2689                      "    valid values: %d to %d by steps of %d",
2690                      queryctrl.minimum, queryctrl.maximum,
2691                      queryctrl.step );
2692
2693             var_Create( p_obj, psz_name,
2694                         VLC_VAR_INTEGER | VLC_VAR_HASMIN | VLC_VAR_HASMAX
2695                       | VLC_VAR_HASSTEP | VLC_VAR_ISCOMMAND );
2696             val.i_int = queryctrl.minimum;
2697             var_Change( p_obj, psz_name, VLC_VAR_SETMIN, &val, NULL );
2698             val.i_int = queryctrl.maximum;
2699             var_Change( p_obj, psz_name, VLC_VAR_SETMAX, &val, NULL );
2700             val.i_int = queryctrl.step;
2701             var_Change( p_obj, psz_name, VLC_VAR_SETSTEP, &val, NULL );
2702             break;
2703         case V4L2_CTRL_TYPE_BOOLEAN:
2704             msg_Dbg( p_obj, "    boolean control" );
2705             var_Create( p_obj, psz_name,
2706                         VLC_VAR_BOOL | VLC_VAR_ISCOMMAND );
2707             break;
2708         case V4L2_CTRL_TYPE_MENU:
2709             msg_Dbg( p_obj, "    menu control" );
2710             var_Create( p_obj, psz_name,
2711                         VLC_VAR_INTEGER | VLC_VAR_HASCHOICE
2712                       | VLC_VAR_ISCOMMAND );
2713             memset( &querymenu, 0, sizeof( querymenu ) );
2714             for( i_mid = queryctrl.minimum;
2715                  i_mid <= (unsigned)queryctrl.maximum;
2716                  i_mid++ )
2717             {
2718                 querymenu.index = i_mid;
2719                 querymenu.id = queryctrl.id;
2720                 if( ioctl( i_fd, VIDIOC_QUERYMENU, &querymenu ) >= 0 )
2721                 {
2722                     msg_Dbg( p_obj, "        %d: %s",
2723                              querymenu.index, querymenu.name );
2724                     val.i_int = querymenu.index;
2725                     val2.psz_string = (char *)querymenu.name;
2726                     var_Change( p_obj, psz_name,
2727                                 VLC_VAR_ADDCHOICE, &val, &val2 );
2728                 }
2729             }
2730             break;
2731         case V4L2_CTRL_TYPE_BUTTON:
2732             msg_Dbg( p_obj, "    button control" );
2733             var_Create( p_obj, psz_name,
2734                         VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
2735             break;
2736         case V4L2_CTRL_TYPE_CTRL_CLASS:
2737             msg_Dbg( p_obj, "    control class" );
2738             var_Create( p_obj, psz_name, VLC_VAR_VOID );
2739             break;
2740         default:
2741             msg_Dbg( p_obj, "    unknown control type (FIXME)" );
2742             /* FIXME */
2743             break;
2744     }
2745
2746     switch( queryctrl.type )
2747     {
2748         case V4L2_CTRL_TYPE_INTEGER:
2749         case V4L2_CTRL_TYPE_BOOLEAN:
2750         case V4L2_CTRL_TYPE_MENU:
2751             {
2752                 struct v4l2_control control;
2753                 msg_Dbg( p_obj, "    default value: %d",
2754                          queryctrl.default_value );
2755                 memset( &control, 0, sizeof( control ) );
2756                 control.id = queryctrl.id;
2757                 if( ioctl( i_fd, VIDIOC_G_CTRL, &control ) >= 0 )
2758                 {
2759                     msg_Dbg( p_obj, "    current value: %d", control.value );
2760                 }
2761                 if( i_val == -1 )
2762                 {
2763                     i_val = control.value;
2764                     if( b_reset && queryctrl.default_value != control.value )
2765                     {
2766                         msg_Dbg( p_obj, "    reset value to default" );
2767                         Control( p_obj, i_fd, psz_name,
2768                                       queryctrl.id, queryctrl.default_value );
2769                     }
2770                 }
2771                 else
2772                 {
2773                     Control( p_obj, i_fd, psz_name,
2774                                   queryctrl.id, i_val );
2775                 }
2776             }
2777             break;
2778         default:
2779             break;
2780     }
2781
2782     val.psz_string = (char *)queryctrl.name;
2783     var_Change( p_obj, psz_name, VLC_VAR_SETTEXT, &val, NULL );
2784     val.i_int = queryctrl.id;
2785     val2.psz_string = (char *)psz_name;
2786     var_Change( p_obj, "controls", VLC_VAR_ADDCHOICE, &val, &val2 );
2787
2788     switch( var_Type( p_obj, psz_name ) & VLC_VAR_TYPE )
2789     {
2790         case VLC_VAR_BOOL:
2791             var_SetBool( p_obj, psz_name, i_val );
2792             break;
2793         case VLC_VAR_INTEGER:
2794             var_SetInteger( p_obj, psz_name, i_val );
2795             break;
2796         case VLC_VAR_VOID:
2797             break;
2798         default:
2799             msg_Warn( p_obj, "FIXME: %s %s %d", __FILE__, __func__,
2800                       __LINE__ );
2801             break;
2802     }
2803
2804     if (b_demux)
2805         var_AddCallback( p_obj, psz_name,
2806                         DemuxControlCallback, (void*)queryctrl.id );
2807     else
2808         var_AddCallback( p_obj, psz_name,
2809                         AccessControlCallback, (void*)queryctrl.id );
2810
2811     free( psz_name );
2812 }
2813
2814 /*****************************************************************************
2815  * List all user-class v4l2 controls, set them to the user specified
2816  * value and create the relevant variables to enable runtime changes
2817  *****************************************************************************/
2818 static int ControlList( vlc_object_t *p_obj, int i_fd,
2819                         vlc_bool_t b_reset, vlc_bool_t b_demux )
2820 {
2821     struct v4l2_queryctrl queryctrl;
2822     int i_cid;
2823
2824     memset( &queryctrl, 0, sizeof( queryctrl ) );
2825
2826     /* A list of available controls (aka the variable name) will be
2827      * stored as choices in the "controls" variable. We'll thus be able
2828      * to use those to create an appropriate interface */
2829     var_Create( p_obj, "controls", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
2830
2831     var_Create( p_obj, "controls-update", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
2832
2833     /* Add a control to reset all controls to their default values */
2834     vlc_value_t val, val2;
2835     var_Create( p_obj, "controls-reset", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
2836     val.psz_string = _( "Reset controls to default" );
2837     var_Change( p_obj, "controls-reset", VLC_VAR_SETTEXT, &val, NULL );
2838     val.i_int = -1;
2839     val2.psz_string = (char *)"controls-reset";
2840     var_Change( p_obj, "controls", VLC_VAR_ADDCHOICE, &val, &val2 );
2841     if (b_demux)
2842         var_AddCallback( p_obj, "controls-reset", DemuxControlResetCallback, NULL );
2843     else
2844         var_AddCallback( p_obj, "controls-reset", AccessControlResetCallback, NULL );
2845
2846     queryctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
2847     if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 )
2848     {
2849         msg_Dbg( p_obj, "Extended control API supported by v4l2 driver" );
2850
2851         /* List extended controls */
2852         queryctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
2853         while( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 )
2854         {
2855             switch( V4L2_CTRL_ID2CLASS( queryctrl.id ) )
2856             {
2857                 case V4L2_CTRL_CLASS_USER:
2858                     msg_Dbg( p_obj, "Available control: %s (%x)",
2859                              queryctrl.name, queryctrl.id );
2860                     break;
2861                 case V4L2_CTRL_CLASS_MPEG:
2862                     msg_Dbg( p_obj, "Available MPEG control: %s (%x)",
2863                              queryctrl.name, queryctrl.id );
2864                     break;
2865                 default:
2866                     msg_Dbg( p_obj, "Available private control: %s (%x)",
2867                              queryctrl.name, queryctrl.id );
2868                     break;
2869             }
2870             ControlListPrint( p_obj, i_fd, queryctrl, b_reset, b_demux );
2871             queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
2872         }
2873     }
2874     else
2875     {
2876         msg_Dbg( p_obj, "Extended control API not supported by v4l2 driver" );
2877
2878         /* List public controls */
2879         for( i_cid = V4L2_CID_BASE;
2880              i_cid < V4L2_CID_LASTP1;
2881              i_cid ++ )
2882         {
2883             queryctrl.id = i_cid;
2884             if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 )
2885             {
2886                 if( queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
2887                     continue;
2888                 msg_Dbg( p_obj, "Available control: %s (%x)",
2889                          queryctrl.name, queryctrl.id );
2890                 ControlListPrint( p_obj, i_fd, queryctrl, b_reset, b_demux );
2891             }
2892         }
2893
2894         /* List private controls */
2895         for( i_cid = V4L2_CID_PRIVATE_BASE;
2896              ;
2897              i_cid ++ )
2898         {
2899             queryctrl.id = i_cid;
2900             if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 )
2901             {
2902                 if( queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
2903                     continue;
2904                 msg_Dbg( p_obj, "Available private control: %s (%x)",
2905                          queryctrl.name, queryctrl.id );
2906                 ControlListPrint( p_obj, i_fd, queryctrl, b_reset, b_demux );
2907             }
2908             else
2909                 break;
2910         }
2911     }
2912
2913     return VLC_SUCCESS;
2914 }
2915
2916 /*****************************************************************************
2917  * Reset all user-class v4l2 controls to their default value
2918  *****************************************************************************/
2919 static int ControlReset( vlc_object_t *p_obj, int i_fd )
2920 {
2921     struct v4l2_queryctrl queryctrl;
2922     int i_cid;
2923
2924     memset( &queryctrl, 0, sizeof( queryctrl ) );
2925
2926     /* public controls */
2927     for( i_cid = V4L2_CID_BASE;
2928          i_cid < V4L2_CID_LASTP1;
2929          i_cid ++ )
2930     {
2931         queryctrl.id = i_cid;
2932         if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 )
2933         {
2934             struct v4l2_control control;
2935             if( queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
2936                 continue;
2937             memset( &control, 0, sizeof( control ) );
2938             control.id = queryctrl.id;
2939             if( ioctl( i_fd, VIDIOC_G_CTRL, &control ) >= 0
2940              && queryctrl.default_value != control.value )
2941             {
2942                 int i;
2943                 for( i = 0; controls[i].psz_name != NULL; i++ )
2944                     if( controls[i].i_cid == queryctrl.id ) break;
2945                 Control( p_obj, i_fd,
2946                          controls[i].psz_name ? controls[i].psz_name
2947                                               : (const char *)queryctrl.name,
2948                          queryctrl.id, queryctrl.default_value );
2949             }
2950         }
2951     }
2952
2953     /* private controls */
2954     for( i_cid = V4L2_CID_PRIVATE_BASE;
2955          ;
2956          i_cid ++ )
2957     {
2958         queryctrl.id = i_cid;
2959         if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 )
2960         {
2961             struct v4l2_control control;
2962             if( queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
2963                 continue;
2964             memset( &control, 0, sizeof( control ) );
2965             control.id = queryctrl.id;
2966             if( ioctl( i_fd, VIDIOC_G_CTRL, &control ) >= 0
2967              && queryctrl.default_value != control.value )
2968             {
2969                 Control( p_obj, i_fd, (const char *)queryctrl.name,
2970                          queryctrl.id, queryctrl.default_value );
2971             }
2972         }
2973         else
2974             break;
2975     }
2976     return VLC_SUCCESS;
2977 }
2978
2979 /*****************************************************************************
2980  * Issue user-class v4l2 controls
2981  *****************************************************************************/
2982 static int Control( vlc_object_t *p_obj, int i_fd,
2983                     const char *psz_name, int i_cid, int i_value )
2984 {
2985     struct v4l2_queryctrl queryctrl;
2986     struct v4l2_control control;
2987
2988     if( i_value == -1 )
2989         return VLC_SUCCESS;
2990
2991     memset( &queryctrl, 0, sizeof( queryctrl ) );
2992
2993     queryctrl.id = i_cid;
2994
2995     if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) < 0
2996         || queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
2997     {
2998         msg_Dbg( p_obj, "%s (%x) control is not supported.", psz_name,
2999                  i_cid );
3000         return VLC_EGENERIC;
3001     }
3002
3003     memset( &control, 0, sizeof( control ) );
3004     control.id = i_cid;
3005
3006     if( i_value >= 0 )
3007     {
3008         control.value = i_value;
3009         if( ioctl( i_fd, VIDIOC_S_CTRL, &control ) < 0 )
3010         {
3011             msg_Err( p_obj, "unable to set %s to %d (%m)", psz_name,
3012                      i_value );
3013             return VLC_EGENERIC;
3014         }
3015     }
3016     if( ioctl( i_fd, VIDIOC_G_CTRL, &control ) >= 0 )
3017     {
3018         vlc_value_t val;
3019         msg_Dbg( p_obj, "video %s: %d", psz_name, control.value );
3020         switch( var_Type( p_obj, psz_name ) & VLC_VAR_TYPE )
3021         {
3022             case VLC_VAR_BOOL:
3023                 val.b_bool = control.value;
3024                 var_Change( p_obj, psz_name, VLC_VAR_SETVALUE, &val, NULL );
3025                 var_SetVoid( p_obj, "controls-update" );
3026                 break;
3027             case VLC_VAR_INTEGER:
3028                 val.i_int = control.value;
3029                 var_Change( p_obj, psz_name, VLC_VAR_SETVALUE, &val, NULL );
3030                 var_SetVoid( p_obj, "controls-update" );
3031                 break;
3032         }
3033     }
3034     return VLC_SUCCESS;
3035 }
3036
3037 /*****************************************************************************
3038  * On the fly change settings callback
3039  *****************************************************************************/
3040 static int DemuxControlCallback( vlc_object_t *p_this,
3041     const char *psz_var, vlc_value_t oldval, vlc_value_t newval,
3042     void *p_data )
3043 {
3044     demux_t *p_demux = (demux_t*)p_this;
3045     demux_sys_t *p_sys = p_demux->p_sys;
3046     int i_cid = (int)p_data;
3047
3048     int i_fd = p_sys->i_fd_video;
3049
3050     if( i_fd < 0 )
3051         return VLC_EGENERIC;
3052
3053     Control( p_this, i_fd, psz_var, i_cid, newval.i_int );
3054
3055     return VLC_EGENERIC;
3056 }
3057
3058 static int DemuxControlResetCallback( vlc_object_t *p_this,
3059     const char *psz_var, vlc_value_t oldval, vlc_value_t newval,
3060     void *p_data )
3061 {
3062     demux_t *p_demux = (demux_t*)p_this;
3063     demux_sys_t *p_sys = p_demux->p_sys;
3064
3065     int i_fd = p_sys->i_fd_video;
3066
3067     if( i_fd < 0 )
3068         return VLC_EGENERIC;
3069
3070     ControlReset( p_this, i_fd );
3071
3072     return VLC_EGENERIC;
3073 }
3074
3075 static int AccessControlCallback( vlc_object_t *p_this,
3076     const char *psz_var, vlc_value_t oldval, vlc_value_t newval,
3077     void *p_data )
3078 {
3079     access_t *p_access = (access_t *)p_this;
3080     demux_sys_t *p_sys = (demux_sys_t *) p_access->p_sys;
3081     int i_cid = (int)p_data;
3082
3083     int i_fd = p_sys->i_fd_video;
3084
3085     if( i_fd < 0 )
3086         return VLC_EGENERIC;
3087
3088     Control( p_this, i_fd, psz_var, i_cid, newval.i_int );
3089
3090     return VLC_EGENERIC;
3091 }
3092
3093 static int AccessControlResetCallback( vlc_object_t *p_this,
3094     const char *psz_var, vlc_value_t oldval, vlc_value_t newval,
3095     void *p_data )
3096 {
3097     access_t *p_access = (access_t *)p_this;
3098     demux_sys_t *p_sys = (demux_sys_t *) p_access->p_sys;
3099
3100     int i_fd = p_sys->i_fd_video;
3101
3102     if( i_fd < 0 )
3103         return VLC_EGENERIC;
3104
3105     ControlReset( p_this, i_fd );
3106
3107     return VLC_EGENERIC;
3108 }