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