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