root/modules/demux/avi/avi.c

Revision f3205789f5f153cb7a756d4033c8a3cace9058c8, 80.2 kB (checked in by Laurent Aimar <fenrir@videolan.org>, 3 months ago)

Fixed AVI palette support.

  • Property mode set to 100644
<
Line 
1 /*****************************************************************************
2  * avi.c : AVI file Stream input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001-2004 the VideoLAN team
5  * $Id$
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26
27 #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_interface.h>
36
37 #include <vlc_meta.h>
38 #include <vlc_codecs.h>
39 #include <vlc_charset.h>
40
41 #include "libavi.h"
42
43 /*****************************************************************************
44  * Module descriptor
45  *****************************************************************************/
46
47 #define INTERLEAVE_TEXT N_("Force interleaved method" )
48 #define INTERLEAVE_LONGTEXT N_( "Force interleaved method." )
49
50 #define INDEX_TEXT N_("Force index creation")
51 #define INDEX_LONGTEXT N_( \
52     "Recreate a index for the AVI file. Use this if your AVI file is damaged "\
53     "or incomplete (not seekable)." )
54
55 static int  Open ( vlc_object_t * );
56 static void Close( vlc_object_t * );
57
58 static const int pi_index[] = {0,1,2};
59
60 static const char *const ppsz_indexes[] = { N_("Ask"), N_("Always fix"),
61                                 N_("Never fix") };
62
63 vlc_module_begin();
64     set_shortname( "AVI" );
65     set_description( N_("AVI demuxer") );
66     set_capability( "demux", 212 );
67     set_category( CAT_INPUT );
68     set_subcategory( SUBCAT_INPUT_DEMUX );
69
70     add_bool( "avi-interleaved", 0, NULL,
71               INTERLEAVE_TEXT, INTERLEAVE_LONGTEXT, true );
72     add_integer( "avi-index", 0, NULL,
73               INDEX_TEXT, INDEX_LONGTEXT, false );
74         change_integer_list( pi_index, ppsz_indexes, NULL );
75
76     set_callbacks( Open, Close );
77 vlc_module_end();
78
79 /*****************************************************************************
80  * Local prototypes
81  *****************************************************************************/
82 static int Control         ( demux_t *, int, va_list );
83 static int Seek            ( demux_t *, mtime_t, int );
84 static int Demux_Seekable  ( demux_t * );
85 static int Demux_UnSeekable( demux_t * );
86
87 #define __ABS( x ) ( (x) < 0 ? (-(x)) : (x) )
88
89 typedef struct
90 {
91     vlc_fourcc_t i_fourcc;
92     off_t        i_pos;
93     uint32_t     i_size;
94     vlc_fourcc_t i_type;     /* only for AVIFOURCC_LIST */
95
96     uint8_t      i_peek[8];  /* first 8 bytes */
97
98     unsigned int i_stream;
99     unsigned int i_cat;
100 } avi_packet_t;
101
102
103 typedef struct
104 {
105     vlc_fourcc_t i_id;
106     uint32_t     i_flags;
107     off_t        i_pos;
108     uint32_t     i_length;
109     uint32_t     i_lengthtotal;
110
111 } avi_entry_t;
112
113 typedef struct
114 {
115     bool      b_activated;
116
117     unsigned int    i_cat; /* AUDIO_ES, VIDEO_ES */
118     vlc_fourcc_t    i_codec;
119
120     int             i_rate;
121     int             i_scale;
122     int             i_samplesize;
123
124     es_out_id_t     *p_es;
125
126     /* Avi Index */
127     avi_entry_t     *p_index;
128     unsigned int    i_idxnb;
129     unsigned int    i_idxmax;
130
131     unsigned int    i_idxposc;  /* numero of chunk */
132     unsigned int    i_idxposb;  /* byte in the current chunk */
133
134     /* extra information given to the decoder */
135     void            *p_extra;
136
137     /* For VBR audio only */
138     unsigned int    i_blockno;
139     unsigned int    i_blocksize;
140
141     /* For muxed streams */
142     stream_t        *p_out_muxed;
143 } avi_track_t;
144
145 struct demux_sys_t
146 {
147     mtime_t i_time;
148     mtime_t i_length;
149
150     bool  b_seekable;
151     bool  b_muxed;
152     avi_chunk_t ck_root;
153
154     bool  b_odml;
155
156     off_t   i_movi_begin;
157     off_t   i_movi_lastchunk_pos;   /* XXX position of last valid chunk */
158
159     /* number of streams and information */
160     unsigned int i_track;
161     avi_track_t  **track;
162
163     /* meta */
164     vlc_meta_t  *meta;
165 };
166
167 static inline off_t __EVEN( off_t i )
168 {
169     return (i & 1) ? i + 1 : i;
170 }
171
172 static mtime_t AVI_PTSToChunk( avi_track_t *, mtime_t i_pts );
173 static mtime_t AVI_PTSToByte ( avi_track_t *, mtime_t i_pts );
174 static mtime_t AVI_GetDPTS   ( avi_track_t *, int64_t i_count );
175 static mtime_t AVI_GetPTS    ( avi_track_t * );
176
177
178 static int AVI_StreamChunkFind( demux_t *, unsigned int i_stream );
179 static int AVI_StreamChunkSet ( demux_t *,
180                                 unsigned int i_stream, unsigned int i_ck );
181 static int AVI_StreamBytesSet ( demux_t *,
182                                 unsigned int i_stream, off_t   i_byte );
183
184 vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t );
185 static int   AVI_GetKeyFlag    ( vlc_fourcc_t , uint8_t * );
186
187 static int AVI_PacketGetHeader( demux_t *, avi_packet_t *p_pk );
188 static int AVI_PacketNext     ( demux_t * );
189 static int AVI_PacketRead     ( demux_t *, avi_packet_t *, block_t **);
190 static int AVI_PacketSearch   ( demux_t * );
191
192 static void AVI_IndexLoad    ( demux_t * );
193 static void AVI_IndexCreate  ( demux_t * );
194 static void AVI_IndexAddEntry( demux_sys_t *, int, avi_entry_t * );
195
196 static mtime_t  AVI_MovieGetLength( demux_t * );
197
198 /*****************************************************************************
199  * Stream management
200  *****************************************************************************/
201 static int        AVI_TrackSeek  ( demux_t *, int, mtime_t );
202 static int        AVI_TrackStopFinishedStreams( demux_t *);
203
204 /* Remarks:
205  - For VBR mp3 stream:
206     count blocks by rounded-up chunksizes instead of chunks
207     we need full emulation of dshow avi demuxer bugs :(
208     fixes silly nandub-style a-v delaying in avi with vbr mp3...
209     (from mplayer 2002/08/02)
210  - to complete....
211  */
212
213 /*****************************************************************************
214  * Open: check file and initializes AVI structures
215  *****************************************************************************/
216 static int Open( vlc_object_t * p_this )
217 {
218     demux_t  *p_demux = (demux_t *)p_this;
219     demux_sys_t     *p_sys;
220
221     bool       b_index = false;
222     int              i_do_index;
223
224     avi_chunk_t         ck_riff;
225     avi_chunk_list_t    *p_riff = (avi_chunk_list_t*)&ck_riff;
226     avi_chunk_list_t    *p_hdrl, *p_movi;
227     avi_chunk_avih_t    *p_avih;
228
229     unsigned int i_track;
230     unsigned int i, i_peeker;
231
232     const uint8_t *p_peek;
233
234     /* Is it an avi file ? */
235     if( stream_Peek( p_demux->s, &p_peek, 200 ) < 200 ) return VLC_EGENERIC;
236
237     for( i_peeker = 0; i_peeker < 188; i_peeker++ )
238     {
239         if( !strncmp( (char *)&p_peek[0], "RIFF", 4 ) && !strncmp( (char *)&p_peek[8], "AVI ", 4 ) )
240             break;
241         if( !strncmp( (char *)&p_peek[0], "ON2 ", 4 ) && !strncmp( (char *)&p_peek[8], "ON2f", 4 ) )
242             break;
243         p_peek++;
244     }
245     if( i_peeker == 188 )
246     {
247         return VLC_EGENERIC;
248     }
249
250     /* Initialize input  structures. */
251     p_sys = p_demux->p_sys = malloc( sizeof(demux_sys_t) );
252     memset( p_sys, 0, sizeof( demux_sys_t ) );
253     p_sys->i_time   = 0;
254     p_sys->i_length = 0;
255     p_sys->i_movi_lastchunk_pos = 0;
256     p_sys->b_odml   = false;
257     p_sys->b_muxed  = false;
258     p_sys->i_track  = 0;
259     p_sys->track    = NULL;
260     p_sys->meta     = NULL;
261
262     stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &p_sys->b_seekable );
263
264     p_demux->pf_control = Control;
265     p_demux->pf_demux = Demux_Seekable;
266
267     /* For unseekable stream, automaticaly use Demux_UnSeekable */
268     if( !p_sys->b_seekable || config_GetInt( p_demux, "avi-interleaved" ) )
269     {
270         p_demux->pf_demux = Demux_UnSeekable;
271     }
272
273     if( i_peeker > 0 )
274     {
275         stream_Read( p_demux->s, NULL, i_peeker );
276     }
277
278     if( AVI_ChunkReadRoot( p_demux->s, &p_sys->ck_root ) )
279     {
280         msg_Err( p_demux, "avi module discarded (invalid file)" );
281         return VLC_EGENERIC;
282     }
283
284     if( AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF ) > 1 )
285     {
286         unsigned int i_count =
287             AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF );
288
289         msg_Warn( p_demux, "multiple riff -> OpenDML ?" );
290         for( i = 1; i < i_count; i++ )
291         {
292             avi_chunk_list_t *p_sysx;
293
294             p_sysx = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, i );
295             if( p_sysx->i_type == AVIFOURCC_AVIX )
296             {
297                 msg_Warn( p_demux, "detected OpenDML file" );
298                 p_sys->b_odml = true;
299                 break;
300             }
301         }
302     }
303
304     p_riff  = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0 );
305     p_hdrl  = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0 );
306     p_movi  = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0 );
307
308     if( !p_hdrl || !p_movi )
309     {
310         msg_Err( p_demux, "avi module discarded (invalid file)" );
311         goto error;
312     }
313
314     if( !( p_avih = AVI_ChunkFind( p_hdrl, AVIFOURCC_avih, 0 ) ) )
315     {
316         msg_Err( p_demux, "cannot find avih chunk" );
317         goto error;
318     }
319     i_track = AVI_ChunkCount( p_hdrl, AVIFOURCC_strl );
320     if( p_avih->i_streams != i_track )
321     {
322         msg_Warn( p_demux,
323                   "found %d stream but %d are declared",
324                   i_track, p_avih->i_streams );
325     }
326     if( i_track == 0 )
327     {
328         msg_Err( p_demux, "no stream defined!" );
329         goto error;
330     }
331
332     /* print information on streams */
333     msg_Dbg( p_demux, "AVIH: %d stream, flags %s%s%s%s ",
334              i_track,
335              p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
336              p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
337              p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
338              p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
339     if( ( p_sys->meta = vlc_meta_New() ) )
340     {
341         char buffer[200];
342         sprintf( buffer, "%s%s%s%s",
343                  p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
344                  p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
345                  p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
346                  p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
347         vlc_meta_SetSetting( p_sys->meta, buffer );
348     }
349
350     /* now read info on each stream and create ES */
351     for( i = 0 ; i < i_track; i++ )
352     {
353         avi_track_t           *tk     = malloc( sizeof( avi_track_t ) );
354         if( !tk )
355             goto error;
356
357         avi_chunk_list_t      *p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i );
358         avi_chunk_strh_t      *p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0 );
359         avi_chunk_STRING_t    *p_strn = AVI_ChunkFind( p_strl, AVIFOURCC_strn, 0 );
360         avi_chunk_strf_auds_t *p_auds = NULL;
361         avi_chunk_strf_vids_t *p_vids = NULL;
362         es_format_t fmt;
363
364         memset( tk, 0, sizeof( avi_track_t ) );
365
366         p_vids = (avi_chunk_strf_vids_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
367         p_auds = (avi_chunk_strf_auds_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
368
369         if( p_strl == NULL || p_strh == NULL || p_auds == NULL || p_vids == NULL )
370         {
371             msg_Warn( p_demux, "stream[%d] incomplete", i );
372             continue;
373         }
374
375         tk->i_rate  = p_strh->i_rate;
376         tk->i_scale = p_strh->i_scale;
377         tk->i_samplesize = p_strh->i_samplesize;
378         msg_Dbg( p_demux, "stream[%d] rate:%d scale:%d samplesize:%d",
379                  i, tk->i_rate, tk->i_scale, tk->i_samplesize );
380
381         switch( p_strh->i_type )
382         {
383             case( AVIFOURCC_auds ):
384                 tk->i_cat   = AUDIO_ES;
385                 tk->i_codec = AVI_FourccGetCodec( AUDIO_ES,
386                                                   p_auds->p_wf->wFormatTag );
387
388                 tk->i_blocksize = p_auds->p_wf->nBlockAlign;
389                 if( tk->i_blocksize == 0 )
390                 {
391                     if( p_auds->p_wf->wFormatTag == 1 )
392                         tk->i_blocksize = p_auds->p_wf->nChannels * (p_auds->p_wf->wBitsPerSample/8);
393                     else
394                         tk->i_blocksize = 1;
395                 }
396                 else if( tk->i_samplesize != 0 && tk->i_samplesize != tk->i_blocksize )
397                 {
398                     msg_Warn( p_demux, "track[%d] samplesize=%d and blocksize=%d are not equal."
399                                        "Using blocksize as a workaround.",
400                                        i, tk->i_samplesize, tk->i_blocksize );
401                     tk->i_samplesize = tk->i_blocksize;
402                 }
403
404                 if( tk->i_codec == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
405                 {
406                     tk->i_blocksize = 0; /* fix vorbis VBR decoding */
407                 }
408
409                 es_format_Init( &fmt, AUDIO_ES, tk->i_codec );
410
411                 fmt.audio.i_channels        = p_auds->p_wf->nChannels;
412                 fmt.audio.i_rate            = p_auds->p_wf->nSamplesPerSec;
413                 fmt.i_bitrate               = p_auds->p_wf->nAvgBytesPerSec*8;
414                 fmt.audio.i_blockalign      = p_auds->p_wf->nBlockAlign;
415                 fmt.audio.i_bitspersample   = p_auds->p_wf->wBitsPerSample;
416                 fmt.b_packetized            = !tk->i_blocksize;
417
418                 msg_Dbg( p_demux,
419                     "stream[%d] audio(0x%x) %d channels %dHz %dbits",
420                     i, p_auds->p_wf->wFormatTag, p_auds->p_wf->nChannels,
421                     p_auds->p_wf->nSamplesPerSec,
422                     p_auds->p_wf->wBitsPerSample );
423
424                 fmt.i_extra = __MIN( p_auds->p_wf->cbSize,
425                     p_auds->i_chunk_size - sizeof(WAVEFORMATEX) );
426                 fmt.p_extra = tk->p_extra = malloc( fmt.i_extra );
427                 if( !fmt.p_extra ) goto error;
428                 memcpy( fmt.p_extra, &p_auds->p_wf[1], fmt.i_extra );
429
430                 /* Rewrite the vorbis headers from Xiph-like format
431                  * to VLC internal format
432                  *
433                  * Xiph format:
434                  *  - 1st byte == N, is the number of packets - 1
435                  *  - Following bytes are the size of the N first packets:
436                  *      while( *p == 0xFF ) { size += 0xFF; p++ } size += *p;
437                  *      (the size of the last packet is the size of remaining
438                  *      data in the buffer)
439                  *  - Finally, all the packets concatenated
440                  *
441                  * VLC format:
442                  *  - Size of the packet on 16 bits (big endian) FIXME: should be 32 bits to be safe
443                  *  - The packet itself
444                  *  - Size of the next packet, and so on ...
445                  */
446
447                 if( tk->i_codec == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
448                 {
449                     uint8_t *p_extra = fmt.p_extra;
450                     size_t i_extra = fmt.i_extra;
451
452                     if( i_extra <= 1 ) break;
453                     if( *p_extra++ != 2 ) break; /* 3 packets - 1 = 2 */
454                     i_extra--;
455
456                     size_t i_identifier_len = 0;
457                     while( *p_extra == 0xFF )
458                     {
459                         i_identifier_len += 0xFF;
460                         p_extra++;
461                         if( --i_extra <= 1 ) break;
462                     }
463                     i_identifier_len += *p_extra++;
464                     if( i_identifier_len > --i_extra ) break;
465
466                     size_t i_comment_len = 0;
467                     while( *p_extra == 0xFF )
468                     {
469                         i_comment_len += 0xFF;
470                         p_extra++;
471                         if( --i_extra <= 1 ) break;
472                     }
473                     i_comment_len += *p_extra++;
474                     if( i_comment_len > --i_extra ) break;
475                     size_t i_cookbook_len = i_extra;
476
477                     size_t i_headers_size = 3  * 2 + i_identifier_len +
478                                             i_comment_len + i_cookbook_len;
479                     uint8_t *p_out = malloc( i_headers_size );
480                     if( !p_out ) goto error;
481                     free( fmt.p_extra );
482                     fmt.p_extra = tk->p_extra = p_out;
483                     fmt.i_extra = i_headers_size;
484                     #define copy_packet( len ) \
485                         *p_out++ = len >> 8; \
486                         *p_out++ = len & 0xFF; \
487                         memcpy( p_out, p_extra, len ); \
488                         p_out += len; \
489                         p_extra += len;
490                     copy_packet( i_identifier_len );
491                     copy_packet( i_comment_len );
492                     copy_packet( i_cookbook_len );
493                     #undef copy_packet
494                     break;
495                 }
496                 break;
497
498             case( AVIFOURCC_vids ):
499                 tk->i_cat   = VIDEO_ES;
500                 tk->i_codec = AVI_FourccGetCodec( VIDEO_ES,
501                                                   p_vids->p_bih->biCompression );
502                 if( p_vids->p_bih->biCompression == 0x00 )
503                 {
504                     switch( p_vids->p_bih->biBitCount )
505                     {
506                         case 32:
507                             tk->i_codec = VLC_FOURCC('R','V','3','2');
508                             break;
509                         case 24:
510                             tk->i_codec = VLC_FOURCC('R','V','2','4');
511                             break;
512                         case 16:
513                             /* tk->i_codec = VLC_FOURCC('R','V','1','6');*/
514                             /* break;*/
515                         case 15:
516                             tk->i_codec = VLC_FOURCC('R','V','1','5');
517                             break;
518                         case 9:
519                             tk->i_codec = VLC_FOURCC( 'Y', 'V', 'U', '9' ); /* <- TODO check that */
520                             break;
521                         case 8:
522                             tk->i_codec = VLC_FOURCC('Y','8','0','0');
523                             break;
524                     }
525                     es_format_Init( &fmt, VIDEO_ES, tk->i_codec );
526
527                     if( p_vids->p_bih->biBitCount == 24 )
528                     {
529                         /* This is in BGR format */
530                         fmt.video.i_bmask = 0x00ff0000;
531                         fmt.video.i_gmask = 0x0000ff00;
532                         fmt.video.i_rmask = 0x000000ff;
533                     }
534                 }
535                 else
536                 {
537                     es_format_Init( &fmt, VIDEO_ES, p_vids->p_bih->biCompression );
538                     if( tk->i_codec == FOURCC_mp4v &&
539                         !strncasecmp( (char*)&p_strh->i_handler, "XVID", 4 ) )
540                     {
541                         fmt.i_codec = VLC_FOURCC( 'X', 'V', 'I', 'D' );
542                     }
543                 }
544                 tk->i_samplesize = 0;
545                 fmt.video.i_width  = p_vids->p_bih->biWidth;
546                 fmt.video.i_height = p_vids->p_bih->biHeight;
547                 fmt.video.i_bits_per_pixel = p_vids->p_bih->biBitCount;
548                 fmt.video.i_frame_rate = tk->i_rate;
549                 fmt.video.i_frame_rate_base = tk->i_scale;
550                 fmt.i_extra =
551                     __MIN( p_vids->p_bih->biSize - sizeof( BITMAPINFOHEADER ),
552                            p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER) );
553                 fmt.p_extra = &p_vids->p_bih[1];
554                 msg_Dbg( p_demux, "stream[%d] video(%4.4s) %"PRIu32"x%"PRIu32" %dbpp %ffps",
555                          i, (char*)&p_vids->p_bih->biCompression,
556                          (uint32_t)p_vids->p_bih->biWidth,
557                          (uint32_t)p_vids->p_bih->biHeight,
558                          p_vids->p_bih->biBitCount,
559                          (float)tk->i_rate/(float)tk->i_scale );
560
561                 if( p_vids->p_bih->biCompression == 0x00 )
562                 {
563                     /* RGB DIB are coded from bottom to top */
564                     fmt.video.i_height =
565                         (unsigned int)(-(int)p_vids->p_bih->biHeight);
566                 }
567
568                 /* Extract palette from extradata if bpp <= 8
569                  * (assumes that extradata contains only palette but appears
570                  *  to be true for all palettized codecs we support) */
571                 if( fmt.video.i_bits_per_pixel > 0 && fmt.video.i_bits_per_pixel <= 8 )
572                 {
573                     /* The palette is not always included in biSize */
574                     fmt.i_extra = p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER);
575                     if( fmt.i_extra > 0 )
576                     {
577                         const uint8_t *p_pal = fmt.p_extra;
578
579                         fmt.video.p_palette = calloc( sizeof(video_palette_t), 1 );
580                         fmt.video.p_palette->i_entries = __MIN(fmt.i_extra/4, 256);
581
582                         for( int i = 0; i < fmt.video.p_palette->i_entries; i++ )
583                         {
584                             for( int j = 0; j < 4; j++ )
585                                 fmt.video.p_palette->palette[i][j] = p_pal[4*i+j];
586                         }
587                     }
588                 }
589                 break;
590
591             case( AVIFOURCC_txts):
592                 tk->i_cat   = SPU_ES;
593                 tk->i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
594                 msg_Dbg( p_demux, "stream[%d] subtitles", i );
595                 es_format_Init( &fmt, SPU_ES, tk->i_codec );
596                 break;
597
598             case( AVIFOURCC_iavs):
599             case( AVIFOURCC_ivas):
600                 p_sys->b_muxed = true;
601                 msg_Dbg( p_demux, "stream[%d] iavs with handler %4.4s", i, (char *)&p_strh->i_handler );
602                 if( p_strh->i_handler == FOURCC_dvsd ||
603                     p_strh->i_handler == FOURCC_dvhd ||
604                     p_strh->i_handler == FOURCC_dvsl ||
605                     p_strh->i_handler == FOURCC_dv25 ||
606                     p_strh->i_handler == FOURCC_dv50 )
607                 {
608                     tk->p_out_muxed = stream_DemuxNew( p_demux, (char *)"rawdv", p_demux->out );
609                     if( !tk->p_out_muxed )
610                         msg_Err( p_demux, "could not load the DV parser" );
611                     else break;
612                 }
613                 free( tk );
614                 continue;
615
616             case( AVIFOURCC_mids):
617                 msg_Dbg( p_demux, "stream[%d] midi is UNSUPPORTED", i );
618
619             default:
620                 msg_Warn( p_demux, "stream[%d] unknown type %4.4s", i, (char *)&p_strh->i_type );
621                 free( tk );
622                 continue;
623         }
624         if( p_strn )
625         {
626             /* The charset of p_strn is undefined */
627             EnsureUTF8( p_strn->p_str );
628             fmt.psz_description = strdup( p_strn->p_str );
629         }
630         if( tk->p_out_muxed == NULL )
631             tk->p_es = es_out_Add( p_demux->out, &fmt );
632         TAB_APPEND( p_sys->i_track, p_sys->track, tk );
633     }
634
635     if( p_sys->i_track <= 0 )
636     {
637         msg_Err( p_demux, "no valid track" );
638         goto error;
639     }
640
641     i_do_index =  config_GetInt( p_demux, "avi-index" );
642     if( i_do_index == 1 ) /* Always fix */
643     {
644 aviindex:
645         if( p_sys->b_seekable )
646         {
647             AVI_IndexCreate( p_demux );
648         }
649         else
650         {
651             msg_Warn( p_demux, "cannot create index (unseekable stream)" );
652             AVI_IndexLoad( p_demux );
653         }
654     }
655     else
656     {
657         AVI_IndexLoad( p_demux );
658     }
659
660     /* *** movie length in sec *** */
661     p_sys->i_length = AVI_MovieGetLength( p_demux );
662     if( p_sys->i_length < (mtime_t)p_avih->i_totalframes *
663                           (mtime_t)p_avih->i_microsecperframe /
664                           (mtime_t)1000000 )
665     {
666         msg_Warn( p_demux, "broken or missing index, 'seek' will be "
667                            "approximative or will exhibit strange behavior" );
668         if( i_do_index == 0 && !b_index )
669         {
670             if( !p_sys->b_seekable ) {
671                 b_index = true;
672                 goto aviindex;
673             }
674             int i_create;
675             i_create = intf_UserYesNo( p_demux, _("AVI Index") ,
676                         _( "This AVI file is broken. Seeking will not "
677                         "work correctly.\nDo you want to "
678                         "try to repair it?\n\nThis might take a long time." ),
679                         _( "Repair" ), _( "Don't repair" ), _( "Cancel") );
680             if( i_create == DIALOG_OK_YES )
681             {
682                 b_index = true;
683                 msg_Dbg( p_demux, "Fixing AVI index" );
684                 goto aviindex;
685             }
686             else if( i_create == DIALOG_CANCELLED )
687             {
688                 /* Kill input */
689                 vlc_object_kill( p_demux->p_parent );
690                 goto error;
691             }
692         }
693     }
694
695     /* fix some BeOS MediaKit generated file */
696     for( i = 0 ; i < p_sys->i_track; i++ )
697     {
698         avi_track_t         *tk = p_sys->track[i];
699         avi_chunk_list_t    *p_strl;
700         avi_chunk_strh_t    *p_strh;
701         avi_chunk_strf_auds_t    *p_auds;
702
703         if( tk->i_cat != AUDIO_ES )
704         {
705             continue;
706         }
707         if( tk->i_idxnb < 1 ||
708             tk->i_scale != 1 ||
709             tk->i_samplesize != 0 )
710         {
711             continue;
712         }
713         p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i );
714         p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0 );
715         p_auds = AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
716
717         if( p_auds->p_wf->wFormatTag != WAVE_FORMAT_PCM &&
718             (unsigned int)tk->i_rate == p_auds->p_wf->nSamplesPerSec )
719         {
720             int64_t i_track_length =
721                 tk->p_index[tk->i_idxnb-1].i_length +
722                 tk->p_index[tk->i_idxnb-1].i_lengthtotal;
723             mtime_t i_length = (mtime_t)p_avih->i_totalframes *
724                                (mtime_t)p_avih->i_microsecperframe;
725
726             if( i_length == 0 )
727             {
728                 msg_Warn( p_demux, "track[%d] cannot be fixed (BeOS MediaKit generated)", i );
729                 continue;
730             }
731             tk->i_samplesize = 1;
732             tk->i_rate       = i_track_length  * (int64_t)1000000/ i_length;
733             msg_Warn( p_demux, "track[%d] fixed with rate=%d scale=%d (BeOS MediaKit generated)", i, tk->i_rate, tk->i_scale );
734         }
735     }
736
737     if( p_sys->b_seekable )
738     {
739         /* we have read all chunk so go back to movi */
740         stream_Seek( p_demux->s, p_movi->i_chunk_pos );
741     }
742     /* Skip movi header */
743     stream_Read( p_demux->s, NULL, 12 );
744
745     p_sys->i_movi_begin = p_movi->i_chunk_pos;
746     return VLC_SUCCESS;
747
748 error:
749     if( p_sys->meta )
750     {
751         vlc_meta_Delete( p_sys->meta );
752     }
753     AVI_ChunkFreeRoot( p_demux->s, &p_sys->ck_root );
754     free( p_sys );
755     return VLC_EGENERIC;
756 }
757
758 /*****************************************************************************
759  * Close: frees unused data
760  *****************************************************************************/
761 static void Close ( vlc_object_t * p_this )
762 {
763     demux_t *    p_demux = (demux_t *)p_this;
764     unsigned int i;
765     demux_sys_t *p_sys = p_demux->p_sys  ;
766
767     for( i = 0; i < p_sys->i_track; i++ )
768     {
769         if( p_sys->track[i] )
770         {
771             if( p_sys->track[i]->p_out_muxed )
772                 stream_DemuxDelete( p_sys->track[i]->p_out_muxed );
773             free( p_sys->track[i]->p_index );
774             free( p_sys->track[i]->p_extra );
775             free( p_sys->track[i] );
776         }
777     }
778     free( p_sys->track );
779     AVI_ChunkFreeRoot( p_demux->s, &p_sys->ck_root );
780     vlc_meta_Delete( p_sys->meta );
781
782     free( p_sys );
783 }
784
785 /*****************************************************************************
786  * Demux_Seekable: reads and demuxes data packets for stream seekable
787  *****************************************************************************
788  * AVIDemux: reads and demuxes data packets
789  *****************************************************************************
790  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
791  *****************************************************************************/
792 typedef struct
793 {
794     bool b_ok;
795
796     int i_toread;
797
798     off_t i_posf; /* where we will read :
799                    if i_idxposb == 0 : begining of chunk (+8 to acces data)
800                    else : point on data directly */
801 } avi_track_toread_t;
802
803 static int Demux_Seekable( demux_t *p_demux )
804 {
805     demux_sys_t *p_sys = p_demux->p_sys;
806
807     unsigned int i_track_count = 0;
808     unsigned int i_track;
809     bool b_stream;
810     /* cannot be more than 100 stream (dcXX or wbXX) */
811     avi_track_toread_t toread[100];
812
813
814     /* detect new selected/unselected streams */
815     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
816     {
817         avi_track_t *tk = p_sys->track[i_track];
818         bool  b;
819
820         if( p_sys->b_muxed && tk->p_out_muxed )
821         {
822             i_track_count++;
823             tk->b_activated = true;
824             continue;
825         }
826
827         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
828         if( b && !tk->b_activated )
829         {