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