]> git.sesse.net Git - vlc/blob - modules/access/v4l/v4l.c
* now 0.6.0-cvs
[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.16 2003/05/15 22:27:36 massiot Exp $
6  *
7  * Author: Samuel Hocevar <sam@zoy.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/input.h>
33 #include <vlc/vout.h>
34 #include <codecs.h>
35 #include "encoder.h"
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/ioctl.h>
40 #include <unistd.h>
41 #include <sys/mman.h>
42 #include <errno.h>
43
44 #include <fcntl.h>
45 #include <linux/videodev.h>
46
47 #include <sys/soundcard.h>
48
49 /*****************************************************************************
50  * Local prototypes
51  *****************************************************************************/
52 static int  AccessOpen  ( vlc_object_t * );
53 static void AccessClose ( vlc_object_t * );
54 static int  Read        ( input_thread_t *, byte_t *, size_t );
55
56 static int  DemuxOpen  ( vlc_object_t * );
57 static void DemuxClose ( vlc_object_t * );
58 static int  Demux      ( input_thread_t * );
59
60
61 /*****************************************************************************
62  * Module descriptior
63  *****************************************************************************/
64 #define CACHING_TEXT N_("Caching value in ms")
65 #define CACHING_LONGTEXT N_( \
66     "Allows you to modify the default caching value for v4l streams. This " \
67     "value should be set in miliseconds units." )
68
69 vlc_module_begin();
70     set_description( _("Video4Linux input") );
71     add_category_hint( N_("v4l"), NULL, VLC_TRUE );
72     add_integer( "v4l-caching", DEFAULT_PTS_DELAY / 1000, NULL,
73                  CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
74     add_shortcut( "v4l" );
75     set_capability( "access", 10 );
76     set_callbacks( AccessOpen, AccessClose );
77
78     add_submodule();
79         set_description( _("Video4Linux demuxer") );
80         add_shortcut( "v4l" );
81         set_capability( "demux", 200 );
82         set_callbacks( DemuxOpen, DemuxClose );
83 vlc_module_end();
84
85
86 /****************************************************************************
87  * I. Access Part
88  ****************************************************************************/
89 struct access_sys_t
90 {
91     char    *psz_video_device;
92     int     fd;
93
94     vlc_fourcc_t    i_codec;   // if i_codec != i_chroma then we need a compressor
95     video_encoder_t *p_encoder;
96     picture_t       pic;
97
98     int i_channel;
99     int i_audio;
100     int i_norm;
101     int i_tuner;
102     int i_frequency;
103     int i_chroma;
104     int i_width;
105     int i_height;
106
107     struct video_capability vid_cap;
108     struct video_mbuf       vid_mbuf;
109
110     uint8_t *p_video_mmap;
111     int     i_frame_pos;
112     struct video_mmap   vid_mmap;
113     struct video_picture vid_picture;
114
115     uint8_t *p_video_frame;
116     int     i_video_frame_size;
117     int     i_video_frame_size_allocated;
118
119     char         *psz_adev;
120     int          fd_audio;
121     vlc_fourcc_t i_acodec_raw;
122     int          i_sample_rate;
123     vlc_bool_t   b_stereo;
124
125     uint8_t *p_audio_frame;
126     int     i_audio_frame_size;
127     int     i_audio_frame_size_allocated;
128
129     /* header */
130     int     i_header_size;
131     int     i_header_pos;
132     uint8_t *p_header;      // at lest 8 bytes allocated
133
134     /* data */
135     int     i_data_size;
136     int     i_data_pos;
137     uint8_t *p_data;        // never allocated
138
139 };
140
141 /*
142  * header:
143  *  fcc  ".v4l"
144  *  u32    stream count
145  *      fcc "auds"|"vids"       0
146  *      fcc codec               4
147  *      if vids
148  *          u32 width           8
149  *          u32 height          12
150  *          u32 padding         16
151  *      if auds
152  *          u32 channels        12
153  *          u32 samplerate      8
154  *          u32 samplesize      16
155  *
156  * data:
157  *  u32     stream number
158  *  u32     data size
159  *  u8      data
160  */
161
162 static void    SetDWBE( uint8_t *p, uint32_t dw )
163 {
164     p[0] = (dw >> 24)&0xff;
165     p[1] = (dw >> 16)&0xff;
166     p[2] = (dw >>  8)&0xff;
167     p[3] = (dw      )&0xff;
168 }
169
170 static void    SetQWBE( uint8_t *p, uint64_t qw )
171 {
172     SetDWBE( p,     (qw >> 32)&0xffffffff );
173     SetDWBE( &p[4], qw&0xffffffff);
174 }
175
176 static uint32_t GetDWBE( uint8_t *p_buff )
177 {
178     return( ( p_buff[0] << 24 ) + ( p_buff[1] << 16 ) +
179             ( p_buff[2] <<  8 ) + p_buff[3] );
180 }
181 static uint64_t GetQWBE( uint8_t *p )
182 {
183     return( ( (uint64_t)GetDWBE( p ) << 32) | (uint64_t)GetDWBE( &p[4] ) );
184 }
185
186 /*****************************************************************************
187  * Open: open device:
188  *****************************************************************************
189  *
190  * url: <video device>::::
191  *
192  *****************************************************************************/
193 static int AccessOpen( vlc_object_t *p_this )
194 {
195     input_thread_t *p_input = (input_thread_t *)p_this;
196     access_sys_t   *p_sys;
197     char           *psz_dup, *psz_parser;
198
199     struct video_channel    vid_channel;
200
201     /* create access private data */
202     p_sys = malloc( sizeof( access_sys_t ) );
203     memset( p_sys, 0, sizeof( access_sys_t ) );
204
205     p_sys->psz_video_device = NULL;
206     p_sys->fd               = -1;
207     p_sys->i_channel        = -1;
208     p_sys->i_audio          = -1;
209     p_sys->i_norm           = VIDEO_MODE_AUTO;    // auto
210     p_sys->i_tuner          = -1;
211     p_sys->i_frequency      = -1;
212     p_sys->i_width          = 0;
213     p_sys->i_height         = 0;
214
215     p_sys->i_frame_pos = 0;
216
217     p_sys->i_codec          = VLC_FOURCC( 0, 0, 0, 0 );
218     p_sys->i_video_frame_size_allocated = 0;
219     p_sys->psz_adev         = NULL;
220     p_sys->fd_audio         = -1;
221     p_sys->i_sample_rate    = 44100;
222     p_sys->b_stereo         = VLC_TRUE;
223
224     p_sys->i_data_size = 0;
225     p_sys->i_data_pos  = 0;
226     p_sys->p_data      = NULL;
227
228     /* parse url and open device(s) */
229     psz_dup = strdup( p_input->psz_name );
230     psz_parser = psz_dup;
231
232     while( *psz_parser && *psz_parser != ':' )
233     {
234         psz_parser++;
235     }
236
237     if( *psz_parser == ':' )
238     {
239         /* read options */
240         for( ;; )
241         {
242             *psz_parser++ = '\0';
243             if( !strncmp( psz_parser, "channel=", strlen( "channel=" ) ) )
244             {
245                 p_sys->i_channel = strtol( psz_parser + strlen( "channel=" ),
246                                            &psz_parser, 0 );
247             }
248             else if( !strncmp( psz_parser, "norm=", strlen( "norm=" ) ) )
249             {
250                 psz_parser += strlen( "norm=" );
251                 if( !strncmp( psz_parser, "pal", strlen( "pal" ) ) )
252                 {
253                     p_sys->i_norm = VIDEO_MODE_PAL;
254                     psz_parser += strlen( "pal" );
255                 }
256                 else if( !strncmp( psz_parser, "ntsc", strlen( "ntsc" ) ) )
257                 {
258                     p_sys->i_norm = VIDEO_MODE_NTSC;
259                     psz_parser += strlen( "ntsc" );
260                 }
261                 else if( !strncmp( psz_parser, "secam", strlen( "secam" ) ) )
262                 {
263                     p_sys->i_norm = VIDEO_MODE_SECAM;
264                     psz_parser += strlen( "secam" );
265                 }
266                 else if( !strncmp( psz_parser, "auto", strlen( "auto" ) ) )
267                 {
268                     p_sys->i_norm = VIDEO_MODE_AUTO;
269                     psz_parser += strlen( "auto" );
270                 }
271                 else
272                 {
273                     p_sys->i_norm = strtol( psz_parser, &psz_parser, 0 );
274                 }
275             }
276             else if( !strncmp( psz_parser, "frequency=",
277                                strlen( "frequency=" ) ) )
278             {
279                 p_sys->i_frequency =
280                     strtol( psz_parser + strlen( "frequency=" ),
281                             &psz_parser, 0 );
282             }
283             else if( !strncmp( psz_parser, "audio=", strlen( "audio=" ) ) )
284             {
285                 p_sys->i_audio = strtol( psz_parser + strlen( "audio=" ),
286                                          &psz_parser, 0 );
287             }
288             else if( !strncmp( psz_parser, "size=", strlen( "size=" ) ) )
289             {
290                 psz_parser += strlen( "size=" );
291                 if( !strncmp( psz_parser, "subqcif", strlen( "subqcif" ) ) )
292                 {
293                     p_sys->i_width  = 128;
294                     p_sys->i_height = 96;
295                 }
296                 else if( !strncmp( psz_parser, "qsif", strlen( "qsif" ) ) )
297                 {
298                     p_sys->i_width  = 160;
299                     p_sys->i_height = 120;
300                 }
301                 else if( !strncmp( psz_parser, "qcif", strlen( "qcif" ) ) )
302                 {
303                     p_sys->i_width  = 176;
304                     p_sys->i_height = 144;
305                 }
306                 else if( !strncmp( psz_parser, "sif", strlen( "sif" ) ) )
307                 {
308                     p_sys->i_width  = 320;
309                     p_sys->i_height = 244;
310                 }
311                 else if( !strncmp( psz_parser, "cif", strlen( "cif" ) ) )
312                 {
313                     p_sys->i_width  = 352;
314                     p_sys->i_height = 288;
315                 }
316                 else if( !strncmp( psz_parser, "vga", strlen( "vga" ) ) )
317                 {
318                     p_sys->i_width  = 640;
319                     p_sys->i_height = 480;
320                 }
321                 else
322                 {
323                     /* widthxheight */
324                     p_sys->i_width = strtol( psz_parser, &psz_parser, 0 );
325                     if( *psz_parser == 'x' || *psz_parser == 'X')
326                     {
327                         p_sys->i_height = strtol( psz_parser + 1,
328                                                   &psz_parser, 0 );
329                     }
330                     msg_Dbg( p_input, "WxH %dx%d", p_sys->i_width,
331                              p_sys->i_height );
332                 }
333             }
334             else if( !strncmp( psz_parser, "tuner=", strlen( "tuner=" ) ) )
335             {
336                 p_sys->i_tuner = strtol( psz_parser + strlen( "tuner=" ),
337                                          &psz_parser, 0 );
338             }
339             else if( !strncmp( psz_parser, "codec=", strlen( "codec=" ) ) )
340             {
341                 psz_parser += strlen( "codec=" );
342                 if( !strncmp( psz_parser, "mpeg4", strlen( "mpeg4" ) ) )
343                 {
344                     p_sys->i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
345                 }
346                 else if( !strncmp( psz_parser, "mpeg1", strlen( "mpeg1" ) ) )
347                 {
348                     p_sys->i_codec = VLC_FOURCC( 'm', 'p', '1', 'v' );
349                 }
350                 else
351                 {
352                     msg_Warn( p_input, "unknow codec" );
353                 }
354             }
355             else if( !strncmp( psz_parser, "adev=", strlen( "adev=" ) ) )
356             {
357                 int  i_len;
358
359                 psz_parser += strlen( "adev=" );
360                 if( strchr( psz_parser, ':' ) )
361                 {
362                     i_len = strchr( psz_parser, ':' ) - psz_parser;
363                 }
364                 else
365                 {
366                     i_len = strlen( psz_parser );
367                 }
368
369                 p_sys->psz_adev = strndup( psz_parser, i_len );
370
371                 psz_parser += i_len;
372             }
373             else if( !strncmp( psz_parser, "samplerate=",
374                                strlen( "samplerate=" ) ) )
375             {
376                 p_sys->i_sample_rate =
377                     strtol( psz_parser + strlen( "samplerate=" ),
378                             &psz_parser, 0 );
379             }
380             else if( !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) )
381             {
382                 psz_parser += strlen( "stereo" );
383
384                 p_sys->b_stereo = VLC_TRUE;
385             }
386             else if( !strncmp( psz_parser, "mono", strlen( "mono" ) ) )
387             {
388                 psz_parser += strlen( "mono" );
389
390                 p_sys->b_stereo = VLC_FALSE;
391             }
392             else
393             {
394                 msg_Warn( p_input, "unknow option" );
395             }
396
397             while( *psz_parser && *psz_parser != ':' )
398             {
399                 psz_parser++;
400             }
401
402             if( *psz_parser == '\0' )
403             {
404                 break;
405             }
406         }
407     }
408
409     if( *psz_dup )
410     {
411         p_sys->psz_video_device = strdup( psz_dup );
412     }
413     else
414     {
415         p_sys->psz_video_device = strdup( "/dev/video" );
416     }
417     msg_Dbg( p_input, "video device=`%s'", p_sys->psz_video_device );
418
419     if( p_sys->psz_adev && *p_sys->psz_adev == '\0' )
420     {
421         p_sys->psz_adev = strdup( "/dev/dsp" );
422     }
423     msg_Dbg( p_input, "audio device=`%s'", p_sys->psz_adev );
424
425
426
427     if( ( p_sys->fd = open( p_sys->psz_video_device, O_RDWR ) ) < 0 )
428     {
429         msg_Err( p_input, "cannot open device" );
430         goto failed;
431     }
432
433     if( ioctl( p_sys->fd, VIDIOCGCAP, &p_sys->vid_cap ) < 0 )
434     {
435         msg_Err( p_input, "cannot get capabilities" );
436         goto failed;
437     }
438
439     msg_Dbg( p_input,
440              "V4L device %s %d channels %d audios %d < w < %d %d < h < %d",
441              p_sys->vid_cap.name,
442              p_sys->vid_cap.channels,
443              p_sys->vid_cap.audios,
444              p_sys->vid_cap.minwidth,  p_sys->vid_cap.maxwidth,
445              p_sys->vid_cap.minheight, p_sys->vid_cap.maxheight );
446
447     if( p_sys->i_channel < 0 || p_sys->i_channel >= p_sys->vid_cap.channels )
448     {
449         msg_Dbg( p_input, "invalid channel, falling back on channel 0" );
450         p_sys->i_channel = 0;
451     }
452     if( p_sys->i_audio >= p_sys->vid_cap.audios )
453     {
454         msg_Dbg( p_input, "invalid audio, falling back with no audio" );
455         p_sys->i_audio = -1;
456     }
457
458     if( p_sys->i_width < p_sys->vid_cap.minwidth ||
459         p_sys->i_width > p_sys->vid_cap.maxwidth )
460     {
461         msg_Dbg( p_input, "invalid width" );
462         p_sys->i_width = 0;
463     }
464     if( p_sys->i_height < p_sys->vid_cap.minheight ||
465         p_sys->i_height > p_sys->vid_cap.maxheight )
466     {
467         msg_Dbg( p_input, "invalid height" );
468         p_sys->i_height = 0;
469     }
470
471     if( !( p_sys->vid_cap.type&VID_TYPE_CAPTURE ) )
472     {
473         msg_Err( p_input, "cannot grab" );
474         goto failed;
475     }
476
477     vid_channel.channel = p_sys->i_channel;
478     if( ioctl( p_sys->fd, VIDIOCGCHAN, &vid_channel ) < 0 )
479     {
480         msg_Err( p_input, "cannot get channel infos" );
481         goto failed;
482     }
483     msg_Dbg( p_input,
484              "setting channel %s(%d) %d tuners flags=0x%x type=0x%x norm=0x%x",
485              vid_channel.name,
486              vid_channel.channel,
487              vid_channel.tuners,
488              vid_channel.flags,
489              vid_channel.type,
490              vid_channel.norm );
491
492     if( p_sys->i_tuner >= vid_channel.tuners )
493     {
494         msg_Dbg( p_input, "invalid tuner, falling back on tuner 0" );
495         p_sys->i_tuner = 0;
496     }
497
498     vid_channel.norm = p_sys->i_norm;
499     if( ioctl( p_sys->fd, VIDIOCSCHAN, &vid_channel ) < 0 )
500     {
501         msg_Err( p_input, "cannot set channel" );
502         goto failed;
503     }
504
505     if( vid_channel.flags & VIDEO_VC_TUNER )
506     {
507
508         /* set tuner */
509 #if 0
510         struct video_tuner vid_tuner;
511         if( p_sys->i_tuner >= 0 )
512         {
513             vid_tuner.tuner = p_sys->i_tuner;
514             if( ioctl( p_sys->fd, VIDIOCGTUNER, &vid_tuner ) < 0 )
515             {
516                 msg_Err( p_input, "cannot get tuner" );
517                 goto failed;
518             }
519             msg_Dbg( p_input, "tuner %s low=%d high=%d, flags=0x%x "
520                      "mode=0x%x signal=0x%x",
521                      vid_tuner.name, vid_tuner.rangelow, vid_tuner.rangehigh,
522                      vid_tuner.flags, vid_tuner.mode, vid_tuner.signal );
523
524             msg_Dbg( p_input, "setting tuner %s (%d)",
525                      vid_tuner.name, vid_tuner.tuner );
526
527             //vid_tuner.mode = p_sys->i_norm; /* FIXME FIXME to be checked FIXME FIXME */
528             if( ioctl( p_sys->fd, VIDIOCSTUNER, &vid_tuner ) < 0 )
529             {
530                 msg_Err( p_input, "cannot set tuner" );
531                 goto failed;
532             }
533         }
534 #endif
535         /* set frequency */
536         if( p_sys->i_frequency >= 0 )
537         {
538             if( ioctl( p_sys->fd, VIDIOCSFREQ, &p_sys->i_frequency ) < 0 )
539             {
540                 msg_Err( p_input, "cannot set frequency" );
541                 goto failed;
542             }
543             msg_Dbg( p_input, "frequency %d", p_sys->i_frequency );
544         }
545     }
546
547     /* set audio */
548     if( vid_channel.flags & VIDEO_VC_AUDIO )
549     {
550         struct video_audio      vid_audio;
551
552         /* XXX TODO volume, balance, ... */
553         if( p_sys->i_audio >= 0 )
554         {
555             vid_audio.audio = p_sys->i_audio;
556             if( ioctl( p_sys->fd, VIDIOCGAUDIO, &vid_audio ) < 0 )
557             {
558                 msg_Err( p_input, "cannot get audio" );
559                 goto failed;
560             }
561
562             /* unmute audio */
563             vid_audio.flags &= ~VIDEO_AUDIO_MUTE;
564
565             if( ioctl( p_sys->fd, VIDIOCSAUDIO, &vid_audio ) < 0 )
566             {
567                 msg_Err( p_input, "cannot set audio" );
568                 goto failed;
569             }
570
571             if( p_sys->psz_adev )
572             {
573                 int    i_format;
574                 if( ( p_sys->fd_audio = open( p_sys->psz_adev, O_RDONLY|O_NONBLOCK ) ) < 0 )
575                 {
576                     msg_Err( p_input, "cannot open audio device" );
577                     goto failed;
578                 }
579
580                 i_format = AFMT_S16_LE;
581                 if( ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format ) < 0
582                     || i_format != AFMT_S16_LE )
583                 {
584                     msg_Err( p_input,
585                              "cannot set audio format (16b little endian)" );
586                     goto failed;
587                 }
588
589                 if( ioctl( p_sys->fd_audio, SNDCTL_DSP_STEREO,
590                            &p_sys->b_stereo ) < 0 )
591                 {
592                     msg_Err( p_input, "cannot set audio channels count" );
593                     goto failed;
594                 }
595
596                 if( ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED,
597                            &p_sys->i_sample_rate ) < 0 )
598                 {
599                     msg_Err( p_input, "cannot set audio sample rate" );
600                     goto failed;
601                 }
602
603                 msg_Dbg( p_input,
604                          "adev=`%s' %s %dHz",
605                          p_sys->psz_adev,
606                          p_sys->b_stereo ? "stereo" : "mono",
607                          p_sys->i_sample_rate );
608
609                 p_sys->i_audio_frame_size = 0;
610                 p_sys->i_audio_frame_size_allocated = 6*1024;
611                 p_sys->p_audio_frame =
612                     malloc( p_sys->i_audio_frame_size_allocated );
613             }
614         }
615     }
616
617     /* fix width/heigh */
618     if( p_sys->i_width == 0 || p_sys->i_height == 0 )
619     {
620         struct video_window vid_win;
621
622         if( ioctl( p_sys->fd, VIDIOCGWIN, &vid_win ) < 0 )
623         {
624             msg_Err( p_input, "cannot get win" );
625             goto failed;
626         }
627         p_sys->i_width  = vid_win.width;
628         p_sys->i_height = vid_win.height;
629
630         msg_Dbg( p_input, "will use %dx%d", p_sys->i_width, p_sys->i_height );
631     }
632
633     p_sys->p_video_frame = NULL;
634
635     /* Find out video format used by device */
636     if( ioctl( p_sys->fd, VIDIOCGPICT, &p_sys->vid_picture ) == 0 )
637     {
638         int i_chroma, i;
639         struct video_picture vid_picture = p_sys->vid_picture;
640
641         /* Try to set the format to something easy to encode */
642         vid_picture.palette = VIDEO_PALETTE_YUV420P;
643         if( ioctl( p_sys->fd, VIDIOCSPICT, &vid_picture ) == 0 )
644         {
645             p_sys->vid_picture = vid_picture;
646         }
647         else
648         {
649             vid_picture.palette = VIDEO_PALETTE_YUV422P;
650             if( ioctl( p_sys->fd, VIDIOCSPICT, &vid_picture ) == 0 )
651             {
652                 p_sys->vid_picture = vid_picture;
653             }
654         }
655
656         /* Find out final format */
657         switch( p_sys->vid_picture.palette )
658         {
659         case VIDEO_PALETTE_GREY:
660             i_chroma = VLC_FOURCC( 'G', 'R', 'E', 'Y' );
661             break;
662         case VIDEO_PALETTE_HI240:
663             i_chroma = VLC_FOURCC( 'I', '2', '4', '0' );
664             break;
665         case VIDEO_PALETTE_RGB565:
666             i_chroma = VLC_FOURCC( 'R', 'V', '1', '6' );
667             break;
668         case VIDEO_PALETTE_RGB555:
669             i_chroma = VLC_FOURCC( 'R', 'V', '1', '5' );
670             break;
671         case VIDEO_PALETTE_RGB24:
672             i_chroma = VLC_FOURCC( 'R', 'V', '2', '4' );
673             break;
674         case VIDEO_PALETTE_RGB32:
675             i_chroma = VLC_FOURCC( 'R', 'V', '3', '2' );
676             break;
677         case VIDEO_PALETTE_YUV422:
678             i_chroma = VLC_FOURCC( 'I', '4', '2', '2' );
679             break;
680         case VIDEO_PALETTE_YUYV:
681             i_chroma = VLC_FOURCC( 'Y', 'U', 'Y', 'V' );
682             break;
683         case VIDEO_PALETTE_UYVY:
684             i_chroma = VLC_FOURCC( 'U', 'Y', 'V', 'Y' );
685             break;
686         case VIDEO_PALETTE_YUV420:
687             i_chroma = VLC_FOURCC( 'I', '4', '2', 'N' );
688             break;
689         case VIDEO_PALETTE_YUV411:
690             i_chroma = VLC_FOURCC( 'I', '4', '1', 'N' );
691             break;
692         case VIDEO_PALETTE_RAW:
693             i_chroma = VLC_FOURCC( 'G', 'R', 'A', 'W' );
694             break;
695         case VIDEO_PALETTE_YUV422P:
696             i_chroma = VLC_FOURCC( 'I', '4', '2', '2' );
697             break;
698         case VIDEO_PALETTE_YUV420P:
699             i_chroma = VLC_FOURCC( 'I', '4', '2', '0' );
700             break;
701         case VIDEO_PALETTE_YUV411P:
702             i_chroma = VLC_FOURCC( 'I', '4', '1', '1' );
703             break;
704         }
705
706         p_sys->i_chroma = i_chroma;
707
708         /* Fill in picture_t fields */
709         vout_InitPicture( VLC_OBJECT(p_input), &p_sys->pic,
710                           p_sys->i_width, p_sys->i_height, p_sys->i_chroma );
711         if( !p_sys->pic.i_planes )
712         {
713             msg_Err( p_input, "unsupported chroma" );
714             goto failed;
715         }
716         p_sys->i_video_frame_size = 0;
717         for( i = 0; i < p_sys->pic.i_planes; i++ )
718         {
719             p_sys->i_video_frame_size += p_sys->pic.p[i].i_lines *
720               p_sys->pic.p[i].i_visible_pitch;
721         }
722
723         msg_Dbg( p_input, "v4l device uses frame size: %i",
724                  p_sys->i_video_frame_size );
725         msg_Dbg( p_input, "v4l device uses chroma: %4.4s", (char*)&i_chroma );
726     }
727     else
728     {
729         msg_Err( p_input, "ioctl VIDIOCGPICT failed" );
730         goto failed;
731     }
732
733     /* Allocate mmap buffer */
734     if( ioctl( p_sys->fd, VIDIOCGMBUF, &p_sys->vid_mbuf ) < 0 )
735     {
736         msg_Err( p_input, "mmap unsupported" );
737         goto failed;
738     }
739
740     p_sys->p_video_mmap = mmap( 0, p_sys->vid_mbuf.size,
741                                 PROT_READ|PROT_WRITE, MAP_SHARED,
742                                 p_sys->fd, 0 );
743     if( p_sys->p_video_mmap == MAP_FAILED )
744     {
745         /* FIXME -> normal read */
746         msg_Err( p_input, "mmap failed" );
747         goto failed;
748     }
749
750     /* init grabbing */
751     p_sys->vid_mmap.frame  = 0;
752     p_sys->vid_mmap.width  = p_sys->i_width;
753     p_sys->vid_mmap.height = p_sys->i_height;
754     p_sys->vid_mmap.format = p_sys->vid_picture.palette;
755     if( ioctl( p_sys->fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) < 0 )
756     {
757         msg_Warn( p_input, "%4.4s refused", (char*)&p_sys->i_chroma );
758         msg_Err( p_input, "chroma selection failed" );
759         goto failed;
760     }
761
762     /* encoder part */
763     if( p_sys->i_codec != VLC_FOURCC( 0, 0, 0, 0 ) )
764     {
765         msg_Dbg( p_input,
766                  "need a rencoder from %4.4s to %4.4s",
767                  (char*)&p_sys->i_chroma,
768                  (char*)&p_sys->i_codec );
769 #define p_enc p_sys->p_encoder
770         p_enc = vlc_object_create( p_input, sizeof( video_encoder_t ) );
771         p_enc->i_codec = p_sys->i_codec;
772         p_enc->i_chroma= p_sys->i_chroma;
773         p_enc->i_width = p_sys->i_width;
774         p_enc->i_height= p_sys->i_height;
775         p_enc->i_aspect= 0;
776
777
778         p_enc->p_module = module_Need( p_enc, "video encoder",
779                                        "$video-encoder" );
780         if( !p_enc->p_module )
781         {
782             msg_Warn( p_input, "no suitable encoder to %4.4s",
783                       (char*)&p_enc->i_codec );
784             vlc_object_destroy( p_enc );
785             goto failed;
786         }
787
788         /* *** init the codec *** */
789         if( p_enc->pf_init( p_enc ) )
790         {
791             msg_Err( p_input, "failed to initialize video encoder plugin" );
792             vlc_object_destroy( p_enc );
793             goto failed;
794         }
795
796         /* *** alloacted buffer *** */
797         if( p_enc->i_buffer_size <= 0 )
798         {
799           p_enc->i_buffer_size = 1024 * 1024;// * p_enc->i_width * p_enc->i_height;
800         }
801         p_sys->i_video_frame_size = p_enc->i_buffer_size;
802         p_sys->i_video_frame_size_allocated = p_enc->i_buffer_size;
803         if( !( p_sys->p_video_frame = malloc( p_enc->i_buffer_size ) ) )
804         {
805             msg_Err( p_input, "out of memory" );
806             goto failed;
807         }
808 #undef p_enc
809     }
810     else
811     {
812         p_sys->i_codec  = p_sys->i_chroma;
813         p_sys->p_encoder = NULL;
814     }
815
816
817     p_input->pf_read        = Read;
818     p_input->pf_seek        = NULL;
819     p_input->pf_set_area    = NULL;
820     p_input->pf_set_program = NULL;
821
822     p_input->p_access_data  = p_sys;
823
824     vlc_mutex_lock( &p_input->stream.stream_lock );
825     p_input->stream.b_pace_control = 0;
826     p_input->stream.b_seekable = 0;
827     p_input->stream.p_selected_area->i_size = 0;
828     p_input->stream.p_selected_area->i_tell = 0;
829     p_input->stream.i_method = INPUT_METHOD_FILE;
830     vlc_mutex_unlock( &p_input->stream.stream_lock );
831
832     /* Update default_pts to a suitable value for access */
833     p_input->i_pts_delay = config_GetInt( p_input, "v4l-caching" ) * 1000;
834
835     msg_Info( p_input, "v4l grabbing started" );
836
837     /* create header */
838     p_sys->i_header_size = 8 + 20;
839     p_sys->i_header_pos  = 0;
840     p_sys->p_header      = malloc( p_sys->i_header_size );
841
842     memcpy(  &p_sys->p_header[0], ".v4l", 4 );
843     SetDWBE( &p_sys->p_header[4], 1 );
844
845     memcpy(  &p_sys->p_header[ 8], "vids", 4 );
846     memcpy(  &p_sys->p_header[12], &p_sys->i_codec, 4 );
847     SetDWBE( &p_sys->p_header[16], p_sys->i_width );
848     SetDWBE( &p_sys->p_header[20], p_sys->i_height );
849     SetDWBE( &p_sys->p_header[24], 0 );
850
851     if( p_sys->fd_audio > 0 )
852     {
853         p_sys->i_header_size += 20;
854         p_sys->p_header = realloc( p_sys->p_header, p_sys->i_header_size );
855
856         SetDWBE( &p_sys->p_header[4], 2 );
857
858         memcpy(  &p_sys->p_header[28], "auds", 4 );
859         memcpy(  &p_sys->p_header[32], "araw", 4 );
860         SetDWBE( &p_sys->p_header[36], p_sys->b_stereo ? 2 : 1 );
861         SetDWBE( &p_sys->p_header[40], p_sys->i_sample_rate );
862         SetDWBE( &p_sys->p_header[44], 16 );
863     }
864     return VLC_SUCCESS;
865
866 failed:
867     free( p_sys->psz_video_device );
868     if( p_sys->fd >= 0 )
869     {
870         close( p_sys->fd );
871     }
872     free( p_sys );
873     return VLC_EGENERIC;
874 }
875
876 /*****************************************************************************
877  * V4lClose: close device
878  *****************************************************************************/
879 static void AccessClose( vlc_object_t *p_this )
880 {
881     input_thread_t  *p_input = (input_thread_t *)p_this;
882     access_sys_t    *p_sys   = p_input->p_access_data;
883
884     msg_Info( p_input, "v4l grabbing stoped" );
885
886     free( p_sys->psz_video_device );
887     close( p_sys->fd );
888     if( p_sys->p_video_mmap )
889     {
890         munmap( p_sys->p_video_mmap, p_sys->vid_mbuf.size );
891     }
892     if( p_sys->fd_audio >= 0 )
893     {
894         close( p_sys->fd_audio );
895     }
896
897     if( p_sys->p_encoder )
898     {
899         p_sys->p_encoder->pf_end( p_sys->p_encoder );
900
901         module_Unneed( p_sys->p_encoder,
902                        p_sys->p_encoder->p_module );
903         vlc_object_destroy( p_sys->p_encoder );
904
905         free( p_sys->p_video_frame );
906     }
907     free( p_sys );
908 }
909
910 static int GrabAudio( input_thread_t * p_input,
911                       uint8_t **pp_data,
912                       int      *pi_data,
913                       mtime_t  *pi_pts )
914 {
915     access_sys_t    *p_sys   = p_input->p_access_data;
916     struct audio_buf_info buf_info;
917     int i_read;
918     int i_correct;
919
920     i_read = read( p_sys->fd_audio, p_sys->p_audio_frame,
921                    p_sys->i_audio_frame_size_allocated );
922
923     if( i_read <= 0 )
924     {
925         return VLC_EGENERIC;
926     }
927
928     p_sys->i_audio_frame_size = i_read;
929
930     /* from vls : correct the date because of kernel buffering */
931     i_correct = i_read;
932     if( ioctl( p_sys->fd_audio, SNDCTL_DSP_GETISPACE, &buf_info ) == 0 )
933     {
934         i_correct += buf_info.bytes;
935     }
936
937
938     *pp_data = p_sys->p_audio_frame;
939     *pi_data = p_sys->i_audio_frame_size;
940     *pi_pts  = mdate() - (mtime_t)1000000 * (mtime_t)i_correct /
941                          2 / ( p_sys->b_stereo ? 2 : 1) / p_sys->i_sample_rate;
942     return VLC_SUCCESS;
943 }
944
945 static int GrabVideo( input_thread_t * p_input,
946                       uint8_t **pp_data,
947                       int *pi_data,
948                       mtime_t  *pi_pts )
949 {
950     access_sys_t *p_sys   = p_input->p_access_data;
951
952     p_sys->vid_mmap.frame = ( p_sys->i_frame_pos + 1 ) %
953                             p_sys->vid_mbuf.frames;
954     for( ;; )
955     {
956         if( ioctl( p_sys->fd, VIDIOCMCAPTURE, &p_sys->vid_mmap ) >= 0 )
957         {
958             break;
959         }
960
961         if( errno != EAGAIN )
962         {
963             msg_Err( p_input, "failed while grabbing new frame" );
964             return( -1 );
965         }
966         msg_Dbg( p_input, "another try ?" );
967     }
968
969     //msg_Warn( p_input, "grab a new frame" );
970
971     while( ioctl(p_sys->fd, VIDIOCSYNC, &p_sys->i_frame_pos) < 0 &&
972            ( errno == EAGAIN || errno == EINTR ) );
973
974
975     p_sys->i_frame_pos = p_sys->vid_mmap.frame;
976
977     if( p_sys->p_encoder )
978     {
979         int i;
980
981         p_sys->pic.p[0].p_pixels = p_sys->p_video_mmap +
982             p_sys->vid_mbuf.offsets[p_sys->i_frame_pos];
983
984         for( i = 1; i < p_sys->pic.i_planes; i++ )
985         {
986             p_sys->pic.p[i].p_pixels = p_sys->pic.p[i-1].p_pixels +
987                 p_sys->pic.p[i-1].i_pitch * p_sys->pic.p[i-1].i_lines;
988         }
989
990         p_sys->i_video_frame_size = p_sys->i_video_frame_size_allocated;
991         p_sys->p_encoder->pf_encode( p_sys->p_encoder, &p_sys->pic,
992                                      p_sys->p_video_frame,
993                                      &p_sys->i_video_frame_size );
994     }
995     else
996     {
997         p_sys->p_video_frame = p_sys->p_video_mmap +
998                                p_sys->vid_mbuf.offsets[p_sys->i_frame_pos];
999     }
1000
1001     *pp_data = p_sys->p_video_frame;
1002     *pi_data = p_sys->i_video_frame_size;
1003     *pi_pts  = mdate();
1004     return VLC_SUCCESS;
1005 }
1006
1007 /*****************************************************************************
1008  * Read: reads from the device into PES packets.
1009  *****************************************************************************
1010  * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
1011  * bytes.
1012  *****************************************************************************/
1013 static int Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
1014 {
1015     access_sys_t *p_sys = p_input->p_access_data;
1016     int          i_data = 0;
1017     int          i_stream;
1018     mtime_t      i_pts;
1019
1020     //msg_Info( p_input, "access read data_size %i, data_pos %i",
1021                 //p_sys->i_data_size, p_sys->i_data_pos );
1022     while( i_len > 0 )
1023     {
1024         /* First copy header if any */
1025         if( i_len > 0 && p_sys->i_header_pos < p_sys->i_header_size )
1026         {
1027             int i_copy;
1028
1029             i_copy = __MIN( p_sys->i_header_size - p_sys->i_header_pos,
1030                             (int)i_len );
1031             memcpy( p_buffer, &p_sys->p_header[p_sys->i_header_pos], i_copy );
1032             p_sys->i_header_pos += i_copy;
1033
1034             p_buffer += i_copy;
1035             i_len -= i_copy;
1036             i_data += i_copy;
1037         }
1038
1039         /* then data */
1040         if( i_len > 0 && p_sys->i_data_pos < p_sys->i_data_size )
1041         {
1042             int i_copy;
1043
1044             i_copy = __MIN( p_sys->i_data_size - p_sys->i_data_pos,
1045                             (int)i_len );
1046
1047             memcpy( p_buffer, &p_sys->p_data[p_sys->i_data_pos], i_copy );
1048             p_sys->i_data_pos += i_copy;
1049
1050             p_buffer += i_copy;
1051             i_len -= i_copy;
1052             i_data += i_copy;
1053         }
1054
1055         /* The caller got what he wanted */
1056         if( i_len <= 0 )
1057         {
1058             return( i_data );
1059         }
1060
1061         /* Read no more than one frame at a time.
1062          * That kills latency, especially for encoded v4l streams */
1063         if( p_sys->i_data_size && p_sys->i_data_pos == p_sys->i_data_size )
1064         {
1065             p_sys->i_data_pos = 0; p_sys->i_data_size = 0;
1066             return( i_data );
1067         }
1068
1069         /* re fill data by grabbing audio/video */
1070         p_sys->i_data_pos = 0;
1071
1072         /* try grabbing audio frames */
1073         i_stream = 1;
1074         if( p_sys->fd_audio < 0 ||
1075             GrabAudio( p_input, &p_sys->p_data, &p_sys->i_data_size, &i_pts ) )
1076         {
1077             /* and then get video frame if no audio */
1078             i_stream = 0;
1079             if( GrabVideo( p_input, &p_sys->p_data, &p_sys->i_data_size, &i_pts ) )
1080             {
1081                 return -1;
1082             }
1083         }
1084
1085         /* create pseudo header */
1086         p_sys->i_header_size = 16;
1087         p_sys->i_header_pos  = 0;
1088         SetDWBE( &p_sys->p_header[0], i_stream );
1089         SetDWBE( &p_sys->p_header[4], p_sys->i_data_size );
1090         SetQWBE( &p_sys->p_header[8], i_pts );
1091     }
1092
1093     return i_data;
1094 }
1095
1096 /****************************************************************************
1097  * I. Demux Part
1098  ****************************************************************************/
1099 #define MAX_PACKETS_IN_FIFO 3
1100
1101 static int DemuxOpen( vlc_object_t *p_this )
1102 {
1103     input_thread_t *p_input = (input_thread_t *)p_this;
1104     //demux_sys_t    *p_sys;
1105
1106     uint8_t        *p_peek;
1107     int            i_streams;
1108     int            i;
1109
1110     data_packet_t  *p_pk;
1111
1112     /* Initialize access plug-in structures. */
1113     if( p_input->i_mtu == 0 )
1114     {
1115         /* Improve speed. */
1116         p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE ;
1117     }
1118
1119     /* a little test to see if it's a v4l stream */
1120     if( input_Peek( p_input, &p_peek, 8 ) < 8 )
1121     {
1122         msg_Warn( p_input, "v4l plugin discarded (cannot peek)" );
1123         return( VLC_EGENERIC );
1124     }
1125
1126     if( strncmp( p_peek, ".v4l", 4 ) || GetDWBE( &p_peek[4] ) <= 0 )
1127     {
1128         msg_Warn( p_input, "v4l plugin discarded (not a valid stream)" );
1129         return VLC_EGENERIC;
1130     }
1131
1132     /*  create one program */
1133     vlc_mutex_lock( &p_input->stream.stream_lock );
1134     if( input_InitStream( p_input, 0 ) == -1)
1135     {
1136         vlc_mutex_unlock( &p_input->stream.stream_lock );
1137         msg_Err( p_input, "cannot init stream" );
1138         return( VLC_EGENERIC );
1139     }
1140     if( input_AddProgram( p_input, 0, 0) == NULL )
1141     {
1142         vlc_mutex_unlock( &p_input->stream.stream_lock );
1143         msg_Err( p_input, "cannot add program" );
1144         return( VLC_EGENERIC );
1145     }
1146
1147     p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
1148     p_input->stream.i_mux_rate =  0;
1149
1150     i_streams = GetDWBE( &p_peek[4] );
1151     if( input_Peek( p_input, &p_peek, 8 + 20 * i_streams )
1152         < 8 + 20 * i_streams )
1153     {
1154         msg_Err( p_input, "v4l plugin discarded (cannot peek)" );
1155         return( VLC_EGENERIC );
1156     }
1157     p_peek += 8;
1158
1159     for( i = 0; i < i_streams; i++ )
1160     {
1161         es_descriptor_t *p_es;
1162
1163         if( !strncmp( p_peek, "auds", 4 ) )
1164         {
1165 #define wf ((WAVEFORMATEX*)p_es->p_waveformatex)
1166             p_es = input_AddES( p_input, p_input->stream.pp_programs[0],
1167                                 i + 1, AUDIO_ES, NULL, 0 );
1168             p_es->i_stream_id   = i + 1;
1169             p_es->i_fourcc      =
1170                 VLC_FOURCC( p_peek[4], p_peek[5], p_peek[6], p_peek[7] );
1171
1172             p_es->p_waveformatex= malloc( sizeof( WAVEFORMATEX ) );
1173
1174             wf->wFormatTag      = WAVE_FORMAT_UNKNOWN;
1175             wf->nChannels       = GetDWBE( &p_peek[8] );
1176             wf->nSamplesPerSec  = GetDWBE( &p_peek[12] );
1177             wf->wBitsPerSample  = GetDWBE( &p_peek[16] );
1178             wf->nBlockAlign     = wf->wBitsPerSample * wf->nChannels / 8;
1179             wf->nAvgBytesPerSec = wf->nBlockAlign * wf->nSamplesPerSec;
1180             wf->cbSize          = 0;
1181
1182             msg_Dbg( p_input, "added new audio es %d channels %dHz",
1183                      wf->nChannels, wf->nSamplesPerSec );
1184
1185             input_SelectES( p_input, p_es );
1186 #undef wf
1187         }
1188         else if( !strncmp( p_peek, "vids", 4 ) )
1189         {
1190 #define bih ((BITMAPINFOHEADER*)p_es->p_bitmapinfoheader)
1191             p_es = input_AddES( p_input, p_input->stream.pp_programs[0],
1192                                 i + 1, VIDEO_ES, NULL, 0 );
1193             p_es->i_stream_id   = i + 1;
1194             p_es->i_fourcc  =
1195                 VLC_FOURCC( p_peek[4], p_peek[5], p_peek[6], p_peek[7] );
1196
1197             p_es->p_bitmapinfoheader = malloc( sizeof( BITMAPINFOHEADER ) );
1198
1199             bih->biSize     = sizeof( BITMAPINFOHEADER );
1200             bih->biWidth    = GetDWBE( &p_peek[8] );
1201             bih->biHeight   = GetDWBE( &p_peek[12] );
1202             bih->biPlanes   = 0;
1203             bih->biBitCount = 0;
1204             bih->biCompression      = 0;
1205             bih->biSizeImage= 0;
1206             bih->biXPelsPerMeter    = 0;
1207             bih->biYPelsPerMeter    = 0;
1208             bih->biClrUsed  = 0;
1209             bih->biClrImportant     = 0;
1210
1211             msg_Dbg( p_input, "added new video es %4.4s %dx%d",
1212                      (char*)&p_es->i_fourcc, bih->biWidth, bih->biHeight );
1213
1214             input_SelectES( p_input, p_es );
1215 #undef bih
1216         }
1217
1218         p_peek += 20;
1219     }
1220
1221     p_input->stream.p_selected_program->b_is_ok = 1;
1222     vlc_mutex_unlock( &p_input->stream.stream_lock );
1223
1224     if( input_SplitBuffer( p_input, &p_pk, 8 + i_streams * 20 ) > 0 )
1225     {
1226         input_DeletePacket( p_input->p_method_data, p_pk );
1227     }
1228
1229     p_input->pf_demux = Demux;
1230     return VLC_SUCCESS;
1231 }
1232
1233 static void DemuxClose( vlc_object_t *p_this )
1234 {
1235     return;
1236 }
1237
1238 static int Demux( input_thread_t *p_input )
1239 {
1240     es_descriptor_t *p_es;
1241     pes_packet_t    *p_pes;
1242
1243     int i_stream;
1244     int i_size;
1245     uint8_t *p_peek;
1246     mtime_t        i_pts;
1247
1248     if( input_Peek( p_input, &p_peek, 16 ) < 16 )
1249     {
1250         msg_Warn( p_input, "cannot peek (EOF ?)" );
1251         return( 0 );
1252     }
1253
1254     i_stream = GetDWBE( &p_peek[0] );
1255     i_size   = GetDWBE( &p_peek[4] );
1256     i_pts    = GetQWBE( &p_peek[8] );
1257
1258     //msg_Dbg( p_input, "stream=%d size=%d", i_stream, i_size );
1259 //    p_es = input_FindES( p_input, i_stream );
1260     p_es = p_input->stream.p_selected_program->pp_es[i_stream];
1261     if( !p_es )
1262     {
1263         msg_Err( p_input, "cannot find ES" );
1264     }
1265
1266     p_pes = input_NewPES( p_input->p_method_data );
1267     if( p_pes == NULL )
1268     {
1269         msg_Warn( p_input, "cannot allocate PES" );
1270         msleep( 1000 );
1271         return( 1 );
1272     }
1273     i_size += 16;
1274     while( i_size > 0 )
1275     {
1276         data_packet_t   *p_data;
1277         int i_read;
1278
1279         if( (i_read = input_SplitBuffer( p_input, &p_data,
1280                                          __MIN( i_size, 10000 ) ) ) <= 0 )
1281         {
1282             input_DeletePES( p_input->p_method_data, p_pes );
1283             return( 0 );
1284         }
1285         if( !p_pes->p_first )
1286         {
1287             p_pes->p_first = p_data;
1288             p_pes->i_nb_data = 1;
1289             p_pes->i_pes_size = i_read;
1290         }
1291         else
1292         {
1293             p_pes->p_last->p_next  = p_data;
1294             p_pes->i_nb_data++;
1295             p_pes->i_pes_size += i_read;
1296         }
1297         p_pes->p_last  = p_data;
1298         i_size -= i_read;
1299     }
1300 //    input_SplitBuffer( p_input, &p_pk, i_size + 8 );
1301     p_pes->p_first->p_payload_start += 16;
1302     p_pes->i_pes_size               -= 16;
1303     if( p_es && p_es->p_decoder_fifo )
1304     {
1305         vlc_mutex_lock( &p_es->p_decoder_fifo->data_lock );
1306         if( p_es->p_decoder_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
1307         {
1308             /* Wait for the decoder. */
1309             vlc_cond_wait( &p_es->p_decoder_fifo->data_wait,
1310                            &p_es->p_decoder_fifo->data_lock );
1311         }
1312         vlc_mutex_unlock( &p_es->p_decoder_fifo->data_lock );
1313         //p_pes->i_pts = mdate() + p_input->i_pts_delay;
1314         p_pes->i_pts = p_pes->i_dts = i_pts + p_input->i_pts_delay;
1315         input_DecodePES( p_es->p_decoder_fifo, p_pes );
1316     }
1317     else
1318     {
1319         input_DeletePES( p_input->p_method_data, p_pes );
1320     }
1321
1322     return 1;
1323 }