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