[Spice-devel] [PATCH spice] Remove guest side video time-stamping

Marc-André Lureau marcandre.lureau at gmail.com
Fri Nov 14 04:55:27 PST 2014


The multimedia time is defined by the server side monotonic time [1],
but the drawing time-stamp is done in guest side, so it requires
synchronization between host and guest. This is expensive, when no audio
is playing, there is a ~30x/sec wakeup to update the qxl device mmtime,
and it requires marking dirty the rom region.

Instead, the video timestamping can be done more efficiently on server
side, without visible drawbacks.

[1] a better timestamp could be the audio time, since audio players are
    usually sync with audio time)

Related to:
https://bugzilla.redhat.com/show_bug.cgi?id=912763
---

This is a resend, as a non-RFC version this time.

 server/red_dispatcher.c |  9 ---------
 server/red_worker.c     |  1 +
 server/reds-private.h   |  2 --
 server/reds.c           | 13 -------------
 server/snd_worker.c     |  1 -
 server/spice-qxl.h      |  2 +-
 6 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index a6ffe7b..d8389bc 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -751,15 +751,6 @@ static void qxl_worker_loadvm_commands(QXLWorker *qxl_worker,
     red_dispatcher_loadvm_commands((RedDispatcher*)qxl_worker, ext, count);
 }
 
-void red_dispatcher_set_mm_time(uint32_t mm_time)
-{
-    RedDispatcher *now = dispatchers;
-    while (now) {
-        now->qxl->st->qif->set_mm_time(now->qxl, mm_time);
-        now = now->next;
-    }
-}
-
 static inline int calc_compression_level(void)
 {
     spice_assert(streaming_video != STREAM_VIDEO_INVALID);
diff --git a/server/red_worker.c b/server/red_worker.c
index 9f18495..cbb78a2 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -4195,6 +4195,7 @@ static inline void red_process_drawable(RedWorker *worker, RedDrawable *red_draw
         return;
     }
 
+    red_drawable->mm_time = reds_get_mm_time();
     surface_id = drawable->surface_id;
 
     worker->surfaces[surface_id].refs++;
diff --git a/server/reds-private.h b/server/reds-private.h
index ee09e7c..0bfbf3b 100644
--- a/server/reds-private.h
+++ b/server/reds-private.h
@@ -6,7 +6,6 @@
 #include <spice/protocol.h>
 
 #define MIGRATE_TIMEOUT (1000 * 10) /* 10sec */
-#define MM_TIMER_GRANULARITY_MS (1000 / 30)
 #define MM_TIME_DELTA 400 /*ms*/
 
 typedef struct TicketAuthentication {
@@ -159,7 +158,6 @@ typedef struct RedsState {
     int dispatcher_allows_client_mouse;
     MonitorMode monitor_mode;
     SpiceTimer *mig_timer;
-    SpiceTimer *mm_timer;
 
     int vm_running;
     Ring char_devs_states; /* list of SpiceCharDeviceStateItem */
diff --git a/server/reds.c b/server/reds.c
index 505bacd..c2d71f6 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -2799,7 +2799,6 @@ uint32_t reds_get_mm_time(void)
 
 void reds_enable_mm_timer(void)
 {
-    core->timer_start(reds->mm_timer, MM_TIMER_GRANULARITY_MS);
     reds->mm_timer_enabled = TRUE;
     reds->mm_time_latency = MM_TIME_DELTA;
     reds_send_mm_time();
@@ -2807,16 +2806,9 @@ void reds_enable_mm_timer(void)
 
 void reds_disable_mm_timer(void)
 {
-    core->timer_cancel(reds->mm_timer);
     reds->mm_timer_enabled = FALSE;
 }
 
-static void mm_timer_proc(void *opaque)
-{
-    red_dispatcher_set_mm_time(reds_get_mm_time());
-    core->timer_start(reds->mm_timer, MM_TIMER_GRANULARITY_MS);
-}
-
 static SpiceCharDeviceState *attach_to_red_agent(SpiceCharDeviceInstance *sin)
 {
     VDIPortState *state = &reds->agent_state;
@@ -3237,11 +3229,6 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
     }
 #endif
 
-    if (!(reds->mm_timer = core->timer_add(mm_timer_proc, NULL))) {
-        spice_error("mm timer create failed");
-    }
-    reds_enable_mm_timer();
-
     if (reds_init_net() < 0) {
         goto err;
     }
diff --git a/server/snd_worker.c b/server/snd_worker.c
index 6f20f55..fdb5e6c 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -1117,7 +1117,6 @@ SPICE_GNUC_VISIBLE void spice_server_playback_put_samples(SpicePlaybackInstance
         snd_playback_free_frame(playback_channel, playback_channel->pending_frame);
     }
     frame->time = reds_get_mm_time();
-    red_dispatcher_set_mm_time(frame->time);
     playback_channel->pending_frame = frame;
     snd_set_command(&playback_channel->base, SND_PLAYBACK_PCM_MASK);
     snd_playback_send(&playback_channel->base);
diff --git a/server/spice-qxl.h b/server/spice-qxl.h
index edf3394..99cb2af 100644
--- a/server/spice-qxl.h
+++ b/server/spice-qxl.h
@@ -158,7 +158,7 @@ struct QXLInterface {
 
     void (*attache_worker)(QXLInstance *qin, QXLWorker *qxl_worker);
     void (*set_compression_level)(QXLInstance *qin, int level);
-    void (*set_mm_time)(QXLInstance *qin, uint32_t mm_time);
+    void (*set_mm_time)(QXLInstance *qin, uint32_t mm_time) SPICE_GNUC_DEPRECATED;
 
     void (*get_init_info)(QXLInstance *qin, QXLDevInitInfo *info);
     int (*get_command)(QXLInstance *qin, struct QXLCommandExt *cmd);
-- 
1.9.3



More information about the Spice-devel mailing list