v4l2: Fixed dynamic video metric updates. Better handling of defaults.
[vlc.git] / 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  * Author: Benjamin Pracht <bigben at videolan dot org>
8  *         Richard Hosking <richard at hovis dot net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*
26  * Sections based on the reference V4L2 capture example at
27  * http://v4l2spec.bytesex.org/spec/capture-example.html
28  *
29  * ALSA support based on parts of
30  * http://www.equalarea.com/paul/alsa-audio.html
31  * and hints taken from alsa-utils (aplay/arecord)
32  * http://www.alsa-project.org
33  */
34
35 /*
36  * TODO: No mjpeg support yet.
37  * TODO: Tuner partial implementation.
38  * TODO: Alsa input support - experimental
39  */
40
41 /*****************************************************************************
42  * Preamble
43  *****************************************************************************/
44
45 #include <vlc/vlc.h>
46 #include <vlc_access.h>
47 #include <vlc_demux.h>
48 #include <vlc_input.h>
49 #include <vlc_vout.h>
50
51 #include <fcntl.h>
52 #include <unistd.h>
53 #include <sys/ioctl.h>
54 #include <sys/mman.h>
55
56 #include <linux/videodev2.h>
57
58 #include <sys/soundcard.h>
59
60 #ifdef HAVE_ALSA
61 # define ALSA_PCM_NEW_HW_PARAMS_API
62 # define ALSA_PCM_NEW_SW_PARAMS_API
63 # include <alsa/asoundlib.h>
64 #endif
65
66 /*****************************************************************************
67  * Module descriptior
68  *****************************************************************************/
69
70 static int  Open ( vlc_object_t * );
71 static void Close( vlc_object_t * );
72
73 #define DEV_TEXT N_("Device name")
74 #define DEV_LONGTEXT N_( \
75     "Name of the device to use. " \
76     "If you don't specify anything, /dev/video0 will be used.")
77 #define ADEV_TEXT N_("Audio device name")
78 #define ADEV_LONGTEXT N_( \
79     "Name of the audio device to use. " \
80     "If you don't specify anything, /dev/dsp will be used.")
81 #define STANDARD_TEXT N_( "Standard" )
82 #define STANDARD_LONGTEXT N_( \
83     "Video standard (Default, SECAM, PAL, or NTSC)." )
84 #define CHROMA_TEXT N_("Video input chroma format")
85 #define CHROMA_LONGTEXT N_( \
86     "Force the Video4Linux2 video device to use a specific chroma format " \
87     "(eg. I420, RV24, etc.)")
88 #define INPUT_TEXT N_( "Input" )
89 #define INPUT_LONGTEXT N_( \
90     "Input of the card to use (Usually, 0 = tuner, " \
91     "1 = composite, 2 = svideo)." )
92 #define IOMETHOD_TEXT N_( "IO Method" )
93 #define IOMETHOD_LONGTEXT N_( \
94     "IO Method (READ, MMAP, USERPTR)." )
95 #define WIDTH_TEXT N_( "Width" )
96 #define WIDTH_LONGTEXT N_( \
97     "Force width (-1 for autodetect)." )
98 #define HEIGHT_TEXT N_( "Height" )
99 #define HEIGHT_LONGTEXT N_( \
100     "Force height (-1 for autodetect)." )
101 #define BRIGHTNESS_TEXT N_( "Brightness" )
102 #define BRIGHTNESS_LONGTEXT N_( \
103     "Brightness of the video input." )
104 #define CONTRAST_TEXT N_( "Contrast" )
105 #define CONTRAST_LONGTEXT N_( \
106     "Contrast of the video input." )
107 #define SATURATION_TEXT N_( "Saturation" )
108 #define SATURATION_LONGTEXT N_( \
109     "Saturation of the video input." )
110 #define HUE_TEXT N_( "Hue" )
111 #define HUE_LONGTEXT N_( \
112     "Hue of the video input." )
113 #define FPS_TEXT N_( "Framerate" )
114 #define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \
115     "(-1 for autodetect)." )
116 #define ALSA_TEXT N_( "Use Alsa" )
117 #define ALSA_LONGTEXT N_( \
118     "Use ALSA instead of OSS for audio" )
119 #define STEREO_TEXT N_( "Stereo" )
120 #define STEREO_LONGTEXT N_( \
121     "Capture the audio stream in stereo." )
122 #define SAMPLERATE_TEXT N_( "Samplerate" )
123 #define SAMPLERATE_LONGTEXT N_( \
124     "Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100, 48000)" )
125 #define CACHING_TEXT N_("Caching value in ms")
126 #define CACHING_LONGTEXT N_( \
127     "Caching value for V4L2 captures. This " \
128     "value should be set in milliseconds." )
129
130 typedef enum {
131     IO_METHOD_READ,
132     IO_METHOD_MMAP,
133     IO_METHOD_USERPTR,
134 } io_method;
135
136 static int i_standards_list[] =
137     { V4L2_STD_UNKNOWN, V4L2_STD_SECAM, V4L2_STD_PAL, V4L2_STD_NTSC };
138 static const char *psz_standards_list_text[] =
139     { N_("Default"), N_("SECAM"), N_("PAL"),  N_("NTSC") };
140
141 static int i_iomethod_list[] =
142     { IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR };
143 static const char *psz_iomethod_list_text[] =
144     { N_("READ"), N_("MMAP"),  N_("USERPTR") };
145
146 vlc_module_begin();
147     set_shortname( _("Video4Linux2") );
148     set_description( _("Video4Linux2 input") );
149     set_category( CAT_INPUT );
150     set_subcategory( SUBCAT_INPUT_ACCESS );
151
152     add_string( "v4l2-dev", "/dev/video0", 0, DEV_TEXT, DEV_LONGTEXT,
153                 VLC_FALSE );
154     add_string( "v4l2-adev", "/dev/dsp", 0, ADEV_TEXT, ADEV_LONGTEXT,
155                 VLC_FALSE );
156     add_integer( "v4l2-standard", 0, NULL, STANDARD_TEXT, STANDARD_LONGTEXT,
157                 VLC_FALSE );
158         change_integer_list( i_standards_list, psz_standards_list_text, 0 );
159     add_string( "v4l2-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT,
160                 VLC_TRUE );
161     add_integer( "v4l2-input", 0, NULL, INPUT_TEXT, INPUT_LONGTEXT,
162                 VLC_TRUE );
163     add_integer( "v4l2-io", IO_METHOD_MMAP, NULL, IOMETHOD_TEXT,
164                  IOMETHOD_LONGTEXT, VLC_TRUE );
165         change_integer_list( i_iomethod_list, psz_iomethod_list_text, 0 );
166     add_integer( "v4l2-width", 0, NULL, WIDTH_TEXT,
167                 WIDTH_LONGTEXT, VLC_TRUE );
168     add_integer( "v4l2-height", 0, NULL, HEIGHT_TEXT,
169                 HEIGHT_LONGTEXT, VLC_TRUE );
170     add_integer( "v4l2-brightness", -1, NULL, BRIGHTNESS_TEXT,
171                 BRIGHTNESS_LONGTEXT, VLC_TRUE );
172     add_integer( "v4l2-contrast", -1, NULL, CONTRAST_TEXT,
173                 CONTRAST_LONGTEXT, VLC_TRUE );
174     add_integer( "v4l2-saturation", -1, NULL, SATURATION_TEXT,
175                 SATURATION_LONGTEXT, VLC_TRUE );
176     add_integer( "v4l2-hue", -1, NULL, HUE_TEXT,
177                 HUE_LONGTEXT, VLC_TRUE );
178     add_float( "v4l2-fps", 0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_TRUE );
179 #ifdef HAVE_ALSA
180     add_bool( "v4l2-alsa", VLC_FALSE, NULL, ALSA_TEXT, ALSA_LONGTEXT,
181                 VLC_TRUE );
182 #endif
183     add_bool( "v4l2-stereo", VLC_TRUE, NULL, STEREO_TEXT, STEREO_LONGTEXT,
184                 VLC_TRUE );
185     add_integer( "v4l2-samplerate", 48000, NULL, SAMPLERATE_TEXT,
186                 SAMPLERATE_LONGTEXT, VLC_TRUE );
187     add_integer( "v4l2-caching", DEFAULT_PTS_DELAY / 1000, NULL,
188                 CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
189
190     add_shortcut( "v4l2" );
191     set_capability( "access_demux", 10 );
192     set_callbacks( Open, Close );
193 vlc_module_end();
194
195 /*****************************************************************************
196  * Access: local prototypes
197  *****************************************************************************/
198
199 static void ParseMRL( demux_t * );
200
201 static int Control( demux_t *, int, va_list );
202
203 static int Demux( demux_t * );
204 static block_t* GrabVideo( demux_t *p_demux );
205 static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame );
206 static block_t* GrabAudio( demux_t *p_demux );
207
208 vlc_bool_t IsPixelFormatSupported( demux_t *p_demux, unsigned int i_pixelformat );
209
210 char* ResolveALSADeviceName( char *psz_device );
211 static int OpenVideoDev( demux_t *, char *psz_device );
212 static int OpenAudioDev( demux_t *, char *psz_device );
213 static vlc_bool_t ProbeVideoDev( demux_t *, char *psz_device );
214 static vlc_bool_t ProbeAudioDev( demux_t *, char *psz_device );
215
216 static int VideoControlList( demux_t *p_demux, int i_fd );
217 static int VideoControl( demux_t *, int i_fd,
218                          const char *psz_label, int i_cid, int i_value );
219 static int VideoControlCallback( vlc_object_t *p_this,
220     const char *psz_var, vlc_value_t oldval, vlc_value_t newval,
221     void *p_data );
222
223 static struct
224 {
225     unsigned int i_v4l2;
226     int i_fourcc;
227 } v4l2chroma_to_fourcc[] =
228 {
229     { V4L2_PIX_FMT_GREY,    VLC_FOURCC( 'G', 'R', 'E', 'Y' ) },
230     { V4L2_PIX_FMT_HI240,   VLC_FOURCC( 'I', '2', '4', '0' ) },
231     { V4L2_PIX_FMT_RGB565,  VLC_FOURCC( 'R', 'V', '1', '6' ) },
232     { V4L2_PIX_FMT_RGB555,  VLC_FOURCC( 'R', 'V', '1', '5' ) },
233     { V4L2_PIX_FMT_BGR24,   VLC_FOURCC( 'R', 'V', '2', '4' ) },
234     { V4L2_PIX_FMT_BGR32,   VLC_FOURCC( 'R', 'V', '3', '2' ) },
235     { V4L2_PIX_FMT_YUYV,    VLC_FOURCC( 'Y', 'U', 'Y', '2' ) },
236     { V4L2_PIX_FMT_YUYV,    VLC_FOURCC( 'Y', 'U', 'Y', 'V' ) },
237     { V4L2_PIX_FMT_UYVY,    VLC_FOURCC( 'U', 'Y', 'V', 'Y' ) },
238     { V4L2_PIX_FMT_Y41P,    VLC_FOURCC( 'I', '4', '1', 'N' ) },
239     { V4L2_PIX_FMT_YUV422P, VLC_FOURCC( 'I', '4', '2', '2' ) },
240     { V4L2_PIX_FMT_YVU420,  VLC_FOURCC( 'I', '4', '2', '0' ) },
241     { V4L2_PIX_FMT_YUV411P, VLC_FOURCC( 'I', '4', '1', '1' ) },
242     { V4L2_PIX_FMT_YUV410,  VLC_FOURCC( 'I', '4', '1', '0' ) },
243     { 0, 0 }
244 };
245
246 struct buffer_t
247 {
248     void *  start;
249     size_t  length;
250     void *  orig_userp;
251 };
252
253 struct demux_sys_t
254 {
255     char *psz_device;  /* Main device from MRL, can be video or audio */
256
257     char *psz_vdev;
258     int  i_fd_video;
259
260     char *psz_adev;
261     int  i_fd_audio;
262
263     char *psz_requested_chroma;
264
265     /* Video */
266     io_method io;
267
268     int i_pts;
269
270     struct v4l2_capability dev_cap;
271
272     int i_input;
273     struct v4l2_input *p_inputs;
274     int i_selected_input;
275
276     int i_standard;
277     struct v4l2_standard *p_standards;
278     v4l2_std_id i_selected_standard_id;
279
280     int i_audio;
281     /* V4L2 devices cannot have more than 32 audio inputs */
282     struct v4l2_audio p_audios[32];
283
284     int i_tuner;
285     struct v4l2_tuner *p_tuners;
286
287     int i_codec;
288     struct v4l2_fmtdesc *p_codecs;
289
290     struct buffer_t *p_buffers;
291     unsigned int i_nbuffers;
292
293     int i_width;
294     int i_height;
295     float f_fps;            /* <= 0.0 mean to grab at full rate */
296     mtime_t i_video_pts;    /* only used when f_fps > 0 */
297     int i_fourcc;
298
299     int i_brightness;
300     int i_contrast;
301     int i_saturation;
302     int i_hue;
303
304     picture_t pic;
305     int i_video_frame_size;
306
307     es_out_id_t *p_es_video;
308
309     /* Audio */
310     unsigned int i_sample_rate;
311     vlc_bool_t b_stereo;
312     int i_audio_max_frame_size;
313     block_t *p_block_audio;
314     es_out_id_t *p_es_audio;
315
316 #ifdef HAVE_ALSA
317     /* ALSA Audio */
318     vlc_bool_t b_use_alsa;
319     snd_pcm_t *p_alsa_pcm;
320     int i_alsa_frame_size;
321     int i_alsa_chunk_size;
322 #endif
323 };
324
325 /*****************************************************************************
326  * Open: opens v4l2 device
327  *****************************************************************************
328  *
329  * url: <video device>::::
330  *
331  *****************************************************************************/
332 static int Open( vlc_object_t *p_this )
333 {
334     demux_t     *p_demux = (demux_t*)p_this;
335     demux_sys_t *p_sys;
336     vlc_value_t val;
337
338     /* Only when selected */
339     if( *p_demux->psz_access == '\0' ) return VLC_EGENERIC;
340
341     /* Set up p_demux */
342     p_demux->pf_control = Control;
343     p_demux->pf_demux = Demux;
344     p_demux->info.i_update = 0;
345     p_demux->info.i_title = 0;
346     p_demux->info.i_seekpoint = 0;
347
348     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
349     if( p_sys == NULL ) return VLC_ENOMEM;
350
351     p_sys->i_video_pts = -1;
352
353     var_Create( p_demux, "v4l2-standard", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
354     var_Get( p_demux, "v4l2-standard", &val );
355     p_sys->i_selected_standard_id = i_standards_list[val.i_int];
356
357     p_sys->i_selected_input = var_CreateGetInteger( p_demux, "v4l2-input" );
358
359     p_sys->io = var_CreateGetInteger( p_demux, "v4l2-io" );
360
361     p_sys->i_width = var_CreateGetInteger( p_demux, "v4l2-width" );
362     p_sys->i_height = var_CreateGetInteger( p_demux, "v4l2-height" );
363
364     p_sys->i_brightness =
365         var_CreateGetIntegerCommand( p_demux, "v4l2-brightness" );
366     p_sys->i_contrast =
367         var_CreateGetIntegerCommand( p_demux, "v4l2-contrast" );
368     p_sys->i_saturation =
369         var_CreateGetIntegerCommand( p_demux, "v4l2-saturation" );
370     p_sys->i_hue =
371         var_CreateGetIntegerCommand( p_demux, "v4l2-hue" );
372
373     var_AddCallback( p_demux, "v4l2-brightness", VideoControlCallback, NULL );
374     var_AddCallback( p_demux, "v4l2-contrast", VideoControlCallback, NULL );
375     var_AddCallback( p_demux, "v4l2-saturation", VideoControlCallback, NULL );
376     var_AddCallback( p_demux, "v4l2-hue", VideoControlCallback, NULL );
377
378     var_Create( p_demux, "v4l2-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
379     var_Get( p_demux, "v4l2-fps", &val );
380     p_sys->f_fps = val.f_float;
381
382     var_Create( p_demux, "v4l2-samplerate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
383     var_Get( p_demux, "v4l2-samplerate", &val );
384     p_sys->i_sample_rate = val.i_int;
385
386     p_sys->psz_requested_chroma = var_CreateGetString( p_demux, "v4l2-chroma" );
387
388 #ifdef HAVE_ALSA
389     var_Create( p_demux, "v4l2-alsa", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
390     var_Get( p_demux, "v4l2-alsa", &val );
391     p_sys->b_use_alsa = val.b_bool;
392 #endif
393
394     var_Create( p_demux, "v4l2-stereo", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
395     var_Get( p_demux, "v4l2-stereo", &val );
396     p_sys->b_stereo = val.b_bool;
397
398     p_sys->i_pts = var_CreateGetInteger( p_demux, "v4l2-caching" );
399
400     p_sys->psz_device = p_sys->psz_vdev = p_sys->psz_adev = NULL;
401     p_sys->i_fd_video = -1;
402     p_sys->i_fd_audio = -1;
403
404     p_sys->p_es_video = p_sys->p_es_audio = 0;
405     p_sys->p_block_audio = 0;
406
407     ParseMRL( p_demux );
408
409 #ifdef HAVE_ALSA
410     /* Alsa support available? */
411     msg_Dbg( p_demux, "ALSA input support available" );
412 #endif
413
414     /* Find main device (video or audio) */
415     if( p_sys->psz_device && *p_sys->psz_device )
416     {
417         msg_Dbg( p_demux, "main device='%s'", p_sys->psz_device );
418
419         /* Try to open as video device */
420         msg_Dbg( p_demux, "trying device '%s' as video", p_sys->psz_device );
421         if( ProbeVideoDev( p_demux, p_sys->psz_device ) )
422         {
423             msg_Dbg( p_demux, "'%s' is a video device", p_sys->psz_device );
424             /* Device was a video device */
425             if( p_sys->psz_vdev ) free( p_sys->psz_vdev );
426             p_sys->psz_vdev = p_sys->psz_device;
427             p_sys->psz_device = NULL;
428             p_sys->i_fd_video = OpenVideoDev( p_demux, p_sys->psz_vdev );
429             if( p_sys->i_fd_video < 0 )
430             {
431                 Close( p_this );
432                 return VLC_EGENERIC;
433             }
434         }
435         else
436         {
437             /* Try to open as audio device */
438             msg_Dbg( p_demux, "trying device '%s' as audio", p_sys->psz_device );
439             if( ProbeAudioDev( p_demux, p_sys->psz_device ) )
440             {
441                 msg_Dbg( p_demux, "'%s' is an audio device", p_sys->psz_device );
442                 /* Device was an audio device */
443                 if( p_sys->psz_adev ) free( p_sys->psz_adev );
444                 p_sys->psz_adev = p_sys->psz_device;
445                 p_sys->psz_device = NULL;
446                 p_sys->i_fd_audio = OpenAudioDev( p_demux, p_sys->psz_adev );
447                 if( p_sys->i_fd_audio < 0 )
448                 {
449                     Close( p_this );
450                     return VLC_EGENERIC;
451                 }
452             }
453         }
454     }
455
456     /* If no device opened, only continue if the access was forced */
457     if( p_sys->i_fd_video < 0 && p_sys->i_fd_audio < 0 )
458     {
459         if( strcmp( p_demux->psz_access, "v4l2" ) )
460         {
461             Close( p_this );
462             return VLC_EGENERIC;
463         }
464     }
465
466     /* Find video device */
467     if( p_sys->i_fd_video < 0 )
468     {
469         if( !p_sys->psz_vdev || !*p_sys->psz_vdev )
470         {
471             if( p_sys->psz_vdev ) free( p_sys->psz_vdev );
472             p_sys->psz_vdev = var_CreateGetString( p_demux, "v4l2-dev" );
473         }
474
475         msg_Dbg( p_demux, "opening '%s' as video", p_sys->psz_vdev );
476         if( p_sys->psz_vdev && *p_sys->psz_vdev && ProbeVideoDev( p_demux, p_sys->psz_vdev ) )
477         {
478             p_sys->i_fd_video = OpenVideoDev( p_demux, p_sys->psz_vdev );
479         }
480     }
481
482     /* Find audio device */
483     if( p_sys->i_fd_audio < 0 )
484     {
485         if( !p_sys->psz_adev || !*p_sys->psz_adev )
486         {
487             if( p_sys->psz_adev ) free( p_sys->psz_adev );
488             p_sys->psz_adev = var_CreateGetString( p_demux, "v4l2-adev" );
489         }
490
491         msg_Dbg( p_demux, "opening '%s' as audio", p_sys->psz_adev );
492         if( p_sys->psz_adev && *p_sys->psz_adev && ProbeAudioDev( p_demux, p_sys->psz_adev ) )
493         {
494             p_sys->i_fd_audio = OpenAudioDev( p_demux, p_sys->psz_adev );
495         }
496     }
497
498     if( p_sys->i_fd_video < 0 && p_sys->i_fd_audio < 0 )
499     {
500         Close( p_this );
501         return VLC_EGENERIC;
502     }
503
504     return VLC_SUCCESS;
505 }
506
507 /*****************************************************************************
508  * ParseMRL: parse the options contained in the MRL
509  *****************************************************************************/
510 static void ParseMRL( demux_t *p_demux )
511 {
512     demux_sys_t *p_sys = p_demux->p_sys;
513
514     char *psz_dup = strdup( p_demux->psz_path );
515     char *psz_parser = psz_dup;
516
517     while( *psz_parser && *psz_parser != ':' )
518     {
519         psz_parser++;
520     }
521
522     if( *psz_parser == ':' )
523     {
524         /* read options */
525         for( ;; )
526         {
527             *psz_parser++ = '\0';
528
529             if( !strncmp( psz_parser, "adev=", strlen( "adev=" ) ) )
530             {
531                 int  i_len;
532
533                 psz_parser += strlen( "adev=" );
534                 if( strchr( psz_parser, ':' ) )
535                 {
536                     i_len = strchr( psz_parser, ':' ) - psz_parser;
537                 }
538                 else
539                 {
540                     i_len = strlen( psz_parser );
541                 }
542
543                 p_sys->psz_adev = strndup( psz_parser, i_len );
544
545                 psz_parser += i_len;
546             }
547             else if( !strncmp( psz_parser, "standard=", strlen( "standard=" ) ) )
548             {
549                 psz_parser += strlen( "standard=" );
550                 if( !strncmp( psz_parser, "pal", strlen( "pal" ) ) )
551                 {
552                     p_sys->i_selected_standard_id = V4L2_STD_PAL;
553                     psz_parser += strlen( "pal" );
554                 }
555                 else if( !strncmp( psz_parser, "ntsc", strlen( "ntsc" ) ) )
556                 {
557                     p_sys->i_selected_standard_id = V4L2_STD_NTSC;
558                     psz_parser += strlen( "ntsc" );
559                 }
560                 else if( !strncmp( psz_parser, "secam", strlen( "secam" ) ) )
561                 {
562                     p_sys->i_selected_standard_id = V4L2_STD_SECAM;
563                     psz_parser += strlen( "secam" );
564                 }
565                 else if( !strncmp( psz_parser, "default", strlen( "default" ) ) )
566                 {
567                     p_sys->i_selected_standard_id = V4L2_STD_UNKNOWN;
568                     psz_parser += strlen( "default" );
569                 }
570                 else
571                 {
572                     p_sys->i_selected_standard_id = i_standards_list[strtol( psz_parser, &psz_parser, 0 )];
573                 }
574             }
575             else if( !strncmp( psz_parser, "chroma=", strlen( "chroma=" ) ) )
576             {
577                 int  i_len;
578
579                 psz_parser += strlen( "chroma=" );
580                 if( strchr( psz_parser, ':' ) )
581                 {
582                     i_len = strchr( psz_parser, ':' ) - psz_parser;
583                 }
584                 else
585                 {
586                     i_len = strlen( psz_parser );
587                 }
588
589                 if( p_sys->psz_requested_chroma ) free( p_sys->psz_requested_chroma );
590                 p_sys->psz_requested_chroma = strndup( psz_parser, i_len );
591
592                 psz_parser += i_len;
593             }
594             else if( !strncmp( psz_parser, "input=", strlen( "input=" ) ) )
595             {
596                 p_sys->i_selected_input = strtol( psz_parser + strlen( "input=" ),
597                                        &psz_parser, 0 );
598             }
599             else if( !strncmp( psz_parser, "fps=", strlen( "fps=" ) ) )
600             {
601                 p_sys->f_fps = strtof( psz_parser + strlen( "fps=" ),
602                                        &psz_parser );
603             }
604             else if( !strncmp( psz_parser, "io=", strlen( "io=" ) ) )
605             {
606                 psz_parser += strlen( "io=" );
607                 if( !strncmp( psz_parser, "read", strlen( "read" ) ) )
608                 {
609                     p_sys->io = IO_METHOD_READ;
610                     psz_parser += strlen( "read" );
611                 }
612                 else if( !strncmp( psz_parser, "mmap", strlen( "mmap" ) ) )
613                 {
614                     p_sys->io = IO_METHOD_MMAP;
615                     psz_parser += strlen( "mmap" );
616                 }
617                 else if( !strncmp( psz_parser, "userptr", strlen( "userptr" ) ) )
618                 {
619                     p_sys->io = IO_METHOD_USERPTR;
620                     psz_parser += strlen( "userptr" );
621                 }
622                 else
623                 {
624                     p_sys->io = strtol( psz_parser, &psz_parser, 0 );
625                 }
626             }
627             else if( !strncmp( psz_parser, "width=",
628                                strlen( "width=" ) ) )
629             {
630                 p_sys->i_width =
631                     strtol( psz_parser + strlen( "width=" ),
632                             &psz_parser, 0 );
633             }
634             else if( !strncmp( psz_parser, "height=",
635                                strlen( "height=" ) ) )
636             {
637                 p_sys->i_height =
638                     strtol( psz_parser + strlen( "height=" ),
639                             &psz_parser, 0 );
640             }
641             else if( !strncmp( psz_parser, "brightness=",
642                                strlen( "brightness=" ) ) )
643             {
644                 p_sys->i_brightness =
645                     strtol( psz_parser + strlen( "brightness=" ),
646                             &psz_parser, 0 );
647             }
648             else if( !strncmp( psz_parser, "contrast=",
649                                strlen( "contrast=" ) ) )
650             {
651                 p_sys->i_contrast =
652                     strtol( psz_parser + strlen( "contrast=" ),
653                             &psz_parser, 0 );
654             }
655             else if( !strncmp( psz_parser, "saturation=",
656                                strlen( "saturation=" ) ) )
657             {
658                 p_sys->i_saturation =
659                     strtol( psz_parser + strlen( "saturation=" ),
660                             &psz_parser, 0 );
661             }
662             else if( !strncmp( psz_parser, "hue=",
663                                strlen( "hue=" ) ) )
664             {
665                 p_sys->i_hue =
666                     strtol( psz_parser + strlen( "hue=" ),
667                             &psz_parser, 0 );
668             }
669             else if( !strncmp( psz_parser, "samplerate=",
670                                strlen( "samplerate=" ) ) )
671             {
672                 p_sys->i_sample_rate =
673                     strtol( psz_parser + strlen( "samplerate=" ),
674                             &psz_parser, 0 );
675             }
676 #ifdef HAVE_ALSA
677             else if( !strncmp( psz_parser, "alsa", strlen( "alsa" ) ) )
678             {
679                 psz_parser += strlen( "alsa" );
680                 p_sys->b_use_alsa = VLC_TRUE;
681             }
682 #endif
683             else if( !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) )
684             {
685                 psz_parser += strlen( "stereo" );
686                 p_sys->b_stereo = VLC_TRUE;
687             }
688             else if( !strncmp( psz_parser, "mono", strlen( "mono" ) ) )
689             {
690                 psz_parser += strlen( "mono" );
691                 p_sys->b_stereo = VLC_FALSE;
692             }
693             else if( !strncmp( psz_parser, "caching=", strlen( "caching=" ) ) )
694             {
695                 p_sys->i_pts = strtol( psz_parser + strlen( "caching=" ),
696                                        &psz_parser, 0 );
697             }
698             else
699             {
700                 msg_Warn( p_demux, "unknown option" );
701             }
702
703             while( *psz_parser && *psz_parser != ':' )
704             {
705                 psz_parser++;
706             }
707
708             if( *psz_parser == '\0' )
709             {
710                 break;
711             }
712         }
713     }
714
715     /* Main device */
716     if( *psz_dup )
717     {
718         p_sys->psz_device = strdup( psz_dup );
719     }
720     if( psz_dup ) free( psz_dup );
721 }
722
723 /*****************************************************************************
724  * Close: close device, free resources
725  *****************************************************************************/
726 static void Close( vlc_object_t *p_this )
727 {
728     demux_t     *p_demux = (demux_t *)p_this;
729     demux_sys_t *p_sys   = p_demux->p_sys;
730     struct v4l2_buffer buf;
731     enum v4l2_buf_type buf_type;
732     unsigned int i;
733
734     /* Stop video capture */
735     if( p_sys->i_fd_video >= 0 )
736     {
737         switch( p_sys->io )
738         {
739         case IO_METHOD_READ:
740             /* Nothing to do */
741             break;
742
743         case IO_METHOD_MMAP:
744         case IO_METHOD_USERPTR:
745             /* Some drivers 'hang' internally if this is not done before streamoff */
746             for( unsigned int i = 0; i < p_sys->i_nbuffers; i++ )
747             {
748                 memset( &buf, 0, sizeof(buf) );
749                 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
750                 buf.memory = ( p_sys->io == IO_METHOD_USERPTR ) ?
751                     V4L2_MEMORY_USERPTR : V4L2_MEMORY_MMAP;
752                 ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ); /* ignore result */
753             }
754
755             buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
756             if( ioctl( p_sys->i_fd_video, VIDIOC_STREAMOFF, &buf_type ) < 0 ) {
757                 msg_Err( p_demux, "VIDIOC_STREAMOFF failed" );
758             }
759
760             break;
761         }
762     }
763
764     /* Free Video Buffers */
765     if( p_sys->p_buffers ) {
766         switch( p_sys->io )
767         {
768         case IO_METHOD_READ:
769             free( p_sys->p_buffers[0].start );
770             break;
771
772         case IO_METHOD_MMAP:
773             for( i = 0; i < p_sys->i_nbuffers; ++i )
774             {
775                 if( munmap( p_sys->p_buffers[i].start, p_sys->p_buffers[i].length ) )
776                 {
777                     msg_Err( p_demux, "munmap failed" );
778                 }
779             }
780             break;
781
782         case IO_METHOD_USERPTR:
783             for( i = 0; i < p_sys->i_nbuffers; ++i )
784             {
785                free( p_sys->p_buffers[i].orig_userp );
786             }
787             break;
788         }
789         free( p_sys->p_buffers );
790     }
791
792     /* Close */
793     if( p_sys->i_fd_video >= 0 ) close( p_sys->i_fd_video );
794 #ifdef HAVE_ALSA
795     if( p_sys->b_use_alsa )
796     {
797         if( p_sys->p_alsa_pcm ) snd_pcm_close( p_sys->p_alsa_pcm );
798     }
799     else
800 #endif
801     {
802         if( p_sys->i_fd_audio >= 0 ) close( p_sys->i_fd_audio );
803     }
804
805     if( p_sys->p_block_audio ) block_Release( p_sys->p_block_audio );
806     if( p_sys->psz_device ) free( p_sys->psz_device );
807     if( p_sys->psz_vdev ) free( p_sys->psz_vdev );
808     if( p_sys->psz_adev ) free( p_sys->psz_adev );
809     if( p_sys->p_standards ) free( p_sys->p_standards );
810     if( p_sys->p_inputs ) free( p_sys->p_inputs );
811     if( p_sys->p_tuners ) free( p_sys->p_tuners );
812     if( p_sys->p_codecs ) free( p_sys->p_codecs );
813     if( p_sys->psz_requested_chroma ) free( p_sys->psz_requested_chroma );
814
815     free( p_sys );
816 }
817
818 /*****************************************************************************
819  * Control:
820  *****************************************************************************/
821 static int Control( demux_t *p_demux, int i_query, va_list args )
822 {
823     demux_sys_t *p_sys = p_demux->p_sys;
824     vlc_bool_t *pb;
825     int64_t    *pi64;
826
827     switch( i_query )
828     {
829         /* Special for access_demux */
830         case DEMUX_CAN_PAUSE:
831         case DEMUX_SET_PAUSE_STATE:
832         case DEMUX_CAN_CONTROL_PACE:
833             pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
834             *pb = VLC_FALSE;
835             return VLC_SUCCESS;
836
837         case DEMUX_GET_PTS_DELAY:
838             pi64 = (int64_t*)va_arg( args, int64_t * );
839             *pi64 = (int64_t)p_sys->i_pts * 1000;
840             return VLC_SUCCESS;
841
842         case DEMUX_GET_TIME:
843             pi64 = (int64_t*)va_arg( args, int64_t * );
844             *pi64 = mdate();
845             return VLC_SUCCESS;
846
847         /* TODO implement others */
848         default:
849             return VLC_EGENERIC;
850     }
851
852     return VLC_EGENERIC;
853 }
854
855 /*****************************************************************************
856  * Demux: Processes the audio or video frame
857  *****************************************************************************/
858 static int Demux( demux_t *p_demux )
859 {
860     demux_sys_t *p_sys = p_demux->p_sys;
861     es_out_id_t *p_es = p_sys->p_es_audio;
862     block_t *p_block = NULL;
863
864     /* Try grabbing audio frames first */
865     if( p_sys->i_fd_audio < 0 || !( p_block = GrabAudio( p_demux ) ) )
866     {
867         /* Try grabbing video frame */
868         p_es = p_sys->p_es_video;
869         if( p_sys->i_fd_video > 0 ) p_block = GrabVideo( p_demux );
870     }
871
872     if( !p_block )
873     {
874         /* Sleep so we do not consume all the cpu, 10ms seems
875          * like a good value (100fps) */
876         msleep( 10 );
877         return 1;
878     }
879
880     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
881     es_out_Send( p_demux->out, p_es, p_block );
882
883     return 1;
884 }
885
886 /*****************************************************************************
887  * GrabVideo: Grab a video frame
888  *****************************************************************************/
889 static block_t* GrabVideo( demux_t *p_demux )
890 {
891     demux_sys_t *p_sys = p_demux->p_sys;
892
893     block_t *p_block = NULL;
894     struct v4l2_buffer buf;
895
896     if( p_sys->f_fps >= 0.1 && p_sys->i_video_pts > 0 )
897     {
898         mtime_t i_dur = (mtime_t)((double)1000000 / (double)p_sys->f_fps);
899
900         /* Did we wait long enough ? (frame rate reduction) */
901         if( p_sys->i_video_pts + i_dur > mdate() ) return 0;
902     }
903
904     /* Grab Video Frame */
905     switch( p_sys->io )
906     {
907     case IO_METHOD_READ:
908         if( read( p_sys->i_fd_video, p_sys->p_buffers[0].start, p_sys->p_buffers[0].length ) )
909         {
910             switch( errno )
911             {
912             case EAGAIN:
913                 return 0;
914             case EIO:
915                 /* Could ignore EIO, see spec. */
916                 /* fall through */
917             default:
918                 msg_Err( p_demux, "Failed to read frame" );
919                 return 0;
920                }
921         }
922
923         p_block = ProcessVideoFrame( p_demux, (uint8_t*)p_sys->p_buffers[0].start );
924         if( !p_block ) return 0;
925
926         break;
927
928     case IO_METHOD_MMAP:
929         memset( &buf, 0, sizeof(buf) );
930         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
931         buf.memory = V4L2_MEMORY_MMAP;
932
933         /* Wait for next frame */
934         if (ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ) < 0 )
935         {
936             switch( errno )
937             {
938             case EAGAIN:
939                 return 0;
940             case EIO:
941                 /* Could ignore EIO, see spec. */
942                 /* fall through */
943             default:
944                 msg_Err( p_demux, "Failed to wait (VIDIOC_DQBUF)" );
945                 return 0;
946                }
947         }
948
949         if( buf.index >= p_sys->i_nbuffers ) {
950             msg_Err( p_demux, "Failed capturing new frame as i>=nbuffers" );
951             return 0;
952         }
953
954         p_block = ProcessVideoFrame( p_demux, p_sys->p_buffers[buf.index].start );
955         if( !p_block ) return 0;
956
957         /* Unlock */
958         if( ioctl( p_sys->i_fd_video, VIDIOC_QBUF, &buf ) < 0 )
959         {
960             msg_Err (p_demux, "Failed to unlock (VIDIOC_QBUF)");
961             return 0;
962         }
963
964         break;
965
966     case IO_METHOD_USERPTR:
967         memset( &buf, 0, sizeof(buf) );
968         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
969         buf.memory = V4L2_MEMORY_USERPTR;
970
971         /* Wait for next frame */
972         if (ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ) < 0 )
973         {
974             switch( errno )
975             {
976             case EAGAIN:
977                 return 0;
978             case EIO:
979                 /* Could ignore EIO, see spec. */
980                 /* fall through */
981             default:
982                 msg_Err( p_demux, "Failed to wait (VIDIOC_DQBUF)" );
983                 return 0;
984             }
985         }
986
987         /* Find frame? */
988         unsigned int i;
989         for( i = 0; i < p_sys->i_nbuffers; i++ )
990         {
991             if( buf.m.userptr == (unsigned long)p_sys->p_buffers[i].start &&
992                 buf.length == p_sys->p_buffers[i].length ) break;
993         }
994
995         if( i >= p_sys->i_nbuffers )
996         {
997             msg_Err( p_demux, "Failed capturing new frame as i>=nbuffers" );
998             return 0;
999         }
1000
1001         p_block = ProcessVideoFrame( p_demux, (uint8_t*)buf.m.userptr );
1002         if( !p_block ) return 0;
1003
1004         /* Unlock */
1005         if( ioctl( p_sys->i_fd_video, VIDIOC_QBUF, &buf ) < 0 )
1006         {
1007             msg_Err (p_demux, "Failed to unlock (VIDIOC_QBUF)");
1008             return 0;
1009         }
1010
1011         break;
1012
1013     }
1014
1015     /* Timestamp */
1016     p_sys->i_video_pts = p_block->i_pts = p_block->i_dts = mdate();
1017
1018     return p_block;
1019 }
1020
1021 /*****************************************************************************
1022  * ProcessVideoFrame: Helper function to take a buffer and copy it into
1023  * a new block
1024  *****************************************************************************/
1025 static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame )
1026 {
1027     demux_sys_t *p_sys = p_demux->p_sys;
1028     block_t *p_block;
1029
1030     if( !p_frame ) return 0;
1031
1032     /* New block */
1033     if( !( p_block = block_New( p_demux, p_sys->i_video_frame_size ) ) )
1034     {
1035         msg_Warn( p_demux, "Cannot get new block" );
1036         return 0;
1037     }
1038
1039     /* Copy frame */
1040     memcpy( p_block->p_buffer, p_frame, p_sys->i_video_frame_size );
1041
1042     return p_block;
1043 }
1044
1045 /*****************************************************************************
1046  * GrabAudio: Grab an audio frame
1047  *****************************************************************************/
1048 static block_t* GrabAudio( demux_t *p_demux )
1049 {
1050     demux_sys_t *p_sys = p_demux->p_sys;
1051     struct audio_buf_info buf_info;
1052     int i_read, i_correct;
1053     block_t *p_block;
1054
1055     if( p_sys->p_block_audio ) p_block = p_sys->p_block_audio;
1056     else p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
1057
1058     if( !p_block )
1059     {
1060         msg_Warn( p_demux, "cannot get block" );
1061         return 0;
1062     }
1063
1064     p_sys->p_block_audio = p_block;
1065
1066 #ifdef HAVE_ALSA
1067     if( p_sys->b_use_alsa )
1068     {
1069         /* ALSA */
1070         i_read = snd_pcm_readi( p_sys->p_alsa_pcm, p_block->p_buffer, p_sys->i_alsa_chunk_size );
1071         /* TODO: ALSA ERROR HANDLING?? xrun?? */
1072     }
1073     else
1074 #endif
1075     {
1076         /* OSS */
1077         i_read = read( p_sys->i_fd_audio, p_block->p_buffer,
1078                     p_sys->i_audio_max_frame_size );
1079     }
1080
1081     if( i_read <= 0 ) return 0;
1082
1083     p_block->i_buffer = i_read;
1084     p_sys->p_block_audio = 0;
1085
1086     /* Correct the date because of kernel buffering */
1087     i_correct = i_read;
1088 #ifdef HAVE_ALSA
1089     if( !p_sys->b_use_alsa )
1090 #endif
1091     {
1092         if( ioctl( p_sys->i_fd_audio, SNDCTL_DSP_GETISPACE, &buf_info ) == 0 )
1093         {
1094             i_correct += buf_info.bytes;
1095         }
1096     }
1097 #ifdef HAVE_ALSA
1098     else
1099     {
1100         /* TODO: ALSA timing */
1101         /* Very experimental code... */
1102         int i_err;
1103         snd_pcm_sframes_t delay = 0;
1104         if( ( i_err = snd_pcm_delay( p_sys->p_alsa_pcm, &delay ) ) >= 0 )
1105         {
1106             int i_correction_delta = delay * p_sys->i_alsa_frame_size;
1107             /* Test for overrun */
1108             if( i_correction_delta>p_sys->i_audio_max_frame_size )
1109             {
1110                 msg_Warn( p_demux, "ALSA read overrun" );
1111                 i_correction_delta = p_sys->i_audio_max_frame_size;
1112                 snd_pcm_prepare( p_sys->p_alsa_pcm );
1113             }
1114             i_correct += i_correction_delta;
1115         }
1116         else
1117         {
1118             /* delay failed so reset */
1119             msg_Warn( p_demux, "ALSA snd_pcm_delay failed (%s)", snd_strerror( i_err ) );
1120             snd_pcm_prepare( p_sys->p_alsa_pcm );
1121         }
1122     }
1123 #endif
1124
1125     /* Timestamp */
1126     p_block->i_pts = p_block->i_dts =
1127         mdate() - I64C(1000000) * (mtime_t)i_correct /
1128         2 / ( p_sys->b_stereo ? 2 : 1) / p_sys->i_sample_rate;
1129
1130     return p_block;
1131 }
1132
1133 /*****************************************************************************
1134  * Helper function to initalise video IO using the Read method
1135  *****************************************************************************/
1136 static int InitRead( demux_t *p_demux, int i_fd, unsigned int i_buffer_size )
1137 {
1138     demux_sys_t *p_sys = p_demux->p_sys;
1139
1140     p_sys->p_buffers = calloc( 1, sizeof( *p_sys->p_buffers ) );
1141     if( !p_sys->p_buffers )
1142     {
1143         msg_Err( p_demux, "Out of memory" );
1144         goto open_failed;
1145     }
1146
1147     p_sys->p_buffers[0].length = i_buffer_size;
1148     p_sys->p_buffers[0].start = malloc( i_buffer_size );
1149     if( !p_sys->p_buffers[0].start )
1150     {
1151         msg_Err( p_demux, "Out of memory" );
1152         goto open_failed;
1153     }
1154
1155     return VLC_SUCCESS;
1156
1157 open_failed:
1158     return VLC_EGENERIC;
1159
1160 }
1161
1162 /*****************************************************************************
1163  * Helper function to initalise video IO using the mmap method
1164  *****************************************************************************/
1165 static int InitMmap( demux_t *p_demux, int i_fd )
1166 {
1167     demux_sys_t *p_sys = p_demux->p_sys;
1168     struct v4l2_requestbuffers req;
1169
1170     memset( &req, 0, sizeof(req) );
1171     req.count = 4;
1172     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1173     req.memory = V4L2_MEMORY_MMAP;
1174
1175     if( ioctl( i_fd, VIDIOC_REQBUFS, &req ) < 0 )
1176     {
1177         msg_Err( p_demux, "device does not support mmap i/o" );
1178         goto open_failed;
1179     }
1180
1181     if( req.count < 2 )
1182     {
1183         msg_Err( p_demux, "Insufficient buffer memory" );
1184         goto open_failed;
1185     }
1186
1187     p_sys->p_buffers = calloc( req.count, sizeof( *p_sys->p_buffers ) );
1188     if( !p_sys->p_buffers )
1189     {
1190         msg_Err( p_demux, "Out of memory" );
1191         goto open_failed;
1192     }
1193
1194     for( p_sys->i_nbuffers = 0; p_sys->i_nbuffers < req.count; ++p_sys->i_nbuffers )
1195     {
1196         struct v4l2_buffer buf;
1197
1198         memset( &buf, 0, sizeof(buf) );
1199         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1200         buf.memory = V4L2_MEMORY_MMAP;
1201         buf.index = p_sys->i_nbuffers;
1202
1203         if( ioctl( i_fd, VIDIOC_QUERYBUF, &buf ) < 0 )
1204         {
1205             msg_Err( p_demux, "VIDIOC_QUERYBUF" );
1206             goto open_failed;
1207         }
1208
1209         p_sys->p_buffers[p_sys->i_nbuffers].length = buf.length;
1210         p_sys->p_buffers[p_sys->i_nbuffers].start =
1211             mmap( NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, i_fd, buf.m.offset );
1212
1213         if( p_sys->p_buffers[p_sys->i_nbuffers].start == MAP_FAILED )
1214         {
1215             msg_Err( p_demux, "mmap failed (%m)" );
1216             goto open_failed;
1217         }
1218     }
1219
1220     return VLC_SUCCESS;
1221
1222 open_failed:
1223     return VLC_EGENERIC;
1224
1225 }
1226
1227 /*****************************************************************************
1228  * Helper function to initalise video IO using the userbuf method
1229  *****************************************************************************/
1230 static int InitUserP( demux_t *p_demux, int i_fd, unsigned int i_buffer_size )
1231 {
1232     demux_sys_t *p_sys = p_demux->p_sys;
1233     struct v4l2_requestbuffers req;
1234     unsigned int i_page_size;
1235
1236     i_page_size = getpagesize();
1237     i_buffer_size = ( i_buffer_size + i_page_size - 1 ) & ~( i_page_size - 1);
1238
1239     memset( &req, 0, sizeof(req) );
1240     req.count = 4;
1241     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1242     req.memory = V4L2_MEMORY_USERPTR;
1243
1244     if( ioctl( i_fd, VIDIOC_REQBUFS, &req ) < 0 )
1245     {
1246         msg_Err( p_demux, "device does not support user pointer i/o" );
1247         goto open_failed;
1248     }
1249
1250     p_sys->p_buffers = calloc( 4, sizeof( *p_sys->p_buffers ) );
1251     if( !p_sys->p_buffers )
1252     {
1253         msg_Err( p_demux, "Out of memory" );
1254         goto open_failed;
1255     }
1256
1257     for( p_sys->i_nbuffers = 0; p_sys->i_nbuffers < 4; ++p_sys->i_nbuffers )
1258     {
1259         p_sys->p_buffers[p_sys->i_nbuffers].length = i_buffer_size;
1260         p_sys->p_buffers[p_sys->i_nbuffers].start =
1261             vlc_memalign( &p_sys->p_buffers[p_sys->i_nbuffers].orig_userp,
1262                 /* boundary */ i_page_size, i_buffer_size );
1263
1264         if( !p_sys->p_buffers[p_sys->i_nbuffers].start )
1265         {
1266             msg_Err( p_demux, "out of memory" );
1267             goto open_failed;
1268         }
1269     }
1270
1271     return VLC_SUCCESS;
1272
1273 open_failed:
1274     return VLC_EGENERIC;
1275
1276 }
1277
1278 /*****************************************************************************
1279  * IsPixelFormatSupported: returns true if the specified V4L2 pixel format is
1280  * in the array of supported formats returned by the driver
1281  *****************************************************************************/
1282 vlc_bool_t IsPixelFormatSupported( demux_t *p_demux, unsigned int i_pixelformat )
1283 {
1284     demux_sys_t *p_sys = p_demux->p_sys;
1285
1286     for( int i_index = 0; i_index < p_sys->i_codec; i_index++ )
1287     {
1288         if( p_sys->p_codecs[i_index].pixelformat == i_pixelformat ) return VLC_TRUE;
1289     }
1290
1291     return VLC_FALSE;
1292 }
1293
1294 /*****************************************************************************
1295  * OpenVideoDev: open and set up the video device and probe for capabilities
1296  *****************************************************************************/
1297 int OpenVideoDev( demux_t *p_demux, char *psz_device )
1298 {
1299     int i_fd;
1300     demux_sys_t *p_sys = p_demux->p_sys;
1301     struct v4l2_cropcap cropcap;
1302     struct v4l2_crop crop;
1303     struct v4l2_format fmt;
1304     unsigned int i_min;
1305     enum v4l2_buf_type buf_type;
1306
1307     if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 )
1308     {
1309         msg_Err( p_demux, "cannot open device (%m)" );
1310         goto open_failed;
1311     }
1312
1313     /* Select standard */
1314
1315     if( p_sys->i_selected_standard_id != V4L2_STD_UNKNOWN )
1316     {
1317         if( ioctl( i_fd, VIDIOC_S_STD, &p_sys->i_selected_standard_id ) < 0 )
1318         {
1319             msg_Err( p_demux, "cannot set standard (%m)" );
1320             goto open_failed;
1321         }
1322         msg_Dbg( p_demux, "Set standard" );
1323     }
1324
1325     /* Select input */
1326
1327     if( p_sys->i_selected_input > p_sys->i_input )
1328     {
1329         msg_Warn( p_demux, "invalid input. Using the default one" );
1330         p_sys->i_selected_input = 0;
1331     }
1332
1333     if( ioctl( i_fd, VIDIOC_S_INPUT, &p_sys->i_selected_input ) < 0 )
1334     {
1335         msg_Err( p_demux, "cannot set input (%m)" );
1336         goto open_failed;
1337     }
1338
1339     /* Verify device support for the various IO methods */
1340     switch( p_sys->io )
1341     {
1342     case IO_METHOD_READ:
1343         if( !(p_sys->dev_cap.capabilities & V4L2_CAP_READWRITE) )
1344         {
1345             msg_Err( p_demux, "device does not support read i/o" );
1346             goto open_failed;
1347         }
1348         break;
1349
1350     case IO_METHOD_MMAP:
1351     case IO_METHOD_USERPTR:
1352         if( !(p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING) )
1353         {
1354             msg_Err( p_demux, "device does not support streaming i/o" );
1355             goto open_failed;
1356         }
1357         break;
1358
1359     default:
1360         msg_Err( p_demux, "io method not supported" );
1361         goto open_failed;
1362     }
1363
1364     /* Reset Cropping */
1365     memset( &cropcap, 0, sizeof(cropcap) );
1366     cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1367     if( ioctl( i_fd, VIDIOC_CROPCAP, &cropcap ) >= 0 )
1368     {
1369         crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1370         crop.c = cropcap.defrect; /* reset to default */
1371         if( ioctl( i_fd, VIDIOC_S_CROP, &crop ) < 0 )
1372         {
1373             switch( errno )
1374             {
1375             case EINVAL:
1376                 /* Cropping not supported. */
1377                 break;
1378             default:
1379                 /* Errors ignored. */
1380                 break;
1381             }
1382         }
1383     }
1384
1385     /* Try and find default resolution if not specified */
1386     memset( &fmt, 0, sizeof(fmt) );
1387     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1388
1389     if( p_sys->i_width <= 0 || p_sys->i_height <= 0 )
1390     {
1391         if( ioctl( i_fd, VIDIOC_G_FMT, &fmt ) < 0 )
1392         {
1393             msg_Err( p_demux, "Cannot get default width and height." );
1394             goto open_failed;
1395         }
1396
1397         p_sys->i_width = fmt.fmt.pix.width;
1398         p_sys->i_height = fmt.fmt.pix.height;
1399
1400         if( fmt.fmt.pix.field == V4L2_FIELD_ALTERNATE )
1401         {
1402             p_sys->i_height = p_sys->i_height * 2;
1403         }
1404     }
1405     else
1406     {
1407         msg_Dbg( p_demux, "trying specified size %dx%d", p_sys->i_width, p_sys->i_height );
1408     }
1409
1410     fmt.fmt.pix.width = p_sys->i_width;
1411     fmt.fmt.pix.height = p_sys->i_height;
1412     fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
1413
1414     /* Test and set Chroma */
1415     fmt.fmt.pix.pixelformat = 0;
1416     if( p_sys->psz_requested_chroma && strlen( p_sys->psz_requested_chroma ) > 0 )
1417     {
1418         /* User specified chroma */
1419         if( strlen( p_sys->psz_requested_chroma ) >= 4 )
1420         {
1421             int i_requested_fourcc = VLC_FOURCC(
1422                 p_sys->psz_requested_chroma[0], p_sys->psz_requested_chroma[1],
1423                 p_sys->psz_requested_chroma[2], p_sys->psz_requested_chroma[3] );
1424             for( int i = 0; v4l2chroma_to_fourcc[i].i_v4l2 != 0; i++ )
1425             {
1426                 if( v4l2chroma_to_fourcc[i].i_fourcc == i_requested_fourcc )
1427                 {
1428                     fmt.fmt.pix.pixelformat = v4l2chroma_to_fourcc[i].i_v4l2;
1429                     break;
1430                 }
1431             }
1432         }
1433         /* Try and set user chroma */
1434         if( !IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ) || ( fmt.fmt.pix.pixelformat && ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 ) )
1435         {
1436             msg_Warn( p_demux, "Driver is unable to use specified chroma %s. Trying defaults.", p_sys->psz_requested_chroma );
1437             fmt.fmt.pix.pixelformat = 0;
1438         }
1439     }
1440
1441     /* If no user specified chroma, find best */
1442     if( !fmt.fmt.pix.pixelformat )
1443     {
1444         fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
1445         if( !IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ) || ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 )
1446         {
1447             fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
1448             if( !IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ) || ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 )
1449             {
1450                 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1451                 if( !IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ) || ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 )
1452                 {
1453                     msg_Err( p_demux, "Could not select any of the default chromas!" );
1454                     goto open_failed;
1455                 }
1456             }
1457         }
1458     }
1459
1460     /* Reassign width, height and chroma incase driver override */
1461     p_sys->i_width = fmt.fmt.pix.width;
1462     p_sys->i_height = fmt.fmt.pix.height;
1463
1464     /* Look up final fourcc */
1465     p_sys->i_fourcc = 0;
1466     for( int i = 0; v4l2chroma_to_fourcc[i].i_fourcc != 0; i++ )
1467     {
1468         if( v4l2chroma_to_fourcc[i].i_v4l2 == fmt.fmt.pix.pixelformat )
1469         {
1470             p_sys->i_fourcc = v4l2chroma_to_fourcc[i].i_fourcc;
1471             break;
1472         }
1473     }
1474
1475     /* Buggy driver paranoia */
1476     i_min = fmt.fmt.pix.width * 2;
1477     if( fmt.fmt.pix.bytesperline < i_min )
1478         fmt.fmt.pix.bytesperline = i_min;
1479     i_min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
1480     if( fmt.fmt.pix.sizeimage < i_min )
1481         fmt.fmt.pix.sizeimage = i_min;
1482
1483 #ifdef VIDIOC_ENUM_FRAMEINTERVALS
1484     /* This is new in Linux 2.6.19 */
1485     /* List supported frame rates */
1486     struct v4l2_frmivalenum frmival;
1487     frmival.index = 0;
1488     frmival.pixel_format = fmt.fmt.pix.pixelformat;
1489     frmival.width = p_sys->i_width;
1490     frmival.height = p_sys->i_height;
1491     if( ioctl( i_fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival ) >= 0 )
1492     {
1493         char sz_fourcc[5];
1494         memset( &sz_fourcc, 0, sizeof( sz_fourcc ) );
1495         vlc_fourcc_to_char( p_sys->i_fourcc, &sz_fourcc );
1496         msg_Dbg( p_demux, "supported frame intervals for %4s, %dx%d:",
1497                  sz_fourcc, frmival.width, frmival.height );
1498         switch( frmival.type )
1499         {
1500             case V4L2_FRMIVAL_TYPE_DISCRETE:
1501                 do
1502                 {
1503                     msg_Dbg( p_demux, "    supported frame interval: %d/%d",
1504                              frmival.discrete.numerator,
1505                              frmival.discrete.denominator );
1506                     frmival.index++;
1507                 } while( ioctl( i_fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival ) >= 0 );
1508                 break;
1509             case V4L2_FRMIVAL_TYPE_STEPWISE:
1510                 msg_Dbg( p_demux, "    supported frame intervals: %d/%d to "
1511                          "%d/%d using %d/%d increments",
1512                          frmival.stepwise.min.numerator,
1513                          frmival.stepwise.min.denominator,
1514                          frmival.stepwise.max.numerator,
1515                          frmival.stepwise.max.denominator,
1516                          frmival.stepwise.step.numerator,
1517                          frmival.stepwise.step.denominator );
1518                 break;
1519             case V4L2_FRMIVAL_TYPE_CONTINUOUS:
1520                 msg_Dbg( p_demux, "    supported frame intervals: %d/%d to %d/%d",
1521                          frmival.stepwise.min.numerator,
1522                          frmival.stepwise.min.denominator,
1523                          frmival.stepwise.max.numerator,
1524                          frmival.stepwise.max.denominator );
1525                 break;
1526         }
1527     }
1528 #endif
1529
1530     VideoControlList( p_demux, i_fd );
1531
1532     VideoControl( p_demux, i_fd,
1533                   "brightness", V4L2_CID_BRIGHTNESS, p_sys->i_brightness );
1534     VideoControl( p_demux, i_fd,
1535                   "contrast", V4L2_CID_CONTRAST, p_sys->i_contrast );
1536     VideoControl( p_demux, i_fd,
1537                   "saturation", V4L2_CID_SATURATION, p_sys->i_saturation );
1538     VideoControl( p_demux, i_fd, "hue", V4L2_CID_HUE, p_sys->i_hue );
1539
1540     /* Init vout Picture */
1541     vout_InitPicture( VLC_OBJECT(p_demux), &p_sys->pic, p_sys->i_fourcc,
1542         p_sys->i_width, p_sys->i_height, p_sys->i_width *
1543         VOUT_ASPECT_FACTOR / p_sys->i_height );
1544     if( !p_sys->pic.i_planes )
1545     {
1546         msg_Err( p_demux, "unsupported chroma" );
1547         goto open_failed;
1548     }
1549     p_sys->i_video_frame_size = 0;
1550     for( int i = 0; i < p_sys->pic.i_planes; i++ )
1551     {
1552          p_sys->i_video_frame_size += p_sys->pic.p[i].i_visible_lines * p_sys->pic.p[i].i_visible_pitch;
1553     }
1554
1555     /* Init IO method */
1556     switch( p_sys->io )
1557     {
1558     case IO_METHOD_READ:
1559         if( InitRead( p_demux, i_fd, fmt.fmt.pix.sizeimage ) != VLC_SUCCESS ) goto open_failed;
1560         break;
1561
1562     case IO_METHOD_MMAP:
1563         if( InitMmap( p_demux, i_fd ) != VLC_SUCCESS ) goto open_failed;
1564         break;
1565
1566     case IO_METHOD_USERPTR:
1567         if( InitUserP( p_demux, i_fd, fmt.fmt.pix.sizeimage ) != VLC_SUCCESS ) goto open_failed;
1568         break;
1569
1570     }
1571
1572     /* Add */
1573     es_format_t es_fmt;
1574     es_format_Init( &es_fmt, VIDEO_ES, p_sys->i_fourcc );
1575     es_fmt.video.i_width  = p_sys->i_width;
1576     es_fmt.video.i_height = p_sys->i_height;
1577     es_fmt.video.i_aspect = 4 * VOUT_ASPECT_FACTOR / 3;
1578
1579     /* Setup rgb mask for RGB formats */
1580     if( p_sys->i_fourcc == VLC_FOURCC( 'R','V','2','4' ) )
1581     {
1582         /* This is in BGR format */
1583         es_fmt.video.i_bmask = 0x00ff0000;
1584         es_fmt.video.i_gmask = 0x0000ff00;
1585         es_fmt.video.i_rmask = 0x000000ff;
1586     }
1587
1588     msg_Dbg( p_demux, "added new video es %4.4s %dx%d",
1589         (char*)&es_fmt.i_codec, es_fmt.video.i_width, es_fmt.video.i_height );
1590     p_sys->p_es_video = es_out_Add( p_demux->out, &es_fmt );
1591
1592     /* Start Capture */
1593
1594     switch( p_sys->io )
1595     {
1596     case IO_METHOD_READ:
1597         /* Nothing to do */
1598         break;
1599
1600     case IO_METHOD_MMAP:
1601         for (unsigned int i = 0; i < p_sys->i_nbuffers; ++i)
1602         {
1603             struct v4l2_buffer buf;
1604
1605             memset( &buf, 0, sizeof(buf) );
1606             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1607             buf.memory = V4L2_MEMORY_MMAP;
1608             buf.index = i;
1609
1610             if( ioctl( i_fd, VIDIOC_QBUF, &buf ) < 0 )
1611             {
1612                 msg_Err( p_demux, "VIDIOC_QBUF failed" );
1613                 goto open_failed;
1614             }
1615         }
1616
1617         buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1618         if( ioctl( i_fd, VIDIOC_STREAMON, &buf_type ) < 0 )
1619         {
1620             msg_Err( p_demux, "VIDIOC_STREAMON failed" );
1621             goto open_failed;
1622         }
1623
1624         break;
1625
1626     case IO_METHOD_USERPTR:
1627         for( unsigned int i = 0; i < p_sys->i_nbuffers; ++i )
1628         {
1629             struct v4l2_buffer buf;
1630
1631             memset( &buf, 0, sizeof(buf) );
1632             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1633             buf.memory = V4L2_MEMORY_USERPTR;
1634             buf.index = i;
1635             buf.m.userptr = (unsigned long)p_sys->p_buffers[i].start;
1636             buf.length = p_sys->p_buffers[i].length;
1637
1638             if( ioctl( i_fd, VIDIOC_QBUF, &buf ) < 0 )
1639             {
1640                 msg_Err( p_demux, "VIDIOC_QBUF failed" );
1641                 goto open_failed;
1642             }
1643         }
1644
1645         buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1646         if( ioctl( i_fd, VIDIOC_STREAMON, &buf_type ) < 0 )
1647         {
1648             msg_Err( p_demux, "VIDIOC_STREAMON failed" );
1649             goto open_failed;
1650         }
1651
1652         break;
1653     }
1654
1655     /* report fps */
1656     if( p_sys->f_fps >= 0.1 )
1657     {
1658         msg_Dbg( p_demux, "User set fps=%f", p_sys->f_fps );
1659     }
1660
1661     return i_fd;
1662
1663 open_failed:
1664     if( i_fd >= 0 ) close( i_fd );
1665     return -1;
1666
1667 }
1668
1669 #ifdef HAVE_ALSA
1670 /*****************************************************************************
1671  * ResolveALSADeviceName: Change any . to : in the ALSA device name
1672  *****************************************************************************/
1673 char* ResolveALSADeviceName( char *psz_device )
1674 {
1675     char* psz_alsa_name = strdup( psz_device );
1676     for( unsigned int i = 0; i < strlen( psz_device ); i++ )
1677     {
1678         if( psz_alsa_name[i] == '.' ) psz_alsa_name[i] = ':';
1679     }
1680     return psz_alsa_name;
1681 }
1682 #endif
1683
1684 /*****************************************************************************
1685  * OpenAudioDev: open and set up the audio device and probe for capabilities
1686  *****************************************************************************/
1687 int OpenAudioDev( demux_t *p_demux, char *psz_device )
1688 {
1689     demux_sys_t *p_sys = p_demux->p_sys;
1690     int i_fd = 0;
1691     int i_format;
1692 #ifdef HAVE_ALSA
1693     p_sys->p_alsa_pcm = NULL;
1694     char* psz_alsa_device_name = ResolveALSADeviceName( psz_device );
1695     snd_pcm_hw_params_t *p_hw_params = NULL;
1696     snd_pcm_uframes_t buffer_size;
1697     snd_pcm_uframes_t chunk_size;
1698 #endif
1699
1700 #ifdef HAVE_ALSA
1701     if( p_sys->b_use_alsa )
1702     {
1703         /* ALSA */
1704
1705         int i_err;
1706
1707         if( ( i_err = snd_pcm_open( &p_sys->p_alsa_pcm, psz_alsa_device_name,
1708             SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK ) ) < 0)
1709         {
1710             msg_Err( p_demux, "Cannot open ALSA audio device %s (%s)",
1711                 psz_alsa_device_name,
1712                 snd_strerror( i_err ) );
1713             goto adev_fail;
1714         }
1715
1716         if( ( i_err = snd_pcm_nonblock( p_sys->p_alsa_pcm, 1 ) ) < 0)
1717         {
1718             msg_Err( p_demux, "Cannot set ALSA nonblock (%s)", 
1719                 snd_strerror( i_err ) );
1720             goto adev_fail;
1721         }
1722
1723         /* Begin setting hardware parameters */
1724
1725         if( ( i_err = snd_pcm_hw_params_malloc( &p_hw_params ) ) < 0 )
1726         {
1727             msg_Err( p_demux, "ALSA: cannot allocate hardware parameter structure (%s)",
1728                 snd_strerror( i_err ) );
1729             goto adev_fail;
1730         }
1731
1732         if( ( i_err = snd_pcm_hw_params_any( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
1733         {
1734             msg_Err( p_demux, "ALSA: cannot initialize hardware parameter structure (%s)",
1735                 snd_strerror( i_err ) );
1736             goto adev_fail;
1737         }
1738
1739         /* Set Interleaved access */
1740         if( ( i_err = snd_pcm_hw_params_set_access( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
1741         {
1742             msg_Err( p_demux, "ALSA: cannot set access type (%s)",
1743                 snd_strerror( i_err ) );
1744             goto adev_fail;
1745         }
1746
1747         /* Set 16 bit little endian */
1748         if( ( i_err = snd_pcm_hw_params_set_format( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_FORMAT_S16_LE ) ) < 0 )
1749         {
1750             msg_Err( p_demux, "ALSA: cannot set sample format (%s)",
1751                 snd_strerror( i_err ) );
1752             goto adev_fail;
1753         }
1754
1755         /* Set sample rate */
1756 #ifdef HAVE_ALSA_NEW_API
1757         i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, &p_sys->i_sample_rate, NULL );
1758 #else
1759         i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, p_sys->i_sample_rate, NULL );
1760 #endif
1761         if( i_err < 0 )
1762         {
1763             msg_Err( p_demux, "ALSA: cannot set sample rate (%s)",
1764                 snd_strerror( i_err ) );
1765             goto adev_fail;
1766         }
1767
1768         /* Set channels */
1769         unsigned int channels = p_sys->b_stereo ? 2 : 1;
1770         if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
1771         {
1772             channels = ( channels==1 ) ? 2 : 1;
1773             msg_Warn( p_demux, "ALSA: cannot set channel count (%s). Trying with channels=%d",
1774                 snd_strerror( i_err ),
1775                 channels );
1776             if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
1777             {
1778                 msg_Err( p_demux, "ALSA: cannot set channel count (%s)",
1779                     snd_strerror( i_err ) );
1780                 goto adev_fail;
1781             }
1782             p_sys->b_stereo = ( channels == 2 );
1783         }
1784
1785         /* Set metrics for buffer calculations later */
1786         unsigned int buffer_time;
1787         if( ( i_err = snd_pcm_hw_params_get_buffer_time_max(p_hw_params, &buffer_time, 0) ) < 0 )
1788         {
1789             msg_Err( p_demux, "ALSA: cannot get buffer time max (%s)",
1790                 snd_strerror( i_err ) );
1791             goto adev_fail;
1792         }
1793         if (buffer_time > 500000) buffer_time = 500000;
1794
1795         /* Set period time */
1796         unsigned int period_time = buffer_time / 4;
1797 #ifdef HAVE_ALSA_NEW_API
1798         i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, &period_time, 0 );
1799 #else
1800         i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, period_time, 0 );
1801 #endif
1802         if( i_err < 0 )
1803         {
1804             msg_Err( p_demux, "ALSA: cannot set period time (%s)",
1805                 snd_strerror( i_err ) );
1806             goto adev_fail;
1807         }
1808
1809         /* Set buffer time */
1810 #ifdef HAVE_ALSA_NEW_API
1811         i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, &buffer_time, 0 );
1812 #else
1813         i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, buffer_time, 0 );
1814 #endif
1815         if( i_err < 0 )
1816         {
1817             msg_Err( p_demux, "ALSA: cannot set buffer time (%s)",
1818                 snd_strerror( i_err ) );
1819             goto adev_fail;
1820         }
1821
1822         /* Apply new hardware parameters */
1823         if( ( i_err = snd_pcm_hw_params( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
1824         {
1825             msg_Err( p_demux, "ALSA: cannot set hw parameters (%s)",
1826                 snd_strerror( i_err ) );
1827             goto adev_fail;
1828         }
1829
1830         /* Get various buffer metrics */
1831         snd_pcm_hw_params_get_period_size( p_hw_params, &chunk_size, 0 );
1832         snd_pcm_hw_params_get_buffer_size( p_hw_params, &buffer_size );
1833         if (chunk_size == buffer_size)
1834         {
1835             msg_Err( p_demux, "ALSA: period cannot equal buffer size (%lu == %lu)",
1836                 chunk_size, buffer_size);
1837             goto adev_fail;
1838         }
1839
1840         int bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE);
1841         int bits_per_frame = bits_per_sample * channels;
1842
1843         p_sys->i_alsa_chunk_size = chunk_size;
1844         p_sys->i_alsa_frame_size = (bits_per_sample / 8) * channels;
1845         p_sys->i_audio_max_frame_size = chunk_size * bits_per_frame / 8; 
1846
1847         snd_pcm_hw_params_free( p_hw_params );
1848         p_hw_params = NULL;
1849
1850         /* Prep device */
1851         if( ( i_err = snd_pcm_prepare( p_sys->p_alsa_pcm ) ) < 0 )
1852         {
1853             msg_Err( p_demux, "ALSA: cannot prepare audio interface for use (%s)",
1854                 snd_strerror( i_err ) );
1855             goto adev_fail;
1856         }
1857
1858         /* Return a fake handle so other tests work */
1859         i_fd = 1;
1860
1861     }
1862     else
1863 #endif /* HAVE_ALSA */
1864     {
1865         /* OSS */
1866
1867         if( (i_fd = open( psz_device, O_RDONLY | O_NONBLOCK )) < 0 )
1868         {
1869             msg_Err( p_demux, "cannot open OSS audio device (%m)" );
1870             goto adev_fail;
1871         }
1872
1873         i_format = AFMT_S16_LE;
1874         if( ioctl( i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0
1875             || i_format != AFMT_S16_LE )
1876         {
1877             msg_Err( p_demux, "cannot set audio format (16b little endian) "
1878                      "(%m)" );
1879             goto adev_fail;
1880         }
1881
1882         if( ioctl( i_fd, SNDCTL_DSP_STEREO,
1883                    &p_sys->b_stereo ) < 0 )
1884         {
1885             msg_Err( p_demux, "cannot set audio channels count (%m)" );
1886             goto adev_fail;
1887         }
1888
1889         if( ioctl( i_fd, SNDCTL_DSP_SPEED,
1890                    &p_sys->i_sample_rate ) < 0 )
1891         {
1892             msg_Err( p_demux, "cannot set audio sample rate (%m)" );
1893             goto adev_fail;
1894         }
1895
1896         p_sys->i_audio_max_frame_size = 6 * 1024;
1897     }
1898
1899     msg_Dbg( p_demux, "opened adev=`%s' %s %dHz",
1900              psz_device, p_sys->b_stereo ? "stereo" : "mono",
1901              p_sys->i_sample_rate );
1902
1903     es_format_t fmt;
1904     es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );
1905
1906     fmt.audio.i_channels = p_sys->b_stereo ? 2 : 1;
1907     fmt.audio.i_rate = p_sys->i_sample_rate;
1908     fmt.audio.i_bitspersample = 16;
1909     fmt.audio.i_blockalign = fmt.audio.i_channels * fmt.audio.i_bitspersample / 8;
1910     fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate * fmt.audio.i_bitspersample;
1911
1912     msg_Dbg( p_demux, "new audio es %d channels %dHz",
1913       fmt.audio.i_channels, fmt.audio.i_rate );
1914
1915     p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
1916
1917 #ifdef HAVE_ALSA
1918     free( psz_alsa_device_name );
1919 #endif
1920
1921     return i_fd;
1922
1923  adev_fail:
1924
1925     if( i_fd >= 0 ) close( i_fd );
1926
1927 #ifdef HAVE_ALSA
1928     if( p_hw_params ) snd_pcm_hw_params_free( p_hw_params );
1929     if( p_sys->p_alsa_pcm ) snd_pcm_close( p_sys->p_alsa_pcm );
1930     free( psz_alsa_device_name );
1931 #endif
1932
1933     return -1;
1934
1935 }
1936
1937 /*****************************************************************************
1938  * ProbeVideoDev: probe video for capabilities
1939  *****************************************************************************/
1940 vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
1941 {
1942     int i_index;
1943     int i_standard;
1944
1945     int i_fd;
1946     demux_sys_t *p_sys = p_demux->p_sys;
1947
1948     if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 )
1949     {
1950         msg_Err( p_demux, "cannot open video device (%m)" );
1951         goto open_failed;
1952     }
1953
1954     /* Get device capabilites */
1955
1956     if( ioctl( i_fd, VIDIOC_QUERYCAP, &p_sys->dev_cap ) < 0 )
1957     {
1958         msg_Err( p_demux, "cannot get video capabilities (%m)" );
1959         goto open_failed;
1960     }
1961
1962     msg_Dbg( p_demux, "V4L2 device: %s using driver: %s (version: %u.%u.%u) on %s",
1963                             p_sys->dev_cap.card,
1964                             p_sys->dev_cap.driver,
1965                             (p_sys->dev_cap.version >> 16) & 0xFF,
1966                             (p_sys->dev_cap.version >> 8) & 0xFF,
1967                             p_sys->dev_cap.version & 0xFF,
1968                             p_sys->dev_cap.bus_info );
1969
1970     msg_Dbg( p_demux, "the device has the capabilities: (%c) Video Capure, "
1971                                                        "(%c) Audio, "
1972                                                        "(%c) Tuner",
1973              ( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE  ? 'X':' '),
1974              ( p_sys->dev_cap.capabilities & V4L2_CAP_AUDIO  ? 'X':' '),
1975              ( p_sys->dev_cap.capabilities & V4L2_CAP_TUNER  ? 'X':' ') );
1976
1977     msg_Dbg( p_demux, "supported I/O methods are: (%c) Read/Write, "
1978                                                  "(%c) Streaming, "
1979                                                  "(%c) Asynchronous",
1980             ( p_sys->dev_cap.capabilities & V4L2_CAP_READWRITE ? 'X':' ' ),
1981             ( p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING ? 'X':' ' ),
1982             ( p_sys->dev_cap.capabilities & V4L2_CAP_ASYNCIO ? 'X':' ' ) );
1983
1984     /* Now, enumerate all the video inputs. This is useless at the moment
1985        since we have no way to present that info to the user except with
1986        debug messages */
1987
1988     if( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
1989     {
1990         while( ioctl( i_fd, VIDIOC_S_INPUT, &p_sys->i_input ) >= 0 )
1991         {
1992             p_sys->i_input++;
1993         }
1994
1995         p_sys->p_inputs = calloc( 1, p_sys->i_input * sizeof( struct v4l2_input ) );
1996         if( !p_sys->p_inputs ) goto open_failed;
1997
1998         for( i_index = 0; i_index < p_sys->i_input; i_index++ )
1999         {
2000             p_sys->p_inputs[i_index].index = i_index;
2001
2002             if( ioctl( i_fd, VIDIOC_ENUMINPUT, &p_sys->p_inputs[i_index] ) )
2003             {
2004                 msg_Err( p_demux, "cannot get video input characteristics (%m)" );
2005                 goto open_failed;
2006             }
2007             msg_Dbg( p_demux, "video input %i (%s) has type: %s",
2008                                 i_index,
2009                                 p_sys->p_inputs[i_index].name,
2010                                 p_sys->p_inputs[i_index].type
2011                                         == V4L2_INPUT_TYPE_TUNER ?
2012                                         "Tuner adapter" :
2013                                         "External analog input" );
2014         }
2015     }
2016
2017     /* Probe video standards */
2018     if( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
2019     {
2020         struct v4l2_standard t_standards;
2021         t_standards.index = 0;
2022         while( ioctl( i_fd, VIDIOC_ENUMSTD, &t_standards ) >=0 )
2023         {
2024             p_sys->i_standard++;
2025             t_standards.index = p_sys->i_standard;
2026         }
2027
2028         p_sys->p_standards = calloc( 1, p_sys->i_standard * sizeof( struct v4l2_standard ) );
2029         if( !p_sys->p_standards ) goto open_failed;
2030
2031         for( i_standard = 0; i_standard < p_sys->i_standard; i_standard++ )
2032         {
2033             p_sys->p_standards[i_standard].index = i_standard;
2034
2035             if( ioctl( i_fd, VIDIOC_ENUMSTD, &p_sys->p_standards[i_standard] ) )
2036             {
2037                 msg_Err( p_demux, "cannot get video input standards (%m)" );
2038                 goto open_failed;
2039             }
2040             msg_Dbg( p_demux, "video standard %i is: %s",
2041                                 i_standard,
2042                                 p_sys->p_standards[i_standard].name);
2043         }
2044     }
2045
2046     /* initialize the structures for the ioctls */
2047     for( i_index = 0; i_index < 32; i_index++ )
2048     {
2049         p_sys->p_audios[i_index].index = i_index;
2050     }
2051
2052     /* Probe audio inputs */
2053
2054     if( p_sys->dev_cap.capabilities & V4L2_CAP_AUDIO )
2055     {
2056         while( p_sys->i_audio < 32 &&
2057                ioctl( i_fd, VIDIOC_S_AUDIO, &p_sys->p_audios[p_sys->i_audio] ) >= 0 )
2058         {
2059             if( ioctl( i_fd, VIDIOC_G_AUDIO, &p_sys->p_audios[ p_sys->i_audio] ) < 0 )
2060             {
2061                 msg_Err( p_demux, "cannot get audio input characteristics (%m)" );
2062                 goto open_failed;
2063             }
2064
2065             msg_Dbg( p_demux, "audio device %i (%s) is %s",
2066                                 p_sys->i_audio,
2067                                 p_sys->p_audios[p_sys->i_audio].name,
2068                                 p_sys->p_audios[p_sys->i_audio].capability &
2069                                                     V4L2_AUDCAP_STEREO ?
2070                                         "Stereo" : "Mono" );
2071
2072             p_sys->i_audio++;
2073         }
2074     }
2075
2076     if( p_sys->dev_cap.capabilities & V4L2_CAP_TUNER )
2077     {
2078         struct v4l2_tuner tuner;
2079
2080         memset( &tuner, 0, sizeof(tuner) );
2081         while( ioctl( i_fd, VIDIOC_S_TUNER, &tuner ) >= 0 )
2082         {
2083             p_sys->i_tuner++;
2084             tuner.index = p_sys->i_tuner;
2085         }
2086
2087         p_sys->p_tuners = calloc( 1, p_sys->i_tuner * sizeof( struct v4l2_tuner ) );
2088         if( !p_sys->p_tuners ) goto open_failed;
2089
2090         for( i_index = 0; i_index < p_sys->i_tuner; i_index++ )
2091         {
2092             p_sys->p_tuners[i_index].index = i_index;
2093
2094             if( ioctl( i_fd, VIDIOC_G_TUNER, &p_sys->p_tuners[i_index] ) )
2095             {
2096                 msg_Err( p_demux, "cannot get tuner characteristics (%m)" );
2097                 goto open_failed;
2098             }
2099             msg_Dbg( p_demux, "tuner %i (%s) has type: %s, "
2100                               "frequency range: %.1f %s -> %.1f %s",
2101                                 i_index,
2102                                 p_sys->p_tuners[i_index].name,
2103                                 p_sys->p_tuners[i_index].type
2104                                         == V4L2_TUNER_RADIO ?
2105                                         "Radio" : "Analog TV",
2106                                 p_sys->p_tuners[i_index].rangelow * 62.5,
2107                                 p_sys->p_tuners[i_index].capability &
2108                                         V4L2_TUNER_CAP_LOW ?
2109                                         "Hz" : "kHz",
2110                                 p_sys->p_tuners[i_index].rangehigh * 62.5,
2111                                 p_sys->p_tuners[i_index].capability &
2112                                         V4L2_TUNER_CAP_LOW ?
2113                                         "Hz" : "kHz" );
2114         }
2115     }
2116
2117     /* Probe for available chromas */
2118     if( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
2119     {
2120         struct v4l2_fmtdesc codec;
2121
2122         i_index = 0;
2123         memset( &codec, 0, sizeof(codec) );
2124         codec.index = i_index;
2125         codec.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2126
2127         while( ioctl( i_fd, VIDIOC_ENUM_FMT, &codec ) >= 0 )
2128         {
2129             i_index++;
2130             codec.index = i_index;
2131         }
2132
2133         p_sys->i_codec = i_index;
2134
2135         p_sys->p_codecs = calloc( 1, p_sys->i_codec * sizeof( struct v4l2_fmtdesc ) );
2136
2137         for( i_index = 0; i_index < p_sys->i_codec; i_index++ )
2138         {
2139             p_sys->p_codecs[i_index].index = i_index;
2140             p_sys->p_codecs[i_index].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2141
2142             if( ioctl( i_fd, VIDIOC_ENUM_FMT, &p_sys->p_codecs[i_index] ) < 0 )
2143             {
2144                 msg_Err( p_demux, "cannot get codec description (%m)" );
2145                 goto open_failed;
2146             }
2147
2148             /* only print if vlc supports the format */
2149             vlc_bool_t b_codec_supported = VLC_FALSE;
2150             for( int i = 0; v4l2chroma_to_fourcc[i].i_v4l2 != 0; i++ )
2151             {
2152                 if( v4l2chroma_to_fourcc[i].i_v4l2 == p_sys->p_codecs[i_index].pixelformat )
2153                 {
2154                     b_codec_supported = VLC_TRUE;
2155
2156                     char sz_fourcc[5];
2157                     memset( &sz_fourcc, 0, sizeof( sz_fourcc ) );
2158                     vlc_fourcc_to_char( v4l2chroma_to_fourcc[i].i_fourcc, &sz_fourcc );
2159                     msg_Dbg( p_demux, "device supports chroma %4s [%s]",
2160                                 sz_fourcc,
2161                                 p_sys->p_codecs[i_index].description );
2162
2163 #ifdef VIDIOC_ENUM_FRAMESIZES
2164                     /* This is new in Linux 2.6.19 */
2165                     /* List valid frame sizes for this format */
2166                     struct v4l2_frmsizeenum frmsize;
2167                     frmsize.index = 0;
2168                     frmsize.pixel_format = p_sys->p_codecs[i_index].pixelformat;
2169                     if( ioctl( i_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize ) < 0 )
2170                     {
2171                         msg_Err( p_demux, "Error while querying for frame size" );
2172                     }
2173                     else
2174                     {
2175                         switch( frmsize.type )
2176                         {
2177                             case V4L2_FRMSIZE_TYPE_DISCRETE:
2178                                 do
2179                                 {
2180                                     msg_Dbg( p_demux,
2181                 "    device supports size %dx%d",
2182                 frmsize.discrete.width, frmsize.discrete.height );
2183                                     frmsize.index++;
2184                                 } while( ioctl( i_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize ) >= 0 );
2185                                 break;
2186                             case V4L2_FRMSIZE_TYPE_STEPWISE:
2187                                 msg_Dbg( p_demux,
2188                 "    device supports sizes %dx%d to %dx%d using %dx%d increments",
2189                 frmsize.stepwise.min_width, frmsize.stepwise.min_height,
2190                 frmsize.stepwise.max_width, frmsize.stepwise.max_height,
2191                 frmsize.stepwise.step_width, frmsize.stepwise.step_height );
2192                                 break;
2193                             case V4L2_FRMSIZE_TYPE_CONTINUOUS:
2194                                 msg_Dbg( p_demux,
2195                 "    device supports all sizes %dx%d to %dx%d",
2196                 frmsize.stepwise.min_width, frmsize.stepwise.min_height,
2197                 frmsize.stepwise.max_width, frmsize.stepwise.max_height );
2198                                 break;
2199                         }
2200                     }
2201 #endif
2202                 }
2203             }
2204             if( !b_codec_supported )
2205             {
2206                 msg_Dbg( p_demux, "device codec %s not supported",
2207                     p_sys->p_codecs[i_index].description );
2208             }
2209
2210         }
2211     }
2212
2213
2214     if( i_fd >= 0 ) close( i_fd );
2215     return VLC_TRUE;
2216
2217 open_failed:
2218
2219     if( i_fd >= 0 ) close( i_fd );
2220     return VLC_FALSE;
2221
2222 }
2223
2224 /*****************************************************************************
2225  * ProbeAudioDev: probe audio for capabilities
2226  *****************************************************************************/
2227 vlc_bool_t ProbeAudioDev( demux_t *p_demux, char *psz_device )
2228 {
2229     int i_fd = 0;
2230     int i_caps;
2231
2232 #ifdef HAVE_ALSA
2233     demux_sys_t *p_sys = p_demux->p_sys;
2234
2235     if( p_sys->b_use_alsa )
2236     {
2237         /* ALSA */
2238
2239         int i_err;
2240         snd_pcm_t *p_alsa_pcm;
2241         char* psz_alsa_device_name = ResolveALSADeviceName( psz_device );
2242
2243         if( ( i_err = snd_pcm_open( &p_alsa_pcm, psz_alsa_device_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK ) ) < 0 )
2244         {
2245             msg_Err( p_demux, "cannot open device %s for ALSA audio (%s)", psz_alsa_device_name, snd_strerror( i_err ) );
2246             free( psz_alsa_device_name );
2247             goto open_failed;
2248         }
2249
2250         snd_pcm_close( p_alsa_pcm );
2251         free( psz_alsa_device_name );
2252     }
2253     else
2254 #endif /* HAVE_ALSA */
2255     {
2256         /* OSS */
2257
2258         if( ( i_fd = open( psz_device, O_RDONLY | O_NONBLOCK ) ) < 0 )
2259         {
2260             msg_Err( p_demux, "cannot open device %s for OSS audio (%m)", psz_device );
2261             goto open_failed;
2262         }
2263
2264         /* this will fail if the device is video */
2265         if( ioctl( i_fd, SNDCTL_DSP_GETCAPS, &i_caps ) < 0 )
2266         {
2267             msg_Err( p_demux, "cannot get audio caps (%m)" );
2268             goto open_failed;
2269         }
2270
2271         if( i_fd >= 0 ) close( i_fd );
2272     }
2273
2274     return VLC_TRUE;
2275
2276 open_failed:
2277     if( i_fd >= 0 ) close( i_fd );
2278     return VLC_FALSE;
2279
2280 }
2281
2282 /*****************************************************************************
2283  * List available controls
2284  *****************************************************************************/
2285 static int VideoControlList( demux_t *p_demux, int i_fd )
2286 {
2287     struct v4l2_queryctrl queryctrl;
2288     struct v4l2_querymenu querymenu;
2289
2290     memset( &queryctrl, 0, sizeof( queryctrl ) );
2291
2292     /* List public controls */
2293     for( queryctrl.id = V4L2_CID_BASE;
2294          queryctrl.id < V4L2_CID_LASTP1;
2295          queryctrl.id ++ )
2296     {
2297         if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 )
2298         {
2299             if( queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
2300                 continue;
2301             msg_Dbg( p_demux, "Available control: %s (%x)",
2302                      queryctrl.name, queryctrl.id );
2303             if( queryctrl.flags & V4L2_CTRL_FLAG_GRABBED )
2304                 msg_Dbg( p_demux, "    control is busy" );
2305             if( queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY )
2306                 msg_Dbg( p_demux, "    control is read-only" );
2307             switch( queryctrl.type )
2308             {
2309                 case V4L2_CTRL_TYPE_INTEGER:
2310                     msg_Dbg( p_demux, "    integer control" );
2311                     msg_Dbg( p_demux,
2312                              "    valid values: %d to %d by steps of %d",
2313                              queryctrl.minimum, queryctrl.maximum,
2314                              queryctrl.step );
2315                     msg_Dbg( p_demux, "    default value: %d",
2316                              queryctrl.default_value );
2317                     break;
2318                 case V4L2_CTRL_TYPE_BOOLEAN:
2319                     msg_Dbg( p_demux, "    boolean control" );
2320                     msg_Dbg( p_demux, "    default value: %d",
2321                              queryctrl.default_value );
2322                     break;
2323                 case V4L2_CTRL_TYPE_MENU:
2324                     msg_Dbg( p_demux, "    menu control" );
2325                     memset( &querymenu, 0, sizeof( querymenu ) );
2326                     for( querymenu.index = queryctrl.minimum;
2327                          querymenu.index <= (unsigned)queryctrl.maximum;
2328                          querymenu.index++ )
2329                     {
2330                         if( ioctl( i_fd, VIDIOC_QUERYMENU, &querymenu ) >= 0 )
2331                         {
2332                             msg_Dbg( p_demux, "        %d: %s",
2333                                      querymenu.index, querymenu.name );
2334                         }
2335                     }
2336                     msg_Dbg( p_demux, "    default value: %d",
2337                              queryctrl.default_value );
2338                     break;
2339                 case V4L2_CTRL_TYPE_BUTTON:
2340                     msg_Dbg( p_demux, "    button control" );
2341                     break;
2342                 default:
2343                     msg_Dbg( p_demux, "    unknown control type (FIXME)" );
2344                     /* FIXME */
2345                     break;
2346             }
2347         }
2348     }
2349
2350     /* List private controls */
2351     for( queryctrl.id = V4L2_CID_PRIVATE_BASE;
2352          ;
2353          queryctrl.id ++ )
2354     {
2355         if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 )
2356         {
2357             if( queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
2358                 continue;
2359             msg_Dbg( p_demux, "Available private control: %s",
2360                      queryctrl.name );
2361         }
2362         else
2363             break;
2364     }
2365     return VLC_SUCCESS;
2366 }
2367
2368 /*****************************************************************************
2369  * Issue video controls
2370  *****************************************************************************/
2371 static int VideoControl( demux_t *p_demux, int i_fd,
2372                          const char *psz_label, int i_cid, int i_value )
2373 {
2374     struct v4l2_queryctrl queryctrl;
2375     struct v4l2_control control;
2376     memset( &queryctrl, 0, sizeof( queryctrl ) );
2377
2378     if( i_value == -1 )
2379         return VLC_SUCCESS;
2380
2381     queryctrl.id = i_cid;
2382
2383     if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) < 0
2384         || queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
2385     {
2386         msg_Err( p_demux, "%s (%x) control is not supported.", psz_label,
2387                  i_value );
2388         return VLC_EGENERIC;
2389     }
2390
2391     memset( &control, 0, sizeof( control ) );
2392     control.id = i_cid;
2393
2394     if( i_value >= 0 )
2395     {
2396         control.value = i_value;
2397         if( ioctl( i_fd, VIDIOC_S_CTRL, &control ) < 0 )
2398         {
2399             msg_Err( p_demux, "unable to set %s to %d (%m)", psz_label,
2400                      i_value );
2401             return VLC_EGENERIC;
2402         }
2403     }
2404     if( ioctl( i_fd, VIDIOC_G_CTRL, &control ) >= 0 )
2405     {
2406         msg_Dbg( p_demux, "video %s: %d", psz_label, control.value );
2407     }
2408     return VLC_SUCCESS;
2409 }
2410
2411 /*****************************************************************************
2412  * On the fly change settings callback
2413  *****************************************************************************/
2414 static int VideoControlCallback( vlc_object_t *p_this,
2415     const char *psz_var, vlc_value_t oldval, vlc_value_t newval,
2416     void *p_data )
2417 {
2418     demux_t *p_demux = (demux_t*)p_this;
2419     demux_sys_t *p_sys = p_demux->p_sys;
2420
2421     int i_fd = p_sys->i_fd_video;
2422
2423     if( i_fd < 0 )
2424         return VLC_EGENERIC;
2425
2426     if( !strcmp( psz_var, "v4l2-brightness" ) )
2427     {
2428         p_sys->i_brightness = newval.i_int;
2429         return VideoControl( p_demux, i_fd,
2430                     "brightness", V4L2_CID_BRIGHTNESS, p_sys->i_brightness );
2431     }
2432     else if( !strcmp( psz_var, "v4l2-contrast" ) )
2433     {
2434         p_sys->i_contrast = newval.i_int;
2435         return VideoControl( p_demux, i_fd,
2436                     "contrast", V4L2_CID_CONTRAST, p_sys->i_contrast );
2437     }
2438     else if( !strcmp( psz_var, "v4l2-saturation" ) )
2439     {
2440         p_sys->i_saturation = newval.i_int;
2441         return VideoControl( p_demux, i_fd,
2442                     "saturation", V4L2_CID_SATURATION, p_sys->i_saturation );
2443     }
2444     else if( !strcmp( psz_var, "v4l2-hue" ) )
2445     {
2446         p_sys->i_hue = newval.i_int;
2447         return VideoControl( p_demux, i_fd,
2448                     "hue", V4L2_CID_HUE, p_sys->i_hue );
2449     }
2450
2451     return VLC_EGENERIC;
2452 }