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