From 65b858f7d34d07a3e11ef22406015b027145b5b6 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 22 Feb 2016 13:08:08 +0100 Subject: ad_lavc: interpolate missing timestamps This is actually already done by dec_audio.c. But if AV_FRAME_DATA_SKIP_SAMPLES is applied, this happens too late here. The problem is that this will slice off samples, and make it impossible for later code to reconstruct the timestamp properly. Missing timestamps can still happen with some demuxers, e.g. demux_mkv.c with Opus tracks. (Although libavformat interpolates these itself.) --- audio/decode/ad_lavc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index eeb4526f13..5cd335b44c 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -43,6 +43,7 @@ struct priv { struct mp_audio frame; bool force_channel_map; uint32_t skip_samples; + double next_pts; }; static void uninit(struct dec_audio *da); @@ -138,6 +139,8 @@ static int init(struct dec_audio *da, const char *decoder) return 0; } + ctx->next_pts = MP_NOPTS_VALUE; + return 1; } @@ -164,6 +167,7 @@ static int control(struct dec_audio *da, int cmd, void *arg) case ADCTRL_RESET: avcodec_flush_buffers(ctx->avctx); ctx->skip_samples = 0; + ctx->next_pts = MP_NOPTS_VALUE; return CONTROL_TRUE; } return CONTROL_UNKNOWN; @@ -222,6 +226,11 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, mpframe->pts = out_pts; + if (mpframe->pts == MP_NOPTS_VALUE) + mpframe->pts = priv->next_pts; + if (mpframe->pts != MP_NOPTS_VALUE) + priv->next_pts = mpframe->pts + mpframe->samples / (double)mpframe->rate; + #if HAVE_AVFRAME_SKIP_SAMPLES AVFrameSideData *sd = av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES); -- cgit v1.2.3