[Spice-devel] [qxl 5/5] spiceqxl_audio: Stop the playback channel if there is nothing to play

Francois Gouget fgouget at codeweavers.com
Fri Mar 18 14:32:22 UTC 2016


This lets the client free the audio resources when an audio application
is not actually playing anything, typically because playback is paused.
This matches QEMU's behavior.
As a side benefit it stops the client's mm-time from being stuck (due
to the audio backend's delay updates being applied to the mm-time of
the last audio message) which lets video streams play in this situation.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
 src/spiceqxl_audio.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/spiceqxl_audio.c b/src/spiceqxl_audio.c
index 8d187b7..9002863 100644
--- a/src/spiceqxl_audio.c
+++ b/src/spiceqxl_audio.c
@@ -46,6 +46,7 @@
        and feed ahead into the Spice server (up to FEED_BUFFER_PERIODS).
 */
 
+#define IDLE_MS              300
 #define PERIOD_MS            10
 #define READ_BUFFER_PERIODS  2
 #define FEED_BUFFER_PERIODS  8
@@ -72,7 +73,7 @@ struct audio_data {
     int fifo_count;
     int closed_fifos;
     SpiceTimer *wall_timer;
-    int wall_timer_live;
+    int wall_timer_type;
     int dir_watch;
     int fifo_dir_watch;
     SpiceWatch *fifo_dir_qxl_watch;
@@ -279,9 +280,9 @@ static void read_from_fifos(int fd, int event, void *opaque)
     int i;
     int maxlen = 0;
 
-    if (data->wall_timer_live) {
+    if (data->wall_timer_type) {
         qxl->core->timer_cancel(data->wall_timer);
-        data->wall_timer_live = 0;
+        data->wall_timer_type = 0;
     }
 
     for (i = 0; i < data->fifo_count; i++) {
@@ -333,12 +334,16 @@ static void read_from_fifos(int fd, int event, void *opaque)
     if (!process_fifos(qxl, data, maxlen)) {
         /* There is still some fifo data to process */
         qxl->core->timer_start(data->wall_timer, PERIOD_MS);
-        data->wall_timer_live = 1;
+        data->wall_timer_type = PERIOD_MS;
 
     } else if (data->fifo_count) {
         /* All the fifo data was processed. Wait for more */
         start_watching(qxl);
 
+        /* But none may arrive so stop processing if that happens */
+        qxl->core->timer_start(data->wall_timer, IDLE_MS);
+        data->wall_timer_type = IDLE_MS;
+
     } else if (data->active) {
         /* There is no open fifo anymore */
         spice_server_playback_stop(&qxl->playback_sin);
@@ -361,14 +366,23 @@ static void start_watching(qxl_screen_t *qxl)
     }
 }
 
+/* a helper for read_from_fifos() */
 static void wall_ticker(void *opaque)
 {
     qxl_screen_t *qxl = opaque;
     struct audio_data *data = qxl->playback_opaque;
 
-    data->wall_timer_live = 0;
-
-    read_from_fifos(-1, 0, qxl);
+    if (data->wall_timer_type == IDLE_MS) {
+        /* There is no open fifo anymore */
+        if (data->active) {
+            spice_server_playback_stop(&qxl->playback_sin);
+            data->active = 0;
+        }
+        data->wall_timer_type = 0;
+    } else {
+        data->wall_timer_type = 0;
+        read_from_fifos(-1, 0, qxl);
+    }
 }
 
 #if defined(HAVE_SYS_INOTIFY_H)
-- 
2.7.0


More information about the Spice-devel mailing list