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