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