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