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) %d channels %dHz %dbits",
447 i
, p_auds
->p_wf
->wFormatTag
, p_auds
->p_wf
->nChannels
,
448 p_auds
->p_wf
->nSamplesPerSec
,
449 p_auds
->p_wf
->wBitsPerSample
);
451 fmt
.i_extra
= __MIN( p_auds
->p_wf
->cbSize
,
452 p_auds
->i_chunk_size
- sizeof(WAVEFORMATEX
) );
453 if( fmt
.i_extra
> 0 )
455 fmt
.p_extra
= malloc( fmt
.i_extra
);
456 if( !fmt
.p_extra
) goto error
;
457 memcpy( fmt
.p_extra
, &p_auds
->p_wf
[1], fmt
.i_extra
);
461 case( AVIFOURCC_vids
):
462 tk
->i_cat
= VIDEO_ES
;
463 tk
->i_codec
= AVI_FourccGetCodec( VIDEO_ES
,
464 p_vids
->p_bih
->biCompression
);
465 if( p_vids
->p_bih
->biCompression
== VLC_FOURCC( 'D', 'X', 'S', 'B' ) )
467 msg_Dbg( p_demux
, "stream[%d] subtitles", i
);
468 es_format_Init( &fmt
, SPU_ES
, p_vids
->p_bih
->biCompression
);
472 else if( p_vids
->p_bih
->biCompression
== 0x00 )
474 switch( p_vids
->p_bih
->biBitCount
)
477 tk
->i_codec
= VLC_CODEC_RGB32
;
480 tk
->i_codec
= VLC_CODEC_RGB24
;
482 case 16: /* Yes it is RV15 */
484 tk
->i_codec
= VLC_CODEC_RGB15
;
486 case 9: /* <- TODO check that */
487 tk
->i_codec
= VLC_CODEC_I410
;
489 case 8: /* <- TODO check that */
490 tk
->i_codec
= VLC_CODEC_GREY
;
493 es_format_Init( &fmt
, VIDEO_ES
, tk
->i_codec
);
495 switch( tk
->i_codec
)
497 case VLC_CODEC_RGB24
:
498 case VLC_CODEC_RGB32
:
499 fmt
.video
.i_rmask
= 0x00ff0000;
500 fmt
.video
.i_gmask
= 0x0000ff00;
501 fmt
.video
.i_bmask
= 0x000000ff;
503 case VLC_CODEC_RGB15
:
504 fmt
.video
.i_rmask
= 0x7c00;
505 fmt
.video
.i_gmask
= 0x03e0;
506 fmt
.video
.i_bmask
= 0x001f;
514 es_format_Init( &fmt
, VIDEO_ES
, p_vids
->p_bih
->biCompression
);
515 if( tk
->i_codec
== VLC_CODEC_MP4V
&&
516 !strncasecmp( (char*)&p_strh
->i_handler
, "XVID", 4 ) )
519 fmt
.i_original_fourcc
= VLC_FOURCC( 'X', 'V', 'I', 'D' );
522 tk
->i_samplesize
= 0;
523 fmt
.video
.i_width
= p_vids
->p_bih
->biWidth
;
524 fmt
.video
.i_height
= p_vids
->p_bih
->biHeight
;
525 fmt
.video
.i_bits_per_pixel
= p_vids
->p_bih
->biBitCount
;
526 fmt
.video
.i_frame_rate
= tk
->i_rate
;
527 fmt
.video
.i_frame_rate_base
= tk
->i_scale
;
529 __MIN( p_vids
->p_bih
->biSize
- sizeof( BITMAPINFOHEADER
),
530 p_vids
->i_chunk_size
- sizeof(BITMAPINFOHEADER
) );
531 if( fmt
.i_extra
> 0 )
533 fmt
.p_extra
= malloc( fmt
.i_extra
);
534 if( !fmt
.p_extra
) goto error
;
535 memcpy( fmt
.p_extra
, &p_vids
->p_bih
[1], fmt
.i_extra
);
538 msg_Dbg( p_demux
, "stream[%d] video(%4.4s) %"PRIu32
"x%"PRIu32
" %dbpp %ffps",
539 i
, (char*)&p_vids
->p_bih
->biCompression
,
540 (uint32_t)p_vids
->p_bih
->biWidth
,
541 (uint32_t)p_vids
->p_bih
->biHeight
,
542 p_vids
->p_bih
->biBitCount
,
543 (float)tk
->i_rate
/(float)tk
->i_scale
);
545 if( p_vids
->p_bih
->biCompression
== 0x00 )
547 /* RGB DIB are coded from bottom to top */
549 (unsigned int)(-(int)p_vids
->p_bih
->biHeight
);
552 /* Extract palette from extradata if bpp <= 8
553 * (assumes that extradata contains only palette but appears
554 * to be true for all palettized codecs we support) */
555 if( fmt
.video
.i_bits_per_pixel
> 0 && fmt
.video
.i_bits_per_pixel
<= 8 )
557 /* The palette is not always included in biSize */
558 fmt
.i_extra
= p_vids
->i_chunk_size
- sizeof(BITMAPINFOHEADER
);
559 if( fmt
.i_extra
> 0 )
561 const uint8_t *p_pal
= fmt
.p_extra
;
563 fmt
.video
.p_palette
= calloc( 1, sizeof(video_palette_t
) );
564 fmt
.video
.p_palette
->i_entries
= __MIN(fmt
.i_extra
/4, 256);
566 for( int i
= 0; i
< fmt
.video
.p_palette
->i_entries
; i
++ )
568 for( int j
= 0; j
< 4; j
++ )
569 fmt
.video
.p_palette
->palette
[i
][j
] = p_pal
[4*i
+j
];
575 case( AVIFOURCC_txts
):
576 msg_Dbg( p_demux
, "stream[%d] subtitle attachment", i
);
577 AVI_ExtractSubtitle( p_demux
, i
, p_strl
, p_strn
);
581 case( AVIFOURCC_iavs
):
582 case( AVIFOURCC_ivas
):
583 p_sys
->b_muxed
= true;
584 msg_Dbg( p_demux
, "stream[%d] iavs with handler %4.4s", i
, (char *)&p_strh
->i_handler
);
585 if( p_strh
->i_handler
== FOURCC_dvsd
||
586 p_strh
->i_handler
== FOURCC_dvhd
||
587 p_strh
->i_handler
== FOURCC_dvsl
||
588 p_strh
->i_handler
== FOURCC_dv25
||
589 p_strh
->i_handler
== FOURCC_dv50
)
591 tk
->p_out_muxed
= stream_DemuxNew( p_demux
, (char *)"rawdv", p_demux
->out
);
592 if( !tk
->p_out_muxed
)
593 msg_Err( p_demux
, "could not load the DV parser" );
599 case( AVIFOURCC_mids
):
600 msg_Dbg( p_demux
, "stream[%d] midi is UNSUPPORTED", i
);
603 msg_Warn( p_demux
, "stream[%d] unknown type %4.4s", i
, (char *)&p_strh
->i_type
);
608 fmt
.psz_description
= FromACP( p_strn
->p_str
);
609 if( tk
->p_out_muxed
== NULL
)
610 tk
->p_es
= es_out_Add( p_demux
->out
, &fmt
);
611 TAB_APPEND( p_sys
->i_track
, p_sys
->track
, tk
);
614 es_format_Clean( &fmt
);
618 if( p_sys
->i_track
<= 0 )
620 msg_Err( p_demux
, "no valid track" );
624 i_do_index
= var_InheritInteger( p_demux
, "avi-index" );
625 if( i_do_index
== 1 ) /* Always fix */
628 if( p_sys
->b_seekable
)
630 AVI_IndexCreate( p_demux
);
634 msg_Warn( p_demux
, "cannot create index (unseekable stream)" );
635 AVI_IndexLoad( p_demux
);
640 AVI_IndexLoad( p_demux
);
643 /* *** movie length in sec *** */
644 p_sys
->i_length
= AVI_MovieGetLength( p_demux
);
646 /* Check the index completeness */
647 unsigned int i_idx_totalframes
= 0;
648 for( unsigned int i
= 0; i
< p_sys
->i_track
; i
++ )
650 const avi_track_t
*tk
= p_sys
->track
[i
];
651 if( tk
->i_cat
== VIDEO_ES
&& tk
->idx
.p_entry
)
652 i_idx_totalframes
= __MAX(i_idx_totalframes
, tk
->idx
.i_size
);
655 if( i_idx_totalframes
!= p_avih
->i_totalframes
&&
656 p_sys
->i_length
< (mtime_t
)p_avih
->i_totalframes
*
657 (mtime_t
)p_avih
->i_microsecperframe
/
660 if( !vlc_object_alive( p_demux
) )
663 msg_Warn( p_demux
, "broken or missing index, 'seek' will be "
664 "approximative or will exhibit strange behavior" );
665 if( i_do_index
== 0 && !b_index
)
667 if( !p_sys
->b_seekable
) {
671 switch( dialog_Question( p_demux
, _("Broken or missing AVI Index") ,
672 _( "Because this AVI file index is broken or missing, "
673 "seeking will not work correctly.\n"
674 "VLC won't repair your file but can temporary fix this "
675 "problem by building an index in memory.\n"
676 "This step might take a long time on a large file.\n"
677 "What do you want to do ?" ),
678 _( "Build index then play" ), _( "Play as is" ), _( "Do not play") ) )
682 msg_Dbg( p_demux
, "Fixing AVI index" );
686 vlc_object_kill( p_demux
->p_parent
);
692 /* fix some BeOS MediaKit generated file */
693 for( i
= 0 ; i
< p_sys
->i_track
; i
++ )
695 avi_track_t
*tk
= p_sys
->track
[i
];
696 avi_chunk_list_t
*p_strl
;
697 avi_chunk_strh_t
*p_strh
;
698 avi_chunk_strf_auds_t
*p_auds
;
700 if( tk
->i_cat
!= AUDIO_ES
)
704 if( tk
->idx
.i_size
< 1 ||
706 tk
->i_samplesize
!= 0 )
710 p_strl
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_strl
, i
);
711 p_strh
= AVI_ChunkFind( p_strl
, AVIFOURCC_strh
, 0 );
712 p_auds
= AVI_ChunkFind( p_strl
, AVIFOURCC_strf
, 0 );
714 if( p_auds
->p_wf
->wFormatTag
!= WAVE_FORMAT_PCM
&&
715 (unsigned int)tk
->i_rate
== p_auds
->p_wf
->nSamplesPerSec
)
717 int64_t i_track_length
=
718 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_length
+
719 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_lengthtotal
;
720 mtime_t i_length
= (mtime_t
)p_avih
->i_totalframes
*
721 (mtime_t
)p_avih
->i_microsecperframe
;
725 msg_Warn( p_demux
, "track[%d] cannot be fixed (BeOS MediaKit generated)", i
);
728 tk
->i_samplesize
= 1;
729 tk
->i_rate
= i_track_length
* (int64_t)1000000/ i_length
;
730 msg_Warn( p_demux
, "track[%d] fixed with rate=%d scale=%d (BeOS MediaKit generated)", i
, tk
->i_rate
, tk
->i_scale
);
734 if( p_sys
->b_seekable
)
736 /* we have read all chunk so go back to movi */
737 stream_Seek( p_demux
->s
, p_movi
->i_chunk_pos
);
739 /* Skip movi header */
740 stream_Read( p_demux
->s
, NULL
, 12 );
742 p_sys
->i_movi_begin
= p_movi
->i_chunk_pos
;
746 for( unsigned i
= 0; i
< p_sys
->i_attachment
; i
++)
747 vlc_input_attachment_Delete(p_sys
->attachment
[i
]);
748 free(p_sys
->attachment
);
751 vlc_meta_Delete( p_sys
->meta
);
753 AVI_ChunkFreeRoot( p_demux
->s
, &p_sys
->ck_root
);
755 return vlc_object_alive( p_demux
) ? VLC_EGENERIC
: VLC_ETIMEOUT
;
758 /*****************************************************************************
759 * Close: frees unused data
760 *****************************************************************************/
761 static void Close ( vlc_object_t
* p_this
)
763 demux_t
* p_demux
= (demux_t
*)p_this
;
765 demux_sys_t
*p_sys
= p_demux
->p_sys
;
767 for( i
= 0; i
< p_sys
->i_track
; i
++ )
769 if( p_sys
->track
[i
] )
771 if( p_sys
->track
[i
]->p_out_muxed
)
772 stream_Delete( p_sys
->track
[i
]->p_out_muxed
);
773 avi_index_Clean( &p_sys
->track
[i
]->idx
);
774 free( p_sys
->track
[i
] );
777 free( p_sys
->track
);
778 AVI_ChunkFreeRoot( p_demux
->s
, &p_sys
->ck_root
);
779 vlc_meta_Delete( p_sys
->meta
);
780 for( unsigned i
= 0; i
< p_sys
->i_attachment
; i
++)
781 vlc_input_attachment_Delete(p_sys
->attachment
[i
]);
782 free(p_sys
->attachment
);
787 /*****************************************************************************
788 * Demux_Seekable: reads and demuxes data packets for stream seekable
789 *****************************************************************************
790 * AVIDemux: reads and demuxes data packets
791 *****************************************************************************
792 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
793 *****************************************************************************/
800 off_t i_posf
; /* where we will read :
801 if i_idxposb == 0 : begining of chunk (+8 to acces data)
802 else : point on data directly */
803 } avi_track_toread_t
;
805 static int Demux_Seekable( demux_t
*p_demux
)
807 demux_sys_t
*p_sys
= p_demux
->p_sys
;
809 unsigned int i_track_count
= 0;
810 unsigned int i_track
;
811 /* cannot be more than 100 stream (dcXX or wbXX) */
812 avi_track_toread_t toread
[100];
815 /* detect new selected/unselected streams */
816 for( i_track
= 0; i_track
< p_sys
->i_track
; i_track
++ )
818 avi_track_t
*tk
= p_sys
->track
[i_track
];
821 if( p_sys
->b_muxed
&& tk
->p_out_muxed
)
824 tk
->b_activated
= true;
828 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
, tk
->p_es
, &b
);
829 if( b
&& !tk
->b_activated
)
831 if( p_sys
->b_seekable
)
833 AVI_TrackSeek( p_demux
, i_track
, p_sys
->i_time
);
835 tk
->b_activated
= true;
837 else if( !b
&& tk
->b_activated
)
839 tk
->b_activated
= false;
847 if( i_track_count
<= 0 )
849 int64_t i_length
= p_sys
->i_length
* (mtime_t
)1000000;
851 p_sys
->i_time
+= 25*1000; /* read 25ms */
854 if( p_sys
->i_time
>= i_length
)
858 msg_Warn( p_demux
, "no track selected, exiting..." );
862 /* wait for the good time */
863 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, p_sys
->i_time
+ 1 );
864 p_sys
->i_time
+= 25*1000; /* read 25ms */
867 for( i_track
= 0; i_track
< p_sys
->i_track
; i_track
++ )
869 avi_track_t
*tk
= p_sys
->track
[i_track
];
872 toread
[i_track
].b_ok
= tk
->b_activated
&& !tk
->b_eof
;
873 if( tk
->i_idxposc
< tk
->idx
.i_size
)
875 toread
[i_track
].i_posf
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_pos
;
876 if( tk
->i_idxposb
> 0 )
878 toread
[i_track
].i_posf
+= 8 + tk
->i_idxposb
;
883 toread
[i_track
].i_posf
= -1;
886 i_dpts
= p_sys
->i_time
- AVI_GetPTS( tk
);
888 if( tk
->i_samplesize
)
890 toread
[i_track
].i_toread
= AVI_PTSToByte( tk
, __ABS( i_dpts
) );
894 toread
[i_track
].i_toread
= AVI_PTSToChunk( tk
, __ABS( i_dpts
) );
899 toread
[i_track
].i_toread
*= -1;
912 /* search for first chunk to be read */
913 for( i
= 0, b_done
= true, i_pos
= -1; i
< p_sys
->i_track
; i
++ )
915 if( !toread
[i
].b_ok
||
916 AVI_GetDPTS( p_sys
->track
[i
],
917 toread
[i
].i_toread
) <= -25 * 1000 )
922 if( toread
[i
].i_toread
> 0 )
924 b_done
= false; /* not yet finished */
926 if( toread
[i
].i_posf
> 0 )
928 if( i_pos
== -1 || i_pos
> toread
[i
].i_posf
)
931 i_pos
= toread
[i
].i_posf
;
938 for( i
= 0; i
< p_sys
->i_track
; i
++ )
943 msg_Warn( p_demux
, "all tracks have failed, exiting..." );
949 int i_loop_count
= 0;
951 /* no valid index, we will parse directly the stream
952 * in case we fail we will disable all finished stream */
953 if( p_sys
->i_movi_lastchunk_pos
>= p_sys
->i_movi_begin
+ 12 )
955 stream_Seek( p_demux
->s
, p_sys
->i_movi_lastchunk_pos
);
956 if( AVI_PacketNext( p_demux
) )
958 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
963 stream_Seek( p_demux
->s
, p_sys
->i_movi_begin
+ 12 );
970 if( AVI_PacketGetHeader( p_demux
, &avi_pk
) )
973 "cannot get packet header, track disabled" );
974 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
976 if( avi_pk
.i_stream
>= p_sys
->i_track
||
977 ( avi_pk
.i_cat
!= AUDIO_ES
&& avi_pk
.i_cat
!= VIDEO_ES
) )
979 if( AVI_PacketNext( p_demux
) )
982 "cannot skip packet, track disabled" );
983 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
986 /* Prevents from eating all the CPU with broken files.
987 * This value should be low enough so that it doesn't
988 * affect the reading speed too much. */
989 if( !(++i_loop_count
% 1024) )
991 if( !vlc_object_alive (p_demux
) ) return -1;
994 if( !(i_loop_count
% (1024 * 10)) )
996 "don't seem to find any data..." );
1002 i_track
= avi_pk
.i_stream
;
1003 tk
= p_sys
->track
[i_track
];
1005 /* add this chunk to the index */
1007 index
.i_id
= avi_pk
.i_fourcc
;
1008 index
.i_flags
= AVI_GetKeyFlag(tk
->i_codec
, avi_pk
.i_peek
);
1009 index
.i_pos
= avi_pk
.i_pos
;
1010 index
.i_length
= avi_pk
.i_size
;
1011 avi_index_Append( &tk
->idx
, &p_sys
->i_movi_lastchunk_pos
, &index
);
1013 /* do we will read this data ? */
1014 if( AVI_GetDPTS( tk
, toread
[i_track
].i_toread
) > -25*1000 )
1020 if( AVI_PacketNext( p_demux
) )
1023 "cannot skip packet, track disabled" );
1024 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
1033 stream_Seek( p_demux
->s
, i_pos
);
1036 /* Set the track to use */
1037 tk
= p_sys
->track
[i_track
];
1039 /* read thoses data */
1040 if( tk
->i_samplesize
)
1042 unsigned int i_toread
;
1044 if( ( i_toread
= toread
[i_track
].i_toread
) <= 0 )
1046 if( tk
->i_samplesize
> 1 )
1048 i_toread
= tk
->i_samplesize
;
1052 i_toread
= AVI_PTSToByte( tk
, 20 * 1000 );
1053 i_toread
= __MAX( i_toread
, 100 );
1056 i_size
= __MIN( tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
-
1062 i_size
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
;
1065 if( tk
->i_idxposb
== 0 )
1067 i_size
+= 8; /* need to read and skip header */
1070 if( ( p_frame
= stream_Block( p_demux
->s
, __EVEN( i_size
) ) )==NULL
)
1072 msg_Warn( p_demux
, "failed reading data" );
1074 toread
[i_track
].b_ok
= false;
1077 if( i_size
% 2 ) /* read was padded on word boundary */
1079 p_frame
->i_buffer
--;
1082 if( tk
->i_idxposb
== 0 )
1084 p_frame
->p_buffer
+= 8;
1085 p_frame
->i_buffer
-= 8;
1087 p_frame
->i_pts
= AVI_GetPTS( tk
) + 1;
1088 if( tk
->idx
.p_entry
[tk
->i_idxposc
].i_flags
&AVIIF_KEYFRAME
)
1090 p_frame
->i_flags
= BLOCK_FLAG_TYPE_I
;
1094 p_frame
->i_flags
= BLOCK_FLAG_TYPE_PB
;
1098 if( tk
->i_samplesize
)
1100 if( tk
->i_idxposb
== 0 )
1104 toread
[i_track
].i_toread
-= i_size
;
1105 tk
->i_idxposb
+= i_size
;
1106 if( tk
->i_idxposb
>=
1107 tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
)
1115 int i_length
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
;
1118 if( tk
->i_cat
== AUDIO_ES
)
1120 tk
->i_blockno
+= tk
->i_blocksize
> 0 ? ( i_length
+ tk
->i_blocksize
- 1 ) / tk
->i_blocksize
: 1;
1122 toread
[i_track
].i_toread
--;
1125 if( tk
->i_idxposc
< tk
->idx
.i_size
)
1127 toread
[i_track
].i_posf
=
1128 tk
->idx
.p_entry
[tk
->i_idxposc
].i_pos
;
1129 if( tk
->i_idxposb
> 0 )
1131 toread
[i_track
].i_posf
+= 8 + tk
->i_idxposb
;
1137 toread
[i_track
].i_posf
= -1;
1140 if( tk
->i_cat
!= VIDEO_ES
)
1141 p_frame
->i_dts
= p_frame
->i_pts
;
1144 p_frame
->i_dts
= p_frame
->i_pts
;
1145 p_frame
->i_pts
= VLC_TS_INVALID
;
1148 //p_pes->i_rate = p_demux->stream.control.i_rate;
1149 if( tk
->p_out_muxed
)
1150 stream_DemuxSend( tk
->p_out_muxed
, p_frame
);
1152 es_out_Send( p_demux
->out
, tk
->p_es
, p_frame
);
1157 /*****************************************************************************
1158 * Demux_UnSeekable: reads and demuxes data packets for unseekable file
1159 *****************************************************************************
1160 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1161 *****************************************************************************/
1162 static int Demux_UnSeekable( demux_t
*p_demux
)
1164 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1165 avi_track_t
*p_stream_master
= NULL
;
1166 unsigned int i_stream
;
1167 unsigned int i_packet
;
1169 if( p_sys
->b_muxed
)
1171 msg_Err( p_demux
, "Can not yet process muxed avi substreams without seeking" );
1172 return VLC_EGENERIC
;
1175 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, p_sys
->i_time
+ 1 );
1177 /* *** find master stream for data packet skipping algo *** */
1178 /* *** -> first video, if any, or first audio ES *** */
1179 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
1181 avi_track_t
*tk
= p_sys
->track
[i_stream
];
1184 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
, tk
->p_es
, &b
);
1186 if( b
&& tk
->i_cat
== VIDEO_ES
)
1188 p_stream_master
= tk
;
1192 p_stream_master
= tk
;
1196 if( !p_stream_master
)
1198 msg_Warn( p_demux
, "no more stream selected" );
1202 p_sys
->i_time
= AVI_GetPTS( p_stream_master
);
1204 for( i_packet
= 0; i_packet
< 10; i_packet
++)
1206 #define p_stream p_sys->track[avi_pk.i_stream]
1208 avi_packet_t avi_pk
;
1210 if( AVI_PacketGetHeader( p_demux
, &avi_pk
) )
1215 if( avi_pk
.i_stream
>= p_sys
->i_track
||
1216 ( avi_pk
.i_cat
!= AUDIO_ES
&& avi_pk
.i_cat
!= VIDEO_ES
) )
1218 /* we haven't found an audio or video packet:
1219 * - we have seek, found first next packet
1220 * - others packets could be found, skip them
1222 switch( avi_pk
.i_fourcc
)
1224 case AVIFOURCC_JUNK
:
1225 case AVIFOURCC_LIST
:
1226 case AVIFOURCC_RIFF
:
1227 return( !AVI_PacketNext( p_demux
) ? 1 : 0 );
1228 case AVIFOURCC_idx1
:
1231 return( !AVI_PacketNext( p_demux
) ? 1 : 0 );
1233 return( 0 ); /* eof */
1236 "seems to have lost position, resync" );
1237 if( AVI_PacketSearch( p_demux
) )
1239 msg_Err( p_demux
, "resync failed" );
1246 /* check for time */
1247 if( __ABS( AVI_GetPTS( p_stream
) -
1248 AVI_GetPTS( p_stream_master
) )< 600*1000 )
1250 /* load it and send to decoder */
1252 if( AVI_PacketRead( p_demux
, &avi_pk
, &p_frame
) || p_frame
== NULL
)
1256 p_frame
->i_pts
= AVI_GetPTS( p_stream
) + 1;
1258 if( avi_pk
.i_cat
!= VIDEO_ES
)
1259 p_frame
->i_dts
= p_frame
->i_pts
;
1262 p_frame
->i_dts
= p_frame
->i_pts
;
1263 p_frame
->i_pts
= VLC_TS_INVALID
;
1266 //p_pes->i_rate = p_demux->stream.control.i_rate;
1267 es_out_Send( p_demux
->out
, p_stream
->p_es
, p_frame
);
1271 if( AVI_PacketNext( p_demux
) )
1277 /* *** update stream time position *** */
1278 if( p_stream
->i_samplesize
)
1280 p_stream
->i_idxposb
+= avi_pk
.i_size
;
1284 if( p_stream
->i_cat
== AUDIO_ES
)
1286 p_stream
->i_blockno
+= p_stream
->i_blocksize
> 0 ? ( avi_pk
.i_size
+ p_stream
->i_blocksize
- 1 ) / p_stream
->i_blocksize
: 1;
1288 p_stream
->i_idxposc
++;
1298 /*****************************************************************************
1299 * Seek: goto to i_date or i_percent
1300 *****************************************************************************/
1301 static int Seek( demux_t
*p_demux
, mtime_t i_date
, int i_percent
)
1304 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1305 unsigned int i_stream
;
1306 msg_Dbg( p_demux
, "seek requested: %"PRId64
" seconds %d%%",
1307 i_date
/ 1000000, i_percent
);
1309 if( p_sys
->b_seekable
)
1311 if( !p_sys
->i_length
)
1313 avi_track_t
*p_stream
;
1316 /* use i_percent to create a true i_date */
1317 msg_Warn( p_demux
, "seeking without index at %d%%"
1318 " only works for interleaved files", i_percent
);
1319 if( i_percent
>= 100 )
1321 msg_Warn( p_demux
, "cannot seek so far !" );
1322 return VLC_EGENERIC
;
1324 i_percent
= __MAX( i_percent
, 0 );
1326 /* try to find chunk that is at i_percent or the file */
1327 i_pos
= __MAX( i_percent
* stream_Size( p_demux
->s
) / 100,
1328 p_sys
->i_movi_begin
);
1329 /* search first selected stream (and prefer non eof ones) */
1330 for( i_stream
= 0, p_stream
= NULL
;
1331 i_stream
< p_sys
->i_track
; i_stream
++ )
1333 if( !p_stream
|| p_stream
->b_eof
)
1334 p_stream
= p_sys
->track
[i_stream
];
1336 if( p_stream
->b_activated
&& !p_stream
->b_eof
)
1339 if( !p_stream
|| !p_stream
->b_activated
)
1341 msg_Warn( p_demux
, "cannot find any selected stream" );
1342 return VLC_EGENERIC
;
1345 /* be sure that the index exist */
1346 if( AVI_StreamChunkSet( p_demux
, i_stream
, 0 ) )
1348 msg_Warn( p_demux
, "cannot seek" );
1349 return VLC_EGENERIC
;
1352 while( i_pos
>= p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_pos
+
1353 p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_length
+ 8 )
1355 /* search after i_idxposc */
1356 if( AVI_StreamChunkSet( p_demux
,
1357 i_stream
, p_stream
->i_idxposc
+ 1 ) )
1359 msg_Warn( p_demux
, "cannot seek" );
1360 return VLC_EGENERIC
;
1364 i_date
= AVI_GetPTS( p_stream
);
1365 /* TODO better support for i_samplesize != 0 */
1366 msg_Dbg( p_demux
, "estimate date %"PRId64
, i_date
);
1370 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
1372 avi_track_t
*p_stream
= p_sys
->track
[i_stream
];
1374 if( !p_stream
->b_activated
)
1377 p_stream
->b_eof
= AVI_TrackSeek( p_demux
, i_stream
, i_date
) != 0;
1379 es_out_Control( p_demux
->out
, ES_OUT_SET_NEXT_DISPLAY_TIME
, i_date
);
1380 p_sys
->i_time
= i_date
;
1381 msg_Dbg( p_demux
, "seek: %"PRId64
" seconds", p_sys
->i_time
/1000000 );
1386 msg_Err( p_demux
, "shouldn't yet be executed" );
1387 return VLC_EGENERIC
;
1391 /*****************************************************************************
1393 *****************************************************************************/
1394 static double ControlGetPosition( demux_t
*p_demux
)
1396 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1398 if( p_sys
->i_length
> 0 )
1400 return (double)p_sys
->i_time
/ (double)( p_sys
->i_length
* (mtime_t
)1000000 );
1402 else if( stream_Size( p_demux
->s
) > 0 )
1408 /* search the more advanced selected es */
1409 for( i
= 0; i
< p_sys
->i_track
; i
++ )
1411 avi_track_t
*tk
= p_sys
->track
[i
];
1412 if( tk
->b_activated
&& tk
->i_idxposc
< tk
->idx
.i_size
)
1414 i_tmp
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_pos
+
1415 tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
+ 8;
1422 return (double)i64
/ stream_Size( p_demux
->s
);
1427 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
1429 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1437 case DEMUX_GET_POSITION
:
1438 pf
= (double*)va_arg( args
, double * );
1439 *pf
= ControlGetPosition( p_demux
);
1441 case DEMUX_SET_POSITION
:
1442 f
= (double)va_arg( args
, double );
1443 if( p_sys
->b_seekable
)
1445 i64
= (mtime_t
)(1000000.0 * p_sys
->i_length
* f
);
1446 return Seek( p_demux
, i64
, (int)(f
* 100) );
1450 int64_t i_pos
= stream_Size( p_demux
->s
) * f
;
1451 return stream_Seek( p_demux
->s
, i_pos
);
1454 case DEMUX_GET_TIME
:
1455 pi64
= (int64_t*)va_arg( args
, int64_t * );
1456 *pi64
= p_sys
->i_time
;
1459 case DEMUX_SET_TIME
:
1463 i64
= (int64_t)va_arg( args
, int64_t );
1464 if( p_sys
->i_length
> 0 )
1466 i_percent
= 100 * i64
/ (p_sys
->i_length
*1000000);
1468 else if( p_sys
->i_time
> 0 )
1470 i_percent
= (int)( 100.0 * ControlGetPosition( p_demux
) *
1471 (double)i64
/ (double)p_sys
->i_time
);
1473 return Seek( p_demux
, i64
, i_percent
);
1475 case DEMUX_GET_LENGTH
:
1476 pi64
= (int64_t*)va_arg( args
, int64_t * );
1477 *pi64
= p_sys
->i_length
* (mtime_t
)1000000;
1481 pf
= (double*)va_arg( args
, double * );
1483 for( i
= 0; i
< (int)p_sys
->i_track
; i
++ )
1485 avi_track_t
*tk
= p_sys
->track
[i
];
1486 if( tk
->i_cat
== VIDEO_ES
&& tk
->i_scale
> 0)
1488 *pf
= (float)tk
->i_rate
/ (float)tk
->i_scale
;
1494 case DEMUX_GET_META
:
1495 p_meta
= (vlc_meta_t
*)va_arg( args
, vlc_meta_t
* );
1496 vlc_meta_Merge( p_meta
, p_sys
->meta
);
1499 case DEMUX_GET_ATTACHMENTS
:
1501 if( p_sys
->i_attachment
<= 0 )
1502 return VLC_EGENERIC
;
1504 input_attachment_t
***ppp_attach
= va_arg( args
, input_attachment_t
*** );
1505 int *pi_int
= va_arg( args
, int * );
1507 *pi_int
= p_sys
->i_attachment
;
1508 *ppp_attach
= calloc( p_sys
->i_attachment
, sizeof(*ppp_attach
));
1509 for( unsigned i
= 0; i
< p_sys
->i_attachment
&& *ppp_attach
; i
++ )
1510 (*ppp_attach
)[i
] = vlc_input_attachment_Duplicate( p_sys
->attachment
[i
] );
1515 return VLC_EGENERIC
;
1519 /*****************************************************************************
1520 * Function to convert pts to chunk or byte
1521 *****************************************************************************/
1523 static mtime_t
AVI_PTSToChunk( avi_track_t
*tk
, mtime_t i_pts
)
1528 return (mtime_t
)((int64_t)i_pts
*
1529 (int64_t)tk
->i_rate
/
1530 (int64_t)tk
->i_scale
/
1533 static mtime_t
AVI_PTSToByte( avi_track_t
*tk
, mtime_t i_pts
)
1535 if( !tk
->i_scale
|| !tk
->i_samplesize
)
1538 return (mtime_t
)((int64_t)i_pts
*
1539 (int64_t)tk
->i_rate
/
1540 (int64_t)tk
->i_scale
/
1542 (int64_t)tk
->i_samplesize
);
1545 static mtime_t
AVI_GetDPTS( avi_track_t
*tk
, int64_t i_count
)
1552 i_dpts
= (mtime_t
)( (int64_t)1000000 *
1554 (int64_t)tk
->i_scale
/
1555 (int64_t)tk
->i_rate
);
1557 if( tk
->i_samplesize
)
1559 return i_dpts
/ tk
->i_samplesize
;
1564 static mtime_t
AVI_GetPTS( avi_track_t
*tk
)
1566 if( tk
->i_samplesize
)
1568 int64_t i_count
= 0;
1570 /* we need a valid entry we will emulate one */
1571 if( tk
->i_idxposc
== tk
->idx
.i_size
)
1575 /* use the last entry */
1576 i_count
= tk
->idx
.p_entry
[tk
->idx
.i_size
- 1].i_lengthtotal
1577 + tk
->idx
.p_entry
[tk
->idx
.i_size
- 1].i_length
;
1582 i_count
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_lengthtotal
;
1584 return AVI_GetDPTS( tk
, i_count
+ tk
->i_idxposb
);
1588 if( tk
->i_cat
== AUDIO_ES
)
1590 return AVI_GetDPTS( tk
, tk
->i_blockno
);
1594 return AVI_GetDPTS( tk
, tk
->i_idxposc
);
1599 static int AVI_StreamChunkFind( demux_t
*p_demux
, unsigned int i_stream
)
1601 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1602 avi_packet_t avi_pk
;
1603 int i_loop_count
= 0;
1605 /* find first chunk of i_stream that isn't in index */
1607 if( p_sys
->i_movi_lastchunk_pos
>= p_sys
->i_movi_begin
+ 12 )
1609 stream_Seek( p_demux
->s
, p_sys
->i_movi_lastchunk_pos
);
1610 if( AVI_PacketNext( p_demux
) )
1612 return VLC_EGENERIC
;
1617 stream_Seek( p_demux
->s
, p_sys
->i_movi_begin
+ 12 );
1622 if( !vlc_object_alive (p_demux
) ) return VLC_EGENERIC
;
1624 if( AVI_PacketGetHeader( p_demux
, &avi_pk
) )
1626 msg_Warn( p_demux
, "cannot get packet header" );
1627 return VLC_EGENERIC
;
1629 if( avi_pk
.i_stream
>= p_sys
->i_track
||
1630 ( avi_pk
.i_cat
!= AUDIO_ES
&& avi_pk
.i_cat
!= VIDEO_ES
) )
1632 if( AVI_PacketNext( p_demux
) )
1634 return VLC_EGENERIC
;
1637 /* Prevents from eating all the CPU with broken files.
1638 * This value should be low enough so that it doesn't
1639 * affect the reading speed too much. */
1640 if( !(++i_loop_count
% 1024) )
1642 if( !vlc_object_alive (p_demux
) ) return VLC_EGENERIC
;
1645 if( !(i_loop_count
% (1024 * 10)) )
1646 msg_Warn( p_demux
, "don't seem to find any data..." );
1651 avi_track_t
*tk_pk
= p_sys
->track
[avi_pk
.i_stream
];
1653 /* add this chunk to the index */
1655 index
.i_id
= avi_pk
.i_fourcc
;
1656 index
.i_flags
= AVI_GetKeyFlag(tk_pk
->i_codec
, avi_pk
.i_peek
);
1657 index
.i_pos
= avi_pk
.i_pos
;
1658 index
.i_length
= avi_pk
.i_size
;
1659 avi_index_Append( &tk_pk
->idx
, &p_sys
->i_movi_lastchunk_pos
, &index
);
1661 if( avi_pk
.i_stream
== i_stream
)
1666 if( AVI_PacketNext( p_demux
) )
1668 return VLC_EGENERIC
;
1674 /* be sure that i_ck will be a valid index entry */
1675 static int AVI_StreamChunkSet( demux_t
*p_demux
, unsigned int i_stream
,
1678 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1679 avi_track_t
*p_stream
= p_sys
->track
[i_stream
];
1681 p_stream
->i_idxposc
= i_ck
;
1682 p_stream
->i_idxposb
= 0;
1684 if( i_ck
>= p_stream
->idx
.i_size
)
1686 p_stream
->i_idxposc
= p_stream
->idx
.i_size
- 1;
1689 p_stream
->i_idxposc
++;
1690 if( AVI_StreamChunkFind( p_demux
, i_stream
) )
1692 return VLC_EGENERIC
;
1695 } while( p_stream
->i_idxposc
< i_ck
);
1701 /* XXX FIXME up to now, we assume that all chunk are one after one */
1702 static int AVI_StreamBytesSet( demux_t
*p_demux
,
1703 unsigned int i_stream
,
1706 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1707 avi_track_t
*p_stream
= p_sys
->track
[i_stream
];
1709 if( ( p_stream
->idx
.i_size
> 0 )
1710 &&( i_byte
< p_stream
->idx
.p_entry
[p_stream
->idx
.i_size
- 1].i_lengthtotal
+
1711 p_stream
->idx
.p_entry
[p_stream
->idx
.i_size
- 1].i_length
) )
1713 /* index is valid to find the ck */
1714 /* uses dichototmie to be fast enougth */
1715 int i_idxposc
= __MIN( p_stream
->i_idxposc
, p_stream
->idx
.i_size
- 1 );
1716 int i_idxmax
= p_stream
->idx
.i_size
;
1720 if( p_stream
->idx
.p_entry
[i_idxposc
].i_lengthtotal
> i_byte
)
1722 i_idxmax
= i_idxposc
;
1723 i_idxposc
= ( i_idxmin
+ i_idxposc
) / 2 ;
1727 if( p_stream
->idx
.p_entry
[i_idxposc
].i_lengthtotal
+
1728 p_stream
->idx
.p_entry
[i_idxposc
].i_length
<= i_byte
)
1730 i_idxmin
= i_idxposc
;
1731 i_idxposc
= (i_idxmax
+ i_idxposc
) / 2 ;
1735 p_stream
->i_idxposc
= i_idxposc
;
1736 p_stream
->i_idxposb
= i_byte
-
1737 p_stream
->idx
.p_entry
[i_idxposc
].i_lengthtotal
;
1746 p_stream
->i_idxposc
= p_stream
->idx
.i_size
- 1;
1747 p_stream
->i_idxposb
= 0;
1750 p_stream
->i_idxposc
++;
1751 if( AVI_StreamChunkFind( p_demux
, i_stream
) )
1753 return VLC_EGENERIC
;
1756 } while( p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_lengthtotal
+
1757 p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_length
<= i_byte
);
1759 p_stream
->i_idxposb
= i_byte
-
1760 p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_lengthtotal
;
1765 static int AVI_TrackSeek( demux_t
*p_demux
,
1769 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1770 avi_track_t
*tk
= p_sys
->track
[i_stream
];
1772 #define p_stream p_sys->track[i_stream]
1775 i_oldpts
= AVI_GetPTS( p_stream
);
1777 if( !p_stream
->i_samplesize
)
1779 if( AVI_StreamChunkSet( p_demux
,
1781 AVI_PTSToChunk( p_stream
, i_date
) ) )
1783 return VLC_EGENERIC
;
1786 if( p_stream
->i_cat
== AUDIO_ES
)
1790 for( i
= 0; i
< tk
->i_idxposc
; i
++ )
1792 if( tk
->i_blocksize
> 0 )
1794 tk
->i_blockno
+= ( tk
->idx
.p_entry
[i
].i_length
+ tk
->i_blocksize
- 1 ) / tk
->i_blocksize
;
1804 "old:%"PRId64
" %s new %"PRId64
,
1806 i_oldpts
> i_date
? ">" : "<",
1809 if( p_stream
->i_cat
== VIDEO_ES
)
1811 /* search key frame */
1812 //if( i_date < i_oldpts || 1 )
1814 while( p_stream
->i_idxposc
> 0 &&
1815 !( p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_flags
&
1818 if( AVI_StreamChunkSet( p_demux
,
1820 p_stream
->i_idxposc
- 1 ) )
1822 return VLC_EGENERIC
;
1829 while( p_stream
->i_idxposc
< p_stream
->idx
.i_size
&&
1830 !( p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_flags
&
1833 if( AVI_StreamChunkSet( p_demux
,
1835 p_stream
->i_idxposc
+ 1 ) )
1837 return VLC_EGENERIC
;
1846 if( AVI_StreamBytesSet( p_demux
,
1848 AVI_PTSToByte( p_stream
, i_date
) ) )
1850 return VLC_EGENERIC
;
1857 /****************************************************************************
1858 * Return true if it's a key frame
1859 ****************************************************************************/
1860 static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc
, uint8_t *p_byte
)
1864 case VLC_CODEC_DIV1
:
1866 * startcode: 0x00000100 32bits
1867 * framenumber ? 5bits
1868 * piture type 0(I),1(P) 2bits
1870 if( GetDWBE( p_byte
) != 0x00000100 )
1872 /* it's not an msmpegv1 stream, strange...*/
1873 return AVIIF_KEYFRAME
;
1875 return p_byte
[4] & 0x06 ? 0 : AVIIF_KEYFRAME
;
1877 case VLC_CODEC_DIV2
:
1878 case VLC_CODEC_DIV3
:
1879 case VLC_CODEC_WMV1
:
1881 * picture type 0(I),1(P) 2bits
1883 return p_byte
[0] & 0xC0 ? 0 : AVIIF_KEYFRAME
;
1884 case VLC_CODEC_MP4V
:
1885 /* we should find first occurrence of 0x000001b6 (32bits)
1886 * startcode: 0x000001b6 32bits
1887 * piture type 0(I),1(P) 2bits
1889 if( GetDWBE( p_byte
) != 0x000001b6 )
1891 /* not true , need to find the first VOP header */
1892 return AVIIF_KEYFRAME
;
1894 return p_byte
[4] & 0xC0 ? 0 : AVIIF_KEYFRAME
;
1897 /* I can't do it, so say yes */
1898 return AVIIF_KEYFRAME
;
1902 vlc_fourcc_t
AVI_FourccGetCodec( unsigned int i_cat
, vlc_fourcc_t i_codec
)
1907 wf_tag_to_fourcc( i_codec
, &i_codec
, NULL
);
1910 return vlc_fourcc_GetCodec( i_cat
, i_codec
);
1912 return VLC_FOURCC( 'u', 'n', 'd', 'f' );
1916 /****************************************************************************
1918 ****************************************************************************/
1919 static void AVI_ParseStreamHeader( vlc_fourcc_t i_id
,
1920 unsigned int *pi_number
, unsigned int *pi_type
)
1922 #define SET_PTR( p, v ) if( p ) *(p) = (v);
1925 c1
= ((uint8_t *)&i_id
)[0];
1926 c2
= ((uint8_t *)&i_id
)[1];
1928 if( c1
< '0' || c1
> '9' || c2
< '0' || c2
> '9' )
1930 SET_PTR( pi_number
, 100 ); /* > max stream number */
1931 SET_PTR( pi_type
, UNKNOWN_ES
);
1935 SET_PTR( pi_number
, (c1
- '0') * 10 + (c2
- '0' ) );
1936 switch( VLC_TWOCC( ((uint8_t *)&i_id
)[2], ((uint8_t *)&i_id
)[3] ) )
1939 SET_PTR( pi_type
, AUDIO_ES
);
1944 SET_PTR( pi_type
, VIDEO_ES
);
1948 SET_PTR( pi_type
, SPU_ES
);
1951 SET_PTR( pi_type
, UNKNOWN_ES
);
1958 /****************************************************************************
1960 ****************************************************************************/
1961 static int AVI_PacketGetHeader( demux_t
*p_demux
, avi_packet_t
*p_pk
)
1963 const uint8_t *p_peek
;
1965 if( stream_Peek( p_demux
->s
, &p_peek
, 16 ) < 16 )
1967 return VLC_EGENERIC
;
1969 p_pk
->i_fourcc
= VLC_FOURCC( p_peek
[0], p_peek
[1], p_peek
[2], p_peek
[3] );
1970 p_pk
->i_size
= GetDWLE( p_peek
+ 4 );
1971 p_pk
->i_pos
= stream_Tell( p_demux
->s
);
1972 if( p_pk
->i_fourcc
== AVIFOURCC_LIST
|| p_pk
->i_fourcc
== AVIFOURCC_RIFF
)
1974 p_pk
->i_type
= VLC_FOURCC( p_peek
[8], p_peek
[9],
1975 p_peek
[10], p_peek
[11] );
1982 memcpy( p_pk
->i_peek
, p_peek
+ 8, 8 );
1984 AVI_ParseStreamHeader( p_pk
->i_fourcc
, &p_pk
->i_stream
, &p_pk
->i_cat
);
1988 static int AVI_PacketNext( demux_t
*p_demux
)
1990 avi_packet_t avi_ck
;
1993 if( AVI_PacketGetHeader( p_demux
, &avi_ck
) )
1995 return VLC_EGENERIC
;
1998 if( avi_ck
.i_fourcc
== AVIFOURCC_LIST
&&
1999 ( avi_ck
.i_type
== AVIFOURCC_rec
|| avi_ck
.i_type
== AVIFOURCC_movi
) )
2003 else if( avi_ck
.i_fourcc
== AVIFOURCC_RIFF
&&
2004 avi_ck
.i_type
== AVIFOURCC_AVIX
)
2010 i_skip
= __EVEN( avi_ck
.i_size
) + 8;
2013 if( stream_Read( p_demux
->s
, NULL
, i_skip
) != i_skip
)
2015 return VLC_EGENERIC
;
2020 static int AVI_PacketRead( demux_t
*p_demux
,
2022 block_t
**pp_frame
)
2026 i_size
= __EVEN( p_pk
->i_size
+ 8 );
2028 if( ( *pp_frame
= stream_Block( p_demux
->s
, i_size
) ) == NULL
)
2030 return VLC_EGENERIC
;
2032 (*pp_frame
)->p_buffer
+= 8;
2033 (*pp_frame
)->i_buffer
-= 8;
2035 if( i_size
!= p_pk
->i_size
+ 8 )
2037 (*pp_frame
)->i_buffer
--;
2043 static int AVI_PacketSearch( demux_t
*p_demux
)
2045 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2046 avi_packet_t avi_pk
;
2051 if( stream_Read( p_demux
->s
, NULL
, 1 ) != 1 )
2053 return VLC_EGENERIC
;
2055 AVI_PacketGetHeader( p_demux
, &avi_pk
);
2056 if( avi_pk
.i_stream
< p_sys
->i_track
&&
2057 ( avi_pk
.i_cat
== AUDIO_ES
|| avi_pk
.i_cat
== VIDEO_ES
) )
2061 switch( avi_pk
.i_fourcc
)
2063 case AVIFOURCC_JUNK
:
2064 case AVIFOURCC_LIST
:
2065 case AVIFOURCC_RIFF
:
2066 case AVIFOURCC_idx1
:
2070 /* Prevents from eating all the CPU with broken files.
2071 * This value should be low enough so that it doesn't affect the
2072 * reading speed too much (not that we care much anyway because
2073 * this code is called only on broken files). */
2074 if( !(++i_count
% 1024) )
2076 if( !vlc_object_alive (p_demux
) ) return VLC_EGENERIC
;
2079 if( !(i_count
% (1024 * 10)) )
2080 msg_Warn( p_demux
, "trying to resync..." );
2085 /****************************************************************************
2087 ****************************************************************************/
2088 static void avi_index_Init( avi_index_t
*p_index
)
2090 p_index
->i_size
= 0;
2092 p_index
->p_entry
= NULL
;
2094 static void avi_index_Clean( avi_index_t
*p_index
)
2096 free( p_index
->p_entry
);
2098 static void avi_index_Append( avi_index_t
*p_index
, off_t
*pi_last_pos
,
2099 avi_entry_t
*p_entry
)
2101 /* Update last chunk position */
2102 if( *pi_last_pos
< p_entry
->i_pos
)
2103 *pi_last_pos
= p_entry
->i_pos
;
2106 if( p_index
->i_size
>= p_index
->i_max
)
2108 p_index
->i_max
+= 16384;
2109 p_index
->p_entry
= realloc_or_free( p_index
->p_entry
,
2110 p_index
->i_max
* sizeof( *p_index
->p_entry
) );
2111 if( !p_index
->p_entry
)
2114 /* calculate cumulate length */
2115 if( p_index
->i_size
> 0 )
2117 p_entry
->i_lengthtotal
=
2118 p_index
->p_entry
[p_index
->i_size
- 1].i_length
+
2119 p_index
->p_entry
[p_index
->i_size
- 1].i_lengthtotal
;
2123 p_entry
->i_lengthtotal
= 0;
2126 p_index
->p_entry
[p_index
->i_size
++] = *p_entry
;
2129 static int AVI_IndexFind_idx1( demux_t
*p_demux
,
2130 avi_chunk_idx1_t
**pp_idx1
,
2131 uint64_t *pi_offset
)
2133 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2135 avi_chunk_list_t
*p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0);
2136 avi_chunk_idx1_t
*p_idx1
= AVI_ChunkFind( p_riff
, AVIFOURCC_idx1
, 0);
2140 msg_Warn( p_demux
, "cannot find idx1 chunk, no index defined" );
2141 return VLC_EGENERIC
;
2145 /* *** calculate offset *** */
2146 /* Well, avi is __SHIT__ so test more than one entry
2147 * (needed for some avi files) */
2148 avi_chunk_list_t
*p_movi
= AVI_ChunkFind( p_riff
, AVIFOURCC_movi
, 0);
2150 for( unsigned i
= 0; i
< __MIN( p_idx1
->i_entry_count
, 10 ); i
++ )
2152 if( p_idx1
->entry
[i
].i_pos
< p_movi
->i_chunk_pos
)
2154 *pi_offset
= p_movi
->i_chunk_pos
+ 8;
2161 static int AVI_IndexLoad_idx1( demux_t
*p_demux
,
2162 avi_index_t p_index
[], off_t
*pi_last_offset
)
2164 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2166 avi_chunk_idx1_t
*p_idx1
;
2168 if( AVI_IndexFind_idx1( p_demux
, &p_idx1
, &i_offset
) )
2169 return VLC_EGENERIC
;
2171 for( unsigned i_index
= 0; i_index
< p_idx1
->i_entry_count
; i_index
++ )
2176 AVI_ParseStreamHeader( p_idx1
->entry
[i_index
].i_fourcc
,
2179 if( i_stream
< p_sys
->i_track
&&
2180 i_cat
== p_sys
->track
[i_stream
]->i_cat
)
2183 index
.i_id
= p_idx1
->entry
[i_index
].i_fourcc
;
2184 index
.i_flags
= p_idx1
->entry
[i_index
].i_flags
&(~AVIIF_FIXKEYFRAME
);
2185 index
.i_pos
= p_idx1
->entry
[i_index
].i_pos
+ i_offset
;
2186 index
.i_length
= p_idx1
->entry
[i_index
].i_length
;
2188 avi_index_Append( &p_index
[i_stream
], pi_last_offset
, &index
);
2194 static void __Parse_indx( demux_t
*p_demux
, avi_index_t
*p_index
, off_t
*pi_max_offset
,
2195 avi_chunk_indx_t
*p_indx
)
2199 msg_Dbg( p_demux
, "loading subindex(0x%x) %d entries", p_indx
->i_indextype
, p_indx
->i_entriesinuse
);
2200 if( p_indx
->i_indexsubtype
== 0 )
2202 for( unsigned i
= 0; i
< p_indx
->i_entriesinuse
; i
++ )
2204 index
.i_id
= p_indx
->i_id
;
2205 index
.i_flags
= p_indx
->idx
.std
[i
].i_size
& 0x80000000 ? 0 : AVIIF_KEYFRAME
;
2206 index
.i_pos
= p_indx
->i_baseoffset
+ p_indx
->idx
.std
[i
].i_offset
- 8;
2207 index
.i_length
= p_indx
->idx
.std
[i
].i_size
&0x7fffffff;
2209 avi_index_Append( p_index
, pi_max_offset
, &index
);
2212 else if( p_indx
->i_indexsubtype
== AVI_INDEX_2FIELD
)
2214 for( unsigned i
= 0; i
< p_indx
->i_entriesinuse
; i
++ )
2216 index
.i_id
= p_indx
->i_id
;
2217 index
.i_flags
= p_indx
->idx
.field
[i
].i_size
& 0x80000000 ? 0 : AVIIF_KEYFRAME
;
2218 index
.i_pos
= p_indx
->i_baseoffset
+ p_indx
->idx
.field
[i
].i_offset
- 8;
2219 index
.i_length
= p_indx
->idx
.field
[i
].i_size
;
2221 avi_index_Append( p_index
, pi_max_offset
, &index
);
2226 msg_Warn( p_demux
, "unknown subtype index(0x%x)", p_indx
->i_indexsubtype
);
2230 static void AVI_IndexLoad_indx( demux_t
*p_demux
,
2231 avi_index_t p_index
[], off_t
*pi_last_offset
)
2233 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2235 avi_chunk_list_t
*p_riff
;
2236 avi_chunk_list_t
*p_hdrl
;
2238 p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0);
2239 p_hdrl
= AVI_ChunkFind( p_riff
, AVIFOURCC_hdrl
, 0 );
2241 for( unsigned i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
2243 avi_chunk_list_t
*p_strl
;
2244 avi_chunk_indx_t
*p_indx
;
2246 #define p_stream p_sys->track[i_stream]
2247 p_strl
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_strl
, i_stream
);
2248 p_indx
= AVI_ChunkFind( p_strl
, AVIFOURCC_indx
, 0 );
2253 msg_Warn( p_demux
, "cannot find indx (misdetect/broken OpenDML "
2258 if( p_indx
->i_indextype
== AVI_INDEX_OF_CHUNKS
)
2260 __Parse_indx( p_demux
, &p_index
[i_stream
], pi_last_offset
, p_indx
);
2262 else if( p_indx
->i_indextype
== AVI_INDEX_OF_INDEXES
)
2265 for( unsigned i
= 0; i
< p_indx
->i_entriesinuse
; i
++ )
2267 if( stream_Seek( p_demux
->s
, p_indx
->idx
.super
[i
].i_offset
)||
2268 AVI_ChunkRead( p_demux
->s
, &ck_sub
, NULL
) )
2272 if( ck_sub
.indx
.i_indextype
== AVI_INDEX_OF_CHUNKS
)
2273 __Parse_indx( p_demux
, &p_index
[i_stream
], pi_last_offset
, &ck_sub
.indx
);
2274 AVI_ChunkFree( p_demux
->s
, &ck_sub
);
2279 msg_Warn( p_demux
, "unknown type index(0x%x)", p_indx
->i_indextype
);
2285 static void AVI_IndexLoad( demux_t
*p_demux
)
2287 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2290 assert( p_sys
->i_track
<= 100 );
2291 avi_index_t p_idx_indx
[p_sys
->i_track
];
2292 avi_index_t p_idx_idx1
[p_sys
->i_track
];
2293 for( unsigned i
= 0; i
< p_sys
->i_track
; i
++ )
2295 avi_index_Init( &p_idx_indx
[i
] );
2296 avi_index_Init( &p_idx_idx1
[i
] );
2298 off_t i_indx_last_pos
= p_sys
->i_movi_lastchunk_pos
;
2299 off_t i_idx1_last_pos
= p_sys
->i_movi_lastchunk_pos
;
2301 AVI_IndexLoad_indx( p_demux
, p_idx_indx
, &i_indx_last_pos
);
2302 if( !p_sys
->b_odml
)
2303 AVI_IndexLoad_idx1( p_demux
, p_idx_idx1
, &i_idx1_last_pos
);
2305 /* Select the longest index */
2306 for( unsigned i
= 0; i
< p_sys
->i_track
; i
++ )
2308 if( p_idx_indx
[i
].i_size
> p_idx_idx1
[i
].i_size
)
2310 msg_Dbg( p_demux
, "selected ODML index for stream[%u]", i
);
2311 p_sys
->track
[i
]->idx
= p_idx_indx
[i
];
2312 avi_index_Clean( &p_idx_idx1
[i
] );
2316 msg_Dbg( p_demux
, "selected standard index for stream[%u]", i
);
2317 p_sys
->track
[i
]->idx
= p_idx_idx1
[i
];
2318 avi_index_Clean( &p_idx_indx
[i
] );
2321 p_sys
->i_movi_lastchunk_pos
= __MAX( i_indx_last_pos
, i_idx1_last_pos
);
2323 for( unsigned i
= 0; i
< p_sys
->i_track
; i
++ )
2325 avi_index_t
*p_index
= &p_sys
->track
[i
]->idx
;
2329 for( unsigned j
= 0; !b_key
&& j
< p_index
->i_size
; j
++ )
2330 b_key
= p_index
->p_entry
[j
].i_flags
& AVIIF_KEYFRAME
;
2333 msg_Err( p_demux
, "no key frame set for track %u", i
);
2334 for( unsigned j
= 0; j
< p_index
->i_size
; j
++ )
2335 p_index
->p_entry
[j
].i_flags
|= AVIIF_KEYFRAME
;
2339 msg_Dbg( p_demux
, "stream[%d] created %d index entries",
2340 i
, p_index
->i_size
);
2344 static void AVI_IndexCreate( demux_t
*p_demux
)
2346 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2348 avi_chunk_list_t
*p_riff
;
2349 avi_chunk_list_t
*p_movi
;
2351 unsigned int i_stream
;
2354 mtime_t i_dialog_update
;
2355 dialog_progress_bar_t
*p_dialog
= NULL
;
2357 p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0);
2358 p_movi
= AVI_ChunkFind( p_riff
, AVIFOURCC_movi
, 0);
2362 msg_Err( p_demux
, "cannot find p_movi" );
2366 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
2367 avi_index_Init( &p_sys
->track
[i_stream
]->idx
);
2369 i_movi_end
= __MIN( (off_t
)(p_movi
->i_chunk_pos
+ p_movi
->i_chunk_size
),
2370 stream_Size( p_demux
->s
) );
2372 stream_Seek( p_demux
->s
, p_movi
->i_chunk_pos
+ 12 );
2373 msg_Warn( p_demux
, "creating index from LIST-movi, will take time !" );
2376 /* Only show dialog if AVI is > 10MB */
2377 i_dialog_update
= mdate();
2378 if( stream_Size( p_demux
->s
) > 10000000 )
2379 p_dialog
= dialog_ProgressCreate( p_demux
, _("Fixing AVI Index..."),
2380 NULL
, _("Cancel") );
2386 if( !vlc_object_alive (p_demux
) )
2389 /* Don't update/check dialog too often */
2390 if( p_dialog
&& mdate() - i_dialog_update
> 100000 )
2392 if( dialog_ProgressCancelled( p_dialog
) )
2395 double f_current
= stream_Tell( p_demux
->s
);
2396 double f_size
= stream_Size( p_demux
->s
);
2397 double f_pos
= f_current
/ f_size
;
2398 dialog_ProgressSet( p_dialog
, NULL
, f_pos
);
2400 i_dialog_update
= mdate();
2403 if( AVI_PacketGetHeader( p_demux
, &pk
) )
2406 if( pk
.i_stream
< p_sys
->i_track
&&
2407 pk
.i_cat
== p_sys
->track
[pk
.i_stream
]->i_cat
)
2409 avi_track_t
*tk
= p_sys
->track
[pk
.i_stream
];
2412 index
.i_id
= pk
.i_fourcc
;
2413 index
.i_flags
= AVI_GetKeyFlag(tk
->i_codec
, pk
.i_peek
);
2414 index
.i_pos
= pk
.i_pos
;
2415 index
.i_length
= pk
.i_size
;
2416 avi_index_Append( &tk
->idx
, &p_sys
->i_movi_lastchunk_pos
, &index
);
2420 switch( pk
.i_fourcc
)
2422 case AVIFOURCC_idx1
:
2425 avi_chunk_list_t
*p_sysx
;
2426 p_sysx
= AVI_ChunkFind( &p_sys
->ck_root
,
2427 AVIFOURCC_RIFF
, 1 );
2429 msg_Dbg( p_demux
, "looking for new RIFF chunk" );
2430 if( stream_Seek( p_demux
->s
, p_sysx
->i_chunk_pos
+ 24 ) )
2436 case AVIFOURCC_RIFF
:
2437 msg_Dbg( p_demux
, "new RIFF chunk found" );
2441 case AVIFOURCC_JUNK
:
2445 msg_Warn( p_demux
, "need resync, probably broken avi" );
2446 if( AVI_PacketSearch( p_demux
) )
2448 msg_Warn( p_demux
, "lost sync, abord index creation" );
2454 if( ( !p_sys
->b_odml
&& pk
.i_pos
+ pk
.i_size
>= i_movi_end
) ||
2455 AVI_PacketNext( p_demux
) )
2462 if( p_dialog
!= NULL
)
2463 dialog_ProgressDestroy( p_dialog
);
2465 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
2467 msg_Dbg( p_demux
, "stream[%d] creating %d index entries",
2468 i_stream
, p_sys
->track
[i_stream
]->idx
.i_size
);
2473 static void AVI_MetaLoad( demux_t
*p_demux
,
2474 avi_chunk_list_t
*p_riff
, avi_chunk_avih_t
*p_avih
)
2476 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2478 vlc_meta_t
*p_meta
= p_sys
->meta
= vlc_meta_New();
2483 snprintf( buffer
, sizeof(buffer
), "%s%s%s%s",
2484 p_avih
->i_flags
&AVIF_HASINDEX
? " HAS_INDEX" : "",
2485 p_avih
->i_flags
&AVIF_MUSTUSEINDEX
? " MUST_USE_INDEX" : "",
2486 p_avih
->i_flags
&AVIF_ISINTERLEAVED
? " IS_INTERLEAVED" : "",
2487 p_avih
->i_flags
&AVIF_TRUSTCKTYPE
? " TRUST_CKTYPE" : "" );
2488 vlc_meta_SetSetting( p_meta
, buffer
);
2490 avi_chunk_list_t
*p_info
= AVI_ChunkFind( p_riff
, AVIFOURCC_INFO
, 0 );
2494 static const struct {
2498 { AVIFOURCC_IART
, vlc_meta_Artist
},
2499 { AVIFOURCC_ICMT
, vlc_meta_Description
},
2500 { AVIFOURCC_ICOP
, vlc_meta_Copyright
},
2501 { AVIFOURCC_IGNR
, vlc_meta_Genre
},
2502 { AVIFOURCC_INAM
, vlc_meta_Title
},
2505 for( int i
= 0; p_dsc
[i
].i_id
!= 0; i
++ )
2507 avi_chunk_STRING_t
*p_strz
= AVI_ChunkFind( p_info
, p_dsc
[i
].i_id
, 0 );
2510 char *psz_value
= FromACP( p_strz
->p_str
);
2515 vlc_meta_Set( p_meta
, p_dsc
[i
].i_type
, psz_value
);
2520 /*****************************************************************************
2522 *****************************************************************************/
2523 static void AVI_ExtractSubtitle( demux_t
*p_demux
,
2524 unsigned int i_stream
,
2525 avi_chunk_list_t
*p_strl
,
2526 avi_chunk_STRING_t
*p_strn
)
2528 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2529 block_t
*p_block
= NULL
;
2530 input_attachment_t
*p_attachment
= NULL
;
2531 char *psz_description
= NULL
;
2532 avi_chunk_indx_t
*p_indx
= NULL
;
2534 if( !p_sys
->b_seekable
)
2537 p_indx
= AVI_ChunkFind( p_strl
, AVIFOURCC_indx
, 0 );
2543 if( p_indx
->i_indextype
== AVI_INDEX_OF_INDEXES
&&
2544 p_indx
->i_entriesinuse
> 0 )
2546 if( stream_Seek( p_demux
->s
, p_indx
->idx
.super
[0].i_offset
)||
2547 AVI_ChunkRead( p_demux
->s
, &ck
, NULL
) )
2552 if( p_indx
->i_indextype
!= AVI_INDEX_OF_CHUNKS
||
2553 p_indx
->i_entriesinuse
!= 1 ||
2554 p_indx
->i_indexsubtype
!= 0 )
2557 i_position
= p_indx
->i_baseoffset
+
2558 p_indx
->idx
.std
[0].i_offset
- 8;
2559 i_size
= (p_indx
->idx
.std
[0].i_size
& 0x7fffffff) + 8;
2563 avi_chunk_idx1_t
*p_idx1
;
2566 if( AVI_IndexFind_idx1( p_demux
, &p_idx1
, &i_offset
) )
2570 for( unsigned i
= 0; i
< p_idx1
->i_entry_count
; i
++ )
2572 const idx1_entry_t
*e
= &p_idx1
->entry
[i
];
2574 unsigned i_stream_idx
;
2576 AVI_ParseStreamHeader( e
->i_fourcc
, &i_stream_idx
, &i_cat
);
2577 if( i_cat
== SPU_ES
&& i_stream_idx
== i_stream
)
2579 i_position
= e
->i_pos
+ i_offset
;
2580 i_size
= e
->i_length
+ 8;
2589 if( i_size
> 1000000 )
2592 if( stream_Seek( p_demux
->s
, i_position
) )
2594 p_block
= stream_Block( p_demux
->s
, i_size
);
2598 /* Parse packet header */
2599 const uint8_t *p
= p_block
->p_buffer
;
2600 if( i_size
< 8 || p
[2] != 't' || p
[3] != 'x' )
2605 /* Parse subtitle chunk header */
2606 if( i_size
< 11 || memcmp( p
, "GAB2", 4 ) ||
2607 p
[4] != 0x00 || GetWLE( &p
[5] ) != 0x2 )
2609 const unsigned i_name
= GetDWLE( &p
[7] );
2610 if( 11 + i_size
<= i_name
)
2613 psz_description
= FromCharset( "UTF-16LE", &p
[11], i_name
);
2615 i_size
-= 11 + i_name
;
2616 if( i_size
< 6 || GetWLE( &p
[0] ) != 0x04 )
2618 const unsigned i_payload
= GetDWLE( &p
[2] );
2619 if( i_size
< 6 + i_payload
|| i_payload
<= 0 )
2624 if( !psz_description
)
2625 psz_description
= p_strn
? FromACP( p_strn
->p_str
) : NULL
;
2627 if( asprintf( &psz_name
, "subtitle%d.srt", p_sys
->i_attachment
) <= 0 )
2629 p_attachment
= vlc_input_attachment_New( psz_name
,
2630 "application/x-srt",
2634 TAB_APPEND( p_sys
->i_attachment
, p_sys
->attachment
, p_attachment
);
2638 free( psz_description
);
2641 block_Release( p_block
);
2644 msg_Dbg( p_demux
, "Loaded an embed subtitle" );
2646 msg_Warn( p_demux
, "Failed to load an embed subtitle" );
2648 if( p_indx
== &ck
.indx
)
2649 AVI_ChunkFree( p_demux
->s
, &ck
);
2651 /*****************************************************************************
2653 *****************************************************************************/
2654 static int AVI_TrackStopFinishedStreams( demux_t
*p_demux
)
2656 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2660 for( i
= 0; i
< p_sys
->i_track
; i
++ )
2662 avi_track_t
*tk
= p_sys
->track
[i
];
2663 if( tk
->i_idxposc
>= tk
->idx
.i_size
)
2675 /****************************************************************************
2676 * AVI_MovieGetLength give max streams length in second
2677 ****************************************************************************/
2678 static mtime_t
AVI_MovieGetLength( demux_t
*p_demux
)
2680 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2681 mtime_t i_maxlength
= 0;
2684 for( i
= 0; i
< p_sys
->i_track
; i
++ )
2686 avi_track_t
*tk
= p_sys
->track
[i
];
2689 /* fix length for each stream */
2690 if( tk
->idx
.i_size
< 1 || !tk
->idx
.p_entry
)
2695 if( tk
->i_samplesize
)
2697 i_length
= AVI_GetDPTS( tk
,
2698 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_lengthtotal
+
2699 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_length
);
2703 i_length
= AVI_GetDPTS( tk
, tk
->idx
.i_size
);
2705 i_length
/= (mtime_t
)1000000; /* in seconds */
2708 "stream[%d] length:%"PRId64
" (based on index)",
2711 i_maxlength
= __MAX( i_maxlength
, i_length
);