Skip to content

Commit

Permalink
windowing/gbm: Add display clock
Browse files Browse the repository at this point in the history
This allows use of "sync video to display"
and features like resampling for smooth playback
of 24fps content on 25fps display
  • Loading branch information
popcornmix committed Apr 6, 2021
1 parent 3fb0652 commit bd44202
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 1 deletion.
2 changes: 2 additions & 0 deletions xbmc/windowing/gbm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ add_subdirectory(drm)

set(SOURCES OptionalsReg.cpp
WinSystemGbm.cpp
VideoSyncGbm.cpp
GBMUtils.cpp
WinSystemGbmEGLContext.cpp
GBMDPMSSupport.cpp)

set(HEADERS OptionalsReg.h
WinSystemGbm.h
VideoSyncGbm.h
GBMUtils.h
WinSystemGbmEGLContext.h
GBMDPMSSupport.h)
Expand Down
115 changes: 115 additions & 0 deletions xbmc/windowing/gbm/VideoSyncGbm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright (C) 2005-2021 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 "VideoSyncGbm.h"
#include "ServiceBroker.h"
#include "windowing/GraphicContext.h"
#include "windowing/WinSystem.h"
#include "utils/TimeUtils.h"
#include "utils/log.h"
#include "threads/Thread.h"
#include "xbmc/windowing/gbm/WinSystemGbm.h"

#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
#include "xf86drm.h"
#include "xf86drmMode.h"

bool CVideoSyncGbm::Setup(PUPDATECLOCK func)
{
UpdateClock = func;
m_abort = false;
CServiceBroker::GetWinSystem()->Register(this);
CLog::Log(LOGDEBUG, "CVideoSyncGbm:{} setting up", __FUNCTION__);

auto winSystem = dynamic_cast<KODI::WINDOWING::GBM::CWinSystemGbm*>(CServiceBroker::GetWinSystem());
if (!winSystem)
{
CLog::Log(LOGWARNING, "CVideoSyncGbm:{}: failed to get winSystem", __FUNCTION__);
return false;
}
auto drm = winSystem->GetDrm();
if (!drm)
{
CLog::Log(LOGWARNING, "CVideoSyncGbm:{}: failed to get drm", __FUNCTION__);
return false;
}
auto crtc = drm->GetCrtc();
if (!crtc)
{
CLog::Log(LOGWARNING, "CVideoSyncGbm:{}: failed to get crtc", __FUNCTION__);
return false;
}

uint64_t ns = 0;
m_crtcId = crtc->GetCrtcId();
m_fd = drm->GetFileDescriptor();
int s = drmCrtcGetSequence(m_fd, m_crtcId, &m_sequence, &ns);
if (s != 0)
{
CLog::Log(LOGWARNING, "CVideoSyncGbm:{}: drmCrtcGetSequence failed (%d)", __FUNCTION__, s);
return false;
}
CLog::Log(LOGINFO, "CVideoSyncGbm:{}: opened (fd:{} crtc:{} seq:{} ns:{})", __FUNCTION__, m_fd, m_crtcId, m_sequence, ns);
return true;
}

void CVideoSyncGbm::Run(CEvent& stopEvent)
{
/* This shouldn't be very busy and timing is important so increase priority */
CThread::GetCurrentThread()->SetPriority(CThread::GetCurrentThread()->GetPriority()+1);

if (m_fd < 0)
{
CLog::Log(LOGWARNING, "CVideoSyncGbm:{}: failed to open device (%d)", __FUNCTION__, m_fd);
return;
}
CLog::Log(LOGDEBUG, "CVideoSyncGbm:{}: started (%d)", m_fd);

while (!stopEvent.Signaled() && !m_abort)
{
uint64_t sequence = 0, ns = 0;
usleep(1000);
int s = drmCrtcGetSequence(m_fd, m_crtcId, &sequence, &ns);
if (s != 0)
{
CLog::Log(LOGWARNING, "CVideoSyncGbm:{}: drmCrtcGetSequence failed (%d)", __FUNCTION__, s);
break;
}
//CLog::Log(LOGDEBUG, "CVideoSyncGbm:{}: drmCrtcGetSequence: seq:{}:{} ns:{} s:{}", __FUNCTION__, sequence, m_sequence, ns, s);
if (sequence == m_sequence)
continue;
UpdateClock(sequence - m_sequence, CurrentHostCounter(), m_refClock);
m_sequence = sequence;
}
}

void CVideoSyncGbm::Cleanup()
{
CLog::Log(LOGDEBUG, "CVideoSyncGbm:{}: cleaning up", __FUNCTION__);
CServiceBroker::GetWinSystem()->Unregister(this);
}

float CVideoSyncGbm::GetFps()
{
m_fps = CServiceBroker::GetWinSystem()->GetGfxContext().GetFPS();
CLog::Log(LOGDEBUG, "CVideoSyncGbm:{}: fps: %.2f", __FUNCTION__, m_fps);
return m_fps;
}

void CVideoSyncGbm::OnResetDisplay()
{
m_abort = true;
}

void CVideoSyncGbm::RefreshChanged()
{
if (m_fps != CServiceBroker::GetWinSystem()->GetGfxContext().GetFPS())
m_abort = true;
}
30 changes: 30 additions & 0 deletions xbmc/windowing/gbm/VideoSyncGbm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2005-2021 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.
*/

#pragma once

#include "windowing/VideoSync.h"
#include "guilib/DispResource.h"

class CVideoSyncGbm : public CVideoSync, IDispResource
{
public:
CVideoSyncGbm(void *clock) : CVideoSync(clock) {};
virtual bool Setup(PUPDATECLOCK func);
virtual void Run(CEvent& stopEvent);
virtual void Cleanup();
virtual float GetFps();
virtual void OnResetDisplay();
virtual void RefreshChanged();

private:
int m_fd = -1;
uint32_t m_crtcId = 0;
uint64_t m_sequence = 0;
volatile bool m_abort;
};
9 changes: 8 additions & 1 deletion xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "utils/XTimeUtils.h"
#include "utils/log.h"
#include "windowing/WindowSystemFactory.h"
#include "VideoSyncGbm.h"

#include <gbm.h>

Expand Down Expand Up @@ -144,7 +145,7 @@ void CWinSystemGbmGLESContext::PresentRender(bool rendered, bool videoLayer)
}
else
{
KODI::TIME::Sleep(10);
KODI::TIME::Sleep(1);
}
}

Expand All @@ -160,3 +161,9 @@ bool CWinSystemGbmGLESContext::CreateContext()
}
return true;
}

std::unique_ptr<CVideoSync> CWinSystemGbmGLESContext::GetVideoSync(void *clock)
{
std::unique_ptr<CVideoSync> pVSync(new CVideoSyncGbm(clock));
return pVSync;
}
1 change: 1 addition & 0 deletions xbmc/windowing/gbm/WinSystemGbmGLESContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class CWinSystemGbmGLESContext : public CWinSystemGbmEGLContext, public CRenderS
void PresentRender(bool rendered, bool videoLayer) override;
protected:
void SetVSyncImpl(bool enable) override {}
std::unique_ptr<CVideoSync> GetVideoSync(void *clock) override;
void PresentRenderImpl(bool rendered) override {};
bool CreateContext() override;
};
Expand Down

0 comments on commit bd44202

Please sign in to comment.