Browse files

video: add a default frame latency of 1 frame

This is configureable in adancedsettings under video/latency/frames.
The default value should correspond to a A/V delay of -16ms at 60 hz
and -41ms at 24hz

Most video output will be counting it's delay in times of frames, not
in absolute time. Any advanced frame processing on normal TV's will
at least incure a 1 frame delay.
  • Loading branch information...
1 parent 2fbabe5 commit b59ba8c60037a121f21cb7505f61cd6d95ebfc5d @elupus committed Nov 7, 2012
Showing with 5 additions and 0 deletions.
  1. +4 −0 xbmc/settings/AdvancedSettings.cpp
  2. +1 −0 xbmc/settings/AdvancedSettings.h
View
4 xbmc/settings/AdvancedSettings.cpp
@@ -112,6 +112,7 @@ void CAdvancedSettings::Initialize()
m_DXVANoDeintProcForProgressive = false;
m_videoFpsDetect = 1;
m_videoDefaultLatency = 0.0;
+ m_videoFrameLatency = 1;
m_musicUseTimeSeeking = true;
m_musicTimeSeekForward = 10;
@@ -625,6 +626,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
// Get default global display latency
XMLUtils::GetFloat(pVideoLatency, "delay", m_videoDefaultLatency, -600.0f, 600.0f);
+ XMLUtils::GetInt(pVideoLatency, "frames", m_videoFrameLatency, -60, 60);
}
}
@@ -1195,6 +1197,8 @@ void CAdvancedSettings::AddSettingsFile(const CStdString &filename)
float CAdvancedSettings::GetDisplayLatency(float refreshrate)
{
float delay = m_videoDefaultLatency / 1000.0f;
+ if(refreshrate)
+ delay += m_videoFrameLatency / refreshrate;
for (int i = 0; i < (int) m_videoRefreshLatency.size(); i++)
{
RefreshVideoLatency& videolatency = m_videoRefreshLatency[i];
View
1 xbmc/settings/AdvancedSettings.h
@@ -157,6 +157,7 @@ class CAdvancedSettings
std::vector<RefreshOverride> m_videoAdjustRefreshOverrides;
std::vector<RefreshVideoLatency> m_videoRefreshLatency;
float m_videoDefaultLatency;
+ int m_videoFrameLatency;
bool m_videoDisableBackgroundDeinterlace;
int m_videoCaptureUseOcclusionQuery;
bool m_DXVACheckCompatibility;

11 comments on commit b59ba8c

@fritsch

I think this is quite confusing for new users now. Most look at the lips moving and estimate the delay roughly and write it to advancedsettings.xml

Your patch uses a "linear" model, meaning 24hz: 1/24 seconds delay and for 60hz 1/60 seconds delay. In theory this could help to only set the latency once - but as real life has prooved: 24hz modes does not linearly compare to 60hz. Most displays "tested" do a lot of more delay when in 24hz or 23.98hz mode.

So the user ends up the same as before - specifying multiple delays, but only the values differ.
So I don't see the advantage in real life environment, only more confusion, cause of an additional setting - how should one measure 2/60 vs. 4/60 delay?

The best way would be to use the hdmi spec to identify the delay that TV and computer communicate within this protocol.

Some tests by users concerning delay and audio / video sync: http://forum.xbmc.org/showthread.php?tid=141646

@elupus
Owner

yes hdmi info would be best. but i doubt that is correct in many cases.

I do understand that for anybody that have set a global delay using this not standard way ( you could have done it in gui ), this changes what they had calibrated, but it does this for EVERYBODY else too -> rather controversial change.

The point here is really that we have been doing this wrong for a long time. We have not taken into account that we have frame delay of at least one frame leading to always being quite off for low HZ modes.

Do note i've not removed the ability to override for a specific frame rates (and this won't take affect if you have set the delay specifically for a frame rate). But i'mho the linear y = kx + m should be enough for most cases.

I'll look through that thread thou.

@elupus
Owner

Right.. it seems about like what i had expected. 200ms is what i have to set as offset on my system at 24hz. Some people don't seem to experience it. Do not there is another MAJOR issue at play there too. The frame delay is technically dynamic.

If we render video with a fps >= HZ we will fill upp all video buffers in the video HW. This could be something like 3 frames (ie a setting of 3). while when we play a videos with fps < HZ, we will have empty HW buffers -> 1 frame delay.

Thus to solve this fully we'd need to take that into account if the video we are playing are causing HW buffers to fill, or remain drained.

@elupus
Owner

Ps.. this is why there is such a big difference between 24 and 23.97 hz modes.

@fritsch

I am completely with you and I read the patch, so I pretty know the old delay method is still there. In my oppinion I would do the 1/refreshrate as default - just remove the advancedsetting. It will improve the situation for the "standard delay" people. The 60hz fraction won't realize any change or can you really see 1/60 seconds delay?

My problem is only with the advancedsettings.xml - If users start to misuse this setting for the global delay. I find it hard to set values in frames, that cannot be measured (in frames), so you start thinking in seconds (ms) again and just calculate in fps.

@elupus
Owner

well if you think in delay and calculate based on current hz you will still set it right :). Advanced settings are not really for users. It's for very advanced users for helping to "debug" out a better new default.

I even think we should have a value of 2 as default. But I'm not sure I can get that accepted :). So it need to be possible to calibrate for now.

We really need sample video's for user to run through on different resolutions, then calculate these values auto.

@elupus
Owner

note: https://github.com/elupus/xbmc/commits/vqueue would likely solve the issues with the 24fps filling up hw buffers. But i've not worked on it for quite some time now.

@fritsch

We build such a measurement system at work to be able to calculate delays. Cause - we were interested in deflecometric analysis, we must be really sure when a pattern we send actually is on screen. For this purpose a Pandaboard was chosen to directly interfer with the LVDS. When you now have to same setups with one external trigger for the same signal you can measure the difference.

The above thread I linked, was created during the OpenELEC 2.0 release, cause a lot of users complained. After evaluating those results, we set a default delay of 175ms for 23< x <= 24. It was not easy to get unflamed measured values.

@elupus
Owner

Right.. but as you can see from the reports. at 24hz with a 23.9.. movie, you don't get a delay that large. That is the major problem really, we always get several extra frames delay when fps is same as hz. Also there is no guarantee that the hz you ask the video hw to render at is what you actually exactly get, thus we can't really rely on fps of movie and configured hz of display.

The only real solution is to know how much is queued up for display.

@fritsch

Looking at your patches, really shortly only: I would trust the hpet, yes - but I would not trust the VBlank. So better using the hpet, to actually measure if the vlank is done correctly (Triple Buffering and such stuff are also a pain on Linux).

@fritsch

@FernetMenta has done a lot of stuff into this direction. From verifying the "swapBuffers" to video buffers for the player - to be able to get images on screen in sync and being able to have enough in the queue to get the images out quite fine.

Been looking forward on you two if you do this great improving stuff alltogether after the frodo release. Watching the queue + having a buffer + watching the output - should be a great new world and a new level of xbmc experience.

Please sign in to comment.