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