summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-01-14 22:14:46 +0100
committerwm4 <wm4@nowhere>2015-01-14 22:14:46 +0100
commit4cabd08e8a54c201f153ce28c783f2e7d4ee413a (patch)
treefcff210a20928175f6c84aef42db0c83eb1ce20a /audio
parent1a522f2976004b8896d71e71446ae04723df3cec (diff)
downloadmpv-4cabd08e8a54c201f153ce28c783f2e7d4ee413a.tar.bz2
mpv-4cabd08e8a54c201f153ce28c783f2e7d4ee413a.tar.xz
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.
Diffstat (limited to 'audio')
-rw-r--r--audio/decode/dec_audio.c49
1 files changed, 25 insertions, 24 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,25 +153,35 @@ 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);
}
-/* 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)
+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);
+ }
}
- talloc_steal(da, da->waiting);
- da->decode_format = *da->waiting;
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)
+{
+ return decode_new_frame(da);
+}
+
static bool copy_output(struct af_stream *afs, struct mp_audio_buffer *outbuf,
int minsamples, bool eof)
{
@@ -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;
}