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