From 4cabd08e8a54c201f153ce28c783f2e7d4ee413a Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 14 Jan 2015 22:14:46 +0100 Subject: [PATCH] audio: fix initial audio PTS Commit 5e25a3d2 broke handling of the initial frame (the one decoded with initial_audio_decode()). It didn't update the pts_offset field, leading to a shift in timestamps by one audio frame. Fix by calling the actual decode function in a single place. This requires slightly more changes than what would be necessary to fix the bug, but it also somewhat simplifies the data flow. --- audio/decode/dec_audio.c | 51 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index 30facb4c11..ab4cd2ec55 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -153,23 +153,33 @@ void audio_uninit(struct dec_audio *d_audio) MP_VERBOSE(d_audio, "Uninit audio filters...\n"); af_destroy(d_audio->afilter); uninit_decoder(d_audio); + talloc_free(d_audio->waiting); talloc_free(d_audio); } +static int decode_new_frame(struct dec_audio *da) +{ + while (!da->waiting) { + int ret = da->ad_driver->decode_packet(da, &da->waiting); + if (ret < 0) + return ret; + + if (da->waiting) { + da->pts_offset += da->waiting->samples; + da->decode_format = *da->waiting; + mp_audio_set_null_data(&da->decode_format); + } + } + return mp_audio_config_valid(da->waiting) ? AD_OK : AD_ERR; +} + /* Decode packets until we know the audio format. Then reinit the buffer. * Returns AD_OK on success, negative AD_* code otherwise. * Also returns AD_OK if already initialized (and does nothing). */ int initial_audio_decode(struct dec_audio *da) { - while (!da->waiting) { - int ret = da->ad_driver->decode_packet(da, &da->waiting); - if (ret < 0) - return ret; - } - talloc_steal(da, da->waiting); - da->decode_format = *da->waiting; - return mp_audio_config_valid(da->waiting) ? AD_OK : AD_ERR; + return decode_new_frame(da); } static bool copy_output(struct af_stream *afs, struct mp_audio_buffer *outbuf, @@ -208,31 +218,22 @@ int audio_decode(struct dec_audio *da, struct mp_audio_buffer *outbuf, if (copy_output(afs, outbuf, minsamples, false)) break; - struct mp_audio *mpa = da->waiting; - da->waiting = NULL; - if (!mpa) { - res = da->ad_driver->decode_packet(da, &mpa); - if (res < 0) { - // drain filters first (especially for true EOF case) - copy_output(afs, outbuf, minsamples, true); - break; - } - if (!mpa) - continue; - - da->pts_offset += mpa->samples; - da->decode_format = *mpa; - mp_audio_set_null_data(&da->decode_format); + res = decode_new_frame(da); + if (res < 0) { + // drain filters first (especially for true EOF case) + copy_output(afs, outbuf, minsamples, true); + break; } // On format change, make sure to drain the filter chain. - if (!mp_audio_config_equals(&afs->input, mpa)) { - da->waiting = talloc_steal(da, mpa); + if (!mp_audio_config_equals(&afs->input, da->waiting)) { copy_output(afs, outbuf, minsamples, true); res = AD_NEW_FMT; break; } + struct mp_audio *mpa = da->waiting; + da->waiting = NULL; if (af_filter_frame(afs, mpa) < 0) return AD_ERR; }