]> git.sesse.net Git - vlc/blob - modules/demux/avi/avi.c
4dbca4fdcbbf604bfe94b5cef047f6774dee7afb
[vlc] / modules / demux / avi / avi.c
1 /*****************************************************************************
2  * avi.c : AVI file Stream input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001-2004 the VideoLAN team
5  * $Id$
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_demux.h>
34
35 #include <vlc_dialog.h>
36
37 #include <vlc_meta.h>
38 #include <vlc_codecs.h>
39 #include <vlc_charset.h>
40
41 #include "libavi.h"
42
43 /*****************************************************************************
44  * Module descriptor
45  *****************************************************************************/
46
47 #define INTERLEAVE_TEXT N_("Force interleaved method" )
48 #define INTERLEAVE_LONGTEXT N_( "Force interleaved method." )
49
50 #define INDEX_TEXT N_("Force index creation")
51 #define INDEX_LONGTEXT N_( \
52     "Recreate a index for the AVI file. Use this if your AVI file is damaged "\
53     "or incomplete (not seekable)." )
54
55 static int  Open ( vlc_object_t * );
56 static void Close( vlc_object_t * );
57
58 static const int pi_index[] = {0,1,2};
59
60 static const char *const ppsz_indexes[] = { N_("Ask"), N_("Always fix"),
61                                 N_("Never fix") };
62
63 vlc_module_begin ()
64     set_shortname( "AVI" )
65     set_description( N_("AVI demuxer") )
66     set_capability( "demux", 212 )
67     set_category( CAT_INPUT )
68     set_subcategory( SUBCAT_INPUT_DEMUX )
69
70     add_bool( "avi-interleaved", 0, NULL,
71               INTERLEAVE_TEXT, INTERLEAVE_LONGTEXT, true )
72     add_integer( "avi-index", 0, NULL,
73               INDEX_TEXT, INDEX_LONGTEXT, false )
74         change_integer_list( pi_index, ppsz_indexes, NULL )
75
76     set_callbacks( Open, Close )
77 vlc_module_end ()
78
79 /*****************************************************************************
80  * Local prototypes
81  *****************************************************************************/
82 static int Control         ( demux_t *, int, va_list );
83 static int Seek            ( demux_t *, mtime_t, int );
84 static int Demux_Seekable  ( demux_t * );
85 static int Demux_UnSeekable( demux_t * );
86
87 #define __ABS( x ) ( (x) < 0 ? (-(x)) : (x) )
88
89 typedef struct
90 {
91     vlc_fourcc_t i_fourcc;
92     off_t        i_pos;
93     uint32_t     i_size;
94     vlc_fourcc_t i_type;     /* only for AVIFOURCC_LIST */
95
96     uint8_t      i_peek[8];  /* first 8 bytes */
97
98     unsigned int i_stream;
99     unsigned int i_cat;
100 } avi_packet_t;
101
102
103 typedef struct
104 {
105     vlc_fourcc_t i_id;
106     uint32_t     i_flags;
107     off_t        i_pos;
108     uint32_t     i_length;
109     int64_t      i_lengthtotal;
110
111 } avi_entry_t;
112
113 typedef struct
114 {
115     bool            b_activated;
116     bool            b_eof;
117
118     unsigned int    i_cat; /* AUDIO_ES, VIDEO_ES */
119     vlc_fourcc_t    i_codec;
120
121     int             i_rate;
122     int             i_scale;
123     int             i_samplesize;
124
125     es_out_id_t     *p_es;
126
127     /* Avi Index */
128     avi_entry_t     *p_index;
129     unsigned int    i_idxnb;
130     unsigned int    i_idxmax;
131
132     unsigned int    i_idxposc;  /* numero of chunk */
133     unsigned int    i_idxposb;  /* byte in the current chunk */
134
135     /* extra information given to the decoder */
136     void            *p_extra;
137
138     /* For VBR audio only */
139     unsigned int    i_blockno;
140     unsigned int    i_blocksize;
141
142     /* For muxed streams */
143     stream_t        *p_out_muxed;
144 } avi_track_t;
145
146 struct demux_sys_t
147 {
148     mtime_t i_time;
149     mtime_t i_length;
150
151     bool  b_seekable;
152     bool  b_muxed;
153     avi_chunk_t ck_root;
154
155     bool  b_odml;
156
157     off_t   i_movi_begin;
158     off_t   i_movi_lastchunk_pos;   /* XXX position of last valid chunk */
159
160     /* number of streams and information */
161     unsigned int i_track;
162     avi_track_t  **track;
163
164     /* meta */
165     vlc_meta_t  *meta;
166 };
167
168 static inline off_t __EVEN( off_t i )
169 {
170     return (i & 1) ? i + 1 : i;
171 }
172
173 static mtime_t AVI_PTSToChunk( avi_track_t *, mtime_t i_pts );
174 static mtime_t AVI_PTSToByte ( avi_track_t *, mtime_t i_pts );
175 static mtime_t AVI_GetDPTS   ( avi_track_t *, int64_t i_count );
176 static mtime_t AVI_GetPTS    ( avi_track_t * );
177
178
179 static int AVI_StreamChunkFind( demux_t *, unsigned int i_stream );
180 static int AVI_StreamChunkSet ( demux_t *,
181                                 unsigned int i_stream, unsigned int i_ck );
182 static int AVI_StreamBytesSet ( demux_t *,
183                                 unsigned int i_stream, off_t   i_byte );
184
185 vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t );
186 static int   AVI_GetKeyFlag    ( vlc_fourcc_t , uint8_t * );
187
188 static int AVI_PacketGetHeader( demux_t *, avi_packet_t *p_pk );
189 static int AVI_PacketNext     ( demux_t * );
190 static int AVI_PacketRead     ( demux_t *, avi_packet_t *, block_t **);
191 static int AVI_PacketSearch   ( demux_t * );
192
193 static void AVI_IndexLoad    ( demux_t * );
194 static void AVI_IndexCreate  ( demux_t * );
195 static void AVI_IndexAddEntry( demux_sys_t *, int, avi_entry_t * );
196
197 static mtime_t  AVI_MovieGetLength( demux_t * );
198
199 /*****************************************************************************
200  * Stream management
201  *****************************************************************************/
202 static int        AVI_TrackSeek  ( demux_t *, int, mtime_t );
203 static int        AVI_TrackStopFinishedStreams( demux_t *);
204
205 /* Remarks:
206  - For VBR mp3 stream:
207     count blocks by rounded-up chunksizes instead of chunks
208     we need full emulation of dshow avi demuxer bugs :(
209     fixes silly nandub-style a-v delaying in avi with vbr mp3...
210     (from mplayer 2002/08/02)
211  - to complete....
212  */
213
214 /*****************************************************************************
215  * Open: check file and initializes AVI structures
216  *****************************************************************************/
217 static int Open( vlc_object_t * p_this )
218 {
219     demux_t  *p_demux = (demux_t *)p_this;
220     demux_sys_t     *p_sys;
221
222     bool       b_index = false;
223     int              i_do_index;
224
225     avi_chunk_t         ck_riff;
226     avi_chunk_list_t    *p_riff = (avi_chunk_list_t*)&ck_riff;
227     avi_chunk_list_t    *p_hdrl, *p_movi;
228     avi_chunk_avih_t    *p_avih;
229
230     unsigned int i_track;
231     unsigned int i, i_peeker;
232
233     const uint8_t *p_peek;
234
235     /* Is it an avi file ? */
236     if( stream_Peek( p_demux->s, &p_peek, 200 ) < 200 ) return VLC_EGENERIC;
237
238     for( i_peeker = 0; i_peeker < 188; i_peeker++ )
239     {
240         if( !strncmp( (char *)&p_peek[0], "RIFF", 4 ) && !strncmp( (char *)&p_peek[8], "AVI ", 4 ) )
241             break;
242         if( !strncmp( (char *)&p_peek[0], "ON2 ", 4 ) && !strncmp( (char *)&p_peek[8], "ON2f", 4 ) )
243             break;
244         p_peek++;
245     }
246     if( i_peeker == 188 )
247     {
248         return VLC_EGENERIC;
249     }
250
251     /* Initialize input  structures. */
252     p_sys = p_demux->p_sys = malloc( sizeof(demux_sys_t) );
253     memset( p_sys, 0, sizeof( demux_sys_t ) );
254     p_sys->i_time   = 0;
255     p_sys->i_length = 0;
256     p_sys->i_movi_lastchunk_pos = 0;
257     p_sys->b_odml   = false;
258     p_sys->b_muxed  = false;
259     p_sys->i_track  = 0;
260     p_sys->track    = NULL;
261     p_sys->meta     = NULL;
262
263     stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &p_sys->b_seekable );
264
265     p_demux->pf_control = Control;
266     p_demux->pf_demux = Demux_Seekable;
267
268     /* For unseekable stream, automaticaly use Demux_UnSeekable */
269     if( !p_sys->b_seekable || config_GetInt( p_demux, "avi-interleaved" ) )
270     {
271         p_demux->pf_demux = Demux_UnSeekable;
272     }
273
274     if( i_peeker > 0 )
275     {
276         stream_Read( p_demux->s, NULL, i_peeker );
277     }
278
279     if( AVI_ChunkReadRoot( p_demux->s, &p_sys->ck_root ) )
280     {
281         msg_Err( p_demux, "avi module discarded (invalid file)" );
282         return VLC_EGENERIC;
283     }
284
285     if( AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF ) > 1 )
286     {
287         unsigned int i_count =
288             AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF );
289
290         msg_Warn( p_demux, "multiple riff -> OpenDML ?" );
291         for( i = 1; i < i_count; i++ )
292         {
293             avi_chunk_list_t *p_sysx;
294
295             p_sysx = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, i );
296             if( p_sysx->i_type == AVIFOURCC_AVIX )
297             {
298                 msg_Warn( p_demux, "detected OpenDML file" );
299                 p_sys->b_odml = true;
300                 break;
301             }
302         }
303     }
304
305     p_riff  = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0 );
306     p_hdrl  = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0 );
307     p_movi  = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0 );
308
309     if( !p_hdrl || !p_movi )
310     {
311         msg_Err( p_demux, "avi module discarded (invalid file)" );
312         goto error;
313     }
314
315     if( !( p_avih = AVI_ChunkFind( p_hdrl, AVIFOURCC_avih, 0 ) ) )
316     {
317         msg_Err( p_demux, "cannot find avih chunk" );
318         goto error;
319     }
320     i_track = AVI_ChunkCount( p_hdrl, AVIFOURCC_strl );
321     if( p_avih->i_streams != i_track )
322     {
323         msg_Warn( p_demux,
324                   "found %d stream but %d are declared",
325                   i_track, p_avih->i_streams );
326     }
327     if( i_track == 0 )
328     {
329         msg_Err( p_demux, "no stream defined!" );
330         goto error;
331     }
332
333     /* print information on streams */
334     msg_Dbg( p_demux, "AVIH: %d stream, flags %s%s%s%s ",
335              i_track,
336              p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
337              p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
338              p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
339              p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
340     if( ( p_sys->meta = vlc_meta_New() ) )
341     {
342         char buffer[200];
343         snprintf( buffer, sizeof(buffer), "%s%s%s%s",
344                   p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
345                   p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
346                   p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
347                   p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
348         vlc_meta_SetSetting( p_sys->meta, buffer );
349     }
350
351     /* now read info on each stream and create ES */
352     for( i = 0 ; i < i_track; i++ )
353     {
354         avi_track_t           *tk     = malloc( sizeof( avi_track_t ) );
355         if( !tk )
356             goto error;
357
358         avi_chunk_list_t      *p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i );
359         avi_chunk_strh_t      *p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0 );
360         avi_chunk_STRING_t    *p_strn = AVI_ChunkFind( p_strl, AVIFOURCC_strn, 0 );
361         avi_chunk_strf_auds_t *p_auds = NULL;
362         avi_chunk_strf_vids_t *p_vids = NULL;
363         es_format_t fmt;
364
365         memset( tk, 0, sizeof(*tk) );
366         tk->b_eof = false;
367         tk->b_activated = true;
368
369         p_vids = (avi_chunk_strf_vids_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
370         p_auds = (avi_chunk_strf_auds_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
371
372         if( p_strl == NULL || p_strh == NULL || p_auds == NULL || p_vids == NULL )
373         {
374             msg_Warn( p_demux, "stream[%d] incomplete", i );
375             free( tk );
376             continue;
377         }
378
379         tk->i_rate  = p_strh->i_rate;
380         tk->i_scale = p_strh->i_scale;
381         tk->i_samplesize = p_strh->i_samplesize;
382         msg_Dbg( p_demux, "stream[%d] rate:%d scale:%d samplesize:%d",
383                  i, tk->i_rate, tk->i_scale, tk->i_samplesize );
384
385         switch( p_strh->i_type )
386         {
387             case( AVIFOURCC_auds ):
388                 tk->i_cat   = AUDIO_ES;
389                 tk->i_codec = AVI_FourccGetCodec( AUDIO_ES,
390                                                   p_auds->p_wf->wFormatTag );
391
392                 tk->i_blocksize = p_auds->p_wf->nBlockAlign;
393                 if( tk->i_blocksize == 0 )
394                 {
395                     if( p_auds->p_wf->wFormatTag == 1 )
396                         tk->i_blocksize = p_auds->p_wf->nChannels * (p_auds->p_wf->wBitsPerSample/8);
397                     else
398                         tk->i_blocksize = 1;
399                 }
400                 else if( tk->i_samplesize != 0 && tk->i_samplesize != tk->i_blocksize )
401                 {
402                     msg_Warn( p_demux, "track[%d] samplesize=%d and blocksize=%d are not equal."
403                                        "Using blocksize as a workaround.",
404                                        i, tk->i_samplesize, tk->i_blocksize );
405                     tk->i_samplesize = tk->i_blocksize;
406                 }
407
408                 if( tk->i_codec == VLC_CODEC_VORBIS )
409                 {
410                     tk->i_blocksize = 0; /* fix vorbis VBR decoding */
411                 }
412
413                 es_format_Init( &fmt, AUDIO_ES, tk->i_codec );
414
415                 fmt.audio.i_channels        = p_auds->p_wf->nChannels;
416                 fmt.audio.i_rate            = p_auds->p_wf->nSamplesPerSec;
417                 fmt.i_bitrate               = p_auds->p_wf->nAvgBytesPerSec*8;
418                 fmt.audio.i_blockalign      = p_auds->p_wf->nBlockAlign;
419                 fmt.audio.i_bitspersample   = p_auds->p_wf->wBitsPerSample;
420                 fmt.b_packetized            = !tk->i_blocksize;
421
422                 msg_Dbg( p_demux,
423                     "stream[%d] audio(0x%x) %d channels %dHz %dbits",
424                     i, p_auds->p_wf->wFormatTag, p_auds->p_wf->nChannels,
425                     p_auds->p_wf->nSamplesPerSec, 
426                     p_auds->p_wf->wBitsPerSample );
427
428                 fmt.i_extra = __MIN( p_auds->p_wf->cbSize,
429                     p_auds->i_chunk_size - sizeof(WAVEFORMATEX) );
430                 fmt.p_extra = tk->p_extra = malloc( fmt.i_extra );
431                 if( !fmt.p_extra ) goto error;
432                 memcpy( fmt.p_extra, &p_auds->p_wf[1], fmt.i_extra );
433
434                 /* Rewrite the vorbis headers from Xiph-like format
435                  * to VLC internal format
436                  *
437                  * Xiph format:
438                  *  - 1st byte == N, is the number of packets - 1
439                  *  - Following bytes are the size of the N first packets:
440                  *      while( *p == 0xFF ) { size += 0xFF; p++ } size += *p;
441                  *      (the size of the last packet is the size of remaining
442                  *      data in the buffer)
443                  *  - Finally, all the packets concatenated
444                  *
445                  * VLC format:
446                  *  - Size of the packet on 16 bits (big endian) FIXME: should be 32 bits to be safe
447                  *  - The packet itself
448                  *  - Size of the next packet, and so on ...
449                  */
450
451                 if( tk->i_codec == VLC_CODEC_VORBIS )
452                 {
453                     uint8_t *p_extra = fmt.p_extra; 
454                     size_t i_extra = fmt.i_extra;
455
456                     if( i_extra <= 1 ) break;
457                     if( *p_extra++ != 2 ) break; /* 3 packets - 1 = 2 */
458                     i_extra--;
459
460                     size_t i_identifier_len = 0;
461                     while( *p_extra == 0xFF )
462                     {
463                         i_identifier_len += 0xFF;
464                         p_extra++;
465                         if( --i_extra <= 1 ) break;
466                     }
467                     i_identifier_len += *p_extra++;
468                     if( i_identifier_len > --i_extra ) break;
469
470                     size_t i_comment_len = 0;
471                     while( *p_extra == 0xFF )
472                     {
473                         i_comment_len += 0xFF;
474                         p_extra++;
475                         if( --i_extra <= 1 ) break;
476                     }
477                     i_comment_len += *p_extra++;
478                     if( i_comment_len > --i_extra ) break;
479                     size_t i_cookbook_len = i_extra;
480
481                     size_t i_headers_size = 3  * 2 + i_identifier_len +
482                                             i_comment_len + i_cookbook_len;
483                     uint8_t *p_out = malloc( i_headers_size );
484                     if( !p_out ) goto error;
485                     free( fmt.p_extra );
486                     fmt.p_extra = tk->p_extra = p_out;
487                     fmt.i_extra = i_headers_size;
488                     #define copy_packet( len ) \
489                         *p_out++ = len >> 8; \
490                         *p_out++ = len & 0xFF; \
491                         memcpy( p_out, p_extra, len ); \
492                         p_out += len; \
493                         p_extra += len;
494                     copy_packet( i_identifier_len );
495                     copy_packet( i_comment_len );
496                     copy_packet( i_cookbook_len );
497                     #undef copy_packet
498                     break;
499                 }
500                 break;
501
502             case( AVIFOURCC_vids ):
503                 tk->i_cat   = VIDEO_ES;
504                 tk->i_codec = AVI_FourccGetCodec( VIDEO_ES,
505                                                   p_vids->p_bih->biCompression );
506                 if( p_vids->p_bih->biCompression == VLC_FOURCC( 'D', 'X', 'S', 'B' ) )
507                 {
508                    msg_Dbg( p_demux, "stream[%d] subtitles", i );
509                    es_format_Init( &fmt, SPU_ES, p_vids->p_bih->biCompression );
510                    break;
511                 }
512                 else if( p_vids->p_bih->biCompression == 0x00 )
513                 {
514                     switch( p_vids->p_bih->biBitCount )
515                     {
516                         case 32:
517                             tk->i_codec = VLC_CODEC_RGB32;
518                             break;
519                         case 24:
520                             tk->i_codec = VLC_CODEC_RGB24;
521                             break;
522                         case 16: /* Yes it is RV15 */
523                         case 15:
524                             tk->i_codec = VLC_CODEC_RGB15;
525                             break;
526                         case 9: /* <- TODO check that */
527                             tk->i_codec = VLC_CODEC_I410;
528                             break;
529                         case 8: /* <- TODO check that */
530                             tk->i_codec = VLC_CODEC_GREY;
531                             break;
532                     }
533                     es_format_Init( &fmt, VIDEO_ES, tk->i_codec );
534
535                     switch( tk->i_codec )
536                     {
537                     case VLC_CODEC_RGB24:
538                     case VLC_CODEC_RGB32:
539                         fmt.video.i_rmask = 0x00ff0000;
540                         fmt.video.i_gmask = 0x0000ff00;
541                         fmt.video.i_bmask = 0x000000ff;
542                         break;
543                     case VLC_CODEC_RGB15:
544                         fmt.video.i_rmask = 0x7c00;
545                         fmt.video.i_gmask = 0x03e0;
546                         fmt.video.i_bmask = 0x001f;
547                         break;
548                     default:
549                         break;
550                     }
551                 }
552                 else
553                 {
554                     es_format_Init( &fmt, VIDEO_ES, p_vids->p_bih->biCompression );
555                     if( tk->i_codec == VLC_CODEC_MP4V &&
556                         !strncasecmp( (char*)&p_strh->i_handler, "XVID", 4 ) )
557                     {
558                         fmt.i_codec           =
559                         fmt.i_original_fourcc = VLC_FOURCC( 'X', 'V', 'I', 'D' );
560                     }
561                 }
562                 tk->i_samplesize = 0;
563                 fmt.video.i_width  = p_vids->p_bih->biWidth;
564                 fmt.video.i_height = p_vids->p_bih->biHeight;
565                 fmt.video.i_bits_per_pixel = p_vids->p_bih->biBitCount;
566                 fmt.video.i_frame_rate = tk->i_rate;
567                 fmt.video.i_frame_rate_base = tk->i_scale;
568                 fmt.i_extra =
569                     __MIN( p_vids->p_bih->biSize - sizeof( BITMAPINFOHEADER ),
570                            p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER) );
571                 fmt.p_extra = &p_vids->p_bih[1];
572                 msg_Dbg( p_demux, "stream[%d] video(%4.4s) %"PRIu32"x%"PRIu32" %dbpp %ffps",
573                          i, (char*)&p_vids->p_bih->biCompression,
574                          (uint32_t)p_vids->p_bih->biWidth,
575                          (uint32_t)p_vids->p_bih->biHeight,
576                          p_vids->p_bih->biBitCount,
577                          (float)tk->i_rate/(float)tk->i_scale );
578
579                 if( p_vids->p_bih->biCompression == 0x00 )
580                 {
581                     /* RGB DIB are coded from bottom to top */
582                     fmt.video.i_height =
583                         (unsigned int)(-(int)p_vids->p_bih->biHeight);
584                 }
585
586                 /* Extract palette from extradata if bpp <= 8
587                  * (assumes that extradata contains only palette but appears
588                  *  to be true for all palettized codecs we support) */
589                 if( fmt.video.i_bits_per_pixel > 0 && fmt.video.i_bits_per_pixel <= 8 )
590                 {
591                     /* The palette is not always included in biSize */
592                     fmt.i_extra = p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER);
593                     if( fmt.i_extra > 0 )
594                     {
595                         const uint8_t *p_pal = fmt.p_extra;
596
597                         fmt.video.p_palette = calloc( 1, sizeof(video_palette_t) );
598                         fmt.video.p_palette->i_entries = __MIN(fmt.i_extra/4, 256);
599
600                         for( int i = 0; i < fmt.video.p_palette->i_entries; i++ )
601                         {
602                             for( int j = 0; j < 4; j++ )
603                                 fmt.video.p_palette->palette[i][j] = p_pal[4*i+j];
604                         }
605                     }
606                 }
607                 break;
608
609             case( AVIFOURCC_txts):
610                 tk->i_cat   = SPU_ES;
611                 tk->i_codec = VLC_CODEC_SUBT;
612                 msg_Dbg( p_demux, "stream[%d] subtitles", i );
613                 es_format_Init( &fmt, SPU_ES, tk->i_codec );
614                 break;
615
616             case( AVIFOURCC_iavs):
617             case( AVIFOURCC_ivas):
618                 p_sys->b_muxed = true;
619                 msg_Dbg( p_demux, "stream[%d] iavs with handler %4.4s", i, (char *)&p_strh->i_handler );
620                 if( p_strh->i_handler == FOURCC_dvsd ||
621                     p_strh->i_handler == FOURCC_dvhd ||
622                     p_strh->i_handler == FOURCC_dvsl ||
623                     p_strh->i_handler == FOURCC_dv25 ||
624                     p_strh->i_handler == FOURCC_dv50 )
625                 {
626                     tk->p_out_muxed = stream_DemuxNew( p_demux, (char *)"rawdv", p_demux->out );
627                     if( !tk->p_out_muxed )
628                         msg_Err( p_demux, "could not load the DV parser" );
629                     else break;
630                 }
631                 free( tk );
632                 continue;
633
634             case( AVIFOURCC_mids):
635                 msg_Dbg( p_demux, "stream[%d] midi is UNSUPPORTED", i );
636
637             default:
638                 msg_Warn( p_demux, "stream[%d] unknown type %4.4s", i, (char *)&p_strh->i_type );
639                 free( tk );
640                 continue;
641         }
642         if( p_strn )
643             fmt.psz_description = FromLatin1( p_strn->p_str );
644         if( tk->p_out_muxed == NULL )
645             tk->p_es = es_out_Add( p_demux->out, &fmt );
646         TAB_APPEND( p_sys->i_track, p_sys->track, tk );
647     }
648
649     if( p_sys->i_track <= 0 )
650     {
651         msg_Err( p_demux, "no valid track" );
652         goto error;
653     }
654
655     i_do_index =  config_GetInt( p_demux, "avi-index" );
656     if( i_do_index == 1 ) /* Always fix */
657     {
658 aviindex:
659         if( p_sys->b_seekable )
660         {
661             AVI_IndexCreate( p_demux );
662         }
663         else
664         {
665             msg_Warn( p_demux, "cannot create index (unseekable stream)" );
666             AVI_IndexLoad( p_demux );
667         }
668     }
669     else
670     {
671         AVI_IndexLoad( p_demux );
672     }
673
674     /* *** movie length in sec *** */
675     p_sys->i_length = AVI_MovieGetLength( p_demux );
676     if( p_sys->i_length < (mtime_t)p_avih->i_totalframes *
677                           (mtime_t)p_avih->i_microsecperframe /
678                           (mtime_t)1000000 )
679     {
680         if( !vlc_object_alive( p_demux) )
681             goto error;
682
683         msg_Warn( p_demux, "broken or missing index, 'seek' will be "
684                            "approximative or will exhibit strange behavior" );
685         if( i_do_index == 0 && !b_index )
686         {
687             if( !p_sys->b_seekable ) {
688                 b_index = true;
689                 goto aviindex;
690             }
691             switch( dialog_Question( p_demux, _("AVI Index") ,
692                _( "This AVI file is broken. Seeking will not work correctly.\n"
693                   "Do you want to try to fix it?\n\n"
694                   "This might take a long time." ),
695                   _( "Repair" ), _( "Don't repair" ), _( "Cancel") ) )
696             {
697                 case 1:
698                     b_index = true;
699                     msg_Dbg( p_demux, "Fixing AVI index" );
700                     goto aviindex;
701                 case 3:
702                     /* Kill input */
703                     vlc_object_kill( p_demux->p_parent );
704                     goto error;
705             }
706         }
707     }
708
709     /* fix some BeOS MediaKit generated file */
710     for( i = 0 ; i < p_sys->i_track; i++ )
711     {
712         avi_track_t         *tk = p_sys->track[i];
713         avi_chunk_list_t    *p_strl;
714         avi_chunk_strh_t    *p_strh;
715         avi_chunk_strf_auds_t    *p_auds;
716
717         if( tk->i_cat != AUDIO_ES )
718         {
719             continue;
720         }
721         if( tk->i_idxnb < 1 ||
722             tk->i_scale != 1 ||
723             tk->i_samplesize != 0 )
724         {
725             continue;
726         }
727         p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i );
728         p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0 );
729         p_auds = AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
730
731         if( p_auds->p_wf->wFormatTag != WAVE_FORMAT_PCM &&
732             (unsigned int)tk->i_rate == p_auds->p_wf->nSamplesPerSec )
733         {
734             int64_t i_track_length =
735                 tk->p_index[tk->i_idxnb-1].i_length +
736                 tk->p_index[tk->i_idxnb-1].i_lengthtotal;
737             mtime_t i_length = (mtime_t)p_avih->i_totalframes *
738                                (mtime_t)p_avih->i_microsecperframe;
739
740             if( i_length == 0 )
741             {
742                 msg_Warn( p_demux, "track[%d] cannot be fixed (BeOS MediaKit generated)", i );
743                 continue;
744             }
745             tk->i_samplesize = 1;
746             tk->i_rate       = i_track_length  * (int64_t)1000000/ i_length;
747             msg_Warn( p_demux, "track[%d] fixed with rate=%d scale=%d (BeOS MediaKit generated)", i, tk->i_rate, tk->i_scale );
748         }
749     }
750
751     if( p_sys->b_seekable )
752     {
753         /* we have read all chunk so go back to movi */
754         stream_Seek( p_demux->s, p_movi->i_chunk_pos );
755     }
756     /* Skip movi header */
757     stream_Read( p_demux->s, NULL, 12 );
758
759     p_sys->i_movi_begin = p_movi->i_chunk_pos;
760     return VLC_SUCCESS;
761
762 error:
763     if( p_sys->meta )
764     {
765         vlc_meta_Delete( p_sys->meta );
766     }
767     AVI_ChunkFreeRoot( p_demux->s, &p_sys->ck_root );
768     free( p_sys );
769     return VLC_EGENERIC;
770 }
771
772 /*****************************************************************************
773  * Close: frees unused data
774  *****************************************************************************/
775 static void Close ( vlc_object_t * p_this )
776 {
777     demux_t *    p_demux = (demux_t *)p_this;
778     unsigned int i;
779     demux_sys_t *p_sys = p_demux->p_sys  ;
780
781     for( i = 0; i < p_sys->i_track; i++ )
782     {
783         if( p_sys->track[i] )
784         {
785             if( p_sys->track[i]->p_out_muxed )
786                 stream_Delete( p_sys->track[i]->p_out_muxed );
787             free( p_sys->track[i]->p_index );
788             free( p_sys->track[i]->p_extra );
789             free( p_sys->track[i] );
790         }
791     }
792     free( p_sys->track );
793     AVI_ChunkFreeRoot( p_demux->s, &p_sys->ck_root );
794     vlc_meta_Delete( p_sys->meta );
795
796     free( p_sys );
797 }
798
799 /*****************************************************************************
800  * Demux_Seekable: reads and demuxes data packets for stream seekable
801  *****************************************************************************
802  * AVIDemux: reads and demuxes data packets
803  *****************************************************************************
804  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
805  *****************************************************************************/
806 typedef struct
807 {
808     bool b_ok;
809
810     int i_toread;
811
812     off_t i_posf; /* where we will read :
813                    if i_idxposb == 0 : begining of chunk (+8 to acces data)
814                    else : point on data directly */
815 } avi_track_toread_t;
816
817 static int Demux_Seekable( demux_t *p_demux )
818 {
819     demux_sys_t *p_sys = p_demux->p_sys;
820
821     unsigned int i_track_count = 0;
822     unsigned int i_track;
823     bool b_stream;
824     /* cannot be more than 100 stream (dcXX or wbXX) */
825     avi_track_toread_t toread[100];
826
827
828     /* detect new selected/unselected streams */
829     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
830     {
831         avi_track_t *tk = p_sys->track[i_track];
832         bool  b;
833
834         if( p_sys->b_muxed && tk->p_out_muxed )
835         {
836             i_track_count++;
837             tk->b_activated = true;
838             continue;
839         }
840
841         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
842         if( b && !tk->b_activated )
843         {
844             if( p_sys->b_seekable)
845             {
846                 AVI_TrackSeek( p_demux, i_track, p_sys->i_time );
847             }
848             tk->b_activated = true;
849         }
850         else if( !b && tk->b_activated )
851         {
852             tk->b_activated = false;
853         }
854         if( b )
855         {
856             i_track_count++;
857         }
858     }
859
860     if( i_track_count <= 0 )
861     {
862         int64_t i_length = p_sys->i_length * (mtime_t)1000000;
863
864         p_sys->i_time += 25*1000;  /* read 25ms */
865         if( i_length > 0 )
866         {
867             if( p_sys->i_time >= i_length )
868                 return 0;
869             return 1;
870         }
871         msg_Warn( p_demux, "no track selected, exiting..." );
872         return 0;
873     }
874
875     /* wait for the good time */
876     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time + 1 );
877     p_sys->i_time += 25*1000;  /* read 25ms */
878
879     /* init toread */
880     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
881     {
882         avi_track_t *tk = p_sys->track[i_track];
883         mtime_t i_dpts;
884
885         toread[i_track].b_ok = tk->b_activated && !tk->b_eof;
886         if( tk->i_idxposc < tk->i_idxnb )
887         {
888             toread[i_track].i_posf = tk->p_index[tk->i_idxposc].i_pos;
889            if( tk->i_idxposb > 0 )
890            {
891                 toread[i_track].i_posf += 8 + tk->i_idxposb;
892            }
893         }
894         else
895         {
896             toread[i_track].i_posf = -1;
897         }
898
899         i_dpts = p_sys->i_time - AVI_GetPTS( tk  );
900
901         if( tk->i_samplesize )
902         {
903             toread[i_track].i_toread = AVI_PTSToByte( tk, __ABS( i_dpts ) );
904         }
905         else
906         {
907             toread[i_track].i_toread = AVI_PTSToChunk( tk, __ABS( i_dpts ) );
908         }
909
910         if( i_dpts < 0 )
911         {
912             toread[i_track].i_toread *= -1;
913         }
914     }
915
916     b_stream = false;
917
918     for( ;; )
919     {
920         avi_track_t     *tk;
921         bool       b_done;
922         block_t         *p_frame;
923         off_t i_pos;
924         unsigned int i;
925         size_t i_size;
926
927         /* search for first chunk to be read */
928         for( i = 0, b_done = true, i_pos = -1; i < p_sys->i_track; i++ )
929         {
930             if( !toread[i].b_ok ||
931                 AVI_GetDPTS( p_sys->track[i],
932                              toread[i].i_toread ) <= -25 * 1000 )
933             {
934                 continue;
935             }
936
937             if( toread[i].i_toread > 0 )
938             {
939                 b_done = false; /* not yet finished */
940             }
941             if( toread[i].i_posf > 0 )
942             {
943                 if( i_pos == -1 || i_pos > toread[i].i_posf )
944                 {
945                     i_track = i;
946                     i_pos = toread[i].i_posf;
947                 }
948             }
949         }
950
951         if( b_done )
952         {
953             for( i = 0; i < p_sys->i_track; i++ )
954             {
955                 if( toread[i].b_ok )
956                     return 1;
957             }
958             msg_Warn( p_demux, "all tracks have failed, exiting..." );
959             return 0;
960         }
961
962         if( i_pos == -1 )
963         {
964             int i_loop_count = 0;
965
966             /* no valid index, we will parse directly the stream
967              * in case we fail we will disable all finished stream */
968             if( p_sys->i_movi_lastchunk_pos >= p_sys->i_movi_begin + 12 )
969             {
970                 stream_Seek( p_demux->s, p_sys->i_movi_lastchunk_pos );
971                 if( AVI_PacketNext( p_demux ) )
972                 {
973                     return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
974                 }
975             }
976             else
977             {
978                 stream_Seek( p_demux->s, p_sys->i_movi_begin + 12 );
979             }
980
981             for( ;; )
982             {
983                 avi_packet_t avi_pk;
984
985                 if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
986                 {
987                     msg_Warn( p_demux,
988                              "cannot get packet header, track disabled" );
989                     return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
990                 }
991                 if( avi_pk.i_stream >= p_sys->i_track ||
992                     ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
993                 {
994                     if( AVI_PacketNext( p_demux ) )
995                     {
996                         msg_Warn( p_demux,
997                                   "cannot skip packet, track disabled" );
998                         return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
999                     }
1000
1001                     /* Prevents from eating all the CPU with broken files.
1002                      * This value should be low enough so that it doesn't
1003                      * affect the reading speed too much. */
1004                     if( !(++i_loop_count % 1024) )
1005                     {
1006                         if( !vlc_object_alive (p_demux) ) return -1;
1007                         msleep( 10000 );
1008
1009                         if( !(i_loop_count % (1024 * 10)) )
1010                             msg_Warn( p_demux,
1011                                       "don't seem to find any data..." );
1012                     }
1013                     continue;
1014                 }
1015                 else
1016                 {
1017                     /* add this chunk to the index */
1018                     avi_entry_t index;
1019
1020                     index.i_id = avi_pk.i_fourcc;
1021                     index.i_flags =
1022                        AVI_GetKeyFlag(p_sys->track[avi_pk.i_stream]->i_codec,
1023                                       avi_pk.i_peek);
1024                     index.i_pos = avi_pk.i_pos;
1025                     index.i_length = avi_pk.i_size;
1026                     AVI_IndexAddEntry( p_sys, avi_pk.i_stream, &index );
1027
1028                     i_track = avi_pk.i_stream;
1029                     tk = p_sys->track[i_track];
1030                     /* do we will read this data ? */
1031                     if( AVI_GetDPTS( tk, toread[i_track].i_toread ) > -25*1000 )
1032                     {
1033                         break;
1034                     }
1035                     else
1036                     {
1037                         if( AVI_PacketNext( p_demux ) )
1038                         {
1039                             msg_Warn( p_demux,
1040                                       "cannot skip packet, track disabled" );
1041                             return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
1042                         }
1043                     }
1044                 }
1045             }
1046
1047         }
1048         else
1049         {
1050             stream_Seek( p_demux->s, i_pos );
1051         }
1052
1053         /* Set the track to use */
1054         tk = p_sys->track[i_track];
1055
1056         /* read thoses data */
1057         if( tk->i_samplesize )
1058         {
1059             unsigned int i_toread;
1060
1061             if( ( i_toread = toread[i_track].i_toread ) <= 0 )
1062             {
1063                 if( tk->i_samplesize > 1 )
1064                 {
1065                     i_toread = tk->i_samplesize;
1066                 }
1067                 else
1068                 {
1069                     i_toread = AVI_PTSToByte( tk, 20 * 1000 );
1070                     i_toread = __MAX( i_toread, 100 );
1071                 }
1072             }
1073             i_size = __MIN( tk->p_index[tk->i_idxposc].i_length -
1074                                 tk->i_idxposb,
1075                             i_toread );
1076         }
1077         else
1078         {
1079             i_size = tk->p_index[tk->i_idxposc].i_length;
1080         }
1081
1082         if( tk->i_idxposb == 0 )
1083         {
1084             i_size += 8; /* need to read and skip header */
1085         }
1086
1087         if( ( p_frame = stream_Block( p_demux->s, __EVEN( i_size ) ) )==NULL )
1088         {
1089             msg_Warn( p_demux, "failed reading data" );
1090             tk->b_eof = false;
1091             toread[i_track].b_ok = false;
1092             continue;
1093         }
1094         if( i_size % 2 )    /* read was padded on word boundary */
1095         {
1096             p_frame->i_buffer--;
1097         }
1098         /* skip header */
1099         if( tk->i_idxposb == 0 )
1100         {
1101             p_frame->p_buffer += 8;
1102             p_frame->i_buffer -= 8;
1103         }
1104         p_frame->i_pts = AVI_GetPTS( tk ) + 1;
1105         if( tk->p_index[tk->i_idxposc].i_flags&AVIIF_KEYFRAME )
1106         {
1107             p_frame->i_flags = BLOCK_FLAG_TYPE_I;
1108         }
1109         else
1110         {
1111             p_frame->i_flags = BLOCK_FLAG_TYPE_PB;
1112         }
1113
1114         /* read data */
1115         if( tk->i_samplesize )
1116         {
1117             if( tk->i_idxposb == 0 )
1118             {
1119                 i_size -= 8;
1120             }
1121             toread[i_track].i_toread -= i_size;
1122             tk->i_idxposb += i_size;
1123             if( tk->i_idxposb >=
1124                     tk->p_index[tk->i_idxposc].i_length )
1125             {
1126                 tk->i_idxposb = 0;
1127                 tk->i_idxposc++;
1128             }
1129         }
1130         else
1131         {
1132             int i_length = tk->p_index[tk->i_idxposc].i_length;
1133
1134             tk->i_idxposc++;
1135             if( tk->i_cat == AUDIO_ES )
1136             {
1137                 tk->i_blockno += tk->i_blocksize > 0 ? ( i_length + tk->i_blocksize - 1 ) / tk->i_blocksize : 1;
1138             }
1139             toread[i_track].i_toread--;
1140         }
1141
1142         if( tk->i_idxposc < tk->i_idxnb)
1143         {
1144             toread[i_track].i_posf =
1145                 tk->p_index[tk->i_idxposc].i_pos;
1146             if( tk->i_idxposb > 0 )
1147             {
1148                 toread[i_track].i_posf += 8 + tk->i_idxposb;
1149             }
1150
1151         }
1152         else
1153         {
1154             toread[i_track].i_posf = -1;
1155         }
1156
1157         b_stream = true; /* at least one read succeed */
1158
1159         if( tk->i_cat != VIDEO_ES )
1160             p_frame->i_dts = p_frame->i_pts;
1161         else
1162         {
1163             p_frame->i_dts = p_frame->i_pts;
1164             p_frame->i_pts = 0;
1165         }
1166
1167         //p_pes->i_rate = p_demux->stream.control.i_rate;
1168         if( tk->p_out_muxed )
1169             stream_DemuxSend( tk->p_out_muxed, p_frame );
1170         else
1171             es_out_Send( p_demux->out, tk->p_es, p_frame );
1172     }
1173 }
1174
1175
1176 /*****************************************************************************
1177  * Demux_UnSeekable: reads and demuxes data packets for unseekable file
1178  *****************************************************************************
1179  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1180  *****************************************************************************/
1181 static int Demux_UnSeekable( demux_t *p_demux )
1182 {
1183     demux_sys_t     *p_sys = p_demux->p_sys;
1184     avi_track_t *p_stream_master = NULL;
1185     unsigned int i_stream;
1186     unsigned int i_packet;
1187
1188     if( p_sys->b_muxed )
1189     {
1190         msg_Err( p_demux, "Can not yet process muxed avi substreams without seeking" );
1191         return VLC_EGENERIC;
1192     }
1193
1194     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time + 1 );
1195
1196     /* *** find master stream for data packet skipping algo *** */
1197     /* *** -> first video, if any, or first audio ES *** */
1198     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
1199     {
1200         avi_track_t *tk = p_sys->track[i_stream];
1201         bool  b;
1202
1203         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
1204
1205         if( b && tk->i_cat == VIDEO_ES )
1206         {
1207             p_stream_master = tk;
1208         }
1209         else if( b )
1210         {
1211             p_stream_master = tk;
1212         }
1213     }
1214
1215     if( !p_stream_master )
1216     {
1217         msg_Warn( p_demux, "no more stream selected" );
1218         return( 0 );
1219     }
1220
1221     p_sys->i_time = AVI_GetPTS( p_stream_master );
1222
1223     for( i_packet = 0; i_packet < 10; i_packet++)
1224     {
1225 #define p_stream    p_sys->track[avi_pk.i_stream]
1226
1227         avi_packet_t    avi_pk;
1228
1229         if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
1230         {
1231             return( 0 );
1232         }
1233
1234         if( avi_pk.i_stream >= p_sys->i_track ||
1235             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
1236         {
1237             /* we haven't found an audio or video packet:
1238              *  - we have seek, found first next packet
1239              *  - others packets could be found, skip them
1240              */
1241             switch( avi_pk.i_fourcc )
1242             {
1243                 case AVIFOURCC_JUNK:
1244                 case AVIFOURCC_LIST:
1245                 case AVIFOURCC_RIFF:
1246                     return( !AVI_PacketNext( p_demux ) ? 1 : 0 );
1247                 case AVIFOURCC_idx1:
1248                     if( p_sys->b_odml )
1249                     {
1250                         return( !AVI_PacketNext( p_demux ) ? 1 : 0 );
1251                     }
1252                     return( 0 );    /* eof */
1253                 default:
1254                     msg_Warn( p_demux,
1255                               "seems to have lost position, resync" );
1256                     if( AVI_PacketSearch( p_demux ) )
1257                     {
1258                         msg_Err( p_demux, "resync failed" );
1259                         return( -1 );
1260                     }
1261             }
1262         }
1263         else
1264         {
1265             /* check for time */
1266             if( __ABS( AVI_GetPTS( p_stream ) -
1267                         AVI_GetPTS( p_stream_master ) )< 600*1000 )
1268             {
1269                 /* load it and send to decoder */
1270                 block_t *p_frame;
1271                 if( AVI_PacketRead( p_demux, &avi_pk, &p_frame ) || p_frame == NULL )
1272                 {
1273                     return( -1 );
1274                 }
1275                 p_frame->i_pts = AVI_GetPTS( p_stream ) + 1;
1276
1277                 if( avi_pk.i_cat != VIDEO_ES )
1278                     p_frame->i_dts = p_frame->i_pts;
1279                 else
1280                 {
1281                     p_frame->i_dts = p_frame->i_pts;
1282                     p_frame->i_pts = 0;
1283                 }
1284
1285                 //p_pes->i_rate = p_demux->stream.control.i_rate;
1286                 es_out_Send( p_demux->out, p_stream->p_es, p_frame );
1287             }
1288             else
1289             {
1290                 if( AVI_PacketNext( p_demux ) )
1291                 {
1292                     return( 0 );
1293                 }
1294             }
1295
1296             /* *** update stream time position *** */
1297             if( p_stream->i_samplesize )
1298             {
1299                 p_stream->i_idxposb += avi_pk.i_size;
1300             }
1301             else
1302             {
1303                 if( p_stream->i_cat == AUDIO_ES )
1304                 {
1305                     p_stream->i_blockno += p_stream->i_blocksize > 0 ? ( avi_pk.i_size + p_stream->i_blocksize - 1 ) / p_stream->i_blocksize : 1;
1306                 }
1307                 p_stream->i_idxposc++;
1308             }
1309
1310         }
1311 #undef p_stream
1312     }
1313
1314     return( 1 );
1315 }
1316
1317 /*****************************************************************************
1318  * Seek: goto to i_date or i_percent
1319  *****************************************************************************/
1320 static int Seek( demux_t *p_demux, mtime_t i_date, int i_percent )
1321 {
1322
1323     demux_sys_t *p_sys = p_demux->p_sys;
1324     unsigned int i_stream;
1325     msg_Dbg( p_demux, "seek requested: %"PRId64" seconds %d%%",
1326              i_date / 1000000, i_percent );
1327
1328     if( p_sys->b_seekable )
1329     {
1330         if( !p_sys->i_length )
1331         {
1332             avi_track_t *p_stream;
1333             int64_t i_pos;
1334
1335             /* use i_percent to create a true i_date */
1336             msg_Warn( p_demux, "seeking without index at %d%%"
1337                       " only works for interleaved files", i_percent );
1338             if( i_percent >= 100 )
1339             {
1340                 msg_Warn( p_demux, "cannot seek so far !" );
1341                 return VLC_EGENERIC;
1342             }
1343             i_percent = __MAX( i_percent, 0 );
1344
1345             /* try to find chunk that is at i_percent or the file */
1346             i_pos = __MAX( i_percent * stream_Size( p_demux->s ) / 100,
1347                            p_sys->i_movi_begin );
1348             /* search first selected stream (and prefer non eof ones) */
1349             for( i_stream = 0, p_stream = NULL;
1350                         i_stream < p_sys->i_track; i_stream++ )
1351             {
1352                 if( !p_stream || p_stream->b_eof )
1353                     p_stream = p_sys->track[i_stream];
1354
1355                 if( p_stream->b_activated && !p_stream->b_eof )
1356                     break;
1357             }
1358             if( !p_stream || !p_stream->b_activated )
1359             {
1360                 msg_Warn( p_demux, "cannot find any selected stream" );
1361                 return VLC_EGENERIC;
1362             }
1363
1364             /* be sure that the index exist */
1365             if( AVI_StreamChunkSet( p_demux, i_stream, 0 ) )
1366             {
1367                 msg_Warn( p_demux, "cannot seek" );
1368                 return VLC_EGENERIC;
1369             }
1370
1371             while( i_pos >= p_stream->p_index[p_stream->i_idxposc].i_pos +
1372                p_stream->p_index[p_stream->i_idxposc].i_length + 8 )
1373             {
1374                 /* search after i_idxposc */
1375                 if( AVI_StreamChunkSet( p_demux,
1376                                         i_stream, p_stream->i_idxposc + 1 ) )
1377                 {
1378                     msg_Warn( p_demux, "cannot seek" );
1379                     return VLC_EGENERIC;
1380                 }
1381             }
1382
1383             i_date = AVI_GetPTS( p_stream );
1384             /* TODO better support for i_samplesize != 0 */
1385             msg_Dbg( p_demux, "estimate date %"PRId64, i_date );
1386         }
1387
1388         /* */
1389         for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
1390         {
1391             avi_track_t *p_stream = p_sys->track[i_stream];
1392
1393             if( !p_stream->b_activated )
1394                 continue;
1395
1396             p_stream->b_eof = AVI_TrackSeek( p_demux, i_stream, i_date ) != 0;
1397         }
1398         es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
1399         p_sys->i_time = i_date;
1400         msg_Dbg( p_demux, "seek: %"PRId64" seconds", p_sys->i_time /1000000 );
1401         return VLC_SUCCESS;
1402     }
1403     else
1404     {
1405         msg_Err( p_demux, "shouldn't yet be executed" );
1406         return VLC_EGENERIC;
1407     }
1408 }
1409
1410 /*****************************************************************************
1411  * Control:
1412  *****************************************************************************/
1413 static double ControlGetPosition( demux_t *p_demux )
1414 {
1415     demux_sys_t *p_sys = p_demux->p_sys;
1416
1417     if( p_sys->i_length > 0 )
1418     {
1419         return (double)p_sys->i_time / (double)( p_sys->i_length * (mtime_t)1000000 );
1420     }
1421     else if( stream_Size( p_demux->s ) > 0 )
1422     {
1423         unsigned int i;
1424         int64_t i_tmp;
1425         int64_t i64 = 0;
1426
1427         /* search the more advanced selected es */
1428         for( i = 0; i < p_sys->i_track; i++ )
1429         {
1430             avi_track_t *tk = p_sys->track[i];
1431             if( tk->b_activated && tk->i_idxposc < tk->i_idxnb )
1432             {
1433                 i_tmp = tk->p_index[tk->i_idxposc].i_pos +
1434                         tk->p_index[tk->i_idxposc].i_length + 8;
1435                 if( i_tmp > i64 )
1436                 {
1437                     i64 = i_tmp;
1438                 }
1439             }
1440         }
1441         return (double)i64 / stream_Size( p_demux->s );
1442     }
1443     return 0.0;
1444 }
1445
1446 static int Control( demux_t *p_demux, int i_query, va_list args )
1447 {
1448     demux_sys_t *p_sys = p_demux->p_sys;
1449     int i;
1450     double   f, *pf;
1451     int64_t i64, *pi64;
1452     vlc_meta_t *p_meta;
1453
1454     switch( i_query )
1455     {
1456         case DEMUX_GET_POSITION:
1457             pf = (double*)va_arg( args, double * );
1458             *pf = ControlGetPosition( p_demux );
1459             return VLC_SUCCESS;
1460         case DEMUX_SET_POSITION:
1461             f = (double)va_arg( args, double );
1462             if( p_sys->b_seekable )
1463             {
1464                 i64 = (mtime_t)(1000000.0 * p_sys->i_length * f );
1465                 return Seek( p_demux, i64, (int)(f * 100) );
1466             }
1467             else
1468             {
1469                 int64_t i_pos = stream_Size( p_demux->s ) * f;
1470                 return stream_Seek( p_demux->s, i_pos );
1471             }
1472
1473         case DEMUX_GET_TIME:
1474             pi64 = (int64_t*)va_arg( args, int64_t * );
1475             *pi64 = p_sys->i_time;
1476             return VLC_SUCCESS;
1477
1478         case DEMUX_SET_TIME:
1479         {
1480             int i_percent = 0;
1481
1482             i64 = (int64_t)va_arg( args, int64_t );
1483             if( p_sys->i_length > 0 )
1484             {
1485                 i_percent = 100 * i64 / (p_sys->i_length*1000000);
1486             }
1487             else if( p_sys->i_time > 0 )
1488             {
1489                 i_percent = (int)( 100.0 * ControlGetPosition( p_demux ) *
1490                                    (double)i64 / (double)p_sys->i_time );
1491             }
1492             return Seek( p_demux, i64, i_percent );
1493         }
1494         case DEMUX_GET_LENGTH:
1495             pi64 = (int64_t*)va_arg( args, int64_t * );
1496             *pi64 = p_sys->i_length * (mtime_t)1000000;
1497             return VLC_SUCCESS;
1498
1499         case DEMUX_GET_FPS:
1500             pf = (double*)va_arg( args, double * );
1501             *pf = 0.0;
1502             for( i = 0; i < (int)p_sys->i_track; i++ )
1503             {
1504                 avi_track_t *tk = p_sys->track[i];
1505                 if( tk->i_cat == VIDEO_ES && tk->i_scale > 0)
1506                 {
1507                     *pf = (float)tk->i_rate / (float)tk->i_scale;
1508                     break;
1509                 }
1510             }
1511             return VLC_SUCCESS;
1512         case DEMUX_GET_META:
1513             p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
1514             vlc_meta_Merge( p_meta,  p_sys->meta );
1515             return VLC_SUCCESS;
1516
1517         default:
1518             return VLC_EGENERIC;
1519     }
1520 }
1521
1522 /*****************************************************************************
1523  * Function to convert pts to chunk or byte
1524  *****************************************************************************/
1525
1526 static mtime_t AVI_PTSToChunk( avi_track_t *tk, mtime_t i_pts )
1527 {
1528     if( !tk->i_scale )
1529         return (mtime_t)0;
1530
1531     return (mtime_t)((int64_t)i_pts *
1532                      (int64_t)tk->i_rate /
1533                      (int64_t)tk->i_scale /
1534                      (int64_t)1000000 );
1535 }
1536 static mtime_t AVI_PTSToByte( avi_track_t *tk, mtime_t i_pts )
1537 {
1538     if( !tk->i_scale || !tk->i_samplesize )
1539         return (mtime_t)0;
1540
1541     return (mtime_t)((int64_t)i_pts *
1542                      (int64_t)tk->i_rate /
1543                      (int64_t)tk->i_scale /
1544                      (int64_t)1000000 *
1545                      (int64_t)tk->i_samplesize );
1546 }
1547
1548 static mtime_t AVI_GetDPTS( avi_track_t *tk, int64_t i_count )
1549 {
1550     mtime_t i_dpts = 0;
1551
1552     if( !tk->i_rate )
1553         return i_dpts;
1554
1555     i_dpts = (mtime_t)( (int64_t)1000000 *
1556                         (int64_t)i_count *
1557                         (int64_t)tk->i_scale /
1558                         (int64_t)tk->i_rate );
1559
1560     if( tk->i_samplesize )
1561     {
1562         return i_dpts / tk->i_samplesize;
1563     }
1564     return i_dpts;
1565 }
1566
1567 static mtime_t AVI_GetPTS( avi_track_t *tk )
1568 {
1569     if( tk->i_samplesize )
1570     {
1571         int64_t i_count = 0;
1572
1573         /* we need a valid entry we will emulate one */
1574         if( tk->i_idxposc == tk->i_idxnb )
1575         {
1576             if( tk->i_idxposc )
1577             {
1578                 /* use the last entry */
1579                 i_count = tk->p_index[tk->i_idxnb - 1].i_lengthtotal
1580                             + tk->p_index[tk->i_idxnb - 1].i_length;
1581             }
1582         }
1583         else
1584         {
1585             i_count = tk->p_index[tk->i_idxposc].i_lengthtotal;
1586         }
1587         return AVI_GetDPTS( tk, i_count + tk->i_idxposb );
1588     }
1589     else
1590     {
1591         if( tk->i_cat == AUDIO_ES )
1592         {
1593             return AVI_GetDPTS( tk, tk->i_blockno );
1594         }
1595         else
1596         {
1597             return AVI_GetDPTS( tk, tk->i_idxposc );
1598         }
1599     }
1600 }
1601
1602 static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream )
1603 {
1604     demux_sys_t *p_sys = p_demux->p_sys;
1605     avi_packet_t avi_pk;
1606     int i_loop_count = 0;
1607
1608     /* find first chunk of i_stream that isn't in index */
1609
1610     if( p_sys->i_movi_lastchunk_pos >= p_sys->i_movi_begin + 12 )
1611     {
1612         stream_Seek( p_demux->s, p_sys->i_movi_lastchunk_pos );
1613         if( AVI_PacketNext( p_demux ) )
1614         {
1615             return VLC_EGENERIC;
1616         }
1617     }
1618     else
1619     {
1620         stream_Seek( p_demux->s, p_sys->i_movi_begin + 12 );
1621     }
1622
1623     for( ;; )
1624     {
1625         if( !vlc_object_alive (p_demux) ) return VLC_EGENERIC;
1626
1627         if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
1628         {
1629             msg_Warn( p_demux, "cannot get packet header" );
1630             return VLC_EGENERIC;
1631         }
1632         if( avi_pk.i_stream >= p_sys->i_track ||
1633             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
1634         {
1635             if( AVI_PacketNext( p_demux ) )
1636             {
1637                 return VLC_EGENERIC;
1638             }
1639
1640             /* Prevents from eating all the CPU with broken files.
1641              * This value should be low enough so that it doesn't
1642              * affect the reading speed too much. */
1643             if( !(++i_loop_count % 1024) )
1644             {
1645                 if( !vlc_object_alive (p_demux) ) return VLC_EGENERIC;
1646                 msleep( 10000 );
1647
1648                 if( !(i_loop_count % (1024 * 10)) )
1649                     msg_Warn( p_demux, "don't seem to find any data..." );
1650             }
1651         }
1652         else
1653         {
1654             /* add this chunk to the index */
1655             avi_entry_t index;
1656
1657             index.i_id = avi_pk.i_fourcc;
1658             index.i_flags =
1659                AVI_GetKeyFlag(p_sys->track[avi_pk.i_stream]->i_codec,
1660                               avi_pk.i_peek);
1661             index.i_pos = avi_pk.i_pos;
1662             index.i_length = avi_pk.i_size;
1663             AVI_IndexAddEntry( p_sys, avi_pk.i_stream, &index );
1664
1665             if( avi_pk.i_stream == i_stream  )
1666             {
1667                 return VLC_SUCCESS;
1668             }
1669
1670             if( AVI_PacketNext( p_demux ) )
1671             {
1672                 return VLC_EGENERIC;
1673             }
1674         }
1675     }
1676 }
1677
1678 /* be sure that i_ck will be a valid index entry */
1679 static int AVI_StreamChunkSet( demux_t *p_demux, unsigned int i_stream,
1680                                unsigned int i_ck )
1681 {
1682     demux_sys_t *p_sys = p_demux->p_sys;
1683     avi_track_t *p_stream = p_sys->track[i_stream];
1684
1685     p_stream->i_idxposc = i_ck;
1686     p_stream->i_idxposb = 0;
1687
1688     if(  i_ck >= p_stream->i_idxnb )
1689     {
1690         p_stream->i_idxposc = p_stream->i_idxnb - 1;
1691         do
1692         {
1693             p_stream->i_idxposc++;
1694             if( AVI_StreamChunkFind( p_demux, i_stream ) )
1695             {
1696                 return VLC_EGENERIC;
1697             }
1698
1699         } while( p_stream->i_idxposc < i_ck );
1700     }
1701
1702     return VLC_SUCCESS;
1703 }
1704
1705 /* XXX FIXME up to now, we assume that all chunk are one after one */
1706 static int AVI_StreamBytesSet( demux_t    *p_demux,
1707                                unsigned int i_stream,
1708                                off_t   i_byte )
1709 {
1710     demux_sys_t *p_sys = p_demux->p_sys;
1711     avi_track_t *p_stream = p_sys->track[i_stream];
1712
1713     if( ( p_stream->i_idxnb > 0 )
1714         &&( i_byte < p_stream->p_index[p_stream->i_idxnb - 1].i_lengthtotal +
1715                 p_stream->p_index[p_stream->i_idxnb - 1].i_length ) )
1716     {
1717         /* index is valid to find the ck */
1718         /* uses dichototmie to be fast enougth */
1719         int i_idxposc = __MIN( p_stream->i_idxposc, p_stream->i_idxnb - 1 );
1720         int i_idxmax  = p_stream->i_idxnb;
1721         int i_idxmin  = 0;
1722         for( ;; )
1723         {
1724             if( p_stream->p_index[i_idxposc].i_lengthtotal > i_byte )
1725             {
1726                 i_idxmax  = i_idxposc ;
1727                 i_idxposc = ( i_idxmin + i_idxposc ) / 2 ;
1728             }
1729             else
1730             {
1731                 if( p_stream->p_index[i_idxposc].i_lengthtotal +
1732                         p_stream->p_index[i_idxposc].i_length <= i_byte)
1733                 {
1734                     i_idxmin  = i_idxposc ;
1735                     i_idxposc = (i_idxmax + i_idxposc ) / 2 ;
1736                 }
1737                 else
1738                 {
1739                     p_stream->i_idxposc = i_idxposc;
1740                     p_stream->i_idxposb = i_byte -
1741                             p_stream->p_index[i_idxposc].i_lengthtotal;
1742                     return VLC_SUCCESS;
1743                 }
1744             }
1745         }
1746
1747     }
1748     else
1749     {
1750         p_stream->i_idxposc = p_stream->i_idxnb - 1;
1751         p_stream->i_idxposb = 0;
1752         do
1753         {
1754             p_stream->i_idxposc++;
1755             if( AVI_StreamChunkFind( p_demux, i_stream ) )
1756             {
1757                 return VLC_EGENERIC;
1758             }
1759
1760         } while( p_stream->p_index[p_stream->i_idxposc].i_lengthtotal +
1761                     p_stream->p_index[p_stream->i_idxposc].i_length <= i_byte );
1762
1763         p_stream->i_idxposb = i_byte -
1764                        p_stream->p_index[p_stream->i_idxposc].i_lengthtotal;
1765         return VLC_SUCCESS;
1766     }
1767 }
1768
1769 static int AVI_TrackSeek( demux_t *p_demux,
1770                            int i_stream,
1771                            mtime_t i_date )
1772 {
1773     demux_sys_t  *p_sys = p_demux->p_sys;
1774     avi_track_t  *tk = p_sys->track[i_stream];
1775
1776 #define p_stream    p_sys->track[i_stream]
1777     mtime_t i_oldpts;
1778
1779     i_oldpts = AVI_GetPTS( p_stream );
1780
1781     if( !p_stream->i_samplesize )
1782     {
1783         if( AVI_StreamChunkSet( p_demux,
1784                                 i_stream,
1785                                 AVI_PTSToChunk( p_stream, i_date ) ) )
1786         {
1787             return VLC_EGENERIC;
1788         }
1789
1790         if( p_stream->i_cat == AUDIO_ES )
1791         {
1792             unsigned int i;
1793             tk->i_blockno = 0;
1794             for( i = 0; i < tk->i_idxposc; i++ )
1795             {
1796                 if( tk->i_blocksize > 0 )
1797                 {
1798                     tk->i_blockno += ( tk->p_index[i].i_length + tk->i_blocksize - 1 ) / tk->i_blocksize;
1799                 }
1800                 else
1801                 {
1802                     tk->i_blockno++;
1803                 }
1804             }
1805         }
1806
1807         msg_Dbg( p_demux,
1808                  "old:%"PRId64" %s new %"PRId64,
1809                  i_oldpts,
1810                  i_oldpts > i_date ? ">" : "<",
1811                  i_date );
1812
1813         if( p_stream->i_cat == VIDEO_ES )
1814         {
1815             /* search key frame */
1816             //if( i_date < i_oldpts || 1 )
1817             {
1818                 while( p_stream->i_idxposc > 0 &&
1819                    !( p_stream->p_index[p_stream->i_idxposc].i_flags &
1820                                                                 AVIIF_KEYFRAME ) )
1821                 {
1822                     if( AVI_StreamChunkSet( p_demux,
1823                                             i_stream,
1824                                             p_stream->i_idxposc - 1 ) )
1825                     {
1826                         return VLC_EGENERIC;
1827                     }
1828                 }
1829             }
1830 #if 0
1831             else
1832             {
1833                 while( p_stream->i_idxposc < p_stream->i_idxnb &&
1834                         !( p_stream->p_index[p_stream->i_idxposc].i_flags &
1835                                                                 AVIIF_KEYFRAME ) )
1836                 {
1837                     if( AVI_StreamChunkSet( p_demux,
1838                                             i_stream,
1839                                             p_stream->i_idxposc + 1 ) )
1840                     {
1841                         return VLC_EGENERIC;
1842                     }
1843                 }
1844             }
1845 #endif
1846         }
1847     }
1848     else
1849     {
1850         if( AVI_StreamBytesSet( p_demux,
1851                                 i_stream,
1852                                 AVI_PTSToByte( p_stream, i_date ) ) )
1853         {
1854             return VLC_EGENERIC;
1855         }
1856     }
1857     return VLC_SUCCESS;
1858 #undef p_stream
1859 }
1860
1861 /****************************************************************************
1862  * Return true if it's a key frame
1863  ****************************************************************************/
1864 static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc, uint8_t *p_byte )
1865 {
1866     switch( i_fourcc )
1867     {
1868         case VLC_CODEC_DIV1:
1869             /* we have:
1870              *  startcode:      0x00000100   32bits
1871              *  framenumber     ?             5bits
1872              *  piture type     0(I),1(P)     2bits
1873              */
1874             if( GetDWBE( p_byte ) != 0x00000100 )
1875             {
1876                 /* it's not an msmpegv1 stream, strange...*/
1877                 return AVIIF_KEYFRAME;
1878             }
1879             return p_byte[4] & 0x06 ? 0 : AVIIF_KEYFRAME;
1880
1881         case VLC_CODEC_DIV2:
1882         case VLC_CODEC_DIV3:
1883         case VLC_CODEC_WMV1:
1884             /* we have
1885              *  picture type    0(I),1(P)     2bits
1886              */
1887             return p_byte[0] & 0xC0 ? 0 : AVIIF_KEYFRAME;
1888         case VLC_CODEC_MP4V:
1889             /* we should find first occurrence of 0x000001b6 (32bits)
1890              *  startcode:      0x000001b6   32bits
1891              *  piture type     0(I),1(P)     2bits
1892              */
1893             if( GetDWBE( p_byte ) != 0x000001b6 )
1894             {
1895                 /* not true , need to find the first VOP header */
1896                 return AVIIF_KEYFRAME;
1897             }
1898             return p_byte[4] & 0xC0 ? 0 : AVIIF_KEYFRAME;
1899
1900         default:
1901             /* I can't do it, so say yes */
1902             return AVIIF_KEYFRAME;
1903     }
1904 }
1905
1906 vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t i_codec )
1907 {
1908     switch( i_cat )
1909     {
1910         case AUDIO_ES:
1911             wf_tag_to_fourcc( i_codec, &i_codec, NULL );
1912             return i_codec;
1913         case VIDEO_ES:
1914             return vlc_fourcc_GetCodec( i_cat, i_codec );
1915         default:
1916             return VLC_FOURCC( 'u', 'n', 'd', 'f' );
1917     }
1918 }
1919
1920 /****************************************************************************
1921  *
1922  ****************************************************************************/
1923 static void AVI_ParseStreamHeader( vlc_fourcc_t i_id,
1924                                    unsigned int *pi_number, unsigned int *pi_type )
1925 {
1926 #define SET_PTR( p, v ) if( p ) *(p) = (v);
1927     int c1, c2;
1928
1929     c1 = ((uint8_t *)&i_id)[0];
1930     c2 = ((uint8_t *)&i_id)[1];
1931
1932     if( c1 < '0' || c1 > '9' || c2 < '0' || c2 > '9' )
1933     {
1934         SET_PTR( pi_number, 100 ); /* > max stream number */
1935         SET_PTR( pi_type, UNKNOWN_ES );
1936     }
1937     else
1938     {
1939         SET_PTR( pi_number, (c1 - '0') * 10 + (c2 - '0' ) );
1940         switch( VLC_TWOCC( ((uint8_t *)&i_id)[2], ((uint8_t *)&i_id)[3] ) )
1941         {
1942             case AVITWOCC_wb:
1943                 SET_PTR( pi_type, AUDIO_ES );
1944                 break;
1945             case AVITWOCC_dc:
1946             case AVITWOCC_db:
1947             case AVITWOCC_AC:
1948                 SET_PTR( pi_type, VIDEO_ES );
1949                 break;
1950             default:
1951                 SET_PTR( pi_type, UNKNOWN_ES );
1952                 break;
1953         }
1954     }
1955 #undef SET_PTR
1956 }
1957
1958 /****************************************************************************
1959  *
1960  ****************************************************************************/
1961 static int AVI_PacketGetHeader( demux_t *p_demux, avi_packet_t *p_pk )
1962 {
1963     const uint8_t *p_peek;
1964
1965     if( stream_Peek( p_demux->s, &p_peek, 16 ) < 16 )
1966     {
1967         return VLC_EGENERIC;
1968     }
1969     p_pk->i_fourcc  = VLC_FOURCC( p_peek[0], p_peek[1], p_peek[2], p_peek[3] );
1970     p_pk->i_size    = GetDWLE( p_peek + 4 );
1971     p_pk->i_pos     = stream_Tell( p_demux->s );
1972     if( p_pk->i_fourcc == AVIFOURCC_LIST || p_pk->i_fourcc == AVIFOURCC_RIFF )
1973     {
1974         p_pk->i_type = VLC_FOURCC( p_peek[8],  p_peek[9],
1975                                    p_peek[10], p_peek[11] );
1976     }
1977     else
1978     {
1979         p_pk->i_type = 0;
1980     }
1981
1982     memcpy( p_pk->i_peek, p_peek + 8, 8 );
1983
1984     AVI_ParseStreamHeader( p_pk->i_fourcc, &p_pk->i_stream, &p_pk->i_cat );
1985     return VLC_SUCCESS;
1986 }
1987
1988 static int AVI_PacketNext( demux_t *p_demux )
1989 {
1990     avi_packet_t    avi_ck;
1991     int             i_skip = 0;
1992
1993     if( AVI_PacketGetHeader( p_demux, &avi_ck ) )
1994     {
1995         return VLC_EGENERIC;
1996     }
1997
1998     if( avi_ck.i_fourcc == AVIFOURCC_LIST &&
1999         ( avi_ck.i_type == AVIFOURCC_rec || avi_ck.i_type == AVIFOURCC_movi ) )
2000     {
2001         i_skip = 12;
2002     }
2003     else if( avi_ck.i_fourcc == AVIFOURCC_RIFF &&
2004              avi_ck.i_type == AVIFOURCC_AVIX )
2005     {
2006         i_skip = 24;
2007     }
2008     else
2009     {
2010         i_skip = __EVEN( avi_ck.i_size ) + 8;
2011     }
2012
2013     if( stream_Read( p_demux->s, NULL, i_skip ) != i_skip )
2014     {
2015         return VLC_EGENERIC;
2016     }
2017     return VLC_SUCCESS;
2018 }
2019
2020 static int AVI_PacketRead( demux_t   *p_demux,
2021                            avi_packet_t     *p_pk,
2022                            block_t          **pp_frame )
2023 {
2024     size_t i_size;
2025
2026     i_size = __EVEN( p_pk->i_size + 8 );
2027
2028     if( ( *pp_frame = stream_Block( p_demux->s, i_size ) ) == NULL )
2029     {
2030         return VLC_EGENERIC;
2031     }
2032     (*pp_frame)->p_buffer += 8;
2033     (*pp_frame)->i_buffer -= 8;
2034
2035     if( i_size != p_pk->i_size + 8 )
2036     {
2037         (*pp_frame)->i_buffer--;
2038     }
2039
2040     return VLC_SUCCESS;
2041 }
2042
2043 static int AVI_PacketSearch( demux_t *p_demux )
2044 {
2045     demux_sys_t     *p_sys = p_demux->p_sys;
2046     avi_packet_t    avi_pk;
2047     int             i_count = 0;
2048
2049     for( ;; )
2050     {
2051         if( stream_Read( p_demux->s, NULL, 1 ) != 1 )
2052         {
2053             return VLC_EGENERIC;
2054         }
2055         AVI_PacketGetHeader( p_demux, &avi_pk );
2056         if( avi_pk.i_stream < p_sys->i_track &&
2057             ( avi_pk.i_cat == AUDIO_ES || avi_pk.i_cat == VIDEO_ES ) )
2058         {
2059             return VLC_SUCCESS;
2060         }
2061         switch( avi_pk.i_fourcc )
2062         {
2063             case AVIFOURCC_JUNK:
2064             case AVIFOURCC_LIST:
2065             case AVIFOURCC_RIFF:
2066             case AVIFOURCC_idx1:
2067                 return VLC_SUCCESS;
2068         }
2069
2070         /* Prevents from eating all the CPU with broken files.
2071          * This value should be low enough so that it doesn't affect the
2072          * reading speed too much (not that we care much anyway because
2073          * this code is called only on broken files). */
2074         if( !(++i_count % 1024) )
2075         {
2076             if( !vlc_object_alive (p_demux) ) return VLC_EGENERIC;
2077
2078             msleep( 10000 );
2079             if( !(i_count % (1024 * 10)) )
2080                 msg_Warn( p_demux, "trying to resync..." );
2081         }
2082     }
2083 }
2084
2085 /****************************************************************************
2086  * Index stuff.
2087  ****************************************************************************/
2088 static void AVI_IndexAddEntry( demux_sys_t *p_sys,
2089                                int i_stream,
2090                                avi_entry_t *p_index)
2091 {
2092     avi_track_t *tk = p_sys->track[i_stream];
2093
2094     /* Update i_movi_lastchunk_pos */
2095     if( p_sys->i_movi_lastchunk_pos < p_index->i_pos )
2096     {
2097         p_sys->i_movi_lastchunk_pos = p_index->i_pos;
2098     }
2099
2100     /* add the entry */
2101     if( tk->i_idxnb >= tk->i_idxmax )
2102     {
2103         tk->i_idxmax += 16384;
2104         tk->p_index = realloc( tk->p_index,
2105                                tk->i_idxmax * sizeof( avi_entry_t ) );
2106         if( tk->p_index == NULL )
2107         {
2108             return;
2109         }
2110     }
2111     /* calculate cumulate length */
2112     if( tk->i_idxnb > 0 )
2113     {
2114         p_index->i_lengthtotal =
2115             tk->p_index[tk->i_idxnb - 1].i_length +
2116                 tk->p_index[tk->i_idxnb - 1].i_lengthtotal;
2117     }
2118     else
2119     {
2120         p_index->i_lengthtotal = 0;
2121     }
2122
2123     tk->p_index[tk->i_idxnb++] = *p_index;
2124 }
2125
2126 static int AVI_IndexLoad_idx1( demux_t *p_demux )
2127 {
2128     demux_sys_t *p_sys = p_demux->p_sys;
2129
2130     avi_chunk_list_t    *p_riff;
2131     avi_chunk_list_t    *p_movi;
2132     avi_chunk_idx1_t    *p_idx1;
2133
2134     unsigned int i_stream;
2135     unsigned int i_index;
2136     off_t        i_offset;
2137     unsigned int i;
2138
2139     bool b_keyset[100];
2140
2141     p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0);
2142     p_idx1 = AVI_ChunkFind( p_riff, AVIFOURCC_idx1, 0);
2143     p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
2144
2145     if( !p_idx1 )
2146     {
2147         msg_Warn( p_demux, "cannot find idx1 chunk, no index defined" );
2148         return VLC_EGENERIC;
2149     }
2150
2151     /* *** calculate offset *** */
2152     /* Well, avi is __SHIT__ so test more than one entry
2153      * (needed for some avi files) */
2154     i_offset = 0;
2155     for( i = 0; i < __MIN( p_idx1->i_entry_count, 10 ); i++ )
2156     {
2157         if( p_idx1->entry[i].i_pos < p_movi->i_chunk_pos )
2158         {
2159             i_offset = p_movi->i_chunk_pos + 8;
2160             break;
2161         }
2162     }
2163
2164     /* Reset b_keyset */
2165     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2166         b_keyset[i_stream] = false;
2167
2168     for( i_index = 0; i_index < p_idx1->i_entry_count; i_index++ )
2169     {
2170         unsigned int i_cat;
2171
2172         AVI_ParseStreamHeader( p_idx1->entry[i_index].i_fourcc,
2173                                &i_stream,
2174                                &i_cat );
2175         if( i_stream < p_sys->i_track &&
2176             i_cat == p_sys->track[i_stream]->i_cat )
2177         {
2178             avi_entry_t index;
2179             index.i_id      = p_idx1->entry[i_index].i_fourcc;
2180             index.i_flags   =
2181                 p_idx1->entry[i_index].i_flags&(~AVIIF_FIXKEYFRAME);
2182             index.i_pos     = p_idx1->entry[i_index].i_pos + i_offset;
2183             index.i_length  = p_idx1->entry[i_index].i_length;
2184             AVI_IndexAddEntry( p_sys, i_stream, &index );
2185
2186             if( index.i_flags&AVIIF_KEYFRAME )
2187                 b_keyset[i_stream] = true;
2188         }
2189     }
2190
2191     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2192     {
2193         if( !b_keyset[i_stream] )
2194         {
2195             avi_track_t *tk = p_sys->track[i_stream];
2196
2197             msg_Dbg( p_demux, "no key frame set for track %d", i_stream );
2198             for( i_index = 0; i_index < tk->i_idxnb; i_index++ )
2199                 tk->p_index[i_index].i_flags |= AVIIF_KEYFRAME;
2200         }
2201     }
2202     return VLC_SUCCESS;
2203 }
2204
2205 static void __Parse_indx( demux_t    *p_demux,
2206                           int               i_stream,
2207                           avi_chunk_indx_t  *p_indx )
2208 {
2209     demux_sys_t         *p_sys    = p_demux->p_sys;
2210     avi_entry_t     index;
2211     int32_t             i;
2212
2213     msg_Dbg( p_demux, "loading subindex(0x%x) %d entries", p_indx->i_indextype, p_indx->i_entriesinuse );
2214     if( p_indx->i_indexsubtype == 0 )
2215     {
2216         for( i = 0; i < p_indx->i_entriesinuse; i++ )
2217         {
2218             index.i_id      = p_indx->i_id;
2219             index.i_flags   = p_indx->idx.std[i].i_size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
2220             index.i_pos     = p_indx->i_baseoffset + p_indx->idx.std[i].i_offset - 8;
2221             index.i_length  = p_indx->idx.std[i].i_size&0x7fffffff;
2222
2223             AVI_IndexAddEntry( p_sys, i_stream, &index );
2224         }
2225     }
2226     else if( p_indx->i_indexsubtype == AVI_INDEX_2FIELD )
2227     {
2228         for( i = 0; i < p_indx->i_entriesinuse; i++ )
2229         {
2230             index.i_id      = p_indx->i_id;
2231             index.i_flags   = p_indx->idx.field[i].i_size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
2232             index.i_pos     = p_indx->i_baseoffset + p_indx->idx.field[i].i_offset - 8;
2233             index.i_length  = p_indx->idx.field[i].i_size;
2234
2235             AVI_IndexAddEntry( p_sys, i_stream, &index );
2236         }
2237     }
2238     else
2239     {
2240         msg_Warn( p_demux, "unknown subtype index(0x%x)", p_indx->i_indexsubtype );
2241     }
2242 }
2243
2244 static void AVI_IndexLoad_indx( demux_t *p_demux )
2245 {
2246     demux_sys_t         *p_sys = p_demux->p_sys;
2247     unsigned int        i_stream;
2248     int32_t             i;
2249
2250     avi_chunk_list_t    *p_riff;
2251     avi_chunk_list_t    *p_hdrl;
2252
2253     p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0);
2254     p_hdrl = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0 );
2255
2256     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2257     {
2258         avi_chunk_list_t    *p_strl;
2259         avi_chunk_indx_t    *p_indx;
2260
2261 #define p_stream  p_sys->track[i_stream]
2262         p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i_stream );
2263         p_indx = AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0 );
2264
2265         if( !p_indx )
2266         {
2267             msg_Warn( p_demux, "cannot find indx (misdetect/broken OpenDML "
2268                                "file?)" );
2269             continue;
2270         }
2271
2272         if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS )
2273         {
2274             __Parse_indx( p_demux, i_stream, p_indx );
2275         }
2276         else if( p_indx->i_indextype == AVI_INDEX_OF_INDEXES )
2277         {
2278             avi_chunk_t    ck_sub;
2279             for( i = 0; i < p_indx->i_entriesinuse; i++ )
2280             {
2281                 if( stream_Seek( p_demux->s, p_indx->idx.super[i].i_offset )||
2282                     AVI_ChunkRead( p_demux->s, &ck_sub, NULL  ) )
2283                 {
2284                     break;
2285                 }
2286                 __Parse_indx( p_demux, i_stream, &ck_sub.indx );
2287             }
2288         }
2289         else
2290         {
2291             msg_Warn( p_demux, "unknown type index(0x%x)", p_indx->i_indextype );
2292         }
2293 #undef p_stream
2294     }
2295 }
2296
2297 static void AVI_IndexLoad( demux_t *p_demux )
2298 {
2299     demux_sys_t *p_sys = p_demux->p_sys;
2300     unsigned int i_stream;
2301
2302     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2303     {
2304         p_sys->track[i_stream]->i_idxnb  = 0;
2305         p_sys->track[i_stream]->i_idxmax = 0;
2306         p_sys->track[i_stream]->p_index  = NULL;
2307     }
2308
2309     if( p_sys->b_odml )
2310     {
2311         AVI_IndexLoad_indx( p_demux );
2312     }
2313     else  if( AVI_IndexLoad_idx1( p_demux ) )
2314     {
2315         /* try indx if idx1 failed as some "normal" file have indx too */
2316         AVI_IndexLoad_indx( p_demux );
2317     }
2318
2319     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2320     {
2321         msg_Dbg( p_demux, "stream[%d] created %d index entries",
2322                 i_stream, p_sys->track[i_stream]->i_idxnb );
2323     }
2324 }
2325
2326 static void AVI_IndexCreate( demux_t *p_demux )
2327 {
2328     demux_sys_t *p_sys = p_demux->p_sys;
2329
2330     avi_chunk_list_t *p_riff;
2331     avi_chunk_list_t *p_movi;
2332
2333     unsigned int i_stream;
2334     off_t i_movi_end;
2335
2336     mtime_t i_dialog_update;
2337     dialog_progress_bar_t *p_dialog = NULL;
2338
2339     p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0);
2340     p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
2341
2342     if( !p_movi )
2343     {
2344         msg_Err( p_demux, "cannot find p_movi" );
2345         return;
2346     }
2347
2348     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2349     {
2350         p_sys->track[i_stream]->i_idxnb  = 0;
2351         p_sys->track[i_stream]->i_idxmax = 0;
2352         p_sys->track[i_stream]->p_index  = NULL;
2353     }
2354     i_movi_end = __MIN( (off_t)(p_movi->i_chunk_pos + p_movi->i_chunk_size),
2355                         stream_Size( p_demux->s ) );
2356
2357     stream_Seek( p_demux->s, p_movi->i_chunk_pos + 12 );
2358     msg_Warn( p_demux, "creating index from LIST-movi, will take time !" );
2359
2360
2361     /* Only show dialog if AVI is > 10MB */
2362     i_dialog_update = mdate();
2363     if( stream_Size( p_demux->s ) > 10000000 )
2364         p_dialog = dialog_ProgressCreate( p_demux, _("Fixing AVI Index..."),
2365                                        NULL, _("Cancel") );
2366
2367     for( ;; )
2368     {
2369         avi_packet_t pk;
2370
2371         if( !vlc_object_alive (p_demux) )
2372             break;
2373
2374         /* Don't update/check dialog too often */
2375         if( p_dialog && mdate() - i_dialog_update > 100000 )
2376         {
2377             if( dialog_ProgressCancelled( p_dialog ) )
2378                 break;
2379
2380             float f_pos = (float)stream_Tell( p_demux->s ) /
2381                           (float)stream_Size( p_demux->s );
2382             dialog_ProgressSet( p_dialog, NULL, f_pos );
2383
2384             i_dialog_update = mdate();
2385         }
2386
2387         if( AVI_PacketGetHeader( p_demux, &pk ) )
2388             break;
2389
2390         if( pk.i_stream < p_sys->i_track &&
2391             pk.i_cat == p_sys->track[pk.i_stream]->i_cat )
2392         {
2393             avi_entry_t index;
2394             index.i_id      = pk.i_fourcc;
2395             index.i_flags   =
2396                AVI_GetKeyFlag(p_sys->track[pk.i_stream]->i_codec, pk.i_peek);
2397             index.i_pos     = pk.i_pos;
2398             index.i_length  = pk.i_size;
2399             AVI_IndexAddEntry( p_sys, pk.i_stream, &index );
2400         }
2401         else
2402         {
2403             switch( pk.i_fourcc )
2404             {
2405             case AVIFOURCC_idx1:
2406                 if( p_sys->b_odml )
2407                 {
2408                     avi_chunk_list_t *p_sysx;
2409                     p_sysx = AVI_ChunkFind( &p_sys->ck_root,
2410                                             AVIFOURCC_RIFF, 1 );
2411
2412                     msg_Dbg( p_demux, "looking for new RIFF chunk" );
2413                     if( stream_Seek( p_demux->s, p_sysx->i_chunk_pos + 24 ) )
2414                         goto print_stat;
2415                     break;
2416                 }
2417                 goto print_stat;
2418
2419             case AVIFOURCC_RIFF:
2420                     msg_Dbg( p_demux, "new RIFF chunk found" );
2421                     break;
2422
2423             case AVIFOURCC_rec:
2424             case AVIFOURCC_JUNK:
2425                 break;
2426
2427             default:
2428                 msg_Warn( p_demux, "need resync, probably broken avi" );
2429                 if( AVI_PacketSearch( p_demux ) )
2430                 {
2431                     msg_Warn( p_demux, "lost sync, abord index creation" );
2432                     goto print_stat;
2433                 }
2434             }
2435         }
2436
2437         if( ( !p_sys->b_odml && pk.i_pos + pk.i_size >= i_movi_end ) ||
2438             AVI_PacketNext( p_demux ) )
2439         {
2440             break;
2441         }
2442     }
2443
2444 print_stat:
2445     if( p_dialog != NULL )
2446         dialog_ProgressDestroy( p_dialog );
2447
2448     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2449     {
2450         msg_Dbg( p_demux, "stream[%d] creating %d index entries",
2451                 i_stream, p_sys->track[i_stream]->i_idxnb );
2452     }
2453 }
2454
2455 /*****************************************************************************
2456  * Stream management
2457  *****************************************************************************/
2458 static int AVI_TrackStopFinishedStreams( demux_t *p_demux )
2459 {
2460     demux_sys_t *p_sys = p_demux->p_sys;
2461     unsigned int i;
2462     int b_end = true;
2463
2464     for( i = 0; i < p_sys->i_track; i++ )
2465     {
2466         avi_track_t *tk = p_sys->track[i];
2467         if( tk->i_idxposc >= tk->i_idxnb )
2468         {
2469             tk->b_eof = true;
2470         }
2471         else
2472         {
2473             b_end = false;
2474         }
2475     }
2476     return( b_end );
2477 }
2478
2479 /****************************************************************************
2480  * AVI_MovieGetLength give max streams length in second
2481  ****************************************************************************/
2482 static mtime_t  AVI_MovieGetLength( demux_t *p_demux )
2483 {
2484     demux_sys_t  *p_sys = p_demux->p_sys;
2485     mtime_t      i_maxlength = 0;
2486     unsigned int i;
2487
2488     for( i = 0; i < p_sys->i_track; i++ )
2489     {
2490         avi_track_t *tk = p_sys->track[i];
2491         mtime_t i_length;
2492
2493         /* fix length for each stream */
2494         if( tk->i_idxnb < 1 || !tk->p_index )
2495         {
2496             continue;
2497         }
2498
2499         if( tk->i_samplesize )
2500         {
2501             i_length = AVI_GetDPTS( tk,
2502                                     tk->p_index[tk->i_idxnb-1].i_lengthtotal +
2503                                         tk->p_index[tk->i_idxnb-1].i_length );
2504         }
2505         else
2506         {
2507             i_length = AVI_GetDPTS( tk, tk->i_idxnb );
2508         }
2509         i_length /= (mtime_t)1000000;    /* in seconds */
2510
2511         msg_Dbg( p_demux,
2512                  "stream[%d] length:%"PRId64" (based on index)",
2513                  i,
2514                  i_length );
2515         i_maxlength = __MAX( i_maxlength, i_length );
2516     }
2517
2518     return i_maxlength;
2519 }