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