* src/libvlc.h: fixed spelling mistake.
[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.48 2003/05/22 21:42:44 gbazin 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, 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         /* search key frame */
1729         msg_Dbg( p_input,
1730                  "old:"I64Fd" %s new "I64Fd,
1731                  i_oldpts,
1732                  i_oldpts > i_date ? ">" : "<",
1733                  i_date );
1734
1735         if( i_date < i_oldpts )
1736         {
1737             while( p_stream->i_idxposc > 0 &&
1738                !( p_stream->p_index[p_stream->i_idxposc].i_flags &
1739                                                             AVIIF_KEYFRAME ) )
1740             {
1741                 if( AVI_SetStreamChunk( p_input,
1742                                         i_stream,
1743                                         p_stream->i_idxposc - 1 ) )
1744                 {
1745                     return VLC_EGENERIC;
1746                 }
1747             }
1748         }
1749         else
1750         {
1751             while( p_stream->i_idxposc < p_stream->i_idxnb &&
1752                     !( p_stream->p_index[p_stream->i_idxposc].i_flags &
1753                                                             AVIIF_KEYFRAME ) )
1754             {
1755                 if( AVI_SetStreamChunk( p_input,
1756                                         i_stream,
1757                                         p_stream->i_idxposc + 1 ) )
1758                 {
1759                     return VLC_EGENERIC;
1760                 }
1761             }
1762         }
1763     }
1764     else
1765     {
1766         if( AVI_SetStreamBytes( p_input,
1767                                 i_stream,
1768                                 AVI_PTSToByte( p_stream, i_date ) ) )
1769         {
1770             return VLC_EGENERIC;
1771         }
1772     }
1773     return VLC_SUCCESS;
1774 #undef p_stream
1775 }
1776
1777 /*****************************************************************************
1778  * AVISeek: goto to i_date or i_percent
1779  *****************************************************************************
1780  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1781  *****************************************************************************/
1782 static int    AVISeek   ( input_thread_t *p_input,
1783                           mtime_t i_date, int i_percent )
1784 {
1785
1786     demux_sys_t *p_avi = p_input->p_demux_data;
1787     unsigned int i_stream;
1788     msg_Dbg( p_input,
1789              "seek requested: "I64Fd" secondes %d%%",
1790              i_date / 1000000,
1791              i_percent );
1792
1793     if( p_avi->b_seekable )
1794     {
1795         if( !p_avi->i_length )
1796         {
1797             avi_stream_t *p_stream;
1798             int64_t i_pos;
1799
1800             /* use i_percent to create a true i_date */
1801             msg_Warn( p_input,
1802                       "mmh, seeking without index at %d%%"
1803                       " work only for interleaved file", i_percent );
1804
1805             if( i_percent >= 100 )
1806             {
1807                 msg_Warn( p_input, "cannot seek so far !" );
1808                 return( -1 );
1809             }
1810             i_percent = __MAX( i_percent, 0 );
1811
1812             /* try to find chunk that is at i_percent or the file */
1813             i_pos = __MAX( i_percent *
1814                            p_input->stream.p_selected_area->i_size / 100,
1815                            p_avi->i_movi_begin );
1816             /* search first selected stream */
1817             for( i_stream = 0, p_stream = NULL;
1818                         i_stream < p_avi->i_streams; i_stream++ )
1819             {
1820                 p_stream = p_avi->pp_info[i_stream];
1821                 if( p_stream->b_activated )
1822                 {
1823                     break;
1824                 }
1825             }
1826             if( !p_stream || !p_stream->b_activated )
1827             {
1828                 msg_Warn( p_input, "cannot find any selected stream" );
1829                 return( -1 );
1830             }
1831
1832             /* be sure that the index exit */
1833             if( AVI_SetStreamChunk( p_input,
1834                                     i_stream,
1835                                     0 ) )
1836             {
1837                 msg_Warn( p_input, "cannot seek" );
1838                 return( -1 );
1839             }
1840
1841             while( i_pos >= p_stream->p_index[p_stream->i_idxposc].i_pos +
1842                p_stream->p_index[p_stream->i_idxposc].i_length + 8 )
1843             {
1844                 /* search after i_idxposc */
1845                 if( AVI_SetStreamChunk( p_input,
1846                                         i_stream, p_stream->i_idxposc + 1 ) )
1847                 {
1848                     msg_Warn( p_input, "cannot seek" );
1849                     return( -1 );
1850                 }
1851             }
1852             i_date = AVI_GetPTS( p_stream );
1853             /* TODO better support for i_samplesize != 0 */
1854             msg_Dbg( p_input, "estimate date "I64Fd, i_date );
1855         }
1856
1857 #define p_stream    p_avi->pp_info[i_stream]
1858         p_avi->i_time = 0;
1859         /* seek for chunk based streams */
1860         for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
1861         {
1862             if( p_stream->b_activated && !p_stream->i_samplesize )
1863 //            if( p_stream->b_activated )
1864             {
1865                 AVI_StreamSeek( p_input, p_avi, i_stream, i_date );
1866                 p_avi->i_time = __MAX( AVI_GetPTS( p_stream ),
1867                                         p_avi->i_time );
1868             }
1869         }
1870 #if 1
1871         if( p_avi->i_time )
1872         {
1873             i_date = p_avi->i_time;
1874         }
1875         /* seek for bytes based streams */
1876         for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
1877         {
1878             if( p_stream->b_activated && p_stream->i_samplesize )
1879             {
1880                 AVI_StreamSeek( p_input, p_avi, i_stream, i_date );
1881 //                p_avi->i_time = __MAX( AVI_GetPTS( p_stream ), p_avi->i_time );
1882             }
1883         }
1884         msg_Dbg( p_input, "seek: "I64Fd" secondes", p_avi->i_time /1000000 );
1885         /* set true movie time */
1886 #endif
1887         if( !p_avi->i_time )
1888         {
1889             p_avi->i_time = i_date;
1890         }
1891 #undef p_stream
1892         return( 1 );
1893     }
1894     else
1895     {
1896         msg_Err( p_input, "shouldn't yet be executed" );
1897         return( -1 );
1898     }
1899 }
1900
1901 #if 0
1902 static pes_packet_t *PES_split( input_thread_t *p_input, avi_stream_t *p_stream, pes_packet_t *p_pes )
1903 {
1904     pes_packet_t  *p_pes2;
1905     data_packet_t *p_data;
1906     int           i_nb_data;
1907
1908     if( p_pes->i_nb_data < 2 )
1909     {
1910         return( NULL );
1911     }
1912     p_pes2 = input_NewPES( p_input->p_method_data );
1913     p_pes2->i_pts = p_pes->i_pts;
1914     p_pes2->i_dts = p_pes->i_dts;
1915     p_pes2->i_nb_data = p_pes->i_nb_data/2;
1916     p_pes2->i_pes_size = 0;
1917     for( i_nb_data = 0, p_data = p_pes->p_first;
1918          i_nb_data < p_pes2->i_nb_data;
1919          i_nb_data++, p_data = p_data->p_next )
1920     {
1921         p_pes2->i_pes_size +=
1922             p_data->p_payload_end - p_data->p_payload_start;
1923         p_pes2->p_last = p_data;
1924     }
1925     p_pes2->p_first = p_pes->p_first;
1926     p_pes2->p_last->p_next = NULL;
1927
1928     p_pes->p_first = p_data;
1929     p_pes->i_pes_size -= p_pes2->i_pes_size;
1930     p_pes->i_nb_data -= p_pes2->i_nb_data;
1931 //    p_pes->i_pts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
1932 //    p_pes->i_dts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
1933     p_pes->i_pts = 0;
1934     p_pes->i_dts = 0;
1935     return( p_pes2 );
1936 }
1937 #endif
1938
1939 /*****************************************************************************
1940  * AVIDemux_Seekable: reads and demuxes data packets for stream seekable
1941  *****************************************************************************
1942  * AVIDemux: reads and demuxes data packets
1943  *****************************************************************************
1944  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1945  *****************************************************************************/
1946 typedef struct avi_stream_toread_s
1947 {
1948     vlc_bool_t b_ok;
1949
1950     int i_toread;
1951
1952     off_t i_posf; // where we will read :
1953                   // if i_idxposb == 0 : begining of chunk (+8 to acces data)
1954                   // else : point on data directly
1955 } avi_stream_toread_t;
1956
1957 static int AVIDemux_Seekable( input_thread_t *p_input )
1958 {
1959     unsigned int i_stream_count;
1960     unsigned int i_stream;
1961     vlc_bool_t b_stream;
1962     vlc_bool_t b_play_audio;
1963     vlc_bool_t b_video; /* is there some video track selected */
1964     // cannot be more than 100 stream (dcXX or wbXX)
1965     avi_stream_toread_t toread[100];
1966
1967     demux_sys_t *p_avi = p_input->p_demux_data;
1968
1969
1970     /* detect new selected/unselected streams */
1971     for( i_stream = 0,i_stream_count= 0, b_video = VLC_FALSE;
1972             i_stream < p_avi->i_streams; i_stream++ )
1973     {
1974 #define p_stream    p_avi->pp_info[i_stream]
1975         if( p_stream->p_es )
1976         {
1977             if( p_stream->p_es->p_decoder_fifo &&
1978                 !p_stream->b_activated )
1979             {
1980                 AVI_StreamStart( p_input, p_avi, i_stream );
1981             }
1982             else
1983             if( !p_stream->p_es->p_decoder_fifo &&
1984                 p_stream->b_activated )
1985             {
1986                 AVI_StreamStop( p_input, p_avi, i_stream );
1987             }
1988         }
1989         if( p_stream->b_activated )
1990         {
1991             i_stream_count++;
1992             if( p_stream->i_cat == VIDEO_ES )
1993             {
1994                 b_video = VLC_TRUE;
1995             }
1996         }
1997 #undef  p_stream
1998     }
1999
2000     if( i_stream_count <= 0 )
2001     {
2002         msg_Warn( p_input, "no track selected, exiting..." );
2003         return( 0 );
2004     }
2005
2006     if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
2007     {
2008         mtime_t i_date;
2009         int i_percent;
2010         /* first wait for empty buffer, arbitrary time FIXME */
2011         //msleep( DEFAULT_PTS_DELAY );
2012
2013         i_date = (mtime_t)1000000 *
2014                  (mtime_t)p_avi->i_length *
2015                  (mtime_t)AVI_TellAbsolute( p_input ) /
2016                  (mtime_t)p_input->stream.p_selected_area->i_size;
2017         i_percent = 100 * AVI_TellAbsolute( p_input ) /
2018                         p_input->stream.p_selected_area->i_size;
2019
2020 //        input_ClockInit( p_input->stream.p_selected_program );
2021         AVISeek( p_input, i_date, i_percent);
2022
2023 #ifdef __AVI_SUBTITLE__
2024         if( p_avi->p_sub )
2025         {
2026             subtitle_Seek( p_avi->p_sub, p_avi->i_time );
2027         }
2028 #endif
2029     }
2030
2031
2032     /* wait for the good time */
2033
2034     p_avi->i_pcr = p_avi->i_time * 9 / 100;
2035
2036     input_ClockManageRef( p_input,
2037                           p_input->stream.p_selected_program,
2038                           p_avi->i_pcr );
2039
2040
2041     p_avi->i_time += 25*1000;  /* read 25ms */
2042
2043 #ifdef __AVI_SUBTITLE__
2044     if( p_avi->p_sub )
2045     {
2046         subtitle_Demux( p_avi->p_sub, p_avi->i_time );
2047     }
2048 #endif
2049
2050     /* Check if we need to send the audio data to decoder */
2051     b_play_audio = !p_input->stream.control.b_mute;
2052
2053     /* init toread */
2054     for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
2055     {
2056 #define p_stream    p_avi->pp_info[i_stream]
2057         mtime_t i_dpts;
2058
2059         toread[i_stream].b_ok = p_stream->b_activated;
2060         if( p_stream->i_idxposc < p_stream->i_idxnb )
2061         {
2062             toread[i_stream].i_posf =
2063                 p_stream->p_index[p_stream->i_idxposc].i_pos;
2064            if( p_stream->i_idxposb > 0 )
2065            {
2066                 toread[i_stream].i_posf += 8 + p_stream->i_idxposb;
2067            }
2068         }
2069         else
2070         {
2071             toread[i_stream].i_posf = -1;
2072         }
2073
2074         i_dpts = p_avi->i_time - AVI_GetPTS( p_stream  );
2075
2076         if( p_stream->i_samplesize )
2077         {
2078             toread[i_stream].i_toread = AVI_PTSToByte( p_stream,
2079                                                        __ABS( i_dpts ) );
2080         }
2081         else
2082         {
2083             toread[i_stream].i_toread = AVI_PTSToChunk( p_stream,
2084                                                         __ABS( i_dpts ) );
2085         }
2086
2087         if( i_dpts < 0 )
2088         {
2089             toread[i_stream].i_toread *= -1;
2090         }
2091 #undef  p_stream
2092     }
2093
2094     b_stream = VLC_FALSE;
2095
2096     for( ;; )
2097     {
2098 #define p_stream    p_avi->pp_info[i_stream]
2099         vlc_bool_t       b_done;
2100         pes_packet_t    *p_pes;
2101         off_t i_pos;
2102         unsigned int i;
2103         size_t i_size;
2104
2105         /* search for first chunk to be read */
2106         for( i = 0, b_done = VLC_TRUE, i_pos = -1; i < p_avi->i_streams; i++ )
2107         {
2108             if( !toread[i].b_ok ||
2109                 AVI_GetDPTS( p_avi->pp_info[i],
2110                              toread[i].i_toread ) <= -25 * 1000 )
2111             {
2112                 continue;
2113             }
2114
2115             if( toread[i].i_toread > 0 )
2116             {
2117                 b_done = VLC_FALSE; // not yet finished
2118             }
2119
2120             if( toread[i].i_posf > 0 )
2121             {
2122                 if( i_pos == -1 || i_pos > toread[i_stream].i_posf )
2123                 {
2124                     i_stream = i;
2125                     i_pos = toread[i].i_posf;
2126                 }
2127             }
2128         }
2129
2130         if( b_done )
2131         {
2132 //            return( b_stream ? 1 : 0 );
2133             return( 1 );
2134         }
2135
2136         if( i_pos == -1 )
2137         {
2138             /* no valid index, we will parse directly the stream
2139              * in case we fail we will disable all finished stream */
2140             if( p_avi->i_movi_lastchunk_pos >= p_avi->i_movi_begin + 12 )
2141             {
2142                 AVI_SeekAbsolute( p_input, p_avi->i_movi_lastchunk_pos );
2143                 if( AVI_PacketNext( p_input ) )
2144                 {
2145                     return( AVI_StreamStopFinishedStreams( p_input, p_avi ) ? 0 : 1 );
2146                 }
2147             }
2148             else
2149             {
2150                 AVI_SeekAbsolute( p_input, p_avi->i_movi_begin + 12 );
2151             }
2152
2153             for( ;; )
2154             {
2155                 avi_packet_t avi_pk;
2156
2157                 if( AVI_PacketGetHeader( p_input, &avi_pk ) )
2158                 {
2159                     msg_Warn( p_input,
2160                              "cannot get packet header, track disabled" );
2161                     return( AVI_StreamStopFinishedStreams( p_input, p_avi ) ? 0 : 1 );
2162                 }
2163                 if( avi_pk.i_stream >= p_avi->i_streams ||
2164                     ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
2165                 {
2166                     if( AVI_PacketNext( p_input ) )
2167                     {
2168                         msg_Warn( p_input,
2169                                   "cannot skip packet, track disabled" );
2170                         return( AVI_StreamStopFinishedStreams( p_input, p_avi ) ? 0 : 1 );
2171                     }
2172                     continue;
2173                 }
2174                 else
2175                 {
2176                     /* add this chunk to the index */
2177                     AVIIndexEntry_t index;
2178
2179                     index.i_id = avi_pk.i_fourcc;
2180                     index.i_flags =
2181                        AVI_GetKeyFlag(p_avi->pp_info[avi_pk.i_stream]->i_codec,
2182                                       avi_pk.i_peek);
2183                     index.i_pos = avi_pk.i_pos;
2184                     index.i_length = avi_pk.i_size;
2185                     AVI_IndexAddEntry( p_avi, avi_pk.i_stream, &index );
2186
2187                     i_stream = avi_pk.i_stream;
2188                     /* do we will read this data ? */
2189                     if( AVI_GetDPTS( p_stream,
2190                              toread[i_stream].i_toread ) > -25 * 1000 )
2191                     {
2192                         break;
2193                     }
2194                     else
2195                     {
2196                         if( AVI_PacketNext( p_input ) )
2197                         {
2198                             msg_Warn( p_input,
2199                                       "cannot skip packet, track disabled" );
2200                             return( AVI_StreamStopFinishedStreams( p_input, p_avi ) ? 0 : 1 );
2201                         }
2202                     }
2203                 }
2204             }
2205
2206         }
2207         else
2208         {
2209             AVI_SeekAbsolute( p_input, i_pos );
2210         }
2211
2212         /* read thoses data */
2213         if( p_stream->i_samplesize )
2214         {
2215             unsigned int i_toread;
2216
2217             if( ( i_toread = toread[i_stream].i_toread ) <= 0 )
2218             {
2219                 if( p_stream->i_samplesize > 1 )
2220                 {
2221                     i_toread = p_stream->i_samplesize;
2222                 }
2223                 else
2224                 {
2225                     i_toread = __MAX( AVI_PTSToByte( p_stream, 20 * 1000 ), 100 );
2226                 }
2227             }
2228             i_size = __MIN( p_stream->p_index[p_stream->i_idxposc].i_length -
2229                                 p_stream->i_idxposb,
2230                             i_toread );
2231         }
2232         else
2233         {
2234             i_size = p_stream->p_index[p_stream->i_idxposc].i_length;
2235         }
2236
2237         if( p_stream->i_idxposb == 0 )
2238         {
2239             i_size += 8; // need to read and skip header
2240         }
2241
2242         if( input_ReadInPES( p_input, &p_pes, __EVEN( i_size ) ) < 0 )
2243         {
2244             msg_Warn( p_input, "failled reading data" );
2245             AVI_StreamStop( p_input, p_avi, i_stream );
2246             toread[i_stream].b_ok = VLC_FALSE;
2247             continue;
2248         }
2249
2250         if( i_size % 2 )    // read was padded on word boundary
2251         {
2252             p_pes->p_last->p_payload_end--;
2253             p_pes->i_pes_size--;
2254         }
2255         // skip header
2256         if( p_stream->i_idxposb == 0 )
2257         {
2258             p_pes->p_first->p_payload_start += 8;
2259             p_pes->i_pes_size -= 8;
2260         }
2261
2262         p_pes->i_pts = AVI_GetPTS( p_stream );
2263
2264 #if 0
2265         /* fix pts for audio: ie pts sould be for the first byte of the first frame */
2266         if( p_stream->i_samplesize == 1 )
2267         {
2268             AVI_FixPTS( p_stream, p_pes );
2269         }
2270 #endif
2271
2272         /* read data */
2273         if( p_stream->i_samplesize )
2274         {
2275             if( p_stream->i_idxposb == 0 )
2276             {
2277                 i_size -= 8;
2278             }
2279             toread[i_stream].i_toread -= i_size;
2280             p_stream->i_idxposb += i_size;
2281             if( p_stream->i_idxposb >=
2282                     p_stream->p_index[p_stream->i_idxposc].i_length )
2283             {
2284                 p_stream->i_idxposb = 0;
2285                 p_stream->i_idxposc++;
2286             }
2287         }
2288         else
2289         {
2290             toread[i_stream].i_toread--;
2291             p_stream->i_idxposc++;
2292         }
2293
2294         if( p_stream->i_idxposc < p_stream->i_idxnb)
2295         {
2296             toread[i_stream].i_posf =
2297                 p_stream->p_index[p_stream->i_idxposc].i_pos;
2298             if( p_stream->i_idxposb > 0 )
2299             {
2300                 toread[i_stream].i_posf += 8 + p_stream->i_idxposb;
2301             }
2302
2303         }
2304         else
2305         {
2306             toread[i_stream].i_posf = -1;
2307         }
2308
2309         b_stream = VLC_TRUE; // at least one read succeed
2310
2311         if( p_stream->p_es && p_stream->p_es->p_decoder_fifo &&
2312             ( b_play_audio || p_stream->i_cat != AUDIO_ES ) )
2313         {
2314             p_pes->i_dts =
2315                 p_pes->i_pts =
2316                     input_ClockGetTS( p_input,
2317                                       p_input->stream.p_selected_program,
2318                                       p_pes->i_pts * 9/100);
2319
2320             p_pes->i_rate = p_input->stream.control.i_rate;
2321
2322             input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes );
2323         }
2324         else
2325         {
2326             input_DeletePES( p_input->p_method_data, p_pes );
2327         }
2328     }
2329 }
2330
2331
2332 /*****************************************************************************
2333  * AVIDemux_UnSeekable: reads and demuxes data packets for unseekable file
2334  *****************************************************************************
2335  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
2336  *****************************************************************************/
2337 static int AVIDemux_UnSeekable( input_thread_t *p_input )
2338 {
2339     demux_sys_t     *p_avi = p_input->p_demux_data;
2340     avi_stream_t *p_stream_master;
2341     vlc_bool_t b_audio;
2342     unsigned int i_stream;
2343     unsigned int i_packet;
2344
2345     /* Check if we need to send the audio data to decoder */
2346     b_audio = !p_input->stream.control.b_mute;
2347
2348     input_ClockManageRef( p_input,
2349                           p_input->stream.p_selected_program,
2350                           p_avi->i_pcr );
2351     /* *** find master stream for data packet skipping algo *** */
2352     /* *** -> first video, if any, or first audio ES *** */
2353     for( i_stream = 0, p_stream_master = NULL;
2354             i_stream < p_avi->i_streams; i_stream++ )
2355     {
2356 #define p_stream    p_avi->pp_info[i_stream]
2357         if( p_stream->p_es &&
2358             p_stream->p_es->p_decoder_fifo )
2359         {
2360             if( p_stream->i_cat == VIDEO_ES )
2361             {
2362                 p_stream_master = p_stream;
2363                 break;
2364             }
2365             if( p_stream->i_cat == AUDIO_ES && !p_stream_master )
2366             {
2367                 p_stream_master = p_stream;
2368             }
2369         }
2370 #undef p_stream
2371     }
2372     if( !p_stream_master )
2373     {
2374         msg_Warn( p_input, "no more stream selected" );
2375         return( 0 );
2376     }
2377
2378     p_avi->i_pcr = AVI_GetPTS( p_stream_master ) * 9 / 100;
2379
2380     for( i_packet = 0; i_packet < 10; i_packet++)
2381     {
2382 #define p_stream    p_avi->pp_info[avi_pk.i_stream]
2383
2384         avi_packet_t    avi_pk;
2385
2386         if( AVI_PacketGetHeader( p_input, &avi_pk ) )
2387         {
2388             return( 0 );
2389         }
2390 //        AVI_ParseStreamHeader( avi_pk.i_fourcc, &i_stream, &i_cat );
2391
2392         if( avi_pk.i_stream >= p_avi->i_streams ||
2393             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
2394         {
2395             /* we haven't found an audio or video packet:
2396              *  - we have seek, found first next packet
2397              *  - others packets could be found, skip them
2398              */
2399             switch( avi_pk.i_fourcc )
2400             {
2401                 case AVIFOURCC_JUNK:
2402                 case AVIFOURCC_LIST:
2403                 case AVIFOURCC_RIFF:
2404                     return( !AVI_PacketNext( p_input ) ? 1 : 0 );
2405                 case AVIFOURCC_idx1:
2406                     if( p_avi->b_odml )
2407                     {
2408                         return( !AVI_PacketNext( p_input ) ? 1 : 0 );
2409                     }
2410                     return( 0 );    // eof
2411                 default:
2412                     msg_Warn( p_input,
2413                               "seems to have lost position, resync" );
2414                     if( AVI_PacketSearch( p_input ) )
2415                     {
2416                         msg_Err( p_input, "resync failed" );
2417                         return( -1 );
2418                     }
2419             }
2420         }
2421         else
2422         {
2423             /* do will send this packet to decoder ? */
2424             if( ( !b_audio && avi_pk.i_cat == AUDIO_ES )||
2425                 !p_stream->p_es ||
2426                 !p_stream->p_es->p_decoder_fifo )
2427             {
2428                 if( AVI_PacketNext( p_input ) )
2429                 {
2430                     return( 0 );
2431                 }
2432             }
2433             else
2434             {
2435                 /* it's a selected stream, check for time */
2436                 if( __ABS( AVI_GetPTS( p_stream ) -
2437                             AVI_GetPTS( p_stream_master ) )< 600*1000 )
2438                 {
2439                     /* load it and send to decoder */
2440                     pes_packet_t    *p_pes;
2441                     if( AVI_PacketRead( p_input, &avi_pk, &p_pes ) || !p_pes)
2442                     {
2443                         return( -1 );
2444                     }
2445                     p_pes->i_dts =
2446                         p_pes->i_pts =
2447                             input_ClockGetTS( p_input,
2448                                           p_input->stream.p_selected_program,
2449                                           AVI_GetPTS( p_stream ) * 9/100);
2450
2451                     p_pes->i_rate = p_input->stream.control.i_rate;
2452
2453                     input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes );
2454                 }
2455                 else
2456                 {
2457                     if( AVI_PacketNext( p_input ) )
2458                     {
2459                         return( 0 );
2460                     }
2461                 }
2462             }
2463
2464             /* *** update stream time position *** */
2465             if( p_stream->i_samplesize )
2466             {
2467                 p_stream->i_idxposb += avi_pk.i_size;
2468             }
2469             else
2470             {
2471                 p_stream->i_idxposc++;
2472             }
2473
2474         }
2475
2476 #undef p_stream
2477     }
2478
2479     return( 1 );
2480 }
2481