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