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