From f6cc8a39507a630bb20c865b81039eafa72834b6 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Sat, 27 Sep 2008 23:59:11 +0200 Subject: [PATCH] Convert stream to system timestamp after the decoder. - This is needed for proper seek/pause/fast forward/... - The decoder/packetizer do not need to scale packet length anymore as the decoder thread do it. --- include/vlc_codec.h | 23 +++++ include/vlc_codec_synchro.h | 2 +- modules/codec/a52.c | 14 +-- modules/codec/avcodec/audio.c | 10 +-- modules/codec/avcodec/video.c | 15 ++-- modules/codec/csri.c | 13 +-- modules/codec/faad.c | 12 +-- modules/codec/libass.c | 25 ++---- modules/codec/libmpeg2.c | 12 +-- modules/codec/mpeg_audio.c | 14 +-- modules/codec/spudec/parse.c | 2 - modules/codec/spudec/spudec.c | 1 - modules/codec/spudec/spudec.h | 1 - modules/codec/subtitles/subsdec.c | 2 - modules/codec/subtitles/subsusf.c | 2 - modules/codec/telx.c | 3 - modules/codec/vorbis.c | 13 +-- modules/packetizer/mpeg4audio.c | 14 +-- modules/packetizer/mpeg4video.c | 8 +- modules/packetizer/vc1.c | 1 - src/input/clock.c | 13 +++ src/input/decoder.c | 112 +++++++++++++++++++++--- src/input/decoder_synchro.c | 31 ++++--- src/input/es_out.c | 139 +++++++++++------------------- src/input/input_clock.h | 9 +- src/libvlccore.sym | 1 + 26 files changed, 252 insertions(+), 240 deletions(-) diff --git a/include/vlc_codec.h b/include/vlc_codec.h index 0e6640fccb..d4165a7597 100644 --- a/include/vlc_codec.h +++ b/include/vlc_codec.h @@ -147,8 +147,31 @@ struct encoder_t * @} */ +/** + * This function returns a specific input attachment (using its name). + * + * You MUST release the returned value. + */ VLC_EXPORT( input_attachment_t *, decoder_GetInputAttachment, ( decoder_t *, const char *psz_name ) LIBVLC_USED ); + +/** + * This function gives all input attachments at once. + * + * You MUST release the returned values + */ VLC_EXPORT( int, decoder_GetInputAttachments, ( decoder_t *p_dec, input_attachment_t ***ppp_attachment, int *pi_attachment ) ); + +/** + * This function converts a decoder timestamp into a display date comparable + * to mdate(). + * You MUST use it *only* for gathering statistics about speed. + */ VLC_EXPORT( mtime_t, decoder_GetDisplayDate, ( decoder_t *, mtime_t ) LIBVLC_USED ); +/** + * This function returns the current input rate. + * You MUST use it *only* for gathering statistics about speed. + */ +VLC_EXPORT( int, decoder_GetDisplayRate, ( decoder_t * ) ); + #endif /* _VLC_CODEC_H */ diff --git a/include/vlc_codec_synchro.h b/include/vlc_codec_synchro.h index 3fd26712ae..fefab4e173 100644 --- a/include/vlc_codec_synchro.h +++ b/include/vlc_codec_synchro.h @@ -45,5 +45,5 @@ VLC_EXPORT( void, decoder_SynchroTrash, ( decoder_synchro_t * ) ); VLC_EXPORT( void, decoder_SynchroDecode, ( decoder_synchro_t * ) ); VLC_EXPORT( void, decoder_SynchroEnd, ( decoder_synchro_t *, int, bool ) ); VLC_EXPORT( mtime_t, decoder_SynchroDate, ( decoder_synchro_t * ) LIBVLC_USED ); -VLC_EXPORT( void, decoder_SynchroNewPicture, ( decoder_synchro_t *, int, int, mtime_t, mtime_t, int, bool ) ); +VLC_EXPORT( void, decoder_SynchroNewPicture, ( decoder_synchro_t *, int, int, mtime_t, mtime_t, bool ) ); diff --git a/modules/codec/a52.c b/modules/codec/a52.c index 8684049bd3..f6521d558d 100644 --- a/modules/codec/a52.c +++ b/modules/codec/a52.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -84,8 +83,6 @@ struct decoder_sys_t mtime_t i_pts; int i_frame_size, i_bit_rate; unsigned int i_rate, i_channels, i_channels_conf; - - int i_input_rate; }; enum { @@ -147,7 +144,6 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer ) aout_DateSet( &p_sys->end_date, 0 ); p_sys->bytestream = block_BytestreamInit(); - p_sys->i_input_rate = INPUT_RATE_DEFAULT; /* Set output properties */ p_dec->fmt_out.i_cat = AUDIO_ES; @@ -207,9 +203,6 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) return NULL; } - if( (*pp_block)->i_rate > 0 ) - p_sys->i_input_rate = (*pp_block)->i_rate; - block_BytestreamPush( &p_sys->bytestream, *pp_block ); while( 1 ) @@ -408,8 +401,7 @@ static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec ) if( p_buf == NULL ) return NULL; p_buf->start_date = aout_DateGet( &p_sys->end_date ); - p_buf->end_date = aout_DateIncrement( &p_sys->end_date, - A52_FRAME_NB * p_sys->i_input_rate / INPUT_RATE_DEFAULT ); + p_buf->end_date = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ); return p_buf; } @@ -428,9 +420,7 @@ static block_t *GetSoutBuffer( decoder_t *p_dec ) p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date ); p_block->i_length = - aout_DateIncrement( &p_sys->end_date, - A52_FRAME_NB * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) - - p_block->i_pts; + aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ) - p_block->i_pts; return p_block; } diff --git a/modules/codec/avcodec/audio.c b/modules/codec/avcodec/audio.c index 6bf9af4e62..708e193f8f 100644 --- a/modules/codec/avcodec/audio.c +++ b/modules/codec/avcodec/audio.c @@ -32,7 +32,6 @@ #include #include #include -#include /* ffmpeg header */ #ifdef HAVE_LIBAVCODEC_AVCODEC_H @@ -82,8 +81,6 @@ struct decoder_sys_t /* */ int i_reject_count; - - int i_input_rate; }; /***************************************************************************** @@ -207,7 +204,6 @@ int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context, p_sys->p_samples = NULL; p_sys->i_samples = 0; p_sys->i_reject_count = 0; - p_sys->i_input_rate = INPUT_RATE_DEFAULT; aout_DateSet( &p_sys->end_date, 0 ); if( p_dec->fmt_in.audio.i_rate ) @@ -240,8 +236,7 @@ static aout_buffer_t *SplitBuffer( decoder_t *p_dec ) } p_buffer->start_date = aout_DateGet( &p_sys->end_date ); - p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, - i_samples * p_sys->i_input_rate / INPUT_RATE_DEFAULT ); + p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples ); memcpy( p_buffer->p_buffer, p_sys->p_samples, p_buffer->i_nb_bytes ); @@ -265,9 +260,6 @@ aout_buffer_t * DecodeAudio ( decoder_t *p_dec, block_t **pp_block ) p_block = *pp_block; - if( p_block->i_rate > 0 ) - p_sys->i_input_rate = p_block->i_rate; - if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) { block_Release( p_block ); diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c index e42d6f627e..638147bad7 100644 --- a/modules/codec/avcodec/video.c +++ b/modules/codec/avcodec/video.c @@ -32,7 +32,6 @@ #include #include #include -#include /* hmmm, just for INPUT_RATE_DEFAULT */ #include /* BITMAPINFOHEADER */ /* ffmpeg header */ @@ -100,7 +99,7 @@ static void ffmpeg_CopyPicture ( decoder_t *, picture_t *, AVFrame * ); static int ffmpeg_GetFrameBuf ( struct AVCodecContext *, AVFrame * ); static int ffmpeg_ReGetFrameBuf( struct AVCodecContext *, AVFrame * ); static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * ); -static void ffmpeg_NextPts( decoder_t *, int i_block_rate ); +static void ffmpeg_NextPts( decoder_t * ); static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc ) { @@ -617,7 +616,7 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) if( !b_drawpicture && p_pic ) p_dec->pf_vout_buffer_del( p_dec, p_pic ); - ffmpeg_NextPts( p_dec, p_block->i_rate ); + ffmpeg_NextPts( p_dec ); continue; } @@ -671,7 +670,7 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) int i; p_pic->date = p_sys->i_pts; - ffmpeg_NextPts( p_dec, p_block->i_rate ); + ffmpeg_NextPts( p_dec ); if( p_sys->b_first_frame ) { @@ -1007,7 +1006,7 @@ static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context, } } -static void ffmpeg_NextPts( decoder_t *p_dec, int i_block_rate ) +static void ffmpeg_NextPts( decoder_t *p_dec ) { decoder_sys_t *p_sys = p_dec->p_sys; @@ -1020,16 +1019,14 @@ static void ffmpeg_NextPts( decoder_t *p_dec, int i_block_rate ) { p_sys->i_pts += INT64_C(1000000) * (2 + p_sys->p_ff_pic->repeat_pict) * - p_dec->fmt_in.video.i_frame_rate_base * - i_block_rate / INPUT_RATE_DEFAULT / + p_dec->fmt_in.video.i_frame_rate_base / (2 * p_dec->fmt_in.video.i_frame_rate); } else if( p_sys->p_context->time_base.den > 0 ) { p_sys->i_pts += INT64_C(1000000) * (2 + p_sys->p_ff_pic->repeat_pict) * - p_sys->p_context->time_base.num * - i_block_rate / INPUT_RATE_DEFAULT / + p_sys->p_context->time_base.num / (2 * p_sys->p_context->time_base.den); } } diff --git a/modules/codec/csri.c b/modules/codec/csri.c index 681a671aaf..9cb78efe43 100644 --- a/modules/codec/csri.c +++ b/modules/codec/csri.c @@ -85,8 +85,9 @@ struct decoder_sys_t struct subpicture_sys_t { decoder_t *p_dec; - void *p_subs_data; - int i_subs_len; + void *p_subs_data; + int i_subs_len; + mtime_t i_stream_system_delta; }; /***************************************************************************** @@ -165,8 +166,6 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) return NULL; p_block = *pp_block; - if( p_block->i_rate != 0 ) - p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT; *pp_block = NULL; if( p_block->i_buffer == 0 || p_block->p_buffer[0] == '\0' ) @@ -203,6 +202,8 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) } memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer, p_block->i_buffer ); + p_spu->p_sys->i_stream_system_delta = + p_block->i_pts - decoder_GetDisplayDate( p_dec, p_block->i_pts ); p_spu->i_start = p_block->i_pts; p_spu->i_stop = p_block->i_pts + p_block->i_length; @@ -241,7 +242,7 @@ static void PreRender( spu_t *p_spu, subpicture_t *p_subpic, } static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic, - const video_format_t *p_fmt, mtime_t ts ) + const video_format_t *p_fmt, mtime_t i_ts ) { decoder_t *p_dec = p_subpic->p_sys->p_dec; decoder_sys_t *p_sys = p_dec->p_sys; @@ -308,7 +309,7 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic, csri_frame.pixfmt = CSRI_F_BGRA; csri_frame.planes[0] = (unsigned char*)p_spu_region->p_picture->Y_PIXELS; csri_frame.strides[0] = p_spu_region->p_picture->Y_PITCH; - csri_render( p_sys->p_instance, &csri_frame, ts * 0.000001 ); + csri_render( p_sys->p_instance, &csri_frame, (i_ts + p_subpic->p_sys->i_stream_system_delta) * 0.000001 ); } } diff --git a/modules/codec/faad.c b/modules/codec/faad.c index 7af61bc7f0..93118cd04c 100644 --- a/modules/codec/faad.c +++ b/modules/codec/faad.c @@ -28,9 +28,9 @@ #include #include +#include #include #include -#include #include @@ -73,8 +73,6 @@ struct decoder_sys_t uint32_t pi_channel_positions[MAX_CHANNEL_POSITIONS]; bool b_sbr, b_ps; - - int i_input_rate; }; static const uint32_t pi_channels_in[MAX_CHANNEL_POSITIONS] = @@ -188,8 +186,6 @@ static int Open( vlc_object_t *p_this ) p_sys->i_buffer = p_sys->i_buffer_size = 0; p_sys->p_buffer = NULL; - p_sys->i_input_rate = INPUT_RATE_DEFAULT; - /* Faad2 can't deal with truncated data (eg. from MPEG TS) */ p_dec->b_need_packetized = true; @@ -215,9 +211,6 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) return NULL; } - if( p_block->i_rate > 0 ) - p_sys->i_input_rate = p_block->i_rate; - /* Remove ADTS header if we have decoder specific config */ if( p_dec->fmt_in.i_extra && p_block->i_buffer > 7 ) { @@ -431,8 +424,7 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) } p_out->start_date = aout_DateGet( &p_sys->date ); - p_out->end_date = aout_DateIncrement( &p_sys->date, - (frame.samples / frame.channels) * p_sys->i_input_rate / INPUT_RATE_DEFAULT ); + p_out->end_date = aout_DateIncrement( &p_sys->date, frame.samples / frame.channels ); DoReordering( (uint32_t *)p_out->p_buffer, samples, frame.samples / frame.channels, frame.channels, diff --git a/modules/codec/libass.c b/modules/codec/libass.c index 754ec54da6..fd4e1601b3 100644 --- a/modules/codec/libass.c +++ b/modules/codec/libass.c @@ -103,8 +103,9 @@ static void DecSysHold( decoder_sys_t *p_sys ); struct subpicture_sys_t { decoder_sys_t *p_dec_sys; - void *p_subs_data; - int i_subs_len; + void *p_subs_data; + int i_subs_len; + mtime_t i_stream_system_delta; }; typedef struct @@ -218,24 +219,9 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_block = *pp_block; if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) { - msg_Dbg( p_dec, "Resetting libass track after time discontinuity" ); - /* We need to reset our tracks for the time discontinuity to be - * handled */ - vlc_mutex_lock( p_sys->p_ass->p_lock ); - if( p_sys->p_track ) - ass_free_track( p_sys->p_track ); - - p_sys->p_track = ass_new_track( p_sys->p_ass->p_library ); - if( p_sys->p_track ) - ass_process_codec_private( p_sys->p_track, - p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra ); - vlc_mutex_unlock( p_sys->p_ass->p_lock ); - block_Release( p_block ); return NULL; } - if( p_block->i_rate != 0 ) - p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT; *pp_block = NULL; if( p_block->i_buffer == 0 || p_block->p_buffer[0] == '\0' ) @@ -271,6 +257,8 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) } memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer, p_block->i_buffer ); + p_spu->p_sys->i_stream_system_delta = + p_block->i_pts - decoder_GetDisplayDate( p_dec, p_block->i_pts ); p_spu->i_start = p_block->i_pts; p_spu->i_stop = p_block->i_pts + p_block->i_length; @@ -354,7 +342,8 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic, /* */ int i_changed; - ass_image_t *p_img = ass_render_frame( p_ass->p_renderer, p_sys->p_track, i_ts/1000, &i_changed ); + ass_image_t *p_img = ass_render_frame( p_ass->p_renderer, p_sys->p_track, + (i_ts + p_subpic->p_sys->i_stream_system_delta)/1000, &i_changed ); if( !i_changed && !b_fmt_changed ) { diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c index 149ae58f8c..f8c244aa8d 100644 --- a/modules/codec/libmpeg2.c +++ b/modules/codec/libmpeg2.c @@ -57,7 +57,6 @@ struct decoder_sys_t mtime_t i_current_pts; mtime_t i_previous_dts; mtime_t i_current_dts; - int i_current_rate; picture_t * p_picture_to_destroy; bool b_garbage_pic; bool b_after_sequence_header; /* is it the next frame after @@ -247,7 +246,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) if ( p_sys->b_slice_i ) { decoder_SynchroNewPicture( p_sys->p_synchro, - I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate, + I_CODING_TYPE, 2, 0, 0, p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ); decoder_SynchroDecode( p_sys->p_synchro ); decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 ); @@ -283,8 +282,6 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_sys->i_current_dts = p_block->i_dts; } - p_sys->i_current_rate = p_block->i_rate; - mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer, p_block->p_buffer + p_block->i_buffer ); @@ -355,7 +352,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) /* Intra-slice refresh. Simulate a blank I picture. */ msg_Dbg( p_dec, "intra-slice refresh stream" ); decoder_SynchroNewPicture( p_sys->p_synchro, - I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate, + I_CODING_TYPE, 2, 0, 0, p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ); decoder_SynchroDecode( p_sys->p_synchro ); decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 ); @@ -405,7 +402,6 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE, p_sys->p_info->current_picture->nb_fields == 1 ? 2 : p_sys->p_info->current_picture->nb_fields, i_pts, i_dts, - p_sys->i_current_rate, p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ); if( !p_dec->b_pace_control && !p_sys->b_preroll && @@ -455,7 +451,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_sys->b_garbage_pic ); p_sys->b_garbage_pic = 0; - if ( p_sys->p_picture_to_destroy != p_pic ) + if( p_sys->p_picture_to_destroy != p_pic ) { p_pic->date = decoder_SynchroDate( p_sys->p_synchro ); } @@ -535,7 +531,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) if( p_sys->b_slice_i ) { decoder_SynchroNewPicture( p_sys->p_synchro, - I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate, + I_CODING_TYPE, 2, 0, 0, p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY ); decoder_SynchroDecode( p_sys->p_synchro ); decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 ); diff --git a/modules/codec/mpeg_audio.c b/modules/codec/mpeg_audio.c index 9bb2cc58a4..e5e55f4903 100644 --- a/modules/codec/mpeg_audio.c +++ b/modules/codec/mpeg_audio.c @@ -35,7 +35,6 @@ #include #include #include -#include #include @@ -68,8 +67,6 @@ struct decoder_sys_t unsigned int i_layer, i_bit_rate; bool b_discontinuity; - - int i_input_rate; }; enum { @@ -160,7 +157,6 @@ static int OpenDecoder( vlc_object_t *p_this ) aout_DateSet( &p_sys->end_date, 0 ); p_sys->bytestream = block_BytestreamInit(); p_sys->b_discontinuity = false; - p_sys->i_input_rate = INPUT_RATE_DEFAULT; /* Set output properties */ p_dec->fmt_out.i_cat = AUDIO_ES; @@ -226,9 +222,6 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) return NULL; } - if( (*pp_block)->i_rate > 0 ) - p_sys->i_input_rate = (*pp_block)->i_rate; - block_BytestreamPush( &p_sys->bytestream, *pp_block ); while( 1 ) @@ -545,8 +538,7 @@ static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec ) p_buf->start_date = aout_DateGet( &p_sys->end_date ); p_buf->end_date = - aout_DateIncrement( &p_sys->end_date, - p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ); + aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ); p_buf->b_discontinuity = p_sys->b_discontinuity; p_sys->b_discontinuity = false; @@ -570,9 +562,7 @@ static block_t *GetSoutBuffer( decoder_t *p_dec ) p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date ); p_block->i_length = - aout_DateIncrement( &p_sys->end_date, - p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) - - p_block->i_pts; + aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) - p_block->i_pts; return p_block; } diff --git a/modules/codec/spudec/parse.c b/modules/codec/spudec/parse.c index f2c404faac..5a2ee51330 100644 --- a/modules/codec/spudec/parse.c +++ b/modules/codec/spudec/parse.c @@ -185,8 +185,6 @@ static int ParseControlSeq( decoder_t *p_dec, subpicture_t *p_spu, /* Get the control sequence date */ date = (mtime_t)GetWBE( &p_sys->buffer[i_index] ) * 11000; - if( p_sys->i_rate ) - date = date * p_sys->i_rate / INPUT_RATE_DEFAULT; /* Next offset */ i_cur_seq = i_index; diff --git a/modules/codec/spudec/spudec.c b/modules/codec/spudec/spudec.c index cc81a5e598..5f4e83e3e7 100644 --- a/modules/codec/spudec/spudec.c +++ b/modules/codec/spudec/spudec.c @@ -151,7 +151,6 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) /* FIXME: what the, we shouldn’t need to allocate 64k of buffer --sam. */ p_sys->i_spu = block_ChainExtract( p_spu_block, p_sys->buffer, 65536 ); p_sys->i_pts = p_spu_block->i_pts; - p_sys->i_rate = p_spu_block->i_rate; block_ChainRelease( p_spu_block ); /* Parse and decode */ diff --git a/modules/codec/spudec/spudec.h b/modules/codec/spudec/spudec.h index 71de9ba77a..da5789e1aa 100644 --- a/modules/codec/spudec/spudec.h +++ b/modules/codec/spudec/spudec.h @@ -28,7 +28,6 @@ struct decoder_sys_t int b_packetizer; mtime_t i_pts; - int i_rate; unsigned int i_spu_size; unsigned int i_rle_size; unsigned int i_spu; diff --git a/modules/codec/subtitles/subsdec.c b/modules/codec/subtitles/subsdec.c index fa65156fb9..359944c37d 100644 --- a/modules/codec/subtitles/subsdec.c +++ b/modules/codec/subtitles/subsdec.c @@ -264,8 +264,6 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) block_Release( p_block ); return NULL; } - if( p_block->i_rate != 0 ) - p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT; p_spu = ParseText( p_dec, p_block ); diff --git a/modules/codec/subtitles/subsusf.c b/modules/codec/subtitles/subsusf.c index 40cc2222ce..945ed09e18 100644 --- a/modules/codec/subtitles/subsusf.c +++ b/modules/codec/subtitles/subsusf.c @@ -118,8 +118,6 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) return NULL; p_block = *pp_block; - if( p_block->i_rate != 0 ) - p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT; p_spu = ParseText( p_dec, p_block ); diff --git a/modules/codec/telx.c b/modules/codec/telx.c index a0ab9068eb..9c6978f0fd 100644 --- a/modules/codec/telx.c +++ b/modules/codec/telx.c @@ -33,7 +33,6 @@ #include #include -#include #include "vlc_vout.h" #include "vlc_bits.h" @@ -458,8 +457,6 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) if( pp_block == NULL || *pp_block == NULL ) return NULL; p_block = *pp_block; - if( p_block->i_rate != 0 ) - p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT; *pp_block = NULL; dbg((p_dec, "start of telx packet with header %2x\n", diff --git a/modules/codec/vorbis.c b/modules/codec/vorbis.c index 952b33f97a..f7dd711442 100644 --- a/modules/codec/vorbis.c +++ b/modules/codec/vorbis.c @@ -87,8 +87,6 @@ struct decoder_sys_t audio_date_t end_date; int i_last_block_size; - int i_input_rate; - /* ** Channel reordering */ @@ -246,7 +244,6 @@ static int OpenDecoder( vlc_object_t *p_this ) p_sys->i_last_block_size = 0; p_sys->b_packetizer = false; p_sys->i_headers = 0; - p_sys->i_input_rate = INPUT_RATE_DEFAULT; /* Take care of vorbis init */ vorbis_info_init( &p_sys->vi ); @@ -301,9 +298,6 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) /* Block to Ogg packet */ oggpacket.packet = (*pp_block)->p_buffer; oggpacket.bytes = (*pp_block)->i_buffer; - - if( (*pp_block)->i_rate > 0 ) - p_sys->i_input_rate = (*pp_block)->i_rate; } else { @@ -573,8 +567,7 @@ static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket ) /* Date management */ p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date ); - p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date, - i_samples * p_sys->i_input_rate / INPUT_RATE_DEFAULT ); + p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples ); return p_aout_buffer; } else @@ -601,9 +594,7 @@ static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket, p_block->i_dts = p_block->i_pts = aout_DateGet( &p_sys->end_date ); if( p_sys->i_headers >= 3 ) - p_block->i_length = aout_DateIncrement( &p_sys->end_date, - i_samples * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) - - p_block->i_pts; + p_block->i_length = aout_DateIncrement( &p_sys->end_date, i_samples ) - p_block->i_pts; else p_block->i_length = 0; diff --git a/modules/packetizer/mpeg4audio.c b/modules/packetizer/mpeg4audio.c index 9a926acdd2..762268efd7 100644 --- a/modules/packetizer/mpeg4audio.c +++ b/modules/packetizer/mpeg4audio.c @@ -35,9 +35,6 @@ #include #include #include -#include -#include -#include #include #include "vlc_block_helper.h" @@ -209,7 +206,6 @@ static int OpenPacketizer( vlc_object_t *p_this ) p_sys->i_state = STATE_NOSYNC; aout_DateSet( &p_sys->end_date, 0 ); p_sys->bytestream = block_BytestreamInit(); - p_sys->i_input_rate = INPUT_RATE_DEFAULT; p_sys->b_latm_cfg = false; /* Set output properties */ @@ -317,7 +313,7 @@ static block_t *PacketizeRawBlock( decoder_t *p_dec, block_t **pp_block ) p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date ); p_block->i_length = aout_DateIncrement( &p_sys->end_date, - p_dec->fmt_out.audio.i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) - p_block->i_pts; + p_dec->fmt_out.audio.i_frame_length ) - p_block->i_pts; return p_block; } @@ -990,9 +986,6 @@ static block_t *PacketizeStreamBlock( decoder_t *p_dec, block_t **pp_block ) return NULL; } - if( (*pp_block)->i_rate > 0 ) - p_sys->i_input_rate = (*pp_block)->i_rate; - block_BytestreamPush( &p_sys->bytestream, *pp_block ); for( ;; ) @@ -1216,9 +1209,8 @@ static void SetupOutput( decoder_t *p_dec, block_t *p_block ) p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date ); - p_block->i_length = aout_DateIncrement( &p_sys->end_date, - p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) - - p_block->i_pts; + p_block->i_length = + aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) - p_block->i_pts; } /***************************************************************************** diff --git a/modules/packetizer/mpeg4video.c b/modules/packetizer/mpeg4video.c index c9136efd34..a7ad59a0fb 100644 --- a/modules/packetizer/mpeg4video.c +++ b/modules/packetizer/mpeg4video.c @@ -36,7 +36,6 @@ #include #include #include -#include /* hmmm, just for INPUT_RATE_DEFAULT */ #include "vlc_bits.h" #include "vlc_block_helper.h" @@ -295,7 +294,6 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block ) block_BytestreamFlush( &p_sys->bytestream ); p_pic->i_pts = i_pts = p_sys->bytestream.p_block->i_pts; p_pic->i_dts = i_dts = p_sys->bytestream.p_block->i_dts; - p_pic->i_rate = p_sys->bytestream.p_block->i_rate; block_GetBytes( &p_sys->bytestream, p_pic->p_buffer, p_pic->i_buffer ); @@ -569,15 +567,13 @@ static int ParseVOP( decoder_t *p_dec, block_t *p_vop ) p_dec->fmt_in.video.i_frame_rate_base > 0 ) { p_sys->i_interpolated_pts += INT64_C(1000000) * - p_dec->fmt_in.video.i_frame_rate_base * - p_vop->i_rate / INPUT_RATE_DEFAULT / + p_dec->fmt_in.video.i_frame_rate_base / p_dec->fmt_in.video.i_frame_rate; } else if( p_dec->p_sys->i_fps_num ) p_sys->i_interpolated_pts += ( INT64_C(1000000) * (i_time_ref + i_time_increment - - p_sys->i_last_time - p_sys->i_last_timeincr) * - p_vop->i_rate / INPUT_RATE_DEFAULT / + p_sys->i_last_time - p_sys->i_last_timeincr) / p_dec->p_sys->i_fps_num ); p_sys->i_last_time = i_time_ref; diff --git a/modules/packetizer/vc1.c b/modules/packetizer/vc1.c index 854b93691d..64e7c65f08 100644 --- a/modules/packetizer/vc1.c +++ b/modules/packetizer/vc1.c @@ -252,7 +252,6 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block ) block_BytestreamFlush( &p_sys->bytestream ); p_pic->i_pts = p_sys->bytestream.p_block->i_pts; p_pic->i_dts = p_sys->bytestream.p_block->i_dts; - p_pic->i_rate = p_sys->bytestream.p_block->i_rate; block_GetBytes( &p_sys->bytestream, p_pic->p_buffer, p_pic->i_buffer ); diff --git a/src/input/clock.c b/src/input/clock.c index 7a06ad3a96..4c32d5c33b 100644 --- a/src/input/clock.c +++ b/src/input/clock.c @@ -313,6 +313,19 @@ mtime_t input_clock_GetTS( input_clock_t *cl, return i_converted_ts + i_pts_delay; } +/***************************************************************************** + * input_clock_GetRate: Return current rate + *****************************************************************************/ +int input_clock_GetRate( input_clock_t *cl ) +{ + int i_rate; + + vlc_mutex_lock( &cl->lock ); + i_rate = cl->i_rate; + vlc_mutex_unlock( &cl->lock ); + + return i_rate; +} /***************************************************************************** * ClockStreamToSystem: converts a movie clock to system date diff --git a/src/input/decoder.c b/src/input/decoder.c index 1d6e0a7d11..de4f46fb28 100644 --- a/src/input/decoder.c +++ b/src/input/decoder.c @@ -138,8 +138,14 @@ int decoder_GetInputAttachments( decoder_t *p_dec, */ mtime_t decoder_GetDisplayDate( decoder_t *p_dec, mtime_t i_ts ) { - VLC_UNUSED(p_dec); - return i_ts; + decoder_owner_sys_t *p_owner = p_dec->p_owner; + return input_clock_GetTS( p_owner->p_clock, p_owner->p_input->i_pts_delay, i_ts ); +} +/* decoder_GetDisplayRate: + */ +int decoder_GetDisplayRate( decoder_t *p_dec ) +{ + return input_clock_GetRate( p_dec->p_owner->p_clock ); } /** @@ -396,6 +402,7 @@ int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel ) vlc_object_release( p_cc ); return VLC_EGENERIC; } + p_cc->p_owner->p_clock = p_owner->p_clock; vlc_mutex_lock( &p_owner->lock_cc ); p_dec->p_owner->pp_cc[i_channel] = p_cc; @@ -626,10 +633,79 @@ static inline void DecoderUpdatePreroll( int64_t *pi_preroll, const block_t *p ) else if( p->i_dts > 0 ) *pi_preroll = __MIN( *pi_preroll, p->i_dts ); } + +static mtime_t DecoderTeletextFixTs( mtime_t i_ts, mtime_t i_ts_delay ) +{ + mtime_t current_date = mdate(); + + /* FIXME I don't really like that, es_out SHOULD do it using the video pts */ + if( !i_ts || i_ts > current_date + 10000000 || i_ts < current_date ) + { + /* ETSI EN 300 472 Annex A : do not take into account the PTS + * for teletext streams. */ + return current_date + 400000 + i_ts_delay; + } + return i_ts; +} + +static void DecoderSoutBufferFixTs( block_t *p_block, + input_clock_t *p_clock, mtime_t i_ts_delay, + bool b_teletext ) +{ + p_block->i_rate = input_clock_GetRate( p_clock ); + + if( p_block->i_dts > 0 ) + p_block->i_dts = input_clock_GetTS( p_clock, i_ts_delay, p_block->i_dts ); + + if( p_block->i_pts > 0 ) + p_block->i_pts = input_clock_GetTS( p_clock, i_ts_delay, p_block->i_pts ); + + if( p_block->i_length > 0 ) + p_block->i_length = ( p_block->i_length * p_block->i_rate + + INPUT_RATE_DEFAULT-1 ) / INPUT_RATE_DEFAULT; + + if( b_teletext ) + p_block->i_pts = DecoderTeletextFixTs( p_block->i_pts, i_ts_delay ); +} +static void DecoderAoutBufferFixTs( aout_buffer_t *p_buffer, + input_clock_t *p_clock, mtime_t i_ts_delay ) +{ + if( p_buffer->start_date ) + p_buffer->start_date = input_clock_GetTS( p_clock, i_ts_delay, p_buffer->start_date ); + + if( p_buffer->end_date ) + p_buffer->end_date = input_clock_GetTS( p_clock, i_ts_delay, p_buffer->end_date ); +} +static void DecoderVoutBufferFixTs( picture_t *p_picture, + input_clock_t *p_clock, mtime_t i_ts_delay ) +{ + if( p_picture->date ) + p_picture->date = input_clock_GetTS( p_clock, i_ts_delay, p_picture->date ); +} +static void DecoderSpuBufferFixTs( subpicture_t *p_subpic, + input_clock_t *p_clock, mtime_t i_ts_delay, + bool b_teletext ) +{ + bool b_ephemere = p_subpic->i_start == p_subpic->i_stop; + + if( p_subpic->i_start ) + p_subpic->i_start = input_clock_GetTS( p_clock, i_ts_delay, p_subpic->i_start ); + + if( p_subpic->i_stop ) + p_subpic->i_stop = input_clock_GetTS( p_clock, i_ts_delay, p_subpic->i_stop ); + + /* Do not create ephemere picture because of rounding errors */ + if( !b_ephemere && p_subpic->i_start == p_subpic->i_stop ) + p_subpic->i_stop++; + + if( b_teletext ) + p_subpic->i_start = DecoderTeletextFixTs( p_subpic->i_start, i_ts_delay ); +} + static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block ) { input_thread_t *p_input = p_dec->p_owner->p_input; - const int i_rate = p_block->i_rate; + input_clock_t *p_clock = p_dec->p_owner->p_clock; aout_buffer_t *p_aout_buf; while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) ) @@ -661,7 +737,14 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block ) msg_Dbg( p_dec, "End of audio preroll" ); p_dec->p_owner->i_preroll_end = -1; } - aout_DecPlay( p_aout, p_aout_input, p_aout_buf, i_rate ); + + const int i_rate = input_clock_GetRate( p_clock ); + DecoderAoutBufferFixTs( p_aout_buf, p_clock, p_input->i_pts_delay ); + if( i_rate >= INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE && + i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE ) + aout_DecPlay( p_aout, p_aout_input, p_aout_buf, i_rate ); + else + aout_DecDeleteBuffer( p_aout, p_aout_input, p_aout_buf ); } } static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc ) @@ -743,6 +826,7 @@ static void VoutFlushPicture( vout_thread_t *p_vout ) vlc_mutex_unlock( &p_vout->picture_lock ); } +#if 0 static void DecoderOptimizePtsDelay( decoder_t *p_dec ) { input_thread_t *p_input = p_dec->p_owner->p_input; @@ -839,6 +923,7 @@ static void DecoderOptimizePtsDelay( decoder_t *p_dec ) vlc_mutex_unlock( &p_vout->picture_lock ); } } +#endif static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block ) { @@ -876,12 +961,16 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block ) p_dec->p_owner->i_preroll_end = -1; } - if( ( !p_dec->p_owner->p_packetizer || !p_dec->p_owner->p_packetizer->pf_get_cc ) && p_dec->pf_get_cc ) + if( p_dec->pf_get_cc && + ( !p_dec->p_owner->p_packetizer || !p_dec->p_owner->p_packetizer->pf_get_cc ) ) DecoderGetCc( p_dec, p_dec ); + DecoderVoutBufferFixTs( p_pic, p_dec->p_owner->p_clock, p_input->i_pts_delay ); + vout_DatePicture( p_vout, p_pic, p_pic->date ); - DecoderOptimizePtsDelay( p_dec ); + /* Re-enable it but do it right this time */ + //DecoderOptimizePtsDelay( p_dec ); vout_DisplayPicture( p_vout, p_pic ); } @@ -897,7 +986,7 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block ) static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) { decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner; - const int i_rate = p_block ? p_block->i_rate : INPUT_RATE_DEFAULT; + const bool b_telx = p_dec->fmt_in.i_codec == VLC_FOURCC('t','e','l','x'); if( p_block && p_block->i_buffer <= 0 ) { @@ -952,7 +1041,9 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) block_t *p_next = p_sout_block->p_next; p_sout_block->p_next = NULL; - p_sout_block->i_rate = i_rate; + + DecoderSoutBufferFixTs( p_sout_block, + p_dec->p_owner->p_clock, p_dec->p_owner->p_input->i_pts_delay, b_telx ); sout_InputSendBuffer( p_dec->p_owner->p_sout_input, p_sout_block ); @@ -1000,7 +1091,6 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) { block_t *p_next = p_packetized_block->p_next; p_packetized_block->p_next = NULL; - p_packetized_block->i_rate = i_rate; DecoderDecodeAudio( p_dec, p_packetized_block ); @@ -1038,7 +1128,6 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) { block_t *p_next = p_packetized_block->p_next; p_packetized_block->p_next = NULL; - p_packetized_block->i_rate = i_rate; DecoderDecodeVideo( p_dec, p_packetized_block ); @@ -1093,7 +1182,10 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) subpicture_Delete( p_spu ); } else + { + DecoderSpuBufferFixTs( p_spu, p_dec->p_owner->p_clock, p_input->i_pts_delay, b_telx ); spu_DisplaySubpicture( p_vout->p_spu, p_spu ); + } } else { diff --git a/src/input/decoder_synchro.c b/src/input/decoder_synchro.c index f28aea4769..4ff8c7bd04 100644 --- a/src/input/decoder_synchro.c +++ b/src/input/decoder_synchro.c @@ -116,7 +116,6 @@ struct decoder_synchro_t /* */ int i_frame_rate; - int i_current_rate; bool b_no_skip; bool b_quiet; @@ -178,7 +177,7 @@ decoder_synchro_t * decoder_SynchroInit( decoder_t *p_dec, int i_frame_rate ) memset( p_synchro->pi_meaningful, 0, 4 * sizeof(unsigned int) ); p_synchro->i_nb_ref = 0; p_synchro->i_trash_nb_ref = p_synchro->i_dec_nb_ref = 0; - p_synchro->current_pts = mdate() + DEFAULT_PTS_DELAY; + p_synchro->current_pts = 1, p_synchro->backward_pts = 0; p_synchro->i_current_period = p_synchro->i_backward_period = 0; p_synchro->i_trashed_pic = p_synchro->i_not_chosen_pic = @@ -219,13 +218,16 @@ bool decoder_SynchroChoose( decoder_synchro_t * p_synchro, int i_coding_type, mtime_t now, period; mtime_t pts = 0; bool b_decode = 0; + int i_current_rate; if ( p_synchro->b_no_skip ) return 1; + i_current_rate = decoder_GetDisplayRate( p_synchro->p_dec ); + now = mdate(); period = 1000000 * 1001 / p_synchro->i_frame_rate - * p_synchro->i_current_rate / INPUT_RATE_DEFAULT; + * i_current_rate / INPUT_RATE_DEFAULT; p_synchro->i_render_time = i_render_time; @@ -234,11 +236,11 @@ bool decoder_SynchroChoose( decoder_synchro_t * p_synchro, int i_coding_type, case I_CODING_TYPE: if( b_low_delay ) { - pts = S.current_pts; + pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts ); } else if( S.backward_pts ) { - pts = S.backward_pts; + pts = decoder_GetDisplayDate( p_synchro->p_dec, S.backward_pts ); } else { @@ -247,7 +249,7 @@ bool decoder_SynchroChoose( decoder_synchro_t * p_synchro, int i_coding_type, * | +- current picture * +- current PTS */ - pts = S.current_pts + period * (S.i_n_b + 2); + pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts ) + period * (S.i_n_b + 2); } if( (1 + S.i_n_p * (S.i_n_b + 1)) * period > @@ -269,15 +271,15 @@ bool decoder_SynchroChoose( decoder_synchro_t * p_synchro, int i_coding_type, case P_CODING_TYPE: if( b_low_delay ) { - pts = S.current_pts; + pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts ); } else if( S.backward_pts ) { - pts = S.backward_pts; + pts = decoder_GetDisplayDate( p_synchro->p_dec, S.backward_pts ); } else { - pts = S.current_pts + period * (S.i_n_b + 1); + pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts + period * (S.i_n_b + 1) ); } if( p_synchro->i_nb_ref < 1 ) @@ -310,7 +312,7 @@ bool decoder_SynchroChoose( decoder_synchro_t * p_synchro, int i_coding_type, break; case B_CODING_TYPE: - pts = S.current_pts; + pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts ); if( p_synchro->i_nb_ref < 2 ) { @@ -397,16 +399,13 @@ mtime_t decoder_SynchroDate( decoder_synchro_t * p_synchro ) * decoder_SynchroNewPicture: Update stream structure and PTS *****************************************************************************/ void decoder_SynchroNewPicture( decoder_synchro_t * p_synchro, int i_coding_type, - int i_repeat_field, mtime_t next_pts, - mtime_t next_dts, int i_current_rate, - bool b_low_delay ) + int i_repeat_field, mtime_t next_pts, + mtime_t next_dts, bool b_low_delay ) { - mtime_t period = 1000000 * 1001 / p_synchro->i_frame_rate - * i_current_rate / INPUT_RATE_DEFAULT; + mtime_t period = 1000000 * 1001 / p_synchro->i_frame_rate; #if 0 mtime_t now = mdate(); #endif - p_synchro->i_current_rate = i_current_rate; switch( i_coding_type ) { diff --git a/src/input/es_out.c b/src/input/es_out.c index 0916bed6b6..be12d3c191 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -135,7 +135,7 @@ struct es_out_sys_t int64_t i_audio_delay; int64_t i_spu_delay; - /* Rate used to rescale ES ts */ + /* Rate used for clock */ int i_rate; /* Record */ @@ -390,7 +390,6 @@ void input_EsOutChangeRate( es_out_t *out, int i_rate ) int i; p_sys->i_rate = i_rate; - EsOutDiscontinuity( out, false, false ); for( i = 0; i < p_sys->i_pgrm; i++ ) input_clock_ChangeRate( p_sys->pgrm[i]->p_clock, i_rate ); @@ -1507,11 +1506,11 @@ static void EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force ) */ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) { - es_out_sys_t *p_sys = out->p_sys; - input_thread_t *p_input = p_sys->p_input; - es_out_pgrm_t *p_pgrm = es->p_pgrm; + es_out_sys_t *p_sys = out->p_sys; + input_thread_t *p_input = p_sys->p_input; + es_out_pgrm_t *p_pgrm = es->p_pgrm; int64_t i_delay; - int i_total=0; + int i_total = 0; if( es->fmt.i_cat == AUDIO_ES ) i_delay = p_sys->i_audio_delay; @@ -1520,7 +1519,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) else i_delay = 0; - if( libvlc_stats (p_input) ) + if( libvlc_stats( p_input ) ) { vlc_mutex_lock( &p_input->p->counters.counters_lock ); stats_UpdateInteger( p_input, p_input->p->counters.p_demux_read, @@ -1543,94 +1542,63 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) es->i_preroll_end = -1; } - if( p_block->i_dts > 0 && (p_block->i_flags&BLOCK_FLAG_PREROLL) ) - { + if( p_block->i_dts > 0 ) p_block->i_dts += i_delay; - } - else if( p_block->i_dts > 0 ) - { - p_block->i_dts = - input_clock_GetTS( p_pgrm->p_clock, p_input->i_pts_delay, p_block->i_dts ) + i_delay; - } - if( p_block->i_pts > 0 && (p_block->i_flags&BLOCK_FLAG_PREROLL) ) - { + + if( p_block->i_pts > 0 ) p_block->i_pts += i_delay; - } - else if( p_block->i_pts > 0 ) + + p_block->i_rate = 0; + + if( !es->p_dec ) { - p_block->i_pts = - input_clock_GetTS( p_pgrm->p_clock, p_input->i_pts_delay, p_block->i_pts ) + i_delay; + block_Release( p_block ); + return VLC_SUCCESS; } - if ( p_block->i_rate == INPUT_RATE_DEFAULT && - es->fmt.i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' ) ) + + /* Decode */ + if( es->p_dec_record ) { - mtime_t current_date = mdate(); - if( !p_block->i_pts - || p_block->i_pts > current_date + 10000000 - || current_date > p_block->i_pts ) - { - /* ETSI EN 300 472 Annex A : do not take into account the PTS - * for teletext streams. */ - p_block->i_pts = current_date + 400000 - + p_input->i_pts_delay + i_delay; - } + block_t *p_dup = block_Duplicate( p_block ); + if( p_dup ) + input_DecoderDecode( es->p_dec_record, p_dup ); } + input_DecoderDecode( es->p_dec, p_block ); - p_block->i_rate = p_sys->i_rate; + /* Check CC status */ + bool pb_cc[4]; + bool b_cc_new = false; - /* TODO handle mute */ - if( es->p_dec && - ( es->fmt.i_cat != AUDIO_ES || - ( p_sys->i_rate >= INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE && - p_sys->i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE ) ) ) + input_DecoderIsCcPresent( es->p_dec, pb_cc ); + for( int i = 0; i < 4; i++ ) { - bool pb_cc[4]; - bool b_cc_new = false; - int i; - if( es->p_dec_record ) - { - block_t *p_dup = block_Duplicate( p_block ); - if( p_dup ) - input_DecoderDecode( es->p_dec_record, p_dup ); - } - input_DecoderDecode( es->p_dec, p_block ); + static const vlc_fourcc_t fcc[4] = { + VLC_FOURCC('c', 'c', '1', ' '), + VLC_FOURCC('c', 'c', '2', ' '), + VLC_FOURCC('c', 'c', '3', ' '), + VLC_FOURCC('c', 'c', '4', ' '), + }; + es_format_t fmt; - /* Check CC status */ - input_DecoderIsCcPresent( es->p_dec, pb_cc ); - for( i = 0; i < 4; i++ ) - { - static const vlc_fourcc_t fcc[4] = { - VLC_FOURCC('c', 'c', '1', ' '), - VLC_FOURCC('c', 'c', '2', ' '), - VLC_FOURCC('c', 'c', '3', ' '), - VLC_FOURCC('c', 'c', '4', ' '), - }; - es_format_t fmt; - - if( es->pb_cc_present[i] || !pb_cc[i] ) - continue; - msg_Dbg( p_input, "Adding CC track %d for es[%d]", 1+i, es->i_id ); - - es_format_Init( &fmt, SPU_ES, fcc[i] ); - fmt.i_group = es->fmt.i_group; - if( asprintf( &fmt.psz_description, - _("Closed captions %u"), 1 + i ) == -1 ) - fmt.psz_description = NULL; - es->pp_cc_es[i] = EsOutAdd( out, &fmt ); - es->pp_cc_es[i]->p_master = es; - es_format_Clean( &fmt ); - - /* */ - es->pb_cc_present[i] = true; - b_cc_new = true; - } - if( b_cc_new ) - var_SetBool( p_sys->p_input, "intf-change", true ); - } - else - { - block_Release( p_block ); + if( es->pb_cc_present[i] || !pb_cc[i] ) + continue; + msg_Dbg( p_input, "Adding CC track %d for es[%d]", 1+i, es->i_id ); + + es_format_Init( &fmt, SPU_ES, fcc[i] ); + fmt.i_group = es->fmt.i_group; + if( asprintf( &fmt.psz_description, + _("Closed captions %u"), 1 + i ) == -1 ) + fmt.psz_description = NULL; + es->pp_cc_es[i] = EsOutAdd( out, &fmt ); + es->pp_cc_es[i]->p_master = es; + es_format_Clean( &fmt ); + + /* */ + es->pb_cc_present[i] = true; + b_cc_new = true; } + if( b_cc_new ) + var_SetBool( p_sys->p_input, "intf-change", true ); return VLC_SUCCESS; } @@ -2003,9 +1971,6 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args ) if( !es || !es->p_dec ) return VLC_EGENERIC; - /* XXX We should call input_clock_GetTS but PCR has been reseted - * and it will return 0, so we won't call input_clock_GetTS on all preroll samples - * but that's ugly(more time discontinuity), it need to be improved -- fenrir */ es->i_preroll_end = i_date; return VLC_SUCCESS; diff --git a/src/input/input_clock.h b/src/input/input_clock.h index cfb11fea3e..c23b471eff 100644 --- a/src/input/input_clock.h +++ b/src/input/input_clock.h @@ -63,17 +63,22 @@ void input_clock_Reset( input_clock_t * ); /** * This functions will return a deadline used to control the reading speed. */ -mtime_t input_clock_GetWakeup( input_clock_t *cl ); +mtime_t input_clock_GetWakeup( input_clock_t * ); /** * This functions allows to change the actual reading speed. */ -void input_clock_ChangeRate( input_clock_t *cl, int i_rate ); +void input_clock_ChangeRate( input_clock_t *, int i_rate ); /** * This function converts a timestamp from stream clock to system clock. */ mtime_t input_clock_GetTS( input_clock_t *, mtime_t i_pts_delay, mtime_t ); +/** + * This function returns the current rate. + */ +int input_clock_GetRate( input_clock_t * ); + #endif diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 9e3cb014b1..0a8e96fb10 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -78,6 +78,7 @@ date_Init date_Move date_Set decoder_GetDisplayDate +decoder_GetDisplayRate decoder_GetInputAttachment decoder_GetInputAttachments decoder_SynchroChoose -- 2.39.2