]> git.sesse.net Git - vlc/blob - modules/demux/avi/avi.c
da5200a93edc5fd4f1edf4655965b740ce01331c
[vlc] / modules / demux / avi / avi.c
1 /*****************************************************************************
2  * avi.c : AVI file Stream input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: avi.c,v 1.46 2003/05/03 01:12:13 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 headr)" );
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,
1243                                 p_input->stream.p_selected_program, 1+i,
1244                                 0 );
1245         vlc_mutex_unlock( &p_input->stream.stream_lock );
1246         p_es->i_stream_id =i; /* XXX: i don't use it */
1247         p_es->i_fourcc = p_info->i_fourcc;
1248         p_es->i_cat = p_info->i_cat;
1249         if( p_es->i_cat == AUDIO_ES )
1250         {
1251             if( i_init_size < sizeof( WAVEFORMATEX ) )
1252             {
1253                 i_init_size = sizeof( WAVEFORMATEX );
1254             }
1255             p_es->p_waveformatex = malloc( i_init_size );
1256             memcpy( p_es->p_waveformatex, p_init_data, i_init_size );
1257         }
1258         else if( p_es->i_cat == VIDEO_ES )
1259         {
1260             p_es->p_bitmapinfoheader = malloc( i_init_size );
1261             memcpy( p_es->p_bitmapinfoheader, p_init_data, i_init_size );
1262         }
1263 #undef p_info
1264     }
1265
1266 #ifdef __AVI_SUBTITLE__
1267     if( ( p_avi->p_sub = subtitle_New( p_input, NULL, i_microsecperframe ) ) )
1268     {
1269         subtitle_Select( p_avi->p_sub );
1270     }
1271 #endif
1272
1273     if( config_GetInt( p_input, "avi-index" ) )
1274     {
1275         if( p_avi->b_seekable )
1276         {
1277             AVI_IndexCreate( p_input );
1278         }
1279         else
1280         {
1281             msg_Warn( p_input, "cannot create index (unseekable stream)" );
1282             AVI_IndexLoad( p_input );
1283         }
1284     }
1285     else
1286     {
1287         AVI_IndexLoad( p_input );
1288     }
1289
1290     /* *** movie length in sec *** */
1291     p_avi->i_length = AVI_MovieGetLength( p_input, p_avi );
1292     if( p_avi->i_length < (mtime_t)p_avih->i_totalframes *
1293                           (mtime_t)p_avih->i_microsecperframe /
1294                           (mtime_t)1000000 )
1295     {
1296         msg_Warn( p_input, "broken or missing index, 'seek' will be axproximative or will have strange behavour" );
1297     }
1298
1299     /* fix some BeOS MediaKit generated file */
1300     for( i = 0 ; i < p_avi->i_streams; i++ )
1301     {
1302         avi_chunk_list_t    *p_avi_strl;
1303         avi_chunk_strh_t    *p_avi_strh;
1304         avi_chunk_strf_auds_t    *p_avi_strf_auds;
1305 #define p_stream  p_avi->pp_info[i]
1306
1307         if( p_stream->i_cat != AUDIO_ES )
1308         {
1309             continue;
1310         }
1311         if( p_stream->i_idxnb < 1 ||
1312             p_stream->i_scale != 1 ||
1313             p_stream->i_samplesize != 0 )
1314         {
1315             continue;
1316         }
1317         p_avi_strl = (avi_chunk_list_t*)AVI_ChunkFind( p_hdrl,
1318                                                        AVIFOURCC_strl, i );
1319         p_avi_strh = (avi_chunk_strh_t*)AVI_ChunkFind( p_avi_strl,
1320                                                        AVIFOURCC_strh, 0 );
1321         p_avi_strf_auds =
1322             (avi_chunk_strf_auds_t*)AVI_ChunkFind( p_avi_strl,
1323                                                    AVIFOURCC_strf, 0 );
1324
1325         if( p_avi_strf_auds->p_wf->wFormatTag != WAVE_FORMAT_PCM &&
1326             (unsigned int)p_stream->i_rate == p_avi_strf_auds->p_wf->nSamplesPerSec )
1327         {
1328             int64_t i_track_length =
1329                 p_stream->p_index[p_stream->i_idxnb-1].i_length +
1330                 p_stream->p_index[p_stream->i_idxnb-1].i_lengthtotal;
1331             mtime_t i_length = (mtime_t)p_avih->i_totalframes *
1332                                (mtime_t)p_avih->i_microsecperframe;
1333
1334             if( i_length == 0 )
1335             {
1336                 msg_Warn( p_input, "track[%d] cannot be fixed (BeOS MediaKit generated)", i );
1337                 continue;
1338             }
1339             p_stream->i_samplesize = 1;
1340             p_stream->i_rate       = i_track_length  * (int64_t)1000000/ i_length;
1341             msg_Warn( p_input, "track[%d] fixed with rate=%d scale=%d (BeOS MediaKit generated)", i, p_stream->i_rate, p_stream->i_scale );
1342         }
1343 #undef p_stream
1344     }
1345
1346     vlc_mutex_lock( &p_input->stream.stream_lock );
1347     if( p_avi->i_length )
1348     {
1349         p_input->stream.i_mux_rate =
1350             p_input->stream.p_selected_area->i_size / 50 / p_avi->i_length;
1351     }
1352     else
1353     {
1354         p_input->stream.i_mux_rate = 0;
1355     }
1356     vlc_mutex_unlock( &p_input->stream.stream_lock );
1357
1358     b_stream_audio = VLC_FALSE;
1359     b_stream_video = VLC_FALSE;
1360
1361     for( i = 0; i < p_avi->i_streams; i++ )
1362     {
1363 #define p_info  p_avi->pp_info[i]
1364         switch( p_info->p_es->i_cat )
1365         {
1366             case( VIDEO_ES ):
1367
1368                 if( !b_stream_video )
1369                 {
1370                     b_stream_video = AVI_StreamStart( p_input, p_avi, i );
1371                 }
1372                 break;
1373
1374             case( AUDIO_ES ):
1375                 if( !b_stream_audio )
1376                 {
1377                     b_stream_audio = AVI_StreamStart( p_input, p_avi, i );
1378                 }
1379                 break;
1380             default:
1381                 break;
1382         }
1383 #undef p_info
1384     }
1385
1386     if( !b_stream_video )
1387     {
1388         msg_Warn( p_input, "no video stream found" );
1389     }
1390     if( !b_stream_audio )
1391     {
1392         msg_Warn( p_input, "no audio stream found!" );
1393     }
1394
1395     vlc_mutex_lock( &p_input->stream.stream_lock );
1396     p_input->stream.p_selected_program->b_is_ok = 1;
1397     vlc_mutex_unlock( &p_input->stream.stream_lock );
1398
1399     if( p_avi->b_seekable )
1400     {
1401         AVI_ChunkGoto( p_input, p_movi );
1402     }
1403     else
1404     {
1405         // already at begining of p_movi
1406     }
1407     AVI_SkipBytes( p_input, 12 ); // enter in p_movi
1408
1409     p_avi->i_movi_begin = p_movi->i_chunk_pos;
1410     return VLC_SUCCESS;
1411 }
1412
1413
1414
1415
1416 /*****************************************************************************
1417  * Function to convert pts to chunk or byte
1418  *****************************************************************************/
1419
1420 static inline mtime_t AVI_PTSToChunk( avi_stream_t *p_info,
1421                                         mtime_t i_pts )
1422 {
1423     return (mtime_t)((int64_t)i_pts *
1424                      (int64_t)p_info->i_rate /
1425                      (int64_t)p_info->i_scale /
1426                      (int64_t)1000000 );
1427 }
1428 static inline mtime_t AVI_PTSToByte( avi_stream_t *p_info,
1429                                        mtime_t i_pts )
1430 {
1431     return (mtime_t)((int64_t)i_pts *
1432                      (int64_t)p_info->i_rate /
1433                      (int64_t)p_info->i_scale /
1434                      (int64_t)1000000 *
1435                      (int64_t)p_info->i_samplesize );
1436 }
1437
1438 static mtime_t AVI_GetDPTS( avi_stream_t *p_stream, int i_count )
1439 {
1440     if( p_stream->i_samplesize )
1441     {
1442         return (mtime_t)( (int64_t)1000000 *
1443                    (int64_t)i_count *
1444                    (int64_t)p_stream->i_scale /
1445                    (int64_t)p_stream->i_rate /
1446                    (int64_t)p_stream->i_samplesize );
1447     }
1448     else
1449     {
1450         return (mtime_t)( (int64_t)1000000 *
1451                    (int64_t)i_count *
1452                    (int64_t)p_stream->i_scale /
1453                    (int64_t)p_stream->i_rate);
1454     }
1455
1456 }
1457
1458 static mtime_t AVI_GetPTS( avi_stream_t *p_info )
1459 {
1460
1461     if( p_info->i_samplesize )
1462     {
1463         /* we need a valid entry we will emulate one */
1464         int64_t i_len;
1465         if( p_info->i_idxposc == p_info->i_idxnb )
1466         {
1467             if( p_info->i_idxposc )
1468             {
1469                 /* use the last entry */
1470                 i_len = p_info->p_index[p_info->i_idxnb - 1].i_lengthtotal
1471                             + p_info->p_index[p_info->i_idxnb - 1].i_length
1472                             + p_info->i_idxposb; /* should be 0 */
1473             }
1474             else
1475             {
1476                 i_len = p_info->i_idxposb;
1477                 /* no valid entry use only offset*/
1478             }
1479         }
1480         else
1481         {
1482             i_len = p_info->p_index[p_info->i_idxposc].i_lengthtotal
1483                                 + p_info->i_idxposb;
1484         }
1485         return (mtime_t)( (int64_t)1000000 *
1486                   (int64_t)i_len *
1487                    (int64_t)p_info->i_scale /
1488                    (int64_t)p_info->i_rate /
1489                    (int64_t)p_info->i_samplesize );
1490     }
1491     else
1492     {
1493         /* even if p_info->i_idxposc isn't valid, there isn't any problem */
1494         return (mtime_t)( (int64_t)1000000 *
1495                    (int64_t)(p_info->i_idxposc ) *
1496                    (int64_t)p_info->i_scale /
1497                    (int64_t)p_info->i_rate);
1498     }
1499 }
1500
1501 #if 0
1502 static void AVI_FixPTS( avi_stream_t *p_stream, pes_packet_t *p_pes )
1503 {
1504     data_packet_t *p_data;
1505     uint8_t       *p;
1506     int           i_pos = 0;
1507
1508     switch( p_stream->i_fourcc )
1509     {
1510         case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
1511             p_data = p_pes->p_first;
1512             while( p_data )
1513             {
1514                 p = p_data->p_payload_start;
1515                 while( p < p_data->p_payload_end - 2 )
1516                 {
1517                     if( p[0] == 0xff && ( p[1]&0xe0) == 0xe0 )
1518                     {
1519                         mtime_t i_diff = AVI_GetDPTS( p_stream, i_pos );
1520                         p_pes->i_dts += i_diff;
1521                         p_pes->i_pts += i_diff;
1522                         return;
1523                     }
1524                     p++; i_pos++;
1525                 }
1526                 p_data = p_data->p_next;
1527             }
1528             return;
1529         case VLC_FOURCC( 'a', '5', '2', ' ' ):
1530             p_data = p_pes->p_first;
1531             while( p_data )
1532             {
1533                 p = p_data->p_payload_start;
1534                 while( p < p_data->p_payload_end - 2 )
1535                 {
1536                     if( p[0] == 0x0b && p[1] == 0x77 )
1537                     {
1538                         mtime_t i_diff = AVI_GetDPTS( p_stream, i_pos );
1539                         p_pes->i_dts += i_diff;
1540                         p_pes->i_pts += i_diff;
1541                     }
1542                     p++; i_pos++;
1543                 }
1544                 p_data = p_data->p_next;
1545             }
1546             return;
1547         default:
1548             /* we can't fix :( */
1549             return;
1550     }
1551 }
1552 #endif
1553
1554 static int AVI_StreamChunkFind( input_thread_t *p_input,
1555                                 unsigned int i_stream )
1556 {
1557     demux_sys_t *p_avi = p_input->p_demux_data;
1558     avi_packet_t avi_pk;
1559
1560     /* find first chunk of i_stream that isn't in index */
1561
1562     if( p_avi->i_movi_lastchunk_pos >= p_avi->i_movi_begin + 12 )
1563     {
1564         AVI_SeekAbsolute( p_input, p_avi->i_movi_lastchunk_pos );
1565         if( AVI_PacketNext( p_input ) )
1566         {
1567             return VLC_EGENERIC;
1568         }
1569     }
1570     else
1571     {
1572         AVI_SeekAbsolute( p_input, p_avi->i_movi_begin + 12 );
1573     }
1574
1575     for( ;; )
1576     {
1577
1578         if( AVI_PacketGetHeader( p_input, &avi_pk ) )
1579         {
1580             msg_Warn( p_input, "cannot get packet header" );
1581             return VLC_EGENERIC;
1582         }
1583         if( avi_pk.i_stream >= p_avi->i_streams ||
1584             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
1585         {
1586             if( AVI_PacketNext( p_input ) )
1587             {
1588                 return VLC_EGENERIC;
1589             }
1590         }
1591         else
1592         {
1593             /* add this chunk to the index */
1594             AVIIndexEntry_t index;
1595
1596             index.i_id = avi_pk.i_fourcc;
1597             index.i_flags =
1598                AVI_GetKeyFlag(p_avi->pp_info[avi_pk.i_stream]->i_codec,
1599                               avi_pk.i_peek);
1600             index.i_pos = avi_pk.i_pos;
1601             index.i_length = avi_pk.i_size;
1602             AVI_IndexAddEntry( p_avi, avi_pk.i_stream, &index );
1603
1604             if( avi_pk.i_stream == i_stream  )
1605             {
1606                 return VLC_SUCCESS;
1607             }
1608
1609             if( AVI_PacketNext( p_input ) )
1610             {
1611                 return VLC_EGENERIC;
1612             }
1613         }
1614     }
1615 }
1616
1617
1618 /* be sure that i_ck will be a valid index entry */
1619 static int AVI_SetStreamChunk( input_thread_t    *p_input,
1620                                unsigned int i_stream,
1621                                unsigned int i_ck )
1622 {
1623     demux_sys_t *p_avi = p_input->p_demux_data;
1624     avi_stream_t *p_stream = p_avi->pp_info[i_stream];
1625
1626     p_stream->i_idxposc = i_ck;
1627     p_stream->i_idxposb = 0;
1628
1629     if(  i_ck >= p_stream->i_idxnb )
1630     {
1631         p_stream->i_idxposc = p_stream->i_idxnb - 1;
1632         do
1633         {
1634             p_stream->i_idxposc++;
1635             if( AVI_StreamChunkFind( p_input, i_stream ) )
1636             {
1637                 return VLC_EGENERIC;
1638             }
1639
1640         } while( p_stream->i_idxposc < i_ck );
1641     }
1642
1643     return VLC_SUCCESS;
1644 }
1645
1646
1647 /* XXX FIXME up to now, we assume that all chunk are one after one */
1648 static int AVI_SetStreamBytes( input_thread_t    *p_input,
1649                                unsigned int i_stream,
1650                                off_t   i_byte )
1651 {
1652     demux_sys_t *p_avi = p_input->p_demux_data;
1653     avi_stream_t *p_stream = p_avi->pp_info[i_stream];
1654
1655     if( ( p_stream->i_idxnb > 0 )
1656         &&( i_byte < p_stream->p_index[p_stream->i_idxnb - 1].i_lengthtotal +
1657                 p_stream->p_index[p_stream->i_idxnb - 1].i_length ) )
1658     {
1659         /* index is valid to find the ck */
1660         /* uses dichototmie to be fast enougth */
1661         int i_idxposc = __MIN( p_stream->i_idxposc, p_stream->i_idxnb - 1 );
1662         int i_idxmax  = p_stream->i_idxnb;
1663         int i_idxmin  = 0;
1664         for( ;; )
1665         {
1666             if( p_stream->p_index[i_idxposc].i_lengthtotal > i_byte )
1667             {
1668                 i_idxmax  = i_idxposc ;
1669                 i_idxposc = ( i_idxmin + i_idxposc ) / 2 ;
1670             }
1671             else
1672             {
1673                 if( p_stream->p_index[i_idxposc].i_lengthtotal +
1674                         p_stream->p_index[i_idxposc].i_length <= i_byte)
1675                 {
1676                     i_idxmin  = i_idxposc ;
1677                     i_idxposc = (i_idxmax + i_idxposc ) / 2 ;
1678                 }
1679                 else
1680                 {
1681                     p_stream->i_idxposc = i_idxposc;
1682                     p_stream->i_idxposb = i_byte -
1683                             p_stream->p_index[i_idxposc].i_lengthtotal;
1684                     return VLC_SUCCESS;
1685                 }
1686             }
1687         }
1688
1689     }
1690     else
1691     {
1692         p_stream->i_idxposc = p_stream->i_idxnb - 1;
1693         p_stream->i_idxposb = 0;
1694         do
1695         {
1696             p_stream->i_idxposc++;
1697             if( AVI_StreamChunkFind( p_input, i_stream ) )
1698             {
1699                 return VLC_EGENERIC;
1700             }
1701
1702         } while( p_stream->p_index[p_stream->i_idxposc].i_lengthtotal +
1703                     p_stream->p_index[p_stream->i_idxposc].i_length <= i_byte );
1704
1705         p_stream->i_idxposb = i_byte -
1706                        p_stream->p_index[p_stream->i_idxposc].i_lengthtotal;
1707         return VLC_SUCCESS;
1708     }
1709 }
1710
1711 static int AVI_StreamSeek( input_thread_t *p_input,
1712                            demux_sys_t  *p_avi,
1713                            int i_stream,
1714                            mtime_t i_date )
1715 {
1716 #define p_stream    p_avi->pp_info[i_stream]
1717     mtime_t i_oldpts;
1718
1719     i_oldpts = AVI_GetPTS( p_stream );
1720
1721     if( !p_stream->i_samplesize )
1722     {
1723         if( AVI_SetStreamChunk( p_input,
1724                                 i_stream,
1725                                 AVI_PTSToChunk( p_stream, i_date ) ) )
1726         {
1727             return VLC_EGENERIC;
1728         }
1729
1730         /* search key frame */
1731         msg_Dbg( p_input,
1732                  "old:"I64Fd" %s new "I64Fd,
1733                  i_oldpts,
1734                  i_oldpts > i_date ? ">" : "<",
1735                  i_date );
1736
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     else
1767     {
1768         if( AVI_SetStreamBytes( p_input,
1769                                 i_stream,
1770                                 AVI_PTSToByte( p_stream, i_date ) ) )
1771         {
1772             return VLC_EGENERIC;
1773         }
1774     }
1775     return VLC_SUCCESS;
1776 #undef p_stream
1777 }
1778
1779 /*****************************************************************************
1780  * AVISeek: goto to i_date or i_percent
1781  *****************************************************************************
1782  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1783  *****************************************************************************/
1784 static int    AVISeek   ( input_thread_t *p_input,
1785                           mtime_t i_date, int i_percent )
1786 {
1787
1788     demux_sys_t *p_avi = p_input->p_demux_data;
1789     unsigned int i_stream;
1790     msg_Dbg( p_input,
1791              "seek requested: "I64Fd" secondes %d%%",
1792              i_date / 1000000,
1793              i_percent );
1794
1795     if( p_avi->b_seekable )
1796     {
1797         if( !p_avi->i_length )
1798         {
1799             avi_stream_t *p_stream;
1800             int64_t i_pos;
1801
1802             /* use i_percent to create a true i_date */
1803             msg_Warn( p_input,
1804                       "mmh, seeking without index at %d%%"
1805                       " work only for interleaved file", i_percent );
1806
1807             if( i_percent >= 100 )
1808             {
1809                 msg_Warn( p_input, "cannot seek so far !" );
1810                 return( -1 );
1811             }
1812             i_percent = __MAX( i_percent, 0 );
1813
1814             /* try to find chunk that is at i_percent or the file */
1815             i_pos = __MAX( i_percent *
1816                            p_input->stream.p_selected_area->i_size / 100,
1817                            p_avi->i_movi_begin );
1818             /* search first selected stream */
1819             for( i_stream = 0, p_stream = NULL;
1820                         i_stream < p_avi->i_streams; i_stream++ )
1821             {
1822                 p_stream = p_avi->pp_info[i_stream];
1823                 if( p_stream->b_activated )
1824                 {
1825                     break;
1826                 }
1827             }
1828             if( !p_stream || !p_stream->b_activated )
1829             {
1830                 msg_Warn( p_input, "cannot find any selected stream" );
1831                 return( -1 );
1832             }
1833
1834             /* be sure that the index exit */
1835             if( AVI_SetStreamChunk( p_input,
1836                                     i_stream,
1837                                     0 ) )
1838             {
1839                 msg_Warn( p_input, "cannot seek" );
1840                 return( -1 );
1841             }
1842
1843             while( i_pos >= p_stream->p_index[p_stream->i_idxposc].i_pos +
1844                p_stream->p_index[p_stream->i_idxposc].i_length + 8 )
1845             {
1846                 /* search after i_idxposc */
1847                 if( AVI_SetStreamChunk( p_input,
1848                                         i_stream, p_stream->i_idxposc + 1 ) )
1849                 {
1850                     msg_Warn( p_input, "cannot seek" );
1851                     return( -1 );
1852                 }
1853             }
1854             i_date = AVI_GetPTS( p_stream );
1855             /* TODO better support for i_samplesize != 0 */
1856             msg_Dbg( p_input, "estimate date "I64Fd, i_date );
1857         }
1858
1859 #define p_stream    p_avi->pp_info[i_stream]
1860         p_avi->i_time = 0;
1861         /* seek for chunk based streams */
1862         for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
1863         {
1864             if( p_stream->b_activated && !p_stream->i_samplesize )
1865 //            if( p_stream->b_activated )
1866             {
1867                 AVI_StreamSeek( p_input, p_avi, i_stream, i_date );
1868                 p_avi->i_time = __MAX( AVI_GetPTS( p_stream ),
1869                                         p_avi->i_time );
1870             }
1871         }
1872 #if 1
1873         if( p_avi->i_time )
1874         {
1875             i_date = p_avi->i_time;
1876         }
1877         /* seek for bytes based streams */
1878         for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
1879         {
1880             if( p_stream->b_activated && p_stream->i_samplesize )
1881             {
1882                 AVI_StreamSeek( p_input, p_avi, i_stream, i_date );
1883 //                p_avi->i_time = __MAX( AVI_GetPTS( p_stream ), p_avi->i_time );
1884             }
1885         }
1886         msg_Dbg( p_input, "seek: "I64Fd" secondes", p_avi->i_time /1000000 );
1887         /* set true movie time */
1888 #endif
1889         if( !p_avi->i_time )
1890         {
1891             p_avi->i_time = i_date;
1892         }
1893 #undef p_stream
1894         return( 1 );
1895     }
1896     else
1897     {
1898         msg_Err( p_input, "shouldn't yet be executed" );
1899         return( -1 );
1900     }
1901 }
1902
1903 #if 0
1904 static pes_packet_t *PES_split( input_thread_t *p_input, avi_stream_t *p_stream, pes_packet_t *p_pes )
1905 {
1906     pes_packet_t  *p_pes2;
1907     data_packet_t *p_data;
1908     int           i_nb_data;
1909
1910     if( p_pes->i_nb_data < 2 )
1911     {
1912         return( NULL );
1913     }
1914     p_pes2 = input_NewPES( p_input->p_method_data );
1915     p_pes2->i_pts = p_pes->i_pts;
1916     p_pes2->i_dts = p_pes->i_dts;
1917     p_pes2->i_nb_data = p_pes->i_nb_data/2;
1918     p_pes2->i_pes_size = 0;
1919     for( i_nb_data = 0, p_data = p_pes->p_first;
1920          i_nb_data < p_pes2->i_nb_data;
1921          i_nb_data++, p_data = p_data->p_next )
1922     {
1923         p_pes2->i_pes_size +=
1924             p_data->p_payload_end - p_data->p_payload_start;
1925         p_pes2->p_last = p_data;
1926     }
1927     p_pes2->p_first = p_pes->p_first;
1928     p_pes2->p_last->p_next = NULL;
1929
1930     p_pes->p_first = p_data;
1931     p_pes->i_pes_size -= p_pes2->i_pes_size;
1932     p_pes->i_nb_data -= p_pes2->i_nb_data;
1933 //    p_pes->i_pts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
1934 //    p_pes->i_dts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
1935     p_pes->i_pts = 0;
1936     p_pes->i_dts = 0;
1937     return( p_pes2 );
1938 }
1939 #endif
1940
1941 /*****************************************************************************
1942  * AVIDemux_Seekable: reads and demuxes data packets for stream seekable
1943  *****************************************************************************
1944  * AVIDemux: reads and demuxes data packets
1945  *****************************************************************************
1946  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1947  *****************************************************************************/
1948 typedef struct avi_stream_toread_s
1949 {
1950     vlc_bool_t b_ok;
1951
1952     int i_toread;
1953
1954     off_t i_posf; // where we will read :
1955                   // if i_idxposb == 0 : begining of chunk (+8 to acces data)
1956                   // else : point on data directly
1957 } avi_stream_toread_t;
1958
1959 static int AVIDemux_Seekable( input_thread_t *p_input )
1960 {
1961     unsigned int i_stream_count;
1962     unsigned int i_stream;
1963     vlc_bool_t b_stream;
1964     vlc_bool_t b_play_audio;
1965     vlc_bool_t b_video; /* is there some video track selected */
1966     // cannot be more than 100 stream (dcXX or wbXX)
1967     avi_stream_toread_t toread[100];
1968
1969     demux_sys_t *p_avi = p_input->p_demux_data;
1970
1971
1972     /* detect new selected/unselected streams */
1973     for( i_stream = 0,i_stream_count= 0, b_video = VLC_FALSE;
1974             i_stream < p_avi->i_streams; i_stream++ )
1975     {
1976 #define p_stream    p_avi->pp_info[i_stream]
1977         if( p_stream->p_es )
1978         {
1979             if( p_stream->p_es->p_decoder_fifo &&
1980                 !p_stream->b_activated )
1981             {
1982                 AVI_StreamStart( p_input, p_avi, i_stream );
1983             }
1984             else
1985             if( !p_stream->p_es->p_decoder_fifo &&
1986                 p_stream->b_activated )
1987             {
1988                 AVI_StreamStop( p_input, p_avi, i_stream );
1989             }
1990         }
1991         if( p_stream->b_activated )
1992         {
1993             i_stream_count++;
1994             if( p_stream->i_cat == VIDEO_ES )
1995             {
1996                 b_video = VLC_TRUE;
1997             }
1998         }
1999 #undef  p_stream
2000     }
2001
2002     if( i_stream_count <= 0 )
2003     {
2004         msg_Warn( p_input, "no track selected, exiting..." );
2005         return( 0 );
2006     }
2007
2008     if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
2009     {
2010         mtime_t i_date;
2011         int i_percent;
2012         /* first wait for empty buffer, arbitrary time FIXME */
2013         //msleep( DEFAULT_PTS_DELAY );
2014
2015         i_date = (mtime_t)1000000 *
2016                  (mtime_t)p_avi->i_length *
2017                  (mtime_t)AVI_TellAbsolute( p_input ) /
2018                  (mtime_t)p_input->stream.p_selected_area->i_size;
2019         i_percent = 100 * AVI_TellAbsolute( p_input ) /
2020                         p_input->stream.p_selected_area->i_size;
2021
2022 //        input_ClockInit( p_input->stream.p_selected_program );
2023         AVISeek( p_input, i_date, i_percent);
2024
2025 #ifdef __AVI_SUBTITLE__
2026         if( p_avi->p_sub )
2027         {
2028             subtitle_Seek( p_avi->p_sub, p_avi->i_time );
2029         }
2030 #endif
2031     }
2032
2033
2034     /* wait for the good time */
2035
2036     p_avi->i_pcr = p_avi->i_time * 9 / 100;
2037
2038     input_ClockManageRef( p_input,
2039                           p_input->stream.p_selected_program,
2040                           p_avi->i_pcr );
2041
2042
2043     p_avi->i_time += 25*1000;  /* read 25ms */
2044
2045 #ifdef __AVI_SUBTITLE__
2046     if( p_avi->p_sub )
2047     {
2048         subtitle_Demux( p_avi->p_sub, p_avi->i_time );
2049     }
2050 #endif
2051
2052     /* *** send audio data to decoder if rate == DEFAULT_RATE or no video *** */
2053     vlc_mutex_lock( &p_input->stream.stream_lock );
2054     if( p_input->stream.control.i_rate == DEFAULT_RATE || !b_video )
2055     {
2056         b_play_audio = VLC_TRUE;
2057     }
2058     else
2059     {
2060         b_play_audio = VLC_FALSE;
2061     }
2062     vlc_mutex_unlock( &p_input->stream.stream_lock );
2063
2064     /* init toread */
2065     for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
2066     {
2067 #define p_stream    p_avi->pp_info[i_stream]
2068         mtime_t i_dpts;
2069
2070         toread[i_stream].b_ok = p_stream->b_activated;
2071         if( p_stream->i_idxposc < p_stream->i_idxnb )
2072         {
2073             toread[i_stream].i_posf =
2074                 p_stream->p_index[p_stream->i_idxposc].i_pos;
2075            if( p_stream->i_idxposb > 0 )
2076            {
2077                 toread[i_stream].i_posf += 8 + p_stream->i_idxposb;
2078            }
2079         }
2080         else
2081         {
2082             toread[i_stream].i_posf = -1;
2083         }
2084
2085         i_dpts = p_avi->i_time - AVI_GetPTS( p_stream  );
2086
2087         if( p_stream->i_samplesize )
2088         {
2089             toread[i_stream].i_toread = AVI_PTSToByte( p_stream,
2090                                                        __ABS( i_dpts ) );
2091         }
2092         else
2093         {
2094             toread[i_stream].i_toread = AVI_PTSToChunk( p_stream,
2095                                                         __ABS( i_dpts ) );
2096         }
2097
2098         if( i_dpts < 0 )
2099         {
2100             toread[i_stream].i_toread *= -1;
2101         }
2102 #undef  p_stream
2103     }
2104
2105     b_stream = VLC_FALSE;
2106
2107     for( ;; )
2108     {
2109 #define p_stream    p_avi->pp_info[i_stream]
2110         vlc_bool_t       b_done;
2111         pes_packet_t    *p_pes;
2112         off_t i_pos;
2113         unsigned int i;
2114         size_t i_size;
2115
2116         /* search for first chunk to be read */
2117         for( i = 0, b_done = VLC_TRUE, i_pos = -1; i < p_avi->i_streams; i++ )
2118         {
2119             if( !toread[i].b_ok ||
2120                 AVI_GetDPTS( p_avi->pp_info[i],
2121                              toread[i].i_toread ) <= -25 * 1000 )
2122             {
2123                 continue;
2124             }
2125
2126             if( toread[i].i_toread > 0 )
2127             {
2128                 b_done = VLC_FALSE; // not yet finished
2129             }
2130
2131             if( toread[i].i_posf > 0 )
2132             {
2133                 if( i_pos == -1 || i_pos > toread[i_stream].i_posf )
2134                 {
2135                     i_stream = i;
2136                     i_pos = toread[i].i_posf;
2137                 }
2138             }
2139         }
2140
2141         if( b_done )
2142         {
2143 //            return( b_stream ? 1 : 0 );
2144             return( 1 );
2145         }
2146
2147         if( i_pos == -1 )
2148         {
2149             /* no valid index, we will parse directly the stream
2150              * in case we fail we will disable all finished stream */
2151             if( p_avi->i_movi_lastchunk_pos >= p_avi->i_movi_begin + 12 )
2152             {
2153                 AVI_SeekAbsolute( p_input, p_avi->i_movi_lastchunk_pos );
2154                 if( AVI_PacketNext( p_input ) )
2155                 {
2156                     return( AVI_StreamStopFinishedStreams( p_input, p_avi ) ? 0 : 1 );
2157                 }
2158             }
2159             else
2160             {
2161                 AVI_SeekAbsolute( p_input, p_avi->i_movi_begin + 12 );
2162             }
2163
2164             for( ;; )
2165             {
2166                 avi_packet_t avi_pk;
2167
2168                 if( AVI_PacketGetHeader( p_input, &avi_pk ) )
2169                 {
2170                     msg_Warn( p_input,
2171                              "cannot get packet header, track disabled" );
2172                     return( AVI_StreamStopFinishedStreams( p_input, p_avi ) ? 0 : 1 );
2173                 }
2174                 if( avi_pk.i_stream >= p_avi->i_streams ||
2175                     ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
2176                 {
2177                     if( AVI_PacketNext( p_input ) )
2178                     {
2179                         msg_Warn( p_input,
2180                                   "cannot skip packet, track disabled" );
2181                         return( AVI_StreamStopFinishedStreams( p_input, p_avi ) ? 0 : 1 );
2182                     }
2183                     continue;
2184                 }
2185                 else
2186                 {
2187                     /* add this chunk to the index */
2188                     AVIIndexEntry_t index;
2189
2190                     index.i_id = avi_pk.i_fourcc;
2191                     index.i_flags =
2192                        AVI_GetKeyFlag(p_avi->pp_info[avi_pk.i_stream]->i_codec,
2193                                       avi_pk.i_peek);
2194                     index.i_pos = avi_pk.i_pos;
2195                     index.i_length = avi_pk.i_size;
2196                     AVI_IndexAddEntry( p_avi, avi_pk.i_stream, &index );
2197
2198                     i_stream = avi_pk.i_stream;
2199                     /* do we will read this data ? */
2200                     if( AVI_GetDPTS( p_stream,
2201                              toread[i_stream].i_toread ) > -25 * 1000 )
2202                     {
2203                         break;
2204                     }
2205                     else
2206                     {
2207                         if( AVI_PacketNext( p_input ) )
2208                         {
2209                             msg_Warn( p_input,
2210                                       "cannot skip packet, track disabled" );
2211                             return( AVI_StreamStopFinishedStreams( p_input, p_avi ) ? 0 : 1 );
2212                         }
2213                     }
2214                 }
2215             }
2216
2217         }
2218         else
2219         {
2220             AVI_SeekAbsolute( p_input, i_pos );
2221         }
2222
2223         /* read thoses data */
2224         if( p_stream->i_samplesize )
2225         {
2226             unsigned int i_toread;
2227
2228             if( ( i_toread = toread[i_stream].i_toread ) <= 0 )
2229             {
2230                 if( p_stream->i_samplesize > 1 )
2231                 {
2232                     i_toread = p_stream->i_samplesize;
2233                 }
2234                 else
2235                 {
2236                     i_toread = __MAX( AVI_PTSToByte( p_stream, 20 * 1000 ), 100 );
2237                 }
2238             }
2239             i_size = __MIN( p_stream->p_index[p_stream->i_idxposc].i_length -
2240                                 p_stream->i_idxposb,
2241                             i_toread );
2242         }
2243         else
2244         {
2245             i_size = p_stream->p_index[p_stream->i_idxposc].i_length;
2246         }
2247
2248         if( p_stream->i_idxposb == 0 )
2249         {
2250             i_size += 8; // need to read and skip header
2251         }
2252
2253         if( input_ReadInPES( p_input, &p_pes, __EVEN( i_size ) ) < 0 )
2254         {
2255             msg_Warn( p_input, "failled reading data" );
2256             AVI_StreamStop( p_input, p_avi, i_stream );
2257             toread[i_stream].b_ok = VLC_FALSE;
2258             continue;
2259         }
2260
2261         if( i_size % 2 )    // read was padded on word boundary
2262         {
2263             p_pes->p_last->p_payload_end--;
2264             p_pes->i_pes_size--;
2265         }
2266         // skip header
2267         if( p_stream->i_idxposb == 0 )
2268         {
2269             p_pes->p_first->p_payload_start += 8;
2270             p_pes->i_pes_size -= 8;
2271         }
2272
2273         p_pes->i_pts = AVI_GetPTS( p_stream );
2274
2275 #if 0
2276         /* fix pts for audio: ie pts sould be for the first byte of the first frame */
2277         if( p_stream->i_samplesize == 1 )
2278         {
2279             AVI_FixPTS( p_stream, p_pes );
2280         }
2281 #endif
2282
2283         /* read data */
2284         if( p_stream->i_samplesize )
2285         {
2286             if( p_stream->i_idxposb == 0 )
2287             {
2288                 i_size -= 8;
2289             }
2290             toread[i_stream].i_toread -= i_size;
2291             p_stream->i_idxposb += i_size;
2292             if( p_stream->i_idxposb >=
2293                     p_stream->p_index[p_stream->i_idxposc].i_length )
2294             {
2295                 p_stream->i_idxposb = 0;
2296                 p_stream->i_idxposc++;
2297             }
2298         }
2299         else
2300         {
2301             toread[i_stream].i_toread--;
2302             p_stream->i_idxposc++;
2303         }
2304
2305         if( p_stream->i_idxposc < p_stream->i_idxnb)
2306         {
2307             toread[i_stream].i_posf =
2308                 p_stream->p_index[p_stream->i_idxposc].i_pos;
2309             if( p_stream->i_idxposb > 0 )
2310             {
2311                 toread[i_stream].i_posf += 8 + p_stream->i_idxposb;
2312             }
2313
2314         }
2315         else
2316         {
2317             toread[i_stream].i_posf = -1;
2318         }
2319
2320         b_stream = VLC_TRUE; // at least one read succeed
2321
2322         if( p_stream->p_es && p_stream->p_es->p_decoder_fifo &&
2323             ( b_play_audio || p_stream->i_cat != AUDIO_ES ) )
2324         {
2325             p_pes->i_dts =
2326                 p_pes->i_pts =
2327                     input_ClockGetTS( p_input,
2328                                       p_input->stream.p_selected_program,
2329                                       p_pes->i_pts * 9/100);
2330
2331             input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes );
2332         }
2333         else
2334         {
2335             input_DeletePES( p_input->p_method_data, p_pes );
2336         }
2337     }
2338 }
2339
2340
2341 /*****************************************************************************
2342  * AVIDemux_UnSeekable: reads and demuxes data packets for unseekable file
2343  *****************************************************************************
2344  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
2345  *****************************************************************************/
2346 static int AVIDemux_UnSeekable( input_thread_t *p_input )
2347 {
2348     demux_sys_t     *p_avi = p_input->p_demux_data;
2349     avi_stream_t *p_stream_master;
2350     vlc_bool_t b_audio;
2351     unsigned int i_stream;
2352     unsigned int i_packet;
2353
2354     /* *** send audio data to decoder only if rate == DEFAULT_RATE *** */
2355     vlc_mutex_lock( &p_input->stream.stream_lock );
2356     b_audio = p_input->stream.control.i_rate == DEFAULT_RATE;
2357     vlc_mutex_unlock( &p_input->stream.stream_lock );
2358
2359     input_ClockManageRef( p_input,
2360                           p_input->stream.p_selected_program,
2361                           p_avi->i_pcr );
2362     /* *** find master stream for data packet skipping algo *** */
2363     /* *** -> first video, if any, or first audio ES *** */
2364     for( i_stream = 0, p_stream_master = NULL;
2365             i_stream < p_avi->i_streams; i_stream++ )
2366     {
2367 #define p_stream    p_avi->pp_info[i_stream]
2368         if( p_stream->p_es &&
2369             p_stream->p_es->p_decoder_fifo )
2370         {
2371             if( p_stream->i_cat == VIDEO_ES )
2372             {
2373                 p_stream_master = p_stream;
2374                 break;
2375             }
2376             if( p_stream->i_cat == AUDIO_ES && !p_stream_master )
2377             {
2378                 p_stream_master = p_stream;
2379             }
2380         }
2381 #undef p_stream
2382     }
2383     if( !p_stream_master )
2384     {
2385         msg_Warn( p_input, "no more stream selected" );
2386         return( 0 );
2387     }
2388
2389     p_avi->i_pcr = AVI_GetPTS( p_stream_master ) * 9 / 100;
2390
2391     for( i_packet = 0; i_packet < 10; i_packet++)
2392     {
2393 #define p_stream    p_avi->pp_info[avi_pk.i_stream]
2394
2395         avi_packet_t    avi_pk;
2396
2397         if( AVI_PacketGetHeader( p_input, &avi_pk ) )
2398         {
2399             return( 0 );
2400         }
2401 //        AVI_ParseStreamHeader( avi_pk.i_fourcc, &i_stream, &i_cat );
2402
2403         if( avi_pk.i_stream >= p_avi->i_streams ||
2404             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
2405         {
2406             /* we haven't found an audio or video packet:
2407              *  - we have seek, found first next packet
2408              *  - others packets could be found, skip them
2409              */
2410             switch( avi_pk.i_fourcc )
2411             {
2412                 case AVIFOURCC_JUNK:
2413                 case AVIFOURCC_LIST:
2414                 case AVIFOURCC_RIFF:
2415                     return( !AVI_PacketNext( p_input ) ? 1 : 0 );
2416                 case AVIFOURCC_idx1:
2417                     if( p_avi->b_odml )
2418                     {
2419                         return( !AVI_PacketNext( p_input ) ? 1 : 0 );
2420                     }
2421                     return( 0 );    // eof
2422                 default:
2423                     msg_Warn( p_input,
2424                               "seems to have lost position, resync" );
2425                     if( AVI_PacketSearch( p_input ) )
2426                     {
2427                         msg_Err( p_input, "resync failed" );
2428                         return( -1 );
2429                     }
2430             }
2431         }
2432         else
2433         {
2434             /* do will send this packet to decoder ? */
2435             if( ( !b_audio && avi_pk.i_cat == AUDIO_ES )||
2436                 !p_stream->p_es ||
2437                 !p_stream->p_es->p_decoder_fifo )
2438             {
2439                 if( AVI_PacketNext( p_input ) )
2440                 {
2441                     return( 0 );
2442                 }
2443             }
2444             else
2445             {
2446                 /* it's a selected stream, check for time */
2447                 if( __ABS( AVI_GetPTS( p_stream ) -
2448                             AVI_GetPTS( p_stream_master ) )< 600*1000 )
2449                 {
2450                     /* load it and send to decoder */
2451                     pes_packet_t    *p_pes;
2452                     if( AVI_PacketRead( p_input, &avi_pk, &p_pes ) || !p_pes)
2453                     {
2454                         return( -1 );
2455                     }
2456                     p_pes->i_dts =
2457                         p_pes->i_pts =
2458                             input_ClockGetTS( p_input,
2459                                           p_input->stream.p_selected_program,
2460                                           AVI_GetPTS( p_stream ) * 9/100);
2461                     input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes );
2462                 }
2463                 else
2464                 {
2465                     if( AVI_PacketNext( p_input ) )
2466                     {
2467                         return( 0 );
2468                     }
2469                 }
2470             }
2471
2472             /* *** update stream time position *** */
2473             if( p_stream->i_samplesize )
2474             {
2475                 p_stream->i_idxposb += avi_pk.i_size;
2476             }
2477             else
2478             {
2479                 p_stream->i_idxposc++;
2480             }
2481
2482         }
2483
2484 #undef p_stream
2485     }
2486
2487     return( 1 );
2488 }
2489