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