]> git.sesse.net Git - vlc/blob - modules/access/v4l.c
Remove stdlib.h
[vlc] / modules / access / v4l.c
1 /*****************************************************************************
2  * v4l.c : Video4Linux input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2002-2004 the VideoLAN team
5  * $Id$
6  *
7  * Author: Laurent Aimar <fenrir@via.ecp.fr>
8  *         Paul Forgey <paulf at aphrodite dot com>
9  *         Gildas Bazin <gbazin@videolan.org>
10  *         Benjamin Pracht <bigben at videolan dot org>
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  * Preamble
29  *****************************************************************************/
30 #define _GNU_SOURCE
31 #include <stdio.h>
32 #include <string.h>
33
34 #include <vlc/vlc.h>
35 #include <vlc_input.h>
36 #include <vlc_demux.h>
37 #include <vlc_access.h>
38 #include <vlc_vout.h>
39 #include <vlc_codecs.h>
40
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <sys/ioctl.h>
44 #include <unistd.h>
45 #include <sys/mman.h>
46 #include <errno.h>
47 #include <fcntl.h>
48
49 /* From GStreamer's v4l plugin:
50  * Because of some really cool feature in video4linux1, also known as
51  * 'not including sys/types.h and sys/time.h', we had to include it
52  * ourselves. In all their intelligence, these people decided to fix
53  * this in the next version (video4linux2) in such a cool way that it
54  * breaks all compilations of old stuff...
55  * The real problem is actually that linux/time.h doesn't use proper
56  * macro checks before defining types like struct timeval. The proper
57  * fix here is to either fuck the kernel header (which is what we do
58  * by defining _LINUX_TIME_H, an innocent little hack) or by fixing it
59  * upstream, which I'll consider doing later on. If you get compiler
60  * errors here, check your linux/time.h && sys/time.h header setup.
61 */
62 #define _LINUX_TIME_H
63
64 #include <linux/videodev.h>
65 #include "videodev_mjpeg.h"
66
67 #include <sys/soundcard.h>
68
69 /*****************************************************************************
70  * Module descriptior
71  *****************************************************************************/
72 static int  Open ( vlc_object_t * );
73 static void Close( vlc_object_t * );
74
75 #define CACHING_TEXT N_("Caching value in ms")
76 #define CACHING_LONGTEXT N_( \
77     "Caching value for V4L captures. This " \
78     "value should be set in milliseconds." )
79 #define VDEV_TEXT N_("Video device name")
80 #define VDEV_LONGTEXT N_( \
81     "Name of the video device to use. " \
82     "If you don't specify anything, no video device will be used.")
83 #define ADEV_TEXT N_("Audio device name")
84 #define ADEV_LONGTEXT N_( \
85     "Name of the audio device to use. " \
86     "If you don't specify anything, no audio device will be used.")
87 #define CHROMA_TEXT N_("Video input chroma format")
88 #define CHROMA_LONGTEXT N_( \
89     "Force the Video4Linux video device to use a specific chroma format " \
90     "(eg. I420 (default), RV24, etc.)")
91 #define FREQUENCY_TEXT N_( "Frequency" )
92 #define FREQUENCY_LONGTEXT N_( \
93     "Frequency to capture (in kHz), if applicable." )
94 #define CHANNEL_TEXT N_( "Channel" )
95 #define CHANNEL_LONGTEXT N_( \
96     "Channel of the card to use (Usually, 0 = tuner, " \
97     "1 = composite, 2 = svideo)." )
98 #define NORM_TEXT N_( "Norm" )
99 #define NORM_LONGTEXT N_( \
100     "Norm of the stream (Automatic, SECAM, PAL, or NTSC)." )
101 #define AUDIO_TEXT N_( "Audio Channel" )
102 #define AUDIO_LONGTEXT N_( \
103     "Audio Channel to use, if there are several audio inputs." )
104 #define WIDTH_TEXT N_( "Width" )
105 #define WIDTH_LONGTEXT N_( "Width of the stream to capture " \
106     "(-1 for autodetect)." )
107 #define HEIGHT_TEXT N_( "Height" )
108 #define HEIGHT_LONGTEXT N_( "Height of the stream to capture " \
109     "(-1 for autodetect)." )
110 #define BRIGHTNESS_TEXT N_( "Brightness" )
111 #define BRIGHTNESS_LONGTEXT N_( \
112     "Brightness of the video input." )
113 #define HUE_TEXT N_( "Hue" )
114 #define HUE_LONGTEXT N_( \
115     "Hue of the video input." )
116 #define COLOUR_TEXT N_( "Color" )
117 #define COLOUR_LONGTEXT N_( \
118     "Color of the video input." )
119 #define CONTRAST_TEXT N_( "Contrast" )
120 #define CONTRAST_LONGTEXT N_( \
121     "Contrast of the video input." )
122 #define TUNER_TEXT N_( "Tuner" )
123 #define TUNER_LONGTEXT N_( "Tuner to use, if there are several ones." )
124 #define SAMPLERATE_TEXT N_( "Samplerate" )
125 #define SAMPLERATE_LONGTEXT N_( \
126     "Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100)" )
127 #define STEREO_TEXT N_( "Stereo" )
128 #define STEREO_LONGTEXT N_( \
129     "Capture the audio stream in stereo." )
130 #define MJPEG_TEXT N_( "MJPEG" )
131 #define MJPEG_LONGTEXT N_(  \
132     "Set this option if the capture device outputs MJPEG" )
133 #define DECIMATION_TEXT N_( "Decimation" )
134 #define DECIMATION_LONGTEXT N_( \
135     "Decimation level for MJPEG streams" )
136 #define QUALITY_TEXT N_( "Quality" )
137 #define QUALITY_LONGTEXT N_( "Quality of the stream." )
138 #define FPS_TEXT N_( "Framerate" )
139 #define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \
140     "(-1 for autodetect)." )
141
142 static int i_norm_list[] =
143     { VIDEO_MODE_AUTO, VIDEO_MODE_SECAM, VIDEO_MODE_PAL, VIDEO_MODE_NTSC };
144 static const char *psz_norm_list_text[] =
145     { N_("Automatic"), N_("SECAM"), N_("PAL"),  N_("NTSC") };
146
147 vlc_module_begin();
148     set_shortname( _("Video4Linux") );
149     set_description( _("Video4Linux input") );
150     set_category( CAT_INPUT );
151     set_subcategory( SUBCAT_INPUT_ACCESS );
152
153     add_integer( "v4l-caching", DEFAULT_PTS_DELAY / 1000, NULL,
154                  CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
155     add_string( "v4l-vdev", "/dev/video", 0, VDEV_TEXT, VDEV_LONGTEXT,
156                 VLC_FALSE );
157     add_string( "v4l-adev", "/dev/dsp", 0, ADEV_TEXT, ADEV_LONGTEXT,
158                 VLC_FALSE );
159     add_string( "v4l-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT,
160                 VLC_TRUE );
161     add_float( "v4l-fps", -1.0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_TRUE );
162     add_integer( "v4l-samplerate", 44100, NULL, SAMPLERATE_TEXT,
163                 SAMPLERATE_LONGTEXT, VLC_TRUE );
164     add_integer( "v4l-channel", 0, NULL, CHANNEL_TEXT, CHANNEL_LONGTEXT,
165                 VLC_TRUE );
166     add_integer( "v4l-tuner", -1, NULL, TUNER_TEXT, TUNER_LONGTEXT, VLC_TRUE );
167     add_integer( "v4l-norm", VIDEO_MODE_AUTO, NULL, NORM_TEXT, NORM_LONGTEXT,
168                 VLC_FALSE );
169         change_integer_list( i_norm_list, psz_norm_list_text, 0 );
170     add_integer( "v4l-frequency", -1, NULL, FREQUENCY_TEXT, FREQUENCY_LONGTEXT,
171                 VLC_FALSE );
172     add_integer( "v4l-audio", -1, NULL, AUDIO_TEXT, AUDIO_LONGTEXT, VLC_TRUE );
173     add_bool( "v4l-stereo", VLC_TRUE, NULL, STEREO_TEXT, STEREO_LONGTEXT,
174             VLC_TRUE );
175     add_integer( "v4l-width", 0, NULL, WIDTH_TEXT, WIDTH_LONGTEXT, VLC_TRUE );
176     add_integer( "v4l-height", 0, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT,
177                 VLC_TRUE );
178     add_integer( "v4l-brightness", -1, NULL, BRIGHTNESS_TEXT,
179                 BRIGHTNESS_LONGTEXT, VLC_TRUE );
180     add_integer( "v4l-colour", -1, NULL, COLOUR_TEXT, COLOUR_LONGTEXT,
181                 VLC_TRUE );
182     add_integer( "v4l-hue", -1, NULL, HUE_TEXT, HUE_LONGTEXT, VLC_TRUE );
183     add_integer( "v4l-contrast", -1, NULL, CONTRAST_TEXT, CONTRAST_LONGTEXT,
184                 VLC_TRUE );
185     add_bool( "v4l-mjpeg", VLC_FALSE, NULL, MJPEG_TEXT, MJPEG_LONGTEXT,
186             VLC_TRUE );
187     add_integer( "v4l-decimation", 1, NULL, DECIMATION_TEXT,
188             DECIMATION_LONGTEXT, VLC_TRUE );
189     add_integer( "v4l-quality", 100, NULL, QUALITY_TEXT, QUALITY_LONGTEXT,
190             VLC_TRUE );
191
192     add_shortcut( "v4l" );
193     set_capability( "access_demux", 10 );
194     set_callbacks( Open, Close );
195 vlc_module_end();
196
197 /*****************************************************************************
198  * Access: local prototypes
199  *****************************************************************************/
200 static int Demux  ( demux_t * );
201 static int Control( demux_t *, int, va_list );
202
203 static void ParseMRL    ( demux_t * );
204 static int  OpenVideoDev( demux_t *, char * );
205 static int  OpenAudioDev( demux_t *, char * );
206
207 static block_t *GrabAudio( demux_t * );
208 static block_t *GrabVideo( demux_t * );
209
210 #define MJPEG_BUFFER_SIZE (256*1024)
211
212 struct quicktime_mjpeg_app1
213 {
214     uint32_t    i_reserved;             /* set to 0 */
215     uint32_t    i_tag;                  /* 'mjpg' */
216     uint32_t    i_field_size;           /* offset following EOI */
217     uint32_t    i_padded_field_size;    /* offset following EOI+pad */
218     uint32_t    i_next_field;           /* offset to next field */
219     uint32_t    i_DQT_offset;
220     uint32_t    i_DHT_offset;
221     uint32_t    i_SOF_offset;
222     uint32_t    i_SOS_offset;
223     uint32_t    i_data_offset;          /* following SOS marker data */
224 };
225
226 static struct
227 {
228     int i_v4l;
229     int i_fourcc;
230
231 } v4lchroma_to_fourcc[] =
232 {
233     { VIDEO_PALETTE_GREY, VLC_FOURCC( 'G', 'R', 'E', 'Y' ) },
234     { VIDEO_PALETTE_HI240, VLC_FOURCC( 'I', '2', '4', '0' ) },
235     { VIDEO_PALETTE_RGB565, VLC_FOURCC( 'R', 'V', '1', '6' ) },
236     { VIDEO_PALETTE_RGB555, VLC_FOURCC( 'R', 'V', '1', '5' ) },
237     { VIDEO_PALETTE_RGB24, VLC_FOURCC( 'R', 'V', '2', '4' ) },
238     { VIDEO_PALETTE_RGB32, VLC_FOURCC( 'R', 'V', '3', '2' ) },
239     { VIDEO_PALETTE_YUV422, VLC_FOURCC( 'Y', 'U', 'Y', '2' ) },
240     { VIDEO_PALETTE_YUV422, VLC_FOURCC( 'Y', 'U', 'Y', 'V' ) },
241     { VIDEO_PALETTE_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', '2' ) },
242     { VIDEO_PALETTE_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', 'V' ) },
243     { VIDEO_PALETTE_UYVY, VLC_FOURCC( 'U', 'Y', 'V', 'Y' ) },
244     { VIDEO_PALETTE_YUV420, VLC_FOURCC( 'I', '4', '2', 'N' ) },
245     { VIDEO_PALETTE_YUV411, VLC_FOURCC( 'I', '4', '1', 'N' ) },
246     { VIDEO_PALETTE_RAW, VLC_FOURCC( 'G', 'R', 'A', 'W' ) },
247     { VIDEO_PALETTE_YUV422P, VLC_FOURCC( 'I', '4', '2', '2' ) },
248     { VIDEO_PALETTE_YUV420P, VLC_FOURCC( 'I', '4', '2', '0' ) },
249     { VIDEO_PALETTE_YUV411P, VLC_FOURCC( 'I', '4', '1', '1' ) },
250     { 0, 0 }
251 };
252
253 struct demux_sys_t
254 {
255     /* Devices */
256     char *psz_device;         /* Main device from MRL, can be video or audio */
257
258     char *psz_vdev;
259     int  fd_video;
260
261     char *psz_adev;
262     int  fd_audio;
263
264     /* Video properties */
265     picture_t pic;
266
267     int i_fourcc;
268     int i_channel;
269     int i_audio;
270     int i_norm;
271     int i_tuner;
272     int i_frequency;
273     int i_width;
274     int i_height;
275
276     int i_brightness;
277     int i_hue;
278     int i_colour;
279     int i_contrast;
280
281     float f_fps;            /* <= 0.0 mean to grab at full rate */
282     mtime_t i_video_pts;    /* only used when f_fps > 0 */
283
284     vlc_bool_t b_mjpeg;
285     int i_decimation;
286     int i_quality;
287
288     struct video_capability vid_cap;
289     struct video_mbuf       vid_mbuf;
290     struct mjpeg_requestbuffers mjpeg_buffers;
291
292     uint8_t *p_video_mmap;
293     int     i_frame_pos;
294
295     struct video_mmap   vid_mmap;
296     struct video_picture vid_picture;
297
298     int          i_video_frame_size;
299     es_out_id_t  *p_es_video;
300
301     /* Audio properties */
302     vlc_fourcc_t i_acodec_raw;
303     int          i_sample_rate;
304     vlc_bool_t   b_stereo;
305     int          i_audio_max_frame_size;
306     block_t      *p_block_audio;
307     es_out_id_t  *p_es_audio;
308 };
309
310 /*****************************************************************************
311  * Open: opens v4l device
312  *****************************************************************************
313  *
314  * url: <video device>::::
315  *
316  *****************************************************************************/
317 static int Open( vlc_object_t *p_this )
318 {
319     demux_t     *p_demux = (demux_t*)p_this;
320     demux_sys_t *p_sys;
321     vlc_value_t val;
322
323     /* Only when selected */
324     if( *p_demux->psz_access == '\0' )
325         return VLC_EGENERIC;
326
327     /* Set up p_demux */
328     p_demux->pf_demux = Demux;
329     p_demux->pf_control = Control;
330     p_demux->info.i_update = 0;
331     p_demux->info.i_title = 0;
332     p_demux->info.i_seekpoint = 0;
333     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
334     memset( p_sys, 0, sizeof( demux_sys_t ) );
335
336     var_Create( p_demux, "v4l-audio", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
337     var_Get( p_demux, "v4l-audio", &val );
338     p_sys->i_audio          = val.i_int;
339
340     var_Create( p_demux, "v4l-channel", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
341     var_Get( p_demux, "v4l-channel", &val );
342     p_sys->i_channel        = val.i_int;
343
344     var_Create( p_demux, "v4l-norm", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
345     var_Get( p_demux, "v4l-norm", &val );
346     p_sys->i_norm           = val.i_int;
347
348     var_Create( p_demux, "v4l-tuner", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
349     var_Get( p_demux, "v4l-tuner", &val );
350     p_sys->i_tuner          = val.i_int;
351
352     var_Create( p_demux, "v4l-frequency",
353                                     VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
354     var_Get( p_demux, "v4l-frequency", &val );
355     p_sys->i_frequency      = val.i_int;
356
357     var_Create( p_demux, "v4l-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
358     var_Get( p_demux, "v4l-fps", &val );
359     p_sys->f_fps            = val.f_float;
360
361     var_Create( p_demux, "v4l-width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
362     var_Get( p_demux, "v4l-width", &val );
363     p_sys->i_width          = val.i_int;
364
365     var_Create( p_demux, "v4l-height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
366     var_Get( p_demux, "v4l-height", &val );
367     p_sys->i_height         = val.i_int;
368
369     p_sys->i_video_pts      = -1;
370
371     var_Create( p_demux, "v4l-brightness", VLC_VAR_INTEGER |
372                                                         VLC_VAR_DOINHERIT );
373     var_Get( p_demux, "v4l-brightness", &val );
374     p_sys->i_brightness     = val.i_int;
375
376     var_Create( p_demux, "v4l-hue", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
377     var_Get( p_demux, "v4l-hue", &val );
378     p_sys->i_hue            = -1;
379
380     var_Create( p_demux, "v4l-colour", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
381     var_Get( p_demux, "v4l-colour", &val );
382     p_sys->i_colour         = val.i_int;
383
384     var_Create( p_demux, "v4l-contrast", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
385     var_Get( p_demux, "v4l-contrast", &val );
386     p_sys->i_contrast       = val.i_int;
387
388     var_Create( p_demux, "v4l-mjpeg", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
389     var_Get( p_demux, "v4l-mjpeg", &val );
390     p_sys->b_mjpeg     = val.b_bool;
391
392     var_Create( p_demux, "v4l-decimation", VLC_VAR_INTEGER |
393                                                             VLC_VAR_DOINHERIT );
394     var_Get( p_demux, "v4l-decimation", &val );
395     p_sys->i_decimation = val.i_int;
396
397     var_Create( p_demux, "v4l-quality", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
398     var_Get( p_demux, "v4l-quality", &val );
399     p_sys->i_quality = val.i_int;
400
401     var_Create( p_demux, "v4l-samplerate",
402                                     VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
403     var_Get( p_demux, "v4l-samplerate", &val );
404     p_sys->i_sample_rate  = val.i_int;
405
406     var_Create( p_demux, "v4l-stereo", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
407     var_Get( p_demux, "v4l-stereo", &val );
408     p_sys->b_stereo       = val.b_bool;
409
410     p_sys->psz_device = p_sys->psz_vdev = p_sys->psz_adev = NULL;
411     p_sys->fd_video = -1;
412     p_sys->fd_audio = -1;
413
414     p_sys->p_es_video = p_sys->p_es_audio = 0;
415     p_sys->p_block_audio = 0;
416
417     ParseMRL( p_demux );
418
419     /* Find main device (video or audio) */
420     if( p_sys->psz_device && *p_sys->psz_device )
421     {
422         msg_Dbg( p_demux, "main device=`%s'", p_sys->psz_device );
423
424         /* Try to open as video device */
425         p_sys->fd_video = OpenVideoDev( p_demux, p_sys->psz_device );
426
427         if( p_sys->fd_video < 0 )
428         {
429             /* Try to open as audio device */
430             p_sys->fd_audio = OpenAudioDev( p_demux, p_sys->psz_device );
431             if( p_sys->fd_audio >= 0 )
432             {
433                 if( p_sys->psz_adev ) free( p_sys->psz_adev );
434                 p_sys->psz_adev = p_sys->psz_device;
435                 p_sys->psz_device = NULL;
436             }
437         }
438         else
439         {
440             if( p_sys->psz_vdev ) free( p_sys->psz_vdev );
441             p_sys->psz_vdev = p_sys->psz_device;
442             p_sys->psz_device = NULL;
443         }
444     }
445
446     /* If no device opened, only continue if the access was forced */
447     if( p_sys->fd_video < 0 && p_sys->fd_audio < 0 )
448     {
449         if( strcmp( p_demux->psz_access, "v4l" ) )
450         {
451             Close( p_this );
452             return VLC_EGENERIC;
453         }
454     }
455
456     /* Find video device */
457     if( p_sys->fd_video < 0 )
458     {
459         if( !p_sys->psz_vdev || !*p_sys->psz_vdev )
460         {
461             if( p_sys->psz_vdev ) free( p_sys->psz_vdev );
462             p_sys->psz_vdev = var_CreateGetString( p_demux, "v4l-vdev" );;
463         }
464
465         if( p_sys->psz_vdev && *p_sys->psz_vdev )
466         {
467             p_sys->fd_video = OpenVideoDev( p_demux, p_sys->psz_vdev );
468         }
469     }
470
471     /* Find audio device */
472     if( p_sys->fd_audio < 0 )
473     {
474         if( !p_sys->psz_adev || !*p_sys->psz_adev )
475         {
476             if( p_sys->psz_adev ) free( p_sys->psz_adev );
477             p_sys->psz_adev = var_CreateGetString( p_demux, "v4l-adev" );;
478         }
479
480         if( p_sys->psz_adev && *p_sys->psz_adev )
481         {
482             p_sys->fd_audio = OpenAudioDev( p_demux, p_sys->psz_adev );
483         }
484     }
485
486     if( p_sys->fd_video < 0 && p_sys->fd_audio < 0 )
487     {
488         Close( p_this );
489         return VLC_EGENERIC;
490     }
491
492     msg_Dbg( p_demux, "v4l grabbing started" );
493
494     /* Declare elementary streams */
495     if( p_sys->fd_video >= 0 )
496     {
497         es_format_t fmt;
498         es_format_Init( &fmt, VIDEO_ES, p_sys->i_fourcc );
499         fmt.video.i_width  = p_sys->i_width;
500         fmt.video.i_height = p_sys->i_height;
501         fmt.video.i_aspect = 4 * VOUT_ASPECT_FACTOR / 3;
502
503         /* Setup rgb mask for RGB formats */
504         if( p_sys->i_fourcc == VLC_FOURCC('R','V','2','4') )
505         {
506             /* This is in BGR format */
507             fmt.video.i_bmask = 0x00ff0000;
508             fmt.video.i_gmask = 0x0000ff00;
509             fmt.video.i_rmask = 0x000000ff;
510         }
511
512         msg_Dbg( p_demux, "added new video es %4.4s %dx%d",
513                  (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
514         p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
515     }
516
517     if( p_sys->fd_audio >= 0 )
518     {
519         es_format_t fmt;
520         es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );
521
522         fmt.audio.i_channels = p_sys->b_stereo ? 2 : 1;
523         fmt.audio.i_rate = p_sys->i_sample_rate;
524         fmt.audio.i_bitspersample = 16; // FIXME ?
525         fmt.audio.i_blockalign = fmt.audio.i_channels *
526             fmt.audio.i_bitspersample / 8;
527         fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
528             fmt.audio.i_bitspersample;
529
530         msg_Dbg( p_demux, "new audio es %d channels %dHz",
531                  fmt.audio.i_channels, fmt.audio.i_rate );
532
533         p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
534     }
535
536     /* Update default_pts to a suitable value for access */
537     var_Create( p_demux, "v4l-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
538
539     return VLC_SUCCESS;
540 }
541
542 /*****************************************************************************
543  * Close: close device, free resources
544  *****************************************************************************/
545 static void Close( vlc_object_t *p_this )
546 {
547     demux_t     *p_demux = (demux_t *)p_this;
548     demux_sys_t *p_sys   = p_demux->p_sys;
549
550     if( p_sys->psz_device ) free( p_sys->psz_device );
551     if( p_sys->psz_vdev )   free( p_sys->psz_vdev );
552     if( p_sys->psz_adev )   free( p_sys->psz_adev );
553     if( p_sys->fd_video >= 0 ) close( p_sys->fd_video );
554     if( p_sys->fd_audio >= 0 ) close( p_sys->fd_audio );
555     if( p_sys->p_block_audio ) block_Release( p_sys->p_block_audio );
556
557     if( p_sys->b_mjpeg )
558     {
559         int i_noframe = -1;
560         ioctl( p_sys->fd_video, MJPIOC_QBUF_CAPT, &i_noframe );
561     }
562
563     if( p_sys->p_video_mmap && p_sys->p_video_mmap != MAP_FAILED )
564     {
565         if( p_sys->b_mjpeg )
566             munmap( p_sys->p_video_mmap, p_sys->mjpeg_buffers.size *
567                     p_sys->mjpeg_buffers.count );
568         else
569             munmap( p_sys->p_video_mmap, p_sys->vid_mbuf.size );
570     }
571
572     free( p_sys );
573 }
574
575 /*****************************************************************************
576  * Control:
577  *****************************************************************************/
578 static int Control( demux_t *p_demux, int i_query, va_list args )
579 {
580     vlc_bool_t *pb;
581     int64_t    *pi64;
582
583     switch( i_query )
584     {
585         /* Special for access_demux */
586         case DEMUX_CAN_PAUSE:
587         case DEMUX_SET_PAUSE_STATE:
588         case DEMUX_CAN_CONTROL_PACE:
589             pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
590             *pb = VLC_FALSE;
591             return VLC_SUCCESS;
592
593         case DEMUX_GET_PTS_DELAY:
594             pi64 = (int64_t*)va_arg( args, int64_t * );
595             *pi64 = (int64_t)var_GetInteger( p_demux, "v4l-caching" ) * 1000;
596             return VLC_SUCCESS;
597
598         case DEMUX_GET_TIME:
599             pi64 = (int64_t*)va_arg( args, int64_t * );
600             *pi64 = mdate();
601             return VLC_SUCCESS;
602
603         /* TODO implement others */
604         default:
605             return VLC_EGENERIC;
606     }
607
608     return VLC_EGENERIC;
609 }
610
611 /*****************************************************************************
612  * Demux:
613  *****************************************************************************/
614 static int Demux( demux_t *p_demux )
615 {
616     demux_sys_t *p_sys = p_demux->p_sys;
617     es_out_id_t  *p_es = p_sys->p_es_audio;
618     block_t *p_block = NULL;
619
620     /* Try grabbing audio frames first */
621     if( p_sys->fd_audio < 0 || !( p_block = GrabAudio( p_demux ) ) )
622     {
623         /* Try grabbing video frame */
624         p_es = p_sys->p_es_video;
625         if( p_sys->fd_video > 0 ) p_block = GrabVideo( p_demux );
626     }
627
628     if( !p_block )
629     {
630         /* Sleep so we do not consume all the cpu, 10ms seems
631          * like a good value (100fps) */
632         msleep( 10000 );
633         return 1;
634     }
635
636     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
637     es_out_Send( p_demux->out, p_es, p_block );
638
639     return 1;
640 }
641
642 /*****************************************************************************
643  * ParseMRL: parse the options contained in the MRL
644  *****************************************************************************/
645 static void ParseMRL( demux_t *p_demux )
646 {
647     demux_sys_t *p_sys = p_demux->p_sys;
648
649     char *psz_dup = strdup( p_demux->psz_path );
650     char *psz_parser = psz_dup;
651
652     while( *psz_parser && *psz_parser != ':' )
653     {
654         psz_parser++;
655     }
656
657     if( *psz_parser == ':' )
658     {
659         /* read options */
660         for( ;; )
661         {
662             *psz_parser++ = '\0';
663             if( !strncmp( psz_parser, "channel=", strlen( "channel=" ) ) )
664             {
665                 p_sys->i_channel = strtol( psz_parser + strlen( "channel=" ),
666                                            &psz_parser, 0 );
667             }
668             else if( !strncmp( psz_parser, "norm=", strlen( "norm=" ) ) )
669             {
670                 psz_parser += strlen( "norm=" );
671                 if( !strncmp( psz_parser, "pal", strlen( "pal" ) ) )
672                 {
673                     p_sys->i_norm = VIDEO_MODE_PAL;
674                     psz_parser += strlen( "pal" );
675                 }
676                 else if( !strncmp( psz_parser, "ntsc", strlen( "ntsc" ) ) )
677                 {
678                     p_sys->i_norm = VIDEO_MODE_NTSC;
679                     psz_parser += strlen( "ntsc" );
680                 }
681                 else if( !strncmp( psz_parser, "secam", strlen( "secam" ) ) )
682                 {
683                     p_sys->i_norm = VIDEO_MODE_SECAM;
684                     psz_parser += strlen( "secam" );
685                 }
686                 else if( !strncmp( psz_parser, "auto", strlen( "auto" ) ) )
687                 {
688                     p_sys->i_norm = VIDEO_MODE_AUTO;
689                     psz_parser += strlen( "auto" );
690                 }
691                 else
692                 {
693                     p_sys->i_norm = strtol( psz_parser, &psz_parser, 0 );
694                 }
695             }
696             else if( !strncmp( psz_parser, "frequency=",
697                                strlen( "frequency=" ) ) )
698             {
699                 p_sys->i_frequency =
700                     strtol( psz_parser + strlen( "frequency=" ),
701                             &psz_parser, 0 );
702                 if( p_sys->i_frequency < 30000 )
703                 {
704                     msg_Warn( p_demux, "v4l syntax has changed : "
705                               "'frequency' is now channel frequency in kHz");
706                 }
707             }
708             else if( !strncmp( psz_parser, "audio=", strlen( "audio=" ) ) )
709             {
710                 p_sys->i_audio = strtol( psz_parser + strlen( "audio=" ),
711                                          &psz_parser, 0 );
712             }
713             else if( !strncmp( psz_parser, "size=", strlen( "size=" ) ) )
714             {
715                 psz_parser += strlen( "size=" );
716                 if( !strncmp( psz_parser, "subqcif", strlen( "subqcif" ) ) )
717                 {
718                     p_sys->i_width  = 128;
719                     p_sys->i_height = 96;
720                 }
721                 else if( !strncmp( psz_parser, "qsif", strlen( "qsif" ) ) )
722                 {
723                     p_sys->i_width  = 160;
724                     p_sys->i_height = 120;
725                 }
726                 else if( !strncmp( psz_parser, "qcif", strlen( "qcif" ) ) )
727                 {
728                     p_sys->i_width  = 176;
729                     p_sys->i_height = 144;
730                 }
731                 else if( !strncmp( psz_parser, "sif", strlen( "sif" ) ) )
732                 {
733                     p_sys->i_width  = 320;
734                     p_sys->i_height = 244;
735                 }
736                 else if( !strncmp( psz_parser, "cif", strlen( "cif" ) ) )
737                 {
738                     p_sys->i_width  = 352;
739                     p_sys->i_height = 288;
740                 }
741                 else if( !strncmp( psz_parser, "vga", strlen( "vga" ) ) )
742                 {
743                     p_sys->i_width  = 640;
744                     p_sys->i_height = 480;
745                 }
746                 else
747                 {
748                     /* widthxheight */
749                     p_sys->i_width = strtol( psz_parser, &psz_parser, 0 );
750                     if( *psz_parser == 'x' || *psz_parser == 'X')
751                     {
752                         p_sys->i_height = strtol( psz_parser + 1,
753                                                   &psz_parser, 0 );
754                     }
755                     msg_Dbg( p_demux, "WxH %dx%d", p_sys->i_width,
756                              p_sys->i_height );
757                 }
758             }
759             else if( !strncmp( psz_parser, "brightness=", strlen( "brightness=" ) ) )
760             {
761                 p_sys->i_brightness = strtol( psz_parser + strlen( "brightness=" ),
762                                               &psz_parser, 0 );
763             }
764             else if( !strncmp( psz_parser, "colour=", strlen( "colour=" ) ) )
765             {
766                 p_sys->i_colour = strtol( psz_parser + strlen( "colour=" ),
767                                           &psz_parser, 0 );
768             }
769             else if( !strncmp( psz_parser, "hue=", strlen( "hue=" ) ) )
770             {
771                 p_sys->i_hue = strtol( psz_parser + strlen( "hue=" ), 
772                                        &psz_parser, 0 );
773             }
774             else if( !strncmp( psz_parser, "contrast=", strlen( "contrast=" ) ) )
775             {
776                 p_sys->i_contrast = strtol( psz_parser + strlen( "contrast=" ),
777                                             &psz_parser, 0 );
778             }
779             else if( !strncmp( psz_parser, "tuner=", strlen( "tuner=" ) ) )
780             {
781                 p_sys->i_tuner = strtol( psz_parser + strlen( "tuner=" ),
782                                          &psz_parser, 0 );
783             }
784             else if( !strncmp( psz_parser, "adev=", strlen( "adev=" ) ) )
785             {
786                 int  i_len;
787
788                 psz_parser += strlen( "adev=" );
789                 if( strchr( psz_parser, ':' ) )
790                 {
791                     i_len = strchr( psz_parser, ':' ) - psz_parser;
792                 }
793                 else
794                 {
795                     i_len = strlen( psz_parser );
796                 }
797
798                 p_sys->psz_adev = strndup( psz_parser, i_len );
799
800                 psz_parser += i_len;
801             }
802             else if( !strncmp( psz_parser, "samplerate=",
803                                strlen( "samplerate=" ) ) )
804             {
805                 p_sys->i_sample_rate =
806                     strtol( psz_parser + strlen( "samplerate=" ),
807                             &psz_parser, 0 );
808             }
809             else if( !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) )
810             {
811                 psz_parser += strlen( "stereo" );
812
813                 p_sys->b_stereo = VLC_TRUE;
814             }
815             else if( !strncmp( psz_parser, "mono", strlen( "mono" ) ) )
816             {
817                 psz_parser += strlen( "mono" );
818
819                 p_sys->b_stereo = VLC_FALSE;
820             }
821             else if( !strncmp( psz_parser, "mjpeg", strlen( "mjpeg" ) ) )
822             {
823                 psz_parser += strlen( "mjpeg" );
824
825                 p_sys->b_mjpeg = VLC_TRUE;
826             }
827             else if( !strncmp( psz_parser, "decimation=",
828                         strlen( "decimation=" ) ) )
829             {
830                 p_sys->i_decimation =
831                     strtol( psz_parser + strlen( "decimation=" ),
832                             &psz_parser, 0 );
833             }
834             else if( !strncmp( psz_parser, "quality=",
835                         strlen( "quality=" ) ) )
836             {
837                 p_sys->i_quality =
838                     strtol( psz_parser + strlen( "quality=" ),
839                             &psz_parser, 0 );
840             }
841             else if( !strncmp( psz_parser, "fps=", strlen( "fps=" ) ) )
842             {
843                 p_sys->f_fps = strtof( psz_parser + strlen( "fps=" ),
844                                        &psz_parser );
845             }
846             else
847             {
848                 msg_Warn( p_demux, "unknown option" );
849             }
850
851             while( *psz_parser && *psz_parser != ':' )
852             {
853                 psz_parser++;
854             }
855
856             if( *psz_parser == '\0' )
857             {
858                 break;
859             }
860         }
861     }
862
863     if( *psz_dup )
864     {
865         p_sys->psz_device = strdup( psz_dup );
866     }
867     if( psz_dup ) free( psz_dup );
868 }
869
870 /*****************************************************************************
871  * OpenVideoDev:
872  *****************************************************************************/
873 static int OpenVideoDev( demux_t *p_demux, char *psz_device )
874 {
875     demux_sys_t *p_sys = p_demux->p_sys;
876     int i_fd;
877
878     struct video_channel vid_channel;
879     struct mjpeg_params mjpeg;
880     int i;
881
882     if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 )
883     {
884         msg_Err( p_demux, "cannot open device (%s)", strerror( errno ) );
885         goto vdev_failed;
886     }
887
888     if( ioctl( i_fd, VIDIOCGCAP, &p_sys->vid_cap ) < 0 )
889     {
890         msg_Err( p_demux, "cannot get capabilities (%s)", strerror( errno ) );
891         goto vdev_failed;
892     }
893
894     msg_Dbg( p_demux,
895              "V4L device %s %d channels %d audios %d < w < %d %d < h < %d",
896              p_sys->vid_cap.name,
897              p_sys->vid_cap.channels,
898              p_sys->vid_cap.audios,
899              p_sys->vid_cap.minwidth,  p_sys->vid_cap.maxwidth,
900              p_sys->vid_cap.minheight, p_sys->vid_cap.maxheight );
901
902     if( p_sys->i_channel < 0 || p_sys->i_channel >= p_sys->vid_cap.channels )
903     {
904         msg_Dbg( p_demux, "invalid channel, falling back on channel 0" );
905         p_sys->i_channel = 0;
906     }
907     if( p_sys->vid_cap.audios && p_sys->i_audio >= p_sys->vid_cap.audios )
908     {
909         msg_Dbg( p_demux, "invalid audio, falling back with no audio" );
910         p_sys->i_audio = -1;
911     }
912
913     if( p_sys->i_width < p_sys->vid_cap.minwidth ||
914         p_sys->i_width > p_sys->vid_cap.maxwidth )
915     {
916         msg_Dbg( p_demux, "invalid width %i", p_sys->i_width );
917         p_sys->i_width = 0;
918     }
919     if( p_sys->i_height < p_sys->vid_cap.minheight ||
920         p_sys->i_height > p_sys->vid_cap.maxheight )
921     {
922         msg_Dbg( p_demux, "invalid height %i", p_sys->i_height );
923         p_sys->i_height = 0;
924     }
925
926     if( !( p_sys->vid_cap.type & VID_TYPE_CAPTURE ) )
927     {
928         msg_Err( p_demux, "cannot grab" );
929         goto vdev_failed;
930     }
931
932     vid_channel.channel = p_sys->i_channel;
933     if( ioctl( i_fd, VIDIOCGCHAN, &vid_channel ) < 0 )
934     {
935         msg_Err( p_demux, "cannot get channel infos (%s)",
936                           strerror( errno ) );
937         goto vdev_failed;
938     }
939     msg_Dbg( p_demux,
940              "setting channel %s(%d) %d tuners flags=0x%x type=0x%x norm=0x%x",
941              vid_channel.name, vid_channel.channel, vid_channel.tuners,
942              vid_channel.flags, vid_channel.type, vid_channel.norm );
943
944     if( p_sys->i_tuner >= vid_channel.tuners )
945     {
946         msg_Dbg( p_demux, "invalid tuner, falling back on tuner 0" );
947         p_sys->i_tuner = 0;
948     }
949
950     vid_channel.norm = p_sys->i_norm;
951     if( ioctl( i_fd, VIDIOCSCHAN, &vid_channel ) < 0 )
952     {
953         msg_Err( p_demux, "cannot set channel (%s)", strerror( errno ) );
954         goto vdev_failed;
955     }
956
957     if( vid_channel.flags & VIDEO_VC_TUNER )
958     {
959
960         /* set tuner */
961 #if 0
962         struct video_tuner vid_tuner;
963         if( p_sys->i_tuner >= 0 )
964         {
965             vid_tuner.tuner = p_sys->i_tuner;
966             if( ioctl( i_fd, VIDIOCGTUNER, &vid_tuner ) < 0 )
967             {
968                 msg_Err( p_demux, "cannot get tuner (%s)", strerror( errno ) );
969                 goto vdev_failed;
970             }
971             msg_Dbg( p_demux, "tuner %s low=%d high=%d, flags=0x%x "
972                      "mode=0x%x signal=0x%x",
973                      vid_tuner.name, vid_tuner.rangelow, vid_tuner.rangehigh,
974                      vid_tuner.flags, vid_tuner.mode, vid_tuner.signal );
975
976             msg_Dbg( p_demux, "setting tuner %s (%d)",
977                      vid_tuner.name, vid_tuner.tuner );
978
979             /* FIXME FIXME to be checked FIXME FIXME */
980             //vid_tuner.mode = p_sys->i_norm;
981             if( ioctl( i_fd, VIDIOCSTUNER, &vid_tuner ) < 0 )
982             {
983                 msg_Err( p_demux, "cannot set tuner (%s)", strerror( errno ) );
984                 goto vdev_failed;
985             }
986         }
987 #endif
988
989         /* Show a warning if frequency is < than 30000.
990          * User is certainly usint old syntax. */
991
992
993         /* set frequency */
994         if( p_sys->i_frequency >= 0 )
995         {
996             int driver_frequency = p_sys->i_frequency * 16 /1000;
997             if( ioctl( i_fd, VIDIOCSFREQ, &driver_frequency ) < 0 )
998             {
999                 msg_Err( p_demux, "cannot set frequency (%s)",
1000                                   strerror( errno ) );
1001                 goto vdev_failed;
1002             }
1003             msg_Dbg( p_demux, "frequency %d (%d)", p_sys->i_frequency,
1004                                                    driver_frequency );
1005         }
1006     }
1007
1008     /* set audio */
1009     if( vid_channel.flags & VIDEO_VC_AUDIO )
1010     {
1011         struct video_audio      vid_audio;
1012
1013         /* XXX TODO volume, balance, ... */
1014         if( p_sys->i_audio >= 0 )
1015         {
1016             vid_audio.audio = p_sys->i_audio;
1017             if( ioctl( i_fd, VIDIOCGAUDIO, &vid_audio ) < 0 )
1018             {
1019                 msg_Err( p_demux, "cannot get audio (%s)", strerror( errno ) );
1020                 goto vdev_failed;
1021             }
1022
1023             /* unmute audio */
1024             vid_audio.flags &= ~VIDEO_AUDIO_MUTE;
1025
1026             if( ioctl( i_fd, VIDIOCSAUDIO, &vid_audio ) < 0 )
1027             {
1028                 msg_Err( p_demux, "cannot set audio (%s)", strerror( errno ) );
1029                 goto vdev_failed;
1030             }
1031         }
1032
1033     }
1034
1035     /* establish basic params with input and norm before feeling width
1036      * or height */
1037     if( p_sys->b_mjpeg )
1038     {
1039         struct quicktime_mjpeg_app1 *p_app1;
1040         int32_t i_offset;
1041
1042         if( ioctl( i_fd, MJPIOC_G_PARAMS, &mjpeg ) < 0 )
1043         {
1044             msg_Err( p_demux, "cannot get mjpeg params (%s)",
1045                               strerror( errno ) );
1046             goto vdev_failed;
1047         }
1048         mjpeg.input = p_sys->i_channel;
1049         mjpeg.norm  = p_sys->i_norm;
1050         mjpeg.decimation = p_sys->i_decimation;
1051
1052         if( p_sys->i_width )
1053             mjpeg.img_width = p_sys->i_width / p_sys->i_decimation;
1054         if( p_sys->i_height )
1055             mjpeg.img_height = p_sys->i_height / p_sys->i_decimation;
1056
1057         /* establish Quicktime APP1 marker while we are here */
1058         mjpeg.APPn = 1;
1059         mjpeg.APP_len = 40;
1060
1061         /* aligned */
1062         p_app1 = (struct quicktime_mjpeg_app1 *)mjpeg.APP_data;
1063         p_app1->i_reserved = 0;
1064         p_app1->i_tag = VLC_FOURCC( 'm','j','p','g' );
1065         p_app1->i_field_size = 0;
1066         p_app1->i_padded_field_size = 0;
1067         p_app1->i_next_field = 0;
1068         /* XXX WARNING XXX */
1069         /* these's nothing magic about these values.  We are dangerously
1070          * assuming the encoder card is encoding mjpeg-a and is not throwing
1071          * in marker tags we aren't expecting.  It's bad enough we have to
1072          * search through the jpeg output for every frame we grab just to
1073          * find the first field's end marker, so we take this risk to boost
1074          * performance.
1075          * This is really something the driver could do for us because this
1076          * does conform to standards outside of Apple Quicktime.
1077          */
1078         i_offset = 0x2e;
1079         p_app1->i_DQT_offset = hton32( i_offset );
1080         i_offset = 0xb4;
1081         p_app1->i_DHT_offset = hton32( i_offset );
1082         i_offset = 0x258;
1083         p_app1->i_SOF_offset = hton32( i_offset );
1084         i_offset = 0x26b;
1085         p_app1->i_SOS_offset = hton32( i_offset );
1086         i_offset = 0x279;
1087         p_app1->i_data_offset = hton32( i_offset );
1088
1089         /* SOF and SOS aren't specified by the mjpeg API because they aren't
1090          * optional.  They will be present in the output. */
1091         mjpeg.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT;
1092
1093         if( ioctl( i_fd, MJPIOC_S_PARAMS, &mjpeg ) < 0 )
1094         {
1095             msg_Err( p_demux, "cannot set mjpeg params (%s)",
1096                               strerror( errno ) );
1097             goto vdev_failed;
1098         }
1099
1100         p_sys->i_width = mjpeg.img_width * mjpeg.HorDcm;
1101         p_sys->i_height = mjpeg.img_height * mjpeg.VerDcm *
1102             mjpeg.field_per_buff;
1103     }
1104
1105     /* fix width/height */
1106     if( !p_sys->b_mjpeg && ( p_sys->i_width == 0 || p_sys->i_height == 0 ) )
1107     {
1108         struct video_window vid_win;
1109
1110         if( ioctl( i_fd, VIDIOCGWIN, &vid_win ) < 0 )
1111         {
1112             msg_Err( p_demux, "cannot get win (%s)", strerror( errno ) );
1113             goto vdev_failed;
1114         }
1115         p_sys->i_width  = vid_win.width;
1116         p_sys->i_height = vid_win.height;
1117
1118         if( !p_sys->i_width || !p_sys->i_height )
1119         {
1120             p_sys->i_width = p_sys->vid_cap.maxwidth;
1121             p_sys->i_height = p_sys->vid_cap.maxheight;
1122         }
1123
1124         if( !p_sys->i_width || !p_sys->i_height )
1125         {
1126             msg_Err( p_demux, "invalid video size (%ix%i)",
1127                      p_sys->i_width, p_sys->i_height );
1128             goto vdev_failed;
1129         }
1130
1131         msg_Dbg( p_demux, "will use %dx%d", p_sys->i_width, p_sys->i_height );
1132     }
1133
1134     if( !p_sys->b_mjpeg )
1135     {
1136         /* set hue/color/.. */
1137         if( ioctl( i_fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 )
1138         {
1139             struct video_picture vid_picture = p_sys->vid_picture;
1140
1141             if( p_sys->i_brightness >= 0 && p_sys->i_brightness < 65536 )
1142             {
1143                 vid_picture.brightness = p_sys->i_brightness;
1144             }
1145             if( p_sys->i_colour >= 0 && p_sys->i_colour < 65536 )
1146             {
1147                 vid_picture.colour = p_sys->i_colour;
1148             }
1149             if( p_sys->i_hue >= 0 && p_sys->i_hue < 65536 )
1150             {
1151                 vid_picture.hue = p_sys->i_hue;
1152             }
1153             if( p_sys->i_contrast  >= 0 && p_sys->i_contrast < 65536 )
1154             {
1155                 vid_picture.contrast = p_sys->i_contrast;
1156             }
1157             if( ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 )
1158             {
1159                 msg_Dbg( p_demux, "v4l device uses brightness: %d",
1160                          vid_picture.brightness );
1161                 msg_Dbg( p_demux, "v4l device uses colour: %d",
1162                          vid_picture.colour );
1163                 msg_Dbg( p_demux, "v4l device uses hue: %d", vid_picture.hue );
1164                 msg_Dbg( p_demux, "v4l device uses contrast: %d",
1165                          vid_picture.contrast );
1166                 p_sys->vid_picture = vid_picture;
1167             }
1168         }
1169
1170         /* Find out video format used by device */
1171         if( ioctl( i_fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 )
1172         {
1173             struct video_picture vid_picture = p_sys->vid_picture;
1174             char *psz;
1175             int i;
1176
1177             p_sys->i_fourcc = 0;
1178
1179             psz = var_CreateGetString( p_demux, "v4l-chroma" );
1180             if( strlen( psz ) >= 4 )
1181             {
1182                 vid_picture.palette = 0;
1183                 int i_chroma = VLC_FOURCC( psz[0], psz[1], psz[2], psz[3] );
1184
1185                 /* Find out v4l chroma code */
1186                 for( i = 0; v4lchroma_to_fourcc[i].i_v4l != 0; i++ )
1187                 {
1188                     if( v4lchroma_to_fourcc[i].i_fourcc == i_chroma )
1189                     {
1190                         vid_picture.palette = v4lchroma_to_fourcc[i].i_v4l;
1191                         break;
1192                     }
1193                 }
1194             }
1195             free( psz );
1196
1197             if( vid_picture.palette &&
1198                 !ioctl( i_fd, VIDIOCSPICT, &vid_picture ) )
1199             {
1200                 p_sys->vid_picture = vid_picture;
1201             }
1202             else
1203             {
1204                 /* Try to set the format to something easy to encode */
1205                 vid_picture.palette = VIDEO_PALETTE_YUV420P;
1206                 if( ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 )
1207                 {
1208                     p_sys->vid_picture = vid_picture;
1209                 }
1210                 else
1211                 {
1212                     vid_picture.palette = VIDEO_PALETTE_YUV422P;
1213                     if( ioctl( i_fd, VIDIOCSPICT, &vid_picture ) == 0 )
1214                     {
1215                         p_sys->vid_picture = vid_picture;
1216                     }
1217                 }
1218             }
1219
1220             /* Find out final format */
1221             for( i = 0; v4lchroma_to_fourcc[i].i_v4l != 0; i++ )
1222             {
1223                 if( v4lchroma_to_fourcc[i].i_v4l == p_sys->vid_picture.palette)
1224                 {
1225                     p_sys->i_fourcc = v4lchroma_to_fourcc[i].i_fourcc;
1226                     break;
1227                 }
1228             }
1229         }
1230         else
1231         {
1232             msg_Err( p_demux, "ioctl VIDIOCGPICT failed" );
1233             goto vdev_failed;
1234         }
1235     }
1236
1237     if( p_sys->b_mjpeg )
1238     {
1239         int i;
1240
1241         p_sys->mjpeg_buffers.count = 8;
1242         p_sys->mjpeg_buffers.size = MJPEG_BUFFER_SIZE;
1243
1244         if( ioctl( i_fd, MJPIOC_REQBUFS, &p_sys->mjpeg_buffers ) < 0 )
1245         {
1246             msg_Err( p_demux, "mmap unsupported" );
1247             goto vdev_failed;
1248         }
1249
1250         p_sys->p_video_mmap = mmap( 0,
1251                 p_sys->mjpeg_buffers.size * p_sys->mjpeg_buffers.count,
1252                 PROT_READ | PROT_WRITE, MAP_SHARED, i_fd, 0 );
1253         if( p_sys->p_video_mmap == MAP_FAILED )
1254         {
1255             msg_Err( p_demux, "mmap failed" );
1256             goto vdev_failed;
1257         }
1258
1259         p_sys->i_fourcc  = VLC_FOURCC( 'm','j','p','g' );
1260         p_sys->i_frame_pos = -1;
1261
1262         /* queue up all the frames */
1263         for( i = 0; i < (int)p_sys->mjpeg_buffers.count; i++ )
1264         {
1265             if( ioctl( i_fd, MJPIOC_QBUF_CAPT, &i ) < 0 )
1266             {
1267                 msg_Err( p_demux, "unable to queue frame" );
1268                 goto vdev_failed;
1269             }
1270         }
1271     }
1272     else
1273     {
1274         /* Fill in picture_t fields */
1275         vout_InitPicture( VLC_OBJECT(p_demux), &p_sys->pic, p_sys->i_fourcc,
1276                           p_sys->i_width, p_sys->i_height, p_sys->i_width *
1277                           VOUT_ASPECT_FACTOR / p_sys->i_height );
1278         if( !p_sys->pic.i_planes )
1279         {
1280             msg_Err( p_demux, "unsupported chroma" );
1281             goto vdev_failed;
1282         }
1283         p_sys->i_video_frame_size = 0;
1284         for( i = 0; i < p_sys->pic.i_planes; i++ )
1285         {
1286             p_sys->i_video_frame_size += p_sys->pic.p[i].i_visible_lines *
1287               p_sys->pic.p[i].i_visible_pitch;
1288         }
1289
1290         msg_Dbg( p_demux, "v4l device uses frame size: %i",
1291                  p_sys->i_video_frame_size );
1292         msg_Dbg( p_demux, "v4l device uses chroma: %4.4s",
1293                 (char*)&p_sys->i_fourcc );
1294
1295         /* Allocate mmap buffer */
1296         if( ioctl( i_fd, VIDIOCGMBUF, &p_sys->vid_mbuf ) < 0 )
1297         {
1298             msg_Err( p_demux, "mmap unsupported" );
1299             goto vdev_failed;
1300         }
1301
1302         p_sys->p_video_mmap = mmap( 0, p_sys->vid_mbuf.size,
1303                                     PROT_READ|PROT_WRITE, MAP_SHARED,
1304                                     i_fd, 0 );
1305         if( p_sys->p_video_mmap == MAP_FAILED )
1306         {
1307             /* FIXME -> normal read */
1308             msg_Err( p_demux, "mmap failed" );
1309             goto vdev_failed;
1310         }
1311
1312         /* init grabbing */
1313         p_sys->vid_mmap.frame  = 0;
1314         p_sys->vid_mmap.width  = p_sys->i_width;
1315         p_sys->vid_mmap.height = p_sys->i_height;
1316         p_sys->vid_mmap.format = p_sys->vid_picture.palette;
1317         if( ioctl( i_fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 )
1318         {
1319             msg_Warn( p_demux, "%4.4s refused", (char*)&p_sys->i_fourcc );
1320             msg_Err( p_demux, "chroma selection failed" );
1321             goto vdev_failed;
1322         }
1323     }
1324     return i_fd;
1325
1326 vdev_failed:
1327
1328     if( i_fd >= 0 ) close( i_fd );
1329     return -1;
1330 }
1331
1332 /*****************************************************************************
1333  * OpenAudioDev:
1334  *****************************************************************************/
1335 static int OpenAudioDev( demux_t *p_demux, char *psz_device )
1336 {
1337     demux_sys_t *p_sys = p_demux->p_sys;
1338     int i_fd, i_format;
1339
1340     if( (i_fd = open( psz_device, O_RDONLY | O_NONBLOCK )) < 0 )
1341     {
1342         msg_Err( p_demux, "cannot open audio device (%s)", strerror( errno ) );
1343         goto adev_fail;
1344     }
1345
1346     i_format = AFMT_S16_LE;
1347     if( ioctl( i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0
1348         || i_format != AFMT_S16_LE )
1349     {
1350         msg_Err( p_demux, "cannot set audio format (16b little endian) "
1351                  "(%s)", strerror( errno ) );
1352         goto adev_fail;
1353     }
1354
1355     if( ioctl( i_fd, SNDCTL_DSP_STEREO,
1356                &p_sys->b_stereo ) < 0 )
1357     {
1358         msg_Err( p_demux, "cannot set audio channels count (%s)",
1359                  strerror( errno ) );
1360         goto adev_fail;
1361     }
1362
1363     if( ioctl( i_fd, SNDCTL_DSP_SPEED,
1364                &p_sys->i_sample_rate ) < 0 )
1365     {
1366         msg_Err( p_demux, "cannot set audio sample rate (%s)",
1367                  strerror( errno ) );
1368         goto adev_fail;
1369     }
1370
1371     msg_Dbg( p_demux, "openened adev=`%s' %s %dHz",
1372              psz_device, p_sys->b_stereo ? "stereo" : "mono",
1373              p_sys->i_sample_rate );
1374
1375     p_sys->i_audio_max_frame_size = 6 * 1024;
1376
1377     return i_fd;
1378
1379  adev_fail:
1380
1381     if( i_fd >= 0 ) close( i_fd );
1382     return -1;
1383 }
1384
1385 /*****************************************************************************
1386  * GrabAudio: grab audio
1387  *****************************************************************************/
1388 static block_t *GrabAudio( demux_t *p_demux )
1389 {
1390     demux_sys_t *p_sys = p_demux->p_sys;
1391     struct audio_buf_info buf_info;
1392     int i_read, i_correct;
1393     block_t *p_block;
1394
1395     if( p_sys->p_block_audio ) p_block = p_sys->p_block_audio;
1396     else p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
1397
1398     if( !p_block )
1399     {
1400         msg_Warn( p_demux, "cannot get block" );
1401         return 0;
1402     }
1403
1404     p_sys->p_block_audio = p_block;
1405
1406     i_read = read( p_sys->fd_audio, p_block->p_buffer,
1407                    p_sys->i_audio_max_frame_size );
1408
1409     if( i_read <= 0 ) return 0;
1410
1411     p_block->i_buffer = i_read;
1412     p_sys->p_block_audio = 0;
1413
1414     /* Correct the date because of kernel buffering */
1415     i_correct = i_read;
1416     if( ioctl( p_sys->fd_audio, SNDCTL_DSP_GETISPACE, &buf_info ) == 0 )
1417     {
1418         i_correct += buf_info.bytes;
1419     }
1420
1421     p_block->i_pts = p_block->i_dts =
1422         mdate() - I64C(1000000) * (mtime_t)i_correct /
1423         2 / ( p_sys->b_stereo ? 2 : 1) / p_sys->i_sample_rate;
1424
1425     return p_block;
1426 }
1427
1428 /*****************************************************************************
1429  * GrabVideo:
1430  *****************************************************************************/
1431 static uint8_t *GrabCapture( demux_t *p_demux )
1432 {
1433     demux_sys_t *p_sys = p_demux->p_sys;
1434     int i_captured_frame = p_sys->i_frame_pos;
1435
1436     p_sys->vid_mmap.frame = (p_sys->i_frame_pos + 1) % p_sys->vid_mbuf.frames;
1437
1438     while( ioctl( p_sys->fd_video, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 )
1439     {
1440         if( errno != EAGAIN )
1441         {
1442             msg_Err( p_demux, "failed capturing new frame" );
1443             return NULL;
1444         }
1445
1446         if( p_demux->b_die )
1447         {
1448             return NULL;
1449         }
1450
1451         msg_Dbg( p_demux, "grab failed, trying again" );
1452     }
1453
1454     while( ioctl(p_sys->fd_video, VIDIOCSYNC, &p_sys->i_frame_pos) < 0 )
1455     {
1456         if( errno != EAGAIN && errno != EINTR )    
1457         {
1458             msg_Err( p_demux, "failed syncing new frame" );
1459             return NULL;
1460         }
1461     }
1462
1463     p_sys->i_frame_pos = p_sys->vid_mmap.frame;
1464     /* leave i_video_frame_size alone */
1465     return p_sys->p_video_mmap + p_sys->vid_mbuf.offsets[i_captured_frame];
1466 }
1467
1468 static uint8_t *GrabMJPEG( demux_t *p_demux )
1469 {
1470     demux_sys_t *p_sys = p_demux->p_sys;
1471     struct mjpeg_sync sync;
1472     uint8_t *p_frame, *p_field, *p;
1473     uint16_t tag;
1474     uint32_t i_size;
1475     struct quicktime_mjpeg_app1 *p_app1 = NULL;
1476
1477     /* re-queue the last frame we sync'd */
1478     if( p_sys->i_frame_pos != -1 )
1479     {
1480         while( ioctl( p_sys->fd_video, MJPIOC_QBUF_CAPT,
1481                                        &p_sys->i_frame_pos ) < 0 )
1482         {
1483             if( errno != EAGAIN && errno != EINTR )
1484             {
1485                 msg_Err( p_demux, "failed capturing new frame" );
1486                 return NULL;
1487             }
1488         }
1489     }
1490
1491     /* sync on the next frame */
1492     while( ioctl( p_sys->fd_video, MJPIOC_SYNC, &sync ) < 0 )
1493     {
1494         if( errno != EAGAIN && errno != EINTR )    
1495         {
1496             msg_Err( p_demux, "failed syncing new frame" );
1497             return NULL;
1498         }
1499     }
1500
1501     p_sys->i_frame_pos = sync.frame;
1502     p_frame = p_sys->p_video_mmap + p_sys->mjpeg_buffers.size * sync.frame;
1503
1504     /* p_frame now points to the data.  fix up the Quicktime APP1 marker */
1505     tag = 0xffd9;
1506     tag = hton16( tag );
1507     p_field = p_frame;
1508
1509     /* look for EOI */
1510     p = memmem( p_field, sync.length, &tag, 2 );
1511
1512     if( p )
1513     {
1514         p += 2; /* data immediately following EOI */
1515         /* UNALIGNED! */
1516         p_app1 = (struct quicktime_mjpeg_app1 *)(p_field + 6);
1517
1518         i_size = ((uint32_t)(p - p_field));
1519         i_size = hton32( i_size );
1520         memcpy( &p_app1->i_field_size, &i_size, 4 );
1521
1522         while( *p == 0xff && *(p+1) == 0xff )
1523             p++;
1524
1525         i_size = ((uint32_t)(p - p_field));
1526         i_size = hton32( i_size );
1527         memcpy( &p_app1->i_padded_field_size, &i_size, 4 );
1528     }
1529
1530     tag = 0xffd8;
1531     tag = hton16( tag );
1532     p_field = memmem( p, sync.length - (size_t)(p - p_frame), &tag, 2 );
1533
1534     if( p_field )
1535     {
1536         i_size = (uint32_t)(p_field - p_frame);
1537         i_size = hton32( i_size );
1538         memcpy( &p_app1->i_next_field, &i_size, 4 );
1539
1540         /* UNALIGNED! */
1541         p_app1 = (struct quicktime_mjpeg_app1 *)(p_field + 6);
1542         tag = 0xffd9;
1543         tag = hton16( tag );
1544         p = memmem( p_field, sync.length - (size_t)(p_field - p_frame),
1545                 &tag, 2 );
1546
1547         if( !p )
1548         {
1549             /* sometimes the second field doesn't have the EOI.  just put it
1550              * there
1551              */
1552             p = p_frame + sync.length;
1553             memcpy( p, &tag, 2 );
1554             sync.length += 2;
1555         }
1556
1557         p += 2;
1558         i_size = (uint32_t)(p - p_field);
1559         i_size = hton32( i_size );
1560         memcpy( &p_app1->i_field_size, &i_size, 4 );
1561         i_size = (uint32_t)(sync.length - (uint32_t)(p_field - p_frame));
1562         i_size = hton32( i_size );
1563         memcpy( &p_app1->i_padded_field_size, &i_size, 4 );
1564     }
1565
1566     p_sys->i_video_frame_size = sync.length;
1567     return p_frame;
1568 }
1569
1570 static block_t *GrabVideo( demux_t *p_demux )
1571 {
1572     demux_sys_t *p_sys = p_demux->p_sys;
1573     uint8_t     *p_frame;
1574     block_t     *p_block;
1575
1576     if( p_sys->f_fps >= 0.1 && p_sys->i_video_pts > 0 )
1577     {
1578         mtime_t i_dur = (mtime_t)((double)1000000 / (double)p_sys->f_fps);
1579
1580         /* Did we wait long enough ? (frame rate reduction) */
1581         if( p_sys->i_video_pts + i_dur > mdate() ) return 0;
1582     }
1583
1584     if( p_sys->b_mjpeg ) p_frame = GrabMJPEG( p_demux );
1585     else p_frame = GrabCapture( p_demux );
1586
1587     if( !p_frame ) return 0;
1588
1589     if( !( p_block = block_New( p_demux, p_sys->i_video_frame_size ) ) )
1590     {
1591         msg_Warn( p_demux, "cannot get block" );
1592         return 0;
1593     }
1594
1595     memcpy( p_block->p_buffer, p_frame, p_sys->i_video_frame_size );
1596     p_sys->i_video_pts = p_block->i_pts = p_block->i_dts = mdate();
1597
1598     return p_block;
1599 }