<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 16 Mar 2017, at 11:49, Marc-André Lureau <<a href="mailto:mlureau@redhat.com" class="">mlureau@redhat.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Hi</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">----- Original Message -----</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">The multimedia time can easily overflow as is encoded in an<br class="">unsigned 32 bit and have a unit of milliseconds so it wrap<br class="">up every 49 days. Use some math that allow the number to overflow<br class="">without issues.<br class="">This could caused the client to stop handling streaming and<br class="">starting only queueing.<br class=""><br class="">Signed-off-by: Frediano Ziglio <<a href="mailto:fziglio@redhat.com" class="">fziglio@redhat.com</a>><br class="">---<br class="">This patch should be applied independently on 2/2 as intended to be<br class="">merged upstream as a fix while 2/2 depends on this as it change same<br class="">code portions.<br class="">---<br class="">src/channel-display-gst.c   | 11 ++++++-----<br class="">src/channel-display-mjpeg.c | 14 ++++++++------<br class="">src/channel-display-priv.h  | 19 +++++++++++++++++++<br class="">3 files changed, 33 insertions(+), 11 deletions(-)<br class=""><br class="">diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c<br class="">index c4190b2..9c62e67 100644<br class="">--- a/src/channel-display-gst.c<br class="">+++ b/src/channel-display-gst.c<br class="">@@ -183,8 +183,9 @@ static void schedule_frame(SpiceGstDecoder *decoder)<br class="">        }<br class=""><br class="">        SpiceStreamDataHeader *op = spice_msg_in_parsed(frame->msg);<br class="">-        if (now < op->multi_media_time) {<br class="">-            decoder->timer_id = g_timeout_add(op->multi_media_time - now,<br class="">+        gint32 time_diff = compute_mm_time_diff(op->multi_media_time, now);<br class="">+        if (time_diff >= 0) {<br class="">+            decoder->timer_id = g_timeout_add(time_diff,<br class="">                                              display_frame, decoder);<br class="">        } else if (g_queue_get_length(decoder->display_queue) == 1) {<br class="">            /* Still attempt to display the least out of date frame so the<br class="">@@ -192,8 +193,8 @@ static void schedule_frame(SpiceGstDecoder *decoder)<br class="">             */<br class="">            decoder->timer_id = g_timeout_add(0, display_frame, decoder);<br class="">        } else {<br class="">-            SPICE_DEBUG("%s: rendering too late by %u ms (ts: %u, mmtime:<br class="">%u), dropping",<br class="">-                        __FUNCTION__, now - op->multi_media_time,<br class="">+            SPICE_DEBUG("%s: rendering too late by %d ms (ts: %u, mmtime:<br class="">%u), dropping",<br class="">+                        __FUNCTION__, -time_diff,<br class="">                        op->multi_media_time, now);<br class="">            stream_dropped_frame_on_playback(decoder->base.stream);<br class="">            g_queue_pop_head(decoder->display_queue);<br class="">@@ -431,7 +432,7 @@ static gboolean<br class="">spice_gst_decoder_queue_frame(VideoDecoder *video_decoder,<br class="">    }<br class=""><br class="">    SpiceStreamDataHeader *frame_op = spice_msg_in_parsed(frame_msg);<br class="">-    if (frame_op->multi_media_time < decoder->last_mm_time) {<br class="">+    if (compute_mm_time_diff(frame_op->multi_media_time,<br class="">decoder->last_mm_time) < 0) {<br class="">        SPICE_DEBUG("new-frame-time < last-frame-time (%u < %u):"<br class="">                    " resetting stream, id %u",<br class="">                    frame_op->multi_media_time,<br class="">diff --git a/src/channel-display-mjpeg.c b/src/channel-display-mjpeg.c<br class="">index 722494e..1b7373b 100644<br class="">--- a/src/channel-display-mjpeg.c<br class="">+++ b/src/channel-display-mjpeg.c<br class="">@@ -195,15 +195,15 @@ static void mjpeg_decoder_schedule(MJpegDecoder<br class="">*decoder)<br class="">    do {<br class="">        if (frame_msg) {<br class="">            SpiceStreamDataHeader *op = spice_msg_in_parsed(frame_msg);<br class="">-            if (time <= op->multi_media_time) {<br class="">-                guint32 d = op->multi_media_time - time;<br class="">+            gint32 time_diff = compute_mm_time_diff(op->multi_media_time,<br class="">time);<br class="">+            if (time_diff >= 0) {<br class="">                decoder->cur_frame_msg = frame_msg;<br class="">-                decoder->timer_id = g_timeout_add(d,<br class="">mjpeg_decoder_decode_frame, decoder);<br class="">+                decoder->timer_id = g_timeout_add(time_diff,<br class="">mjpeg_decoder_decode_frame, decoder);<br class="">                break;<br class="">            }<br class=""><br class="">-            SPICE_DEBUG("%s: rendering too late by %u ms (ts: %u, mmtime:<br class="">%u), dropping ",<br class="">-                        __FUNCTION__, time - op->multi_media_time,<br class="">+            SPICE_DEBUG("%s: rendering too late by %d ms (ts: %u, mmtime:<br class="">%u), dropping ",<br class="">+                        __FUNCTION__, -time_diff,<br class="">                        op->multi_media_time, time);<br class="">            stream_dropped_frame_on_playback(decoder->base.stream);<br class="">            spice_msg_in_unref(frame_msg);<br class="">@@ -249,7 +249,9 @@ static gboolean mjpeg_decoder_queue_frame(VideoDecoder<br class="">*video_decoder,<br class="">        SpiceStreamDataHeader *last_op, *frame_op;<br class="">        last_op = spice_msg_in_parsed(last_msg);<br class="">        frame_op = spice_msg_in_parsed(frame_msg);<br class="">-        if (frame_op->multi_media_time < last_op->multi_media_time) {<br class="">+        gint32 time_diff =<br class="">+            compute_mm_time_diff(frame_op->multi_media_time,<br class="">last_op->multi_media_time);<br class="">+        if (time_diff < 0) {<br class="">            /* This should really not happen */<br class="">            SPICE_DEBUG("new-frame-time < last-frame-time (%u < %u):"<br class="">                        " resetting stream, id %u",<br class="">diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h<br class="">index b9c08a3..eced6af 100644<br class="">--- a/src/channel-display-priv.h<br class="">+++ b/src/channel-display-priv.h<br class="">@@ -141,6 +141,25 @@ void stream_dropped_frame_on_playback(display_stream<br class="">*st);<br class="">void stream_display_frame(display_stream *st, SpiceMsgIn *frame_msg,<br class="">uint32_t width, uint32_t height, uint8_t *data);<br class="">uint32_t spice_msg_in_frame_data(SpiceMsgIn *frame_msg, uint8_t **data);<br class=""><br class="">+/* Compute the difference between 2 multimedia times.<br class="">+ * Multimedia times are subject to overflow so the check<br class="">+ * for time1 < time2 does not always indicate that time2<br class="">+ * happens after time1.<br class="">+ * So define a function to compute the difference and<br class="">+ * use as documentation for the code.<br class="">+ */<br class="">+static inline gint32 compute_mm_time_diff(guint32 time1, guint32 time2)<br class="">+{<br class="">+    /* Compute time difference returning a signed value<br class="">+     * For instance:<br class="">+     * - if time1 == 3 and time2 == UINT32_MAX this means that<br class="">+     *   time1 overflowed and is 4 milliseconds after time2;<br class="">+     * - if time1 == UINT32_MAX and time2 == 3 this means that<br class="">+     *   time2 overflowed and is 4 milliseconds before time2<br class="">+     *   (so the difference is -4)<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">time2 didn't necessarily overflow, It could also be that time is scheduled for 42d later, right? I am afraid the diff alone isn't enough.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div class=""><br class=""></div><div class="">Does this really happen? If that’s the case, the only “real” solution is to move to 64-bit, because otherwise, it may work at 42 days but will fail at 49.</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">+     */<br class="">+    return (gint32) (time1 - time2);<br class="">+}<br class=""><br class="">G_END_DECLS<br class=""><br class="">--<br class="">2.9.3<br class=""><br class="">_______________________________________________<br class="">Spice-devel mailing list<br class=""><a href="mailto:Spice-devel@lists.freedesktop.org" class="">Spice-devel@lists.freedesktop.org</a><br class=""><a href="https://lists.freedesktop.org/mailman/listinfo/spice-devel" class="">https://lists.freedesktop.org/mailman/listinfo/spice-devel</a><br class=""><br class=""></blockquote><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Spice-devel mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="mailto:Spice-devel@lists.freedesktop.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">Spice-devel@lists.freedesktop.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="https://lists.freedesktop.org/mailman/listinfo/spice-devel" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">https://lists.freedesktop.org/mailman/listinfo/spice-devel</a></div></blockquote></div><br class=""></div></body></html>