<html><body><div style="font-family: times new roman, new york, times, serif; font-size: 12pt; color: #000000"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote class=""><div class="">On 16 Mar 2017, at 11:56, Frediano Ziglio <<a href="mailto:fziglio@redhat.com" class="" target="_blank">fziglio@redhat.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="" class=""><blockquote 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="">----- Original Message -----<br class=""><blockquote class=""><blockquote class=""><br class="">Hi<br class=""><br class="">----- Original Message -----<br class=""><blockquote 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="" target="_blank">fziglio@redhat.com</a>><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  | 15 +++++++++++++++<br class="">3 files changed, 29 insertions(+), 11 deletions(-)<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="">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<br class="">*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 -<br class="">now,<br class="">+        gint32 time_diff = compute_mm_time_diff(op->multi_media_time,<br class="">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<br class="">            the<br class="">@@ -192,8 +193,8 @@ static void schedule_frame(SpiceGstDecoder<br class="">*decoder)<br class="">             */<br class="">            decoder->timer_id = g_timeout_add(0, display_frame,<br class="">            decoder);<br class="">        } else {<br class="">-            SPICE_DEBUG("%s: rendering too late by %u ms (ts: %u,<br class="">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,<br class="">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 =<br class="">            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 =<br class="">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,<br class="">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,<br class="">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<br class="">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..3cd0727 100644<br class="">--- a/src/channel-display-priv.h<br class="">+++ b/src/channel-display-priv.h<br class="">@@ -141,6 +141,21 @@ void<br class="">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<br class="">**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<br class="">time2)<br class="">+{<br class="">+    /* Fast not fully portable version.<br class="">+     * If you are paranoid<br class="">+     * (gint32) ((((time1 - time2) & 0xffffffffu) ^ 0x80000000) -<br class="">0x80000000u)<br class="">+     * is more portable */<br class="">+    return (gint32) (guint32) (time1 - time2);<br class="">+}<br class=""></blockquote><br class="">Fast? I have hard time to understand how that above version would be<br class="">faster,<br class="">and I hope my compiler is smart enough to optimize that simple math and<br class="">type<br class="">cast.<br class=""><br class=""></blockquote><br class="">The comment document the code, what I said is that the code I wrote is<br class="">faster than the alternate (in the comment) version.<br class="">If is confusing  I can remove the alternate version.<br class=""><br class=""><blockquote class="">But what are you trying to compute here? A few examples / tests could<br class="">help<br class="">to<br class="">reason about it.<br class=""><br class="">Why do you need a helper function if you can simply cast time1 - time2 to<br class="">gint32 ?<br class=""><br class=""></blockquote><br class="">From the comment:<br class=""><br class="">* So define a function to compute the difference and<br class="">* use as documentation for the code.<br class=""><br class="">yes, the guint32 cast is not necessary however if you write in the code<br class=""><br class="">  if ((gint32) (time1 - time2) < 0)<br class=""><br class="">is not clear why this is not the same as<br class=""><br class=""></blockquote><br class="">Ok your solution is also fine to me.<br class=""><br class="">I think git blame could give that kind of information, or just a comment<br class="">above the line.<br class=""><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="">yes, but this require to git blame every time you look at the source.</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=""><blockquote 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="">Obviously we have similar code in mjpeg and gst units, so some refactoring<br class="">would avoid the duplication, not only of the diff.<br class=""><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="">definitively, but there are also multiple arithmetic on the same</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="">source.</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=""><blockquote 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=""><blockquote class="">  if (time1 < time2)<br class=""><br class="">with the function people reading the code can understand that you need<br class="">some more effort to compute the difference and will look at the function<br class="">and documentation. You could document the inline of the function but<br class="">to make sure to avoid people miscomputing you'll have to have a comment<br class="">for every computation, easier to have in a single place.<br class=""><br class=""><blockquote class="">Let's take an example where it overlaps (I don't know if the server<br class="">really<br class="">handles that).<br class=""><br class="">"now" is MAXUINT32, and new frame time is say 3:  3 - 4294967295 = 4.<br class="">That's<br class="">what is expected, no? However we would need to check if the new frame has<br class="">a<br class=""></blockquote><br class="">3 - 4294967295 == 4 is not a portable assumption. Neither is<br class="">(uint32_t) 3 - (uint32_t) 4294967295 == 4<br class=""></blockquote><br class="">Ok, I am not an expert in portability, do you have an example where this<br class="">would give different results?<br class=""><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="">If int is 64 bit (uint32_t) 3 - (uint32_t) 4294967295 == -4294967292.</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="">It seems weird but is due to the integral promotion rules.</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></div></blockquote><div class=""><br class=""></div><div class="">Yes, but it does not matter. Once you cast that back down to 32-bits, you get 4. The 64-bit pattern is 0xffffffff00000004, which will convert to 0x4 whether you do a signed or unsigned 32->64 bit extension.</div></div></div></blockquote><div>Yes, but the initial comment did not have the cast.<br></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">Back to the original code, I think the function comment is fine:</div><div class=""><br class=""></div><div class=""><div class=""><div 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="">+ */</div></div></div><div class=""><br class=""></div><div class="">However, the comment inside the function is very confusing:</div><div class=""><br class=""></div><div class=""><div class=""><div class="">/* Fast not fully portable version.<br class="">+     * If you are paranoid<br class="">+     * (gint32) ((((time1 - time2) & 0xffffffffu) ^ 0x80000000) - 0x80000000u)</div><div class=""><br class=""></div><div class="">This is not better in particular because you added a mix of signed and unsigned ints (the first 0x80000000 is signed), and you introduce additional potential integer promotions in the middle. So I would just get rid of that comment.</div></div></div></div></div></blockquote><div>Removed in v2. Beside the gint32 (which should be int_least32_t) this would support platforms not having 32bit ints (not that I know one and I don't think our code can support them either). You can find similar code in binutils.<br></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div class=""><div class="">The necessary and sufficient code is:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>(gint32) (time2 - time1)</div></div></div></div></div></blockquote><div>Yes, this is in v2.<br></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div class=""><div class="">That being said, I would rewrite the function as follows for a different reason:</div><div class=""><br class=""></div><div class="">/* Return true if time2 is after time1 */</div><div class="">static inline bool mm_time_after(guint32 time1, guint32 time2)</div><div class="">{</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>return (gint32) (time2 - time1) > 0;</div><div class="">}</div></div></div></div></div></blockquote><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div class=""><div class="">The reason is that we really care about “are we after”, and I find this clarifies the intent.</div></div></div></div></div></blockquote><div>In some paths we need the difference, for instance to schedule the rendering.</div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div class=""><div class=""><br class=""></div></div></div><blockquote class=""><div class=""><div style="" 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="">Similar to</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="">  printf("%d\n", (uint16_t) 10 - (uint16_t) 16);</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="">which give -6 (but maybe some people could point out that this result is</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="">not portable either... from my knowledge it is).</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></div></blockquote><div class=""><br class=""></div><div class="">As far as I know, it is, except if you find a machine where int is 8 bits, in which case it’s the %d that is not portable ;-)</div></div></div></blockquote><div>I never met such platform and surely we are not going to support any <32bit platforms.<br></div><div>As far as I know int are from 16 bits to 64 bits.<br></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class="">Christophe</div><br class=""><blockquote class=""><div class=""><div style="" 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 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=""><blockquote class=""><br class="">if time1 == UINT32_MAX and time2 == 3 I expect 4 while if<br class="">time2 == UINT32_MAX and time2 == 3 (this can happen for different reasons)<br class="">I expect -4. This make computation easier.<br class=""><br class="">I'll add this example.<br class=""></blockquote><br class="">Yeah, some test cases would be useful to understand the problem and the<br class="">solution.<br class=""><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="">Done</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=""><blockquote 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="">Thanks<br class=""><br class=""><blockquote class=""><br class=""><blockquote class="">ts before the last frame received to check if we overlapped, I think<br class="">(otherwise we should consider this frame as a late frame)<br class=""></blockquote></blockquote></blockquote></div></div></blockquote></div></div></blockquote><div><br></div></div></body></html>