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