X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Favi%2Favi.c;h=34a33621814b7c32b7006873d9488ca31b7ec827;hb=039c69d648bd9bb481fbd29868b8565952098d70;hp=62afc67c08ef0cf07e390ca40ce7f6ed6cc1e169;hpb=94568687c4ee70c12b0a5f523a7ba040ea03a018;p=vlc diff --git a/modules/demux/avi/avi.c b/modules/demux/avi/avi.c index 62afc67c08..34a3362181 100644 --- a/modules/demux/avi/avi.c +++ b/modules/demux/avi/avi.c @@ -100,6 +100,7 @@ static char *FromACP( const char *str ) } #define IGNORE_ES NAV_ES +#define READ_LENGTH (25 * 1000) // 25ms typedef struct { @@ -297,7 +298,7 @@ static int Open( vlc_object_t * p_this ) stream_Control( p_demux->s, STREAM_CAN_SEEK, &p_sys->b_seekable ); p_demux->pf_control = Control; - p_demux->pf_demux = Demux_Seekable; + p_demux->pf_demux = (p_sys->b_seekable) ? Demux_Seekable : Demux_UnSeekable; p_sys->b_interleaved = var_InheritBool( p_demux, "avi-interleaved" ); @@ -394,9 +395,9 @@ static int Open( vlc_object_t * p_this ) tk->b_activated = true; p_vids = (avi_chunk_strf_vids_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 ); - p_auds = (avi_chunk_strf_auds_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 ); + p_auds = (avi_chunk_strf_auds_t*)p_vids; - if( p_strl == NULL || p_strh == NULL || p_auds == NULL || p_vids == NULL ) + if( p_strl == NULL || p_strh == NULL || p_vids == NULL ) { msg_Warn( p_demux, "stream[%d] incomplete", i ); free( tk ); @@ -407,7 +408,7 @@ static int Open( vlc_object_t * p_this ) tk->i_scale = p_strh->i_scale; tk->i_samplesize = p_strh->i_samplesize; msg_Dbg( p_demux, "stream[%d] rate:%d scale:%d samplesize:%d", - i, tk->i_rate, tk->i_scale, tk->i_samplesize ); + i, tk->i_rate, tk->i_scale, tk->i_samplesize ); switch( p_strh->i_type ) { @@ -445,6 +446,11 @@ static int Open( vlc_object_t * p_this ) tk->i_blocksize = 0; /* fix vorbis VBR decoding */ } + if ( tk->i_codec == VLC_CODEC_MP4A ) + { + tk->i_samplesize = 0; /* ADTS/AAC VBR */ + } + es_format_Init( &fmt, AUDIO_ES, tk->i_codec ); fmt.audio.i_channels = p_auds->p_wf->nChannels; @@ -454,6 +460,15 @@ static int Open( vlc_object_t * p_this ) fmt.audio.i_bitspersample = p_auds->p_wf->wBitsPerSample; fmt.b_packetized = !tk->i_blocksize; + avi_chunk_list_t *p_info = AVI_ChunkFind( p_riff, AVIFOURCC_INFO, 0 ); + if( p_info ) + { + int i_chunk = AVIFOURCC_IAS1 + ((i - 1) << 24); + avi_chunk_STRING_t *p_lang = AVI_ChunkFind( p_info, i_chunk, 0 ); + if( p_lang != NULL ) + fmt.psz_language = FromACP( p_lang->p_str ); + } + msg_Dbg( p_demux, "stream[%d] audio(0x%x - %s) %d channels %dHz %dbits", i, p_auds->p_wf->wFormatTag,vlc_fourcc_GetDescription(AUDIO_ES,tk->i_codec), @@ -701,11 +716,8 @@ aviindex: if( i_idx_totalframes != p_avih->i_totalframes && p_sys->i_length < (mtime_t)p_avih->i_totalframes * (mtime_t)p_avih->i_microsecperframe / - (mtime_t)1000000 ) + CLOCK_FREQ ) { - if( !vlc_object_alive( p_demux) ) - goto error; - msg_Warn( p_demux, "broken or missing index, 'seek' will be " "approximative or will exhibit strange behavior" ); if( (i_do_index == 0 || i_do_index == 3) && !b_index ) @@ -778,7 +790,7 @@ aviindex: continue; } tk->i_samplesize = 1; - tk->i_rate = i_track_length * (int64_t)1000000/ i_length; + tk->i_rate = i_track_length * CLOCK_FREQ / i_length; msg_Warn( p_demux, "track[%d] fixed with rate=%d scale=%d (BeOS MediaKit generated)", i, tk->i_rate, tk->i_scale ); } } @@ -975,9 +987,9 @@ static int Demux_Seekable( demux_t *p_demux ) if( i_track_count <= 0 ) { - int64_t i_length = p_sys->i_length * (mtime_t)1000000; + int64_t i_length = p_sys->i_length * CLOCK_FREQ; - p_sys->i_time += 25*1000; /* read 25ms */ + p_sys->i_time += READ_LENGTH; if( i_length > 0 ) { if( p_sys->i_time >= i_length ) @@ -990,13 +1002,12 @@ static int Demux_Seekable( demux_t *p_demux ) /* wait for the good time */ es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + p_sys->i_time ); - p_sys->i_time += 25*1000; /* read 25ms */ + p_sys->i_time += READ_LENGTH; /* init toread */ for( i_track = 0; i_track < p_sys->i_track; i_track++ ) { avi_track_t *tk = p_sys->track[i_track]; - mtime_t i_dpts; toread[i_track].b_ok = tk->b_activated && !tk->b_eof; if( tk->i_idxposc < tk->idx.i_size ) @@ -1012,21 +1023,18 @@ static int Demux_Seekable( demux_t *p_demux ) toread[i_track].i_posf = -1; } - i_dpts = p_sys->i_time - AVI_GetPTS( tk ); + mtime_t i_dpts = p_sys->i_time - AVI_GetPTS( tk ); if( tk->i_samplesize ) { - toread[i_track].i_toread = AVI_PTSToByte( tk, llabs( i_dpts ) ); + toread[i_track].i_toread = AVI_PTSToByte( tk, i_dpts ); } - else + else if ( i_dpts > -2 * CLOCK_FREQ ) /* don't send a too early dts (low fps video) */ { - toread[i_track].i_toread = AVI_PTSToChunk( tk, llabs( i_dpts ) ); - } - - if( i_dpts < 0 ) - { - toread[i_track].i_toread *= -1; + toread[i_track].i_toread = AVI_PTSToChunk( tk, i_dpts ); } + else + toread[i_track].i_toread = -1; } for( ;; ) @@ -1043,12 +1051,12 @@ static int Demux_Seekable( demux_t *p_demux ) { if( !toread[i].b_ok || AVI_GetDPTS( p_sys->track[i], - toread[i].i_toread ) <= -25 * 1000 ) + toread[i].i_toread ) <= -READ_LENGTH ) { continue; } - if( toread[i].i_toread > 0 ) + if( toread[i].i_toread >= 0 ) { b_done = false; /* not yet finished */ } @@ -1117,7 +1125,6 @@ static int Demux_Seekable( demux_t *p_demux ) * affect the reading speed too much. */ if( !(++i_loop_count % 1024) ) { - if( !vlc_object_alive (p_demux) ) return -1; msleep( 10000 ); if( !(i_loop_count % (1024 * 10)) ) @@ -1141,7 +1148,7 @@ static int Demux_Seekable( demux_t *p_demux ) avi_index_Append( &tk->idx, &p_sys->i_movi_lastchunk_pos, &index ); /* do we will read this data ? */ - if( AVI_GetDPTS( tk, toread[i_track].i_toread ) > -25*1000 ) + if( AVI_GetDPTS( tk, toread[i_track].i_toread ) > -READ_LENGTH ) { break; } @@ -1206,7 +1213,7 @@ static int Demux_Seekable( demux_t *p_demux ) continue; } - p_frame->i_pts = AVI_GetPTS( tk ) + 1; + p_frame->i_pts = VLC_TS_0 + AVI_GetPTS( tk ); if( tk->idx.p_entry[tk->i_idxposc].i_flags&AVIIF_KEYFRAME ) { p_frame->i_flags = BLOCK_FLAG_TYPE_I; @@ -1373,7 +1380,7 @@ static int Demux_UnSeekable( demux_t *p_demux ) { return( -1 ); } - p_frame->i_pts = AVI_GetPTS( p_stream ) + 1; + p_frame->i_pts = VLC_TS_0 + AVI_GetPTS( p_stream ); if( avi_pk.i_cat != VIDEO_ES ) p_frame->i_dts = p_frame->i_pts; @@ -1527,8 +1534,9 @@ static int Seek( demux_t *p_demux, mtime_t i_date, int i_percent ) p_stream->b_eof = AVI_TrackSeek( p_demux, i_stream, i_date ) != 0; } - es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date ); p_sys->i_time = i_date; + es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + p_sys->i_time ); + es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, VLC_TS_0 + p_sys->i_time ); msg_Dbg( p_demux, "seek: %"PRId64" seconds", p_sys->i_time /CLOCK_FREQ ); return VLC_SUCCESS; @@ -1763,8 +1771,6 @@ static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream ) for( ;; ) { - if( !vlc_object_alive (p_demux) ) return VLC_EGENERIC; - if( AVI_PacketGetHeader( p_demux, &avi_pk ) ) { msg_Warn( p_demux, "cannot get packet header" ); @@ -1783,7 +1789,6 @@ static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream ) * affect the reading speed too much. */ if( !(++i_loop_count % 1024) ) { - if( !vlc_object_alive (p_demux) ) return VLC_EGENERIC; msleep( 10000 ); if( !(i_loop_count % (1024 * 10)) ) @@ -2221,8 +2226,6 @@ static int AVI_PacketSearch( demux_t *p_demux ) * this code is called only on broken files). */ if( !(++i_count % 1024) ) { - if( !vlc_object_alive (p_demux) ) return VLC_EGENERIC; - msleep( 10000 ); if( !(i_count % (1024 * 10)) ) msg_Warn( p_demux, "trying to resync..." ); @@ -2318,11 +2321,22 @@ static int AVI_IndexFind_idx1( demux_t *p_demux, *pi_offset = 0; else *pi_offset = i_movi_content; + + if( p_idx1->i_entry_count ) + { + /* Invalidate offset if index refers past the data section to avoid false + positives when the offset equals sample size */ + size_t i_dataend = *pi_offset + p_idx1->entry[p_idx1->i_entry_count - 1].i_pos + + p_idx1->entry[p_idx1->i_entry_count - 1].i_length; + if( i_dataend > p_movi->i_chunk_pos + p_movi->i_chunk_size ) + *pi_offset = 0; + } } else { *pi_offset = 0; } + return VLC_SUCCESS; } @@ -2560,9 +2574,6 @@ static void AVI_IndexCreate( demux_t *p_demux ) { avi_packet_t pk; - if( !vlc_object_alive (p_demux) ) - break; - /* Don't update/check dialog too often */ if( p_dialog && mdate() - i_dialog_update > 100000 ) { @@ -2941,7 +2952,7 @@ static mtime_t AVI_MovieGetLength( demux_t *p_demux ) { i_length = AVI_GetDPTS( tk, tk->idx.i_size ); } - i_length /= (mtime_t)1000000; /* in seconds */ + i_length /= CLOCK_FREQ; /* in seconds */ msg_Dbg( p_demux, "stream[%d] length:%"PRId64" (based on index)",