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