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