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, NULL
,
75 INTERLEAVE_TEXT
, INTERLEAVE_LONGTEXT
, true )
76 add_integer( "avi-index", 0, NULL
,
77 INDEX_TEXT
, INDEX_LONGTEXT
, false )
78 change_integer_list( pi_index
, ppsz_indexes
, NULL
)
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) )
95 vlc_fourcc_t i_fourcc
;
98 vlc_fourcc_t i_type
; /* only for AVIFOURCC_LIST */
100 uint8_t i_peek
[8]; /* first 8 bytes */
102 unsigned int i_stream
;
113 int64_t i_lengthtotal
;
121 avi_entry_t
*p_entry
;
124 static void avi_index_Init( avi_index_t
* );
125 static void avi_index_Clean( avi_index_t
* );
126 static void avi_index_Append( avi_index_t
*, off_t
*, avi_entry_t
* );
133 unsigned int i_cat
; /* AUDIO_ES, VIDEO_ES */
134 vlc_fourcc_t i_codec
;
138 unsigned int i_samplesize
;
145 unsigned int i_idxposc
; /* numero of chunk */
146 unsigned int i_idxposb
; /* byte in the current chunk */
148 /* For VBR audio only */
149 unsigned int i_blockno
;
150 unsigned int i_blocksize
;
152 /* For muxed streams */
153 stream_t
*p_out_muxed
;
168 off_t i_movi_lastchunk_pos
; /* XXX position of last valid chunk */
170 /* number of streams and information */
171 unsigned int i_track
;
177 unsigned int i_attachment
;
178 input_attachment_t
**attachment
;
181 static inline off_t
__EVEN( off_t i
)
183 return (i
& 1) ? i
+ 1 : i
;
186 static mtime_t
AVI_PTSToChunk( avi_track_t
*, mtime_t i_pts
);
187 static mtime_t
AVI_PTSToByte ( avi_track_t
*, mtime_t i_pts
);
188 static mtime_t
AVI_GetDPTS ( avi_track_t
*, int64_t i_count
);
189 static mtime_t
AVI_GetPTS ( avi_track_t
* );
192 static int AVI_StreamChunkFind( demux_t
*, unsigned int i_stream
);
193 static int AVI_StreamChunkSet ( demux_t
*,
194 unsigned int i_stream
, unsigned int i_ck
);
195 static int AVI_StreamBytesSet ( demux_t
*,
196 unsigned int i_stream
, off_t i_byte
);
198 vlc_fourcc_t
AVI_FourccGetCodec( unsigned int i_cat
, vlc_fourcc_t
);
199 static int AVI_GetKeyFlag ( vlc_fourcc_t
, uint8_t * );
201 static int AVI_PacketGetHeader( demux_t
*, avi_packet_t
*p_pk
);
202 static int AVI_PacketNext ( demux_t
* );
203 static int AVI_PacketRead ( demux_t
*, avi_packet_t
*, block_t
**);
204 static int AVI_PacketSearch ( demux_t
* );
206 static void AVI_IndexLoad ( demux_t
* );
207 static void AVI_IndexCreate ( demux_t
* );
209 static void AVI_ExtractSubtitle( demux_t
*, int i_stream
, avi_chunk_list_t
*, avi_chunk_STRING_t
* );
211 static mtime_t
AVI_MovieGetLength( demux_t
* );
213 static void AVI_MetaLoad( demux_t
*, avi_chunk_list_t
*p_riff
, avi_chunk_avih_t
*p_avih
);
215 /*****************************************************************************
217 *****************************************************************************/
218 static int AVI_TrackSeek ( demux_t
*, int, mtime_t
);
219 static int AVI_TrackStopFinishedStreams( demux_t
*);
222 - For VBR mp3 stream:
223 count blocks by rounded-up chunksizes instead of chunks
224 we need full emulation of dshow avi demuxer bugs :(
225 fixes silly nandub-style a-v delaying in avi with vbr mp3...
226 (from mplayer 2002/08/02)
230 /*****************************************************************************
231 * Open: check file and initializes AVI structures
232 *****************************************************************************/
233 static int Open( vlc_object_t
* p_this
)
235 demux_t
*p_demux
= (demux_t
*)p_this
;
238 bool b_index
= false;
241 avi_chunk_list_t
*p_riff
;
242 avi_chunk_list_t
*p_hdrl
, *p_movi
;
243 avi_chunk_avih_t
*p_avih
;
245 unsigned int i_track
;
246 unsigned int i
, i_peeker
;
248 const uint8_t *p_peek
;
250 /* Is it an avi file ? */
251 if( stream_Peek( p_demux
->s
, &p_peek
, 200 ) < 200 ) return VLC_EGENERIC
;
253 for( i_peeker
= 0; i_peeker
< 188; i_peeker
++ )
255 if( !strncmp( (char *)&p_peek
[0], "RIFF", 4 ) && !strncmp( (char *)&p_peek
[8], "AVI ", 4 ) )
257 if( !strncmp( (char *)&p_peek
[0], "ON2 ", 4 ) && !strncmp( (char *)&p_peek
[8], "ON2f", 4 ) )
261 if( i_peeker
== 188 )
266 /* Initialize input structures. */
267 p_sys
= p_demux
->p_sys
= malloc( sizeof(demux_sys_t
) );
268 memset( p_sys
, 0, sizeof( demux_sys_t
) );
271 p_sys
->i_movi_lastchunk_pos
= 0;
272 p_sys
->b_odml
= false;
273 p_sys
->b_muxed
= false;
277 TAB_INIT(p_sys
->i_attachment
, p_sys
->attachment
);
279 stream_Control( p_demux
->s
, STREAM_CAN_FASTSEEK
, &p_sys
->b_seekable
);
281 p_demux
->pf_control
= Control
;
282 p_demux
->pf_demux
= Demux_Seekable
;
284 /* For unseekable stream, automaticaly use Demux_UnSeekable */
285 if( !p_sys
->b_seekable
286 || var_InheritInteger( p_demux
, "avi-interleaved" ) )
288 p_demux
->pf_demux
= Demux_UnSeekable
;
293 stream_Read( p_demux
->s
, NULL
, i_peeker
);
296 if( AVI_ChunkReadRoot( p_demux
->s
, &p_sys
->ck_root
) )
298 msg_Err( p_demux
, "avi module discarded (invalid file)" );
303 if( AVI_ChunkCount( &p_sys
->ck_root
, AVIFOURCC_RIFF
) > 1 )
305 unsigned int i_count
=
306 AVI_ChunkCount( &p_sys
->ck_root
, AVIFOURCC_RIFF
);
308 msg_Warn( p_demux
, "multiple riff -> OpenDML ?" );
309 for( i
= 1; i
< i_count
; i
++ )
311 avi_chunk_list_t
*p_sysx
;
313 p_sysx
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, i
);
314 if( p_sysx
->i_type
== AVIFOURCC_AVIX
)
316 msg_Warn( p_demux
, "detected OpenDML file" );
317 p_sys
->b_odml
= true;
323 p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0 );
324 p_hdrl
= AVI_ChunkFind( p_riff
, AVIFOURCC_hdrl
, 0 );
325 p_movi
= AVI_ChunkFind( p_riff
, AVIFOURCC_movi
, 0 );
327 if( !p_hdrl
|| !p_movi
)
329 msg_Err( p_demux
, "avi module discarded (invalid file)" );
333 if( !( p_avih
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_avih
, 0 ) ) )
335 msg_Err( p_demux
, "cannot find avih chunk" );
338 i_track
= AVI_ChunkCount( p_hdrl
, AVIFOURCC_strl
);
339 if( p_avih
->i_streams
!= i_track
)
342 "found %d stream but %d are declared",
343 i_track
, p_avih
->i_streams
);
347 msg_Err( p_demux
, "no stream defined!" );
351 /* print information on streams */
352 msg_Dbg( p_demux
, "AVIH: %d stream, flags %s%s%s%s ",
354 p_avih
->i_flags
&AVIF_HASINDEX
?" HAS_INDEX":"",
355 p_avih
->i_flags
&AVIF_MUSTUSEINDEX
?" MUST_USE_INDEX":"",
356 p_avih
->i_flags
&AVIF_ISINTERLEAVED
?" IS_INTERLEAVED":"",
357 p_avih
->i_flags
&AVIF_TRUSTCKTYPE
?" TRUST_CKTYPE":"" );
359 AVI_MetaLoad( p_demux
, p_riff
, p_avih
);
361 /* now read info on each stream and create ES */
362 for( i
= 0 ; i
< i_track
; i
++ )
364 avi_track_t
*tk
= malloc( sizeof( avi_track_t
) );
368 avi_chunk_list_t
*p_strl
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_strl
, i
);
369 avi_chunk_strh_t
*p_strh
= AVI_ChunkFind( p_strl
, AVIFOURCC_strh
, 0 );
370 avi_chunk_STRING_t
*p_strn
= AVI_ChunkFind( p_strl
, AVIFOURCC_strn
, 0 );
371 avi_chunk_strf_auds_t
*p_auds
= NULL
;
372 avi_chunk_strf_vids_t
*p_vids
= NULL
;
375 memset( tk
, 0, sizeof(*tk
) );
377 tk
->b_activated
= true;
379 p_vids
= (avi_chunk_strf_vids_t
*)AVI_ChunkFind( p_strl
, AVIFOURCC_strf
, 0 );
380 p_auds
= (avi_chunk_strf_auds_t
*)AVI_ChunkFind( p_strl
, AVIFOURCC_strf
, 0 );
382 if( p_strl
== NULL
|| p_strh
== NULL
|| p_auds
== NULL
|| p_vids
== NULL
)
384 msg_Warn( p_demux
, "stream[%d] incomplete", i
);
389 tk
->i_rate
= p_strh
->i_rate
;
390 tk
->i_scale
= p_strh
->i_scale
;
391 tk
->i_samplesize
= p_strh
->i_samplesize
;
392 msg_Dbg( p_demux
, "stream[%d] rate:%d scale:%d samplesize:%d",
393 i
, tk
->i_rate
, tk
->i_scale
, tk
->i_samplesize
);
395 switch( p_strh
->i_type
)
397 case( AVIFOURCC_auds
):
398 tk
->i_cat
= AUDIO_ES
;
399 tk
->i_codec
= AVI_FourccGetCodec( AUDIO_ES
,
400 p_auds
->p_wf
->wFormatTag
);
402 tk
->i_blocksize
= p_auds
->p_wf
->nBlockAlign
;
403 if( tk
->i_blocksize
== 0 )
405 if( p_auds
->p_wf
->wFormatTag
== 1 )
406 tk
->i_blocksize
= p_auds
->p_wf
->nChannels
* (p_auds
->p_wf
->wBitsPerSample
/8);
410 else if( tk
->i_samplesize
!= 0 && tk
->i_samplesize
!= tk
->i_blocksize
)
412 msg_Warn( p_demux
, "track[%d] samplesize=%d and blocksize=%d are not equal."
413 "Using blocksize as a workaround.",
414 i
, tk
->i_samplesize
, tk
->i_blocksize
);
415 tk
->i_samplesize
= tk
->i_blocksize
;
418 if( tk
->i_codec
== VLC_CODEC_VORBIS
)
420 tk
->i_blocksize
= 0; /* fix vorbis VBR decoding */
423 es_format_Init( &fmt
, AUDIO_ES
, tk
->i_codec
);
425 fmt
.audio
.i_channels
= p_auds
->p_wf
->nChannels
;
426 fmt
.audio
.i_rate
= p_auds
->p_wf
->nSamplesPerSec
;
427 fmt
.i_bitrate
= p_auds
->p_wf
->nAvgBytesPerSec
*8;
428 fmt
.audio
.i_blockalign
= p_auds
->p_wf
->nBlockAlign
;
429 fmt
.audio
.i_bitspersample
= p_auds
->p_wf
->wBitsPerSample
;
430 fmt
.b_packetized
= !tk
->i_blocksize
;
433 "stream[%d] audio(0x%x) %d channels %dHz %dbits",
434 i
, p_auds
->p_wf
->wFormatTag
, p_auds
->p_wf
->nChannels
,
435 p_auds
->p_wf
->nSamplesPerSec
,
436 p_auds
->p_wf
->wBitsPerSample
);
438 fmt
.i_extra
= __MIN( p_auds
->p_wf
->cbSize
,
439 p_auds
->i_chunk_size
- sizeof(WAVEFORMATEX
) );
440 fmt
.p_extra
= malloc( fmt
.i_extra
);
441 if( !fmt
.p_extra
) goto error
;
442 memcpy( fmt
.p_extra
, &p_auds
->p_wf
[1], fmt
.i_extra
);
445 case( AVIFOURCC_vids
):
446 tk
->i_cat
= VIDEO_ES
;
447 tk
->i_codec
= AVI_FourccGetCodec( VIDEO_ES
,
448 p_vids
->p_bih
->biCompression
);
449 if( p_vids
->p_bih
->biCompression
== VLC_FOURCC( 'D', 'X', 'S', 'B' ) )
451 msg_Dbg( p_demux
, "stream[%d] subtitles", i
);
452 es_format_Init( &fmt
, SPU_ES
, p_vids
->p_bih
->biCompression
);
455 else if( p_vids
->p_bih
->biCompression
== 0x00 )
457 switch( p_vids
->p_bih
->biBitCount
)
460 tk
->i_codec
= VLC_CODEC_RGB32
;
463 tk
->i_codec
= VLC_CODEC_RGB24
;
465 case 16: /* Yes it is RV15 */
467 tk
->i_codec
= VLC_CODEC_RGB15
;
469 case 9: /* <- TODO check that */
470 tk
->i_codec
= VLC_CODEC_I410
;
472 case 8: /* <- TODO check that */
473 tk
->i_codec
= VLC_CODEC_GREY
;
476 es_format_Init( &fmt
, VIDEO_ES
, tk
->i_codec
);
478 switch( tk
->i_codec
)
480 case VLC_CODEC_RGB24
:
481 case VLC_CODEC_RGB32
:
482 fmt
.video
.i_rmask
= 0x00ff0000;
483 fmt
.video
.i_gmask
= 0x0000ff00;
484 fmt
.video
.i_bmask
= 0x000000ff;
486 case VLC_CODEC_RGB15
:
487 fmt
.video
.i_rmask
= 0x7c00;
488 fmt
.video
.i_gmask
= 0x03e0;
489 fmt
.video
.i_bmask
= 0x001f;
497 es_format_Init( &fmt
, VIDEO_ES
, p_vids
->p_bih
->biCompression
);
498 if( tk
->i_codec
== VLC_CODEC_MP4V
&&
499 !strncasecmp( (char*)&p_strh
->i_handler
, "XVID", 4 ) )
502 fmt
.i_original_fourcc
= VLC_FOURCC( 'X', 'V', 'I', 'D' );
505 tk
->i_samplesize
= 0;
506 fmt
.video
.i_width
= p_vids
->p_bih
->biWidth
;
507 fmt
.video
.i_height
= p_vids
->p_bih
->biHeight
;
508 fmt
.video
.i_bits_per_pixel
= p_vids
->p_bih
->biBitCount
;
509 fmt
.video
.i_frame_rate
= tk
->i_rate
;
510 fmt
.video
.i_frame_rate_base
= tk
->i_scale
;
512 __MIN( p_vids
->p_bih
->biSize
- sizeof( BITMAPINFOHEADER
),
513 p_vids
->i_chunk_size
- sizeof(BITMAPINFOHEADER
) );
514 fmt
.p_extra
= malloc( fmt
.i_extra
);
515 if( !fmt
.p_extra
) goto error
;
516 memcpy( fmt
.p_extra
, &p_vids
->p_bih
[1], fmt
.i_extra
);
518 msg_Dbg( p_demux
, "stream[%d] video(%4.4s) %"PRIu32
"x%"PRIu32
" %dbpp %ffps",
519 i
, (char*)&p_vids
->p_bih
->biCompression
,
520 (uint32_t)p_vids
->p_bih
->biWidth
,
521 (uint32_t)p_vids
->p_bih
->biHeight
,
522 p_vids
->p_bih
->biBitCount
,
523 (float)tk
->i_rate
/(float)tk
->i_scale
);
525 if( p_vids
->p_bih
->biCompression
== 0x00 )
527 /* RGB DIB are coded from bottom to top */
529 (unsigned int)(-(int)p_vids
->p_bih
->biHeight
);
532 /* Extract palette from extradata if bpp <= 8
533 * (assumes that extradata contains only palette but appears
534 * to be true for all palettized codecs we support) */
535 if( fmt
.video
.i_bits_per_pixel
> 0 && fmt
.video
.i_bits_per_pixel
<= 8 )
537 /* The palette is not always included in biSize */
538 fmt
.i_extra
= p_vids
->i_chunk_size
- sizeof(BITMAPINFOHEADER
);
539 if( fmt
.i_extra
> 0 )
541 const uint8_t *p_pal
= fmt
.p_extra
;
543 fmt
.video
.p_palette
= calloc( 1, sizeof(video_palette_t
) );
544 fmt
.video
.p_palette
->i_entries
= __MIN(fmt
.i_extra
/4, 256);
546 for( int i
= 0; i
< fmt
.video
.p_palette
->i_entries
; i
++ )
548 for( int j
= 0; j
< 4; j
++ )
549 fmt
.video
.p_palette
->palette
[i
][j
] = p_pal
[4*i
+j
];
555 case( AVIFOURCC_txts
):
556 msg_Dbg( p_demux
, "stream[%d] subtitle attachment", i
);
557 AVI_ExtractSubtitle( p_demux
, i
, p_strl
, p_strn
);
561 case( AVIFOURCC_iavs
):
562 case( AVIFOURCC_ivas
):
563 p_sys
->b_muxed
= true;
564 msg_Dbg( p_demux
, "stream[%d] iavs with handler %4.4s", i
, (char *)&p_strh
->i_handler
);
565 if( p_strh
->i_handler
== FOURCC_dvsd
||
566 p_strh
->i_handler
== FOURCC_dvhd
||
567 p_strh
->i_handler
== FOURCC_dvsl
||
568 p_strh
->i_handler
== FOURCC_dv25
||
569 p_strh
->i_handler
== FOURCC_dv50
)
571 tk
->p_out_muxed
= stream_DemuxNew( p_demux
, (char *)"rawdv", p_demux
->out
);
572 if( !tk
->p_out_muxed
)
573 msg_Err( p_demux
, "could not load the DV parser" );
579 case( AVIFOURCC_mids
):
580 msg_Dbg( p_demux
, "stream[%d] midi is UNSUPPORTED", i
);
583 msg_Warn( p_demux
, "stream[%d] unknown type %4.4s", i
, (char *)&p_strh
->i_type
);
588 fmt
.psz_description
= FromLatin1( p_strn
->p_str
);
589 if( tk
->p_out_muxed
== NULL
)
590 tk
->p_es
= es_out_Add( p_demux
->out
, &fmt
);
591 TAB_APPEND( p_sys
->i_track
, p_sys
->track
, tk
);
594 es_format_Clean( &fmt
);
598 if( p_sys
->i_track
<= 0 )
600 msg_Err( p_demux
, "no valid track" );
604 i_do_index
= var_InheritInteger( p_demux
, "avi-index" );
605 if( i_do_index
== 1 ) /* Always fix */
608 if( p_sys
->b_seekable
)
610 AVI_IndexCreate( p_demux
);
614 msg_Warn( p_demux
, "cannot create index (unseekable stream)" );
615 AVI_IndexLoad( p_demux
);
620 AVI_IndexLoad( p_demux
);
623 /* *** movie length in sec *** */
624 p_sys
->i_length
= AVI_MovieGetLength( p_demux
);
626 /* Check the index completeness */
627 unsigned int i_idx_totalframes
= 0;
628 for( unsigned int i
= 0; i
< p_sys
->i_track
; i
++ )
630 const avi_track_t
*tk
= p_sys
->track
[i
];
631 if( tk
->i_cat
== VIDEO_ES
&& tk
->idx
.p_entry
)
632 i_idx_totalframes
= __MAX(i_idx_totalframes
, tk
->idx
.i_size
);
635 if( i_idx_totalframes
!= p_avih
->i_totalframes
&&
636 p_sys
->i_length
< (mtime_t
)p_avih
->i_totalframes
*
637 (mtime_t
)p_avih
->i_microsecperframe
/
640 if( !vlc_object_alive( p_demux
) )
643 msg_Warn( p_demux
, "broken or missing index, 'seek' will be "
644 "approximative or will exhibit strange behavior" );
645 if( i_do_index
== 0 && !b_index
)
647 if( !p_sys
->b_seekable
) {
651 switch( dialog_Question( p_demux
, _("AVI Index") ,
652 _( "This AVI file is broken. Seeking will not work correctly.\n"
653 "Do you want to try to fix it?\n\n"
654 "This might take a long time." ),
655 _( "Repair" ), _( "Don't repair" ), _( "Cancel") ) )
659 msg_Dbg( p_demux
, "Fixing AVI index" );
663 vlc_object_kill( p_demux
->p_parent
);
669 /* fix some BeOS MediaKit generated file */
670 for( i
= 0 ; i
< p_sys
->i_track
; i
++ )
672 avi_track_t
*tk
= p_sys
->track
[i
];
673 avi_chunk_list_t
*p_strl
;
674 avi_chunk_strh_t
*p_strh
;
675 avi_chunk_strf_auds_t
*p_auds
;
677 if( tk
->i_cat
!= AUDIO_ES
)
681 if( tk
->idx
.i_size
< 1 ||
683 tk
->i_samplesize
!= 0 )
687 p_strl
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_strl
, i
);
688 p_strh
= AVI_ChunkFind( p_strl
, AVIFOURCC_strh
, 0 );
689 p_auds
= AVI_ChunkFind( p_strl
, AVIFOURCC_strf
, 0 );
691 if( p_auds
->p_wf
->wFormatTag
!= WAVE_FORMAT_PCM
&&
692 (unsigned int)tk
->i_rate
== p_auds
->p_wf
->nSamplesPerSec
)
694 int64_t i_track_length
=
695 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_length
+
696 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_lengthtotal
;
697 mtime_t i_length
= (mtime_t
)p_avih
->i_totalframes
*
698 (mtime_t
)p_avih
->i_microsecperframe
;
702 msg_Warn( p_demux
, "track[%d] cannot be fixed (BeOS MediaKit generated)", i
);
705 tk
->i_samplesize
= 1;
706 tk
->i_rate
= i_track_length
* (int64_t)1000000/ i_length
;
707 msg_Warn( p_demux
, "track[%d] fixed with rate=%d scale=%d (BeOS MediaKit generated)", i
, tk
->i_rate
, tk
->i_scale
);
711 if( p_sys
->b_seekable
)
713 /* we have read all chunk so go back to movi */
714 stream_Seek( p_demux
->s
, p_movi
->i_chunk_pos
);
716 /* Skip movi header */
717 stream_Read( p_demux
->s
, NULL
, 12 );
719 p_sys
->i_movi_begin
= p_movi
->i_chunk_pos
;
723 for( unsigned i
= 0; i
< p_sys
->i_attachment
; i
++)
724 vlc_input_attachment_Delete(p_sys
->attachment
[i
]);
725 free(p_sys
->attachment
);
728 vlc_meta_Delete( p_sys
->meta
);
730 AVI_ChunkFreeRoot( p_demux
->s
, &p_sys
->ck_root
);
732 return vlc_object_alive( p_demux
) ? VLC_EGENERIC
: VLC_ETIMEOUT
;
735 /*****************************************************************************
736 * Close: frees unused data
737 *****************************************************************************/
738 static void Close ( vlc_object_t
* p_this
)
740 demux_t
* p_demux
= (demux_t
*)p_this
;
742 demux_sys_t
*p_sys
= p_demux
->p_sys
;
744 for( i
= 0; i
< p_sys
->i_track
; i
++ )
746 if( p_sys
->track
[i
] )
748 if( p_sys
->track
[i
]->p_out_muxed
)
749 stream_Delete( p_sys
->track
[i
]->p_out_muxed
);
750 avi_index_Clean( &p_sys
->track
[i
]->idx
);
751 free( p_sys
->track
[i
] );
754 free( p_sys
->track
);
755 AVI_ChunkFreeRoot( p_demux
->s
, &p_sys
->ck_root
);
756 vlc_meta_Delete( p_sys
->meta
);
757 for( unsigned i
= 0; i
< p_sys
->i_attachment
; i
++)
758 vlc_input_attachment_Delete(p_sys
->attachment
[i
]);
759 free(p_sys
->attachment
);
764 /*****************************************************************************
765 * Demux_Seekable: reads and demuxes data packets for stream seekable
766 *****************************************************************************
767 * AVIDemux: reads and demuxes data packets
768 *****************************************************************************
769 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
770 *****************************************************************************/
777 off_t i_posf
; /* where we will read :
778 if i_idxposb == 0 : begining of chunk (+8 to acces data)
779 else : point on data directly */
780 } avi_track_toread_t
;
782 static int Demux_Seekable( demux_t
*p_demux
)
784 demux_sys_t
*p_sys
= p_demux
->p_sys
;
786 unsigned int i_track_count
= 0;
787 unsigned int i_track
;
788 /* cannot be more than 100 stream (dcXX or wbXX) */
789 avi_track_toread_t toread
[100];
792 /* detect new selected/unselected streams */
793 for( i_track
= 0; i_track
< p_sys
->i_track
; i_track
++ )
795 avi_track_t
*tk
= p_sys
->track
[i_track
];
798 if( p_sys
->b_muxed
&& tk
->p_out_muxed
)
801 tk
->b_activated
= true;
805 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
, tk
->p_es
, &b
);
806 if( b
&& !tk
->b_activated
)
808 if( p_sys
->b_seekable
)
810 AVI_TrackSeek( p_demux
, i_track
, p_sys
->i_time
);
812 tk
->b_activated
= true;
814 else if( !b
&& tk
->b_activated
)
816 tk
->b_activated
= false;
824 if( i_track_count
<= 0 )
826 int64_t i_length
= p_sys
->i_length
* (mtime_t
)1000000;
828 p_sys
->i_time
+= 25*1000; /* read 25ms */
831 if( p_sys
->i_time
>= i_length
)
835 msg_Warn( p_demux
, "no track selected, exiting..." );
839 /* wait for the good time */
840 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, p_sys
->i_time
+ 1 );
841 p_sys
->i_time
+= 25*1000; /* read 25ms */
844 for( i_track
= 0; i_track
< p_sys
->i_track
; i_track
++ )
846 avi_track_t
*tk
= p_sys
->track
[i_track
];
849 toread
[i_track
].b_ok
= tk
->b_activated
&& !tk
->b_eof
;
850 if( tk
->i_idxposc
< tk
->idx
.i_size
)
852 toread
[i_track
].i_posf
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_pos
;
853 if( tk
->i_idxposb
> 0 )
855 toread
[i_track
].i_posf
+= 8 + tk
->i_idxposb
;
860 toread
[i_track
].i_posf
= -1;
863 i_dpts
= p_sys
->i_time
- AVI_GetPTS( tk
);
865 if( tk
->i_samplesize
)
867 toread
[i_track
].i_toread
= AVI_PTSToByte( tk
, __ABS( i_dpts
) );
871 toread
[i_track
].i_toread
= AVI_PTSToChunk( tk
, __ABS( i_dpts
) );
876 toread
[i_track
].i_toread
*= -1;
889 /* search for first chunk to be read */
890 for( i
= 0, b_done
= true, i_pos
= -1; i
< p_sys
->i_track
; i
++ )
892 if( !toread
[i
].b_ok
||
893 AVI_GetDPTS( p_sys
->track
[i
],
894 toread
[i
].i_toread
) <= -25 * 1000 )
899 if( toread
[i
].i_toread
> 0 )
901 b_done
= false; /* not yet finished */
903 if( toread
[i
].i_posf
> 0 )
905 if( i_pos
== -1 || i_pos
> toread
[i
].i_posf
)
908 i_pos
= toread
[i
].i_posf
;
915 for( i
= 0; i
< p_sys
->i_track
; i
++ )
920 msg_Warn( p_demux
, "all tracks have failed, exiting..." );
926 int i_loop_count
= 0;
928 /* no valid index, we will parse directly the stream
929 * in case we fail we will disable all finished stream */
930 if( p_sys
->i_movi_lastchunk_pos
>= p_sys
->i_movi_begin
+ 12 )
932 stream_Seek( p_demux
->s
, p_sys
->i_movi_lastchunk_pos
);
933 if( AVI_PacketNext( p_demux
) )
935 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
940 stream_Seek( p_demux
->s
, p_sys
->i_movi_begin
+ 12 );
947 if( AVI_PacketGetHeader( p_demux
, &avi_pk
) )
950 "cannot get packet header, track disabled" );
951 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
953 if( avi_pk
.i_stream
>= p_sys
->i_track
||
954 ( avi_pk
.i_cat
!= AUDIO_ES
&& avi_pk
.i_cat
!= VIDEO_ES
) )
956 if( AVI_PacketNext( p_demux
) )
959 "cannot skip packet, track disabled" );
960 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
963 /* Prevents from eating all the CPU with broken files.
964 * This value should be low enough so that it doesn't
965 * affect the reading speed too much. */
966 if( !(++i_loop_count
% 1024) )
968 if( !vlc_object_alive (p_demux
) ) return -1;
971 if( !(i_loop_count
% (1024 * 10)) )
973 "don't seem to find any data..." );
979 i_track
= avi_pk
.i_stream
;
980 tk
= p_sys
->track
[i_track
];
982 /* add this chunk to the index */
984 index
.i_id
= avi_pk
.i_fourcc
;
985 index
.i_flags
= AVI_GetKeyFlag(tk
->i_codec
, avi_pk
.i_peek
);
986 index
.i_pos
= avi_pk
.i_pos
;
987 index
.i_length
= avi_pk
.i_size
;
988 avi_index_Append( &tk
->idx
, &p_sys
->i_movi_lastchunk_pos
, &index
);
990 /* do we will read this data ? */
991 if( AVI_GetDPTS( tk
, toread
[i_track
].i_toread
) > -25*1000 )
997 if( AVI_PacketNext( p_demux
) )
1000 "cannot skip packet, track disabled" );
1001 return( AVI_TrackStopFinishedStreams( p_demux
) ? 0 : 1 );
1010 stream_Seek( p_demux
->s
, i_pos
);
1013 /* Set the track to use */
1014 tk
= p_sys
->track
[i_track
];
1016 /* read thoses data */
1017 if( tk
->i_samplesize
)
1019 unsigned int i_toread
;
1021 if( ( i_toread
= toread
[i_track
].i_toread
) <= 0 )
1023 if( tk
->i_samplesize
> 1 )
1025 i_toread
= tk
->i_samplesize
;
1029 i_toread
= AVI_PTSToByte( tk
, 20 * 1000 );
1030 i_toread
= __MAX( i_toread
, 100 );
1033 i_size
= __MIN( tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
-
1039 i_size
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
;
1042 if( tk
->i_idxposb
== 0 )
1044 i_size
+= 8; /* need to read and skip header */
1047 if( ( p_frame
= stream_Block( p_demux
->s
, __EVEN( i_size
) ) )==NULL
)
1049 msg_Warn( p_demux
, "failed reading data" );
1051 toread
[i_track
].b_ok
= false;
1054 if( i_size
% 2 ) /* read was padded on word boundary */
1056 p_frame
->i_buffer
--;
1059 if( tk
->i_idxposb
== 0 )
1061 p_frame
->p_buffer
+= 8;
1062 p_frame
->i_buffer
-= 8;
1064 p_frame
->i_pts
= AVI_GetPTS( tk
) + 1;
1065 if( tk
->idx
.p_entry
[tk
->i_idxposc
].i_flags
&AVIIF_KEYFRAME
)
1067 p_frame
->i_flags
= BLOCK_FLAG_TYPE_I
;
1071 p_frame
->i_flags
= BLOCK_FLAG_TYPE_PB
;
1075 if( tk
->i_samplesize
)
1077 if( tk
->i_idxposb
== 0 )
1081 toread
[i_track
].i_toread
-= i_size
;
1082 tk
->i_idxposb
+= i_size
;
1083 if( tk
->i_idxposb
>=
1084 tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
)
1092 int i_length
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
;
1095 if( tk
->i_cat
== AUDIO_ES
)
1097 tk
->i_blockno
+= tk
->i_blocksize
> 0 ? ( i_length
+ tk
->i_blocksize
- 1 ) / tk
->i_blocksize
: 1;
1099 toread
[i_track
].i_toread
--;
1102 if( tk
->i_idxposc
< tk
->idx
.i_size
)
1104 toread
[i_track
].i_posf
=
1105 tk
->idx
.p_entry
[tk
->i_idxposc
].i_pos
;
1106 if( tk
->i_idxposb
> 0 )
1108 toread
[i_track
].i_posf
+= 8 + tk
->i_idxposb
;
1114 toread
[i_track
].i_posf
= -1;
1117 if( tk
->i_cat
!= VIDEO_ES
)
1118 p_frame
->i_dts
= p_frame
->i_pts
;
1121 p_frame
->i_dts
= p_frame
->i_pts
;
1122 p_frame
->i_pts
= VLC_TS_INVALID
;
1125 //p_pes->i_rate = p_demux->stream.control.i_rate;
1126 if( tk
->p_out_muxed
)
1127 stream_DemuxSend( tk
->p_out_muxed
, p_frame
);
1129 es_out_Send( p_demux
->out
, tk
->p_es
, p_frame
);
1134 /*****************************************************************************
1135 * Demux_UnSeekable: reads and demuxes data packets for unseekable file
1136 *****************************************************************************
1137 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1138 *****************************************************************************/
1139 static int Demux_UnSeekable( demux_t
*p_demux
)
1141 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1142 avi_track_t
*p_stream_master
= NULL
;
1143 unsigned int i_stream
;
1144 unsigned int i_packet
;
1146 if( p_sys
->b_muxed
)
1148 msg_Err( p_demux
, "Can not yet process muxed avi substreams without seeking" );
1149 return VLC_EGENERIC
;
1152 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, p_sys
->i_time
+ 1 );
1154 /* *** find master stream for data packet skipping algo *** */
1155 /* *** -> first video, if any, or first audio ES *** */
1156 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
1158 avi_track_t
*tk
= p_sys
->track
[i_stream
];
1161 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
, tk
->p_es
, &b
);
1163 if( b
&& tk
->i_cat
== VIDEO_ES
)
1165 p_stream_master
= tk
;
1169 p_stream_master
= tk
;
1173 if( !p_stream_master
)
1175 msg_Warn( p_demux
, "no more stream selected" );
1179 p_sys
->i_time
= AVI_GetPTS( p_stream_master
);
1181 for( i_packet
= 0; i_packet
< 10; i_packet
++)
1183 #define p_stream p_sys->track[avi_pk.i_stream]
1185 avi_packet_t avi_pk
;
1187 if( AVI_PacketGetHeader( p_demux
, &avi_pk
) )
1192 if( avi_pk
.i_stream
>= p_sys
->i_track
||
1193 ( avi_pk
.i_cat
!= AUDIO_ES
&& avi_pk
.i_cat
!= VIDEO_ES
) )
1195 /* we haven't found an audio or video packet:
1196 * - we have seek, found first next packet
1197 * - others packets could be found, skip them
1199 switch( avi_pk
.i_fourcc
)
1201 case AVIFOURCC_JUNK
:
1202 case AVIFOURCC_LIST
:
1203 case AVIFOURCC_RIFF
:
1204 return( !AVI_PacketNext( p_demux
) ? 1 : 0 );
1205 case AVIFOURCC_idx1
:
1208 return( !AVI_PacketNext( p_demux
) ? 1 : 0 );
1210 return( 0 ); /* eof */
1213 "seems to have lost position, resync" );
1214 if( AVI_PacketSearch( p_demux
) )
1216 msg_Err( p_demux
, "resync failed" );
1223 /* check for time */
1224 if( __ABS( AVI_GetPTS( p_stream
) -
1225 AVI_GetPTS( p_stream_master
) )< 600*1000 )
1227 /* load it and send to decoder */
1229 if( AVI_PacketRead( p_demux
, &avi_pk
, &p_frame
) || p_frame
== NULL
)
1233 p_frame
->i_pts
= AVI_GetPTS( p_stream
) + 1;
1235 if( avi_pk
.i_cat
!= VIDEO_ES
)
1236 p_frame
->i_dts
= p_frame
->i_pts
;
1239 p_frame
->i_dts
= p_frame
->i_pts
;
1240 p_frame
->i_pts
= VLC_TS_INVALID
;
1243 //p_pes->i_rate = p_demux->stream.control.i_rate;
1244 es_out_Send( p_demux
->out
, p_stream
->p_es
, p_frame
);
1248 if( AVI_PacketNext( p_demux
) )
1254 /* *** update stream time position *** */
1255 if( p_stream
->i_samplesize
)
1257 p_stream
->i_idxposb
+= avi_pk
.i_size
;
1261 if( p_stream
->i_cat
== AUDIO_ES
)
1263 p_stream
->i_blockno
+= p_stream
->i_blocksize
> 0 ? ( avi_pk
.i_size
+ p_stream
->i_blocksize
- 1 ) / p_stream
->i_blocksize
: 1;
1265 p_stream
->i_idxposc
++;
1275 /*****************************************************************************
1276 * Seek: goto to i_date or i_percent
1277 *****************************************************************************/
1278 static int Seek( demux_t
*p_demux
, mtime_t i_date
, int i_percent
)
1281 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1282 unsigned int i_stream
;
1283 msg_Dbg( p_demux
, "seek requested: %"PRId64
" seconds %d%%",
1284 i_date
/ 1000000, i_percent
);
1286 if( p_sys
->b_seekable
)
1288 if( !p_sys
->i_length
)
1290 avi_track_t
*p_stream
;
1293 /* use i_percent to create a true i_date */
1294 msg_Warn( p_demux
, "seeking without index at %d%%"
1295 " only works for interleaved files", i_percent
);
1296 if( i_percent
>= 100 )
1298 msg_Warn( p_demux
, "cannot seek so far !" );
1299 return VLC_EGENERIC
;
1301 i_percent
= __MAX( i_percent
, 0 );
1303 /* try to find chunk that is at i_percent or the file */
1304 i_pos
= __MAX( i_percent
* stream_Size( p_demux
->s
) / 100,
1305 p_sys
->i_movi_begin
);
1306 /* search first selected stream (and prefer non eof ones) */
1307 for( i_stream
= 0, p_stream
= NULL
;
1308 i_stream
< p_sys
->i_track
; i_stream
++ )
1310 if( !p_stream
|| p_stream
->b_eof
)
1311 p_stream
= p_sys
->track
[i_stream
];
1313 if( p_stream
->b_activated
&& !p_stream
->b_eof
)
1316 if( !p_stream
|| !p_stream
->b_activated
)
1318 msg_Warn( p_demux
, "cannot find any selected stream" );
1319 return VLC_EGENERIC
;
1322 /* be sure that the index exist */
1323 if( AVI_StreamChunkSet( p_demux
, i_stream
, 0 ) )
1325 msg_Warn( p_demux
, "cannot seek" );
1326 return VLC_EGENERIC
;
1329 while( i_pos
>= p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_pos
+
1330 p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_length
+ 8 )
1332 /* search after i_idxposc */
1333 if( AVI_StreamChunkSet( p_demux
,
1334 i_stream
, p_stream
->i_idxposc
+ 1 ) )
1336 msg_Warn( p_demux
, "cannot seek" );
1337 return VLC_EGENERIC
;
1341 i_date
= AVI_GetPTS( p_stream
);
1342 /* TODO better support for i_samplesize != 0 */
1343 msg_Dbg( p_demux
, "estimate date %"PRId64
, i_date
);
1347 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
1349 avi_track_t
*p_stream
= p_sys
->track
[i_stream
];
1351 if( !p_stream
->b_activated
)
1354 p_stream
->b_eof
= AVI_TrackSeek( p_demux
, i_stream
, i_date
) != 0;
1356 es_out_Control( p_demux
->out
, ES_OUT_SET_NEXT_DISPLAY_TIME
, i_date
);
1357 p_sys
->i_time
= i_date
;
1358 msg_Dbg( p_demux
, "seek: %"PRId64
" seconds", p_sys
->i_time
/1000000 );
1363 msg_Err( p_demux
, "shouldn't yet be executed" );
1364 return VLC_EGENERIC
;
1368 /*****************************************************************************
1370 *****************************************************************************/
1371 static double ControlGetPosition( demux_t
*p_demux
)
1373 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1375 if( p_sys
->i_length
> 0 )
1377 return (double)p_sys
->i_time
/ (double)( p_sys
->i_length
* (mtime_t
)1000000 );
1379 else if( stream_Size( p_demux
->s
) > 0 )
1385 /* search the more advanced selected es */
1386 for( i
= 0; i
< p_sys
->i_track
; i
++ )
1388 avi_track_t
*tk
= p_sys
->track
[i
];
1389 if( tk
->b_activated
&& tk
->i_idxposc
< tk
->idx
.i_size
)
1391 i_tmp
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_pos
+
1392 tk
->idx
.p_entry
[tk
->i_idxposc
].i_length
+ 8;
1399 return (double)i64
/ stream_Size( p_demux
->s
);
1404 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
1406 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1414 case DEMUX_GET_POSITION
:
1415 pf
= (double*)va_arg( args
, double * );
1416 *pf
= ControlGetPosition( p_demux
);
1418 case DEMUX_SET_POSITION
:
1419 f
= (double)va_arg( args
, double );
1420 if( p_sys
->b_seekable
)
1422 i64
= (mtime_t
)(1000000.0 * p_sys
->i_length
* f
);
1423 return Seek( p_demux
, i64
, (int)(f
* 100) );
1427 int64_t i_pos
= stream_Size( p_demux
->s
) * f
;
1428 return stream_Seek( p_demux
->s
, i_pos
);
1431 case DEMUX_GET_TIME
:
1432 pi64
= (int64_t*)va_arg( args
, int64_t * );
1433 *pi64
= p_sys
->i_time
;
1436 case DEMUX_SET_TIME
:
1440 i64
= (int64_t)va_arg( args
, int64_t );
1441 if( p_sys
->i_length
> 0 )
1443 i_percent
= 100 * i64
/ (p_sys
->i_length
*1000000);
1445 else if( p_sys
->i_time
> 0 )
1447 i_percent
= (int)( 100.0 * ControlGetPosition( p_demux
) *
1448 (double)i64
/ (double)p_sys
->i_time
);
1450 return Seek( p_demux
, i64
, i_percent
);
1452 case DEMUX_GET_LENGTH
:
1453 pi64
= (int64_t*)va_arg( args
, int64_t * );
1454 *pi64
= p_sys
->i_length
* (mtime_t
)1000000;
1458 pf
= (double*)va_arg( args
, double * );
1460 for( i
= 0; i
< (int)p_sys
->i_track
; i
++ )
1462 avi_track_t
*tk
= p_sys
->track
[i
];
1463 if( tk
->i_cat
== VIDEO_ES
&& tk
->i_scale
> 0)
1465 *pf
= (float)tk
->i_rate
/ (float)tk
->i_scale
;
1471 case DEMUX_GET_META
:
1472 p_meta
= (vlc_meta_t
*)va_arg( args
, vlc_meta_t
* );
1473 vlc_meta_Merge( p_meta
, p_sys
->meta
);
1476 case DEMUX_GET_ATTACHMENTS
:
1478 if( p_sys
->i_attachment
<= 0 )
1479 return VLC_EGENERIC
;
1481 input_attachment_t
***ppp_attach
= va_arg( args
, input_attachment_t
*** );
1482 int *pi_int
= va_arg( args
, int * );
1484 *pi_int
= p_sys
->i_attachment
;
1485 *ppp_attach
= calloc( p_sys
->i_attachment
, sizeof(*ppp_attach
));
1486 for( unsigned i
= 0; i
< p_sys
->i_attachment
&& *ppp_attach
; i
++ )
1487 (*ppp_attach
)[i
] = vlc_input_attachment_Duplicate( p_sys
->attachment
[i
] );
1492 return VLC_EGENERIC
;
1496 /*****************************************************************************
1497 * Function to convert pts to chunk or byte
1498 *****************************************************************************/
1500 static mtime_t
AVI_PTSToChunk( avi_track_t
*tk
, mtime_t i_pts
)
1505 return (mtime_t
)((int64_t)i_pts
*
1506 (int64_t)tk
->i_rate
/
1507 (int64_t)tk
->i_scale
/
1510 static mtime_t
AVI_PTSToByte( avi_track_t
*tk
, mtime_t i_pts
)
1512 if( !tk
->i_scale
|| !tk
->i_samplesize
)
1515 return (mtime_t
)((int64_t)i_pts
*
1516 (int64_t)tk
->i_rate
/
1517 (int64_t)tk
->i_scale
/
1519 (int64_t)tk
->i_samplesize
);
1522 static mtime_t
AVI_GetDPTS( avi_track_t
*tk
, int64_t i_count
)
1529 i_dpts
= (mtime_t
)( (int64_t)1000000 *
1531 (int64_t)tk
->i_scale
/
1532 (int64_t)tk
->i_rate
);
1534 if( tk
->i_samplesize
)
1536 return i_dpts
/ tk
->i_samplesize
;
1541 static mtime_t
AVI_GetPTS( avi_track_t
*tk
)
1543 if( tk
->i_samplesize
)
1545 int64_t i_count
= 0;
1547 /* we need a valid entry we will emulate one */
1548 if( tk
->i_idxposc
== tk
->idx
.i_size
)
1552 /* use the last entry */
1553 i_count
= tk
->idx
.p_entry
[tk
->idx
.i_size
- 1].i_lengthtotal
1554 + tk
->idx
.p_entry
[tk
->idx
.i_size
- 1].i_length
;
1559 i_count
= tk
->idx
.p_entry
[tk
->i_idxposc
].i_lengthtotal
;
1561 return AVI_GetDPTS( tk
, i_count
+ tk
->i_idxposb
);
1565 if( tk
->i_cat
== AUDIO_ES
)
1567 return AVI_GetDPTS( tk
, tk
->i_blockno
);
1571 return AVI_GetDPTS( tk
, tk
->i_idxposc
);
1576 static int AVI_StreamChunkFind( demux_t
*p_demux
, unsigned int i_stream
)
1578 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1579 avi_packet_t avi_pk
;
1580 int i_loop_count
= 0;
1582 /* find first chunk of i_stream that isn't in index */
1584 if( p_sys
->i_movi_lastchunk_pos
>= p_sys
->i_movi_begin
+ 12 )
1586 stream_Seek( p_demux
->s
, p_sys
->i_movi_lastchunk_pos
);
1587 if( AVI_PacketNext( p_demux
) )
1589 return VLC_EGENERIC
;
1594 stream_Seek( p_demux
->s
, p_sys
->i_movi_begin
+ 12 );
1599 if( !vlc_object_alive (p_demux
) ) return VLC_EGENERIC
;
1601 if( AVI_PacketGetHeader( p_demux
, &avi_pk
) )
1603 msg_Warn( p_demux
, "cannot get packet header" );
1604 return VLC_EGENERIC
;
1606 if( avi_pk
.i_stream
>= p_sys
->i_track
||
1607 ( avi_pk
.i_cat
!= AUDIO_ES
&& avi_pk
.i_cat
!= VIDEO_ES
) )
1609 if( AVI_PacketNext( p_demux
) )
1611 return VLC_EGENERIC
;
1614 /* Prevents from eating all the CPU with broken files.
1615 * This value should be low enough so that it doesn't
1616 * affect the reading speed too much. */
1617 if( !(++i_loop_count
% 1024) )
1619 if( !vlc_object_alive (p_demux
) ) return VLC_EGENERIC
;
1622 if( !(i_loop_count
% (1024 * 10)) )
1623 msg_Warn( p_demux
, "don't seem to find any data..." );
1628 avi_track_t
*tk_pk
= p_sys
->track
[avi_pk
.i_stream
];
1630 /* add this chunk to the index */
1632 index
.i_id
= avi_pk
.i_fourcc
;
1633 index
.i_flags
= AVI_GetKeyFlag(tk_pk
->i_codec
, avi_pk
.i_peek
);
1634 index
.i_pos
= avi_pk
.i_pos
;
1635 index
.i_length
= avi_pk
.i_size
;
1636 avi_index_Append( &tk_pk
->idx
, &p_sys
->i_movi_lastchunk_pos
, &index
);
1638 if( avi_pk
.i_stream
== i_stream
)
1643 if( AVI_PacketNext( p_demux
) )
1645 return VLC_EGENERIC
;
1651 /* be sure that i_ck will be a valid index entry */
1652 static int AVI_StreamChunkSet( demux_t
*p_demux
, unsigned int i_stream
,
1655 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1656 avi_track_t
*p_stream
= p_sys
->track
[i_stream
];
1658 p_stream
->i_idxposc
= i_ck
;
1659 p_stream
->i_idxposb
= 0;
1661 if( i_ck
>= p_stream
->idx
.i_size
)
1663 p_stream
->i_idxposc
= p_stream
->idx
.i_size
- 1;
1666 p_stream
->i_idxposc
++;
1667 if( AVI_StreamChunkFind( p_demux
, i_stream
) )
1669 return VLC_EGENERIC
;
1672 } while( p_stream
->i_idxposc
< i_ck
);
1678 /* XXX FIXME up to now, we assume that all chunk are one after one */
1679 static int AVI_StreamBytesSet( demux_t
*p_demux
,
1680 unsigned int i_stream
,
1683 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1684 avi_track_t
*p_stream
= p_sys
->track
[i_stream
];
1686 if( ( p_stream
->idx
.i_size
> 0 )
1687 &&( i_byte
< p_stream
->idx
.p_entry
[p_stream
->idx
.i_size
- 1].i_lengthtotal
+
1688 p_stream
->idx
.p_entry
[p_stream
->idx
.i_size
- 1].i_length
) )
1690 /* index is valid to find the ck */
1691 /* uses dichototmie to be fast enougth */
1692 int i_idxposc
= __MIN( p_stream
->i_idxposc
, p_stream
->idx
.i_size
- 1 );
1693 int i_idxmax
= p_stream
->idx
.i_size
;
1697 if( p_stream
->idx
.p_entry
[i_idxposc
].i_lengthtotal
> i_byte
)
1699 i_idxmax
= i_idxposc
;
1700 i_idxposc
= ( i_idxmin
+ i_idxposc
) / 2 ;
1704 if( p_stream
->idx
.p_entry
[i_idxposc
].i_lengthtotal
+
1705 p_stream
->idx
.p_entry
[i_idxposc
].i_length
<= i_byte
)
1707 i_idxmin
= i_idxposc
;
1708 i_idxposc
= (i_idxmax
+ i_idxposc
) / 2 ;
1712 p_stream
->i_idxposc
= i_idxposc
;
1713 p_stream
->i_idxposb
= i_byte
-
1714 p_stream
->idx
.p_entry
[i_idxposc
].i_lengthtotal
;
1723 p_stream
->i_idxposc
= p_stream
->idx
.i_size
- 1;
1724 p_stream
->i_idxposb
= 0;
1727 p_stream
->i_idxposc
++;
1728 if( AVI_StreamChunkFind( p_demux
, i_stream
) )
1730 return VLC_EGENERIC
;
1733 } while( p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_lengthtotal
+
1734 p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_length
<= i_byte
);
1736 p_stream
->i_idxposb
= i_byte
-
1737 p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_lengthtotal
;
1742 static int AVI_TrackSeek( demux_t
*p_demux
,
1746 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1747 avi_track_t
*tk
= p_sys
->track
[i_stream
];
1749 #define p_stream p_sys->track[i_stream]
1752 i_oldpts
= AVI_GetPTS( p_stream
);
1754 if( !p_stream
->i_samplesize
)
1756 if( AVI_StreamChunkSet( p_demux
,
1758 AVI_PTSToChunk( p_stream
, i_date
) ) )
1760 return VLC_EGENERIC
;
1763 if( p_stream
->i_cat
== AUDIO_ES
)
1767 for( i
= 0; i
< tk
->i_idxposc
; i
++ )
1769 if( tk
->i_blocksize
> 0 )
1771 tk
->i_blockno
+= ( tk
->idx
.p_entry
[i
].i_length
+ tk
->i_blocksize
- 1 ) / tk
->i_blocksize
;
1781 "old:%"PRId64
" %s new %"PRId64
,
1783 i_oldpts
> i_date
? ">" : "<",
1786 if( p_stream
->i_cat
== VIDEO_ES
)
1788 /* search key frame */
1789 //if( i_date < i_oldpts || 1 )
1791 while( p_stream
->i_idxposc
> 0 &&
1792 !( p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_flags
&
1795 if( AVI_StreamChunkSet( p_demux
,
1797 p_stream
->i_idxposc
- 1 ) )
1799 return VLC_EGENERIC
;
1806 while( p_stream
->i_idxposc
< p_stream
->idx
.i_size
&&
1807 !( p_stream
->idx
.p_entry
[p_stream
->i_idxposc
].i_flags
&
1810 if( AVI_StreamChunkSet( p_demux
,
1812 p_stream
->i_idxposc
+ 1 ) )
1814 return VLC_EGENERIC
;
1823 if( AVI_StreamBytesSet( p_demux
,
1825 AVI_PTSToByte( p_stream
, i_date
) ) )
1827 return VLC_EGENERIC
;
1834 /****************************************************************************
1835 * Return true if it's a key frame
1836 ****************************************************************************/
1837 static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc
, uint8_t *p_byte
)
1841 case VLC_CODEC_DIV1
:
1843 * startcode: 0x00000100 32bits
1844 * framenumber ? 5bits
1845 * piture type 0(I),1(P) 2bits
1847 if( GetDWBE( p_byte
) != 0x00000100 )
1849 /* it's not an msmpegv1 stream, strange...*/
1850 return AVIIF_KEYFRAME
;
1852 return p_byte
[4] & 0x06 ? 0 : AVIIF_KEYFRAME
;
1854 case VLC_CODEC_DIV2
:
1855 case VLC_CODEC_DIV3
:
1856 case VLC_CODEC_WMV1
:
1858 * picture type 0(I),1(P) 2bits
1860 return p_byte
[0] & 0xC0 ? 0 : AVIIF_KEYFRAME
;
1861 case VLC_CODEC_MP4V
:
1862 /* we should find first occurrence of 0x000001b6 (32bits)
1863 * startcode: 0x000001b6 32bits
1864 * piture type 0(I),1(P) 2bits
1866 if( GetDWBE( p_byte
) != 0x000001b6 )
1868 /* not true , need to find the first VOP header */
1869 return AVIIF_KEYFRAME
;
1871 return p_byte
[4] & 0xC0 ? 0 : AVIIF_KEYFRAME
;
1874 /* I can't do it, so say yes */
1875 return AVIIF_KEYFRAME
;
1879 vlc_fourcc_t
AVI_FourccGetCodec( unsigned int i_cat
, vlc_fourcc_t i_codec
)
1884 wf_tag_to_fourcc( i_codec
, &i_codec
, NULL
);
1887 return vlc_fourcc_GetCodec( i_cat
, i_codec
);
1889 return VLC_FOURCC( 'u', 'n', 'd', 'f' );
1893 /****************************************************************************
1895 ****************************************************************************/
1896 static void AVI_ParseStreamHeader( vlc_fourcc_t i_id
,
1897 unsigned int *pi_number
, unsigned int *pi_type
)
1899 #define SET_PTR( p, v ) if( p ) *(p) = (v);
1902 c1
= ((uint8_t *)&i_id
)[0];
1903 c2
= ((uint8_t *)&i_id
)[1];
1905 if( c1
< '0' || c1
> '9' || c2
< '0' || c2
> '9' )
1907 SET_PTR( pi_number
, 100 ); /* > max stream number */
1908 SET_PTR( pi_type
, UNKNOWN_ES
);
1912 SET_PTR( pi_number
, (c1
- '0') * 10 + (c2
- '0' ) );
1913 switch( VLC_TWOCC( ((uint8_t *)&i_id
)[2], ((uint8_t *)&i_id
)[3] ) )
1916 SET_PTR( pi_type
, AUDIO_ES
);
1921 SET_PTR( pi_type
, VIDEO_ES
);
1924 SET_PTR( pi_type
, SPU_ES
);
1927 SET_PTR( pi_type
, UNKNOWN_ES
);
1934 /****************************************************************************
1936 ****************************************************************************/
1937 static int AVI_PacketGetHeader( demux_t
*p_demux
, avi_packet_t
*p_pk
)
1939 const uint8_t *p_peek
;
1941 if( stream_Peek( p_demux
->s
, &p_peek
, 16 ) < 16 )
1943 return VLC_EGENERIC
;
1945 p_pk
->i_fourcc
= VLC_FOURCC( p_peek
[0], p_peek
[1], p_peek
[2], p_peek
[3] );
1946 p_pk
->i_size
= GetDWLE( p_peek
+ 4 );
1947 p_pk
->i_pos
= stream_Tell( p_demux
->s
);
1948 if( p_pk
->i_fourcc
== AVIFOURCC_LIST
|| p_pk
->i_fourcc
== AVIFOURCC_RIFF
)
1950 p_pk
->i_type
= VLC_FOURCC( p_peek
[8], p_peek
[9],
1951 p_peek
[10], p_peek
[11] );
1958 memcpy( p_pk
->i_peek
, p_peek
+ 8, 8 );
1960 AVI_ParseStreamHeader( p_pk
->i_fourcc
, &p_pk
->i_stream
, &p_pk
->i_cat
);
1964 static int AVI_PacketNext( demux_t
*p_demux
)
1966 avi_packet_t avi_ck
;
1969 if( AVI_PacketGetHeader( p_demux
, &avi_ck
) )
1971 return VLC_EGENERIC
;
1974 if( avi_ck
.i_fourcc
== AVIFOURCC_LIST
&&
1975 ( avi_ck
.i_type
== AVIFOURCC_rec
|| avi_ck
.i_type
== AVIFOURCC_movi
) )
1979 else if( avi_ck
.i_fourcc
== AVIFOURCC_RIFF
&&
1980 avi_ck
.i_type
== AVIFOURCC_AVIX
)
1986 i_skip
= __EVEN( avi_ck
.i_size
) + 8;
1989 if( stream_Read( p_demux
->s
, NULL
, i_skip
) != i_skip
)
1991 return VLC_EGENERIC
;
1996 static int AVI_PacketRead( demux_t
*p_demux
,
1998 block_t
**pp_frame
)
2002 i_size
= __EVEN( p_pk
->i_size
+ 8 );
2004 if( ( *pp_frame
= stream_Block( p_demux
->s
, i_size
) ) == NULL
)
2006 return VLC_EGENERIC
;
2008 (*pp_frame
)->p_buffer
+= 8;
2009 (*pp_frame
)->i_buffer
-= 8;
2011 if( i_size
!= p_pk
->i_size
+ 8 )
2013 (*pp_frame
)->i_buffer
--;
2019 static int AVI_PacketSearch( demux_t
*p_demux
)
2021 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2022 avi_packet_t avi_pk
;
2027 if( stream_Read( p_demux
->s
, NULL
, 1 ) != 1 )
2029 return VLC_EGENERIC
;
2031 AVI_PacketGetHeader( p_demux
, &avi_pk
);
2032 if( avi_pk
.i_stream
< p_sys
->i_track
&&
2033 ( avi_pk
.i_cat
== AUDIO_ES
|| avi_pk
.i_cat
== VIDEO_ES
) )
2037 switch( avi_pk
.i_fourcc
)
2039 case AVIFOURCC_JUNK
:
2040 case AVIFOURCC_LIST
:
2041 case AVIFOURCC_RIFF
:
2042 case AVIFOURCC_idx1
:
2046 /* Prevents from eating all the CPU with broken files.
2047 * This value should be low enough so that it doesn't affect the
2048 * reading speed too much (not that we care much anyway because
2049 * this code is called only on broken files). */
2050 if( !(++i_count
% 1024) )
2052 if( !vlc_object_alive (p_demux
) ) return VLC_EGENERIC
;
2055 if( !(i_count
% (1024 * 10)) )
2056 msg_Warn( p_demux
, "trying to resync..." );
2061 /****************************************************************************
2063 ****************************************************************************/
2064 static void avi_index_Init( avi_index_t
*p_index
)
2066 p_index
->i_size
= 0;
2068 p_index
->p_entry
= NULL
;
2070 static void avi_index_Clean( avi_index_t
*p_index
)
2072 free( p_index
->p_entry
);
2074 static void avi_index_Append( avi_index_t
*p_index
, off_t
*pi_last_pos
,
2075 avi_entry_t
*p_entry
)
2077 /* Update last chunk position */
2078 if( *pi_last_pos
< p_entry
->i_pos
)
2079 *pi_last_pos
= p_entry
->i_pos
;
2082 if( p_index
->i_size
>= p_index
->i_max
)
2084 p_index
->i_max
+= 16384;
2085 p_index
->p_entry
= realloc_or_free( p_index
->p_entry
,
2086 p_index
->i_max
* sizeof( *p_index
->p_entry
) );
2087 if( !p_index
->p_entry
)
2090 /* calculate cumulate length */
2091 if( p_index
->i_size
> 0 )
2093 p_entry
->i_lengthtotal
=
2094 p_index
->p_entry
[p_index
->i_size
- 1].i_length
+
2095 p_index
->p_entry
[p_index
->i_size
- 1].i_lengthtotal
;
2099 p_entry
->i_lengthtotal
= 0;
2102 p_index
->p_entry
[p_index
->i_size
++] = *p_entry
;
2105 static int AVI_IndexFind_idx1( demux_t
*p_demux
,
2106 avi_chunk_idx1_t
**pp_idx1
,
2107 uint64_t *pi_offset
)
2109 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2111 avi_chunk_list_t
*p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0);
2112 avi_chunk_idx1_t
*p_idx1
= AVI_ChunkFind( p_riff
, AVIFOURCC_idx1
, 0);
2116 msg_Warn( p_demux
, "cannot find idx1 chunk, no index defined" );
2117 return VLC_EGENERIC
;
2121 /* *** calculate offset *** */
2122 /* Well, avi is __SHIT__ so test more than one entry
2123 * (needed for some avi files) */
2124 avi_chunk_list_t
*p_movi
= AVI_ChunkFind( p_riff
, AVIFOURCC_movi
, 0);
2126 for( unsigned i
= 0; i
< __MIN( p_idx1
->i_entry_count
, 10 ); i
++ )
2128 if( p_idx1
->entry
[i
].i_pos
< p_movi
->i_chunk_pos
)
2130 *pi_offset
= p_movi
->i_chunk_pos
+ 8;
2137 static int AVI_IndexLoad_idx1( demux_t
*p_demux
,
2138 avi_index_t p_index
[], off_t
*pi_last_offset
)
2140 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2142 avi_chunk_idx1_t
*p_idx1
;
2144 if( AVI_IndexFind_idx1( p_demux
, &p_idx1
, &i_offset
) )
2145 return VLC_EGENERIC
;
2147 for( unsigned i_index
= 0; i_index
< p_idx1
->i_entry_count
; i_index
++ )
2152 AVI_ParseStreamHeader( p_idx1
->entry
[i_index
].i_fourcc
,
2155 if( i_stream
< p_sys
->i_track
&&
2156 i_cat
== p_sys
->track
[i_stream
]->i_cat
)
2159 index
.i_id
= p_idx1
->entry
[i_index
].i_fourcc
;
2160 index
.i_flags
= p_idx1
->entry
[i_index
].i_flags
&(~AVIIF_FIXKEYFRAME
);
2161 index
.i_pos
= p_idx1
->entry
[i_index
].i_pos
+ i_offset
;
2162 index
.i_length
= p_idx1
->entry
[i_index
].i_length
;
2164 avi_index_Append( &p_index
[i_stream
], pi_last_offset
, &index
);
2170 static void __Parse_indx( demux_t
*p_demux
, avi_index_t
*p_index
, off_t
*pi_max_offset
,
2171 avi_chunk_indx_t
*p_indx
)
2175 msg_Dbg( p_demux
, "loading subindex(0x%x) %d entries", p_indx
->i_indextype
, p_indx
->i_entriesinuse
);
2176 if( p_indx
->i_indexsubtype
== 0 )
2178 for( unsigned i
= 0; i
< p_indx
->i_entriesinuse
; i
++ )
2180 index
.i_id
= p_indx
->i_id
;
2181 index
.i_flags
= p_indx
->idx
.std
[i
].i_size
& 0x80000000 ? 0 : AVIIF_KEYFRAME
;
2182 index
.i_pos
= p_indx
->i_baseoffset
+ p_indx
->idx
.std
[i
].i_offset
- 8;
2183 index
.i_length
= p_indx
->idx
.std
[i
].i_size
&0x7fffffff;
2185 avi_index_Append( p_index
, pi_max_offset
, &index
);
2188 else if( p_indx
->i_indexsubtype
== AVI_INDEX_2FIELD
)
2190 for( unsigned i
= 0; i
< p_indx
->i_entriesinuse
; i
++ )
2192 index
.i_id
= p_indx
->i_id
;
2193 index
.i_flags
= p_indx
->idx
.field
[i
].i_size
& 0x80000000 ? 0 : AVIIF_KEYFRAME
;
2194 index
.i_pos
= p_indx
->i_baseoffset
+ p_indx
->idx
.field
[i
].i_offset
- 8;
2195 index
.i_length
= p_indx
->idx
.field
[i
].i_size
;
2197 avi_index_Append( p_index
, pi_max_offset
, &index
);
2202 msg_Warn( p_demux
, "unknown subtype index(0x%x)", p_indx
->i_indexsubtype
);
2206 static void AVI_IndexLoad_indx( demux_t
*p_demux
,
2207 avi_index_t p_index
[], off_t
*pi_last_offset
)
2209 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2211 avi_chunk_list_t
*p_riff
;
2212 avi_chunk_list_t
*p_hdrl
;
2214 p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0);
2215 p_hdrl
= AVI_ChunkFind( p_riff
, AVIFOURCC_hdrl
, 0 );
2217 for( unsigned i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
2219 avi_chunk_list_t
*p_strl
;
2220 avi_chunk_indx_t
*p_indx
;
2222 #define p_stream p_sys->track[i_stream]
2223 p_strl
= AVI_ChunkFind( p_hdrl
, AVIFOURCC_strl
, i_stream
);
2224 p_indx
= AVI_ChunkFind( p_strl
, AVIFOURCC_indx
, 0 );
2229 msg_Warn( p_demux
, "cannot find indx (misdetect/broken OpenDML "
2234 if( p_indx
->i_indextype
== AVI_INDEX_OF_CHUNKS
)
2236 __Parse_indx( p_demux
, &p_index
[i_stream
], pi_last_offset
, p_indx
);
2238 else if( p_indx
->i_indextype
== AVI_INDEX_OF_INDEXES
)
2241 for( unsigned i
= 0; i
< p_indx
->i_entriesinuse
; i
++ )
2243 if( stream_Seek( p_demux
->s
, p_indx
->idx
.super
[i
].i_offset
)||
2244 AVI_ChunkRead( p_demux
->s
, &ck_sub
, NULL
) )
2248 if( ck_sub
.indx
.i_indextype
== AVI_INDEX_OF_CHUNKS
)
2249 __Parse_indx( p_demux
, &p_index
[i_stream
], pi_last_offset
, &ck_sub
.indx
);
2250 AVI_ChunkFree( p_demux
->s
, &ck_sub
);
2255 msg_Warn( p_demux
, "unknown type index(0x%x)", p_indx
->i_indextype
);
2261 static void AVI_IndexLoad( demux_t
*p_demux
)
2263 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2266 assert( p_sys
->i_track
<= 100 );
2267 avi_index_t p_idx_indx
[p_sys
->i_track
];
2268 avi_index_t p_idx_idx1
[p_sys
->i_track
];
2269 for( unsigned i
= 0; i
< p_sys
->i_track
; i
++ )
2271 avi_index_Init( &p_idx_indx
[i
] );
2272 avi_index_Init( &p_idx_idx1
[i
] );
2274 off_t i_indx_last_pos
= p_sys
->i_movi_lastchunk_pos
;
2275 off_t i_idx1_last_pos
= p_sys
->i_movi_lastchunk_pos
;
2277 AVI_IndexLoad_indx( p_demux
, p_idx_indx
, &i_indx_last_pos
);
2278 if( !p_sys
->b_odml
)
2279 AVI_IndexLoad_idx1( p_demux
, p_idx_idx1
, &i_idx1_last_pos
);
2281 /* Select the longest index */
2282 for( unsigned i
= 0; i
< p_sys
->i_track
; i
++ )
2284 if( p_idx_indx
[i
].i_size
> p_idx_idx1
[i
].i_size
)
2286 msg_Dbg( p_demux
, "selected ODML index for stream[%u]", i
);
2287 p_sys
->track
[i
]->idx
= p_idx_indx
[i
];
2288 avi_index_Clean( &p_idx_idx1
[i
] );
2292 msg_Dbg( p_demux
, "selected standard index for stream[%u]", i
);
2293 p_sys
->track
[i
]->idx
= p_idx_idx1
[i
];
2294 avi_index_Clean( &p_idx_indx
[i
] );
2297 p_sys
->i_movi_lastchunk_pos
= __MAX( i_indx_last_pos
, i_idx1_last_pos
);
2299 for( unsigned i
= 0; i
< p_sys
->i_track
; i
++ )
2301 avi_index_t
*p_index
= &p_sys
->track
[i
]->idx
;
2305 for( unsigned j
= 0; !b_key
&& j
< p_index
->i_size
; j
++ )
2306 b_key
= p_index
->p_entry
[j
].i_flags
& AVIIF_KEYFRAME
;
2309 msg_Err( p_demux
, "no key frame set for track %u", i
);
2310 for( unsigned j
= 0; j
< p_index
->i_size
; j
++ )
2311 p_index
->p_entry
[j
].i_flags
|= AVIIF_KEYFRAME
;
2315 msg_Dbg( p_demux
, "stream[%d] created %d index entries",
2316 i
, p_index
->i_size
);
2320 static void AVI_IndexCreate( demux_t
*p_demux
)
2322 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2324 avi_chunk_list_t
*p_riff
;
2325 avi_chunk_list_t
*p_movi
;
2327 unsigned int i_stream
;
2330 mtime_t i_dialog_update
;
2331 dialog_progress_bar_t
*p_dialog
= NULL
;
2333 p_riff
= AVI_ChunkFind( &p_sys
->ck_root
, AVIFOURCC_RIFF
, 0);
2334 p_movi
= AVI_ChunkFind( p_riff
, AVIFOURCC_movi
, 0);
2338 msg_Err( p_demux
, "cannot find p_movi" );
2342 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
2343 avi_index_Init( &p_sys
->track
[i_stream
]->idx
);
2345 i_movi_end
= __MIN( (off_t
)(p_movi
->i_chunk_pos
+ p_movi
->i_chunk_size
),
2346 stream_Size( p_demux
->s
) );
2348 stream_Seek( p_demux
->s
, p_movi
->i_chunk_pos
+ 12 );
2349 msg_Warn( p_demux
, "creating index from LIST-movi, will take time !" );
2352 /* Only show dialog if AVI is > 10MB */
2353 i_dialog_update
= mdate();
2354 if( stream_Size( p_demux
->s
) > 10000000 )
2355 p_dialog
= dialog_ProgressCreate( p_demux
, _("Fixing AVI Index..."),
2356 NULL
, _("Cancel") );
2362 if( !vlc_object_alive (p_demux
) )
2365 /* Don't update/check dialog too often */
2366 if( p_dialog
&& mdate() - i_dialog_update
> 100000 )
2368 if( dialog_ProgressCancelled( p_dialog
) )
2371 double f_current
= stream_Tell( p_demux
->s
);
2372 double f_size
= stream_Size( p_demux
->s
);
2373 double f_pos
= f_current
/ f_size
;
2374 dialog_ProgressSet( p_dialog
, NULL
, f_pos
);
2376 i_dialog_update
= mdate();
2379 if( AVI_PacketGetHeader( p_demux
, &pk
) )
2382 if( pk
.i_stream
< p_sys
->i_track
&&
2383 pk
.i_cat
== p_sys
->track
[pk
.i_stream
]->i_cat
)
2385 avi_track_t
*tk
= p_sys
->track
[pk
.i_stream
];
2388 index
.i_id
= pk
.i_fourcc
;
2389 index
.i_flags
= AVI_GetKeyFlag(tk
->i_codec
, pk
.i_peek
);
2390 index
.i_pos
= pk
.i_pos
;
2391 index
.i_length
= pk
.i_size
;
2392 avi_index_Append( &tk
->idx
, &p_sys
->i_movi_lastchunk_pos
, &index
);
2396 switch( pk
.i_fourcc
)
2398 case AVIFOURCC_idx1
:
2401 avi_chunk_list_t
*p_sysx
;
2402 p_sysx
= AVI_ChunkFind( &p_sys
->ck_root
,
2403 AVIFOURCC_RIFF
, 1 );
2405 msg_Dbg( p_demux
, "looking for new RIFF chunk" );
2406 if( stream_Seek( p_demux
->s
, p_sysx
->i_chunk_pos
+ 24 ) )
2412 case AVIFOURCC_RIFF
:
2413 msg_Dbg( p_demux
, "new RIFF chunk found" );
2417 case AVIFOURCC_JUNK
:
2421 msg_Warn( p_demux
, "need resync, probably broken avi" );
2422 if( AVI_PacketSearch( p_demux
) )
2424 msg_Warn( p_demux
, "lost sync, abord index creation" );
2430 if( ( !p_sys
->b_odml
&& pk
.i_pos
+ pk
.i_size
>= i_movi_end
) ||
2431 AVI_PacketNext( p_demux
) )
2438 if( p_dialog
!= NULL
)
2439 dialog_ProgressDestroy( p_dialog
);
2441 for( i_stream
= 0; i_stream
< p_sys
->i_track
; i_stream
++ )
2443 msg_Dbg( p_demux
, "stream[%d] creating %d index entries",
2444 i_stream
, p_sys
->track
[i_stream
]->idx
.i_size
);
2449 static void AVI_MetaLoad( demux_t
*p_demux
,
2450 avi_chunk_list_t
*p_riff
, avi_chunk_avih_t
*p_avih
)
2452 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2454 vlc_meta_t
*p_meta
= p_sys
->meta
= vlc_meta_New();
2459 snprintf( buffer
, sizeof(buffer
), "%s%s%s%s",
2460 p_avih
->i_flags
&AVIF_HASINDEX
? " HAS_INDEX" : "",
2461 p_avih
->i_flags
&AVIF_MUSTUSEINDEX
? " MUST_USE_INDEX" : "",
2462 p_avih
->i_flags
&AVIF_ISINTERLEAVED
? " IS_INTERLEAVED" : "",
2463 p_avih
->i_flags
&AVIF_TRUSTCKTYPE
? " TRUST_CKTYPE" : "" );
2464 vlc_meta_SetSetting( p_meta
, buffer
);
2466 avi_chunk_list_t
*p_info
= AVI_ChunkFind( p_riff
, AVIFOURCC_INFO
, 0 );
2470 static const struct {
2474 { AVIFOURCC_IART
, vlc_meta_Artist
},
2475 { AVIFOURCC_ICMT
, vlc_meta_Description
},
2476 { AVIFOURCC_ICOP
, vlc_meta_Copyright
},
2477 { AVIFOURCC_IGNR
, vlc_meta_Genre
},
2478 { AVIFOURCC_INAM
, vlc_meta_Title
},
2481 for( int i
= 0; p_dsc
[i
].i_id
!= 0; i
++ )
2483 avi_chunk_STRING_t
*p_strz
= AVI_ChunkFind( p_info
, p_dsc
[i
].i_id
, 0 );
2486 char *psz_value
= FromLatin1( p_strz
->p_str
);
2491 vlc_meta_Set( p_meta
, p_dsc
[i
].i_type
, psz_value
);
2496 /*****************************************************************************
2498 *****************************************************************************/
2499 static void AVI_ExtractSubtitle( demux_t
*p_demux
,
2501 avi_chunk_list_t
*p_strl
,
2502 avi_chunk_STRING_t
*p_strn
)
2504 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2505 block_t
*p_block
= NULL
;
2506 input_attachment_t
*p_attachment
= NULL
;
2507 char *psz_description
= NULL
;
2508 avi_chunk_indx_t
*p_indx
= NULL
;
2510 if( !p_sys
->b_seekable
)
2513 p_indx
= AVI_ChunkFind( p_strl
, AVIFOURCC_indx
, 0 );
2519 if( p_indx
->i_indextype
== AVI_INDEX_OF_INDEXES
&&
2520 p_indx
->i_entriesinuse
> 0 )
2522 if( stream_Seek( p_demux
->s
, p_indx
->idx
.super
[0].i_offset
)||
2523 AVI_ChunkRead( p_demux
->s
, &ck
, NULL
) )
2528 if( p_indx
->i_indextype
!= AVI_INDEX_OF_CHUNKS
||
2529 p_indx
->i_entriesinuse
!= 1 ||
2530 p_indx
->i_indexsubtype
!= 0 )
2533 i_position
= p_indx
->i_baseoffset
+
2534 p_indx
->idx
.std
[0].i_offset
- 8;
2535 i_size
= (p_indx
->idx
.std
[0].i_size
& 0x7fffffff) + 8;
2539 avi_chunk_idx1_t
*p_idx1
;
2542 if( AVI_IndexFind_idx1( p_demux
, &p_idx1
, &i_offset
) )
2546 for( unsigned i
= 0; i
< p_idx1
->i_entry_count
; i
++ )
2548 const idx1_entry_t
*e
= &p_idx1
->entry
[i
];
2550 unsigned i_stream_idx
;
2552 AVI_ParseStreamHeader( e
->i_fourcc
, &i_stream_idx
, &i_cat
);
2553 if( i_cat
== SPU_ES
&& i_stream_idx
== i_stream
)
2555 i_position
= e
->i_pos
+ i_offset
;
2556 i_size
= e
->i_length
+ 8;
2565 if( i_size
> 1000000 )
2568 if( stream_Seek( p_demux
->s
, i_position
) )
2570 p_block
= stream_Block( p_demux
->s
, i_size
);
2574 /* Parse packet header */
2575 const uint8_t *p
= p_block
->p_buffer
;
2576 if( i_size
< 8 || p
[2] != 't' || p
[3] != 'x' )
2581 /* Parse subtitle chunk header */
2582 if( i_size
< 11 || memcmp( p
, "GAB2", 4 ) ||
2583 p
[4] != 0x00 || GetWLE( &p
[5] ) != 0x2 )
2585 const unsigned i_name
= GetDWLE( &p
[7] );
2586 if( 11 + i_size
<= i_name
)
2589 psz_description
= FromCharset( "UTF-16LE", &p
[11], i_name
);
2591 i_size
-= 11 + i_name
;
2592 if( i_size
< 6 || GetWLE( &p
[0] ) != 0x04 )
2594 const unsigned i_payload
= GetDWLE( &p
[2] );
2595 if( i_size
< 6 + i_payload
|| i_payload
<= 0 )
2600 if( !psz_description
)
2601 psz_description
= p_strn
? FromLatin1( p_strn
->p_str
) : NULL
;
2603 if( asprintf( &psz_name
, "subtitle%d.srt", p_sys
->i_attachment
) <= 0 )
2605 p_attachment
= vlc_input_attachment_New( psz_name
,
2606 "application/x-srt",
2610 TAB_APPEND( p_sys
->i_attachment
, p_sys
->attachment
, p_attachment
);
2614 free( psz_description
);
2617 block_Release( p_block
);
2620 msg_Dbg( p_demux
, "Loaded an embed subtitle" );
2622 msg_Warn( p_demux
, "Failed to load an embed subtitle" );
2624 if( p_indx
== &ck
.indx
)
2625 AVI_ChunkFree( p_demux
->s
, &ck
);
2627 /*****************************************************************************
2629 *****************************************************************************/
2630 static int AVI_TrackStopFinishedStreams( demux_t
*p_demux
)
2632 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2636 for( i
= 0; i
< p_sys
->i_track
; i
++ )
2638 avi_track_t
*tk
= p_sys
->track
[i
];
2639 if( tk
->i_idxposc
>= tk
->idx
.i_size
)
2651 /****************************************************************************
2652 * AVI_MovieGetLength give max streams length in second
2653 ****************************************************************************/
2654 static mtime_t
AVI_MovieGetLength( demux_t
*p_demux
)
2656 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2657 mtime_t i_maxlength
= 0;
2660 for( i
= 0; i
< p_sys
->i_track
; i
++ )
2662 avi_track_t
*tk
= p_sys
->track
[i
];
2665 /* fix length for each stream */
2666 if( tk
->idx
.i_size
< 1 || !tk
->idx
.p_entry
)
2671 if( tk
->i_samplesize
)
2673 i_length
= AVI_GetDPTS( tk
,
2674 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_lengthtotal
+
2675 tk
->idx
.p_entry
[tk
->idx
.i_size
-1].i_length
);
2679 i_length
= AVI_GetDPTS( tk
, tk
->idx
.i_size
);
2681 i_length
/= (mtime_t
)1000000; /* in seconds */
2684 "stream[%d] length:%"PRId64
" (based on index)",
2687 i_maxlength
= __MAX( i_maxlength
, i_length
);