summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-30 02:14:38 +0200
committerwm4 <wm4@nowhere>2014-05-30 02:16:43 +0200
commitc79689206c489b2ba449b8d21e0b5819298c949a (patch)
treefd3d19c60f34ce62396e1aa61cfa99005dc7f953
parentb7c6981278067b22930c6193d79a6d96cb277143 (diff)
downloadmpv-c79689206c489b2ba449b8d21e0b5819298c949a.tar.bz2
mpv-c79689206c489b2ba449b8d21e0b5819298c949a.tar.xz
audio: change handling of an EOF corner case
This code handles buggy AOs (even if all AOs are bug-free, it's good for robustness). Move handling of it to the AO feed thread. Now this check doesn't require magic numbers and does exactly what's it supposed to do.
-rw-r--r--audio/out/push.c14
-rw-r--r--player/audio.c8
2 files changed, 10 insertions, 12 deletions
diff --git a/audio/out/push.c b/audio/out/push.c
index dd1015d441..b779dac69a 100644
--- a/audio/out/push.c
+++ b/audio/out/push.c
@@ -240,7 +240,14 @@ static void ao_play_data(struct ao *ao)
MP_WARN(ao, "Audio device returned non-sense value.\n");
r = data.samples;
}
- mp_audio_buffer_skip(p->buffer, MPMAX(r, 0));
+ r = MPMAX(r, 0);
+ // Probably can't copy the rest of the buffer due to period alignment.
+ bool stuck = r <= 0 && space >= max && data.samples > 0;
+ if ((flags & AOPLAY_FINAL_CHUNK) && stuck) {
+ MP_ERR(ao, "Audio output driver seems to ignore AOPLAY_FINAL_CHUNK.\n");
+ r = max;
+ }
+ mp_audio_buffer_skip(p->buffer, r);
if (p->final_chunk && mp_audio_buffer_samples(p->buffer) == 0) {
p->expected_end_time = mp_time_sec() + AO_EOF_DELAY + 0.25; // + margin
if (ao->driver->get_delay)
@@ -249,10 +256,7 @@ static void ao_play_data(struct ao *ao)
// In both cases, we have to account for space!=0, but the AO not accepting
// any new data (due to rounding to period boundaries).
p->buffers_full = max >= space && r <= 0;
- p->avoid_ao_wait = (max == 0 && space > 0) || p->paused;
- // Probably can't copy the rest of the buffer due to period alignment.
- if (!p->final_chunk && r <= 0 && space >= max && data.samples > 0)
- p->avoid_ao_wait = true;
+ p->avoid_ao_wait = (max == 0 && space > 0) || p->paused || stuck;
}
// Estimate when the AO needs data again.
diff --git a/player/audio.c b/player/audio.c
index a391aeabe5..1070270dda 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -459,13 +459,7 @@ int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
int played = write_to_ao(mpctx, &data, playflags, written_audio_pts(mpctx));
assert(played >= 0 && played <= data.samples);
- if (played > 0) {
- mp_audio_buffer_skip(mpctx->ao_buffer, played);
- } else if (!mpctx->paused && audio_eof && ao_get_delay(ao) < .04) {
- // Sanity check to avoid hanging in case current ao doesn't output
- // partial chunks and doesn't check for AOPLAY_FINAL_CHUNK
- signal_eof = true;
- }
+ mp_audio_buffer_skip(mpctx->ao_buffer, played);
return signal_eof ? -2 : -partial_fill;
}