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