[Spice-devel] [spice-gtk] RFC: Allow to limit the latency introduced by lip sync
Snir Sheriber
ssheribe at redhat.com
Wed Aug 16 06:45:22 UTC 2017
Hi,
On 08/15/2017 05:56 PM, Frediano Ziglio wrote:
> This patch allows to reduce the time the client wait to display frames.
> It can make the lip sync not working but it allows to see the
> video latency introduced by this code.
> This patch is meant to be used mainly for debugging:
> - recently we are seeing some artifacts due to this delay and
> overlaying, removing the delay make easier to understand if the
> problem is related to this or other issues;
> - we are testing guest encoding and we are experiencing a big lag.
> This avoid this part of the lag helping understand where the other
> part of the delay happens.
Actually IMHO this could be also good enough solution for the building
latency issue
for now.
I mentioned it also in Victor's mmtime-adjustment patch thread (at least
I thought I
did- just noticed i accidentally replayed to off-list :/), if we'll let
the user the option
to enable\disable this frames-scheduling-limitation (as presented here)
on-the-fly
(e.g as menu checkbox -as in victor's suggestion) he (the user) would be
able
to enable it in case he's feeling latency was built, and latency will
disappear
immediately (and audio will become out of sync). Adjusting mm_time alone
doesn't seem to fix already built latency...
Snir.
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
> This patch is not intended to be merged as is but to be used to fix
> above problems or as a start for some better settings.
> ---
> src/channel-display-gst.c | 10 ++++++----
> src/channel-display-mjpeg.c | 24 +++++++++++++++++++-----
> src/channel-display-priv.h | 3 +++
> 3 files changed, 28 insertions(+), 9 deletions(-)
>
> Changes since last version:
> - rebased on master.
>
> It seems is still useful, still not clear all sync process.
>
> diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
> index f978602..9ee6229 100644
> --- a/src/channel-display-gst.c
> +++ b/src/channel-display-gst.c
> @@ -173,8 +173,10 @@ static void schedule_frame(SpiceGstDecoder *decoder)
> break;
> }
>
> - if (spice_mmtime_diff(now, gstframe->frame->mm_time) < 0) {
> - decoder->timer_id = g_timeout_add(gstframe->frame->mm_time - now,
> + gint32 time_diff = spice_mmtime_diff(gstframe->frame->mm_time, now);
> + time_diff = MIN(time_diff, max_frame_delay_ms);
> + if (time_diff > 0) {
> + decoder->timer_id = g_timeout_add(time_diff,
> display_frame, decoder);
> } else if (g_queue_get_length(decoder->display_queue) == 1) {
> /* Still attempt to display the least out of date frame so the
> @@ -182,8 +184,8 @@ static void schedule_frame(SpiceGstDecoder *decoder)
> */
> decoder->timer_id = g_timeout_add(0, display_frame, decoder);
> } else {
> - SPICE_DEBUG("%s: rendering too late by %u ms (ts: %u, mmtime: %u), dropping",
> - __FUNCTION__, now - gstframe->frame->mm_time,
> + SPICE_DEBUG("%s: rendering too late by %d ms (ts: %u, mmtime: %u), dropping",
> + __FUNCTION__, -time_diff,
> gstframe->frame->mm_time, now);
> stream_dropped_frame_on_playback(decoder->base.stream);
> g_queue_pop_head(decoder->display_queue);
> diff --git a/src/channel-display-mjpeg.c b/src/channel-display-mjpeg.c
> index f0d55f6..cc9ddf1 100644
> --- a/src/channel-display-mjpeg.c
> +++ b/src/channel-display-mjpeg.c
> @@ -189,6 +189,19 @@ static gboolean mjpeg_decoder_decode_frame(gpointer video_decoder)
>
> /* ---------- VideoDecoder's queue scheduling ---------- */
>
> +enum { MAX_DELAY_MS = 2000 };
> +gint32 max_frame_delay_ms = MAX_DELAY_MS;
> +
> +SPICE_CONSTRUCTOR_FUNC(max_delay_init)
> +{
> + const char *str_delay = g_getenv("SPICE_MAX_FRAME_DELAY");
> + if (str_delay) {
> + int delay = atoi(str_delay);
> + if (delay >= 0 && delay <= MAX_DELAY_MS)
> + max_frame_delay_ms = delay;
> + }
> +}
> +
> static void mjpeg_decoder_schedule(MJpegDecoder *decoder)
> {
> SPICE_DEBUG("%s", __FUNCTION__);
> @@ -201,15 +214,16 @@ static void mjpeg_decoder_schedule(MJpegDecoder *decoder)
> decoder->cur_frame = NULL;
> do {
> if (frame) {
> - if (spice_mmtime_diff(time, frame->mm_time) <= 0) {
> - guint32 d = frame->mm_time - time;
> + gint32 time_diff = spice_mmtime_diff(frame->mm_time, time);
> + time_diff = MIN(time_diff, max_frame_delay_ms);
> + if (time_diff >= 0) {
> decoder->cur_frame = frame;
> - decoder->timer_id = g_timeout_add(d, mjpeg_decoder_decode_frame, decoder);
> + decoder->timer_id = g_timeout_add(time_diff, mjpeg_decoder_decode_frame, decoder);
> break;
> }
>
> - SPICE_DEBUG("%s: rendering too late by %u ms (ts: %u, mmtime: %u), dropping ",
> - __FUNCTION__, time - frame->mm_time,
> + SPICE_DEBUG("%s: rendering too late by %d ms (ts: %u, mmtime: %u), dropping ",
> + __FUNCTION__, -time_diff,
> frame->mm_time, time);
> stream_dropped_frame_on_playback(decoder->base.stream);
> free_spice_frame(frame);
> diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h
> index 1389868..92bd85a 100644
> --- a/src/channel-display-priv.h
> +++ b/src/channel-display-priv.h
> @@ -197,6 +197,9 @@ void stream_display_frame(display_stream *st, SpiceFrame *frame, uint32_t width,
> gint64 get_stream_id_by_stream(SpiceChannel *channel, display_stream *st);
>
>
> +/* maximum delay for frames */
> +extern gint32 max_frame_delay_ms;
> +
> G_END_DECLS
>
> #endif // CHANNEL_DISPLAY_PRIV_H_
More information about the Spice-devel
mailing list