df1008adff631ba109d7bed62e8a60f6421d7cb4
[vlc.git] / modules / demux / avi / avi.c
1 /*****************************************************************************
2  * avi.c : AVI file Stream input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: avi.c,v 1.23 2003/01/11 18:31:17 fenrir Exp $
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include <stdlib.h>                                      /* malloc(), free() */
27 #include <string.h>                                              /* strdup() */
28 #include <errno.h>
29 #include <sys/types.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/input.h>
33
34 #include "video.h"
35
36 #include "libavi.h"
37
38 #define __AVI_SUBTITLE__ 1
39
40 #ifdef __AVI_SUBTITLE__
41 #   include "../util/sub.h"
42 #endif
43 #include "avi.h"
44
45 /*****************************************************************************
46  * Local prototypes
47  *****************************************************************************/
48 static int    AVIInit   ( vlc_object_t * );
49 static void __AVIEnd    ( vlc_object_t * );
50 static int    AVISeek   ( input_thread_t *, mtime_t, int );
51 static int    AVIDemux_Seekable  ( input_thread_t * );
52 static int    AVIDemux_UnSeekable( input_thread_t *p_input );
53
54 #define AVIEnd(a) __AVIEnd(VLC_OBJECT(a))
55
56 /*****************************************************************************
57  * Module descriptor
58  *****************************************************************************/
59 vlc_module_begin();
60     add_category_hint( "demuxer", NULL );
61         add_bool( "avi-interleaved", 0, NULL,
62                   "force interleaved method",
63                   "force interleaved method" );
64         add_bool( "avi-index", 0, NULL,
65                   "force index creation",
66                   "force index creation" );
67
68     set_description( "avi demuxer" );
69     set_capability( "demux", 212 );
70     set_callbacks( AVIInit, __AVIEnd );
71 vlc_module_end();
72
73 /*****************************************************************************
74  * Some useful functions to manipulate memory
75  *****************************************************************************/
76
77 static uint16_t GetWLE( uint8_t *p_buff )
78 {
79     return (uint16_t)p_buff[0] | ( ((uint16_t)p_buff[1]) << 8 );
80 }
81
82 static uint32_t GetDWLE( uint8_t *p_buff )
83 {
84     return (uint32_t)p_buff[0] | ( ((uint32_t)p_buff[1]) << 8 ) |
85             ( ((uint32_t)p_buff[2]) << 16 ) | ( ((uint32_t)p_buff[3]) << 24 );
86 }
87
88 static uint32_t GetDWBE( uint8_t *p_buff )
89 {
90     return (uint32_t)p_buff[3] | ( ((uint32_t)p_buff[2]) << 8 ) |
91             ( ((uint32_t)p_buff[1]) << 16 ) | ( ((uint32_t)p_buff[0]) << 24 );
92 }
93 static vlc_fourcc_t GetFOURCC( byte_t *p_buff )
94 {
95     return VLC_FOURCC( p_buff[0], p_buff[1], p_buff[2], p_buff[3] );
96 }
97
98 static inline off_t __EVEN( off_t i )
99 {
100     return (i & 1) ? i + 1 : i;
101 }
102
103 #define __ABS( x ) ( (x) < 0 ? (-(x)) : (x) )
104
105 /* read data in a pes */
106 static int input_ReadInPES( input_thread_t *p_input,
107                             pes_packet_t **pp_pes,
108                             size_t i_size )
109 {
110     pes_packet_t *p_pes;
111     data_packet_t *p_data;
112
113
114     if( !(p_pes = input_NewPES( p_input->p_method_data ) ) )
115     {
116         pp_pes = NULL;
117         return -1;
118     }
119
120     *pp_pes = p_pes;
121
122     if( !i_size )
123     {
124         p_pes->p_first =
125             p_pes->p_last  =
126                 input_NewPacket( p_input->p_method_data, 0 );
127         p_pes->i_nb_data = 1;
128         p_pes->i_pes_size = 0;
129         return 0;
130     }
131
132     p_pes->i_nb_data = 0;
133     p_pes->i_pes_size = 0;
134
135     while( p_pes->i_pes_size < i_size )
136     {
137         int i_read;
138
139         i_read = input_SplitBuffer(p_input,
140                                    &p_data,
141                                    __MIN( i_size -
142                                           p_pes->i_pes_size, 2048 ) );
143         if( i_read <= 0 )
144         {
145             return p_pes->i_pes_size;
146         }
147
148         if( !p_pes->p_first )
149         {
150             p_pes->p_first = p_data;
151         }
152         else
153         {
154             p_pes->p_last->p_next = p_data;
155         }
156         p_pes->p_last = p_data;
157         p_pes->i_nb_data++;
158         p_pes->i_pes_size += i_read;
159     }
160
161
162     return p_pes->i_pes_size;
163 }
164
165 /* Test if it seems that it's a key frame */
166 static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc, uint8_t *p_byte )
167 {
168     switch( i_fourcc )
169     {
170         case FOURCC_DIV1:
171             /* we have:
172              *  startcode:      0x00000100   32bits
173              *  framenumber     ?             5bits
174              *  piture type     0(I),1(P)     2bits
175              */
176             if( GetDWBE( p_byte ) != 0x00000100 )
177             {
178                 /* it's not an msmpegv1 stream, strange...*/
179                 return AVIIF_KEYFRAME;
180             }
181             else
182             {
183                 return p_byte[4] & 0x06 ? 0 : AVIIF_KEYFRAME;
184             }
185         case FOURCC_DIV2:
186         case FOURCC_DIV3:   // wmv1 also
187             /* we have
188              *  picture type    0(I),1(P)     2bits
189              */
190             return p_byte[0] & 0xC0 ? 0 : AVIIF_KEYFRAME;
191         case FOURCC_mp4v:
192             /* we should find first occurence of 0x000001b6 (32bits)
193              *  startcode:      0x000001b6   32bits
194              *  piture type     0(I),1(P)     2bits
195              */
196             if( GetDWBE( p_byte ) != 0x000001b6 )
197             {
198                 /* not true , need to find the first VOP header */
199                 return AVIIF_KEYFRAME;
200             }
201             else
202             {
203                 return p_byte[4] & 0xC0 ? 0 : AVIIF_KEYFRAME;
204             }
205         default:
206             /* I can't do it, so say yes */
207             return AVIIF_KEYFRAME;
208     }
209 }
210
211 vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t i_codec )
212 {
213     switch( i_cat )
214     {
215         case AUDIO_ES:
216             switch( i_codec )
217             {
218                 case WAVE_FORMAT_PCM:
219                     return VLC_FOURCC( 'a', 'r', 'a', 'w' );
220                 case WAVE_FORMAT_MPEG:
221                 case WAVE_FORMAT_MPEGLAYER3:
222                     return VLC_FOURCC( 'm', 'p', 'g', 'a' );
223                 case WAVE_FORMAT_A52:
224                     return VLC_FOURCC( 'a', '5', '2', ' ' );
225                 case WAVE_FORMAT_WMA1:
226                     return VLC_FOURCC( 'w', 'm', 'a', '1' );
227                 case WAVE_FORMAT_WMA2:
228                     return VLC_FOURCC( 'w', 'm', 'a', '2' );
229                 default:
230                     return VLC_FOURCC( 'm', 's',
231                                        ( i_codec >> 8 )&0xff, i_codec&0xff );
232             }
233         case VIDEO_ES:
234             // XXX DIV1 <- msmpeg4v1, DIV2 <- msmpeg4v2, DIV3 <- msmpeg4v3, mp4v for mpeg4
235             switch( i_codec )
236             {
237                 case FOURCC_DIV1:
238                 case FOURCC_div1:
239                 case FOURCC_MPG4:
240                 case FOURCC_mpg4:
241                     return FOURCC_DIV1;
242                 case FOURCC_DIV2:
243                 case FOURCC_div2:
244                 case FOURCC_MP42:
245                 case FOURCC_mp42:
246                 case FOURCC_MPG3:
247                 case FOURCC_mpg3:
248                     return FOURCC_DIV2;
249                 case FOURCC_div3:
250                 case FOURCC_MP43:
251                 case FOURCC_mp43:
252                 case FOURCC_DIV3:
253                 case FOURCC_DIV4:
254                 case FOURCC_div4:
255                 case FOURCC_DIV5:
256                 case FOURCC_div5:
257                 case FOURCC_DIV6:
258                 case FOURCC_div6:
259                 case FOURCC_AP41:
260                 case FOURCC_3IV1:
261                     return FOURCC_DIV3;
262                 case FOURCC_DIVX:
263                 case FOURCC_divx:
264                 case FOURCC_MP4S:
265                 case FOURCC_mp4s:
266                 case FOURCC_M4S2:
267                 case FOURCC_m4s2:
268                 case FOURCC_xvid:
269                 case FOURCC_XVID:
270                 case FOURCC_XviD:
271                 case FOURCC_DX50:
272                 case FOURCC_mp4v:
273                 case FOURCC_4:
274                     return FOURCC_mp4v;
275             }
276         default:
277             return VLC_FOURCC( 'u', 'n', 'd', 'f' );
278     }
279 }
280
281 static void AVI_ParseStreamHeader( vlc_fourcc_t i_id,
282                                    int *pi_number, int *pi_type )
283 {
284 #define SET_PTR( p, v ) if( p ) *(p) = (v);
285     int c1, c2;
286
287     c1 = ((uint8_t *)&i_id)[0];
288     c2 = ((uint8_t *)&i_id)[1];
289
290     if( c1 < '0' || c1 > '9' || c2 < '0' || c2 > '9' )
291     {
292         SET_PTR( pi_number, 100 ); /* > max stream number */
293         SET_PTR( pi_type, UNKNOWN_ES );
294     }
295     else
296     {
297         SET_PTR( pi_number, (c1 - '0') * 10 + (c2 - '0' ) );
298         switch( VLC_TWOCC( ((uint8_t *)&i_id)[2], ((uint8_t *)&i_id)[3] ) )
299         {
300             case AVITWOCC_wb:
301                 SET_PTR( pi_type, AUDIO_ES );
302                 break;
303             case AVITWOCC_dc:
304             case AVITWOCC_db:
305                 SET_PTR( pi_type, VIDEO_ES );
306                 break;
307             default:
308                 SET_PTR( pi_type, UNKNOWN_ES );
309                 break;
310         }
311     }
312 #undef SET_PTR
313 }
314
315 static int AVI_PacketGetHeader( input_thread_t *p_input, avi_packet_t *p_pk )
316 {
317     uint8_t  *p_peek;
318
319     if( input_Peek( p_input, &p_peek, 16 ) < 16 )
320     {
321         return VLC_EGENERIC;
322     }
323     p_pk->i_fourcc  = GetFOURCC( p_peek );
324     p_pk->i_size    = GetDWLE( p_peek + 4 );
325     p_pk->i_pos     = AVI_TellAbsolute( p_input );
326     if( p_pk->i_fourcc == AVIFOURCC_LIST )
327     {
328         p_pk->i_type = GetFOURCC( p_peek + 8 );
329     }
330     else
331     {
332         p_pk->i_type = 0;
333     }
334
335     memcpy( p_pk->i_peek, p_peek + 8, 8 );
336
337     AVI_ParseStreamHeader( p_pk->i_fourcc, &p_pk->i_stream, &p_pk->i_cat );
338     return VLC_SUCCESS;
339 }
340
341 static int AVI_PacketNext( input_thread_t *p_input )
342 {
343     avi_packet_t    avi_ck;
344
345     if( AVI_PacketGetHeader( p_input, &avi_ck ) )
346     {
347         return VLC_EGENERIC;
348     }
349     if( avi_ck.i_fourcc == AVIFOURCC_LIST && avi_ck.i_type == AVIFOURCC_rec )
350     {
351         return AVI_SkipBytes( p_input, 12 );
352     }
353     else
354     {
355         return AVI_SkipBytes( p_input, __EVEN( avi_ck.i_size ) + 8 );
356     }
357 }
358 static int AVI_PacketRead( input_thread_t   *p_input,
359                            avi_packet_t     *p_pk,
360                            pes_packet_t     **pp_pes )
361 {
362     size_t i_size;
363     vlc_bool_t b_pad;
364
365     i_size = __EVEN( p_pk->i_size + 8 );
366     b_pad  = ( i_size != p_pk->i_size + 8 );
367
368     if( input_ReadInPES( p_input, pp_pes, i_size ) != (ssize_t)i_size )
369     {
370         return VLC_EGENERIC;
371     }
372     (*pp_pes)->p_first->p_payload_start += 8;
373     (*pp_pes)->i_pes_size -= 8;
374
375     if( b_pad )
376     {
377         (*pp_pes)->p_last->p_payload_end--;
378         (*pp_pes)->i_pes_size--;
379     }
380
381     return VLC_SUCCESS;
382 }
383
384 static int AVI_PacketSearch( input_thread_t *p_input )
385 {
386     demux_sys_t     *p_avi = p_input->p_demux_data;
387
388     avi_packet_t    avi_pk;
389     for( ;; )
390     {
391         if( AVI_SkipBytes( p_input, 1 ) )
392         {
393             return VLC_EGENERIC;
394         }
395         AVI_PacketGetHeader( p_input, &avi_pk );
396         if( avi_pk.i_stream < p_avi->i_streams &&
397             ( avi_pk.i_cat == AUDIO_ES || avi_pk.i_cat == VIDEO_ES ) )
398         {
399             return VLC_SUCCESS;
400         }
401         switch( avi_pk.i_fourcc )
402         {
403             case AVIFOURCC_JUNK:
404             case AVIFOURCC_LIST:
405             case AVIFOURCC_idx1:
406                 return VLC_SUCCESS;
407         }
408     }
409 }
410
411
412 static void __AVI_AddEntryIndex( avi_stream_t *p_info,
413                                  AVIIndexEntry_t *p_index)
414 {
415     if( p_info->p_index == NULL )
416     {
417         p_info->i_idxmax = 16384;
418         p_info->i_idxnb = 0;
419         if( !( p_info->p_index = calloc( p_info->i_idxmax,
420                                   sizeof( AVIIndexEntry_t ) ) ) )
421         {
422             return;
423         }
424     }
425     if( p_info->i_idxnb >= p_info->i_idxmax )
426     {
427         p_info->i_idxmax += 16384;
428         if( !( p_info->p_index = realloc( (void*)p_info->p_index,
429                            p_info->i_idxmax *
430                            sizeof( AVIIndexEntry_t ) ) ) )
431         {
432             return;
433         }
434     }
435     /* calculate cumulate length */
436     if( p_info->i_idxnb > 0 )
437     {
438         p_index->i_lengthtotal =
439             p_info->p_index[p_info->i_idxnb - 1].i_length +
440                 p_info->p_index[p_info->i_idxnb - 1].i_lengthtotal;
441     }
442     else
443     {
444         p_index->i_lengthtotal = 0;
445     }
446
447     p_info->p_index[p_info->i_idxnb] = *p_index;
448     p_info->i_idxnb++;
449
450 }
451
452 static void AVI_IndexAddEntry( demux_sys_t *p_avi,
453                                int i_stream,
454                                AVIIndexEntry_t *p_index)
455 {
456     __AVI_AddEntryIndex( p_avi->pp_info[i_stream],
457                          p_index );
458     if( p_avi->i_movi_lastchunk_pos < p_index->i_pos )
459     {
460         p_avi->i_movi_lastchunk_pos = p_index->i_pos;
461     }
462 }
463
464 static void AVI_IndexLoad( input_thread_t *p_input )
465 {
466     demux_sys_t *p_avi = p_input->p_demux_data;
467
468     avi_chunk_list_t    *p_riff;
469     avi_chunk_list_t    *p_movi;
470     avi_chunk_idx1_t    *p_idx1;
471
472     unsigned int i_stream;
473     unsigned int i_index;
474     off_t   i_offset;
475
476     p_riff = (avi_chunk_list_t*)AVI_ChunkFind( &p_avi->ck_root,
477                                                AVIFOURCC_RIFF, 0);
478
479     p_idx1 = (avi_chunk_idx1_t*)AVI_ChunkFind( p_riff, AVIFOURCC_idx1, 0);
480     p_movi = (avi_chunk_list_t*)AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
481
482     if( !p_idx1 )
483     {
484         msg_Warn( p_input, "cannot find idx1 chunk, no index defined" );
485         return;
486     }
487     for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
488     {
489         p_avi->pp_info[i_stream]->i_idxnb  = 0;
490         p_avi->pp_info[i_stream]->i_idxmax = 0;
491         p_avi->pp_info[i_stream]->p_index  = NULL;
492     }
493     /* *** calculate offset *** */
494     if( p_idx1->i_entry_count > 0 &&
495         p_idx1->entry[0].i_pos < p_movi->i_chunk_pos )
496     {
497         i_offset = p_movi->i_chunk_pos + 8;
498     }
499     else
500     {
501         i_offset = 0;
502     }
503
504     for( i_index = 0; i_index < p_idx1->i_entry_count; i_index++ )
505     {
506         unsigned int i_cat;
507
508         AVI_ParseStreamHeader( p_idx1->entry[i_index].i_fourcc,
509                                &i_stream,
510                                &i_cat );
511         if( i_stream < p_avi->i_streams &&
512             i_cat == p_avi->pp_info[i_stream]->i_cat )
513         {
514             AVIIndexEntry_t index;
515             index.i_id      = p_idx1->entry[i_index].i_fourcc;
516             index.i_flags   =
517                 p_idx1->entry[i_index].i_flags&(~AVIIF_FIXKEYFRAME);
518             index.i_pos     = p_idx1->entry[i_index].i_pos + i_offset;
519             index.i_length  = p_idx1->entry[i_index].i_length;
520             AVI_IndexAddEntry( p_avi, i_stream, &index );
521         }
522     }
523     for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
524     {
525         msg_Dbg( p_input,
526                 "stream[%d] creating %d index entries",
527                 i_stream,
528                 p_avi->pp_info[i_stream]->i_idxnb );
529     }
530
531 }
532
533 static void AVI_IndexCreate( input_thread_t *p_input )
534 {
535     demux_sys_t *p_avi = p_input->p_demux_data;
536
537     avi_chunk_list_t    *p_riff;
538     avi_chunk_list_t    *p_movi;
539
540     unsigned int i_stream;
541     off_t i_movi_end;
542
543     p_riff = (avi_chunk_list_t*)AVI_ChunkFind( &p_avi->ck_root,
544                                                AVIFOURCC_RIFF, 0);
545     p_movi = (avi_chunk_list_t*)AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
546
547     if( !p_movi )
548     {
549         msg_Err( p_input, "cannot find p_movi" );
550         return;
551     }
552
553     for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
554     {
555         p_avi->pp_info[i_stream]->i_idxnb  = 0;
556         p_avi->pp_info[i_stream]->i_idxmax = 0;
557         p_avi->pp_info[i_stream]->p_index  = NULL;
558     }
559     i_movi_end = __MIN( (off_t)(p_movi->i_chunk_pos + p_movi->i_chunk_size),
560                         p_input->stream.p_selected_area->i_size );
561
562     AVI_SeekAbsolute( p_input, p_movi->i_chunk_pos + 12);
563     msg_Warn( p_input, "creating index from LIST-movi, will take time !" );
564     for( ;; )
565     {
566         avi_packet_t pk;
567
568         if( AVI_PacketGetHeader( p_input, &pk ) )
569         {
570             break;
571         }
572         if( pk.i_stream < p_avi->i_streams &&
573             pk.i_cat == p_avi->pp_info[pk.i_stream]->i_cat )
574         {
575             AVIIndexEntry_t index;
576             index.i_id      = pk.i_fourcc;
577             index.i_flags   =
578                AVI_GetKeyFlag(p_avi->pp_info[pk.i_stream]->i_codec, pk.i_peek);
579             index.i_pos     = pk.i_pos;
580             index.i_length  = pk.i_size;
581             AVI_IndexAddEntry( p_avi, pk.i_stream, &index );
582         }
583         else
584         {
585             switch( pk.i_fourcc )
586             {
587                 case AVIFOURCC_idx1:
588                     goto print_stat;
589                 case AVIFOURCC_rec:
590                 case AVIFOURCC_JUNK:
591                     break;
592                 default:
593                     msg_Warn( p_input, "need resync, probably broken avi" );
594                     if( AVI_PacketSearch( p_input ) )
595                     {
596                         msg_Warn( p_input, "lost sync, abord index creation" );
597                         goto print_stat;
598                     }
599             }
600         }
601         if( pk.i_pos + pk.i_size >= i_movi_end ||
602             AVI_PacketNext( p_input ) )
603         {
604             break;
605         }
606     }
607
608 print_stat:
609     for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
610     {
611         msg_Dbg( p_input,
612                 "stream[%d] creating %d index entries",
613                 i_stream,
614                 p_avi->pp_info[i_stream]->i_idxnb );
615     }
616 }
617
618
619 /*****************************************************************************
620  * Stream management
621  *****************************************************************************/
622 static vlc_bool_t AVI_StreamStart ( input_thread_t *, demux_sys_t *, int );
623 static int  AVI_StreamSeek   ( input_thread_t *, demux_sys_t *, int, mtime_t );
624 static void AVI_StreamStop   ( input_thread_t *, demux_sys_t *, int );
625
626 static vlc_bool_t AVI_StreamStart( input_thread_t *p_input,
627                                    demux_sys_t *p_avi, int i_stream )
628 {
629 #define p_stream    p_avi->pp_info[i_stream]
630     if( !p_stream->p_es )
631     {
632         msg_Warn( p_input, "stream[%d] unselectable", i_stream );
633         return VLC_FALSE;
634     }
635     if( p_stream->b_activated )
636     {
637         msg_Warn( p_input, "stream[%d] already selected", i_stream );
638         return VLC_TRUE;
639     }
640
641     if( !p_stream->p_es->p_decoder_fifo )
642     {
643         vlc_mutex_lock( &p_input->stream.stream_lock );
644         input_SelectES( p_input, p_stream->p_es );
645         vlc_mutex_unlock( &p_input->stream.stream_lock );
646     }
647     p_stream->b_activated = p_stream->p_es->p_decoder_fifo ? VLC_TRUE
648                                                            : VLC_FALSE;
649     if( p_stream->b_activated && p_avi->b_seekable)
650     {
651         AVI_StreamSeek( p_input, p_avi, i_stream, p_avi->i_time );
652     }
653
654     return p_stream->b_activated;
655 #undef  p_stream
656 }
657
658 static void    AVI_StreamStop( input_thread_t *p_input,
659                                demux_sys_t *p_avi, int i_stream )
660 {
661 #define p_stream    p_avi->pp_info[i_stream]
662
663     if( !p_stream->b_activated )
664     {
665         msg_Warn( p_input, "stream[%d] already unselected", i_stream );
666         return;
667     }
668
669     if( p_stream->p_es->p_decoder_fifo )
670     {
671         vlc_mutex_lock( &p_input->stream.stream_lock );
672         input_UnselectES( p_input, p_stream->p_es );
673         vlc_mutex_unlock( &p_input->stream.stream_lock );
674     }
675
676
677     p_stream->b_activated = VLC_FALSE;
678
679 #undef  p_stream
680 }
681
682 /****************************************************************************
683  * AVI_MovieGetLength give max streams length in second
684  ****************************************************************************/
685 static mtime_t  AVI_MovieGetLength( input_thread_t *p_input, demux_sys_t *p_avi )
686 {
687     unsigned int i_stream;
688     mtime_t i_maxlength;
689
690     i_maxlength = 0;
691     for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
692     {
693 #define p_stream  p_avi->pp_info[i_stream]
694         mtime_t i_length;
695         /* fix length for each stream */
696         if( p_stream->i_idxnb < 1 || !p_stream->p_index )
697         {
698             continue;
699         }
700
701         if( p_stream->i_samplesize )
702         {
703             i_length =
704                 (mtime_t)( p_stream->p_index[p_stream->i_idxnb-1].i_lengthtotal +
705                            p_stream->p_index[p_stream->i_idxnb-1].i_length ) /
706                 (mtime_t)p_stream->i_scale /
707                 (mtime_t)p_stream->i_rate /
708                 (mtime_t)p_stream->i_samplesize;
709         }
710         else
711         {
712             i_length = (mtime_t)p_stream->i_idxnb *
713                        (mtime_t)p_stream->i_scale /
714                        (mtime_t)p_stream->i_rate;
715         }
716
717         msg_Dbg( p_input,
718                  "stream[%d] length:"I64Fd" (based on index)",
719                  i_stream,
720                  i_length );
721         i_maxlength = __MAX( i_maxlength, i_length );
722 #undef p_stream
723     }
724
725     return i_maxlength;
726 }
727
728 /*****************************************************************************
729  * AVIEnd: frees unused data
730  *****************************************************************************/
731 static void __AVIEnd ( vlc_object_t * p_this )
732 {
733     input_thread_t *    p_input = (input_thread_t *)p_this;
734     unsigned int i;
735     demux_sys_t *p_avi = p_input->p_demux_data  ;
736
737     if( p_avi->pp_info )
738     {
739         for( i = 0; i < p_avi->i_streams; i++ )
740         {
741             if( p_avi->pp_info[i] )
742             {
743                 if( p_avi->pp_info[i]->p_index )
744                 {
745                       free( p_avi->pp_info[i]->p_index );
746                 }
747                 free( p_avi->pp_info[i] );
748             }
749         }
750          free( p_avi->pp_info );
751     }
752 #ifdef __AVI_SUBTITLE__
753     if( p_avi->p_sub )
754     {
755         subtitle_Close( p_avi->p_sub );
756         p_avi->p_sub = NULL;
757     }
758 #endif
759     AVI_ChunkFreeRoot( p_input, &p_avi->ck_root );
760 }
761
762 /*****************************************************************************
763  * AVIInit: check file and initializes AVI structures
764  *****************************************************************************/
765 static int AVIInit( vlc_object_t * p_this )
766 {
767     input_thread_t *    p_input = (input_thread_t *)p_this;
768     avi_chunk_t         ck_riff;
769     avi_chunk_list_t    *p_riff = (avi_chunk_list_t*)&ck_riff;
770     avi_chunk_list_t    *p_hdrl, *p_movi;
771 #if 0
772     avi_chunk_list_t    *p_INFO;
773     avi_chunk_strz_t    *p_name;
774 #endif
775     avi_chunk_avih_t    *p_avih;
776     demux_sys_t *p_avi;
777     es_descriptor_t *p_es = NULL; /* avoid warning */
778     unsigned int i;
779 #ifdef __AVI_SUBTITLE__
780     mtime_t i_microsecperframe = 0; // for some subtitle format
781 #endif
782
783     vlc_bool_t b_stream_audio, b_stream_video;
784
785     p_input->pf_demux = AVIDemux_Seekable;
786     if( AVI_TestFile( p_input ) )
787     {
788         msg_Warn( p_input, "avi module discarded (invalid headr)" );
789         return VLC_EGENERIC;
790     }
791
792     /* Initialize access plug-in structures. */
793     if( p_input->i_mtu == 0 )
794     {
795         /* Improve speed. */
796         p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
797     }
798
799     if( !( p_input->p_demux_data =
800                     p_avi = malloc( sizeof(demux_sys_t) ) ) )
801     {
802         msg_Err( p_input, "out of memory" );
803         return VLC_ENOMEM;
804     }
805     memset( p_avi, 0, sizeof( demux_sys_t ) );
806     p_avi->i_time = 0;
807     p_avi->i_pcr  = 0;
808     p_avi->b_seekable = ( ( p_input->stream.b_seekable )
809                         &&( p_input->stream.i_method == INPUT_METHOD_FILE ) );
810     p_avi->i_movi_lastchunk_pos = 0;
811
812     /* *** for unseekable stream, automaticaly use AVIDemux_interleaved *** */
813     if( !p_avi->b_seekable || config_GetInt( p_input, "avi-interleaved" ) )
814     {
815         p_input->pf_demux = AVIDemux_UnSeekable;
816     }
817
818     if( AVI_ChunkReadRoot( p_input, &p_avi->ck_root, p_avi->b_seekable ) )
819     {
820         msg_Err( p_input, "avi module discarded (invalid file)" );
821         return VLC_EGENERIC;
822     }
823     AVI_ChunkDumpDebug( p_input, &p_avi->ck_root );
824
825
826     p_riff  = (avi_chunk_list_t*)AVI_ChunkFind( &p_avi->ck_root,
827                                                 AVIFOURCC_RIFF, 0 );
828     p_hdrl  = (avi_chunk_list_t*)AVI_ChunkFind( p_riff,
829                                                 AVIFOURCC_hdrl, 0 );
830     p_movi  = (avi_chunk_list_t*)AVI_ChunkFind( p_riff,
831                                                 AVIFOURCC_movi, 0 );
832 #if 0
833     p_INFO  = (avi_chunk_list_t*)AVI_ChunkFind( p_riff,
834                                                 AVIFOURCC_INFO, 0 );
835     p_name  = (avi_chunk_strz_t*)AVI_ChunkFind( p_INFO,
836                                                 AVIFOURCC_INAM, 0 );
837     if( p_name )
838     {
839
840     }
841 #endif
842
843     if( !p_hdrl || !p_movi )
844     {
845         msg_Err( p_input, "avi module discarded (invalid file)" );
846         return VLC_EGENERIC;
847     }
848
849     if( !( p_avih = (avi_chunk_avih_t*)AVI_ChunkFind( p_hdrl,
850                                                       AVIFOURCC_avih, 0 ) ) )
851     {
852         msg_Err( p_input, "cannot find avih chunk" );
853         return VLC_EGENERIC;
854     }
855     p_avi->i_streams = AVI_ChunkCount( p_hdrl, AVIFOURCC_strl );
856     if( p_avih->i_streams != p_avi->i_streams )
857     {
858         msg_Warn( p_input,
859                   "found %d stream but %d are declared",
860                   p_avi->i_streams,
861                   p_avih->i_streams );
862     }
863     if( p_avi->i_streams == 0 )
864     {
865         AVIEnd( p_input );
866         msg_Err( p_input, "no stream defined!" );
867         return VLC_EGENERIC;
868     }
869
870     /*  create one program */
871     vlc_mutex_lock( &p_input->stream.stream_lock );
872     if( input_InitStream( p_input, 0 ) == -1)
873     {
874         vlc_mutex_unlock( &p_input->stream.stream_lock );
875         AVIEnd( p_input );
876         msg_Err( p_input, "cannot init stream" );
877         return VLC_EGENERIC;
878     }
879     if( input_AddProgram( p_input, 0, 0) == NULL )
880     {
881         vlc_mutex_unlock( &p_input->stream.stream_lock );
882         AVIEnd( p_input );
883         msg_Err( p_input, "cannot add program" );
884         return VLC_EGENERIC;
885     }
886     p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
887     vlc_mutex_unlock( &p_input->stream.stream_lock );
888
889     /* print informations on streams */
890     msg_Dbg( p_input, "AVIH: %d stream, flags %s%s%s%s ",
891              p_avi->i_streams,
892              p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
893              p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
894              p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
895              p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
896     {
897         input_info_category_t *p_cat = input_InfoCategory( p_input, "Avi" );
898         input_AddInfo( p_cat, "Number of streams", "%d", p_avi->i_streams );
899         input_AddInfo( p_cat, "Flags", "%s%s%s%s",
900                        p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
901                        p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
902                        p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
903                        p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
904     }
905         
906     /* now read info on each stream and create ES */
907     p_avi->pp_info = calloc( p_avi->i_streams,
908                             sizeof( avi_stream_t* ) );
909     memset( p_avi->pp_info,
910             0,
911             sizeof( avi_stream_t* ) * p_avi->i_streams );
912
913     for( i = 0 ; i < p_avi->i_streams; i++ )
914     {
915         avi_chunk_list_t    *p_avi_strl;
916         avi_chunk_strh_t    *p_avi_strh;
917         avi_chunk_strf_auds_t    *p_avi_strf_auds;
918         avi_chunk_strf_vids_t    *p_avi_strf_vids;
919         int     i_init_size;
920         void    *p_init_data;
921 #define p_info  p_avi->pp_info[i]
922         p_info = malloc( sizeof(avi_stream_t ) );
923         memset( p_info, 0, sizeof( avi_stream_t ) );
924
925         p_avi_strl = (avi_chunk_list_t*)AVI_ChunkFind( p_hdrl,
926                                                        AVIFOURCC_strl, i );
927         p_avi_strh = (avi_chunk_strh_t*)AVI_ChunkFind( p_avi_strl,
928                                                        AVIFOURCC_strh, 0 );
929         p_avi_strf_auds = (avi_chunk_strf_auds_t*)
930             p_avi_strf_vids = (avi_chunk_strf_vids_t*)
931                 AVI_ChunkFind( p_avi_strl, AVIFOURCC_strf, 0 );
932
933         if( !p_avi_strl || !p_avi_strh ||
934                 ( !p_avi_strf_auds && !p_avi_strf_vids ) )
935         {
936             msg_Warn( p_input, "stream[%d] incomlete", i );
937             continue;
938         }
939
940         /* *** Init p_info *** */
941         p_info->i_rate  = p_avi_strh->i_rate;
942         p_info->i_scale = p_avi_strh->i_scale;
943         p_info->i_samplesize = p_avi_strh->i_samplesize;
944
945         switch( p_avi_strh->i_type )
946         {
947             case( AVIFOURCC_auds ):
948                 p_info->i_cat = AUDIO_ES;
949                 p_info->i_fourcc =
950                     AVI_FourccGetCodec( AUDIO_ES,
951                                         p_avi_strf_auds->p_wf->wFormatTag );
952                 p_info->i_codec  = p_info->i_fourcc;
953                 i_init_size = p_avi_strf_auds->i_chunk_size;
954                 p_init_data = p_avi_strf_auds->p_wf;
955                 msg_Dbg( p_input, "stream[%d] audio(0x%x) %d channels %dHz %dbits",
956                         i,
957                         p_avi_strf_auds->p_wf->wFormatTag,
958                         p_avi_strf_auds->p_wf->nChannels,
959                         p_avi_strf_auds->p_wf->nSamplesPerSec,
960                         p_avi_strf_auds->p_wf->wBitsPerSample );
961                 {
962                     char hepp[sizeof("Stream") + 10];
963                     input_info_category_t *p_cat;
964                     sprintf(hepp, "Stream %d", i);
965                     p_cat = input_InfoCategory( p_input, hepp);
966                     input_AddInfo( p_cat, "Type", "audio(0x%x)",
967                                    p_avi_strf_auds->p_wf->wFormatTag );
968                     input_AddInfo( p_cat, "Codec", "%4.4s",
969                                    (const char*)&(p_info->i_codec) );
970                     input_AddInfo( p_cat, "Channels", "%d",
971                                    p_avi_strf_auds->p_wf->nChannels );
972                     input_AddInfo( p_cat, "Samplerate", "%d",
973                                    p_avi_strf_auds->p_wf->nSamplesPerSec );
974                     input_AddInfo( p_cat, "Bits Per Sample", "%d",
975                                    p_avi_strf_auds->p_wf->wBitsPerSample );
976                 }
977                 break;
978
979             case( AVIFOURCC_vids ):
980                 p_info->i_cat = VIDEO_ES;
981                 /* XXX quick hack for playing ffmpeg video, I don't know
982                     who is doing something wrong */
983                 p_info->i_samplesize = 0;
984                 p_info->i_fourcc = p_avi_strf_vids->p_bih->biCompression;
985                 p_info->i_codec =
986                     AVI_FourccGetCodec( VIDEO_ES, p_info->i_fourcc );
987                 i_init_size = p_avi_strf_vids->i_chunk_size;
988                 p_init_data = p_avi_strf_vids->p_bih;
989                 msg_Dbg( p_input, "stream[%d] video(%4.4s) %dx%d %dbpp %ffps",
990                         i,
991                          (char*)&p_avi_strf_vids->p_bih->biCompression,
992                          p_avi_strf_vids->p_bih->biWidth,
993                          p_avi_strf_vids->p_bih->biHeight,
994                          p_avi_strf_vids->p_bih->biBitCount,
995                          (float)p_info->i_rate /
996                              (float)p_info->i_scale );
997                 {
998                     char hepp[sizeof("Stream") + 10];
999                     input_info_category_t *p_cat;
1000                     sprintf(hepp, "stream %d", i);
1001                     p_cat = input_InfoCategory( p_input, hepp);
1002                     input_AddInfo( p_cat, "Type", "video" );
1003                     input_AddInfo( p_cat, "Codec", "%4.4s",
1004                                    (const char*)&(p_info->i_codec) );
1005                     input_AddInfo( p_cat, "Resolution", "%dx%d",
1006                                    p_avi_strf_vids->p_bih->biWidth,
1007                                    p_avi_strf_vids->p_bih->biHeight );
1008                     input_AddInfo( p_cat, "Frame Rate", "%f",
1009                                    (float)p_info->i_rate /
1010                                        (float)p_info->i_scale );
1011                     input_AddInfo( p_cat, "Bits Per Pixel", "%d",
1012                                    p_avi_strf_vids->p_bih->biBitCount );
1013                 }
1014 #ifdef __AVI_SUBTITLE__
1015                 if( i_microsecperframe == 0 )
1016                 {
1017                     i_microsecperframe = (mtime_t)1000000 *
1018                                          (mtime_t)p_info->i_scale /
1019                                          (mtime_t)p_info->i_rate;
1020                 }
1021 #endif
1022                 break;
1023             default:
1024                 msg_Err( p_input, "stream[%d] unknown type", i );
1025                 p_info->i_cat = UNKNOWN_ES;
1026                 i_init_size = 0;
1027                 p_init_data = NULL;
1028                 {
1029                     char psz_cat[32]; /* We'll clip i just in case */
1030                     input_info_category_t *p_cat;
1031                     sprintf( psz_cat, "stream %d", __MIN( i, 100000 ) );
1032                     p_cat = input_InfoCategory( p_input, psz_cat );
1033                     input_AddInfo( p_cat, "Type", "unknown" );
1034                 }
1035                 break;
1036         }
1037         p_info->b_activated = VLC_FALSE;
1038         /* add one ES */
1039         vlc_mutex_lock( &p_input->stream.stream_lock );
1040         p_info->p_es =
1041             p_es = input_AddES( p_input,
1042                                 p_input->stream.p_selected_program, 1+i,
1043                                 0 );
1044         vlc_mutex_unlock( &p_input->stream.stream_lock );
1045         p_es->i_stream_id =i; /* XXX: i don't use it */
1046         p_es->i_fourcc = p_info->i_fourcc;
1047         p_es->i_cat = p_info->i_cat;
1048         if( p_es->i_cat == AUDIO_ES )
1049         {
1050             p_es->p_waveformatex = malloc( i_init_size );
1051             memcpy( p_es->p_waveformatex, p_init_data, i_init_size );
1052         }
1053         else if( p_es->i_cat == VIDEO_ES )
1054         {
1055             p_es->p_bitmapinfoheader = malloc( i_init_size );
1056             memcpy( p_es->p_bitmapinfoheader, p_init_data, i_init_size );
1057         }
1058 #undef p_info
1059     }
1060
1061 #ifdef __AVI_SUBTITLE__
1062     if( ( p_avi->p_sub = subtitle_New( p_input, NULL, i_microsecperframe ) ) )
1063     {
1064         subtitle_Select( p_avi->p_sub );
1065     }
1066 #endif
1067
1068     if( config_GetInt( p_input, "avi-index" ) )
1069     {
1070         if( p_avi->b_seekable )
1071         {
1072             AVI_IndexCreate( p_input );
1073         }
1074         else
1075         {
1076             msg_Warn( p_input, "cannot create index (unseekable stream)" );
1077             AVI_IndexLoad( p_input );
1078         }
1079     }
1080     else
1081     {
1082         AVI_IndexLoad( p_input );
1083     }
1084
1085     /* *** movie length in sec *** */
1086     p_avi->i_length = AVI_MovieGetLength( p_input, p_avi );
1087     if( p_avi->i_length < (mtime_t)p_avih->i_totalframes *
1088                           (mtime_t)p_avih->i_microsecperframe /
1089                           (mtime_t)1000000 )
1090     {
1091         msg_Warn( p_input, "broken or missing index, 'seek' will be axproximative or will have strange behavour" );
1092     }
1093
1094     vlc_mutex_lock( &p_input->stream.stream_lock );
1095     if( p_avi->i_length )
1096     {
1097         p_input->stream.i_mux_rate =
1098             p_input->stream.p_selected_area->i_size / 50 / p_avi->i_length;
1099     }
1100     else
1101     {
1102         p_input->stream.i_mux_rate = 0;
1103     }
1104     vlc_mutex_unlock( &p_input->stream.stream_lock );
1105
1106     b_stream_audio = VLC_FALSE;
1107     b_stream_video = VLC_FALSE;
1108
1109     for( i = 0; i < p_avi->i_streams; i++ )
1110     {
1111 #define p_info  p_avi->pp_info[i]
1112         switch( p_info->p_es->i_cat )
1113         {
1114             case( VIDEO_ES ):
1115
1116                 if( !b_stream_video )
1117                 {
1118                     b_stream_video = AVI_StreamStart( p_input, p_avi, i );
1119                 }
1120                 break;
1121
1122             case( AUDIO_ES ):
1123                 if( !b_stream_audio )
1124                 {
1125                     b_stream_audio = AVI_StreamStart( p_input, p_avi, i );
1126                 }
1127                 break;
1128             default:
1129                 break;
1130         }
1131 #undef p_info
1132     }
1133
1134     if( !b_stream_video )
1135     {
1136         msg_Warn( p_input, "no video stream found" );
1137     }
1138     if( !b_stream_audio )
1139     {
1140         msg_Warn( p_input, "no audio stream found!" );
1141     }
1142
1143     vlc_mutex_lock( &p_input->stream.stream_lock );
1144     p_input->stream.p_selected_program->b_is_ok = 1;
1145     vlc_mutex_unlock( &p_input->stream.stream_lock );
1146
1147     if( p_avi->b_seekable )
1148     {
1149         AVI_ChunkGoto( p_input, p_movi );
1150     }
1151     else
1152     {
1153         // already at begining of p_movi
1154     }
1155     AVI_SkipBytes( p_input, 12 ); // enter in p_movi
1156
1157     p_avi->i_movi_begin = p_movi->i_chunk_pos;
1158     return VLC_SUCCESS;
1159 }
1160
1161
1162
1163
1164 /*****************************************************************************
1165  * Function to convert pts to chunk or byte
1166  *****************************************************************************/
1167
1168 static inline mtime_t AVI_PTSToChunk( avi_stream_t *p_info,
1169                                         mtime_t i_pts )
1170 {
1171     return (mtime_t)((int64_t)i_pts *
1172                      (int64_t)p_info->i_rate /
1173                      (int64_t)p_info->i_scale /
1174                      (int64_t)1000000 );
1175 }
1176 static inline mtime_t AVI_PTSToByte( avi_stream_t *p_info,
1177                                        mtime_t i_pts )
1178 {
1179     return (mtime_t)((int64_t)i_pts *
1180                      (int64_t)p_info->i_rate /
1181                      (int64_t)p_info->i_scale /
1182                      (int64_t)1000000 *
1183                      (int64_t)p_info->i_samplesize );
1184 }
1185
1186 static mtime_t AVI_GetDPTS( avi_stream_t *p_stream, int i_count )
1187 {
1188     if( p_stream->i_samplesize )
1189     {
1190         return (mtime_t)( (int64_t)1000000 *
1191                    (int64_t)i_count *
1192                    (int64_t)p_stream->i_scale /
1193                    (int64_t)p_stream->i_rate /
1194                    (int64_t)p_stream->i_samplesize );
1195     }
1196     else
1197     {
1198         return (mtime_t)( (int64_t)1000000 *
1199                    (int64_t)i_count *
1200                    (int64_t)p_stream->i_scale /
1201                    (int64_t)p_stream->i_rate);
1202     }
1203
1204 }
1205
1206 static mtime_t AVI_GetPTS( avi_stream_t *p_info )
1207 {
1208
1209     if( p_info->i_samplesize )
1210     {
1211         /* we need a valid entry we will emulate one */
1212         int64_t i_len;
1213         if( p_info->i_idxposc == p_info->i_idxnb )
1214         {
1215             if( p_info->i_idxposc )
1216             {
1217                 /* use the last entry */
1218                 i_len = p_info->p_index[p_info->i_idxnb - 1].i_lengthtotal
1219                             + p_info->p_index[p_info->i_idxnb - 1].i_length
1220                             + p_info->i_idxposb; /* should be 0 */
1221             }
1222             else
1223             {
1224                 i_len = p_info->i_idxposb;
1225                 /* no valid entry use only offset*/
1226             }
1227         }
1228         else
1229         {
1230             i_len = p_info->p_index[p_info->i_idxposc].i_lengthtotal
1231                                 + p_info->i_idxposb;
1232         }
1233         return (mtime_t)( (int64_t)1000000 *
1234                   (int64_t)i_len *
1235                    (int64_t)p_info->i_scale /
1236                    (int64_t)p_info->i_rate /
1237                    (int64_t)p_info->i_samplesize );
1238     }
1239     else
1240     {
1241         /* even if p_info->i_idxposc isn't valid, there isn't any problem */
1242         return (mtime_t)( (int64_t)1000000 *
1243                    (int64_t)(p_info->i_idxposc ) *
1244                    (int64_t)p_info->i_scale /
1245                    (int64_t)p_info->i_rate);
1246     }
1247 }
1248
1249 static int AVI_StreamChunkFind( input_thread_t *p_input,
1250                                 unsigned int i_stream )
1251 {
1252     demux_sys_t *p_avi = p_input->p_demux_data;
1253     avi_packet_t avi_pk;
1254
1255     /* find first chunk of i_stream that isn't in index */
1256
1257     if( p_avi->i_movi_lastchunk_pos >= p_avi->i_movi_begin )
1258     {
1259         AVI_SeekAbsolute( p_input, p_avi->i_movi_lastchunk_pos );
1260         if( AVI_PacketNext( p_input ) )
1261         {
1262             return VLC_EGENERIC;
1263         }
1264     }
1265     else
1266     {
1267         AVI_SeekAbsolute( p_input, p_avi->i_movi_begin );
1268     }
1269
1270     for( ;; )
1271     {
1272
1273         if( AVI_PacketGetHeader( p_input, &avi_pk ) )
1274         {
1275             msg_Err( p_input, "cannot get packet header" );
1276             return VLC_EGENERIC;
1277         }
1278         if( avi_pk.i_stream >= p_avi->i_streams ||
1279             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
1280         {
1281             switch( avi_pk.i_fourcc )
1282             {
1283                 case AVIFOURCC_LIST:
1284                     AVI_SkipBytes( p_input, 12 );
1285                     break;
1286                 default:
1287                     if( AVI_PacketNext( p_input ) )
1288                     {
1289                         return VLC_EGENERIC;
1290                     }
1291                     break;
1292             }
1293         }
1294         else
1295         {
1296             /* add this chunk to the index */
1297             AVIIndexEntry_t index;
1298
1299             index.i_id = avi_pk.i_fourcc;
1300             index.i_flags =
1301                AVI_GetKeyFlag(p_avi->pp_info[avi_pk.i_stream]->i_codec,
1302                               avi_pk.i_peek);
1303             index.i_pos = avi_pk.i_pos;
1304             index.i_length = avi_pk.i_size;
1305             AVI_IndexAddEntry( p_avi, avi_pk.i_stream, &index );
1306
1307             if( avi_pk.i_stream == i_stream  )
1308             {
1309                 return VLC_SUCCESS;
1310             }
1311
1312             if( AVI_PacketNext( p_input ) )
1313             {
1314                 return VLC_EGENERIC;
1315             }
1316         }
1317     }
1318 }
1319
1320
1321 /* be sure that i_ck will be a valid index entry */
1322 static int AVI_SetStreamChunk( input_thread_t    *p_input,
1323                                unsigned int i_stream,
1324                                unsigned int i_ck )
1325 {
1326     demux_sys_t *p_avi = p_input->p_demux_data;
1327     avi_stream_t *p_stream = p_avi->pp_info[i_stream];
1328
1329     p_stream->i_idxposc = i_ck;
1330     p_stream->i_idxposb = 0;
1331
1332     if(  i_ck >= p_stream->i_idxnb )
1333     {
1334         p_stream->i_idxposc = p_stream->i_idxnb - 1;
1335         do
1336         {
1337             p_stream->i_idxposc++;
1338             if( AVI_StreamChunkFind( p_input, i_stream ) )
1339             {
1340                 return VLC_EGENERIC;
1341             }
1342
1343         } while( p_stream->i_idxposc < i_ck );
1344     }
1345
1346     return VLC_SUCCESS;
1347 }
1348
1349
1350 /* XXX FIXME up to now, we assume that all chunk are one after one */
1351 static int AVI_SetStreamBytes( input_thread_t    *p_input,
1352                                unsigned int i_stream,
1353                                off_t   i_byte )
1354 {
1355     demux_sys_t *p_avi = p_input->p_demux_data;
1356     avi_stream_t *p_stream = p_avi->pp_info[i_stream];
1357
1358     if( ( p_stream->i_idxnb > 0 )
1359         &&( i_byte < p_stream->p_index[p_stream->i_idxnb - 1].i_lengthtotal +
1360                 p_stream->p_index[p_stream->i_idxnb - 1].i_length ) )
1361     {
1362         /* index is valid to find the ck */
1363         /* uses dichototmie to be fast enougth */
1364         int i_idxposc = __MIN( p_stream->i_idxposc, p_stream->i_idxnb - 1 );
1365         int i_idxmax  = p_stream->i_idxnb;
1366         int i_idxmin  = 0;
1367         for( ;; )
1368         {
1369             if( p_stream->p_index[i_idxposc].i_lengthtotal > i_byte )
1370             {
1371                 i_idxmax  = i_idxposc ;
1372                 i_idxposc = ( i_idxmin + i_idxposc ) / 2 ;
1373             }
1374             else
1375             {
1376                 if( p_stream->p_index[i_idxposc].i_lengthtotal +
1377                         p_stream->p_index[i_idxposc].i_length <= i_byte)
1378                 {
1379                     i_idxmin  = i_idxposc ;
1380                     i_idxposc = (i_idxmax + i_idxposc ) / 2 ;
1381                 }
1382                 else
1383                 {
1384                     p_stream->i_idxposc = i_idxposc;
1385                     p_stream->i_idxposb = i_byte -
1386                             p_stream->p_index[i_idxposc].i_lengthtotal;
1387                     return VLC_SUCCESS;
1388                 }
1389             }
1390         }
1391
1392     }
1393     else
1394     {
1395         p_stream->i_idxposc = p_stream->i_idxnb - 1;
1396         p_stream->i_idxposb = 0;
1397         do
1398         {
1399             p_stream->i_idxposc++;
1400             if( AVI_StreamChunkFind( p_input, i_stream ) )
1401             {
1402                 return VLC_EGENERIC;
1403             }
1404
1405         } while( p_stream->p_index[p_stream->i_idxposc].i_lengthtotal +
1406                     p_stream->p_index[p_stream->i_idxposc].i_length <= i_byte );
1407
1408         p_stream->i_idxposb = i_byte -
1409                        p_stream->p_index[p_stream->i_idxposc].i_lengthtotal;
1410         return VLC_SUCCESS;
1411     }
1412 }
1413
1414 static int AVI_StreamSeek( input_thread_t *p_input,
1415                            demux_sys_t  *p_avi,
1416                            int i_stream,
1417                            mtime_t i_date )
1418 {
1419 #define p_stream    p_avi->pp_info[i_stream]
1420     mtime_t i_oldpts;
1421
1422     i_oldpts = AVI_GetPTS( p_stream );
1423
1424     if( !p_stream->i_samplesize )
1425     {
1426         if( AVI_SetStreamChunk( p_input,
1427                                 i_stream,
1428                                 AVI_PTSToChunk( p_stream, i_date ) ) )
1429         {
1430             return VLC_EGENERIC;
1431         }
1432
1433         /* search key frame */
1434         msg_Dbg( p_input,
1435                  "old:"I64Fd" %s new "I64Fd,
1436                  i_oldpts,
1437                  i_oldpts > i_date ? ">" : "<",
1438                  i_date );
1439
1440         if( i_date < i_oldpts )
1441         {
1442             while( p_stream->i_idxposc > 0 &&
1443                !( p_stream->p_index[p_stream->i_idxposc].i_flags &
1444                                                             AVIIF_KEYFRAME ) )
1445             {
1446                 if( AVI_SetStreamChunk( p_input,
1447                                         i_stream,
1448                                         p_stream->i_idxposc - 1 ) )
1449                 {
1450                     return VLC_EGENERIC;
1451                 }
1452             }
1453         }
1454         else
1455         {
1456             while( p_stream->i_idxposc < p_stream->i_idxnb &&
1457                     !( p_stream->p_index[p_stream->i_idxposc].i_flags &
1458                                                             AVIIF_KEYFRAME ) )
1459             {
1460                 if( AVI_SetStreamChunk( p_input,
1461                                         i_stream,
1462                                         p_stream->i_idxposc + 1 ) )
1463                 {
1464                     return VLC_EGENERIC;
1465                 }
1466             }
1467         }
1468     }
1469     else
1470     {
1471         if( AVI_SetStreamBytes( p_input,
1472                                 i_stream,
1473                                 AVI_PTSToByte( p_stream, i_date ) ) )
1474         {
1475             return VLC_EGENERIC;
1476         }
1477     }
1478     return VLC_SUCCESS;
1479 #undef p_stream
1480 }
1481
1482 /*****************************************************************************
1483  * AVISeek: goto to i_date or i_percent
1484  *****************************************************************************
1485  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1486  *****************************************************************************/
1487 static int    AVISeek   ( input_thread_t *p_input,
1488                           mtime_t i_date, int i_percent )
1489 {
1490
1491     demux_sys_t *p_avi = p_input->p_demux_data;
1492     unsigned int i_stream;
1493     msg_Dbg( p_input,
1494              "seek requested: "I64Fd" secondes %d%%",
1495              i_date / 1000000,
1496              i_percent );
1497
1498     if( p_avi->b_seekable )
1499     {
1500         if( !p_avi->i_length )
1501         {
1502             avi_stream_t *p_stream;
1503             uint64_t i_pos;
1504
1505             /* use i_percent to create a true i_date */
1506             msg_Warn( p_input,
1507                       "mmh, seeking without index at %d%%"
1508                       " work only for interleaved file", i_percent );
1509
1510             if( i_percent >= 100 )
1511             {
1512                 msg_Err( p_input, "cannot seek so far !" );
1513                 return( -1 );
1514             }
1515             i_percent = __MAX( i_percent, 0 );
1516
1517             /* try to find chunk that is at i_percent or the file */
1518             i_pos = __MAX( i_percent *
1519                            p_input->stream.p_selected_area->i_size / 100,
1520                            p_avi->i_movi_begin );
1521             /* search first selected stream */
1522             for( i_stream = 0, p_stream = NULL;
1523                         i_stream < p_avi->i_streams; i_stream++ )
1524             {
1525                 p_stream = p_avi->pp_info[i_stream];
1526                 if( p_stream->b_activated )
1527                 {
1528                     break;
1529                 }
1530             }
1531             if( !p_stream || !p_stream->b_activated )
1532             {
1533                 msg_Err( p_input, "cannot find any selected stream" );
1534                 return( -1 );
1535             }
1536
1537             /* be sure that the index exit */
1538             if( AVI_SetStreamChunk( p_input,
1539                                     i_stream,
1540                                     0 ) )
1541             {
1542                 msg_Err( p_input, "cannot seek" );
1543                 return( -1 );
1544             }
1545
1546             while( i_pos >= p_stream->p_index[p_stream->i_idxposc].i_pos +
1547                p_stream->p_index[p_stream->i_idxposc].i_length + 8 )
1548             {
1549                 /* search after i_idxposc */
1550                 if( AVI_SetStreamChunk( p_input,
1551                                         i_stream, p_stream->i_idxposc + 1 ) )
1552                 {
1553                     msg_Err( p_input, "cannot seek" );
1554                     return( -1 );
1555                 }
1556             }
1557             i_date = AVI_GetPTS( p_stream );
1558             /* TODO better support for i_samplesize != 0 */
1559             msg_Dbg( p_input, "estimate date "I64Fd, i_date );
1560         }
1561
1562 #define p_stream    p_avi->pp_info[i_stream]
1563         p_avi->i_time = 0;
1564         /* seek for chunk based streams */
1565         for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
1566         {
1567             if( p_stream->b_activated && !p_stream->i_samplesize )
1568 //            if( p_stream->b_activated )
1569             {
1570                 AVI_StreamSeek( p_input, p_avi, i_stream, i_date );
1571                 p_avi->i_time = __MAX( AVI_GetPTS( p_stream ),
1572                                         p_avi->i_time );
1573             }
1574         }
1575 #if 1
1576         if( p_avi->i_time )
1577         {
1578             i_date = p_avi->i_time;
1579         }
1580         /* seek for bytes based streams */
1581         for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
1582         {
1583             if( p_stream->b_activated && p_stream->i_samplesize )
1584             {
1585                 AVI_StreamSeek( p_input, p_avi, i_stream, i_date );
1586 //                p_avi->i_time = __MAX( AVI_GetPTS( p_stream ), p_avi->i_time );
1587             }
1588         }
1589         msg_Dbg( p_input, "seek: "I64Fd" secondes", p_avi->i_time /1000000 );
1590         /* set true movie time */
1591 #endif
1592         if( !p_avi->i_time )
1593         {
1594             p_avi->i_time = i_date;
1595         }
1596 #undef p_stream
1597         return( 1 );
1598     }
1599     else
1600     {
1601         msg_Err( p_input, "shouldn't yet be executed" );
1602         return( -1 );
1603     }
1604 }
1605
1606 #if 0
1607 static pes_packet_t *PES_split( input_thread_t *p_input, avi_stream_t *p_stream, pes_packet_t *p_pes )
1608 {
1609     pes_packet_t  *p_pes2;
1610     data_packet_t *p_data;
1611     int           i_nb_data;
1612
1613     if( p_pes->i_nb_data < 2 )
1614     {
1615         return( NULL );
1616     }
1617     p_pes2 = input_NewPES( p_input->p_method_data );
1618     p_pes2->i_pts = p_pes->i_pts;
1619     p_pes2->i_dts = p_pes->i_dts;
1620     p_pes2->i_nb_data = p_pes->i_nb_data/2;
1621     p_pes2->i_pes_size = 0;
1622     for( i_nb_data = 0, p_data = p_pes->p_first;
1623          i_nb_data < p_pes2->i_nb_data;
1624          i_nb_data++, p_data = p_data->p_next )
1625     {
1626         p_pes2->i_pes_size +=
1627             p_data->p_payload_end - p_data->p_payload_start;
1628         p_pes2->p_last = p_data;
1629     }
1630     p_pes2->p_first = p_pes->p_first;
1631     p_pes2->p_last->p_next = NULL;
1632
1633     p_pes->p_first = p_data;
1634     p_pes->i_pes_size -= p_pes2->i_pes_size;
1635     p_pes->i_nb_data -= p_pes2->i_nb_data;
1636 //    p_pes->i_pts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
1637 //    p_pes->i_dts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
1638     p_pes->i_pts = 0;
1639     p_pes->i_dts = 0;
1640     return( p_pes2 );
1641 }
1642 #endif
1643
1644 /*****************************************************************************
1645  * AVIDemux_Seekable: reads and demuxes data packets for stream seekable
1646  *****************************************************************************
1647  * AVIDemux: reads and demuxes data packets
1648  *****************************************************************************
1649  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1650  *****************************************************************************/
1651 typedef struct avi_stream_toread_s
1652 {
1653     vlc_bool_t b_ok;
1654
1655     int i_toread;
1656
1657     off_t i_posf; // where we will read :
1658                   // if i_idxposb == 0 : begining of chunk (+8 to acces data)
1659                   // else : point on data directly
1660 } avi_stream_toread_t;
1661
1662 static int AVIDemux_Seekable( input_thread_t *p_input )
1663 {
1664     unsigned int i_stream;
1665     vlc_bool_t b_stream;
1666
1667     // cannot be more than 100 stream (dcXX or wbXX)
1668     avi_stream_toread_t toread[100];
1669
1670     demux_sys_t *p_avi = p_input->p_demux_data;
1671
1672     /* detect new selected/unselected streams */
1673     for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
1674     {
1675 #define p_stream    p_avi->pp_info[i_stream]
1676         if( p_stream->p_es )
1677         {
1678             if( p_stream->p_es->p_decoder_fifo &&
1679                 !p_stream->b_activated )
1680             {
1681                 AVI_StreamStart( p_input, p_avi, i_stream );
1682             }
1683             else
1684             if( !p_stream->p_es->p_decoder_fifo &&
1685                 p_stream->b_activated )
1686             {
1687                 AVI_StreamStop( p_input, p_avi, i_stream );
1688             }
1689         }
1690 #undef  p_stream
1691     }
1692
1693     if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
1694     {
1695         mtime_t i_date;
1696         int i_percent;
1697         /* first wait for empty buffer, arbitrary time FIXME */
1698 //        msleep( DEFAULT_PTS_DELAY );
1699
1700         i_date = (mtime_t)1000000 *
1701                  (mtime_t)p_avi->i_length *
1702                  (mtime_t)AVI_TellAbsolute( p_input ) /
1703                  (mtime_t)p_input->stream.p_selected_area->i_size;
1704         i_percent = 100 * AVI_TellAbsolute( p_input ) /
1705                         p_input->stream.p_selected_area->i_size;
1706
1707 //        input_ClockInit( p_input->stream.p_selected_program );
1708         AVISeek( p_input, i_date, i_percent);
1709
1710 #ifdef __AVI_SUBTITLE__
1711         if( p_avi->p_sub )
1712         {
1713             subtitle_Seek( p_avi->p_sub, p_avi->i_time );
1714         }
1715 #endif
1716     }
1717
1718
1719     /* wait for the good time */
1720
1721     p_avi->i_pcr = p_avi->i_time * 9 / 100;
1722
1723     input_ClockManageRef( p_input,
1724                           p_input->stream.p_selected_program,
1725                           p_avi->i_pcr );
1726
1727
1728     p_avi->i_time += 25*1000;  /* read 25ms */
1729
1730 #ifdef __AVI_SUBTITLE__
1731     if( p_avi->p_sub )
1732     {
1733         subtitle_Demux( p_avi->p_sub, p_avi->i_time );
1734     }
1735 #endif
1736     /* init toread */
1737     for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
1738     {
1739 #define p_stream    p_avi->pp_info[i_stream]
1740         mtime_t i_dpts;
1741
1742         toread[i_stream].b_ok = p_stream->b_activated;
1743
1744         if( p_stream->i_idxposc < p_stream->i_idxnb )
1745         {
1746             toread[i_stream].i_posf =
1747                 p_stream->p_index[p_stream->i_idxposc].i_pos;
1748            if( p_stream->i_idxposb > 0 )
1749            {
1750                 toread[i_stream].i_posf += 8 + p_stream->i_idxposb;
1751            }
1752         }
1753         else
1754         {
1755             toread[i_stream].i_posf = -1;
1756         }
1757
1758         i_dpts = p_avi->i_time - AVI_GetPTS( p_stream  );
1759
1760         if( p_stream->i_samplesize )
1761         {
1762             toread[i_stream].i_toread = AVI_PTSToByte( p_stream,
1763                                                        __ABS( i_dpts ) );
1764         }
1765         else
1766         {
1767             toread[i_stream].i_toread = AVI_PTSToChunk( p_stream,
1768                                                         __ABS( i_dpts ) );
1769         }
1770
1771         if( i_dpts < 0 )
1772         {
1773             toread[i_stream].i_toread *= -1;
1774         }
1775 #undef  p_stream
1776     }
1777
1778     b_stream = VLC_FALSE;
1779
1780     for( ;; )
1781     {
1782 #define p_stream    p_avi->pp_info[i_stream]
1783         vlc_bool_t       b_done;
1784         pes_packet_t    *p_pes;
1785         off_t i_pos;
1786         unsigned int i;
1787         size_t i_size;
1788
1789         /* search for first chunk to be read */
1790         for( i = 0, b_done = VLC_TRUE, i_pos = -1; i < p_avi->i_streams; i++ )
1791         {
1792             if( !toread[i].b_ok ||
1793                 AVI_GetDPTS( p_avi->pp_info[i],
1794                              toread[i].i_toread ) <= -25 * 1000 )
1795             {
1796                 continue;
1797             }
1798
1799             if( toread[i].i_toread > 0 )
1800             {
1801                 b_done = VLC_FALSE; // not yet finished
1802             }
1803
1804             if( toread[i].i_posf > 0 )
1805             {
1806                 if( i_pos == -1 || i_pos > toread[i_stream].i_posf )
1807                 {
1808                     i_stream = i;
1809                     i_pos = toread[i].i_posf;
1810                 }
1811             }
1812         }
1813
1814         if( b_done )
1815         {
1816 //            return( b_stream ? 1 : 0 );
1817             return( 1 );
1818         }
1819
1820         if( i_pos == -1 )
1821         {
1822             /* no valid index, we will parse directly the stream */
1823             if( p_avi->i_movi_lastchunk_pos >= p_avi->i_movi_begin )
1824             {
1825                 AVI_SeekAbsolute( p_input, p_avi->i_movi_lastchunk_pos );
1826                 if( AVI_PacketNext( p_input ) )
1827                 {
1828                     return( 0 );
1829                 }
1830             }
1831             else
1832             {
1833                 AVI_SeekAbsolute( p_input, p_avi->i_movi_begin );
1834             }
1835
1836             for( ;; )
1837             {
1838                 avi_packet_t avi_pk;
1839
1840                 if( AVI_PacketGetHeader( p_input, &avi_pk ) )
1841                 {
1842                     msg_Err( p_input, "cannot get packet header" );
1843                     return( 0 );
1844                 }
1845                 if( avi_pk.i_stream >= p_avi->i_streams ||
1846                     ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
1847                 {
1848                     switch( avi_pk.i_fourcc )
1849                     {
1850                         case AVIFOURCC_LIST:
1851                             AVI_SkipBytes( p_input, 12 );
1852                             break;
1853                         default:
1854                             if( AVI_PacketNext( p_input ) )
1855                             {
1856                                 msg_Err( p_input, "cannot skip packet" );
1857                                 return( 0 );
1858                             }
1859                             break;
1860                     }
1861                     continue;
1862                 }
1863                 else
1864                 {
1865                     /* add this chunk to the index */
1866                     AVIIndexEntry_t index;
1867
1868                     index.i_id = avi_pk.i_fourcc;
1869                     index.i_flags =
1870                        AVI_GetKeyFlag(p_avi->pp_info[avi_pk.i_stream]->i_codec,
1871                                       avi_pk.i_peek);
1872                     index.i_pos = avi_pk.i_pos;
1873                     index.i_length = avi_pk.i_size;
1874                     AVI_IndexAddEntry( p_avi, avi_pk.i_stream, &index );
1875
1876                     i_stream = avi_pk.i_stream;
1877                     /* do we will read this data ? */
1878                     if( AVI_GetDPTS( p_stream,
1879                              toread[i_stream].i_toread ) > -25 * 1000 )
1880                     {
1881                         break;
1882                     }
1883                     else
1884                     {
1885                         if( AVI_PacketNext( p_input ) )
1886                         {
1887                             msg_Err( p_input, "cannot skip packet" );
1888                             return( 0 );
1889                         }
1890                     }
1891                 }
1892             }
1893
1894         }
1895         else
1896         {
1897             AVI_SeekAbsolute( p_input, i_pos );
1898         }
1899
1900         /* read thoses data */
1901         if( p_stream->i_samplesize )
1902         {
1903             int i_toread;
1904
1905             if( ( i_toread = toread[i_stream].i_toread ) <= 0 )
1906             {
1907                 if( p_stream->i_samplesize > 1 )
1908                 {
1909                     i_toread = p_stream->i_samplesize;
1910                 }
1911                 else
1912                 {
1913                     i_toread = __MAX( AVI_PTSToByte( p_stream, 20 * 1000 ), 100 );
1914                 }
1915             }
1916             i_size = __MIN( p_stream->p_index[p_stream->i_idxposc].i_length -
1917                                 p_stream->i_idxposb,
1918                             i_toread );
1919         }
1920         else
1921         {
1922             i_size = p_stream->p_index[p_stream->i_idxposc].i_length;
1923         }
1924
1925         if( p_stream->i_idxposb == 0 )
1926         {
1927             i_size += 8; // need to read and skip header
1928         }
1929
1930         if( input_ReadInPES( p_input, &p_pes, __EVEN( i_size ) ) < 0 )
1931         {
1932             msg_Err( p_input, "failled reading data" );
1933             toread[i_stream].b_ok = VLC_FALSE;
1934             continue;
1935         }
1936
1937         if( i_size % 2 )    // read was padded on word boundary
1938         {
1939             p_pes->p_last->p_payload_end--;
1940             p_pes->i_pes_size--;
1941         }
1942         // skip header
1943         if( p_stream->i_idxposb == 0 )
1944         {
1945             p_pes->p_first->p_payload_start += 8;
1946             p_pes->i_pes_size -= 8;
1947         }
1948
1949         p_pes->i_pts = AVI_GetPTS( p_stream );
1950
1951         /* read data */
1952         if( p_stream->i_samplesize )
1953         {
1954             if( p_stream->i_idxposb == 0 )
1955             {
1956                 i_size -= 8;
1957             }
1958             toread[i_stream].i_toread -= i_size;
1959             p_stream->i_idxposb += i_size;
1960             if( p_stream->i_idxposb >=
1961                     p_stream->p_index[p_stream->i_idxposc].i_length )
1962             {
1963                 p_stream->i_idxposb = 0;
1964                 p_stream->i_idxposc++;
1965             }
1966         }
1967         else
1968         {
1969             toread[i_stream].i_toread--;
1970             p_stream->i_idxposc++;
1971         }
1972
1973         if( p_stream->i_idxposc < p_stream->i_idxnb)
1974         {
1975             toread[i_stream].i_posf =
1976                 p_stream->p_index[p_stream->i_idxposc].i_pos;
1977             if( p_stream->i_idxposb > 0 )
1978             {
1979                 toread[i_stream].i_posf += 8 + p_stream->i_idxposb;
1980             }
1981
1982         }
1983         else
1984         {
1985             toread[i_stream].i_posf = -1;
1986         }
1987
1988         b_stream = VLC_TRUE; // at least one read succeed
1989
1990         if( p_stream->p_es && p_stream->p_es->p_decoder_fifo )
1991         {
1992             p_pes->i_dts =
1993                 p_pes->i_pts =
1994                     input_ClockGetTS( p_input,
1995                                       p_input->stream.p_selected_program,
1996                                       p_pes->i_pts * 9/100);
1997 #if 0
1998             /* debuuging: split pes in 2 parts */
1999             if( p_pes->i_nb_data >= 2 && p_stream->i_cat == AUDIO_ES )
2000             {
2001                 pes_packet_t  *p_pes_;
2002                 data_packet_t *p_data;
2003                 int           i_nb_data;
2004
2005                 p_pes_ = PES_split( p_input, p_stream, p_pes );
2006                 if( p_pes_->i_nb_data >= 2 )
2007                 {
2008                     input_DecodePES( p_stream->p_es->p_decoder_fifo, PES_split( p_input,p_stream,p_pes_ ) );
2009                 }
2010                 input_DecodePES( p_stream->p_es->p_decoder_fifo,p_pes_ );
2011
2012                 if( p_pes->i_nb_data >= 2 )
2013                 {
2014                     input_DecodePES( p_stream->p_es->p_decoder_fifo, PES_split( p_input,p_stream,p_pes ) );
2015                 }
2016                 //input_DecodePES( p_stream->p_es->p_decoder_fifo,p_pes );
2017             }
2018 #endif
2019             input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes );
2020         }
2021         else
2022         {
2023             input_DeletePES( p_input->p_method_data, p_pes );
2024         }
2025     }
2026 }
2027
2028
2029 /*****************************************************************************
2030  * AVIDemux_UnSeekable: reads and demuxes data packets for unseekable file
2031  *****************************************************************************
2032  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
2033  *****************************************************************************/
2034 static int AVIDemux_UnSeekable( input_thread_t *p_input )
2035 {
2036     demux_sys_t     *p_avi = p_input->p_demux_data;
2037     avi_stream_t *p_stream_master;
2038     vlc_bool_t b_audio;
2039     unsigned int i_stream;
2040     unsigned int i_packet;
2041
2042     /* *** send audio data to decoder only if rate == DEFAULT_RATE *** */
2043     vlc_mutex_lock( &p_input->stream.stream_lock );
2044     b_audio = p_input->stream.control.i_rate == DEFAULT_RATE;
2045     vlc_mutex_unlock( &p_input->stream.stream_lock );
2046
2047     input_ClockManageRef( p_input,
2048                           p_input->stream.p_selected_program,
2049                           p_avi->i_pcr );
2050     /* *** find master stream for data packet skipping algo *** */
2051     /* *** -> first video, if any, or first audio ES *** */
2052     for( i_stream = 0, p_stream_master = NULL;
2053             i_stream < p_avi->i_streams; i_stream++ )
2054     {
2055 #define p_stream    p_avi->pp_info[i_stream]
2056         if( p_stream->p_es &&
2057             p_stream->p_es->p_decoder_fifo )
2058         {
2059             if( p_stream->i_cat == VIDEO_ES )
2060             {
2061                 p_stream_master = p_stream;
2062                 break;
2063             }
2064             if( p_stream->i_cat == AUDIO_ES && !p_stream_master )
2065             {
2066                 p_stream_master = p_stream;
2067             }
2068         }
2069 #undef p_stream
2070     }
2071     if( !p_stream_master )
2072     {
2073         msg_Err( p_input, "no more stream selected" );
2074         return( 0 );
2075     }
2076
2077     p_avi->i_pcr = AVI_GetPTS( p_stream_master ) * 9 / 100;
2078
2079     for( i_packet = 0; i_packet < 10; i_packet++)
2080     {
2081 #define p_stream    p_avi->pp_info[avi_pk.i_stream]
2082
2083         avi_packet_t    avi_pk;
2084
2085         if( AVI_PacketGetHeader( p_input, &avi_pk ) )
2086         {
2087             return( 0 );
2088         }
2089 //        AVI_ParseStreamHeader( avi_pk.i_fourcc, &i_stream, &i_cat );
2090
2091         if( avi_pk.i_stream >= p_avi->i_streams ||
2092             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
2093         {
2094             /* we haven't found an audio or video packet:
2095              *  - we have seek, found first next packet
2096              *  - others packets could be found, skip them
2097              */
2098             switch( avi_pk.i_fourcc )
2099             {
2100                 case AVIFOURCC_JUNK:
2101                 case AVIFOURCC_LIST:
2102                     return( !AVI_PacketNext( p_input ) ? 1 : 0 );
2103                 case AVIFOURCC_idx1:
2104                     return( 0 );    // eof
2105                 default:
2106                     msg_Warn( p_input,
2107                               "seems to have lost position, resync" );
2108                     if( AVI_PacketSearch( p_input ) )
2109                     {
2110                         msg_Err( p_input, "resync failed" );
2111                         return( -1 );
2112                     }
2113             }
2114         }
2115         else
2116         {
2117             /* do will send this packet to decoder ? */
2118             if( ( !b_audio && avi_pk.i_cat == AUDIO_ES )||
2119                 !p_stream->p_es ||
2120                 !p_stream->p_es->p_decoder_fifo )
2121             {
2122                 if( AVI_PacketNext( p_input ) )
2123                 {
2124                     return( 0 );
2125                 }
2126             }
2127             else
2128             {
2129                 /* it's a selected stream, check for time */
2130                 if( __ABS( AVI_GetPTS( p_stream ) -
2131                             AVI_GetPTS( p_stream_master ) )< 600*1000 )
2132                 {
2133                     /* load it and send to decoder */
2134                     pes_packet_t    *p_pes;
2135                     if( AVI_PacketRead( p_input, &avi_pk, &p_pes ) || !p_pes)
2136                     {
2137                         return( -1 );
2138                     }
2139                     p_pes->i_dts =
2140                         p_pes->i_pts =
2141                             input_ClockGetTS( p_input,
2142                                           p_input->stream.p_selected_program,
2143                                           AVI_GetPTS( p_stream ) * 9/100);
2144                     input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes );
2145                 }
2146                 else
2147                 {
2148                     if( AVI_PacketNext( p_input ) )
2149                     {
2150                         return( 0 );
2151                     }
2152                 }
2153             }
2154
2155             /* *** update stream time position *** */
2156             if( p_stream->i_samplesize )
2157             {
2158                 p_stream->i_idxposb += avi_pk.i_size;
2159             }
2160             else
2161             {
2162                 p_stream->i_idxposc++;
2163             }
2164
2165         }
2166
2167 #undef p_stream
2168     }
2169
2170     return( 1 );
2171 }
2172