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