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