Mirror
Mirror copied to clipboard
Consider using 1€ filter for smoothing time synchronization
The description of the 1€ filter suggests, that this algorithm seems to be smoother at a lower latency than the used ExponentialMovingAverage.
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.
thanks for suggestion, gonna take a look asap
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;
}
}
}
@vollstock thanks for sharing. the interactive demo is great.
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?
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.
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
time sync will use snapshot interpolation V2's 'localTimeline' in the future. that should fix the existing issues.
new NetworkTime via snapshot interpolation is live