summaryrefslogtreecommitdiffstats
path: root/xbmc/windowing/wayland/VideoSyncWpPresentation.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--xbmc/windowing/wayland/VideoSyncWpPresentation.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/xbmc/windowing/wayland/VideoSyncWpPresentation.cpp b/xbmc/windowing/wayland/VideoSyncWpPresentation.cpp
new file mode 100644
index 0000000..e050a2d
--- /dev/null
+++ b/xbmc/windowing/wayland/VideoSyncWpPresentation.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "VideoSyncWpPresentation.h"
+
+#include "settings/AdvancedSettings.h"
+#include "utils/TimeUtils.h"
+#include "utils/log.h"
+#include "windowing/wayland/WinSystemWayland.h"
+
+#include <cinttypes>
+#include <functional>
+
+using namespace KODI::WINDOWING::WAYLAND;
+using namespace std::placeholders;
+
+CVideoSyncWpPresentation::CVideoSyncWpPresentation(void* clock, CWinSystemWayland& winSystem)
+: CVideoSync(clock), m_winSystem(winSystem)
+{
+}
+
+bool CVideoSyncWpPresentation::Setup(PUPDATECLOCK func)
+{
+ UpdateClock = func;
+ m_stopEvent.Reset();
+ m_fps = m_winSystem.GetSyncOutputRefreshRate();
+
+ return true;
+}
+
+void CVideoSyncWpPresentation::Run(CEvent& stopEvent)
+{
+ m_presentationHandler = m_winSystem.RegisterOnPresentationFeedback(std::bind(&CVideoSyncWpPresentation::HandlePresentation, this, _1, _2, _3, _4, _5));
+
+ XbmcThreads::CEventGroup waitGroup{&stopEvent, &m_stopEvent};
+ waitGroup.wait();
+
+ m_presentationHandler.Unregister();
+}
+
+void CVideoSyncWpPresentation::Cleanup()
+{
+}
+
+float CVideoSyncWpPresentation::GetFps()
+{
+ return m_fps;
+}
+
+void CVideoSyncWpPresentation::HandlePresentation(timespec tv, std::uint32_t refresh, std::uint32_t syncOutputID, float syncOutputRefreshRate, std::uint64_t msc)
+{
+ auto mscDiff = msc - m_lastMsc;
+
+ CLog::Log(LOGDEBUG, LOGAVTIMING,
+ "VideoSyncWpPresentation: tv {}.{:09} s next refresh in +{} ns (fps {:f}) sync output "
+ "id {} fps {:f} msc {} mscdiff {}",
+ static_cast<std::uint64_t>(tv.tv_sec), static_cast<std::uint64_t>(tv.tv_nsec), refresh,
+ 1.0e9 / refresh, syncOutputID, syncOutputRefreshRate, msc, mscDiff);
+
+ if (m_fps != syncOutputRefreshRate || (m_syncOutputID != 0 && m_syncOutputID != syncOutputID))
+ {
+ // Restart if fps changes or sync output changes (which means that the msc jumps)
+ CLog::Log(LOGDEBUG, "fps or sync output changed, restarting Wayland video sync");
+ m_stopEvent.Set();
+ }
+ m_syncOutputID = syncOutputID;
+
+ if (m_lastMsc == 0)
+ {
+ // If this is the first time or MSC is not supported, assume we moved one frame
+ mscDiff = 1;
+ }
+ m_lastMsc = msc;
+
+ // FIXME use timespec instead of currenthostcounter()? Possibly difficult
+ // due to different clock base
+ UpdateClock(mscDiff, CurrentHostCounter(), m_refClock);
+}