summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-17 00:20:20 +0200
committerwm4 <wm4@nowhere>2014-09-17 00:33:40 +0200
commit396756e58ab37d262ca31fece673329d224eca0a (patch)
treebcc25b9ed6dbea7e071a01fe35c9b21e2b05e9d2
parentc158e4641ad8be435fd403bc6dc00f2f99e0940e (diff)
downloadmpv-396756e58ab37d262ca31fece673329d224eca0a.tar.bz2
mpv-396756e58ab37d262ca31fece673329d224eca0a.tar.xz
ao_oss: prevent hang when unpausing after device was lost
Pausing/unpausing while the audio device can't be reopened, and then unpausing again when the device is finally reopened, can hang the player for a while. This happens because p->prepause_samples grows without bounds each time the player is unpaused while the device is lost. On unpause, ao_oss plays prepause_samples of silence to compensate for A/V timing issues due to the partially lost buffer (we can't pause the device at an arbitrary sample position, and the current period will be lost). This in turn will make the player appear to be frozen if too much audio is queued. (Normally, play() must never block, but here it happens because more data is written than get_space() reports. A better implementation would never let prepause_samples grow larger than the period size.) The unbounded growth happens because get_space() always returns that the device can be written while the device is lost. So limit it to 200ms. (A better implementation would limit it to the period size.) Also see #1080.
-rw-r--r--audio/out/ao_oss.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c
index 9ed10cf6c1..b78f244a7b 100644
--- a/audio/out/ao_oss.c
+++ b/audio/out/ao_oss.c
@@ -579,6 +579,9 @@ static int get_space(struct ao *ao)
return zz.fragments * zz.fragsize / ao->sstride;
}
+ if (p->audio_fd < 0 && p->device_failed && get_delay(ao) > 0.2)
+ return 0;
+
if (p->audio_fd < 0 || device_writable(ao) > 0)
return p->outburst / ao->sstride;