summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Kretz <kretz@kde.org>2007-12-02 22:48:36 +0100
committerMatthias Kretz <kretz@kde.org>2007-12-02 22:48:36 +0100
commitcad22619cdb867490ebfb59069f0aa472620edc5 (patch)
treecd41b2d96e973d0aee8e8c397602237deeca8614
parentad59ad1d662d29c4ac3644c8fc6a2c428e2ed2c8 (diff)
downloadxine-lib-cad22619cdb867490ebfb59069f0aa472620edc5.tar.gz
xine-lib-cad22619cdb867490ebfb59069f0aa472620edc5.tar.bz2
Fixed ALSA close function to not discard all data that had been written but not played yet.
When closing the pcm device make sure that everything that was written to the device actually gets played. This was the race we were seeing with Ogg Vorbis and wav playback where a delayed driver->close would fix playback. Notice that blocking mode needs to be used for snd_pcm_drain, otherwise the call would be a noop.
-rw-r--r--ChangeLog2
-rw-r--r--src/audio_out/audio_alsa_out.c6
2 files changed, 7 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 469faf8b8..a4a680bbd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,8 @@ xine-lib (1.1.9) (unreleased)
* Fixed deadlock on ao_close while paused.
* Nicer wakeup behaviour, using select instead of nanosleep (800 -> 100
wakeups/s).
+ * Fixed ALSA close function to not discard all data that had been written
+ but not played yet.
xine-lib (1.1.8)
* Send a channel-changed event to the frontend when receiving the SYNC
diff --git a/src/audio_out/audio_alsa_out.c b/src/audio_out/audio_alsa_out.c
index e92bfbb3a..4ce2b1be3 100644
--- a/src/audio_out/audio_alsa_out.c
+++ b/src/audio_out/audio_alsa_out.c
@@ -856,7 +856,11 @@ static int ao_alsa_write(ao_driver_t *this_gen, int16_t *data, uint32_t count) {
static void ao_alsa_close(ao_driver_t *this_gen) {
alsa_driver_t *this = (alsa_driver_t *) this_gen;
- if(this->audio_fd) snd_pcm_close(this->audio_fd);
+ if(this->audio_fd) {
+ snd_pcm_nonblock(this->audio_fd, 0);
+ snd_pcm_drain(this->audio_fd);
+ snd_pcm_close(this->audio_fd);
+ }
this->audio_fd = NULL;
this->has_pause_resume = 0; /* This is set at open time */
}