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