1 /*****************************************************************************
2 * avi.c : AVI file Stream input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2009 the VideoLAN team
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_demux.h>
35 #include <vlc_input.h>
37 #include <vlc_dialog.h>
40 #include <vlc_codecs.h>
41 #include <vlc_charset.h>
42 #include <vlc_memory.h>
46 /*****************************************************************************
48 *****************************************************************************/
50 #define INTERLEAVE_TEXT N_("Force interleaved method" )
51 #define INTERLEAVE_LONGTEXT N_( "Force interleaved method." )
53 #define INDEX_TEXT N_("Force index creation")
54 #define INDEX_LONGTEXT N_( \
55 "Recreate a index for the AVI file. Use this if your AVI file is damaged "\
56 "or incomplete (not seekable)." )
58 static int Open ( vlc_object_t
* );
59 static void Close( vlc_object_t
* );
61 static const int pi_index
[] = {0,1,2};
63 static const char *const ppsz_indexes
[] = { N_("Ask for action"),
68 set_shortname( "AVI" )
69 set_description( N_("AVI demuxer") )
70 set_capability( "demux", 212 )
71 set_category( CAT_INPUT
)
72 set_subcategory( SUBCAT_INPUT_DEMUX
)
74 add_bool( "avi-interleaved", false,
75 INTERLEAVE_TEXT
, INTERLEAVE_LONGTEXT
, true )
76 add_integer( "avi-index", 0,
77 INDEX_TEXT
, INDEX_LONGTEXT
, false )
78 change_integer_list( pi_index
, ppsz_indexes
)
80 set_callbacks( Open
, Close
)
83 /*****************************************************************************
85 *****************************************************************************/
86 static int Control ( demux_t
*, int, va_list );
87 static int Seek ( demux_t
*, mtime_t
, int );
88 static int Demux_Seekable ( demux_t
* );
89 static int Demux_UnSeekable( demux_t
* );
91 #define __ABS( x ) ( (x) < 0 ? (-(x)) : (x) )
93 static char *FromACP( const char *str
)
95 return FromCharset(vlc_pgettext("GetACP", "CP1252"), str
, strlen(str
));
100 vlc_fourcc_t i_fourcc
;
103 vlc_fourcc_t i_type
; /* only for AVIFOURCC_LIST */
105 uint8_t i_peek
[8]; /* first 8 bytes */
107 unsigned int i_stream
;
118 int64_t i_lengthtotal
;
126 avi_entry_t
*p_entry
;
129 static void avi_index_Init( avi_index_t
* );
130 static void avi_index_Clean( avi_index_t
* );
131 static void avi_index_Append( avi_index_t
*, off_t
*, avi_entry_t
* );
138 unsigned int i_cat
; /* AUDIO_ES, VIDEO_ES */
139 vlc_fourcc_t i_codec
;
143 unsigned int i_samplesize
;
150 unsigned int i_idxposc
; /* numero of chunk */
151 unsigned int i_idxposb
; /* byte in the current chunk */
153 /* For VBR audio only */
154 unsigned int i_blockno
;
155 unsigned int i_blocksize
;
157 /* For muxed streams */
158 stream_t
*p_out_muxed
;
173 off_t i_movi_lastchunk_pos
; /* XXX position of last valid chunk */
175 /* number of streams and information */
176 unsigned int i_track
;
182 unsigned int i_attachment
;
183 input_attachment_t
**attachment
;
186 static inline off_t
__EVEN( off_t i
)
188 return (i
& 1) ? i
+ 1 : i
;
191 static mtime_t
AVI_PTSToChunk( avi_track_t
*, mtime_t i_pts
);
192 static mtime_t
AVI_PTSToByte ( avi_track_t
*, mtime_t i_pts
);
193 static mtime_t
AVI_GetDPTS ( avi_track_t
*, int64_t i_count
);
194 static mtime_t
AVI_GetPTS ( avi_track_t
* );
197 static int AVI_StreamChunkFind( demux_t
*, unsigned int i_stream
);
198 static int AVI_StreamChunkSet ( demux_t
*,
199 unsigned int i_stream
, unsigned int i_ck
);
200 static int AVI_StreamBytesSet ( demux_t
*,
201 unsigned int i_stream
, off_t i_byte
);
203 vlc_fourcc_t
AVI_FourccGetCodec( unsigned int i_cat
, vlc_fourcc_t
);
204 static int AVI_GetKeyFlag ( vlc_fourcc_t
, uint8_t * );
206 static int AVI_PacketGetHeader( demux_t
*, avi_packet_t
*p_pk
);
207 static int AVI_PacketNext ( demux_t
* );
208 static int AVI_PacketRead ( demux_t
*, avi_packet_t
*, block_t
**);
209 static int AVI_PacketSearch ( demux_t
* );
211 static void AVI_IndexLoad ( demux_t
* );
212 static void AVI_IndexCreate ( demux_t
* );
214 static void AVI_ExtractSubtitle( demux_t
*, unsigned int i_stream
, avi_chunk_list_t
*, avi_chunk_STRING_t
* );
216 static mtime_t
AVI_MovieGetLength( demux_t
* );
218 static void AVI_MetaLoad( demux_t
*, avi_chunk_list_t
*p_riff
, avi_chunk_avih_t
*p_avih
);
220 /*****************************************************************************
222 *****************************************************************************/
223 static int AVI_TrackSeek ( demux_t
*, int, mtime_t
);
224 static int AVI_TrackStopFinishedStreams( demux_t
*);
227 - For VBR mp3 stream:
228 count blocks by rounded-up chunksizes instead of chunks
229 we need full emulation of dshow avi demuxer bugs :(
230 fixes silly nandub-style a-v delaying in avi with vbr mp3...
231 (from mplayer 2002/08/02)
235 /*****************************************************************************
236 * Open: check file and initializes AVI structures
237 *****************************************************************************/
238 static int Open( vlc_object_t
* p_this
)
240 demux_t
*p_demux
= (demux_t
*)p_this
;
243 bool b_index
= false;
246 avi_chunk_list_t
*p_riff
;
247 avi_chunk_list_t
*p_hdrl
, *p_movi
;
248 avi_chunk_avih_t
*p_avih
;
250 unsigned int i_track
;
251 unsigned int i
, i_peeker
;
253 const uint8_t *p_peek
;
255 /* Is it an avi file ? */
256 if( stream_Peek( p_demux
->s
, &p_peek
, 200 ) < 200 ) return VLC_EGENERIC
;
258 for( i_peeker
= 0; i_peeker
< 188; i_peeker
++ )
260 if( !strncmp( (char *)&p_peek
[0], "RIFF", 4 ) && !strncmp( (char *)&p_peek
[8], "AVI ", 4 ) )
262 if( !strncmp( (char *)&p_peek
[0], "ON2 ", 4 ) && !strncmp( (char *)&p_peek
[8], "ON2f", 4 ) )
266 if( i_peeker
== 188 )
271 /* Initialize input structures. */
272 p_sys
= p_demux
->p_sys
= malloc( sizeof(demux_sys_t
) );
273 memset( p_sys
, 0, sizeof( demux_sys_t
) );
276 p_sys
->i_movi_lastchunk_pos
= 0;
277 p_sys
->b_odml
= false;
278 p_sys
->b_muxed
= false;
282 TAB_INIT(p_sys
->i_attachment
, p_sys
->attachment
);
284 stream_Control( p_demux
->s
, STREAM_CAN_FASTSEEK
, &p_sys
->b_seekable
);
286 p_demux
->pf_control
= Control
;
287 p_demux
->pf_demux
= Demux_Seekable
;
289 /* For unseekable stream, automatically use Demux_UnSeekable */
290 if( !p_sys
->b_seekable
291 || var_InheritBool( p_demux
, "avi-interleaved" ) )
293 p_demux
->pf_demux
= Demux_UnSeekable
;
298 stream_Read( p_demux
->s
, NULL
, i_peeker
);
301 if( AVI_ChunkReadRoot( p_demux
->s
, &p_sys
->ck_root
) )
303 msg_Err( p_demux
, "avi module discarded (invalid file)" );
308 if( AVI_ChunkCount( &p_sys
->ck_root
, AVIFOURCC_RIFF
) > 1 )
310 unsigned int i_count
=
311 AVI_ChunkCount( &p_sys
->ck_root
, AVIFOURCC_RIFF
);
313 msg_Warn( p_demux
, "multiple riff -> OpenDML ?" );
314 for( i
= 1; i
< i_count
; i
++ )
316 avi_chunk_list_t
*p_sysx
;
318 p_sysx
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, i
);
319 if( p_sysx
->i_type
== AVIFOURCC_AVIX
)
321 msg_Warn( p_demux
, "detected OpenDML file" );
322 p_sys
->b_odml
= true;
328 p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0 );
329 p_hdrl
= AVI_ChunkFind( p_riff
, AVIFOURCC_hdrl
, 0 );
330 p_movi
= AVI_ChunkFind( p_riff
, AVIFOURCC_movi
, 0 );
332 if( !p_hdrl
|| !p_movi
)
334 msg_Err( p_demux
, "avi module discarded (invalid file)" );
338 if( !( p_avih
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_avih
, 0 ) ) )
340 msg_Err( p_demux
, "cannot find avih chunk" );
343 i_track
= AVI_ChunkCount( p_hdrl
, AVIFOURCC_strl
);
344 if( p_avih
->i_streams
!= i_track
)
347 "found %d stream but %d are declared",
348 i_track
, p_avih
->i_streams
);
352 msg_Err( p_demux
, "no stream defined!" );
356 /* print information on streams */
357 msg_Dbg( p_demux
, "AVIH: %d stream, flags %s%s%s%s ",
359 p_avih
->i_flags
&AVIF_HASINDEX
?" HAS_INDEX":"",
360 p_avih
->i_flags
&AVIF_MUSTUSEINDEX
?" MUST_USE_INDEX":"",
361 p_avih
->i_flags
&AVIF_ISINTERLEAVED
?" IS_INTERLEAVED":"",
362 p_avih
->i_flags
&AVIF_TRUSTCKTYPE
?" TRUST_CKTYPE":"" );
364 AVI_MetaLoad( p_demux
, p_riff
, p_avih
);
366 /* now read info on each stream and create ES */
367 for( i
= 0 ; i
< i_track
; i
++ )
369 avi_track_t
*tk
= malloc( sizeof( avi_track_t
) );
373 avi_chunk_list_t
*p_strl
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_strl
, i
);
374 avi_chunk_strh_t
*p_strh
= AVI_ChunkFind( p_strl
, AVIFOURCC_strh
, 0 );
375 avi_chunk_STRING_t
*p_strn
= AVI_ChunkFind( p_strl
, AVIFOURCC_strn
, 0 );
376 avi_chunk_strf_auds_t
*p_auds
= NULL
;
377 avi_chunk_strf_vids_t
*p_vids
= NULL
;
380 memset( tk
, 0, sizeof(*tk
) );
382 tk
->b_activated
= true;
384 p_vids
= (avi_chunk_strf_vids_t
*)AVI_ChunkFind( p_strl
, AVIFOURCC_strf
, 0 );
385 p_auds
= (avi_chunk_strf_auds_t
*)AVI_ChunkFind( p_strl
, AVIFOURCC_strf
, 0 );
387 if( p_strl
== NULL
|| p_strh
== NULL
|| p_auds
== NULL
|| p_vids
== NULL
)
389 msg_Warn( p_demux
, "stream[%d] incomplete", i
);
394 tk
->i_rate
= p_strh
->i_rate
;
395 tk
->i_scale
= p_strh
->i_scale
;
396 tk
->i_samplesize
= p_strh
->i_samplesize
;
397 msg_Dbg( p_demux
, "stream[%d] rate:%d scale:%d samplesize:%d",
398 i
, tk
->i_rate
, tk
->i_scale
, tk
->i_samplesize
);
400 switch( p_strh
->i_type
)
402 case( AVIFOURCC_auds
):
403 tk
->i_cat
= AUDIO_ES
;
404 if( p_auds
->p_wf
->wFormatTag
== WAVE_FORMAT_EXTENSIBLE
&&
405 p_auds
->p_wf
->cbSize
>= sizeof(WAVEFORMATEXTENSIBLE
) - sizeof(WAVEFORMATEX
) )
407 WAVEFORMATEXTENSIBLE
*p_wfe
= (WAVEFORMATEXTENSIBLE
*)p_auds
->p_wf
;
408 tk
->i_codec
= AVI_FourccGetCodec( AUDIO_ES
,
409 p_wfe
->SubFormat
.Data1
);
412 tk
->i_codec
= AVI_FourccGetCodec( AUDIO_ES
,
413 p_auds
->p_wf
->wFormatTag
);
415 tk
->i_blocksize
= p_auds
->p_wf
->nBlockAlign
;
416 if( tk
->i_blocksize
== 0 )
418 if( p_auds
->p_wf
->wFormatTag
== 1 )
419 tk
->i_blocksize
= p_auds
->p_wf
->nChannels
* (p_auds
->p_wf
->wBitsPerSample
/8);
423 else if( tk
->i_samplesize
!= 0 && tk
->i_samplesize
!= tk
->i_blocksize
)
425 msg_Warn( p_demux
, "track[%d] samplesize=%d and blocksize=%d are not equal."
426 "Using blocksize as a workaround.",
427 i
, tk
->i_samplesize
, tk
->i_blocksize
);
428 tk
->i_samplesize
= tk
->i_blocksize
;
431 if( tk
->i_codec
== VLC_CODEC_VORBIS
)
433 tk
->i_blocksize
= 0; /* fix vorbis VBR decoding */
436 es_format_Init( &fmt
, AUDIO_ES
, tk
->i_codec
);
438 fmt
.audio
.i_channels
= p_auds
->p_wf
->nChannels
;
439 fmt
.audio
.i_rate
= p_auds
->p_wf
->nSamplesPerSec
;
440 fmt
.i_bitrate
= p_auds
->p_wf
->nAvgBytesPerSec
*8;
441 fmt
.audio
.i_blockalign
= p_auds
->p_wf
->nBlockAlign
;
442 fmt
.audio
.i_bitspersample
= p_auds
->p_wf
->wBitsPerSample
;
443 fmt
.b_packetized
= !tk
->i_blocksize
;
446 "stream[%d] audio(0x%x - %s) %d channels %dHz %dbits",
447 i
, p_auds
->p_wf
->wFormatTag
,vlc_fourcc_GetDescription(AUDIO_ES
,tk
->i_codec
),
448 p_auds
->p_wf
->nChannels
,
449 p_auds
->p_wf
->nSamplesPerSec
,
450 p_auds
->p_wf
->wBitsPerSample
);
452 fmt
.i_extra
= __MIN( p_auds
->p_wf
->cbSize
,
453 p_auds
->i_chunk_size
- sizeof(WAVEFORMATEX
) );
454 if( fmt
.i_extra
> 0 )
456 fmt
.p_extra
= malloc( fmt
.i_extra
);
457 if( !fmt
.p_extra
) goto error
;
458 memcpy( fmt
.p_extra
, &p_auds
->p_wf
[1], fmt
.i_extra
);
462 case( AVIFOURCC_vids
):
463 tk
->i_cat
= VIDEO_ES
;
464 tk
->i_codec
= AVI_FourccGetCodec( VIDEO_ES
,
465 p_vids
->p_bih
->biCompression
);
466 if( p_vids
->p_bih
->biCompression
== VLC_FOURCC( 'D', 'X', 'S', 'B' ) )
468 msg_Dbg( p_demux
, "stream[%d] subtitles", i
);
469 es_format_Init( &fmt
, SPU_ES
, p_vids
->p_bih
->biCompression
);
473 else if( p_vids
->p_bih
->biCompression
== 0x00 )
475 switch( p_vids
->p_bih
->biBitCount
)
478 tk
->i_codec
= VLC_CODEC_RGB32
;
481 tk
->i_codec
= VLC_CODEC_RGB24
;
483 case 16: /* Yes it is RV15 */
485 tk
->i_codec
= VLC_CODEC_RGB15
;
487 case 9: /* <- TODO check that */
488 tk
->i_codec
= VLC_CODEC_I410
;
490 case 8: /* <- TODO check that */
491 tk
->i_codec
= VLC_CODEC_GREY
;
494 es_format_Init( &fmt
, VIDEO_ES
, tk
->i_codec
);
496 switch( tk
->i_codec
)
498 case VLC_CODEC_RGB24
:
499 case VLC_CODEC_RGB32
:
500 fmt
.video
.i_rmask
= 0x00ff0000;
501 fmt
.video
.i_gmask
= 0x0000ff00;
502 fmt
.video
.i_bmask
= 0x000000ff;
504 case VLC_CODEC_RGB15
:
505 fmt
.video
.i_rmask
= 0x7c00;
506 fmt
.video
.i_gmask
= 0x03e0;
507 fmt
.video
.i_bmask
= 0x001f;
515 es_format_Init( &fmt
, VIDEO_ES
, p_vids
->p_bih
->biCompression
);
516 if( tk
->i_codec
== VLC_CODEC_MP4V
&&
517 !strncasecmp( (char*)&p_strh
->i_handler
, "XVID", 4 ) )
520 fmt
.i_original_fourcc
= VLC_FOURCC( 'X', 'V', 'I', 'D' );
523 tk
->i_samplesize
= 0;
524 fmt
.video
.i_width
= p_vids
->p_bih
->biWidth
;
525 fmt
.video
.i_height
= p_vids
->p_bih
->biHeight
;
526 fmt
.video
.i_bits_per_pixel
= p_vids
->p_bih
->biBitCount
;
527 fmt
.video
.i_frame_rate
= tk
->i_rate
;
528 fmt
.video
.i_frame_rate_base
= tk
->i_scale
;
530 __MIN( p_vids
->p_bih
->biSize
- sizeof( BITMAPINFOHEADER
),
531 p_vids
->i_chunk_size
- sizeof(BITMAPINFOHEADER
) );
532 if( fmt
.i_extra
> 0 )
534 fmt
.p_extra
= malloc( fmt
.i_extra
);
535 if( !fmt
.p_extra
) goto error
;
536 memcpy( fmt
.p_extra
, &p_vids
->p_bih
[1], fmt
.i_extra
);
539 msg_Dbg( p_demux
, "stream[%d] video(%4.4s) %"PRIu32
"x%"PRIu32
" %dbpp %ffps",
540 i
, (char*)&p_vids
->p_bih
->biCompression
,
541 (uint32_t)p_vids
->p_bih
->biWidth
,
542 (uint32_t)p_vids
->p_bih
->biHeight
,
543 p_vids
->p_bih
->biBitCount
,
544 (float)tk
->i_rate
/(float)tk
->i_scale
);
546 if( p_vids
->p_bih
->biCompression
== 0x00 )
548 /* RGB DIB are coded from bottom to top */
550 (unsigned int)(-(int)p_vids
->p_bih
->biHeight
);
553 /* Extract palette from extradata if bpp <= 8
554 * (assumes that extradata contains only palette but appears
555 * to be true for all palettized codecs we support) */
556 if( fmt
.video
.i_bits_per_pixel
> 0 && fmt
.video
.i_bits_per_pixel
<= 8 )
558 /* The palette is not always included in biSize */
559 fmt
.i_extra
= p_vids
->i_chunk_size
- sizeof(BITMAPINFOHEADER
);
560 if( fmt
.i_extra
> 0 )
562 const uint8_t *p_pal
= fmt
.p_extra
;
564 fmt
.video
.p_palette
= calloc( 1, sizeof(video_palette_t
) );
565 fmt
.video
.p_palette
->i_entries
= __MIN(fmt
.i_extra
/4, 256);
567 for( int i
= 0; i
< fmt
.video
.p_palette
->i_entries
; i
++ )
569 for( int j
= 0; j
< 4; j
++ )
570 fmt
.video
.p_palette
->palette
[i
][j
] = p_pal
[4*i
+j
];
576 case( AVIFOURCC_txts
):
577 msg_Dbg( p_demux
, "stream[%d] subtitle attachment", i
);
578 AVI_ExtractSubtitle( p_demux
, i
, p_strl
, p_strn
);
582 case( AVIFOURCC_iavs
):
583 case( AVIFOURCC_ivas
):
584 p_sys
->b_muxed
= true;
585 msg_Dbg( p_demux
, "stream[%d] iavs with handler %4.4s", i
, (char *)&p_strh
->i_handler
);
586 if( p_strh
->i_handler
== FOURCC_dvsd
||
587 p_strh
->i_handler
== FOURCC_dvhd
||
588 p_strh
->i_handler
== FOURCC_dvsl
||
589 p_strh
->i_handler
== FOURCC_dv25
||
590 p_strh
->i_handler
== FOURCC_dv50
)
592 tk
->p_out_muxed
= stream_DemuxNew( p_demux
, (char *)"rawdv", p_demux
->out
);
593 if( !tk
->p_out_muxed
)
594 msg_Err( p_demux
, "could not load the DV parser" );
600 case( AVIFOURCC_mids
):
601 msg_Dbg( p_demux
, "stream[%d] midi is UNSUPPORTED", i
);
604 msg_Warn( p_demux
, "stream[%d] unknown type %4.4s", i
, (char *)&p_strh
->i_type
);
609 fmt
.psz_description
= FromACP( p_strn
->p_str
);
610 if( tk
->p_out_muxed
== NULL
)
611 tk
->p_es
= es_out_Add( p_demux
->out
, &fmt
);
612 TAB_APPEND( p_sys
->i_track
, p_sys
->track
, tk
);
615 es_format_Clean( &fmt
);
619 if( p_sys
->i_track
<= 0 )
621 msg_Err( p_demux
, "no valid track" );
625 i_do_index
= var_InheritInteger( p_demux
, "avi-index" );
626 if( i_do_index
== 1 ) /* Always fix */
629 if( p_sys
->b_seekable
)
631 AVI_IndexCreate( p_demux
);
635 msg_Warn( p_demux
, "cannot create index (unseekable stream)" );
636 AVI_IndexLoad( p_demux
);
641 AVI_IndexLoad( p_demux
);
644 /* *** movie length in sec *** */
645 p_sys
->i_length
= AVI_MovieGetLength( p_demux
);
647 /* Check the index completeness */
648 unsigned int i_idx_totalframes
= 0;
649 for( unsigned int i
= 0; i
< p_sys
->i_track
; i
++ )
651 const avi_track_t
*tk
= p_sys
->track
[i
];
652 if( tk
->i_cat
== VIDEO_ES
&& tk
->idx
.p_entry
)
653 i_idx_totalframes
= __MAX(i_idx_totalframes
, tk
->idx
.i_size
);
656 if( i_idx_totalframes
!= p_avih
->i_totalframes
&&
657 p_sys
->i_length
< (mtime_t
)p_avih
->i_totalframes
*
658 (mtime_t
)p_avih
->i_microsecperframe
/
661 if( !vlc_object_alive( p_demux
) )
664 msg_Warn( p_demux
, "broken or missing index, 'seek' will be "
665 "approximative or will exhibit strange behavior" );
666 if( i_do_index
== 0 && !b_index
)
668 if( !p_sys
->b_seekable
) {
672 switch( dialog_Question( p_demux
, _("Broken or missing AVI Index") ,
673 _( "Because this AVI file index is broken or missing, "
674 "seeking will not work correctly.\n"
675 "VLC won't repair your file but can temporary fix this "
676 "problem by building an index in memory.\n"
677 "This step might take a long time on a large file.\n"
678 "What do you want to do ?" ),
679 _( "Build index then play" ), _( "Play as is" ), _( "Do not play") ) )
683 msg_Dbg( p_demux
, "Fixing AVI index" );
687 vlc_object_kill( p_demux
->p_parent
);
693 /* fix some BeOS MediaKit generated file */
694 for( i
= 0 ; i
< p_sys
->i_track
; i
++ )
696 avi_track_t
*tk
= p_sys
->track
[i
];
697 avi_chunk_list_t
*p_strl
;
698 avi_chunk_strh_t
*p_strh
;
699 avi_chunk_strf_auds_t
*p_auds
;
701 if( tk
->i_cat
!= AUDIO_ES
)
705 if( tk
->idx
.i_size
< 1 ||
707 tk
->i_samplesize
!= 0 )
711 p_strl
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_strl
, i
);
712 p_strh
= AVI_ChunkFind( p_strl
, AVIFOURCC_strh
, 0 );
713 p_auds
= AVI_ChunkFind( p_strl
, AVIFOURCC_strf
, 0 );
715 if( p_auds
->p_wf
->wFormatTag
!= WAVE_FORMAT_PCM
&&
716 (unsigned int)tk
->i_rate
== p_auds
->p_wf
->nSamplesPerSec
)
718 int64_t i_track_length
=
719 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_length
+
720 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_lengthtotal
;
721 mtime_t i_length
= (mtime_t
)p_avih
->i_totalframes
*
722 (mtime_t
)p_avih
->i_microsecperframe
;
726 msg_Warn( p_demux
, "track[%d] cannot be fixed (BeOS MediaKit generated)", i
);
729 tk
->i_samplesize
= 1;
730 tk
->i_rate
= i_track_length
* (int64_t)1000000/ i_length
;
731 msg_Warn( p_demux
, "track[%d] fixed with rate=%d scale=%d (BeOS MediaKit generated)", i
, tk
->i_rate
, tk
->i_scale
);
735 if( p_sys
->b_seekable
)
737 /* we have read all chunk so go back to movi */
738 stream_Seek( p_demux
->s
, p_movi
->i_chunk_pos
);
740 /* Skip movi header */
741 stream_Read( p_demux
->s
, NULL
, 12 );
743 p_sys
->i_movi_begin
= p_movi
->i_chunk_pos
;
747 for( unsigned i
= 0; i
< p_sys
->i_attachment
; i
++)
748 vlc_input_attachment_Delete(p_sys
->attachment
[i
]);
749 free(p_sys
->attachment
);
752 vlc_meta_Delete( p_sys
->meta
);
754 AVI_ChunkFreeRoot( p_demux
->s
, &p_sys
->ck_root
);
756 return vlc_object_alive( p_demux
) ? VLC_EGENERIC
: VLC_ETIMEOUT
;
759 /*****************************************************************************
760 * Close: frees unused data
761 *****************************************************************************/
762 static void Close ( vlc_object_t
* p_this
)
764 demux_t
* p_demux
= (demux_t
*)p_this
;
766 demux_sys_t
*p_sys
= p_demux
->p_sys
;
768 for( i
= 0; i
< p_sys
->i_track
; i
++ )
770 if( p_sys
->track
[i
] )
772 if( p_sys
->track
[i
]->p_out_muxed
)
773 stream_Delete( p_sys
->track
[i
]->p_out_muxed
);
774 avi_index_Clean( &p_sys
->track
[i
]->idx
);
775 free( p_sys
->track
[i
] );
778 free( p_sys
->track
);
779 AVI_ChunkFreeRoot( p_demux
->s
, &p_sys
->ck_root
);
780 vlc_meta_Delete( p_sys
->meta
);
781 for( unsigned i
= 0; i
< p_sys
->i_attachment
; i
++)
782 vlc_input_attachment_Delete(p_sys
->attachment
[i
]);
783 free(p_sys
->attachment
);
788 /*****************************************************************************
789 * Demux_Seekable: reads and demuxes data packets for stream seekable
790 *****************************************************************************
791 * AVIDemux: reads and demuxes data packets
792 *****************************************************************************
793 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
794 *****************************************************************************/
801 off_t i_posf
; /* where we will read :
802 if i_idxposb == 0 : begining of chunk (+8 to acces data)
803 else : point on data directly */
804 } avi_track_toread_t
;
806 static int Demux_Seekable( demux_t
*p_demux
)
808 demux_sys_t
*p_sys
= p_demux
->p_sys
;
810 unsigned int i_track_count
= 0;
811 unsigned int i_track
;
812 /* cannot be more than 100 stream (dcXX or wbXX) */
813 avi_track_toread_t toread
[100];
816 /* detect new selected/unselected streams */
817 for( i_track
= 0; i_track
< p_sys
->i_track
; i_track
++ )
819 avi_track_t
*tk
= p_sys
->track
[i_track
];
822 if( p_sys
->b_muxed
&& tk
->p_out_muxed
)
825 tk
->b_activated
= true;
829 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
, tk
->p_es
, &b
);
830 if( b
&& !tk
->b_activated
)
832 if( p_sys
->b_seekable
)
834 AVI_TrackSeek( p_demux
, i_track
, p_sys
->i_time
);
836 tk
->b_activated
= true;
838 else if( !b
&& tk
->b_activated
)
840 tk
->b_activated
= false;
848 if( i_track_count
<= 0 )
850 int64_t i_length
= p_sys
->i_length
* (mtime_t
)1000000;
852 p_sys
->i_time
+= 25*1000; /* read 25ms */
855 if( p_sys
->i_time
>= i_length
)
859 msg_Warn( p_demux
, "no track selected, exiting..." );
863 /* wait for the good time */
864 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, p_sys
->i_time
+ 1 );
865 p_sys
->i_time
+= 25*1000; /* read 25ms */
868 for( i_track
= 0; i_track
< p_sys
->i_track
; i_track
++ )
870 avi_track_t
*tk
= p_sys
->track
[i_track
];
873 toread
[i_track
].b_ok
= tk
->b_activated
&& !tk
->b_eof
;
874 if( tk
->i_idxposc
< tk
->idx
.i_size
)
876 toread
[i_track
].i_posf
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_pos
;
877 if( tk
->i_idxposb
> 0 )
879 toread
[i_track
].i_posf
+= 8 + tk
->i_idxposb
;
884 toread
[i_track
].i_posf
= -1;
887 i_dpts
= p_sys
->i_time
- AVI_GetPTS( tk
);
889 if( tk
->i_samplesize
)
891 toread
[i_track
].i_toread
= AVI_PTSToByte( tk
, __ABS( i_dpts
) );
895 toread
[i_track
].i_toread
= AVI_PTSToChunk( tk
, __ABS( i_dpts
) );
900 toread
[i_track
].i_toread
*= -1;
913 /* search for first chunk to be read */
914 for( i
= 0, b_done
= true, i_pos
= -1; i
< p_sys
->i_track
; i
++ )
916 if( !toread
[i
].b_ok
||
917 AVI_GetDPTS( p_sys
->track
[i
],
918 toread
[i
].i_toread
) <= -25 * 1000 )
923 if( toread
[i
].i_toread
> 0 )
925 b_done
= false; /* not yet finished */
927 if( toread
[i
].i_posf
> 0 )
929 if( i_pos
== -1 || i_pos
> toread
[i
].i_posf
)
932 i_pos
= toread
[i
].i_posf
;
939 for( i
= 0; i
< p_sys
->i_track
; i
++ )
944 msg_Warn( p_demux
, "all tracks have failed, exiting..." );
950 int i_loop_count
= 0;
952 /* no valid index, we will parse directly the stream
953 * in case we fail we will disable all finished stream */
954 if( p_sys
->i_movi_lastchunk_pos
>= p_sys
->i_movi_begin
+ 12 )
956 stream_Seek( p_demux
->s
, p_sys
->i_movi_lastchunk_pos
);
957 if( AVI_PacketNext( p_demux
) )
959 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
964 stream_Seek( p_demux
->s
, p_sys
->i_movi_begin
+ 12 );
971 if( AVI_PacketGetHeader( p_demux
, &avi_pk
) )
974 "cannot get packet header, track disabled" );
975 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
977 if( avi_pk
.i_stream
>= p_sys
->i_track
||
978 ( avi_pk
.i_cat
!= AUDIO_ES
&& avi_pk
.i_cat
!= VIDEO_ES
) )
980 if( AVI_PacketNext( p_demux
) )
983 "cannot skip packet, track disabled" );
984 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
987 /* Prevents from eating all the CPU with broken files.
988 * This value should be low enough so that it doesn't
989 * affect the reading speed too much. */
990 if( !(++i_loop_count
% 1024) )
992 if( !vlc_object_alive (p_demux
) ) return -1;
995 if( !(i_loop_count
% (1024 * 10)) )
997 "don't seem to find any data..." );
1003 i_track
= avi_pk
.i_stream
;
1004 tk
= p_sys
->track
[i_track
];
1006 /* add this chunk to the index */
1008 index
.i_id
= avi_pk
.i_fourcc
;
1009 index
.i_flags
= AVI_GetKeyFlag(tk
->i_codec
, avi_pk
.i_peek
);
1010 index
.i_pos
= avi_pk
.i_pos
;
1011 index
.i_length
= avi_pk
.i_size
;
1012 avi_index_Append( &tk
->idx
, &p_sys
->i_movi_lastchunk_pos
, &index
);
1014 /* do we will read this data ? */
1015 if( AVI_GetDPTS( tk
, toread
[i_track
].i_toread
) > -25*1000 )
1021 if( AVI_PacketNext( p_demux
) )
1024 "cannot skip packet, track disabled" );
1025 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
1034 stream_Seek( p_demux
->s
, i_pos
);
1037 /* Set the track to use */
1038 tk
= p_sys
->track
[i_track
];
1040 /* read thoses data */
1041 if( tk
->i_samplesize
)
1043 unsigned int i_toread
;
1045 if( ( i_toread
= toread
[i_track
].i_toread
) <= 0 )
1047 if( tk
->i_samplesize
> 1 )
1049 i_toread
= tk
->i_samplesize
;
1053 i_toread
= AVI_PTSToByte( tk
, 20 * 1000 );
1054 i_toread
= __MAX( i_toread
, 100 );
1057 i_size
= __MIN( tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
-
1063 i_size
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
;
1066 if( tk
->i_idxposb
== 0 )
1068 i_size
+= 8; /* need to read and skip header */
1071 if( ( p_frame
= stream_Block( p_demux
->s
, __EVEN( i_size
) ) )==NULL
)
1073 msg_Warn( p_demux
, "failed reading data" );
1075 toread
[i_track
].b_ok
= false;
1078 if( i_size
% 2 ) /* read was padded on word boundary */
1080 p_frame
->i_buffer
--;
1083 if( tk
->i_idxposb
== 0 )
1085 p_frame
->p_buffer
+= 8;
1086 p_frame
->i_buffer
-= 8;
1088 p_frame
->i_pts
= AVI_GetPTS( tk
) + 1;
1089 if( tk
->idx
.p_entry
[tk
->i_idxposc
].i_flags
&AVIIF_KEYFRAME
)
1091 p_frame
->i_flags
= BLOCK_FLAG_TYPE_I
;
1095 p_frame
->i_flags
= BLOCK_FLAG_TYPE_PB
;
1099 if( tk
->i_samplesize
)
1101 if( tk
->i_idxposb
== 0 )
1105 toread
[i_track
].i_toread
-= i_size
;
1106 tk
->i_idxposb
+= i_size
;
1107 if( tk
->i_idxposb
>=
1108 tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
)
1116 int i_length
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
;
1119 if( tk
->i_cat
== AUDIO_ES
)
1121 tk
->i_blockno
+= tk
->i_blocksize
> 0 ? ( i_length
+ tk
->i_blocksize
- 1 ) / tk
->i_blocksize
: 1;
1123 toread
[i_track
].i_toread
--;
1126 if( tk
->i_idxposc
< tk
->idx
.i_size
)
1128 toread
[i_track
].i_posf
=
1129 tk
->idx
.p_entry
[tk
->i_idxposc
].i_pos
;
1130 if( tk
->i_idxposb
> 0 )
1132 toread
[i_track
].i_posf
+= 8 + tk
->i_idxposb
;
1138 toread
[i_track
].i_posf
= -1;
1141 if( tk
->i_cat
!= VIDEO_ES
)
1142 p_frame
->i_dts
= p_frame
->i_pts
;
1145 p_frame
->i_dts
= p_frame
->i_pts
;
1146 p_frame
->i_pts
= VLC_TS_INVALID
;
1149 //p_pes->i_rate = p_demux->stream.control.i_rate;
1150 if( tk
->p_out_muxed
)
1151 stream_DemuxSend( tk
->p_out_muxed
, p_frame
);
1153 es_out_Send( p_demux
->out
, tk
->p_es
, p_frame
);
1158 /*****************************************************************************
1159 * Demux_UnSeekable: reads and demuxes data packets for unseekable file
1160 *****************************************************************************
1161 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1162 *****************************************************************************/
1163 static int Demux_UnSeekable( demux_t
*p_demux
)
1165 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1166 avi_track_t
*p_stream_master
= NULL
;
1167 unsigned int i_stream
;
1168 unsigned int i_packet
;
1170 if( p_sys
->b_muxed
)
1172 msg_Err( p_demux
, "Can not yet process muxed avi substreams without seeking" );
1173 return VLC_EGENERIC
;
1176 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, p_sys
->i_time
+ 1 );
1178 /* *** find master stream for data packet skipping algo *** */
1179 /* *** -> first video, if any, or first audio ES *** */
1180 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
1182 avi_track_t
*tk
= p_sys
->track
[i_stream
];
1185 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
, tk
->p_es
, &b
);
1187 if( b
&& tk
->i_cat
== VIDEO_ES
)
1189 p_stream_master
= tk
;
1193 p_stream_master
= tk
;
1197 if( !p_stream_master
)
1199 msg_Warn( p_demux
, "no more stream selected" );
1203 p_sys
->i_time
= AVI_GetPTS( p_stream_master
);
1205 for( i_packet
= 0; i_packet
< 10; i_packet
++)
1207 #define p_stream p_sys->track[avi_pk.i_stream]
1209 avi_packet_t avi_pk
;
1211 if( AVI_PacketGetHeader( p_demux
, &avi_pk
) )
1216 if( avi_pk
.i_stream
>= p_sys
->i_track
||
1217 ( avi_pk
.i_cat
!= AUDIO_ES
&& avi_pk
.i_cat
!= VIDEO_ES
) )
1219 /* we haven't found an audio or video packet:
1220 * - we have seek, found first next packet
1221 * - others packets could be found, skip them
1223 switch( avi_pk
.i_fourcc
)
1225 case AVIFOURCC_JUNK
:
1226 case AVIFOURCC_LIST
:
1227 case AVIFOURCC_RIFF
:
1228 return( !AVI_PacketNext( p_demux
) ? 1 : 0 );
1229 case AVIFOURCC_idx1
:
1232 return( !AVI_PacketNext( p_demux
) ? 1 : 0 );
1234 return( 0 ); /* eof */
1237 "seems to have lost position, resync" );
1238 if( AVI_PacketSearch( p_demux
) )
1240 msg_Err( p_demux
, "resync failed" );
1247 /* check for time */
1248 if( __ABS( AVI_GetPTS( p_stream
) -
1249 AVI_GetPTS( p_stream_master
) )< 600*1000 )
1251 /* load it and send to decoder */
1253 if( AVI_PacketRead( p_demux
, &avi_pk
, &p_frame
) || p_frame
== NULL
)
1257 p_frame
->i_pts
= AVI_GetPTS( p_stream
) + 1;
1259 if( avi_pk
.i_cat
!= VIDEO_ES
)
1260 p_frame
->i_dts
= p_frame
->i_pts
;
1263 p_frame
->i_dts
= p_frame
->i_pts
;
1264 p_frame
->i_pts
= VLC_TS_INVALID
;
1267 //p_pes->i_rate = p_demux->stream.control.i_rate;
1268 es_out_Send( p_demux
->out
, p_stream
->p_es
, p_frame
);
1272 if( AVI_PacketNext( p_demux
) )
1278 /* *** update stream time position *** */
1279 if( p_stream
->i_samplesize
)
1281 p_stream
->i_idxposb
+= avi_pk
.i_size
;
1285 if( p_stream
->i_cat
== AUDIO_ES
)
1287 p_stream
->i_blockno
+= p_stream
->i_blocksize
> 0 ? ( avi_pk
.i_size
+ p_stream
->i_blocksize
- 1 ) / p_stream
->i_blocksize
: 1;
1289 p_stream
->i_idxposc
++;
1299 /*****************************************************************************
1300 * Seek: goto to i_date or i_percent
1301 *****************************************************************************/
1302 static int Seek( demux_t
*p_demux
, mtime_t i_date
, int i_percent
)
1305 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1306 unsigned int i_stream
;
1307 msg_Dbg( p_demux
, "seek requested: %"PRId64
" seconds %d%%",
1308 i_date
/ 1000000, i_percent
);
1310 if( p_sys
->b_seekable
)
1312 if( !p_sys
->i_length
)
1314 avi_track_t
*p_stream
;
1317 /* use i_percent to create a true i_date */
1318 msg_Warn( p_demux
, "seeking without index at %d%%"
1319 " only works for interleaved files", i_percent
);
1320 if( i_percent
>= 100 )
1322 msg_Warn( p_demux
, "cannot seek so far !" );
1323 return VLC_EGENERIC
;
1325 i_percent
= __MAX( i_percent
, 0 );
1327 /* try to find chunk that is at i_percent or the file */
1328 i_pos
= __MAX( i_percent
* stream_Size( p_demux
->s
) / 100,
1329 p_sys
->i_movi_begin
);
1330 /* search first selected stream (and prefer non eof ones) */
1331 for( i_stream
= 0, p_stream
= NULL
;
1332 i_stream
< p_sys
->i_track
; i_stream
++ )
1334 if( !p_stream
|| p_stream
->b_eof
)
1335 p_stream
= p_sys
->track
[i_stream
];
1337 if( p_stream
->b_activated
&& !p_stream
->b_eof
)
1340 if( !p_stream
|| !p_stream
->b_activated
)
1342 msg_Warn( p_demux
, "cannot find any selected stream" );
1343 return VLC_EGENERIC
;
1346 /* be sure that the index exist */
1347 if( AVI_StreamChunkSet( p_demux
, i_stream
, 0 ) )
1349 msg_Warn( p_demux
, "cannot seek" );
1350 return VLC_EGENERIC
;
1353 while( i_pos
>= p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_pos
+
1354 p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_length
+ 8 )
1356 /* search after i_idxposc */
1357 if( AVI_StreamChunkSet( p_demux
,
1358 i_stream
, p_stream
->i_idxposc
+ 1 ) )
1360 msg_Warn( p_demux
, "cannot seek" );
1361 return VLC_EGENERIC
;
1365 i_date
= AVI_GetPTS( p_stream
);
1366 /* TODO better support for i_samplesize != 0 */
1367 msg_Dbg( p_demux
, "estimate date %"PRId64
, i_date
);
1371 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
1373 avi_track_t
*p_stream
= p_sys
->track
[i_stream
];
1375 if( !p_stream
->b_activated
)
1378 p_stream
->b_eof
= AVI_TrackSeek( p_demux
, i_stream
, i_date
) != 0;
1380 es_out_Control( p_demux
->out
, ES_OUT_SET_NEXT_DISPLAY_TIME
, i_date
);
1381 p_sys
->i_time
= i_date
;
1382 msg_Dbg( p_demux
, "seek: %"PRId64
" seconds", p_sys
->i_time
/1000000 );
1387 msg_Err( p_demux
, "shouldn't yet be executed" );
1388 return VLC_EGENERIC
;
1392 /*****************************************************************************
1394 *****************************************************************************/
1395 static double ControlGetPosition( demux_t
*p_demux
)
1397 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1399 if( p_sys
->i_length
> 0 )
1401 return (double)p_sys
->i_time
/ (double)( p_sys
->i_length
* (mtime_t
)1000000 );
1403 else if( stream_Size( p_demux
->s
) > 0 )
1409 /* search the more advanced selected es */
1410 for( i
= 0; i
< p_sys
->i_track
; i
++ )
1412 avi_track_t
*tk
= p_sys
->track
[i
];
1413 if( tk
->b_activated
&& tk
->i_idxposc
< tk
->idx
.i_size
)
1415 i_tmp
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_pos
+
1416 tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
+ 8;
1423 return (double)i64
/ stream_Size( p_demux
->s
);
1428 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
1430 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1438 case DEMUX_GET_POSITION
:
1439 pf
= (double*)va_arg( args
, double * );
1440 *pf
= ControlGetPosition( p_demux
);
1442 case DEMUX_SET_POSITION
:
1443 f
= (double)va_arg( args
, double );
1444 if( p_sys
->b_seekable
)
1446 i64
= (mtime_t
)(1000000.0 * p_sys
->i_length
* f
);
1447 return Seek( p_demux
, i64
, (int)(f
* 100) );
1451 int64_t i_pos
= stream_Size( p_demux
->s
) * f
;
1452 return stream_Seek( p_demux
->s
, i_pos
);
1455 case DEMUX_GET_TIME
:
1456 pi64
= (int64_t*)va_arg( args
, int64_t * );
1457 *pi64
= p_sys
->i_time
;
1460 case DEMUX_SET_TIME
:
1464 i64
= (int64_t)va_arg( args
, int64_t );
1465 if( p_sys
->i_length
> 0 )
1467 i_percent
= 100 * i64
/ (p_sys
->i_length
*1000000);
1469 else if( p_sys
->i_time
> 0 )
1471 i_percent
= (int)( 100.0 * ControlGetPosition( p_demux
) *
1472 (double)i64
/ (double)p_sys
->i_time
);
1474 return Seek( p_demux
, i64
, i_percent
);
1476 case DEMUX_GET_LENGTH
:
1477 pi64
= (int64_t*)va_arg( args
, int64_t * );
1478 *pi64
= p_sys
->i_length
* (mtime_t
)1000000;
1482 pf
= (double*)va_arg( args
, double * );
1484 for( i
= 0; i
< (int)p_sys
->i_track
; i
++ )
1486 avi_track_t
*tk
= p_sys
->track
[i
];
1487 if( tk
->i_cat
== VIDEO_ES
&& tk
->i_scale
> 0)
1489 *pf
= (float)tk
->i_rate
/ (float)tk
->i_scale
;
1495 case DEMUX_GET_META
:
1496 p_meta
= (vlc_meta_t
*)va_arg( args
, vlc_meta_t
* );
1497 vlc_meta_Merge( p_meta
, p_sys
->meta
);
1500 case DEMUX_GET_ATTACHMENTS
:
1502 if( p_sys
->i_attachment
<= 0 )
1503 return VLC_EGENERIC
;
1505 input_attachment_t
***ppp_attach
= va_arg( args
, input_attachment_t
*** );
1506 int *pi_int
= va_arg( args
, int * );
1508 *pi_int
= p_sys
->i_attachment
;
1509 *ppp_attach
= calloc( p_sys
->i_attachment
, sizeof(*ppp_attach
));
1510 for( unsigned i
= 0; i
< p_sys
->i_attachment
&& *ppp_attach
; i
++ )
1511 (*ppp_attach
)[i
] = vlc_input_attachment_Duplicate( p_sys
->attachment
[i
] );
1516 return VLC_EGENERIC
;
1520 /*****************************************************************************
1521 * Function to convert pts to chunk or byte
1522 *****************************************************************************/
1524 static mtime_t
AVI_PTSToChunk( avi_track_t
*tk
, mtime_t i_pts
)
1529 return (mtime_t
)((int64_t)i_pts
*
1530 (int64_t)tk
->i_rate
/
1531 (int64_t)tk
->i_scale
/
1534 static mtime_t
AVI_PTSToByte( avi_track_t
*tk
, mtime_t i_pts
)
1536 if( !tk
->i_scale
|| !tk
->i_samplesize
)
1539 return (mtime_t
)((int64_t)i_pts
*
1540 (int64_t)tk
->i_rate
/
1541 (int64_t)tk
->i_scale
/
1543 (int64_t)tk
->i_samplesize
);
1546 static mtime_t
AVI_GetDPTS( avi_track_t
*tk
, int64_t i_count
)
1553 i_dpts
= (mtime_t
)( (int64_t)1000000 *
1555 (int64_t)tk
->i_scale
/
1556 (int64_t)tk
->i_rate
);
1558 if( tk
->i_samplesize
)
1560 return i_dpts
/ tk
->i_samplesize
;
1565 static mtime_t
AVI_GetPTS( avi_track_t
*tk
)
1567 if( tk
->i_samplesize
)
1569 int64_t i_count
= 0;
1571 /* we need a valid entry we will emulate one */
1572 if( tk
->i_idxposc
== tk
->idx
.i_size
)
1576 /* use the last entry */
1577 i_count
= tk
->idx
.p_entry
[tk
->idx
.i_size
- 1].i_lengthtotal
1578 + tk
->idx
.p_entry
[tk
->idx
.i_size
- 1].i_length
;
1583 i_count
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_lengthtotal
;
1585 return AVI_GetDPTS( tk
, i_count
+ tk
->i_idxposb
);
1589 if( tk
->i_cat
== AUDIO_ES
)
1591 return AVI_GetDPTS( tk
, tk
->i_blockno
);
1595 return AVI_GetDPTS( tk
, tk
->i_idxposc
);
1600 static int AVI_StreamChunkFind( demux_t
*p_demux
, unsigned int i_stream
)
1602 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1603 avi_packet_t avi_pk
;
1604 int i_loop_count
= 0;
1606 /* find first chunk of i_stream that isn't in index */
1608 if( p_sys
->i_movi_lastchunk_pos
>= p_sys
->i_movi_begin
+ 12 )
1610 stream_Seek( p_demux
->s
, p_sys
->i_movi_lastchunk_pos
);
1611 if( AVI_PacketNext( p_demux
) )
1613 return VLC_EGENERIC
;
1618 stream_Seek( p_demux
->s
, p_sys
->i_movi_begin
+ 12 );
1623 if( !vlc_object_alive (p_demux
) ) return VLC_EGENERIC
;
1625 if( AVI_PacketGetHeader( p_demux
, &avi_pk
) )
1627 msg_Warn( p_demux
, "cannot get packet header" );
1628 return VLC_EGENERIC
;
1630 if( avi_pk
.i_stream
>= p_sys
->i_track
||
1631 ( avi_pk
.i_cat
!= AUDIO_ES
&& avi_pk
.i_cat
!= VIDEO_ES
) )
1633 if( AVI_PacketNext( p_demux
) )
1635 return VLC_EGENERIC
;
1638 /* Prevents from eating all the CPU with broken files.
1639 * This value should be low enough so that it doesn't
1640 * affect the reading speed too much. */
1641 if( !(++i_loop_count
% 1024) )
1643 if( !vlc_object_alive (p_demux
) ) return VLC_EGENERIC
;
1646 if( !(i_loop_count
% (1024 * 10)) )
1647 msg_Warn( p_demux
, "don't seem to find any data..." );
1652 avi_track_t
*tk_pk
= p_sys
->track
[avi_pk
.i_stream
];
1654 /* add this chunk to the index */
1656 index
.i_id
= avi_pk
.i_fourcc
;
1657 index
.i_flags
= AVI_GetKeyFlag(tk_pk
->i_codec
, avi_pk
.i_peek
);
1658 index
.i_pos
= avi_pk
.i_pos
;
1659 index
.i_length
= avi_pk
.i_size
;
1660 avi_index_Append( &tk_pk
->idx
, &p_sys
->i_movi_lastchunk_pos
, &index
);
1662 if( avi_pk
.i_stream
== i_stream
)
1667 if( AVI_PacketNext( p_demux
) )
1669 return VLC_EGENERIC
;
1675 /* be sure that i_ck will be a valid index entry */
1676 static int AVI_StreamChunkSet( demux_t
*p_demux
, unsigned int i_stream
,
1679 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1680 avi_track_t
*p_stream
= p_sys
->track
[i_stream
];
1682 p_stream
->i_idxposc
= i_ck
;
1683 p_stream
->i_idxposb
= 0;
1685 if( i_ck
>= p_stream
->idx
.i_size
)
1687 p_stream
->i_idxposc
= p_stream
->idx
.i_size
- 1;
1690 p_stream
->i_idxposc
++;
1691 if( AVI_StreamChunkFind( p_demux
, i_stream
) )
1693 return VLC_EGENERIC
;
1696 } while( p_stream
->i_idxposc
< i_ck
);
1702 /* XXX FIXME up to now, we assume that all chunk are one after one */
1703 static int AVI_StreamBytesSet( demux_t
*p_demux
,
1704 unsigned int i_stream
,
1707 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1708 avi_track_t
*p_stream
= p_sys
->track
[i_stream
];
1710 if( ( p_stream
->idx
.i_size
> 0 )
1711 &&( i_byte
< p_stream
->idx
.p_entry
[p_stream
->idx
.i_size
- 1].i_lengthtotal
+
1712 p_stream
->idx
.p_entry
[p_stream
->idx
.i_size
- 1].i_length
) )
1714 /* index is valid to find the ck */
1715 /* uses dichototmie to be fast enougth */
1716 int i_idxposc
= __MIN( p_stream
->i_idxposc
, p_stream
->idx
.i_size
- 1 );
1717 int i_idxmax
= p_stream
->idx
.i_size
;
1721 if( p_stream
->idx
.p_entry
[i_idxposc
].i_lengthtotal
> i_byte
)
1723 i_idxmax
= i_idxposc
;
1724 i_idxposc
= ( i_idxmin
+ i_idxposc
) / 2 ;
1728 if( p_stream
->idx
.p_entry
[i_idxposc
].i_lengthtotal
+
1729 p_stream
->idx
.p_entry
[i_idxposc
].i_length
<= i_byte
)
1731 i_idxmin
= i_idxposc
;
1732 i_idxposc
= (i_idxmax
+ i_idxposc
) / 2 ;
1736 p_stream
->i_idxposc
= i_idxposc
;
1737 p_stream
->i_idxposb
= i_byte
-
1738 p_stream
->idx
.p_entry
[i_idxposc
].i_lengthtotal
;
1747 p_stream
->i_idxposc
= p_stream
->idx
.i_size
- 1;
1748 p_stream
->i_idxposb
= 0;
1751 p_stream
->i_idxposc
++;
1752 if( AVI_StreamChunkFind( p_demux
, i_stream
) )
1754 return VLC_EGENERIC
;
1757 } while( p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_lengthtotal
+
1758 p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_length
<= i_byte
);
1760 p_stream
->i_idxposb
= i_byte
-
1761 p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_lengthtotal
;
1766 static int AVI_TrackSeek( demux_t
*p_demux
,
1770 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1771 avi_track_t
*tk
= p_sys
->track
[i_stream
];
1773 #define p_stream p_sys->track[i_stream]
1776 i_oldpts
= AVI_GetPTS( p_stream
);
1778 if( !p_stream
->i_samplesize
)
1780 if( AVI_StreamChunkSet( p_demux
,
1782 AVI_PTSToChunk( p_stream
, i_date
) ) )
1784 return VLC_EGENERIC
;
1787 if( p_stream
->i_cat
== AUDIO_ES
)
1791 for( i
= 0; i
< tk
->i_idxposc
; i
++ )
1793 if( tk
->i_blocksize
> 0 )
1795 tk
->i_blockno
+= ( tk
->idx
.p_entry
[i
].i_length
+ tk
->i_blocksize
- 1 ) / tk
->i_blocksize
;
1805 "old:%"PRId64
" %s new %"PRId64
,
1807 i_oldpts
> i_date
? ">" : "<",
1810 if( p_stream
->i_cat
== VIDEO_ES
)
1812 /* search key frame */
1813 //if( i_date < i_oldpts || 1 )
1815 while( p_stream
->i_idxposc
> 0 &&
1816 !( p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_flags
&
1819 if( AVI_StreamChunkSet( p_demux
,
1821 p_stream
->i_idxposc
- 1 ) )
1823 return VLC_EGENERIC
;
1830 while( p_stream
->i_idxposc
< p_stream
->idx
.i_size
&&
1831 !( p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_flags
&
1834 if( AVI_StreamChunkSet( p_demux
,
1836 p_stream
->i_idxposc
+ 1 ) )
1838 return VLC_EGENERIC
;
1847 if( AVI_StreamBytesSet( p_demux
,
1849 AVI_PTSToByte( p_stream
, i_date
) ) )
1851 return VLC_EGENERIC
;
1858 /****************************************************************************
1859 * Return true if it's a key frame
1860 ****************************************************************************/
1861 static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc
, uint8_t *p_byte
)
1865 case VLC_CODEC_DIV1
:
1867 * startcode: 0x00000100 32bits
1868 * framenumber ? 5bits
1869 * piture type 0(I),1(P) 2bits
1871 if( GetDWBE( p_byte
) != 0x00000100 )
1873 /* it's not an msmpegv1 stream, strange...*/
1874 return AVIIF_KEYFRAME
;
1876 return p_byte
[4] & 0x06 ? 0 : AVIIF_KEYFRAME
;
1878 case VLC_CODEC_DIV2
:
1879 case VLC_CODEC_DIV3
:
1880 case VLC_CODEC_WMV1
:
1882 * picture type 0(I),1(P) 2bits
1884 return p_byte
[0] & 0xC0 ? 0 : AVIIF_KEYFRAME
;
1885 case VLC_CODEC_MP4V
:
1886 /* we should find first occurrence of 0x000001b6 (32bits)
1887 * startcode: 0x000001b6 32bits
1888 * piture type 0(I),1(P) 2bits
1890 if( GetDWBE( p_byte
) != 0x000001b6 )
1892 /* not true , need to find the first VOP header */
1893 return AVIIF_KEYFRAME
;
1895 return p_byte
[4] & 0xC0 ? 0 : AVIIF_KEYFRAME
;
1898 /* I can't do it, so say yes */
1899 return AVIIF_KEYFRAME
;
1903 vlc_fourcc_t
AVI_FourccGetCodec( unsigned int i_cat
, vlc_fourcc_t i_codec
)
1908 wf_tag_to_fourcc( i_codec
, &i_codec
, NULL
);
1911 return vlc_fourcc_GetCodec( i_cat
, i_codec
);
1913 return VLC_FOURCC( 'u', 'n', 'd', 'f' );
1917 /****************************************************************************
1919 ****************************************************************************/
1920 static void AVI_ParseStreamHeader( vlc_fourcc_t i_id
,
1921 unsigned int *pi_number
, unsigned int *pi_type
)
1923 #define SET_PTR( p, v ) if( p ) *(p) = (v);
1926 c1
= ((uint8_t *)&i_id
)[0];
1927 c2
= ((uint8_t *)&i_id
)[1];
1929 if( c1
< '0' || c1
> '9' || c2
< '0' || c2
> '9' )
1931 SET_PTR( pi_number
, 100 ); /* > max stream number */
1932 SET_PTR( pi_type
, UNKNOWN_ES
);
1936 SET_PTR( pi_number
, (c1
- '0') * 10 + (c2
- '0' ) );
1937 switch( VLC_TWOCC( ((uint8_t *)&i_id
)[2], ((uint8_t *)&i_id
)[3] ) )
1940 SET_PTR( pi_type
, AUDIO_ES
);
1945 SET_PTR( pi_type
, VIDEO_ES
);
1949 SET_PTR( pi_type
, SPU_ES
);
1952 SET_PTR( pi_type
, UNKNOWN_ES
);
1959 /****************************************************************************
1961 ****************************************************************************/
1962 static int AVI_PacketGetHeader( demux_t
*p_demux
, avi_packet_t
*p_pk
)
1964 const uint8_t *p_peek
;
1966 if( stream_Peek( p_demux
->s
, &p_peek
, 16 ) < 16 )
1968 return VLC_EGENERIC
;
1970 p_pk
->i_fourcc
= VLC_FOURCC( p_peek
[0], p_peek
[1], p_peek
[2], p_peek
[3] );
1971 p_pk
->i_size
= GetDWLE( p_peek
+ 4 );
1972 p_pk
->i_pos
= stream_Tell( p_demux
->s
);
1973 if( p_pk
->i_fourcc
== AVIFOURCC_LIST
|| p_pk
->i_fourcc
== AVIFOURCC_RIFF
)
1975 p_pk
->i_type
= VLC_FOURCC( p_peek
[8], p_peek
[9],
1976 p_peek
[10], p_peek
[11] );
1983 memcpy( p_pk
->i_peek
, p_peek
+ 8, 8 );
1985 AVI_ParseStreamHeader( p_pk
->i_fourcc
, &p_pk
->i_stream
, &p_pk
->i_cat
);
1989 static int AVI_PacketNext( demux_t
*p_demux
)
1991 avi_packet_t avi_ck
;
1994 if( AVI_PacketGetHeader( p_demux
, &avi_ck
) )
1996 return VLC_EGENERIC
;
1999 if( avi_ck
.i_fourcc
== AVIFOURCC_LIST
&&
2000 ( avi_ck
.i_type
== AVIFOURCC_rec
|| avi_ck
.i_type
== AVIFOURCC_movi
) )
2004 else if( avi_ck
.i_fourcc
== AVIFOURCC_RIFF
&&
2005 avi_ck
.i_type
== AVIFOURCC_AVIX
)
2011 i_skip
= __EVEN( avi_ck
.i_size
) + 8;
2014 if( stream_Read( p_demux
->s
, NULL
, i_skip
) != i_skip
)
2016 return VLC_EGENERIC
;
2021 static int AVI_PacketRead( demux_t
*p_demux
,
2023 block_t
**pp_frame
)
2027 i_size
= __EVEN( p_pk
->i_size
+ 8 );
2029 if( ( *pp_frame
= stream_Block( p_demux
->s
, i_size
) ) == NULL
)
2031 return VLC_EGENERIC
;
2033 (*pp_frame
)->p_buffer
+= 8;
2034 (*pp_frame
)->i_buffer
-= 8;
2036 if( i_size
!= p_pk
->i_size
+ 8 )
2038 (*pp_frame
)->i_buffer
--;
2044 static int AVI_PacketSearch( demux_t
*p_demux
)
2046 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2047 avi_packet_t avi_pk
;
2052 if( stream_Read( p_demux
->s
, NULL
, 1 ) != 1 )
2054 return VLC_EGENERIC
;
2056 AVI_PacketGetHeader( p_demux
, &avi_pk
);
2057 if( avi_pk
.i_stream
< p_sys
->i_track
&&
2058 ( avi_pk
.i_cat
== AUDIO_ES
|| avi_pk
.i_cat
== VIDEO_ES
) )
2062 switch( avi_pk
.i_fourcc
)
2064 case AVIFOURCC_JUNK
:
2065 case AVIFOURCC_LIST
:
2066 case AVIFOURCC_RIFF
:
2067 case AVIFOURCC_idx1
:
2071 /* Prevents from eating all the CPU with broken files.
2072 * This value should be low enough so that it doesn't affect the
2073 * reading speed too much (not that we care much anyway because
2074 * this code is called only on broken files). */
2075 if( !(++i_count
% 1024) )
2077 if( !vlc_object_alive (p_demux
) ) return VLC_EGENERIC
;
2080 if( !(i_count
% (1024 * 10)) )
2081 msg_Warn( p_demux
, "trying to resync..." );
2086 /****************************************************************************
2088 ****************************************************************************/
2089 static void avi_index_Init( avi_index_t
*p_index
)
2091 p_index
->i_size
= 0;
2093 p_index
->p_entry
= NULL
;
2095 static void avi_index_Clean( avi_index_t
*p_index
)
2097 free( p_index
->p_entry
);
2099 static void avi_index_Append( avi_index_t
*p_index
, off_t
*pi_last_pos
,
2100 avi_entry_t
*p_entry
)
2102 /* Update last chunk position */
2103 if( *pi_last_pos
< p_entry
->i_pos
)
2104 *pi_last_pos
= p_entry
->i_pos
;
2107 if( p_index
->i_size
>= p_index
->i_max
)
2109 p_index
->i_max
+= 16384;
2110 p_index
->p_entry
= realloc_or_free( p_index
->p_entry
,
2111 p_index
->i_max
* sizeof( *p_index
->p_entry
) );
2112 if( !p_index
->p_entry
)
2115 /* calculate cumulate length */
2116 if( p_index
->i_size
> 0 )
2118 p_entry
->i_lengthtotal
=
2119 p_index
->p_entry
[p_index
->i_size
- 1].i_length
+
2120 p_index
->p_entry
[p_index
->i_size
- 1].i_lengthtotal
;
2124 p_entry
->i_lengthtotal
= 0;
2127 p_index
->p_entry
[p_index
->i_size
++] = *p_entry
;
2130 static int AVI_IndexFind_idx1( demux_t
*p_demux
,
2131 avi_chunk_idx1_t
**pp_idx1
,
2132 uint64_t *pi_offset
)
2134 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2136 avi_chunk_list_t
*p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0);
2137 avi_chunk_idx1_t
*p_idx1
= AVI_ChunkFind( p_riff
, AVIFOURCC_idx1
, 0);
2141 msg_Warn( p_demux
, "cannot find idx1 chunk, no index defined" );
2142 return VLC_EGENERIC
;
2146 /* *** calculate offset *** */
2147 /* Well, avi is __SHIT__ so test more than one entry
2148 * (needed for some avi files) */
2149 avi_chunk_list_t
*p_movi
= AVI_ChunkFind( p_riff
, AVIFOURCC_movi
, 0);
2151 for( unsigned i
= 0; i
< __MIN( p_idx1
->i_entry_count
, 10 ); i
++ )
2153 if( p_idx1
->entry
[i
].i_pos
< p_movi
->i_chunk_pos
)
2155 *pi_offset
= p_movi
->i_chunk_pos
+ 8;
2162 static int AVI_IndexLoad_idx1( demux_t
*p_demux
,
2163 avi_index_t p_index
[], off_t
*pi_last_offset
)
2165 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2167 avi_chunk_idx1_t
*p_idx1
;
2169 if( AVI_IndexFind_idx1( p_demux
, &p_idx1
, &i_offset
) )
2170 return VLC_EGENERIC
;
2172 for( unsigned i_index
= 0; i_index
< p_idx1
->i_entry_count
; i_index
++ )
2177 AVI_ParseStreamHeader( p_idx1
->entry
[i_index
].i_fourcc
,
2180 if( i_stream
< p_sys
->i_track
&&
2181 i_cat
== p_sys
->track
[i_stream
]->i_cat
)
2184 index
.i_id
= p_idx1
->entry
[i_index
].i_fourcc
;
2185 index
.i_flags
= p_idx1
->entry
[i_index
].i_flags
&(~AVIIF_FIXKEYFRAME
);
2186 index
.i_pos
= p_idx1
->entry
[i_index
].i_pos
+ i_offset
;
2187 index
.i_length
= p_idx1
->entry
[i_index
].i_length
;
2189 avi_index_Append( &p_index
[i_stream
], pi_last_offset
, &index
);
2195 static void __Parse_indx( demux_t
*p_demux
, avi_index_t
*p_index
, off_t
*pi_max_offset
,
2196 avi_chunk_indx_t
*p_indx
)
2200 msg_Dbg( p_demux
, "loading subindex(0x%x) %d entries", p_indx
->i_indextype
, p_indx
->i_entriesinuse
);
2201 if( p_indx
->i_indexsubtype
== 0 )
2203 for( unsigned i
= 0; i
< p_indx
->i_entriesinuse
; i
++ )
2205 index
.i_id
= p_indx
->i_id
;
2206 index
.i_flags
= p_indx
->idx
.std
[i
].i_size
& 0x80000000 ? 0 : AVIIF_KEYFRAME
;
2207 index
.i_pos
= p_indx
->i_baseoffset
+ p_indx
->idx
.std
[i
].i_offset
- 8;
2208 index
.i_length
= p_indx
->idx
.std
[i
].i_size
&0x7fffffff;
2210 avi_index_Append( p_index
, pi_max_offset
, &index
);
2213 else if( p_indx
->i_indexsubtype
== AVI_INDEX_2FIELD
)
2215 for( unsigned i
= 0; i
< p_indx
->i_entriesinuse
; i
++ )
2217 index
.i_id
= p_indx
->i_id
;
2218 index
.i_flags
= p_indx
->idx
.field
[i
].i_size
& 0x80000000 ? 0 : AVIIF_KEYFRAME
;
2219 index
.i_pos
= p_indx
->i_baseoffset
+ p_indx
->idx
.field
[i
].i_offset
- 8;
2220 index
.i_length
= p_indx
->idx
.field
[i
].i_size
;
2222 avi_index_Append( p_index
, pi_max_offset
, &index
);
2227 msg_Warn( p_demux
, "unknown subtype index(0x%x)", p_indx
->i_indexsubtype
);
2231 static void AVI_IndexLoad_indx( demux_t
*p_demux
,
2232 avi_index_t p_index
[], off_t
*pi_last_offset
)
2234 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2236 avi_chunk_list_t
*p_riff
;
2237 avi_chunk_list_t
*p_hdrl
;
2239 p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0);
2240 p_hdrl
= AVI_ChunkFind( p_riff
, AVIFOURCC_hdrl
, 0 );
2242 for( unsigned i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
2244 avi_chunk_list_t
*p_strl
;
2245 avi_chunk_indx_t
*p_indx
;
2247 #define p_stream p_sys->track[i_stream]
2248 p_strl
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_strl
, i_stream
);
2249 p_indx
= AVI_ChunkFind( p_strl
, AVIFOURCC_indx
, 0 );
2254 msg_Warn( p_demux
, "cannot find indx (misdetect/broken OpenDML "
2259 if( p_indx
->i_indextype
== AVI_INDEX_OF_CHUNKS
)
2261 __Parse_indx( p_demux
, &p_index
[i_stream
], pi_last_offset
, p_indx
);
2263 else if( p_indx
->i_indextype
== AVI_INDEX_OF_INDEXES
)
2266 for( unsigned i
= 0; i
< p_indx
->i_entriesinuse
; i
++ )
2268 if( stream_Seek( p_demux
->s
, p_indx
->idx
.super
[i
].i_offset
)||
2269 AVI_ChunkRead( p_demux
->s
, &ck_sub
, NULL
) )
2273 if( ck_sub
.indx
.i_indextype
== AVI_INDEX_OF_CHUNKS
)
2274 __Parse_indx( p_demux
, &p_index
[i_stream
], pi_last_offset
, &ck_sub
.indx
);
2275 AVI_ChunkFree( p_demux
->s
, &ck_sub
);
2280 msg_Warn( p_demux
, "unknown type index(0x%x)", p_indx
->i_indextype
);
2286 static void AVI_IndexLoad( demux_t
*p_demux
)
2288 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2291 assert( p_sys
->i_track
<= 100 );
2292 avi_index_t p_idx_indx
[p_sys
->i_track
];
2293 avi_index_t p_idx_idx1
[p_sys
->i_track
];
2294 for( unsigned i
= 0; i
< p_sys
->i_track
; i
++ )
2296 avi_index_Init( &p_idx_indx
[i
] );
2297 avi_index_Init( &p_idx_idx1
[i
] );
2299 off_t i_indx_last_pos
= p_sys
->i_movi_lastchunk_pos
;
2300 off_t i_idx1_last_pos
= p_sys
->i_movi_lastchunk_pos
;
2302 AVI_IndexLoad_indx( p_demux
, p_idx_indx
, &i_indx_last_pos
);
2303 if( !p_sys
->b_odml
)
2304 AVI_IndexLoad_idx1( p_demux
, p_idx_idx1
, &i_idx1_last_pos
);
2306 /* Select the longest index */
2307 for( unsigned i
= 0; i
< p_sys
->i_track
; i
++ )
2309 if( p_idx_indx
[i
].i_size
> p_idx_idx1
[i
].i_size
)
2311 msg_Dbg( p_demux
, "selected ODML index for stream[%u]", i
);
2312 p_sys
->track
[i
]->idx
= p_idx_indx
[i
];
2313 avi_index_Clean( &p_idx_idx1
[i
] );
2317 msg_Dbg( p_demux
, "selected standard index for stream[%u]", i
);
2318 p_sys
->track
[i
]->idx
= p_idx_idx1
[i
];
2319 avi_index_Clean( &p_idx_indx
[i
] );
2322 p_sys
->i_movi_lastchunk_pos
= __MAX( i_indx_last_pos
, i_idx1_last_pos
);
2324 for( unsigned i
= 0; i
< p_sys
->i_track
; i
++ )
2326 avi_index_t
*p_index
= &p_sys
->track
[i
]->idx
;
2330 for( unsigned j
= 0; !b_key
&& j
< p_index
->i_size
; j
++ )
2331 b_key
= p_index
->p_entry
[j
].i_flags
& AVIIF_KEYFRAME
;
2334 msg_Err( p_demux
, "no key frame set for track %u", i
);
2335 for( unsigned j
= 0; j
< p_index
->i_size
; j
++ )
2336 p_index
->p_entry
[j
].i_flags
|= AVIIF_KEYFRAME
;
2340 msg_Dbg( p_demux
, "stream[%d] created %d index entries",
2341 i
, p_index
->i_size
);
2345 static void AVI_IndexCreate( demux_t
*p_demux
)
2347 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2349 avi_chunk_list_t
*p_riff
;
2350 avi_chunk_list_t
*p_movi
;
2352 unsigned int i_stream
;
2355 mtime_t i_dialog_update
;
2356 dialog_progress_bar_t
*p_dialog
= NULL
;
2358 p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0);
2359 p_movi
= AVI_ChunkFind( p_riff
, AVIFOURCC_movi
, 0);
2363 msg_Err( p_demux
, "cannot find p_movi" );
2367 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
2368 avi_index_Init( &p_sys
->track
[i_stream
]->idx
);
2370 i_movi_end
= __MIN( (off_t
)(p_movi
->i_chunk_pos
+ p_movi
->i_chunk_size
),
2371 stream_Size( p_demux
->s
) );
2373 stream_Seek( p_demux
->s
, p_movi
->i_chunk_pos
+ 12 );
2374 msg_Warn( p_demux
, "creating index from LIST-movi, will take time !" );
2377 /* Only show dialog if AVI is > 10MB */
2378 i_dialog_update
= mdate();
2379 if( stream_Size( p_demux
->s
) > 10000000 )
2380 p_dialog
= dialog_ProgressCreate( p_demux
, _("Fixing AVI Index..."),
2381 NULL
, _("Cancel") );
2387 if( !vlc_object_alive (p_demux
) )
2390 /* Don't update/check dialog too often */
2391 if( p_dialog
&& mdate() - i_dialog_update
> 100000 )
2393 if( dialog_ProgressCancelled( p_dialog
) )
2396 double f_current
= stream_Tell( p_demux
->s
);
2397 double f_size
= stream_Size( p_demux
->s
);
2398 double f_pos
= f_current
/ f_size
;
2399 dialog_ProgressSet( p_dialog
, NULL
, f_pos
);
2401 i_dialog_update
= mdate();
2404 if( AVI_PacketGetHeader( p_demux
, &pk
) )
2407 if( pk
.i_stream
< p_sys
->i_track
&&
2408 pk
.i_cat
== p_sys
->track
[pk
.i_stream
]->i_cat
)
2410 avi_track_t
*tk
= p_sys
->track
[pk
.i_stream
];
2413 index
.i_id
= pk
.i_fourcc
;
2414 index
.i_flags
= AVI_GetKeyFlag(tk
->i_codec
, pk
.i_peek
);
2415 index
.i_pos
= pk
.i_pos
;
2416 index
.i_length
= pk
.i_size
;
2417 avi_index_Append( &tk
->idx
, &p_sys
->i_movi_lastchunk_pos
, &index
);
2421 switch( pk
.i_fourcc
)
2423 case AVIFOURCC_idx1
:
2426 avi_chunk_list_t
*p_sysx
;
2427 p_sysx
= AVI_ChunkFind( &p_sys
->ck_root
,
2428 AVIFOURCC_RIFF
, 1 );
2430 msg_Dbg( p_demux
, "looking for new RIFF chunk" );
2431 if( stream_Seek( p_demux
->s
, p_sysx
->i_chunk_pos
+ 24 ) )
2437 case AVIFOURCC_RIFF
:
2438 msg_Dbg( p_demux
, "new RIFF chunk found" );
2442 case AVIFOURCC_JUNK
:
2446 msg_Warn( p_demux
, "need resync, probably broken avi" );
2447 if( AVI_PacketSearch( p_demux
) )
2449 msg_Warn( p_demux
, "lost sync, abord index creation" );
2455 if( ( !p_sys
->b_odml
&& pk
.i_pos
+ pk
.i_size
>= i_movi_end
) ||
2456 AVI_PacketNext( p_demux
) )
2463 if( p_dialog
!= NULL
)
2464 dialog_ProgressDestroy( p_dialog
);
2466 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
2468 msg_Dbg( p_demux
, "stream[%d] creating %d index entries",
2469 i_stream
, p_sys
->track
[i_stream
]->idx
.i_size
);
2474 static void AVI_MetaLoad( demux_t
*p_demux
,
2475 avi_chunk_list_t
*p_riff
, avi_chunk_avih_t
*p_avih
)
2477 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2479 vlc_meta_t
*p_meta
= p_sys
->meta
= vlc_meta_New();
2484 snprintf( buffer
, sizeof(buffer
), "%s%s%s%s",
2485 p_avih
->i_flags
&AVIF_HASINDEX
? " HAS_INDEX" : "",
2486 p_avih
->i_flags
&AVIF_MUSTUSEINDEX
? " MUST_USE_INDEX" : "",
2487 p_avih
->i_flags
&AVIF_ISINTERLEAVED
? " IS_INTERLEAVED" : "",
2488 p_avih
->i_flags
&AVIF_TRUSTCKTYPE
? " TRUST_CKTYPE" : "" );
2489 vlc_meta_SetSetting( p_meta
, buffer
);
2491 avi_chunk_list_t
*p_info
= AVI_ChunkFind( p_riff
, AVIFOURCC_INFO
, 0 );
2495 static const struct {
2499 { AVIFOURCC_IART
, vlc_meta_Artist
},
2500 { AVIFOURCC_ICMT
, vlc_meta_Description
},
2501 { AVIFOURCC_ICOP
, vlc_meta_Copyright
},
2502 { AVIFOURCC_IGNR
, vlc_meta_Genre
},
2503 { AVIFOURCC_INAM
, vlc_meta_Title
},
2506 for( int i
= 0; p_dsc
[i
].i_id
!= 0; i
++ )
2508 avi_chunk_STRING_t
*p_strz
= AVI_ChunkFind( p_info
, p_dsc
[i
].i_id
, 0 );
2511 char *psz_value
= FromACP( p_strz
->p_str
);
2516 vlc_meta_Set( p_meta
, p_dsc
[i
].i_type
, psz_value
);
2521 /*****************************************************************************
2523 *****************************************************************************/
2524 static void AVI_ExtractSubtitle( demux_t
*p_demux
,
2525 unsigned int i_stream
,
2526 avi_chunk_list_t
*p_strl
,
2527 avi_chunk_STRING_t
*p_strn
)
2529 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2530 block_t
*p_block
= NULL
;
2531 input_attachment_t
*p_attachment
= NULL
;
2532 char *psz_description
= NULL
;
2533 avi_chunk_indx_t
*p_indx
= NULL
;
2535 if( !p_sys
->b_seekable
)
2538 p_indx
= AVI_ChunkFind( p_strl
, AVIFOURCC_indx
, 0 );
2544 if( p_indx
->i_indextype
== AVI_INDEX_OF_INDEXES
&&
2545 p_indx
->i_entriesinuse
> 0 )
2547 if( stream_Seek( p_demux
->s
, p_indx
->idx
.super
[0].i_offset
)||
2548 AVI_ChunkRead( p_demux
->s
, &ck
, NULL
) )
2553 if( p_indx
->i_indextype
!= AVI_INDEX_OF_CHUNKS
||
2554 p_indx
->i_entriesinuse
!= 1 ||
2555 p_indx
->i_indexsubtype
!= 0 )
2558 i_position
= p_indx
->i_baseoffset
+
2559 p_indx
->idx
.std
[0].i_offset
- 8;
2560 i_size
= (p_indx
->idx
.std
[0].i_size
& 0x7fffffff) + 8;
2564 avi_chunk_idx1_t
*p_idx1
;
2567 if( AVI_IndexFind_idx1( p_demux
, &p_idx1
, &i_offset
) )
2571 for( unsigned i
= 0; i
< p_idx1
->i_entry_count
; i
++ )
2573 const idx1_entry_t
*e
= &p_idx1
->entry
[i
];
2575 unsigned i_stream_idx
;
2577 AVI_ParseStreamHeader( e
->i_fourcc
, &i_stream_idx
, &i_cat
);
2578 if( i_cat
== SPU_ES
&& i_stream_idx
== i_stream
)
2580 i_position
= e
->i_pos
+ i_offset
;
2581 i_size
= e
->i_length
+ 8;
2590 if( i_size
> 1000000 )
2593 if( stream_Seek( p_demux
->s
, i_position
) )
2595 p_block
= stream_Block( p_demux
->s
, i_size
);
2599 /* Parse packet header */
2600 const uint8_t *p
= p_block
->p_buffer
;
2601 if( i_size
< 8 || p
[2] != 't' || p
[3] != 'x' )
2606 /* Parse subtitle chunk header */
2607 if( i_size
< 11 || memcmp( p
, "GAB2", 4 ) ||
2608 p
[4] != 0x00 || GetWLE( &p
[5] ) != 0x2 )
2610 const unsigned i_name
= GetDWLE( &p
[7] );
2611 if( 11 + i_size
<= i_name
)
2614 psz_description
= FromCharset( "UTF-16LE", &p
[11], i_name
);
2616 i_size
-= 11 + i_name
;
2617 if( i_size
< 6 || GetWLE( &p
[0] ) != 0x04 )
2619 const unsigned i_payload
= GetDWLE( &p
[2] );
2620 if( i_size
< 6 + i_payload
|| i_payload
<= 0 )
2625 if( !psz_description
)
2626 psz_description
= p_strn
? FromACP( p_strn
->p_str
) : NULL
;
2628 if( asprintf( &psz_name
, "subtitle%d.srt", p_sys
->i_attachment
) <= 0 )
2630 p_attachment
= vlc_input_attachment_New( psz_name
,
2631 "application/x-srt",
2635 TAB_APPEND( p_sys
->i_attachment
, p_sys
->attachment
, p_attachment
);
2639 free( psz_description
);
2642 block_Release( p_block
);
2645 msg_Dbg( p_demux
, "Loaded an embed subtitle" );
2647 msg_Warn( p_demux
, "Failed to load an embed subtitle" );
2649 if( p_indx
== &ck
.indx
)
2650 AVI_ChunkFree( p_demux
->s
, &ck
);
2652 /*****************************************************************************
2654 *****************************************************************************/
2655 static int AVI_TrackStopFinishedStreams( demux_t
*p_demux
)
2657 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2661 for( i
= 0; i
< p_sys
->i_track
; i
++ )
2663 avi_track_t
*tk
= p_sys
->track
[i
];
2664 if( tk
->i_idxposc
>= tk
->idx
.i_size
)
2676 /****************************************************************************
2677 * AVI_MovieGetLength give max streams length in second
2678 ****************************************************************************/
2679 static mtime_t
AVI_MovieGetLength( demux_t
*p_demux
)
2681 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2682 mtime_t i_maxlength
= 0;
2685 for( i
= 0; i
< p_sys
->i_track
; i
++ )
2687 avi_track_t
*tk
= p_sys
->track
[i
];
2690 /* fix length for each stream */
2691 if( tk
->idx
.i_size
< 1 || !tk
->idx
.p_entry
)
2696 if( tk
->i_samplesize
)
2698 i_length
= AVI_GetDPTS( tk
,
2699 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_lengthtotal
+
2700 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_length
);
2704 i_length
= AVI_GetDPTS( tk
, tk
->idx
.i_size
);
2706 i_length
/= (mtime_t
)1000000; /* in seconds */
2709 "stream[%d] length:%"PRId64
" (based on index)",
2712 i_maxlength
= __MAX( i_maxlength
, i_length
);