aa8762f701a62f470c96aa5b616434d2cacbc3d8
[vlc.git] / modules / demux / avi / avi.c
1 /*****************************************************************************
2  * avi.c : AVI file Stream input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001-2009 VLC authors and VideoLAN
5  *
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * 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 #include <assert.h>
31 #include <ctype.h>
32 #include <limits.h>
33
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_demux.h>
37 #include <vlc_input.h>
38
39 #include <vlc_dialog.h>
40
41 #include <vlc_meta.h>
42 #include <vlc_codecs.h>
43 #include <vlc_charset.h>
44
45 #include "libavi.h"
46 #include "../rawdv.h"
47 #include "bitmapinfoheader.h"
48
49 /*****************************************************************************
50  * Module descriptor
51  *****************************************************************************/
52
53 #define INTERLEAVE_TEXT N_("Force interleaved method" )
54
55 #define INDEX_TEXT N_("Force index creation")
56 #define INDEX_LONGTEXT N_( \
57     "Recreate a index for the AVI file. Use this if your AVI file is damaged "\
58     "or incomplete (not seekable)." )
59
60 static int  Open ( vlc_object_t * );
61 static void Close( vlc_object_t * );
62
63 static const int pi_index[] = {0,1,2,3};
64
65 static const char *const ppsz_indexes[] = { N_("Ask for action"),
66                                             N_("Always fix"),
67                                             N_("Never fix"),
68                                             N_("Fix when necessary")};
69
70 vlc_module_begin ()
71     set_shortname( "AVI" )
72     set_description( N_("AVI demuxer") )
73     set_capability( "demux", 212 )
74     set_category( CAT_INPUT )
75     set_subcategory( SUBCAT_INPUT_DEMUX )
76     add_file_extension("avi")
77
78     add_bool( "avi-interleaved", false,
79               INTERLEAVE_TEXT, INTERLEAVE_TEXT, true )
80     add_integer( "avi-index", 0,
81               INDEX_TEXT, INDEX_LONGTEXT, false )
82         change_integer_list( pi_index, ppsz_indexes )
83
84     set_callbacks( Open, Close )
85 vlc_module_end ()
86
87 /*****************************************************************************
88  * Local prototypes
89  *****************************************************************************/
90 static int Control         ( demux_t *, int, va_list );
91 static int Seek            ( demux_t *, vlc_tick_t, double, bool );
92 static int Demux_Seekable  ( demux_t * );
93 static int Demux_UnSeekable( demux_t * );
94
95 static char *FromACP( const char *str )
96 {
97     return FromCharset(vlc_pgettext("GetACP", "CP1252"), str, strlen(str));
98 }
99
100 #define IGNORE_ES DATA_ES
101 #define READ_LENGTH                VLC_TICK_FROM_MS(25)
102 #define READ_LENGTH_NONINTERLEAVED VLC_TICK_FROM_MS(1500)
103
104 //#define AVI_DEBUG
105
106 typedef struct
107 {
108     vlc_fourcc_t i_fourcc;
109     uint64_t     i_pos;
110     uint32_t     i_size;
111     vlc_fourcc_t i_type;     /* only for AVIFOURCC_LIST */
112
113     uint8_t      i_peek[8];  /* first 8 bytes */
114
115     unsigned int i_stream;
116     enum es_format_category_e i_cat;
117 } avi_packet_t;
118
119
120 typedef struct
121 {
122     vlc_fourcc_t i_id;
123     uint32_t     i_flags;
124     uint64_t     i_pos;
125     uint32_t     i_length;
126     uint64_t     i_lengthtotal;
127
128 } avi_entry_t;
129
130 typedef struct
131 {
132     uint32_t        i_size;
133     uint32_t        i_max;
134     avi_entry_t     *p_entry;
135
136 } avi_index_t;
137 static void avi_index_Init( avi_index_t * );
138 static void avi_index_Clean( avi_index_t * );
139 static void avi_index_Append( avi_index_t *, uint64_t *, avi_entry_t * );
140
141 typedef struct
142 {
143     bool            b_activated;
144     bool            b_eof;
145
146     unsigned int    i_rate;
147     unsigned int    i_scale;
148     unsigned int    i_samplesize;
149
150     struct bitmapinfoheader_properties bihprops;
151
152     es_format_t     fmt;
153     es_out_id_t     *p_es;
154     int             i_next_block_flags;
155
156     int             i_dv_audio_rate;
157     es_out_id_t     *p_es_dv_audio;
158
159     /* Avi Index */
160     avi_index_t     idx;
161
162     unsigned int    i_idxposc;  /* numero of chunk */
163     unsigned int    i_idxposb;  /* byte in the current chunk */
164
165     /* For VBR audio only */
166     unsigned int    i_blockno;
167     unsigned int    i_blocksize;
168
169 } avi_track_t;
170
171 typedef struct
172 {
173     vlc_tick_t i_time;
174     vlc_tick_t i_length;
175
176     bool  b_interleaved;
177     bool  b_seekable;
178     bool  b_fastseekable;
179     bool  b_indexloaded; /* if we read indexes from end of file before starting */
180     vlc_tick_t i_read_increment;
181     uint32_t i_avih_flags;
182     avi_chunk_t ck_root;
183
184     bool  b_odml;
185
186     uint64_t i_movi_begin;
187     uint64_t i_movi_lastchunk_pos;   /* XXX position of last valid chunk */
188
189     /* number of streams and information */
190     unsigned int i_track;
191     avi_track_t  **track;
192
193     /* meta */
194     vlc_meta_t  *meta;
195
196     unsigned int       i_attachment;
197     input_attachment_t **attachment;
198 } demux_sys_t;
199
200 #define __EVEN(x) (((x) & 1) ? (x) + 1 : (x))
201
202 static int64_t AVI_PTSToChunk( avi_track_t *, vlc_tick_t i_pts );
203 static int64_t AVI_PTSToByte ( avi_track_t *, vlc_tick_t i_pts );
204 static vlc_tick_t AVI_GetDPTS   ( avi_track_t *, int64_t i_count );
205 static vlc_tick_t AVI_GetPTS    ( avi_track_t * );
206
207
208 static int AVI_StreamChunkFind( demux_t *, unsigned int i_stream );
209 static int AVI_StreamChunkSet ( demux_t *,
210                                 unsigned int i_stream, unsigned int i_ck );
211 static int AVI_StreamBytesSet ( demux_t *,
212                                 unsigned int i_stream, uint64_t i_byte );
213
214 vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t );
215 static int   AVI_GetKeyFlag    ( vlc_fourcc_t , uint8_t * );
216
217 static int AVI_PacketGetHeader( demux_t *, avi_packet_t *p_pk );
218 static int AVI_PacketNext     ( demux_t * );
219 static int AVI_PacketSearch   ( demux_t * );
220
221 static void AVI_IndexLoad    ( demux_t * );
222 static void AVI_IndexCreate  ( demux_t * );
223
224 static void AVI_ExtractSubtitle( demux_t *, unsigned int i_stream, avi_chunk_list_t *, avi_chunk_STRING_t * );
225
226 static void AVI_DvHandleAudio( demux_t *, avi_track_t *, block_t * );
227
228 static vlc_tick_t  AVI_MovieGetLength( demux_t * );
229
230 static void AVI_MetaLoad( demux_t *, avi_chunk_list_t *p_riff, avi_chunk_avih_t *p_avih );
231
232 /*****************************************************************************
233  * Stream management
234  *****************************************************************************/
235 static int        AVI_TrackSeek  ( demux_t *, int, vlc_tick_t );
236 static int        AVI_TrackStopFinishedStreams( demux_t *);
237
238 /* Remarks:
239  - For VBR mp3 stream:
240     count blocks by rounded-up chunksizes instead of chunks
241     we need full emulation of dshow avi demuxer bugs :(
242     fixes silly nandub-style a-v delaying in avi with vbr mp3...
243     (from mplayer 2002/08/02)
244  - to complete....
245  */
246
247 #define QNAP_HEADER_SIZE 56
248 static bool IsQNAPCodec(vlc_fourcc_t codec)
249 {
250     switch (codec)
251     {
252         case VLC_FOURCC('w', '2', '6', '4'):
253         case VLC_FOURCC('q', '2', '6', '4'):
254         case VLC_FOURCC('Q', '2', '6', '4'):
255         case VLC_FOURCC('w', 'M', 'P', '4'):
256         case VLC_FOURCC('q', 'M', 'P', '4'):
257         case VLC_FOURCC('Q', 'M', 'P', '4'):
258         case VLC_FOURCC('w', 'I', 'V', 'G'):
259         case VLC_FOURCC('q', 'I', 'V', 'G'):
260         case VLC_FOURCC('Q', 'I', 'V', 'G'):
261             return true;
262         default:
263             return false;
264     }
265 }
266
267 /*****************************************************************************
268  * Close: frees unused data
269  *****************************************************************************/
270 static void Close ( vlc_object_t * p_this )
271 {
272     demux_t *    p_demux = (demux_t *)p_this;
273     demux_sys_t *p_sys = p_demux->p_sys  ;
274
275     for( unsigned int i = 0; i < p_sys->i_track; i++ )
276     {
277         if( p_sys->track[i] )
278         {
279             es_format_Clean( &p_sys->track[i]->fmt );
280             avi_index_Clean( &p_sys->track[i]->idx );
281             free( p_sys->track[i] );
282         }
283     }
284     free( p_sys->track );
285
286     AVI_ChunkFreeRoot( p_demux->s, &p_sys->ck_root );
287     if( p_sys->meta )
288         vlc_meta_Delete( p_sys->meta );
289
290     for( unsigned i = 0; i < p_sys->i_attachment; i++)
291         vlc_input_attachment_Release(p_sys->attachment[i]);
292     free(p_sys->attachment);
293
294     free( p_sys );
295 }
296
297 /*****************************************************************************
298  * Open: check file and initializes AVI structures
299  *****************************************************************************/
300 static int Open( vlc_object_t * p_this )
301 {
302     demux_t  *p_demux = (demux_t *)p_this;
303     demux_sys_t     *p_sys;
304
305     bool       b_index = false, b_aborted = false;
306     int              i_do_index;
307
308     avi_chunk_list_t    *p_riff;
309     avi_chunk_list_t    *p_hdrl, *p_movi;
310     avi_chunk_avih_t    *p_avih;
311
312     unsigned int i_track;
313     unsigned int i_peeker;
314
315     const uint8_t *p_peek;
316
317     /* Is it an avi file ? */
318     if( vlc_stream_Peek( p_demux->s, &p_peek, 200 ) < 200 )
319         return VLC_EGENERIC;
320
321     for( i_peeker = 0; i_peeker < 188; i_peeker++ )
322     {
323         if( !strncmp( (char *)&p_peek[0], "RIFF", 4 ) && !strncmp( (char *)&p_peek[8], "AVI ", 4 ) )
324             break;
325         if( !strncmp( (char *)&p_peek[0], "ON2 ", 4 ) && !strncmp( (char *)&p_peek[8], "ON2f", 4 ) )
326             break;
327         p_peek++;
328     }
329     if( i_peeker == 188 )
330     {
331         return VLC_EGENERIC;
332     }
333
334     if( i_peeker > 0
335      && vlc_stream_Read( p_demux->s, NULL, i_peeker ) < i_peeker )
336         return VLC_EGENERIC;
337
338     /* Initialize input structures. */
339     p_sys = p_demux->p_sys = calloc( 1, sizeof(demux_sys_t) );
340     if( unlikely(!p_sys) )
341         return VLC_EGENERIC;
342     p_sys->b_odml   = false;
343     p_sys->meta     = NULL;
344     TAB_INIT(p_sys->i_track, p_sys->track);
345     TAB_INIT(p_sys->i_attachment, p_sys->attachment);
346
347     vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK,
348                         &p_sys->b_fastseekable );
349     vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &p_sys->b_seekable );
350
351     p_sys->b_interleaved = var_InheritBool( p_demux, "avi-interleaved" );
352
353     if( AVI_ChunkReadRoot( p_demux->s, &p_sys->ck_root ) )
354     {
355         msg_Err( p_demux, "avi module discarded (invalid file)" );
356         free(p_sys);
357         return VLC_EGENERIC;
358     }
359
360     if( AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF, true ) > 1 )
361     {
362         unsigned int i_count =
363             AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF, true );
364
365         msg_Warn( p_demux, "multiple riff -> OpenDML ?" );
366         for( unsigned i = 1; i < i_count; i++ )
367         {
368             avi_chunk_list_t *p_sysx;
369
370             p_sysx = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, i, true );
371             if( p_sysx && p_sysx->i_type == AVIFOURCC_AVIX )
372             {
373                 msg_Warn( p_demux, "detected OpenDML file" );
374                 p_sys->b_odml = true;
375                 break;
376             }
377         }
378     }
379
380     p_riff  = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true );
381     p_hdrl  = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0, true );
382     p_movi  = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0, true );
383     if( !p_movi )
384         p_movi  = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_movi, 0, true );
385
386     if( !p_hdrl || !p_movi )
387     {
388         msg_Err( p_demux, "invalid file: cannot find hdrl or movi chunks" );
389         goto error;
390     }
391
392     if( !( p_avih = AVI_ChunkFind( p_hdrl, AVIFOURCC_avih, 0, false ) ) )
393     {
394         msg_Err( p_demux, "invalid file: cannot find avih chunk" );
395         goto error;
396     }
397     i_track = AVI_ChunkCount( p_hdrl, AVIFOURCC_strl, true );
398     if( p_avih->i_streams != i_track )
399     {
400         msg_Warn( p_demux,
401                   "found %d stream but %d are declared",
402                   i_track, p_avih->i_streams );
403     }
404     if( i_track == 0 )
405     {
406         msg_Err( p_demux, "no stream defined!" );
407         goto error;
408     }
409
410     /* print information on streams */
411     msg_Dbg( p_demux, "AVIH: %d stream, flags %s%s%s%s ",
412              i_track,
413              p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
414              p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
415              p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
416              p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
417
418     p_sys->b_interleaved |= (p_avih->i_flags & AVIF_ISINTERLEAVED);
419
420     /* Set callbacks */
421     p_demux->pf_control = Control;
422
423     if( p_sys->b_fastseekable )
424     {
425         p_demux->pf_demux = Demux_Seekable;
426         p_sys->i_read_increment = READ_LENGTH;
427     }
428     else if( p_sys->b_seekable )
429     {
430         p_demux->pf_demux = Demux_Seekable;
431         p_sys->i_read_increment = READ_LENGTH_NONINTERLEAVED;
432         if( !p_sys->b_interleaved )
433             msg_Warn( p_demux, "Non interleaved content over slow seekable, "
434                                "expect bad performance" );
435     }
436     else
437     {
438         msg_Warn( p_demux, "Non seekable content " );
439
440         p_demux->pf_demux = Demux_UnSeekable;
441         p_sys->i_read_increment = READ_LENGTH_NONINTERLEAVED;
442          /* non seekable and non interleaved case ? well... */
443         if( !p_sys->b_interleaved )
444         {
445             msg_Warn( p_demux, "Non seekable non interleaved content, "
446                                "disabling other tracks" );
447             i_track = __MIN(i_track, 1);
448         }
449     }
450
451     AVI_MetaLoad( p_demux, p_riff, p_avih );
452     p_sys->i_avih_flags = p_avih->i_flags;
453
454     /* now read info on each stream and create ES */
455     for( unsigned i = 0 ; i < i_track; i++ )
456     {
457         avi_track_t           *tk     = calloc( 1, sizeof( avi_track_t ) );
458         if( unlikely( !tk ) )
459             goto error;
460
461         avi_chunk_list_t      *p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i, true );
462         avi_chunk_strh_t      *p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0, false );
463         avi_chunk_STRING_t    *p_strn = AVI_ChunkFind( p_strl, AVIFOURCC_strn, 0, false );
464         avi_chunk_strf_auds_t *p_auds = NULL;
465         avi_chunk_strf_vids_t *p_vids = NULL;
466
467         tk->b_eof = false;
468         tk->b_activated = true;
469
470         p_vids = (avi_chunk_strf_vids_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0, false );
471         p_auds = (avi_chunk_strf_auds_t*)p_vids;
472
473         if( p_strl == NULL || p_strh == NULL || p_vids == NULL )
474         {
475             msg_Warn( p_demux, "stream[%d] incomplete", i );
476             free( tk );
477             continue;
478         }
479
480         tk->i_rate  = p_strh->i_rate;
481         tk->i_scale = p_strh->i_scale;
482         tk->i_samplesize = p_strh->i_samplesize;
483         msg_Dbg( p_demux, "stream[%u] rate:%u scale:%u samplesize:%u",
484                 i, tk->i_rate, tk->i_scale, tk->i_samplesize );
485         if( !tk->i_scale || !tk->i_rate || !(tk->i_rate * CLOCK_FREQ / tk->i_scale) )
486         {
487             free( tk );
488             continue;
489         }
490
491         switch( p_strh->i_type )
492         {
493             case( AVIFOURCC_auds ):
494             {
495                 es_format_Init( &tk->fmt, AUDIO_ES, 0 );
496
497                 if( p_auds->p_wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
498                     p_auds->p_wf->cbSize >= sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX) )
499                 {
500                     WAVEFORMATEXTENSIBLE *p_wfe = (WAVEFORMATEXTENSIBLE *)p_auds->p_wf;
501                     tk->fmt.i_codec = AVI_FourccGetCodec( AUDIO_ES, p_wfe->SubFormat.Data1 );
502                 }
503                 else
504                     tk->fmt.i_codec = AVI_FourccGetCodec( AUDIO_ES, p_auds->p_wf->wFormatTag );
505
506                 tk->i_blocksize = p_auds->p_wf->nBlockAlign;
507                 if( tk->i_blocksize == 0 )
508                 {
509                     if( p_auds->p_wf->wFormatTag == 1 )
510                         tk->i_blocksize = p_auds->p_wf->nChannels * (p_auds->p_wf->wBitsPerSample/8);
511                     else
512                         tk->i_blocksize = 1;
513                 }
514                 else if( tk->i_samplesize != 0 && tk->i_samplesize != tk->i_blocksize )
515                 {
516                     msg_Warn( p_demux, "track[%u] samplesize=%u and blocksize=%u are not equal."
517                                        "Using blocksize as a workaround.",
518                                        i, tk->i_samplesize, tk->i_blocksize );
519                     tk->i_samplesize = tk->i_blocksize;
520                 }
521
522                 /* fix VBR decoding */
523                 if( tk->fmt.i_codec == VLC_CODEC_VORBIS ||
524                     tk->fmt.i_codec == VLC_CODEC_FLAC )
525                 {
526                     tk->i_blocksize = 0;
527                 }
528
529                 if ( tk->fmt.i_codec == VLC_CODEC_MP4A )
530                 {
531                     tk->i_samplesize = 0; /* ADTS/AAC VBR */
532                 }
533
534                 /* Fix broken scale/rate */
535                 if ( tk->fmt.i_codec == VLC_CODEC_ADPCM_IMA_WAV &&
536                      tk->i_samplesize && tk->i_samplesize > tk->i_rate )
537                 {
538                     tk->i_scale = 1017;
539                     tk->i_rate = p_auds->p_wf->nSamplesPerSec;
540                 }
541
542                 /* From libavformat */
543                 /* Fix broken sample size (which is mp2 num samples / frame) #12722 */
544                 if( tk->fmt.i_codec == VLC_CODEC_MPGA &&
545                     tk->i_samplesize == 1152 && p_auds->p_wf->nBlockAlign == 1152 )
546                 {
547                     p_auds->p_wf->nBlockAlign = tk->i_samplesize = 0;
548                 }
549
550                 tk->fmt.audio.i_channels        = p_auds->p_wf->nChannels;
551                 tk->fmt.audio.i_rate            = p_auds->p_wf->nSamplesPerSec;
552                 tk->fmt.i_bitrate               = p_auds->p_wf->nAvgBytesPerSec*8;
553                 tk->fmt.audio.i_blockalign      = p_auds->p_wf->nBlockAlign;
554                 tk->fmt.audio.i_bitspersample   = p_auds->p_wf->wBitsPerSample;
555                 tk->fmt.b_packetized            = !tk->i_blocksize;
556
557                 avi_chunk_list_t *p_info = AVI_ChunkFind( p_riff, AVIFOURCC_INFO, 0, true );
558                 if( p_info )
559                 {
560                     int i_chunk = AVIFOURCC_IAS1 + ((i - 1) << 24);
561                     avi_chunk_STRING_t *p_lang = AVI_ChunkFind( p_info, i_chunk, 0, false );
562                     if( p_lang != NULL && p_lang->p_str != NULL )
563                         tk->fmt.psz_language = FromACP( p_lang->p_str );
564                 }
565
566                 msg_Dbg( p_demux,
567                     "stream[%u] audio(0x%x - %s) %d channels %dHz %dbits",
568                     i, p_auds->p_wf->wFormatTag,
569                     vlc_fourcc_GetDescription(AUDIO_ES, tk->fmt.i_codec),
570                     p_auds->p_wf->nChannels,
571                     p_auds->p_wf->nSamplesPerSec,
572                     p_auds->p_wf->wBitsPerSample );
573
574                 const size_t i_cboff = sizeof(WAVEFORMATEX);
575                 const size_t i_incboff = ( p_auds->p_wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE ) ?
576                                           sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX): 0;
577                 if( p_auds->i_chunk_size >= i_cboff + p_auds->p_wf->cbSize &&
578                     p_auds->p_wf->cbSize > i_incboff )
579                 {
580                     int i_extra = p_auds->p_wf->cbSize - i_incboff;
581                     tk->fmt.p_extra = malloc( i_extra );
582                     if( unlikely(tk->fmt.p_extra == NULL) )
583                     {
584                         es_format_Clean( &tk->fmt );
585                         free( tk );
586                         goto error;
587                     }
588                     tk->fmt.i_extra = i_extra;
589                     memcpy( tk->fmt.p_extra, ((uint8_t *)(&p_auds->p_wf[1])) + i_incboff, i_extra );
590                 }
591                 break;
592             }
593
594             case( AVIFOURCC_vids ):
595             {
596                 if( p_vids->p_bih->biCompression == VLC_FOURCC( 'D', 'X', 'S', 'B' ) )
597                 {
598                    msg_Dbg( p_demux, "stream[%u] subtitles", i );
599                    es_format_Init( &tk->fmt, SPU_ES, p_vids->p_bih->biCompression );
600                    break;
601                 }
602
603                 es_format_Init( &tk->fmt, VIDEO_ES,
604                         AVI_FourccGetCodec( VIDEO_ES, p_vids->p_bih->biCompression ) );
605
606                 if( ParseBitmapInfoHeader( p_vids->p_bih, p_vids->i_chunk_size, &tk->fmt,
607                                            &tk->bihprops ) != VLC_SUCCESS )
608                 {
609                     es_format_Clean( &tk->fmt );
610                     free( tk );
611                     goto error;
612                 }
613
614                 if( tk->fmt.i_codec == VLC_CODEC_MP4V &&
615                     !strncasecmp( (char*)&p_strh->i_handler, "XVID", 4 ) )
616                 {
617                     tk->fmt.i_codec           =
618                     tk->fmt.i_original_fourcc = VLC_FOURCC( 'X', 'V', 'I', 'D' );
619                 }
620
621                 if( IsQNAPCodec( tk->fmt.i_codec ) )
622                     tk->fmt.b_packetized = false;
623
624                 tk->i_samplesize = 0;
625                 tk->fmt.video.i_frame_rate = tk->i_rate;
626                 tk->fmt.video.i_frame_rate_base = tk->i_scale;
627
628                 avi_chunk_vprp_t *p_vprp = AVI_ChunkFind( p_strl, AVIFOURCC_vprp, 0, false );
629                 if( p_vprp )
630                 {
631                     uint32_t i_frame_aspect_ratio = p_vprp->i_frame_aspect_ratio;
632                     if( p_vprp->i_video_format_token >= 1 &&
633                         p_vprp->i_video_format_token <= 4 )
634                         i_frame_aspect_ratio = 0x00040003;
635                     tk->fmt.video.i_sar_num = ((i_frame_aspect_ratio >> 16) & 0xffff) *
636                                               tk->fmt.video.i_height;
637                     tk->fmt.video.i_sar_den = ((i_frame_aspect_ratio >>  0) & 0xffff) *
638                                               tk->fmt.video.i_width;
639                 }
640
641                 msg_Dbg( p_demux, "stream[%u] video(%4.4s) %"PRIu32"x%"PRIu32" %dbpp %ffps",
642                          i, (char*)&p_vids->p_bih->biCompression,
643                          p_vids->p_bih->biWidth,
644                          (p_vids->p_bih->biHeight <= INT_MAX) ? p_vids->p_bih->biHeight
645                                                               : -1 * p_vids->p_bih->biHeight,
646                          p_vids->p_bih->biBitCount,
647                          (float)tk->i_rate/(float)tk->i_scale );
648                 break;
649             }
650
651             case( AVIFOURCC_txts):
652                 msg_Dbg( p_demux, "stream[%u] subtitle attachment", i );
653                 AVI_ExtractSubtitle( p_demux, i, p_strl, p_strn );
654                 free( tk );
655                 continue;
656
657             case( AVIFOURCC_iavs):
658             case( AVIFOURCC_ivas):
659                 msg_Dbg( p_demux, "stream[%u] iavs with handler %4.4s", i, (char *)&p_strh->i_handler );
660                 es_format_Init( &tk->fmt, VIDEO_ES, AVI_FourccGetCodec( VIDEO_ES, p_strh->i_handler ) );
661                 tk->i_samplesize = 0;
662                 tk->i_dv_audio_rate = tk->fmt.i_codec == VLC_CODEC_DV ? -1 : 0;
663
664                 tk->fmt.video.i_visible_width =
665                 tk->fmt.video.i_width  = p_avih->i_width;
666                 tk->fmt.video.i_visible_height =
667                 tk->fmt.video.i_height = p_avih->i_height;
668                 break;
669
670             case( AVIFOURCC_mids):
671                 msg_Dbg( p_demux, "stream[%u] midi is UNSUPPORTED", i );
672                 /* fall through */
673
674             default:
675                 msg_Warn( p_demux, "stream[%u] unknown type %4.4s", i, (char *)&p_strh->i_type );
676                 free( tk );
677                 continue;
678         }
679         tk->fmt.i_id = i;
680         if( p_strn && p_strn->p_str )
681             tk->fmt.psz_description = FromACP( p_strn->p_str );
682         tk->p_es = es_out_Add( p_demux->out, &tk->fmt );
683         TAB_APPEND( p_sys->i_track, p_sys->track, tk );
684     }
685
686     if( p_sys->i_track <= 0 )
687     {
688         msg_Err( p_demux, "no valid track" );
689         goto error;
690     }
691
692     i_do_index = var_InheritInteger( p_demux, "avi-index" );
693     if( i_do_index == 1 ) /* Always fix */
694     {
695 aviindex:
696         if( p_sys->b_fastseekable )
697         {
698             AVI_IndexCreate( p_demux );
699         }
700         else if( p_sys->b_seekable )
701         {
702             AVI_IndexLoad( p_demux );
703         }
704         else
705         {
706             msg_Warn( p_demux, "cannot create index (unseekable stream)" );
707         }
708     }
709     else if( p_sys->b_seekable )
710     {
711         AVI_IndexLoad( p_demux );
712     }
713
714     /* *** movie length in vlc_tick_t *** */
715     p_sys->i_length = AVI_MovieGetLength( p_demux );
716
717     /* Check the index completeness */
718     unsigned int i_idx_totalframes = 0;
719     for( unsigned int i = 0; i < p_sys->i_track; i++ )
720     {
721         const avi_track_t *tk = p_sys->track[i];
722         if( tk->fmt.i_cat == VIDEO_ES && tk->idx.p_entry )
723             i_idx_totalframes = __MAX(i_idx_totalframes, tk->idx.i_size);
724     }
725     if( i_idx_totalframes != p_avih->i_totalframes &&
726         p_sys->i_length < VLC_TICK_FROM_US( p_avih->i_totalframes *
727                                             p_avih->i_microsecperframe ) )
728     {
729         msg_Warn( p_demux, "broken or missing index, 'seek' will be "
730                            "approximative or will exhibit strange behavior" );
731         if( (i_do_index == 0 || i_do_index == 3) && !b_index )
732         {
733             if( !p_sys->b_fastseekable ) {
734                 b_index = true;
735                 goto aviindex;
736             }
737             if( i_do_index == 0 )
738             {
739                 const char *psz_msg = _(
740                     "Because this file index is broken or missing, "
741                     "seeking will not work correctly.\n"
742                     "VLC won't repair your file but can temporary fix this "
743                     "problem by building an index in memory.\n"
744                     "This step might take a long time on a large file.\n"
745                     "What do you want to do?");
746                 switch( vlc_dialog_wait_question( p_demux,
747                                                   VLC_DIALOG_QUESTION_NORMAL,
748                                                   _("Do not play"),
749                                                   _("Build index then play"),
750                                                   _("Play as is"),
751                                                   _("Broken or missing Index"),
752                                                   "%s", psz_msg ) )
753                 {
754                     case 0:
755                         b_aborted = true;
756                         goto error;
757                     case 1:
758                         b_index = true;
759                         msg_Dbg( p_demux, "Fixing AVI index" );
760                         goto aviindex;
761                 }
762             }
763             else
764             {
765                 b_index = true;
766                 msg_Dbg( p_demux, "Fixing AVI index" );
767                 goto aviindex;
768             }
769         }
770     }
771
772     /* fix some BeOS MediaKit generated file */
773     for( unsigned i = 0 ; i < p_sys->i_track; i++ )
774     {
775         avi_track_t         *tk = p_sys->track[i];
776         avi_chunk_list_t    *p_strl;
777         avi_chunk_strf_auds_t    *p_auds;
778
779         if( tk->fmt.i_cat != AUDIO_ES )
780         {
781             continue;
782         }
783         if( tk->idx.i_size < 1 ||
784             tk->i_scale != 1 ||
785             tk->i_samplesize != 0 )
786         {
787             continue;
788         }
789         p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, tk->fmt.i_id, true );
790         p_auds = AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0, false );
791
792         if( p_auds &&
793             p_auds->p_wf->wFormatTag != WAVE_FORMAT_PCM &&
794             tk->i_rate == p_auds->p_wf->nSamplesPerSec )
795         {
796             int64_t i_track_length =
797                 tk->idx.p_entry[tk->idx.i_size-1].i_length +
798                 tk->idx.p_entry[tk->idx.i_size-1].i_lengthtotal;
799             vlc_tick_t i_length = VLC_TICK_FROM_US( p_avih->i_totalframes *
800                                                     p_avih->i_microsecperframe );
801
802             if( i_length == 0 )
803             {
804                 msg_Warn( p_demux, "track[%u] cannot be fixed (BeOS MediaKit generated)", i );
805                 continue;
806             }
807             tk->i_samplesize = 1;
808             tk->i_rate       = i_track_length  * CLOCK_FREQ / i_length;
809             msg_Warn( p_demux, "track[%u] fixed with rate=%u scale=%u (BeOS MediaKit generated)", i, tk->i_rate, tk->i_scale );
810         }
811     }
812
813     if( p_sys->b_seekable )
814     {
815         /* we have read all chunk so go back to movi */
816         if( vlc_stream_Seek( p_demux->s, p_movi->i_chunk_pos ) )
817             goto error;
818     }
819     /* Skip movi header */
820     if( vlc_stream_Read( p_demux->s, NULL, 12 ) < 12 )
821         goto error;
822
823     p_sys->i_movi_begin = p_movi->i_chunk_pos;
824     return VLC_SUCCESS;
825
826 error:
827     Close( p_this );
828     return b_aborted ? VLC_ETIMEOUT : VLC_EGENERIC;
829 }
830
831 /*****************************************************************************
832  * ReadFrame: Reads frame, using stride if necessary
833  *****************************************************************************/
834
835 static block_t * ReadFrame( demux_t *p_demux, const avi_track_t *tk,
836                      const unsigned int i_header, const int i_size )
837 {
838     block_t *p_frame = vlc_stream_Block( p_demux->s, __EVEN( i_size ) );
839     if ( !p_frame ) return p_frame;
840
841     if( i_size % 2 )    /* read was padded on word boundary */
842     {
843         p_frame->i_buffer--;
844     }
845
846     if( i_header >= p_frame->i_buffer || tk->bihprops.i_stride > INT32_MAX - 3 )
847     {
848         p_frame->i_buffer = 0;
849         return p_frame;
850     }
851
852     /* skip header */
853     p_frame->p_buffer += i_header;
854     p_frame->i_buffer -= i_header;
855
856     const unsigned int i_stride_bytes = (tk->bihprops.i_stride + 3) & ~3;
857
858     if ( !tk->bihprops.i_stride || !i_stride_bytes )
859         return p_frame;
860
861     if( p_frame->i_buffer < i_stride_bytes )
862     {
863         p_frame->i_buffer = 0;
864         return p_frame;
865     }
866
867     if( !tk->bihprops.b_flipped )
868     {
869         const uint8_t *p_src = p_frame->p_buffer + i_stride_bytes;
870         const uint8_t *p_end = p_frame->p_buffer + p_frame->i_buffer;
871         uint8_t *p_dst = p_frame->p_buffer + tk->bihprops.i_stride;
872
873         p_frame->i_buffer = tk->bihprops.i_stride;
874
875         while ( p_src + i_stride_bytes <= p_end )
876         {
877             memmove( p_dst, p_src, tk->bihprops.i_stride );
878             p_src += i_stride_bytes;
879             p_dst += tk->bihprops.i_stride;
880             p_frame->i_buffer += tk->bihprops.i_stride;
881         }
882     }
883     else
884     {
885         block_t *p_flippedframe = block_Alloc( p_frame->i_buffer );
886         if ( !p_flippedframe )
887         {
888             block_Release( p_frame );
889             return NULL;
890         }
891
892         unsigned int i_lines = p_frame->i_buffer / i_stride_bytes;
893         const uint8_t *p_src = p_frame->p_buffer + i_lines * i_stride_bytes;
894         uint8_t *p_dst = p_flippedframe->p_buffer;
895
896         p_flippedframe->i_buffer = 0;
897
898         while ( i_lines-- > 0 )
899         {
900             p_src -= i_stride_bytes;
901             memcpy( p_dst, p_src, tk->bihprops.i_stride );
902             p_dst += tk->bihprops.i_stride;
903             p_flippedframe->i_buffer += tk->bihprops.i_stride;
904         }
905
906         block_Release( p_frame );
907         p_frame = p_flippedframe;
908     }
909
910     return p_frame;
911 }
912
913 /*****************************************************************************
914  * SendFrame: Sends frame to ES and does payload processing
915  *****************************************************************************/
916 static void AVI_SendFrame( demux_t *p_demux, avi_track_t *tk, block_t *p_frame )
917 {
918     if( tk->fmt.i_cat != VIDEO_ES )
919         p_frame->i_dts = p_frame->i_pts;
920     else
921     {
922         p_frame->i_dts = p_frame->i_pts;
923         p_frame->i_pts = VLC_TICK_INVALID;
924     }
925
926     if( tk->i_dv_audio_rate )
927         AVI_DvHandleAudio( p_demux, tk, p_frame );
928
929     /* Strip QNAP header */
930     if( IsQNAPCodec( tk->fmt.i_codec ) )
931     {
932         if( p_frame->i_buffer <= QNAP_HEADER_SIZE )
933         {
934             block_Release( p_frame );
935             return;
936         }
937
938         p_frame->i_buffer -= QNAP_HEADER_SIZE;
939         p_frame->p_buffer += QNAP_HEADER_SIZE;
940     }
941
942     if( tk->i_next_block_flags )
943     {
944         p_frame->i_flags = tk->i_next_block_flags;
945         tk->i_next_block_flags = 0;
946     }
947
948     if( tk->p_es )
949         es_out_Send( p_demux->out, tk->p_es, p_frame );
950     else
951         block_Release( p_frame );
952 }
953
954 /*****************************************************************************
955  * Demux_Seekable: reads and demuxes data packets for stream seekable
956  *****************************************************************************
957  * AVIDemux: reads and demuxes data packets
958  *****************************************************************************
959  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
960  *****************************************************************************/
961 typedef struct
962 {
963     bool b_ok;
964
965     int64_t i_toread;
966
967     int64_t i_posf; /* where we will read :
968                    if i_idxposb == 0 : begining of chunk (+8 to acces data)
969                    else : point on data directly */
970 } avi_track_toread_t;
971
972 static int Demux_Seekable( demux_t *p_demux )
973 {
974     demux_sys_t *p_sys = p_demux->p_sys;
975
976     unsigned int i_track_count = 0;
977     unsigned int i_track;
978     /* cannot be more than 100 stream (dcXX or wbXX) */
979     avi_track_toread_t toread[100];
980
981
982     /* detect new selected/unselected streams */
983     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
984     {
985         avi_track_t *tk = p_sys->track[i_track];
986         bool  b = false;
987
988         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
989         if( tk->p_es_dv_audio )
990         {
991             bool b_extra = false;
992             es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es_dv_audio, &b_extra );
993             b |= b_extra;
994         }
995         if( b && !tk->b_activated )
996         {
997             if( p_sys->b_seekable)
998             {
999                 AVI_TrackSeek( p_demux, i_track, p_sys->i_time );
1000             }
1001             tk->b_activated = true;
1002         }
1003         else if( !b && tk->b_activated )
1004         {
1005             tk->b_activated = false;
1006         }
1007         if( b )
1008         {
1009             i_track_count++;
1010         }
1011     }
1012
1013     if( i_track_count <= 0 )
1014     {
1015         p_sys->i_time += p_sys->i_read_increment;
1016         if( p_sys->i_length != 0 )
1017         {
1018             if( p_sys->i_time >= p_sys->i_length )
1019                 return VLC_DEMUXER_EOF;
1020             return VLC_DEMUXER_SUCCESS;
1021         }
1022         msg_Warn( p_demux, "no track selected, exiting..." );
1023         return VLC_DEMUXER_EOF;
1024     }
1025
1026     /* wait for the good time */
1027     es_out_SetPCR( p_demux->out, VLC_TICK_0 + p_sys->i_time );
1028     p_sys->i_time += p_sys->i_read_increment;
1029
1030     /* init toread */
1031     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1032     {
1033         avi_track_t *tk = p_sys->track[i_track];
1034
1035         toread[i_track].b_ok = tk->b_activated && !tk->b_eof;
1036         if( tk->i_idxposc < tk->idx.i_size )
1037         {
1038             toread[i_track].i_posf = tk->idx.p_entry[tk->i_idxposc].i_pos;
1039            if( tk->i_idxposb > 0 )
1040            {
1041                 toread[i_track].i_posf += 8 + tk->i_idxposb;
1042            }
1043         }
1044         else
1045         {
1046             toread[i_track].i_posf = -1;
1047         }
1048
1049         vlc_tick_t i_dpts = p_sys->i_time - AVI_GetPTS( tk );
1050
1051         if( tk->i_samplesize )
1052         {
1053             toread[i_track].i_toread = AVI_PTSToByte( tk, i_dpts );
1054         }
1055         else if ( i_dpts > VLC_TICK_FROM_SEC(-2) ) /* don't send a too early dts (low fps video) */
1056         {
1057             int64_t i_chunks_count = AVI_PTSToChunk( tk, i_dpts );
1058             if( i_dpts > 0 && AVI_GetDPTS( tk, i_chunks_count ) < i_dpts )
1059             {
1060                 /* AVI code is crap. toread is either bytes, or here, chunk count.
1061                  * That does not even work when reading amount < scale / rate */
1062                 i_chunks_count++;
1063             }
1064             toread[i_track].i_toread = i_chunks_count;
1065         }
1066         else
1067             toread[i_track].i_toread = -1;
1068     }
1069
1070     for( ;; )
1071     {
1072         avi_track_t     *tk;
1073         bool       b_done;
1074         block_t         *p_frame;
1075         int64_t i_pos;
1076         unsigned int i;
1077         size_t i_size;
1078
1079         /* search for first chunk to be read */
1080         for( i = 0, b_done = true, i_pos = -1; i < p_sys->i_track; i++ )
1081         {
1082             if( !toread[i].b_ok ||
1083                 ( p_sys->b_fastseekable && p_sys->b_interleaved &&
1084                   AVI_GetDPTS( p_sys->track[i], toread[i].i_toread ) <= -p_sys->i_read_increment ) )
1085             {
1086                 continue;
1087             }
1088
1089             if( toread[i].i_toread > 0 )
1090             {
1091                 b_done = false; /* not yet finished */
1092
1093                 if( toread[i].i_posf > 0 )
1094                 {
1095                     if( i_pos == -1 || i_pos > toread[i].i_posf )
1096                     {
1097                         i_track = i;
1098                         i_pos = toread[i].i_posf;
1099                     }
1100                 }
1101             }
1102         }
1103
1104         if( b_done )
1105         {
1106             for( i = 0; i < p_sys->i_track; i++ )
1107             {
1108                 if( toread[i].b_ok && toread[i].i_toread >= 0 )
1109                     return VLC_DEMUXER_SUCCESS;
1110             }
1111             msg_Warn( p_demux, "all tracks have failed, exiting..." );
1112             return VLC_DEMUXER_EOF;
1113         }
1114
1115         if( i_pos == -1 )
1116         {
1117             unsigned short i_loop_count = 0;
1118
1119             /* no valid index, we will parse directly the stream
1120              * in case we fail we will disable all finished stream */
1121             if( p_sys->b_seekable && p_sys->i_movi_lastchunk_pos >= p_sys->i_movi_begin + 12 )
1122             {
1123                 if (vlc_stream_Seek(p_demux->s, p_sys->i_movi_lastchunk_pos))
1124                     return VLC_DEMUXER_EGENERIC;
1125
1126                 if( AVI_PacketNext( p_demux ) )
1127                 {
1128                     return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
1129                 }
1130             }
1131             else
1132             {
1133                 if (vlc_stream_Seek(p_demux->s, p_sys->i_movi_begin + 12))
1134                     return VLC_DEMUXER_EGENERIC;
1135             }
1136
1137             for( ;; )
1138             {
1139                 avi_packet_t avi_pk;
1140
1141                 if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
1142                 {
1143                     msg_Warn( p_demux,
1144                              "cannot get packet header, track disabled" );
1145                     return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
1146                 }
1147                 if( avi_pk.i_stream >= p_sys->i_track ||
1148                     ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
1149                 {
1150                     if( AVI_PacketNext( p_demux ) )
1151                     {
1152                         msg_Warn( p_demux,
1153                                   "cannot skip packet, track disabled" );
1154                         return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
1155                     }
1156
1157                     if( !++i_loop_count )
1158                          msg_Warn( p_demux, "don't seem to find any data..." );
1159                     continue;
1160                 }
1161                 else
1162                 {
1163                     i_track = avi_pk.i_stream;
1164                     tk = p_sys->track[i_track];
1165
1166                     /* add this chunk to the index */
1167                     avi_entry_t index;
1168                     index.i_id     = avi_pk.i_fourcc;
1169                     index.i_flags  = AVI_GetKeyFlag(tk->fmt.i_codec, avi_pk.i_peek);
1170                     index.i_pos    = avi_pk.i_pos;
1171                     index.i_length = avi_pk.i_size;
1172                     index.i_lengthtotal = index.i_length;
1173                     avi_index_Append( &tk->idx, &p_sys->i_movi_lastchunk_pos, &index );
1174
1175                     /* do we will read this data ? */
1176                     if( AVI_GetDPTS( tk, toread[i_track].i_toread ) > -p_sys->i_read_increment )
1177                     {
1178                         break;
1179                     }
1180                     else
1181                     {
1182                         if( AVI_PacketNext( p_demux ) )
1183                         {
1184                             msg_Warn( p_demux,
1185                                       "cannot skip packet, track disabled" );
1186                             return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
1187                         }
1188                     }
1189                 }
1190             }
1191
1192         }
1193         else
1194         {
1195             if (vlc_stream_Seek(p_demux->s, i_pos))
1196                 return VLC_DEMUXER_EGENERIC;
1197         }
1198
1199         /* Set the track to use */
1200         tk = p_sys->track[i_track];
1201
1202         /* read thoses data */
1203         if( tk->i_samplesize )
1204         {
1205             int64_t i_toread;
1206
1207             if( ( i_toread = toread[i_track].i_toread ) <= 0 )
1208             {
1209                 if( tk->i_samplesize > 1 )
1210                 {
1211                     i_toread = tk->i_samplesize;
1212                 }
1213                 else
1214                 {
1215                     i_toread = AVI_PTSToByte( tk, VLC_TICK_FROM_MS(20) );
1216                     i_toread = __MAX( i_toread, 100 );
1217                 }
1218             }
1219             i_size = __MIN( tk->idx.p_entry[tk->i_idxposc].i_length -
1220                                 tk->i_idxposb,
1221                             (size_t) i_toread );
1222         }
1223         else
1224         {
1225             i_size = tk->idx.p_entry[tk->i_idxposc].i_length;
1226         }
1227
1228         if( tk->i_idxposb == 0 )
1229         {
1230             i_size += 8; /* need to read and skip header */
1231         }
1232
1233         if( ( p_frame = ReadFrame( p_demux, tk,
1234                         ( tk->i_idxposb == 0 ) ? 8 : 0, i_size ) )==NULL )
1235         {
1236             msg_Warn( p_demux, "failed reading data" );
1237             tk->b_eof = false;
1238             toread[i_track].b_ok = false;
1239             continue;
1240         }
1241
1242         p_frame->i_pts = VLC_TICK_0 + AVI_GetPTS( tk );
1243         if( tk->idx.p_entry[tk->i_idxposc].i_flags&AVIIF_KEYFRAME )
1244         {
1245             p_frame->i_flags = BLOCK_FLAG_TYPE_I;
1246         }
1247         else
1248         {
1249             p_frame->i_flags = BLOCK_FLAG_TYPE_PB;
1250         }
1251
1252         /* read data */
1253         if( tk->i_samplesize )
1254         {
1255             if( tk->i_idxposb == 0 )
1256             {
1257                 i_size -= 8;
1258             }
1259             toread[i_track].i_toread -= i_size;
1260             tk->i_idxposb += i_size;
1261             if( tk->i_idxposb >=
1262                     tk->idx.p_entry[tk->i_idxposc].i_length )
1263             {
1264                 tk->i_idxposb = 0;
1265                 tk->i_idxposc++;
1266             }
1267         }
1268         else
1269         {
1270             int i_length = tk->idx.p_entry[tk->i_idxposc].i_length;
1271
1272             tk->i_idxposc++;
1273             if( tk->fmt.i_cat == AUDIO_ES )
1274             {
1275                 tk->i_blockno += tk->i_blocksize > 0 ? ( i_length + tk->i_blocksize - 1 ) / tk->i_blocksize : 1;
1276             }
1277             toread[i_track].i_toread--;
1278         }
1279
1280         if( tk->i_idxposc < tk->idx.i_size)
1281         {
1282             toread[i_track].i_posf =
1283                 tk->idx.p_entry[tk->i_idxposc].i_pos;
1284             if( tk->i_idxposb > 0 )
1285             {
1286                 toread[i_track].i_posf += 8 + tk->i_idxposb;
1287             }
1288
1289         }
1290         else
1291         {
1292             toread[i_track].i_posf = -1;
1293         }
1294
1295         AVI_SendFrame( p_demux, tk, p_frame );
1296     }
1297 }
1298
1299
1300 /*****************************************************************************
1301  * Demux_UnSeekable: reads and demuxes data packets for unseekable file
1302  *****************************************************************************
1303  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1304  *****************************************************************************/
1305 static int Demux_UnSeekable( demux_t *p_demux )
1306 {
1307     demux_sys_t     *p_sys = p_demux->p_sys;
1308     avi_track_t *p_stream_master = NULL;
1309     unsigned int i_stream;
1310     unsigned int i_packet;
1311
1312     es_out_SetPCR( p_demux->out, VLC_TICK_0 + p_sys->i_time );
1313
1314     /* *** find master stream for data packet skipping algo *** */
1315     /* *** -> first video, if any, or first audio ES *** */
1316     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
1317     {
1318         avi_track_t *tk = p_sys->track[i_stream];
1319         bool  b;
1320
1321         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
1322         if( tk->p_es_dv_audio )
1323         {
1324             bool b_extra;
1325             es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es_dv_audio, &b_extra );
1326             b |= b_extra;
1327         }
1328
1329         if( b )
1330         {
1331             if( tk->fmt.i_cat == VIDEO_ES )
1332             {
1333                 p_stream_master = tk;
1334                 break;
1335             }
1336             else if( !p_stream_master )
1337             {
1338                 p_stream_master = tk;
1339             }
1340         }
1341     }
1342
1343     if( !p_stream_master )
1344     {
1345         if( p_sys->i_track )
1346         {
1347             p_stream_master = p_sys->track[0];
1348         }
1349         else
1350         {
1351             msg_Warn( p_demux, "no more stream selected" );
1352             return VLC_DEMUXER_EOF;
1353         }
1354     }
1355
1356     p_sys->i_time = AVI_GetPTS( p_stream_master );
1357
1358     for( i_packet = 0; i_packet < 10; i_packet++)
1359     {
1360         avi_packet_t    avi_pk;
1361
1362         if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
1363         {
1364             return VLC_DEMUXER_EOF;
1365         }
1366
1367         if( avi_pk.i_stream >= p_sys->i_track ||
1368             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
1369         {
1370             /* we haven't found an audio or video packet:
1371              *  - we have seek, found first next packet
1372              *  - others packets could be found, skip them
1373              */
1374             switch( avi_pk.i_fourcc )
1375             {
1376                 case AVIFOURCC_JUNK:
1377                 case AVIFOURCC_LIST:
1378                 case AVIFOURCC_RIFF:
1379                     return( !AVI_PacketNext( p_demux ) ? 1 : 0 );
1380                 case AVIFOURCC_idx1:
1381                     if( p_sys->b_odml )
1382                     {
1383                         return( !AVI_PacketNext( p_demux ) ? 1 : 0 );
1384                     }
1385                     return VLC_DEMUXER_EOF;
1386                 default:
1387                     msg_Warn( p_demux,
1388                               "seems to have lost position @%"PRIu64", resync",
1389                               vlc_stream_Tell(p_demux->s) );
1390                     if( AVI_PacketSearch( p_demux ) )
1391                     {
1392                         msg_Err( p_demux, "resync failed" );
1393                         return VLC_DEMUXER_EGENERIC;
1394                     }
1395             }
1396         }
1397         else
1398         {
1399             avi_track_t *p_stream = p_sys->track[avi_pk.i_stream];
1400             /* check for time */
1401             if( p_stream == p_stream_master ||
1402                 llabs( AVI_GetPTS( p_stream ) -
1403                         AVI_GetPTS( p_stream_master ) )< VLC_TICK_FROM_SEC(2) )
1404             {
1405                 /* load it and send to decoder */
1406                 block_t *p_frame = ReadFrame( p_demux, p_stream, 8, avi_pk.i_size + 8 ) ;
1407                 if( p_frame == NULL )
1408                 {
1409                     return VLC_DEMUXER_EGENERIC;
1410                 }
1411                 p_frame->i_pts = VLC_TICK_0 + AVI_GetPTS( p_stream );
1412
1413                 AVI_SendFrame( p_demux, p_stream, p_frame );
1414             }
1415             else
1416             {
1417                 if( AVI_PacketNext( p_demux ) )
1418                 {
1419                     return VLC_DEMUXER_EOF;
1420                 }
1421             }
1422
1423             /* *** update stream time position *** */
1424             if( p_stream->i_samplesize )
1425             {
1426                 p_stream->i_idxposb += avi_pk.i_size;
1427             }
1428             else
1429             {
1430                 if( p_stream->fmt.i_cat == AUDIO_ES )
1431                 {
1432                     p_stream->i_blockno += p_stream->i_blocksize > 0 ? ( avi_pk.i_size + p_stream->i_blocksize - 1 ) / p_stream->i_blocksize : 1;
1433                 }
1434                 p_stream->i_idxposc++;
1435             }
1436
1437         }
1438     }
1439
1440     return VLC_DEMUXER_SUCCESS;
1441 }
1442
1443 /*****************************************************************************
1444  * Seek: goto to i_date or i_percent
1445  *****************************************************************************/
1446 static int Seek( demux_t *p_demux, vlc_tick_t i_date, double f_ratio, bool b_accurate )
1447 {
1448     demux_sys_t *p_sys = p_demux->p_sys;
1449     msg_Dbg( p_demux, "seek requested: %"PRId64" seconds %2.2f%%",
1450              SEC_FROM_VLC_TICK(i_date), f_ratio * 100 );
1451
1452     if( p_sys->b_seekable )
1453     {
1454         uint64_t i_pos_backup = vlc_stream_Tell( p_demux->s );
1455
1456         /* Check and lazy load indexes if it was not done (not fastseekable) */
1457         if ( !p_sys->b_indexloaded && ( p_sys->i_avih_flags & AVIF_HASINDEX ) )
1458         {
1459             avi_chunk_t *p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true );
1460             if (unlikely( !p_riff ))
1461                 return VLC_EGENERIC;
1462
1463             int i_ret = AVI_ChunkFetchIndexes( p_demux->s, p_riff );
1464             if ( i_ret )
1465             {
1466                 /* Go back to position before index failure */
1467                 if (vlc_stream_Tell(p_demux->s) != i_pos_backup
1468                  && vlc_stream_Seek(p_demux->s, i_pos_backup))
1469                     return VLC_EGENERIC;
1470
1471                 if ( p_sys->i_avih_flags & AVIF_MUSTUSEINDEX )
1472                     return VLC_EGENERIC;
1473             }
1474             else AVI_IndexLoad( p_demux );
1475
1476             p_sys->b_indexloaded = true; /* we don't want to try each time */
1477         }
1478
1479         if( p_sys->i_length == 0 )
1480         {
1481             avi_track_t *p_stream = NULL;
1482             unsigned i_stream = 0;
1483             uint64_t i_pos;
1484
1485             if ( !p_sys->i_movi_lastchunk_pos && /* set when index is successfully loaded */
1486                  ! ( p_sys->i_avih_flags & AVIF_ISINTERLEAVED ) )
1487             {
1488                 msg_Err( p_demux, "seeking without index at %2.2f%%"
1489                          " only works for interleaved files", f_ratio * 100 );
1490                 goto failandresetpos;
1491             }
1492             /* use i_percent to create a true i_date */
1493             if( f_ratio >= 1.0 )
1494             {
1495                 msg_Warn( p_demux, "cannot seek so far !" );
1496                 goto failandresetpos;
1497             }
1498             f_ratio = __MAX( f_ratio, 0 );
1499
1500             /* try to find chunk that is at i_percent or the file */
1501             i_pos = __MAX( f_ratio * stream_Size( p_demux->s ),
1502                            p_sys->i_movi_begin );
1503             /* search first selected stream (and prefer non-EOF ones) */
1504             for( unsigned i = 0; i < p_sys->i_track; i++ )
1505             {
1506                 avi_track_t *p_track = p_sys->track[i];
1507                 if( !p_track->b_activated )
1508                     continue;
1509
1510                 p_stream = p_track;
1511                 i_stream = i;
1512                 if( !p_track->b_eof )
1513                     break;
1514             }
1515             if( p_stream == NULL )
1516             {
1517                 msg_Warn( p_demux, "cannot find any selected stream" );
1518                 goto failandresetpos;
1519             }
1520
1521             /* be sure that the index exist */
1522             if( AVI_StreamChunkSet( p_demux, i_stream, 0 ) )
1523             {
1524                 msg_Warn( p_demux, "cannot seek" );
1525                 goto failandresetpos;
1526             }
1527
1528             while( i_pos >= p_stream->idx.p_entry[p_stream->i_idxposc].i_pos +
1529                p_stream->idx.p_entry[p_stream->i_idxposc].i_length + 8 )
1530             {
1531                 /* search after i_idxposc */
1532                 if( AVI_StreamChunkSet( p_demux,
1533                                         i_stream, p_stream->i_idxposc + 1 ) )
1534                 {
1535                     msg_Warn( p_demux, "cannot seek" );
1536                     goto failandresetpos;
1537                 }
1538             }
1539
1540             i_date = AVI_GetPTS( p_stream );
1541             /* TODO better support for i_samplesize != 0 */
1542             msg_Dbg( p_demux, "estimate date %"PRId64, i_date );
1543         }
1544
1545         /* */
1546         vlc_tick_t i_wanted = i_date;
1547         vlc_tick_t i_start = i_date;
1548         /* Do a 2 pass seek, first with video (can seek ahead due to keyframes),
1549            so we can seek audio to the same starting time */
1550         for(int i=0; i<2; i++)
1551         {
1552             for( unsigned i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
1553             {
1554                 avi_track_t *p_stream = p_sys->track[i_stream];
1555
1556                 if( !p_stream->b_activated )
1557                     continue;
1558
1559                 if( (i==0 && p_stream->fmt.i_cat != VIDEO_ES) ||
1560                     (i!=0 && p_stream->fmt.i_cat == VIDEO_ES) )
1561                     continue;
1562
1563                 p_stream->b_eof = AVI_TrackSeek( p_demux, i_stream, i_wanted ) != 0;
1564                 if( !p_stream->b_eof )
1565                 {
1566                     p_stream->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
1567
1568                     if( p_stream->fmt.i_cat == AUDIO_ES || p_stream->fmt.i_cat == VIDEO_ES )
1569                         i_start = __MIN(i_start, AVI_GetPTS( p_stream ));
1570
1571                     if( i == 0 && p_stream->fmt.i_cat == VIDEO_ES )
1572                         i_wanted = i_start;
1573                 }
1574             }
1575         }
1576         p_sys->i_time = i_start;
1577         es_out_SetPCR( p_demux->out, VLC_TICK_0 + p_sys->i_time );
1578         if( b_accurate )
1579             es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, VLC_TICK_0 + i_date );
1580         msg_Dbg( p_demux, "seek: %"PRId64" seconds", SEC_FROM_VLC_TICK(p_sys->i_time) );
1581         return VLC_SUCCESS;
1582
1583 failandresetpos:
1584         /* Go back to position before index failure */
1585         if ( vlc_stream_Tell( p_demux->s ) - i_pos_backup )
1586             vlc_stream_Seek( p_demux->s, i_pos_backup );
1587
1588         return VLC_EGENERIC;
1589     }
1590     else
1591     {
1592         msg_Err( p_demux, "shouldn't yet be executed" );
1593         return VLC_EGENERIC;
1594     }
1595 }
1596
1597 /*****************************************************************************
1598  * Control:
1599  *****************************************************************************/
1600 static double ControlGetPosition( demux_t *p_demux )
1601 {
1602     demux_sys_t *p_sys = p_demux->p_sys;
1603
1604     if( p_sys->i_length != 0 )
1605     {
1606         return (double)p_sys->i_time / (double)p_sys->i_length;
1607     }
1608     else if( stream_Size( p_demux->s ) > 0 )
1609     {
1610         double i64 = (uint64_t)vlc_stream_Tell( p_demux->s );
1611         return i64 / stream_Size( p_demux->s );
1612     }
1613     return 0.0;
1614 }
1615
1616 static int Control( demux_t *p_demux, int i_query, va_list args )
1617 {
1618     demux_sys_t *p_sys = p_demux->p_sys;
1619     double   f, *pf;
1620     vlc_tick_t i64;
1621     bool b;
1622     vlc_meta_t *p_meta;
1623
1624     switch( i_query )
1625     {
1626         case DEMUX_CAN_SEEK:
1627             *va_arg( args, bool * ) = p_sys->b_seekable;
1628             return VLC_SUCCESS;
1629
1630         case DEMUX_GET_POSITION:
1631             pf = va_arg( args, double * );
1632             *pf = ControlGetPosition( p_demux );
1633             return VLC_SUCCESS;
1634         case DEMUX_SET_POSITION:
1635             f = va_arg( args, double );
1636             b = va_arg( args, int );
1637             if ( !p_sys->b_seekable )
1638             {
1639                 return VLC_EGENERIC;
1640             }
1641             else
1642             {
1643                 i64 = f * p_sys->i_length;
1644                 return Seek( p_demux, i64, f, b );
1645             }
1646
1647         case DEMUX_GET_TIME:
1648             *va_arg( args, vlc_tick_t * ) = p_sys->i_time;
1649             return VLC_SUCCESS;
1650
1651         case DEMUX_SET_TIME:
1652         {
1653             f = 0;
1654
1655             i64 = va_arg( args, vlc_tick_t );
1656             b = va_arg( args, int );
1657             if( !p_sys->b_seekable )
1658             {
1659                 return VLC_EGENERIC;
1660             }
1661             else if( p_sys->i_length != 0 )
1662             {
1663                 f = (double)i64 / p_sys->i_length;
1664             }
1665             else if( p_sys->i_time > 0 )
1666             {
1667                 f = ControlGetPosition( p_demux ) *
1668                    (double) i64 / (double)p_sys->i_time;
1669             }
1670             return Seek( p_demux, i64, f, b );
1671         }
1672         case DEMUX_GET_LENGTH:
1673             *va_arg( args, vlc_tick_t * ) = p_sys->i_length;
1674             return VLC_SUCCESS;
1675
1676         case DEMUX_GET_FPS:
1677             pf = va_arg( args, double * );
1678             *pf = 0.0;
1679             for( unsigned i = 0; i < p_sys->i_track; i++ )
1680             {
1681                 avi_track_t *tk = p_sys->track[i];
1682                 if( tk->fmt.i_cat == VIDEO_ES && tk->i_scale > 0)
1683                 {
1684                     *pf = (float)tk->i_rate / (float)tk->i_scale;
1685                     break;
1686                 }
1687             }
1688             return VLC_SUCCESS;
1689
1690         case DEMUX_GET_META:
1691             p_meta = va_arg( args, vlc_meta_t * );
1692             vlc_meta_Merge( p_meta,  p_sys->meta );
1693             return VLC_SUCCESS;
1694
1695         case DEMUX_GET_ATTACHMENTS:
1696         {
1697             if( p_sys->i_attachment <= 0 )
1698                 return VLC_EGENERIC;
1699
1700             input_attachment_t ***ppp_attach = va_arg( args, input_attachment_t*** );
1701             int *pi_int = va_arg( args, int * );
1702
1703             *ppp_attach = calloc( p_sys->i_attachment, sizeof(**ppp_attach) );
1704             if( likely(*ppp_attach) )
1705             {
1706                 *pi_int = p_sys->i_attachment;
1707                 for( unsigned i = 0; i < p_sys->i_attachment; i++ )
1708                     (*ppp_attach)[i] = vlc_input_attachment_Hold( p_sys->attachment[i] );
1709                 return VLC_SUCCESS;
1710             }
1711             return VLC_EGENERIC;
1712         }
1713
1714         case DEMUX_CAN_PAUSE:
1715         case DEMUX_SET_PAUSE_STATE:
1716         case DEMUX_CAN_CONTROL_PACE:
1717         case DEMUX_GET_PTS_DELAY:
1718             return demux_vaControlHelper( p_demux->s, 0, -1, 0, 1, i_query, args );
1719
1720         default:
1721             return VLC_EGENERIC;
1722     }
1723 }
1724
1725 /*****************************************************************************
1726  * Function to convert pts to chunk or byte
1727  *****************************************************************************/
1728
1729 static int64_t AVI_Rescale( vlc_tick_t i_value, uint32_t i_timescale, uint32_t i_newscale )
1730 {
1731     /* TODO: replace (and mp4) with better global helper (recursive checks) */
1732     if( i_timescale == i_newscale )
1733         return i_value;
1734
1735     if( (i_value >= 0 && i_value <= INT64_MAX / i_newscale) ||
1736         (i_value < 0  && i_value >= INT64_MIN / i_newscale) )
1737         return i_value * i_newscale / i_timescale;
1738
1739     /* overflow */
1740     int64_t q = i_value / i_timescale;
1741     int64_t r = i_value % i_timescale;
1742     return q * i_newscale + r * i_newscale / i_timescale;
1743 }
1744
1745 static int64_t AVI_PTSToChunk( avi_track_t *tk, vlc_tick_t i_pts )
1746 {
1747     if( !tk->i_scale )
1748         return 0;
1749
1750     i_pts = AVI_Rescale( i_pts, tk->i_scale, tk->i_rate );
1751     return SEC_FROM_VLC_TICK(i_pts);
1752 }
1753
1754 static int64_t AVI_PTSToByte( avi_track_t *tk, vlc_tick_t i_pts )
1755 {
1756     if( !tk->i_scale || !tk->i_samplesize )
1757         return 0;
1758
1759     i_pts = AVI_Rescale( i_pts, tk->i_scale, tk->i_rate );
1760     return i_pts / CLOCK_FREQ * tk->i_samplesize;
1761 }
1762
1763 static vlc_tick_t AVI_GetDPTS( avi_track_t *tk, int64_t i_count )
1764 {
1765     vlc_tick_t i_dpts = 0;
1766
1767     if( !tk->i_rate )
1768         return 0;
1769
1770     if( !tk->i_scale )
1771         return 0;
1772
1773     i_dpts = AVI_Rescale( CLOCK_FREQ * i_count, tk->i_rate, tk->i_scale );
1774
1775     if( tk->i_samplesize )
1776     {
1777         return i_dpts / tk->i_samplesize;
1778     }
1779     return i_dpts;
1780 }
1781
1782 static vlc_tick_t AVI_GetPTS( avi_track_t *tk )
1783 {
1784     /* Lookup samples index */
1785     if( tk->i_samplesize && tk->idx.i_size )
1786     {
1787         int64_t i_count = 0;
1788         unsigned int idx = tk->i_idxposc;
1789
1790         /* we need a valid entry we will emulate one */
1791         if( idx >= tk->idx.i_size )
1792         {
1793             /* use the last entry */
1794             idx = tk->idx.i_size - 1;
1795             i_count = tk->idx.p_entry[idx].i_lengthtotal
1796                     + tk->idx.p_entry[idx].i_length;
1797         }
1798         else
1799         {
1800             i_count = tk->idx.p_entry[idx].i_lengthtotal;
1801         }
1802         return AVI_GetDPTS( tk, i_count + tk->i_idxposb );
1803     }
1804
1805     if( tk->fmt.i_cat == AUDIO_ES )
1806         return AVI_GetDPTS( tk, tk->i_blockno );
1807     else
1808         return AVI_GetDPTS( tk, tk->i_idxposc );
1809 }
1810
1811 static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream )
1812 {
1813     demux_sys_t *p_sys = p_demux->p_sys;
1814     avi_packet_t avi_pk;
1815     unsigned short i_loop_count = 0;
1816
1817     /* find first chunk of i_stream that isn't in index */
1818
1819     if( p_sys->i_movi_lastchunk_pos >= p_sys->i_movi_begin + 12 )
1820     {
1821         if (vlc_stream_Seek(p_demux->s, p_sys->i_movi_lastchunk_pos))
1822             return VLC_EGENERIC;
1823         if( AVI_PacketNext( p_demux ) )
1824         {
1825             return VLC_EGENERIC;
1826         }
1827     }
1828     else
1829     {
1830         if (vlc_stream_Seek(p_demux->s, p_sys->i_movi_begin + 12))
1831             return VLC_EGENERIC;
1832     }
1833
1834     for( ;; )
1835     {
1836         if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
1837         {
1838             msg_Warn( p_demux, "cannot get packet header" );
1839             return VLC_EGENERIC;
1840         }
1841         if( avi_pk.i_stream >= p_sys->i_track ||
1842             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
1843         {
1844             if( AVI_PacketNext( p_demux ) )
1845             {
1846                 return VLC_EGENERIC;
1847             }
1848
1849             if( !++i_loop_count )
1850                  msg_Warn( p_demux, "don't seem to find any data..." );
1851         }
1852         else
1853         {
1854             avi_track_t *tk_pk = p_sys->track[avi_pk.i_stream];
1855
1856             /* add this chunk to the index */
1857             avi_entry_t index;
1858             index.i_id     = avi_pk.i_fourcc;
1859             index.i_flags  = AVI_GetKeyFlag(tk_pk->fmt.i_codec, avi_pk.i_peek);
1860             index.i_pos    = avi_pk.i_pos;
1861             index.i_length = avi_pk.i_size;
1862             index.i_lengthtotal = index.i_length;
1863             avi_index_Append( &tk_pk->idx, &p_sys->i_movi_lastchunk_pos, &index );
1864
1865             if( avi_pk.i_stream == i_stream  )
1866             {
1867                 return VLC_SUCCESS;
1868             }
1869
1870             if( AVI_PacketNext( p_demux ) )
1871             {
1872                 return VLC_EGENERIC;
1873             }
1874         }
1875     }
1876 }
1877
1878 /* be sure that i_ck will be a valid index entry */
1879 static int AVI_StreamChunkSet( demux_t *p_demux, unsigned int i_stream,
1880                                unsigned int i_ck )
1881 {
1882     demux_sys_t *p_sys = p_demux->p_sys;
1883     avi_track_t *p_stream = p_sys->track[i_stream];
1884
1885     p_stream->i_idxposc = i_ck;
1886     p_stream->i_idxposb = 0;
1887
1888     if(  i_ck >= p_stream->idx.i_size )
1889     {
1890         p_stream->i_idxposc = p_stream->idx.i_size - 1;
1891         do
1892         {
1893             p_stream->i_idxposc++;
1894             if( AVI_StreamChunkFind( p_demux, i_stream ) )
1895             {
1896                 return VLC_EGENERIC;
1897             }
1898
1899         } while( p_stream->i_idxposc < i_ck );
1900     }
1901
1902     return VLC_SUCCESS;
1903 }
1904
1905 /* XXX FIXME up to now, we assume that all chunk are one after one */
1906 static int AVI_StreamBytesSet( demux_t    *p_demux,
1907                                unsigned int i_stream,
1908                                uint64_t  i_byte )
1909 {
1910     demux_sys_t *p_sys = p_demux->p_sys;
1911     avi_track_t *p_stream = p_sys->track[i_stream];
1912
1913     if( ( p_stream->idx.i_size > 0 )
1914         &&( i_byte < p_stream->idx.p_entry[p_stream->idx.i_size - 1].i_lengthtotal +
1915                 p_stream->idx.p_entry[p_stream->idx.i_size - 1].i_length ) )
1916     {
1917         /* index is valid to find the ck */
1918         /* uses dichototmie to be fast enougth */
1919         int i_idxposc = __MIN( p_stream->i_idxposc, p_stream->idx.i_size - 1 );
1920         int i_idxmax  = p_stream->idx.i_size;
1921         int i_idxmin  = 0;
1922         for( ;; )
1923         {
1924             if( p_stream->idx.p_entry[i_idxposc].i_lengthtotal > i_byte )
1925             {
1926                 i_idxmax  = i_idxposc ;
1927                 i_idxposc = ( i_idxmin + i_idxposc ) / 2 ;
1928             }
1929             else
1930             {
1931                 if( p_stream->idx.p_entry[i_idxposc].i_lengthtotal +
1932                         p_stream->idx.p_entry[i_idxposc].i_length <= i_byte)
1933                 {
1934                     i_idxmin  = i_idxposc ;
1935                     i_idxposc = (i_idxmax + i_idxposc ) / 2 ;
1936                 }
1937                 else
1938                 {
1939                     p_stream->i_idxposc = i_idxposc;
1940                     p_stream->i_idxposb = i_byte -
1941                             p_stream->idx.p_entry[i_idxposc].i_lengthtotal;
1942                     return VLC_SUCCESS;
1943                 }
1944             }
1945         }
1946
1947     }
1948     else
1949     {
1950         p_stream->i_idxposc = p_stream->idx.i_size - 1;
1951         p_stream->i_idxposb = 0;
1952         do
1953         {
1954             p_stream->i_idxposc++;
1955             if( AVI_StreamChunkFind( p_demux, i_stream ) )
1956             {
1957                 return VLC_EGENERIC;
1958             }
1959
1960         } while( p_stream->idx.p_entry[p_stream->i_idxposc].i_lengthtotal +
1961                     p_stream->idx.p_entry[p_stream->i_idxposc].i_length <= i_byte );
1962
1963         p_stream->i_idxposb = i_byte -
1964                        p_stream->idx.p_entry[p_stream->i_idxposc].i_lengthtotal;
1965         return VLC_SUCCESS;
1966     }
1967 }
1968
1969 static int AVI_TrackSeek( demux_t *p_demux,
1970                            int i_stream,
1971                            vlc_tick_t i_date )
1972 {
1973     demux_sys_t  *p_sys = p_demux->p_sys;
1974     avi_track_t  *tk = p_sys->track[i_stream];
1975
1976 #define p_stream    p_sys->track[i_stream]
1977     vlc_tick_t i_oldpts;
1978
1979     i_oldpts = AVI_GetPTS( p_stream );
1980
1981     if( !p_stream->i_samplesize )
1982     {
1983         if( AVI_StreamChunkSet( p_demux,
1984                                 i_stream,
1985                                 AVI_PTSToChunk( p_stream, i_date ) ) )
1986         {
1987             return VLC_EGENERIC;
1988         }
1989
1990         if( p_stream->fmt.i_cat == AUDIO_ES )
1991         {
1992             unsigned int i;
1993             tk->i_blockno = 0;
1994             for( i = 0; i < tk->i_idxposc; i++ )
1995             {
1996                 if( tk->i_blocksize > 0 )
1997                 {
1998                     tk->i_blockno += ( tk->idx.p_entry[i].i_length + tk->i_blocksize - 1 ) / tk->i_blocksize;
1999                 }
2000                 else
2001                 {
2002                     tk->i_blockno++;
2003                 }
2004             }
2005         }
2006
2007         msg_Dbg( p_demux,
2008                  "old:%"PRId64" %s new %"PRId64,
2009                  i_oldpts,
2010                  i_oldpts > i_date ? ">" : "<",
2011                  i_date );
2012
2013         if( p_stream->fmt.i_cat == VIDEO_ES )
2014         {
2015             /* search key frame */
2016             //if( i_date < i_oldpts || 1 )
2017             {
2018                 while( p_stream->i_idxposc > 0 &&
2019                    !( p_stream->idx.p_entry[p_stream->i_idxposc].i_flags &
2020                                                                 AVIIF_KEYFRAME ) )
2021                 {
2022                     if( AVI_StreamChunkSet( p_demux,
2023                                             i_stream,
2024                                             p_stream->i_idxposc - 1 ) )
2025                     {
2026                         return VLC_EGENERIC;
2027                     }
2028                 }
2029             }
2030 #if 0
2031             else
2032             {
2033                 while( p_stream->i_idxposc < p_stream->idx.i_size &&
2034                         !( p_stream->idx.p_entry[p_stream->i_idxposc].i_flags &
2035                                                                 AVIIF_KEYFRAME ) )
2036                 {
2037                     if( AVI_StreamChunkSet( p_demux,
2038                                             i_stream,
2039                                             p_stream->i_idxposc + 1 ) )
2040                     {
2041                         return VLC_EGENERIC;
2042                     }
2043                 }
2044             }
2045 #endif
2046         }
2047     }
2048     else
2049     {
2050         if( AVI_StreamBytesSet( p_demux,
2051                                 i_stream,
2052                                 AVI_PTSToByte( p_stream, i_date ) ) )
2053         {
2054             return VLC_EGENERIC;
2055         }
2056     }
2057     return VLC_SUCCESS;
2058 #undef p_stream
2059 }
2060
2061 /****************************************************************************
2062  * Return true if it's a key frame
2063  ****************************************************************************/
2064 static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc, uint8_t *p_byte )
2065 {
2066     switch( i_fourcc )
2067     {
2068         case VLC_CODEC_DIV1:
2069             /* we have:
2070              *  startcode:      0x00000100   32bits
2071              *  framenumber     ?             5bits
2072              *  piture type     0(I),1(P)     2bits
2073              */
2074             if( GetDWBE( p_byte ) != 0x00000100 )
2075             {
2076                 /* it's not an msmpegv1 stream, strange...*/
2077                 return AVIIF_KEYFRAME;
2078             }
2079             return p_byte[4] & 0x06 ? 0 : AVIIF_KEYFRAME;
2080
2081         case VLC_CODEC_DIV2:
2082         case VLC_CODEC_DIV3:
2083         case VLC_CODEC_WMV1:
2084             /* we have
2085              *  picture type    0(I),1(P)     2bits
2086              */
2087             return p_byte[0] & 0xC0 ? 0 : AVIIF_KEYFRAME;
2088         case VLC_CODEC_MP4V:
2089             /* we should find first occurrence of 0x000001b6 (32bits)
2090              *  startcode:      0x000001b6   32bits
2091              *  piture type     0(I),1(P)     2bits
2092              */
2093             if( GetDWBE( p_byte ) != 0x000001b6 )
2094             {
2095                 /* not true , need to find the first VOP header */
2096                 return AVIIF_KEYFRAME;
2097             }
2098             return p_byte[4] & 0xC0 ? 0 : AVIIF_KEYFRAME;
2099
2100         default:
2101             /* I can't do it, so say yes */
2102             return AVIIF_KEYFRAME;
2103     }
2104 }
2105
2106 vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t i_codec )
2107 {
2108     switch( i_cat )
2109     {
2110         case AUDIO_ES:
2111             wf_tag_to_fourcc( i_codec, &i_codec, NULL );
2112             return i_codec;
2113         case VIDEO_ES:
2114             return vlc_fourcc_GetCodec( i_cat, i_codec );
2115         default:
2116             return VLC_CODEC_UNKNOWN;
2117     }
2118 }
2119
2120 /****************************************************************************
2121  *
2122  ****************************************************************************/
2123 static void AVI_ParseStreamHeader( vlc_fourcc_t i_id,
2124                                    unsigned int *pi_number,
2125                                    enum es_format_category_e *pi_type )
2126 {
2127     int c1, c2;
2128
2129     c1 = ((uint8_t *)&i_id)[0];
2130     c2 = ((uint8_t *)&i_id)[1];
2131
2132     if( c1 < '0' || c1 > '9' || c2 < '0' || c2 > '9' )
2133     {
2134         *pi_number =  100; /* > max stream number */
2135         *pi_type = UNKNOWN_ES;
2136     }
2137     else
2138     {
2139         *pi_number = (c1 - '0') * 10 + (c2 - '0' );
2140         switch( VLC_TWOCC( ((uint8_t *)&i_id)[2], ((uint8_t *)&i_id)[3] ) )
2141         {
2142             case AVITWOCC_wb:
2143                 *pi_type = AUDIO_ES;
2144                 break;
2145             case AVITWOCC_dc:
2146             case AVITWOCC_db:
2147             case AVITWOCC_AC:
2148                 *pi_type = VIDEO_ES;
2149                 break;
2150             case AVITWOCC_tx:
2151             case AVITWOCC_sb:
2152                 *pi_type = SPU_ES;
2153                 break;
2154             case AVITWOCC_pc:
2155                 *pi_type = IGNORE_ES;
2156                 break;
2157             default:
2158                 *pi_type = UNKNOWN_ES;
2159                 break;
2160         }
2161     }
2162 }
2163
2164 /****************************************************************************
2165  *
2166  ****************************************************************************/
2167 static int AVI_PacketGetHeader( demux_t *p_demux, avi_packet_t *p_pk )
2168 {
2169     const uint8_t *p_peek;
2170
2171     if( vlc_stream_Peek( p_demux->s, &p_peek, 16 ) < 16 )
2172     {
2173         return VLC_EGENERIC;
2174     }
2175     p_pk->i_fourcc  = VLC_FOURCC( p_peek[0], p_peek[1], p_peek[2], p_peek[3] );
2176     p_pk->i_size    = GetDWLE( p_peek + 4 );
2177     p_pk->i_pos     = vlc_stream_Tell( p_demux->s );
2178     if( p_pk->i_fourcc == AVIFOURCC_LIST || p_pk->i_fourcc == AVIFOURCC_RIFF )
2179     {
2180         p_pk->i_type = VLC_FOURCC( p_peek[8],  p_peek[9],
2181                                    p_peek[10], p_peek[11] );
2182     }
2183     else
2184     {
2185         p_pk->i_type = 0;
2186     }
2187
2188     memcpy( p_pk->i_peek, p_peek + 8, 8 );
2189
2190     AVI_ParseStreamHeader( p_pk->i_fourcc, &p_pk->i_stream, &p_pk->i_cat );
2191     return VLC_SUCCESS;
2192 }
2193
2194 static int AVI_PacketNext( demux_t *p_demux )
2195 {
2196     avi_packet_t    avi_ck;
2197     size_t          i_skip = 0;
2198
2199     if( AVI_PacketGetHeader( p_demux, &avi_ck ) )
2200     {
2201         return VLC_EGENERIC;
2202     }
2203
2204     if( avi_ck.i_fourcc == AVIFOURCC_LIST &&
2205         ( avi_ck.i_type == AVIFOURCC_rec || avi_ck.i_type == AVIFOURCC_movi ) )
2206     {
2207         i_skip = 12;
2208     }
2209     else if( avi_ck.i_fourcc == AVIFOURCC_RIFF &&
2210              avi_ck.i_type == AVIFOURCC_AVIX )
2211     {
2212         i_skip = 24;
2213     }
2214     else
2215     {
2216         if( avi_ck.i_size > UINT32_MAX - 9 )
2217             return VLC_EGENERIC;
2218         i_skip = __EVEN( avi_ck.i_size ) + 8;
2219     }
2220
2221     if( i_skip > SSIZE_MAX )
2222         return VLC_EGENERIC;
2223
2224     ssize_t i_ret = vlc_stream_Read( p_demux->s, NULL, i_skip );
2225     if( i_ret < 0 || (size_t) i_ret != i_skip )
2226     {
2227         return VLC_EGENERIC;
2228     }
2229     return VLC_SUCCESS;
2230 }
2231
2232 static int AVI_PacketSearch( demux_t *p_demux )
2233 {
2234     demux_sys_t     *p_sys = p_demux->p_sys;
2235     avi_packet_t    avi_pk;
2236     unsigned short  i_count = 0;
2237
2238     for( ;; )
2239     {
2240         if( vlc_stream_Read( p_demux->s, NULL, 1 ) != 1 )
2241         {
2242             return VLC_EGENERIC;
2243         }
2244         AVI_PacketGetHeader( p_demux, &avi_pk );
2245         if( avi_pk.i_stream < p_sys->i_track &&
2246             ( avi_pk.i_cat == AUDIO_ES || avi_pk.i_cat == VIDEO_ES ) )
2247         {
2248             return VLC_SUCCESS;
2249         }
2250         switch( avi_pk.i_fourcc )
2251         {
2252             case AVIFOURCC_JUNK:
2253             case AVIFOURCC_LIST:
2254             case AVIFOURCC_RIFF:
2255             case AVIFOURCC_idx1:
2256                 return VLC_SUCCESS;
2257         }
2258
2259         if( !++i_count )
2260             msg_Warn( p_demux, "trying to resync..." );
2261     }
2262 }
2263
2264 /****************************************************************************
2265  * Index stuff.
2266  ****************************************************************************/
2267 static void avi_index_Init( avi_index_t *p_index )
2268 {
2269     p_index->i_size  = 0;
2270     p_index->i_max   = 0;
2271     p_index->p_entry = NULL;
2272 }
2273 static void avi_index_Clean( avi_index_t *p_index )
2274 {
2275     free( p_index->p_entry );
2276 }
2277 static void avi_index_Append( avi_index_t *p_index, uint64_t *pi_last_pos,
2278                               avi_entry_t *p_entry )
2279 {
2280     /* Update last chunk position */
2281     if( *pi_last_pos < p_entry->i_pos )
2282          *pi_last_pos = p_entry->i_pos;
2283
2284     /* add the entry */
2285     if( p_index->i_size >= p_index->i_max )
2286     {
2287         p_index->i_max += 16384;
2288         p_index->p_entry = realloc_or_free( p_index->p_entry,
2289                                             p_index->i_max * sizeof( *p_index->p_entry ) );
2290         if( !p_index->p_entry )
2291             return;
2292     }
2293     /* calculate cumulate length */
2294     if( p_index->i_size > 0 )
2295     {
2296         p_entry->i_lengthtotal =
2297             p_index->p_entry[p_index->i_size - 1].i_length +
2298                 p_index->p_entry[p_index->i_size - 1].i_lengthtotal;
2299     }
2300     else
2301     {
2302         p_entry->i_lengthtotal = 0;
2303     }
2304
2305     p_index->p_entry[p_index->i_size++] = *p_entry;
2306 }
2307
2308 static int AVI_IndexFind_idx1( demux_t *p_demux,
2309                                avi_chunk_idx1_t **pp_idx1,
2310                                uint64_t *pi_offset )
2311 {
2312     demux_sys_t *p_sys = p_demux->p_sys;
2313
2314     avi_chunk_list_t *p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true);
2315     avi_chunk_idx1_t *p_idx1 = AVI_ChunkFind( p_riff, AVIFOURCC_idx1, 0, false);
2316
2317     if( !p_idx1 )
2318     {
2319         msg_Warn( p_demux, "cannot find idx1 chunk, no index defined" );
2320         return VLC_EGENERIC;
2321     }
2322     *pp_idx1 = p_idx1;
2323
2324     /* The offset in the index should be from the start of the movi content,
2325      * but some broken files use offset from the start of the file. Just
2326      * checking the offset of the first packet is not enough as some files
2327      * has unused chunk at the beginning of the movi content.
2328      */
2329     avi_chunk_list_t *p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0, true );
2330     if( !p_movi )
2331         return VLC_EGENERIC;
2332     uint64_t i_first_pos = UINT64_MAX;
2333     for( unsigned i = 0; i < __MIN( p_idx1->i_entry_count, 100 ); i++ )
2334     {
2335         if ( p_idx1->entry[i].i_length > 0 )
2336             i_first_pos = __MIN( i_first_pos, p_idx1->entry[i].i_pos );
2337     }
2338
2339     const uint64_t i_movi_content = p_movi->i_chunk_pos + 8;
2340     if( i_first_pos < i_movi_content )
2341     {
2342         *pi_offset = i_movi_content;
2343     }
2344     else if( p_sys->b_seekable && i_first_pos < UINT64_MAX )
2345     {
2346         const uint8_t *p_peek;
2347         if( !vlc_stream_Seek( p_demux->s, i_movi_content + i_first_pos ) &&
2348             vlc_stream_Peek( p_demux->s, &p_peek, 4 ) >= 4 &&
2349             ( !isdigit( p_peek[0] ) || !isdigit( p_peek[1] ) ||
2350               !isalpha( p_peek[2] ) || !isalpha( p_peek[3] ) ) )
2351             *pi_offset = 0;
2352         else
2353             *pi_offset = i_movi_content;
2354
2355         if( p_idx1->i_entry_count )
2356         {
2357             /* Invalidate offset if index refers past the data section to avoid false
2358                positives when the offset equals sample size */
2359             size_t i_dataend = *pi_offset + p_idx1->entry[p_idx1->i_entry_count - 1].i_pos +
2360                                             p_idx1->entry[p_idx1->i_entry_count - 1].i_length;
2361             if( i_dataend > p_movi->i_chunk_pos + p_movi->i_chunk_size )
2362                 *pi_offset = 0;
2363         }
2364     }
2365     else
2366     {
2367         *pi_offset = 0;
2368     }
2369
2370     return VLC_SUCCESS;
2371 }
2372
2373 static int AVI_IndexLoad_idx1( demux_t *p_demux,
2374                                avi_index_t p_index[], uint64_t *pi_last_offset )
2375 {
2376     demux_sys_t *p_sys = p_demux->p_sys;
2377
2378     avi_chunk_idx1_t *p_idx1;
2379     uint64_t         i_offset;
2380     if( AVI_IndexFind_idx1( p_demux, &p_idx1, &i_offset ) )
2381         return VLC_EGENERIC;
2382
2383     p_sys->b_indexloaded = true;
2384
2385     for( unsigned i_index = 0; i_index < p_idx1->i_entry_count; i_index++ )
2386     {
2387         enum es_format_category_e i_cat;
2388         unsigned i_stream;
2389
2390         AVI_ParseStreamHeader( p_idx1->entry[i_index].i_fourcc,
2391                                &i_stream,
2392                                &i_cat );
2393         if( i_stream < p_sys->i_track &&
2394             (i_cat == p_sys->track[i_stream]->fmt.i_cat || i_cat == UNKNOWN_ES ) )
2395         {
2396             avi_entry_t index;
2397             index.i_id     = p_idx1->entry[i_index].i_fourcc;
2398             index.i_flags  = p_idx1->entry[i_index].i_flags&(~AVIIF_FIXKEYFRAME);
2399             index.i_pos    = p_idx1->entry[i_index].i_pos + i_offset;
2400             index.i_length = p_idx1->entry[i_index].i_length;
2401             index.i_lengthtotal = index.i_length;
2402
2403             avi_index_Append( &p_index[i_stream], pi_last_offset, &index );
2404         }
2405     }
2406
2407 #ifdef AVI_DEBUG
2408     for( unsigned i_index = 0; i_index< p_idx1->i_entry_count && i_index < p_sys->i_track; i_index++ )
2409     {
2410         for( unsigned i = 0; i < p_index[i_index].i_size; i++ )
2411         {
2412             vlc_tick_t i_length;
2413             if( p_sys->track[i_index]->i_samplesize )
2414             {
2415                 i_length = AVI_GetDPTS( p_sys->track[i_index],
2416                                         p_index[i_index].p_entry[i].i_lengthtotal );
2417             }
2418             else
2419             {
2420                 i_length = AVI_GetDPTS( p_sys->track[i_index], i );
2421             }
2422             msg_Dbg( p_demux, "index stream %d @%ld time %ld", i_index,
2423                      p_index[i_index].p_entry[i].i_pos, i_length );
2424         }
2425     }
2426 #endif
2427     return VLC_SUCCESS;
2428 }
2429
2430 static void __Parse_indx( demux_t *p_demux, avi_index_t *p_index, uint64_t *pi_max_offset,
2431                           avi_chunk_indx_t *p_indx )
2432 {
2433     demux_sys_t *p_sys = p_demux->p_sys;
2434     avi_entry_t index;
2435
2436     p_sys->b_indexloaded = true;
2437
2438     msg_Dbg( p_demux, "loading subindex(0x%x) %d entries", p_indx->i_indextype, p_indx->i_entriesinuse );
2439     if( p_indx->i_indexsubtype == 0 )
2440     {
2441         for( unsigned i = 0; i < p_indx->i_entriesinuse; i++ )
2442         {
2443             index.i_id     = p_indx->i_id;
2444             index.i_flags  = p_indx->idx.std[i].i_size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
2445             index.i_pos    = p_indx->i_baseoffset + p_indx->idx.std[i].i_offset - 8;
2446             index.i_length = p_indx->idx.std[i].i_size&0x7fffffff;
2447             index.i_lengthtotal = index.i_length;
2448
2449             avi_index_Append( p_index, pi_max_offset, &index );
2450         }
2451     }
2452     else if( p_indx->i_indexsubtype == AVI_INDEX_2FIELD )
2453     {
2454         for( unsigned i = 0; i < p_indx->i_entriesinuse; i++ )
2455         {
2456             index.i_id     = p_indx->i_id;
2457             index.i_flags  = p_indx->idx.field[i].i_size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
2458             index.i_pos    = p_indx->i_baseoffset + p_indx->idx.field[i].i_offset - 8;
2459             index.i_length = p_indx->idx.field[i].i_size;
2460             index.i_lengthtotal = index.i_length;
2461
2462             avi_index_Append( p_index, pi_max_offset, &index );
2463         }
2464     }
2465     else
2466     {
2467         msg_Warn( p_demux, "unknown subtype index(0x%x)", p_indx->i_indexsubtype );
2468     }
2469 }
2470
2471 static void AVI_IndexLoad_indx( demux_t *p_demux,
2472                                 avi_index_t p_index[], uint64_t *pi_last_offset )
2473 {
2474     demux_sys_t         *p_sys = p_demux->p_sys;
2475
2476     avi_chunk_list_t    *p_riff;
2477     avi_chunk_list_t    *p_hdrl;
2478
2479     p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true);
2480     p_hdrl = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0, true );
2481
2482     for( unsigned i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2483     {
2484         avi_chunk_list_t    *p_strl;
2485         avi_chunk_indx_t    *p_indx;
2486
2487 #define p_stream  p_sys->track[i_stream]
2488         p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i_stream, true );
2489         p_indx = AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0, false );
2490
2491         if( !p_indx )
2492         {
2493             if( p_sys->b_odml )
2494                 msg_Warn( p_demux, "cannot find indx (misdetect/broken OpenDML "
2495                                    "file?)" );
2496             continue;
2497         }
2498
2499         if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS )
2500         {
2501             __Parse_indx( p_demux, &p_index[i_stream], pi_last_offset, p_indx );
2502         }
2503         else if( p_indx->i_indextype == AVI_INDEX_OF_INDEXES )
2504         {
2505             if ( !p_sys->b_seekable )
2506                 return;
2507             avi_chunk_t    ck_sub;
2508             for( unsigned i = 0; i < p_indx->i_entriesinuse; i++ )
2509             {
2510                 if( vlc_stream_Seek( p_demux->s,
2511                                      p_indx->idx.super[i].i_offset ) ||
2512                     AVI_ChunkRead( p_demux->s, &ck_sub, NULL  ) )
2513                 {
2514                     break;
2515                 }
2516                 if( ck_sub.common.i_chunk_fourcc == AVIFOURCC_indx &&
2517                      ck_sub.indx.i_indextype == AVI_INDEX_OF_CHUNKS )
2518                     __Parse_indx( p_demux, &p_index[i_stream], pi_last_offset, &ck_sub.indx );
2519                 AVI_ChunkClean( p_demux->s, &ck_sub );
2520             }
2521         }
2522         else
2523         {
2524             msg_Warn( p_demux, "unknown type index(0x%x)", p_indx->i_indextype );
2525         }
2526 #undef p_stream
2527     }
2528 }
2529
2530 static void AVI_IndexLoad( demux_t *p_demux )
2531 {
2532     demux_sys_t *p_sys = p_demux->p_sys;
2533
2534     /* Load indexes */
2535     assert( p_sys->i_track <= 100 );
2536     avi_index_t p_idx_indx[p_sys->i_track];
2537     avi_index_t p_idx_idx1[p_sys->i_track];
2538     for( unsigned i = 0; i < p_sys->i_track; i++ )
2539     {
2540         avi_index_Init( &p_idx_indx[i] );
2541         avi_index_Init( &p_idx_idx1[i] );
2542     }
2543     uint64_t i_indx_last_pos = p_sys->i_movi_lastchunk_pos;
2544     uint64_t i_idx1_last_pos = p_sys->i_movi_lastchunk_pos;
2545
2546     AVI_IndexLoad_indx( p_demux, p_idx_indx, &i_indx_last_pos );
2547     if( !p_sys->b_odml )
2548         AVI_IndexLoad_idx1( p_demux, p_idx_idx1, &i_idx1_last_pos );
2549
2550     /* Select the longest index */
2551     for( unsigned i = 0; i < p_sys->i_track; i++ )
2552     {
2553         if( p_idx_indx[i].i_size > p_idx_idx1[i].i_size )
2554         {
2555             msg_Dbg( p_demux, "selected ODML index for stream[%u]", i );
2556             free(p_sys->track[i]->idx.p_entry);
2557             p_sys->track[i]->idx = p_idx_indx[i];
2558             avi_index_Clean( &p_idx_idx1[i] );
2559         }
2560         else
2561         {
2562             msg_Dbg( p_demux, "selected standard index for stream[%u]", i );
2563             free(p_sys->track[i]->idx.p_entry);
2564             p_sys->track[i]->idx = p_idx_idx1[i];
2565             avi_index_Clean( &p_idx_indx[i] );
2566         }
2567     }
2568     p_sys->i_movi_lastchunk_pos = __MAX( i_indx_last_pos, i_idx1_last_pos );
2569
2570     for( unsigned i = 0; i < p_sys->i_track; i++ )
2571     {
2572         avi_index_t *p_index = &p_sys->track[i]->idx;
2573
2574         /* Fix key flag */
2575         bool b_key = false;
2576         for( unsigned j = 0; !b_key && j < p_index->i_size; j++ )
2577             b_key = p_index->p_entry[j].i_flags & AVIIF_KEYFRAME;
2578         if( !b_key )
2579         {
2580             msg_Err( p_demux, "no key frame set for track %u", i );
2581             for( unsigned j = 0; j < p_index->i_size; j++ )
2582                 p_index->p_entry[j].i_flags |= AVIIF_KEYFRAME;
2583         }
2584
2585         /* */
2586         msg_Dbg( p_demux, "stream[%d] created %d index entries",
2587                  i, p_index->i_size );
2588     }
2589 }
2590
2591 static void AVI_IndexCreate( demux_t *p_demux )
2592 {
2593     demux_sys_t *p_sys = p_demux->p_sys;
2594
2595     avi_chunk_list_t *p_riff;
2596     avi_chunk_list_t *p_movi;
2597
2598     unsigned int i_stream;
2599     uint32_t i_movi_end;
2600
2601     vlc_tick_t i_dialog_update;
2602     vlc_dialog_id *p_dialog_id = NULL;
2603
2604     p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0, true );
2605     p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0, true );
2606
2607     if( !p_movi )
2608     {
2609         msg_Err( p_demux, "cannot find p_movi" );
2610         return;
2611     }
2612
2613     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2614         avi_index_Init( &p_sys->track[i_stream]->idx );
2615
2616     i_movi_end = __MIN( (uint32_t)(p_movi->i_chunk_pos + p_movi->i_chunk_size),
2617                         stream_Size( p_demux->s ) );
2618
2619     vlc_stream_Seek( p_demux->s, p_movi->i_chunk_pos + 12 );
2620     msg_Warn( p_demux, "creating index from LIST-movi, will take time !" );
2621
2622
2623     /* Only show dialog if AVI is > 10MB */
2624     i_dialog_update = vlc_tick_now();
2625     if( stream_Size( p_demux->s ) > 10000000 )
2626     {
2627         p_dialog_id =
2628             vlc_dialog_display_progress( p_demux, false, 0.0, _("Cancel"),
2629                                          _("Broken or missing AVI Index"),
2630                                          _("Fixing AVI Index...") );
2631     }
2632
2633     for( ;; )
2634     {
2635         avi_packet_t pk;
2636
2637         /* Don't update/check dialog too often */
2638         if( p_dialog_id != NULL && vlc_tick_now() - i_dialog_update > VLC_TICK_FROM_MS(100) )
2639         {
2640             if( vlc_dialog_is_cancelled( p_demux, p_dialog_id ) )
2641                 break;
2642
2643             double f_current = vlc_stream_Tell( p_demux->s );
2644             double f_size    = stream_Size( p_demux->s );
2645             double f_pos     = f_current / f_size;
2646             vlc_dialog_update_progress( p_demux, p_dialog_id, f_pos );
2647
2648             i_dialog_update = vlc_tick_now();
2649         }
2650
2651         if( AVI_PacketGetHeader( p_demux, &pk ) )
2652             break;
2653
2654         if( pk.i_stream < p_sys->i_track &&
2655             pk.i_cat == p_sys->track[pk.i_stream]->fmt.i_cat )
2656         {
2657             avi_track_t *tk = p_sys->track[pk.i_stream];
2658
2659             avi_entry_t index;
2660             index.i_id      = pk.i_fourcc;
2661             index.i_flags   = AVI_GetKeyFlag(tk->fmt.i_codec, pk.i_peek);
2662             index.i_pos     = pk.i_pos;
2663             index.i_length  = pk.i_size;
2664             index.i_lengthtotal = pk.i_size;
2665             avi_index_Append( &tk->idx, &p_sys->i_movi_lastchunk_pos, &index );
2666         }
2667         else
2668         {
2669             switch( pk.i_fourcc )
2670             {
2671             case AVIFOURCC_idx1:
2672                 if( p_sys->b_odml )
2673                 {
2674                     avi_chunk_list_t *p_sysx;
2675                     p_sysx = AVI_ChunkFind( &p_sys->ck_root,
2676                                             AVIFOURCC_RIFF, 1, true );
2677
2678                     msg_Dbg( p_demux, "looking for new RIFF chunk" );
2679                     if( !p_sysx || vlc_stream_Seek( p_demux->s,
2680                                          p_sysx->i_chunk_pos + 24 ) )
2681                         goto print_stat;
2682                     break;
2683                 }
2684                 goto print_stat;
2685
2686             case AVIFOURCC_RIFF:
2687                     msg_Dbg( p_demux, "new RIFF chunk found" );
2688                     break;
2689
2690             case AVIFOURCC_rec:
2691             case AVIFOURCC_JUNK:
2692                 break;
2693
2694             default:
2695                 msg_Warn( p_demux, "need resync, probably broken avi" );
2696                 if( AVI_PacketSearch( p_demux ) )
2697                 {
2698                     msg_Warn( p_demux, "lost sync, abord index creation" );
2699                     goto print_stat;
2700                 }
2701             }
2702         }
2703
2704         if( ( !p_sys->b_odml && pk.i_pos + pk.i_size >= i_movi_end ) ||
2705             AVI_PacketNext( p_demux ) )
2706         {
2707             break;
2708         }
2709     }
2710
2711 print_stat:
2712     if( p_dialog_id != NULL )
2713         vlc_dialog_release( p_demux, p_dialog_id );
2714
2715     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
2716     {
2717         msg_Dbg( p_demux, "stream[%d] creating %d index entries",
2718                 i_stream, p_sys->track[i_stream]->idx.i_size );
2719     }
2720 }
2721
2722 /* */
2723 static void AVI_MetaLoad( demux_t *p_demux,
2724                           avi_chunk_list_t *p_riff, avi_chunk_avih_t *p_avih )
2725 {
2726     demux_sys_t *p_sys = p_demux->p_sys;
2727
2728     vlc_meta_t *p_meta = p_sys->meta = vlc_meta_New();
2729     if( !p_meta )
2730         return;
2731
2732     char buffer[200];
2733     snprintf( buffer, sizeof(buffer), "%s%s%s%s",
2734               p_avih->i_flags&AVIF_HASINDEX      ? " HAS_INDEX"      : "",
2735               p_avih->i_flags&AVIF_MUSTUSEINDEX  ? " MUST_USE_INDEX" : "",
2736               p_avih->i_flags&AVIF_ISINTERLEAVED ? " IS_INTERLEAVED" : "",
2737               p_avih->i_flags&AVIF_TRUSTCKTYPE   ? " TRUST_CKTYPE"   : "" );
2738     vlc_meta_SetSetting( p_meta, buffer );
2739
2740     avi_chunk_list_t *p_info = AVI_ChunkFind( p_riff, AVIFOURCC_INFO, 0, true );
2741     if( !p_info )
2742         return;
2743
2744     static const struct {
2745         vlc_fourcc_t i_id;
2746         int          i_type;
2747     } p_dsc[] = {
2748         { AVIFOURCC_IART, vlc_meta_Artist },
2749         { AVIFOURCC_ICMT, vlc_meta_Description },
2750         { AVIFOURCC_ICOP, vlc_meta_Copyright },
2751         { AVIFOURCC_IGNR, vlc_meta_Genre },
2752         { AVIFOURCC_INAM, vlc_meta_Title },
2753         { AVIFOURCC_ICRD, vlc_meta_Date },
2754         { AVIFOURCC_ILNG, vlc_meta_Language },
2755         { AVIFOURCC_IRTD, vlc_meta_Rating },
2756         { AVIFOURCC_IWEB, vlc_meta_URL },
2757         { AVIFOURCC_IPRT, vlc_meta_TrackNumber },
2758         { AVIFOURCC_IFRM, vlc_meta_TrackTotal },
2759         { 0, -1 }
2760     };
2761     for( int i = 0; p_dsc[i].i_id != 0; i++ )
2762     {
2763         avi_chunk_STRING_t *p_strz = AVI_ChunkFind( p_info, p_dsc[i].i_id, 0, false );
2764         if( !p_strz || !p_strz->p_str )
2765             continue;
2766         char *psz_value = FromACP( p_strz->p_str );
2767         if( !psz_value )
2768             continue;
2769
2770         if( *psz_value )
2771             vlc_meta_Set( p_meta, p_dsc[i].i_type, psz_value );
2772         free( psz_value );
2773     }
2774
2775     static const vlc_fourcc_t p_extra[] = {
2776         AVIFOURCC_IARL, AVIFOURCC_ICMS, AVIFOURCC_ICRP, AVIFOURCC_IDIM, AVIFOURCC_IDPI,
2777         AVIFOURCC_IENG, AVIFOURCC_IKEY, AVIFOURCC_ILGT, AVIFOURCC_IMED, AVIFOURCC_IPLT,
2778         AVIFOURCC_IPRD, AVIFOURCC_ISBJ, AVIFOURCC_ISFT, AVIFOURCC_ISHP, AVIFOURCC_ISRC,
2779         AVIFOURCC_ISRF, AVIFOURCC_ITCH, AVIFOURCC_ISMP, AVIFOURCC_IDIT, AVIFOURCC_ISGN,
2780         AVIFOURCC_IWRI, AVIFOURCC_IPRO, AVIFOURCC_ICNM, AVIFOURCC_IPDS, AVIFOURCC_IEDT,
2781         AVIFOURCC_ICDS, AVIFOURCC_IMUS, AVIFOURCC_ISTD, AVIFOURCC_IDST, AVIFOURCC_ICNT,
2782         AVIFOURCC_ISTR, 0,
2783     };
2784
2785     for( int i = 0; p_extra[i] != 0; i++ )
2786     {
2787         avi_chunk_STRING_t *p_strz = AVI_ChunkFind( p_info, p_extra[i], 0, false );
2788         if( !p_strz || !p_strz->p_str )
2789             continue;
2790         char *psz_value = FromACP( p_strz->p_str );
2791         if( !psz_value )
2792             continue;
2793
2794         if( *psz_value )
2795             vlc_meta_AddExtra( p_meta, p_strz->p_type, psz_value );
2796         free( psz_value );
2797     }
2798 }
2799
2800 static void AVI_DvHandleAudio( demux_t *p_demux, avi_track_t *tk, block_t *p_frame )
2801 {
2802     size_t i_offset = 80 * 6 + 80 * 16 * 3 + 3;
2803     if( p_frame->i_buffer < i_offset + 5 )
2804         return;
2805
2806     if( p_frame->p_buffer[i_offset] != 0x50 )
2807         return;
2808
2809     es_format_t fmt;
2810     dv_get_audio_format( &fmt, &p_frame->p_buffer[i_offset + 1] );
2811
2812     if( tk->p_es_dv_audio && tk->i_dv_audio_rate != (int)fmt.audio.i_rate )
2813     {
2814         es_out_Del( p_demux->out, tk->p_es_dv_audio );
2815         tk->p_es_dv_audio = NULL;
2816     }
2817
2818     if( !tk->p_es_dv_audio )
2819     {
2820         tk->p_es_dv_audio = es_out_Add( p_demux->out, &fmt );
2821         tk->i_dv_audio_rate = fmt.audio.i_rate;
2822     }
2823
2824     es_format_Clean( &fmt );
2825
2826     block_t *p_frame_audio = dv_extract_audio( p_frame );
2827     if( p_frame_audio )
2828     {
2829         if( tk->p_es_dv_audio )
2830             es_out_Send( p_demux->out, tk->p_es_dv_audio, p_frame_audio );
2831         else
2832             block_Release( p_frame_audio );
2833     }
2834 }
2835
2836 /*****************************************************************************
2837  * Subtitles
2838  *****************************************************************************/
2839 static void AVI_ExtractSubtitle( demux_t *p_demux,
2840                                  unsigned int i_stream,
2841                                  avi_chunk_list_t *p_strl,
2842                                  avi_chunk_STRING_t *p_strn )
2843 {
2844     demux_sys_t *p_sys = p_demux->p_sys;
2845     block_t *p_block = NULL;
2846     input_attachment_t *p_attachment = NULL;
2847     char *psz_description = NULL;
2848     avi_chunk_indx_t *p_indx = NULL;
2849
2850     if( !p_sys->b_seekable )
2851         goto exit;
2852
2853     p_indx = AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0, false );
2854     avi_chunk_t ck;
2855     int64_t  i_position;
2856     unsigned i_size;
2857     if( p_indx )
2858     {
2859         if( p_indx->i_indextype == AVI_INDEX_OF_INDEXES &&
2860             p_indx->i_entriesinuse > 0 )
2861         {
2862             if( vlc_stream_Seek( p_demux->s, p_indx->idx.super[0].i_offset ) ||
2863                 AVI_ChunkRead( p_demux->s, &ck, NULL  ) ||
2864                 ck.common.i_chunk_fourcc != AVIFOURCC_indx )
2865                 goto exit;
2866             p_indx = &ck.indx;
2867         }
2868
2869         if( p_indx->i_indextype != AVI_INDEX_OF_CHUNKS ||
2870             p_indx->i_entriesinuse != 1 ||
2871             p_indx->i_indexsubtype != 0 )
2872             goto exit;
2873
2874         i_position  = p_indx->i_baseoffset +
2875                       p_indx->idx.std[0].i_offset - 8;
2876         i_size      = (p_indx->idx.std[0].i_size & 0x7fffffff) + 8;
2877     }
2878     else
2879     {
2880         avi_chunk_idx1_t *p_idx1;
2881         uint64_t         i_offset;
2882
2883         if( AVI_IndexFind_idx1( p_demux, &p_idx1, &i_offset ) )
2884             goto exit;
2885
2886         i_size = 0;
2887         for( unsigned i = 0; i < p_idx1->i_entry_count; i++ )
2888         {
2889             const idx1_entry_t *e = &p_idx1->entry[i];
2890             enum es_format_category_e i_cat;
2891             unsigned i_stream_idx;
2892
2893             AVI_ParseStreamHeader( e->i_fourcc, &i_stream_idx, &i_cat );
2894             if( i_cat == SPU_ES && i_stream_idx == i_stream )
2895             {
2896                 i_position = e->i_pos + i_offset;
2897                 i_size     = e->i_length + 8;
2898                 break;
2899             }
2900         }
2901         if( i_size <= 0 )
2902             goto exit;
2903     }
2904
2905     /* */
2906     if( i_size > 10000000 )
2907     {
2908         msg_Dbg( p_demux, "Attached subtitle too big: %u", i_size );
2909         goto exit;
2910     }
2911
2912     if( vlc_stream_Seek( p_demux->s, i_position ) )
2913         goto exit;
2914     p_block = vlc_stream_Block( p_demux->s, i_size );
2915     if( !p_block )
2916         goto exit;
2917
2918     /* Parse packet header */
2919     const uint8_t *p = p_block->p_buffer;
2920     if( i_size < 8 || p[2] != 't' || p[3] != 'x' )
2921         goto exit;
2922     p += 8;
2923     i_size -= 8;
2924
2925     /* Parse subtitle chunk header */
2926     if( i_size < 11 || memcmp( p, "GAB2", 4 ) ||
2927         p[4] != 0x00 || GetWLE( &p[5] ) != 0x2 )
2928         goto exit;
2929     const unsigned i_name = GetDWLE( &p[7] );
2930     if( 11 + i_size <= i_name )
2931         goto exit;
2932     if( i_name > 0 )
2933         psz_description = FromCharset( "UTF-16LE", &p[11], i_name );
2934     p += 11 + i_name;
2935     i_size -= 11 + i_name;
2936     if( i_size < 6 || GetWLE( &p[0] ) != 0x04 )
2937         goto exit;
2938     const unsigned i_payload = GetDWLE( &p[2] );
2939     if( i_size - 6 < i_payload || i_payload == 0 )
2940         goto exit;
2941     p += 6;
2942     i_size -= 6;
2943
2944     if( !psz_description )
2945         psz_description = p_strn && p_strn->p_str ? FromACP( p_strn->p_str ) : NULL;
2946     char *psz_name;
2947     if( asprintf( &psz_name, "subtitle%d.srt", p_sys->i_attachment ) <= 0 )
2948         psz_name = NULL;
2949     p_attachment = vlc_input_attachment_New( psz_name,
2950                                              "application/x-srt",
2951                                              psz_description,
2952                                              p, i_payload );
2953     if( p_attachment )
2954         TAB_APPEND( p_sys->i_attachment, p_sys->attachment, p_attachment );
2955     free( psz_name );
2956
2957 exit:
2958     free( psz_description );
2959
2960     if( p_block )
2961         block_Release( p_block );
2962
2963     if( p_attachment )
2964         msg_Dbg( p_demux, "Loaded an embedded subtitle" );
2965     else
2966         msg_Warn( p_demux, "Failed to load an embedded subtitle" );
2967
2968     if( p_indx == &ck.indx )
2969         AVI_ChunkClean( p_demux->s, &ck );
2970 }
2971 /*****************************************************************************
2972  * Stream management
2973  *****************************************************************************/
2974 static int AVI_TrackStopFinishedStreams( demux_t *p_demux )
2975 {
2976     demux_sys_t *p_sys = p_demux->p_sys;
2977     unsigned int i;
2978     int b_end = true;
2979
2980     for( i = 0; i < p_sys->i_track; i++ )
2981     {
2982         avi_track_t *tk = p_sys->track[i];
2983         if( tk->i_idxposc >= tk->idx.i_size )
2984         {
2985             tk->b_eof = true;
2986         }
2987         else
2988         {
2989             b_end = false;
2990         }
2991     }
2992     return( b_end );
2993 }
2994
2995 /****************************************************************************
2996  * AVI_MovieGetLength give max streams length in ticks
2997  ****************************************************************************/
2998 static vlc_tick_t  AVI_MovieGetLength( demux_t *p_demux )
2999 {
3000     demux_sys_t  *p_sys = p_demux->p_sys;
3001     vlc_tick_t   i_maxlength = 0;
3002     unsigned int i;
3003
3004     for( i = 0; i < p_sys->i_track; i++ )
3005     {
3006         avi_track_t *tk = p_sys->track[i];
3007         vlc_tick_t i_length;
3008
3009         /* fix length for each stream */
3010         if( tk->idx.i_size < 1 || !tk->idx.p_entry )
3011         {
3012             continue;
3013         }
3014
3015         if( tk->i_samplesize )
3016         {
3017             i_length = AVI_GetDPTS( tk,
3018                                     tk->idx.p_entry[tk->idx.i_size-1].i_lengthtotal +
3019                                         tk->idx.p_entry[tk->idx.i_size-1].i_length );
3020         }
3021         else
3022         {
3023             i_length = AVI_GetDPTS( tk, tk->idx.i_size );
3024         }
3025
3026         msg_Dbg( p_demux,
3027                  "stream[%d] length:%"PRId64" (based on index)",
3028                  i,
3029                  SEC_FROM_VLC_TICK(i_length) );
3030         i_maxlength = __MAX( i_maxlength, i_length );
3031     }
3032
3033     return i_maxlength;
3034 }