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