Mirror icon indicating copy to clipboard operation
Mirror copied to clipboard

Consider using 1€ filter for smoothing time synchronization

Open vollstock opened this issue 3 years ago • 7 comments

The description of the 1€ filter suggests, that this algorithm seems to be smoother at a lower latency than the used ExponentialMovingAverage.

Try the example

I consider integrating mirror into a media server solution where network time is used to synchronize playback of videos, timelines, etc. Even in a local gigabit network, I can see a time difference of up to 10 ms. To achieve frame accurate sync this would ideally be lower.

I can imagine that in more common game scenarios a higher time accuracy would be desirable, too.

vollstock avatar Oct 12 '21 09:10 vollstock

thanks for suggestion, gonna take a look asap

miwarnec avatar Apr 03 '22 12:04 miwarnec

c# version from the link:

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace Sensorit.Base
{
    public class OneEuroFilter
    {
        public OneEuroFilter(double minCutoff, double beta)
        {
            firstTime = true;
            this.minCutoff = minCutoff;
            this.beta = beta;

            xFilt = new LowpassFilter();
            dxFilt = new LowpassFilter();
            dcutoff = 1;
        }

        protected bool firstTime;
        protected double minCutoff;
        protected double beta;
        protected LowpassFilter xFilt;
        protected LowpassFilter dxFilt;
        protected double dcutoff;

        public double MinCutoff
        {
            get { return minCutoff; }
            set { minCutoff = value; }
        }

        public double Beta
        {
            get { return beta; }
            set { beta = value; }
        }

        public double Filter(double x, double rate)
        {
            double dx = firstTime ? 0 : (x - xFilt.Last()) * rate;
            if (firstTime)
            {
                firstTime = false;
            }

            var edx = dxFilt.Filter(dx, Alpha(rate, dcutoff));
            var cutoff = minCutoff + beta * Math.Abs(edx);

            return xFilt.Filter(x, Alpha(rate, cutoff));
        }

        protected double Alpha(double rate, double cutoff)
        {
            var tau = 1.0 / (2 * Math.PI * cutoff);
            var te = 1.0 / rate;
            return 1.0 / (1.0 + tau / te);
        }
    }

    public class LowpassFilter
    {
        public LowpassFilter()
        {
            firstTime = true;
        }

        protected bool firstTime;
        protected double hatXPrev;

        public double Last()
        {
            return hatXPrev;
        }

        public double Filter(double x, double alpha)
        {
            double hatX = 0;
            if (firstTime)
            {
                firstTime = false;
                hatX = x;
            }
            else
                hatX = alpha * x + (1 - alpha) * hatXPrev;

            hatXPrev = hatX;

            return hatX;
        }
    }
}

miwarnec avatar Apr 03 '22 12:04 miwarnec

@vollstock thanks for sharing. the interactive demo is great.

miwarnec avatar Apr 03 '22 12:04 miwarnec

If this removes the ±10ms difference that would be Amaizing. But faster response for Network time is not desired - you want the network time to remain as consistent as possible no?

NiftyliuS avatar Apr 03 '22 13:04 NiftyliuS

if it's an incremental improvement then it's worth considering. but we probably need to look into 'proper' network time sync. we already have batching timestamps, soon to be LocalWorldState timestamps. likely we can work with those.

miwarnec avatar Apr 03 '22 15:04 miwarnec

Just out of cusiosity, what do you mean by “proper” sync?

Also, are you aware of the GStreamer-Docs on the topic? https://gstreamer.freedesktop.org/documentation/application-development/advanced/clocks.html?gi-language=c

vollstock avatar Apr 04 '22 07:04 vollstock

time sync will use snapshot interpolation V2's 'localTimeline' in the future. that should fix the existing issues.

miwarnec avatar Jun 18 '22 06:06 miwarnec

new NetworkTime via snapshot interpolation is live

miwarnec avatar Oct 09 '22 07:10 miwarnec