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