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