aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Morten Kvarving <spiff@kodi.tv>2019-06-17 08:45:46 +0200
committerGitHub <noreply@github.com>2019-06-17 08:45:46 +0200
commit79dcf62e412bc0c5904dd73f5983ba77311f0c4d (patch)
treeabbea77999d8d7acaed9b72b09598bee11d3f684
parent2ebf43de424d2e8834e4851c4bbe822e8252687f (diff)
parentb992f859e732ab7e4970c1b6ee2f5f0927b75bb6 (diff)
Merge pull request #16274 from Kwiboo/backport-gbm-drmprime
Backport fixes and improvements for GBM and DRM PRIME
-rw-r--r--cmake/treedata/optional/common/gbm.txt1
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp184
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h43
-rw-r--r--xbmc/cores/VideoPlayer/Process/gbm/CMakeLists.txt7
-rw-r--r--xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.cpp34
-rw-r--r--xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h26
-rw-r--r--xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.cpp134
-rw-r--r--xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h108
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.cpp7
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.h7
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp21
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp99
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h20
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp19
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h18
-rw-r--r--xbmc/utils/CMakeLists.txt6
-rw-r--r--xbmc/utils/EGLFence.cpp69
-rw-r--r--xbmc/utils/EGLFence.h43
-rw-r--r--xbmc/windowing/gbm/DRMUtils.cpp72
-rw-r--r--xbmc/windowing/gbm/WinSystemGbm.cpp12
-rw-r--r--xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp2
21 files changed, 667 insertions, 265 deletions
diff --git a/cmake/treedata/optional/common/gbm.txt b/cmake/treedata/optional/common/gbm.txt
index 196b32357f..d6e6e9ebdc 100644
--- a/cmake/treedata/optional/common/gbm.txt
+++ b/cmake/treedata/optional/common/gbm.txt
@@ -1,2 +1,3 @@
xbmc/cores/RetroPlayer/process/gbm cores/RetroPlayer/process/gbm # GBM
+xbmc/cores/VideoPlayer/Process/gbm cores/VideoPlayer/Process/gbm # GBM
xbmc/windowing/gbm windowing/gbm # GBM \ No newline at end of file
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
index 382b163a71..48796e944b 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
@@ -10,6 +10,7 @@
#include "ServiceBroker.h"
#include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
+#include "cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
@@ -24,137 +25,6 @@ extern "C" {
using namespace KODI::WINDOWING::GBM;
-//------------------------------------------------------------------------------
-// Video Buffers
-//------------------------------------------------------------------------------
-
-CVideoBufferDRMPRIME::CVideoBufferDRMPRIME(IVideoBufferPool& pool, int id)
- : CVideoBuffer(id)
-{
- m_pFrame = av_frame_alloc();
-}
-
-CVideoBufferDRMPRIME::~CVideoBufferDRMPRIME()
-{
- Unref();
- av_frame_free(&m_pFrame);
-}
-
-void CVideoBufferDRMPRIME::SetRef(AVFrame* frame)
-{
- av_frame_move_ref(m_pFrame, frame);
-}
-
-void CVideoBufferDRMPRIME::Unref()
-{
- av_frame_unref(m_pFrame);
-}
-
-int CVideoBufferDRMPRIME::GetColorEncoding() const
-{
- switch (m_pFrame->colorspace)
- {
- case AVCOL_SPC_BT2020_CL:
- case AVCOL_SPC_BT2020_NCL:
- return DRM_COLOR_YCBCR_BT2020;
- case AVCOL_SPC_SMPTE170M:
- case AVCOL_SPC_BT470BG:
- case AVCOL_SPC_FCC:
- return DRM_COLOR_YCBCR_BT601;
- case AVCOL_SPC_BT709:
- return DRM_COLOR_YCBCR_BT709;
- case AVCOL_SPC_RESERVED:
- case AVCOL_SPC_UNSPECIFIED:
- default:
- if (m_pFrame->width > 1024 || m_pFrame->height >= 600)
- return DRM_COLOR_YCBCR_BT709;
- else
- return DRM_COLOR_YCBCR_BT601;
- }
-}
-
-int CVideoBufferDRMPRIME::GetColorRange() const
-{
- switch (m_pFrame->color_range)
- {
- case AVCOL_RANGE_JPEG:
- return DRM_COLOR_YCBCR_FULL_RANGE;
- case AVCOL_RANGE_MPEG:
- default:
- return DRM_COLOR_YCBCR_LIMITED_RANGE;
- }
-}
-
-//------------------------------------------------------------------------------
-
-class CVideoBufferPoolDRMPRIME
- : public IVideoBufferPool
-{
-public:
- ~CVideoBufferPoolDRMPRIME();
- void Return(int id) override;
- CVideoBuffer* Get() override;
-
-protected:
- CCriticalSection m_critSection;
- std::vector<CVideoBufferDRMPRIME*> m_all;
- std::deque<int> m_used;
- std::deque<int> m_free;
-};
-
-CVideoBufferPoolDRMPRIME::~CVideoBufferPoolDRMPRIME()
-{
- for (auto buf : m_all)
- delete buf;
-}
-
-CVideoBuffer* CVideoBufferPoolDRMPRIME::Get()
-{
- CSingleLock lock(m_critSection);
-
- CVideoBufferDRMPRIME* buf = nullptr;
- if (!m_free.empty())
- {
- int idx = m_free.front();
- m_free.pop_front();
- m_used.push_back(idx);
- buf = m_all[idx];
- }
- else
- {
- int id = m_all.size();
- buf = new CVideoBufferDRMPRIME(*this, id);
- m_all.push_back(buf);
- m_used.push_back(id);
- }
-
- buf->Acquire(GetPtr());
- return buf;
-}
-
-void CVideoBufferPoolDRMPRIME::Return(int id)
-{
- CSingleLock lock(m_critSection);
-
- m_all[id]->Unref();
- auto it = m_used.begin();
- while (it != m_used.end())
- {
- if (*it == id)
- {
- m_used.erase(it);
- break;
- }
- else
- ++it;
- }
- m_free.push_back(id);
-}
-
-//------------------------------------------------------------------------------
-// main class
-//------------------------------------------------------------------------------
-
CDVDVideoCodecDRMPRIME::CDVDVideoCodecDRMPRIME(CProcessInfo& processInfo)
: CDVDVideoCodec(processInfo)
{
@@ -220,11 +90,17 @@ static const AVCodec* FindDecoder(CDVDStreamInfo& hints)
return nullptr;
}
-static enum AVPixelFormat GetFormat(struct AVCodecContext* avctx, const enum AVPixelFormat* fmt)
+enum AVPixelFormat CDVDVideoCodecDRMPRIME::GetFormat(struct AVCodecContext* avctx, const enum AVPixelFormat* fmt)
{
for (int n = 0; fmt[n] != AV_PIX_FMT_NONE; n++)
+ {
if (fmt[n] == AV_PIX_FMT_DRM_PRIME)
+ {
+ CDVDVideoCodecDRMPRIME* ctx = static_cast<CDVDVideoCodecDRMPRIME*>(avctx->opaque);
+ ctx->UpdateProcessInfo(avctx, fmt[n]);
return fmt[n];
+ }
+ }
return AV_PIX_FMT_NONE;
}
@@ -259,6 +135,7 @@ bool CDVDVideoCodecDRMPRIME::Open(CDVDStreamInfo& hints, CDVDCodecOptions& optio
}
m_pCodecContext->pix_fmt = AV_PIX_FMT_DRM_PRIME;
+ m_pCodecContext->opaque = static_cast<void*>(this);
m_pCodecContext->get_format = GetFormat;
m_pCodecContext->codec_tag = hints.codec_tag;
m_pCodecContext->coded_width = hints.width;
@@ -281,27 +158,25 @@ bool CDVDVideoCodecDRMPRIME::Open(CDVDStreamInfo& hints, CDVDCodecOptions& optio
return false;
}
- if (m_pCodecContext->pix_fmt != AV_PIX_FMT_DRM_PRIME)
- {
- CLog::Log(LOGNOTICE, "CDVDVideoCodecDRMPRIME::%s - unexpected pix fmt %s", __FUNCTION__, av_get_pix_fmt_name(m_pCodecContext->pix_fmt));
- avcodec_free_context(&m_pCodecContext);
- return false;
- }
-
- const char* pixFmtName = av_get_pix_fmt_name(m_pCodecContext->pix_fmt);
- m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : "");
- m_processInfo.SetVideoDimensions(hints.width, hints.height);
+ UpdateProcessInfo(m_pCodecContext, m_pCodecContext->pix_fmt);
m_processInfo.SetVideoDeintMethod("none");
m_processInfo.SetVideoDAR(hints.aspect);
- if (pCodec->name)
- m_name = std::string("ff-") + pCodec->name;
+ return true;
+}
+
+void CDVDVideoCodecDRMPRIME::UpdateProcessInfo(struct AVCodecContext* avctx, const enum AVPixelFormat pix_fmt)
+{
+ const char* pixFmtName = av_get_pix_fmt_name(pix_fmt);
+ m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : "");
+ m_processInfo.SetVideoDimensions(avctx->coded_width, avctx->coded_height);
+
+ if (avctx->codec && avctx->codec->name)
+ m_name = std::string("ff-") + avctx->codec->name;
else
m_name = "ffmpeg";
- m_processInfo.SetVideoDecoderName(m_name, true);
-
- return true;
+ m_processInfo.SetVideoDecoderName(m_name, pix_fmt == AV_PIX_FMT_DRM_PRIME);
}
bool CDVDVideoCodecDRMPRIME::AddData(const DemuxPacket& packet)
@@ -412,9 +287,18 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::GetPicture(VideoPicture* pVideo
SetPictureParams(pVideoPicture);
- CVideoBufferDRMPRIME* buffer = dynamic_cast<CVideoBufferDRMPRIME*>(m_videoBufferPool->Get());
- buffer->SetRef(m_pFrame);
- pVideoPicture->videoBuffer = buffer;
+ if (m_pFrame->format == AV_PIX_FMT_DRM_PRIME)
+ {
+ CVideoBufferDRMPRIME* buffer = dynamic_cast<CVideoBufferDRMPRIME*>(m_videoBufferPool->Get());
+ buffer->SetRef(m_pFrame);
+ pVideoPicture->videoBuffer = buffer;
+ }
+
+ if (!pVideoPicture->videoBuffer)
+ {
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - videoBuffer:nullptr format:{}", __FUNCTION__, av_get_pix_fmt_name(static_cast<AVPixelFormat>(m_pFrame->format)));
+ return VC_ERROR;
+ }
return VC_PICTURE;
}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h
index cb2929e545..8d399eb5bc 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h
@@ -13,45 +13,6 @@
#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h"
#include "cores/VideoPlayer/Process/VideoBuffer.h"
-extern "C" {
-#include <libavutil/frame.h>
-#include <libavutil/hwcontext_drm.h>
-}
-
-// Color enums is copied from linux include/drm/drm_color_mgmt.h (strangely not part of uapi)
-enum drm_color_encoding {
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_BT709,
- DRM_COLOR_YCBCR_BT2020,
-};
-enum drm_color_range {
- DRM_COLOR_YCBCR_LIMITED_RANGE,
- DRM_COLOR_YCBCR_FULL_RANGE,
-};
-
-class CVideoBufferPoolDRMPRIME;
-
-class CVideoBufferDRMPRIME
- : public CVideoBuffer
-{
-public:
- CVideoBufferDRMPRIME(IVideoBufferPool& pool, int id);
- ~CVideoBufferDRMPRIME();
- void SetRef(AVFrame* frame);
- void Unref();
-
- uint32_t m_fb_id = 0;
- uint32_t m_handles[AV_DRM_MAX_PLANES] = {0};
-
- AVDRMFrameDescriptor* GetDescriptor() const { return reinterpret_cast<AVDRMFrameDescriptor*>(m_pFrame->data[0]); }
- uint32_t GetWidth() const { return m_pFrame->width; }
- uint32_t GetHeight() const { return m_pFrame->height; }
- int GetColorEncoding() const;
- int GetColorRange() const;
-protected:
- AVFrame* m_pFrame = nullptr;
-};
-
class CDVDVideoCodecDRMPRIME
: public CDVDVideoCodec
{
@@ -73,10 +34,12 @@ public:
protected:
void Drain();
void SetPictureParams(VideoPicture* pVideoPicture);
+ void UpdateProcessInfo(struct AVCodecContext* avctx, const enum AVPixelFormat fmt);
+ static enum AVPixelFormat GetFormat(struct AVCodecContext* avctx, const enum AVPixelFormat* fmt);
std::string m_name;
int m_codecControlFlags = 0;
AVCodecContext* m_pCodecContext = nullptr;
AVFrame* m_pFrame = nullptr;
- std::shared_ptr<CVideoBufferPoolDRMPRIME> m_videoBufferPool;
+ std::shared_ptr<IVideoBufferPool> m_videoBufferPool;
};
diff --git a/xbmc/cores/VideoPlayer/Process/gbm/CMakeLists.txt b/xbmc/cores/VideoPlayer/Process/gbm/CMakeLists.txt
new file mode 100644
index 0000000000..d1398d77a3
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/Process/gbm/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(SOURCES ProcessInfoGBM.cpp
+ VideoBufferDRMPRIME.cpp)
+
+set(HEADERS ProcessInfoGBM.h
+ VideoBufferDRMPRIME.h)
+
+core_add_library(processGBM)
diff --git a/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.cpp b/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.cpp
new file mode 100644
index 0000000000..0228319397
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 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 "ProcessInfoGBM.h"
+
+using namespace VIDEOPLAYER;
+
+CProcessInfo* CProcessInfoGBM::Create()
+{
+ return new CProcessInfoGBM();
+}
+
+void CProcessInfoGBM::Register()
+{
+ CProcessInfo::RegisterProcessControl("gbm", CProcessInfoGBM::Create);
+}
+
+CProcessInfoGBM::CProcessInfoGBM()
+{
+}
+
+EINTERLACEMETHOD CProcessInfoGBM::GetFallbackDeintMethod()
+{
+#if defined(__arm__)
+ return EINTERLACEMETHOD::VS_INTERLACEMETHOD_DEINTERLACE_HALF;
+#else
+ return CProcessInfo::GetFallbackDeintMethod();
+#endif
+}
diff --git a/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h b/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h
new file mode 100644
index 0000000000..479e4fde4c
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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 "cores/IPlayer.h"
+#include "cores/VideoPlayer/Process/ProcessInfo.h"
+
+namespace VIDEOPLAYER
+{
+
+class CProcessInfoGBM : public CProcessInfo
+{
+public:
+ CProcessInfoGBM();
+ static CProcessInfo* Create();
+ static void Register();
+ EINTERLACEMETHOD GetFallbackDeintMethod() override;
+};
+
+} // namespace VIDEOPLAYER
diff --git a/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.cpp b/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.cpp
new file mode 100644
index 0000000000..719f0185bc
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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 "VideoBufferDRMPRIME.h"
+
+#include "threads/SingleLock.h"
+
+extern "C"
+{
+#include <libavcodec/avcodec.h>
+#include <libavutil/pixdesc.h>
+}
+
+IVideoBufferDRMPRIME::IVideoBufferDRMPRIME(int id)
+ : CVideoBuffer(id)
+{
+}
+
+CVideoBufferDRMPRIME::CVideoBufferDRMPRIME(IVideoBufferPool& pool, int id)
+ : IVideoBufferDRMPRIME(id)
+{
+ m_pFrame = av_frame_alloc();
+}
+
+CVideoBufferDRMPRIME::~CVideoBufferDRMPRIME()
+{
+ Unref();
+ av_frame_free(&m_pFrame);
+}
+
+void CVideoBufferDRMPRIME::SetRef(AVFrame* frame)
+{
+ av_frame_move_ref(m_pFrame, frame);
+}
+
+void CVideoBufferDRMPRIME::Unref()
+{
+ av_frame_unref(m_pFrame);
+}
+
+int CVideoBufferDRMPRIME::GetColorEncoding() const
+{
+ switch (m_pFrame->colorspace)
+ {
+ case AVCOL_SPC_BT2020_CL:
+ case AVCOL_SPC_BT2020_NCL:
+ return DRM_COLOR_YCBCR_BT2020;
+ case AVCOL_SPC_SMPTE170M:
+ case AVCOL_SPC_BT470BG:
+ case AVCOL_SPC_FCC:
+ return DRM_COLOR_YCBCR_BT601;
+ case AVCOL_SPC_BT709:
+ return DRM_COLOR_YCBCR_BT709;
+ case AVCOL_SPC_RESERVED:
+ case AVCOL_SPC_UNSPECIFIED:
+ default:
+ if (m_pFrame->width > 1024 || m_pFrame->height >= 600)
+ return DRM_COLOR_YCBCR_BT709;
+ else
+ return DRM_COLOR_YCBCR_BT601;
+ }
+}
+
+int CVideoBufferDRMPRIME::GetColorRange() const
+{
+ switch (m_pFrame->color_range)
+ {
+ case AVCOL_RANGE_JPEG:
+ return DRM_COLOR_YCBCR_FULL_RANGE;
+ case AVCOL_RANGE_MPEG:
+ default:
+ return DRM_COLOR_YCBCR_LIMITED_RANGE;
+ }
+}
+
+bool CVideoBufferDRMPRIME::IsValid() const
+{
+ AVDRMFrameDescriptor* descriptor = GetDescriptor();
+ return descriptor && descriptor->nb_layers;
+}
+
+CVideoBufferPoolDRMPRIME::~CVideoBufferPoolDRMPRIME()
+{
+ for (auto buf : m_all)
+ delete buf;
+}
+
+CVideoBuffer* CVideoBufferPoolDRMPRIME::Get()
+{
+ CSingleLock lock(m_critSection);
+
+ CVideoBufferDRMPRIME* buf = nullptr;
+ if (!m_free.empty())
+ {
+ int idx = m_free.front();
+ m_free.pop_front();
+ m_used.push_back(idx);
+ buf = m_all[idx];
+ }
+ else
+ {
+ int id = m_all.size();
+ buf = new CVideoBufferDRMPRIME(*this, id);
+ m_all.push_back(buf);
+ m_used.push_back(id);
+ }
+
+ buf->Acquire(GetPtr());
+ return buf;
+}
+
+void CVideoBufferPoolDRMPRIME::Return(int id)
+{
+ CSingleLock lock(m_critSection);
+
+ m_all[id]->Unref();
+ auto it = m_used.begin();
+ while (it != m_used.end())
+ {
+ if (*it == id)
+ {
+ m_used.erase(it);
+ break;
+ }
+ else
+ ++it;
+ }
+ m_free.push_back(id);
+}
diff --git a/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h b/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h
new file mode 100644
index 0000000000..643395a681
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "cores/VideoPlayer/Process/VideoBuffer.h"
+
+extern "C"
+{
+#include <libavutil/frame.h>
+#include <libavutil/hwcontext_drm.h>
+}
+
+// Color enums is copied from linux include/drm/drm_color_mgmt.h (strangely not part of uapi)
+enum drm_color_encoding
+{
+ DRM_COLOR_YCBCR_BT601,
+ DRM_COLOR_YCBCR_BT709,
+ DRM_COLOR_YCBCR_BT2020,
+};
+enum drm_color_range
+{
+ DRM_COLOR_YCBCR_LIMITED_RANGE,
+ DRM_COLOR_YCBCR_FULL_RANGE,
+};
+
+class IVideoBufferDRMPRIME : public CVideoBuffer
+{
+public:
+ IVideoBufferDRMPRIME() = delete;
+ virtual ~IVideoBufferDRMPRIME() = default;
+
+ virtual AVDRMFrameDescriptor* GetDescriptor() const = 0;
+ virtual uint32_t GetWidth() const = 0;
+ virtual uint32_t GetHeight() const = 0;
+ virtual int GetColorEncoding() const
+ {
+ return DRM_COLOR_YCBCR_BT709;
+ };
+ virtual int GetColorRange() const
+ {
+ return DRM_COLOR_YCBCR_LIMITED_RANGE;
+ };
+
+ virtual bool IsValid() const
+ {
+ return true;
+ };
+ virtual bool Map()
+ {
+ return true;
+ };
+ virtual void Unmap() {};
+
+ uint32_t m_fb_id = 0;
+ uint32_t m_handles[AV_DRM_MAX_PLANES] = {};
+
+protected:
+ explicit IVideoBufferDRMPRIME(int id);
+};
+
+class CVideoBufferDRMPRIME : public IVideoBufferDRMPRIME
+{
+public:
+ CVideoBufferDRMPRIME(IVideoBufferPool& pool, int id);
+ ~CVideoBufferDRMPRIME();
+ void SetRef(AVFrame* frame);
+ void Unref();
+
+ AVDRMFrameDescriptor* GetDescriptor() const override
+ {
+ return reinterpret_cast<AVDRMFrameDescriptor*>(m_pFrame->data[0]);
+ }
+ uint32_t GetWidth() const override
+ {
+ return m_pFrame->width;
+ }
+ uint32_t GetHeight() const override
+ {
+ return m_pFrame->height;
+ }
+ int GetColorEncoding() const override;
+ int GetColorRange() const override;
+
+ bool IsValid() const override;
+
+protected:
+ AVFrame* m_pFrame = nullptr;
+};
+
+class CVideoBufferPoolDRMPRIME : public IVideoBufferPool
+{
+public:
+ ~CVideoBufferPoolDRMPRIME();
+ void Return(int id) override;
+ CVideoBuffer* Get() override;
+
+protected:
+ CCriticalSection m_critSection;
+ std::vector<CVideoBufferDRMPRIME*> m_all;
+ std::deque<int> m_used;
+ std::deque<int> m_free;
+};
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.cpp
index 91809f8ebe..17dd7e1e19 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.cpp
@@ -15,11 +15,14 @@ void CDRMPRIMETexture::Init(EGLDisplay eglDisplay)
m_eglImage.reset(new CEGLImage(eglDisplay));
}
-bool CDRMPRIMETexture::Map(CVideoBufferDRMPRIME *buffer)
+bool CDRMPRIMETexture::Map(IVideoBufferDRMPRIME* buffer)
{
if (m_primebuffer)
return true;
+ if (!buffer->Map())
+ return false;
+
m_texWidth = buffer->GetWidth();
m_texHeight = buffer->GetHeight();
@@ -74,6 +77,8 @@ void CDRMPRIMETexture::Unmap()
glDeleteTextures(1, &m_texture);
+ m_primebuffer->Unmap();
+
m_primebuffer->Release();
m_primebuffer = nullptr;
}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.h
index abc4890acb..55cb2be330 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DRMPRIMEEGL.h
@@ -8,15 +8,16 @@
#pragma once
-#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h"
+#include "cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h"
#include "utils/EGLImage.h"
+#include "utils/Geometry.h"
#include "system_gl.h"
class CDRMPRIMETexture
{
public:
- bool Map(CVideoBufferDRMPRIME *buffer);
+ bool Map(IVideoBufferDRMPRIME* buffer);
void Unmap();
void Init(EGLDisplay eglDisplay);
@@ -24,7 +25,7 @@ public:
CSizeInt GetTextureSize() { return { m_texWidth, m_texHeight }; }
protected:
- CVideoBufferDRMPRIME *m_primebuffer{nullptr};
+ IVideoBufferDRMPRIME* m_primebuffer{nullptr};
std::unique_ptr<CEGLImage> m_eglImage;
const GLenum m_textureTarget{GL_TEXTURE_EXTERNAL_OES};
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp
index 295b269c82..df0fb6fd9c 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp
@@ -8,20 +8,21 @@
#include "RendererDRMPRIME.h"
-#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h"
+#include "ServiceBroker.h"
+#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h"
+#include "cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h"
#include "cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h"
#include "cores/VideoPlayer/VideoRenderers/RenderCapture.h"
#include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
#include "cores/VideoPlayer/VideoRenderers/RenderFlags.h"
-#include "settings/lib/Setting.h"
#include "settings/DisplaySettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
+#include "settings/lib/Setting.h"
#include "utils/log.h"
+#include "windowing/GraphicContext.h"
#include "windowing/gbm/DRMAtomic.h"
#include "windowing/gbm/WinSystemGbm.h"
-#include "windowing/GraphicContext.h"
-#include "ServiceBroker.h"
using namespace KODI::WINDOWING::GBM;
@@ -34,7 +35,7 @@ CRendererDRMPRIME::~CRendererDRMPRIME()
CBaseRenderer* CRendererDRMPRIME::Create(CVideoBuffer* buffer)
{
- if (buffer && dynamic_cast<CVideoBufferDRMPRIME*>(buffer) &&
+ if (buffer && dynamic_cast<IVideoBufferDRMPRIME*>(buffer) &&
CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(SETTING_VIDEOPLAYER_USEPRIMERENDERER) == 0)
{
CWinSystemGbm* winSystem = dynamic_cast<CWinSystemGbm*>(CServiceBroker::GetWinSystem());
@@ -132,7 +133,7 @@ bool CRendererDRMPRIME::NeedBuffer(int index)
if (m_iLastRenderBuffer == index)
return true;
- CVideoBufferDRMPRIME* buffer = dynamic_cast<CVideoBufferDRMPRIME*>(m_buffers[index].videoBuffer);
+ IVideoBufferDRMPRIME* buffer = dynamic_cast<IVideoBufferDRMPRIME*>(m_buffers[index].videoBuffer);
if (buffer && buffer->m_fb_id)
return true;
@@ -162,12 +163,8 @@ void CRendererDRMPRIME::RenderUpdate(int index, int index2, bool clear, unsigned
return;
}
- CVideoBufferDRMPRIME* buffer = dynamic_cast<CVideoBufferDRMPRIME*>(m_buffers[index].videoBuffer);
- if (!buffer)
- return;
-
- AVDRMFrameDescriptor* descriptor = buffer->GetDescriptor();
- if (!descriptor || !descriptor->nb_layers)
+ IVideoBufferDRMPRIME* buffer = dynamic_cast<IVideoBufferDRMPRIME*>(m_buffers[index].videoBuffer);
+ if (!buffer || !buffer->IsValid())
return;
if (!m_videoLayerBridge)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp
index 330823196f..bbe8409cba 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp
@@ -10,10 +10,12 @@
#include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
#include "ServiceBroker.h"
+#include "utils/EGLFence.h"
#include "utils/log.h"
#include "windowing/gbm/WinSystemGbmGLESContext.h"
using namespace KODI::WINDOWING::GBM;
+using namespace KODI::UTILS::EGL;
CRendererDRMPRIMEGLES::~CRendererDRMPRIMEGLES()
{
@@ -23,7 +25,7 @@ CRendererDRMPRIMEGLES::~CRendererDRMPRIMEGLES()
CBaseRenderer* CRendererDRMPRIMEGLES::Create(CVideoBuffer* buffer)
{
- if (buffer && dynamic_cast<CVideoBufferDRMPRIME*>(buffer))
+ if (buffer && dynamic_cast<IVideoBufferDRMPRIME*>(buffer))
return new CRendererDRMPRIMEGLES();
return nullptr;
@@ -43,15 +45,27 @@ bool CRendererDRMPRIMEGLES::Configure(const VideoPicture &picture, float fps, un
for (auto &texture : m_DRMPRIMETextures)
texture.Init(winSystem->GetEGLDisplay());
+ for (auto& fence : m_fences)
+ {
+ fence.reset(new CEGLFence(winSystem->GetEGLDisplay()));
+ }
+
return CLinuxRendererGLES::Configure(picture, fps, orientation);
}
void CRendererDRMPRIMEGLES::ReleaseBuffer(int index)
{
+ m_fences[index]->DestroyFence();
+
m_DRMPRIMETextures[index].Unmap();
CLinuxRendererGLES::ReleaseBuffer(index);
}
+bool CRendererDRMPRIMEGLES::NeedBuffer(int index)
+{
+ return !m_fences[index]->IsSignaled();
+}
+
bool CRendererDRMPRIMEGLES::CreateTexture(int index)
{
CPictureBuffer &buf = m_buffers[index];
@@ -85,9 +99,9 @@ bool CRendererDRMPRIMEGLES::UploadTexture(int index)
{
CPictureBuffer &buf = m_buffers[index];
- CVideoBufferDRMPRIME *buffer = dynamic_cast<CVideoBufferDRMPRIME*>(buf.videoBuffer);
+ IVideoBufferDRMPRIME* buffer = dynamic_cast<IVideoBufferDRMPRIME*>(buf.videoBuffer);
- if (!buffer)
+ if (!buffer || !buffer->IsValid())
{
CLog::Log(LOGNOTICE, "CRendererDRMPRIMEGLES::%s - no buffer", __FUNCTION__);
return false;
@@ -139,28 +153,44 @@ bool CRendererDRMPRIMEGLES::RenderHook(int index)
{
float x, y, z;
float u1, v1;
- } vertex[4];
+ };
+
+ std::array<PackedVertex, 4> vertex;
GLint vertLoc = renderSystem->GUIShaderGetPos();
GLint loc = renderSystem->GUIShaderGetCoord0();
- for (unsigned int i = 0; i < 4; i++)
- {
- // Setup vertex position values
- vertex[i].x = m_rotatedDestCoords[i].x;
- vertex[i].y = m_rotatedDestCoords[i].y;
- vertex[i].z = 0.0f;
- }
-
- // Setup texture coordinates
- vertex[0].u1 = vertex[3].u1 = plane.rect.x1;
- vertex[0].v1 = vertex[1].v1 = plane.rect.y1;
- vertex[1].u1 = vertex[2].u1 = plane.rect.x2;
- vertex[2].v1 = vertex[3].v1 = plane.rect.y2;
+ // top left
+ vertex[0].x = m_rotatedDestCoords[0].x;
+ vertex[0].y = m_rotatedDestCoords[0].y;
+ vertex[0].z = 0.0f;
+ vertex[0].u1 = plane.rect.x1;
+ vertex[0].v1 = plane.rect.y1;
+
+ // top right
+ vertex[1].x = m_rotatedDestCoords[1].x;
+ vertex[1].y = m_rotatedDestCoords[1].y;
+ vertex[1].z = 0.0f;
+ vertex[1].u1 = plane.rect.x2;
+ vertex[1].v1 = plane.rect.y1;
+
+ // bottom right
+ vertex[2].x = m_rotatedDestCoords[2].x;
+ vertex[2].y = m_rotatedDestCoords[2].y;
+ vertex[2].z = 0.0f;
+ vertex[2].u1 = plane.rect.x2;
+ vertex[2].v1 = plane.rect.y2;
+
+ // bottom left
+ vertex[3].x = m_rotatedDestCoords[3].x;
+ vertex[3].y = m_rotatedDestCoords[3].y;
+ vertex[3].z = 0.0f;
+ vertex[3].u1 = plane.rect.x1;
+ vertex[3].v1 = plane.rect.y2;;
glGenBuffers(1, &vertexVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*4, &vertex[0], GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex) * vertex.size(), vertex.data(), GL_STATIC_DRAW);
glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x)));
glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1)));
@@ -170,7 +200,7 @@ bool CRendererDRMPRIMEGLES::RenderHook(int index)
glGenBuffers(1, &indexVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte)*4, idx, GL_STATIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * 4, idx, GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0);
@@ -188,3 +218,34 @@ bool CRendererDRMPRIMEGLES::RenderHook(int index)
return true;
}
+
+void CRendererDRMPRIMEGLES::AfterRenderHook(int index)
+{
+ m_fences[index]->CreateFence();
+}
+
+bool CRendererDRMPRIMEGLES::Supports(ERENDERFEATURE feature)
+{
+ switch (feature)
+ {
+ case RENDERFEATURE_STRETCH:
+ case RENDERFEATURE_ZOOM:
+ case RENDERFEATURE_VERTICAL_SHIFT:
+ case RENDERFEATURE_PIXEL_RATIO:
+ case RENDERFEATURE_ROTATION:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool CRendererDRMPRIMEGLES::Supports(ESCALINGMETHOD method)
+{
+ switch (method)
+ {
+ case VS_SCALINGMETHOD_LINEAR:
+ return true;
+ default:
+ return false;
+ }
+}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h
index f879b6cf5a..e6ef033982 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h
@@ -11,6 +11,20 @@
#include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h"
#include "DRMPRIMEEGL.h"
+#include <array>
+#include <memory>
+
+namespace KODI
+{
+namespace UTILS
+{
+namespace EGL
+{
+class CEGLFence;
+}
+}
+}
+
class CRendererDRMPRIMEGLES : public CLinuxRendererGLES
{
public:
@@ -24,14 +38,20 @@ public:
// CLinuxRendererGLES overrides
bool Configure(const VideoPicture &picture, float fps, unsigned int orientation) override;
void ReleaseBuffer(int index) override;
+ bool NeedBuffer(int index) override;
+
+ bool Supports(ERENDERFEATURE feature) override;
+ bool Supports(ESCALINGMETHOD method) override;
protected:
// CLinuxRendererGLES overrides
bool LoadShadersHook() override;
bool RenderHook(int index) override;
+ void AfterRenderHook(int index) override;
bool UploadTexture(int index) override;
void DeleteTexture(int index) override;
bool CreateTexture(int index) override;
+ std::array<std::unique_ptr<KODI::UTILS::EGL::CEGLFence>, NUM_BUFFERS> m_fences;
CDRMPRIMETexture m_DRMPRIMETextures[NUM_BUFFERS];
};
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp
index 1e7acae2c1..3277d3667c 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp
@@ -8,7 +8,7 @@
#include "VideoLayerBridgeDRMPRIME.h"
-#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h"
+#include "cores/VideoPlayer/Process/gbm/VideoBufferDRMPRIME.h"
#include "utils/log.h"
#include "windowing/gbm/DRMUtils.h"
@@ -33,7 +33,7 @@ void CVideoLayerBridgeDRMPRIME::Disable()
m_DRM->AddProperty(plane, "CRTC_ID", 0);
}
-void CVideoLayerBridgeDRMPRIME::Acquire(CVideoBufferDRMPRIME* buffer)
+void CVideoLayerBridgeDRMPRIME::Acquire(IVideoBufferDRMPRIME* buffer)
{
// release the buffer that is no longer presented on screen
Release(m_prev_buffer);
@@ -46,7 +46,7 @@ void CVideoLayerBridgeDRMPRIME::Acquire(CVideoBufferDRMPRIME* buffer)
m_buffer->Acquire();
}
-void CVideoLayerBridgeDRMPRIME::Release(CVideoBufferDRMPRIME* buffer)
+void CVideoLayerBridgeDRMPRIME::Release(IVideoBufferDRMPRIME* buffer)
{
if (!buffer)
return;
@@ -55,11 +55,14 @@ void CVideoLayerBridgeDRMPRIME::Release(CVideoBufferDRMPRIME* buffer)
buffer->Release();
}
-bool CVideoLayerBridgeDRMPRIME::Map(CVideoBufferDRMPRIME* buffer)
+bool CVideoLayerBridgeDRMPRIME::Map(IVideoBufferDRMPRIME* buffer)
{
if (buffer->m_fb_id)
return true;
+ if (!buffer->Map())
+ return false;
+
AVDRMFrameDescriptor* descriptor = buffer->GetDescriptor();
uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}, flags = 0;
uint64_t modifier[4] = {0};
@@ -108,7 +111,7 @@ bool CVideoLayerBridgeDRMPRIME::Map(CVideoBufferDRMPRIME* buffer)
return true;
}
-void CVideoLayerBridgeDRMPRIME::Unmap(CVideoBufferDRMPRIME* buffer)
+void CVideoLayerBridgeDRMPRIME::Unmap(IVideoBufferDRMPRIME* buffer)
{
if (buffer->m_fb_id)
{
@@ -125,9 +128,11 @@ void CVideoLayerBridgeDRMPRIME::Unmap(CVideoBufferDRMPRIME* buffer)
buffer->m_handles[i] = 0;
}
}
+
+ buffer->Unmap();
}
-void CVideoLayerBridgeDRMPRIME::Configure(CVideoBufferDRMPRIME* buffer)
+void CVideoLayerBridgeDRMPRIME::Configure(IVideoBufferDRMPRIME* buffer)
{
struct plane* plane = m_DRM->GetVideoPlane();
if (m_DRM->SupportsProperty(plane, "COLOR_ENCODING") &&
@@ -138,7 +143,7 @@ void CVideoLayerBridgeDRMPRIME::Configure(CVideoBufferDRMPRIME* buffer)
}
}
-void CVideoLayerBridgeDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect)
+void CVideoLayerBridgeDRMPRIME::SetVideoPlane(IVideoBufferDRMPRIME* buffer, const CRect& destRect)
{
if (!Map(buffer))
{
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h
index b29488b1a3..ade17ac0c3 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.h
@@ -24,7 +24,7 @@ namespace GBM
}
}
-class CVideoBufferDRMPRIME;
+class IVideoBufferDRMPRIME;
class CVideoLayerBridgeDRMPRIME
: public KODI::WINDOWING::GBM::CVideoLayerBridge
@@ -34,19 +34,19 @@ public:
~CVideoLayerBridgeDRMPRIME();
void Disable() override;
- virtual void Configure(CVideoBufferDRMPRIME* buffer);
- virtual void SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect);
+ virtual void Configure(IVideoBufferDRMPRIME* buffer);
+ virtual void SetVideoPlane(IVideoBufferDRMPRIME* buffer, const CRect& destRect);
virtual void UpdateVideoPlane();
protected:
std::shared_ptr<KODI::WINDOWING::GBM::CDRMUtils> m_DRM;
private:
- void Acquire(CVideoBufferDRMPRIME* buffer);
- void Release(CVideoBufferDRMPRIME* buffer);
- bool Map(CVideoBufferDRMPRIME* buffer);
- void Unmap(CVideoBufferDRMPRIME* buffer);
+ void Acquire(IVideoBufferDRMPRIME* buffer);
+ void Release(IVideoBufferDRMPRIME* buffer);
+ bool Map(IVideoBufferDRMPRIME* buffer);
+ void Unmap(IVideoBufferDRMPRIME* buffer);
- CVideoBufferDRMPRIME* m_buffer = nullptr;
- CVideoBufferDRMPRIME* m_prev_buffer = nullptr;
+ IVideoBufferDRMPRIME* m_buffer = nullptr;
+ IVideoBufferDRMPRIME* m_prev_buffer = nullptr;
};
diff --git a/xbmc/utils/CMakeLists.txt b/xbmc/utils/CMakeLists.txt
index f0ce99014b..6dbee35a1a 100644
--- a/xbmc/utils/CMakeLists.txt
+++ b/xbmc/utils/CMakeLists.txt
@@ -169,8 +169,10 @@ if(XSLT_FOUND)
list(APPEND HEADERS XSLTUtils.h)
endif()
if(EGL_FOUND)
- list(APPEND SOURCES EGLUtils.cpp)
- list(APPEND HEADERS EGLUtils.h)
+ list(APPEND SOURCES EGLUtils.cpp
+ EGLFence.cpp)
+ list(APPEND HEADERS EGLUtils.h
+ EGLFence.h)
endif()
# The large map trips the clang optimizer
diff --git a/xbmc/utils/EGLFence.cpp b/xbmc/utils/EGLFence.cpp
new file mode 100644
index 0000000000..bc9f35e173
--- /dev/null
+++ b/xbmc/utils/EGLFence.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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 "EGLFence.h"
+
+#include "EGLUtils.h"
+
+using namespace KODI::UTILS::EGL;
+
+CEGLFence::CEGLFence(EGLDisplay display) :
+ m_display(display)
+{
+ m_eglCreateSyncKHR = CEGLUtils::GetRequiredProcAddress<PFNEGLCREATESYNCKHRPROC>("eglCreateSyncKHR");
+ m_eglDestroySyncKHR = CEGLUtils::GetRequiredProcAddress<PFNEGLDESTROYSYNCKHRPROC>("eglDestroySyncKHR");
+ m_eglGetSyncAttribKHR = CEGLUtils::GetRequiredProcAddress<PFNEGLGETSYNCATTRIBKHRPROC>("eglGetSyncAttribKHR");
+}
+
+void CEGLFence::CreateFence()
+{
+ m_fence = m_eglCreateSyncKHR(m_display, EGL_SYNC_FENCE_KHR, nullptr);
+ if (m_fence == EGL_NO_SYNC_KHR)
+ {
+ CEGLUtils::LogError("failed to create egl sync fence");
+ throw std::runtime_error("failed to create egl sync fence");
+ }
+}
+
+void CEGLFence::DestroyFence()
+{
+ if (m_fence == EGL_NO_SYNC_KHR)
+ {
+ return;
+ }
+
+ if (m_eglDestroySyncKHR(m_display, m_fence) != EGL_TRUE)
+ {
+ CEGLUtils::LogError("failed to destroy egl sync fence");
+ }
+
+ m_fence = EGL_NO_SYNC_KHR;
+}
+
+bool CEGLFence::IsSignaled()
+{
+ // fence has been destroyed so return true immediately so buffer can be used
+ if (m_fence == EGL_NO_SYNC_KHR)
+ {
+ return true;
+ }
+
+ EGLint status = EGL_UNSIGNALED_KHR;
+ if (m_eglGetSyncAttribKHR(m_display, m_fence, EGL_SYNC_STATUS_KHR, &status) != EGL_TRUE)
+ {
+ CEGLUtils::LogError("failed to query egl sync fence");
+ return false;
+ }
+
+ if (status == EGL_SIGNALED_KHR)
+ {
+ return true;
+ }
+
+ return false;
+}
diff --git a/xbmc/utils/EGLFence.h b/xbmc/utils/EGLFence.h
new file mode 100644
index 0000000000..1664772ef0
--- /dev/null
+++ b/xbmc/utils/EGLFence.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+namespace KODI
+{
+namespace UTILS
+{
+namespace EGL
+{
+
+class CEGLFence
+{
+public:
+ explicit CEGLFence(EGLDisplay display);
+ CEGLFence(CEGLFence const& other) = delete;
+ CEGLFence& operator=(CEGLFence const& other) = delete;
+
+ void CreateFence();
+ void DestroyFence();
+ bool IsSignaled();
+
+private:
+ EGLDisplay m_display{nullptr};
+ EGLSyncKHR m_fence{nullptr};
+
+ PFNEGLCREATESYNCKHRPROC m_eglCreateSyncKHR{nullptr};
+ PFNEGLDESTROYSYNCKHRPROC m_eglDestroySyncKHR{nullptr};
+ PFNEGLGETSYNCATTRIBKHRPROC m_eglGetSyncAttribKHR{nullptr};
+};
+
+}
+}
+}
diff --git a/xbmc/windowing/gbm/DRMUtils.cpp b/xbmc/windowing/gbm/DRMUtils.cpp
index df46ad4bdc..48f0bc40bc 100644
--- a/xbmc/windowing/gbm/DRMUtils.cpp
+++ b/xbmc/windowing/gbm/DRMUtils.cpp
@@ -109,27 +109,43 @@ drm_fb * CDRMUtils::DrmFbGetFromBo(struct gbm_bo *bo)
memset(offsets, 0, 16);
#endif
- if (modifiers[0] == DRM_FORMAT_MOD_INVALID)
- modifiers[0] = DRM_FORMAT_MOD_LINEAR;
-
- CLog::Log(LOGDEBUG, "CDRMUtils::%s - using modifier: %lli", __FUNCTION__, modifiers[0]);
-
- auto ret = drmModeAddFB2WithModifiers(m_fd,
- width,
- height,
- fb->format,
- handles,
- strides,
- offsets,
- modifiers,
- &fb->fb_id,
- (modifiers[0] > 0) ? DRM_MODE_FB_MODIFIERS : 0);
+ uint32_t flags = 0;
- if(ret)
+ if (modifiers[0] && modifiers[0] != DRM_FORMAT_MOD_INVALID)
+ {
+ flags |= DRM_MODE_FB_MODIFIERS;
+ CLog::Log(LOGDEBUG, "CDRMUtils::{} - using modifier: {:#x}", __FUNCTION__, modifiers[0]);
+ }
+
+ int ret = drmModeAddFB2WithModifiers(m_fd,
+ width,
+ height,
+ fb->format,
+ handles,
+ strides,
+ offsets,
+ modifiers,
+ &fb->fb_id,
+ flags);
+
+ if(ret < 0)
{
- delete (fb);
- CLog::Log(LOGDEBUG, "CDRMUtils::%s - failed to add framebuffer", __FUNCTION__);
- return nullptr;
+ ret = drmModeAddFB2(m_fd,
+ width,
+ height,
+ fb->format,
+ handles,
+ strides,
+ offsets,
+ &fb->fb_id,
+ flags);
+
+ if (ret < 0)
+ {
+ delete (fb);
+ CLog::Log(LOGDEBUG, "CDRMUtils::{} - failed to add framebuffer: {} ({})", __FUNCTION__, strerror(errno), errno);
+ return nullptr;
+ }
}
gbm_bo_set_user_data(bo, fb, DrmFbDestroyCallback);
@@ -579,9 +595,25 @@ bool CDRMUtils::InitDrm()
auto ret = drmSetClientCap(m_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
if (ret)
{
- CLog::Log(LOGERROR, "CDRMUtils::%s - failed to set Universal planes capability: %s", __FUNCTION__, strerror(errno));
+ CLog::Log(LOGERROR, "CDRMUtils::{} - failed to set universal planes capability: {}", __FUNCTION__, strerror(errno));
+ return false;
+ }
+
+ ret = drmSetClientCap(m_fd, DRM_CLIENT_CAP_STEREO_3D, 1);
+ if (ret)
+ {
+ CLog::Log(LOGERROR, "CDRMUtils::{} - failed to set stereo 3d capability: {}", __FUNCTION__, strerror(errno));
+ return false;
+ }
+
+#if defined(DRM_CLIENT_CAP_ASPECT_RATIO)
+ ret = drmSetClientCap(m_fd, DRM_CLIENT_CAP_ASPECT_RATIO, 0);
+ if (ret)
+ {
+ CLog::Log(LOGERROR, "CDRMUtils::{} - failed to unset aspect ratio capability: {}", __FUNCTION__, strerror(errno));
return false;
}
+#endif
if(!GetResources())
{
diff --git a/xbmc/windowing/gbm/WinSystemGbm.cpp b/xbmc/windowing/gbm/WinSystemGbm.cpp
index 4a3291a550..5cee802be2 100644
--- a/xbmc/windowing/gbm/WinSystemGbm.cpp
+++ b/xbmc/windowing/gbm/WinSystemGbm.cpp
@@ -207,11 +207,19 @@ void CWinSystemGbm::FlipPage(bool rendered, bool videoLayer)
m_videoLayerBridge->Disable();
}
- struct gbm_bo *bo = m_GBM->LockFrontBuffer();
+ struct gbm_bo *bo = nullptr;
+
+ if (rendered)
+ {
+ bo = m_GBM->LockFrontBuffer();
+ }
m_DRM->FlipPage(bo, rendered, videoLayer);
- m_GBM->ReleaseBuffer();
+ if (rendered)
+ {
+ m_GBM->ReleaseBuffer();
+ }
if (m_videoLayerBridge && !videoLayer)
{
diff --git a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp
index c24cb919ae..f763577117 100644
--- a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp
+++ b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp
@@ -14,6 +14,7 @@
#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererGBM.h"
#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h"
#include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
+#include "cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h"
#include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h"
#include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
@@ -65,6 +66,7 @@ bool CWinSystemGbmGLESContext::InitWindowSystem()
CRendererDRMPRIMEGLES::Register();
CRendererDRMPRIME::Register();
CDVDVideoCodecDRMPRIME::Register();
+ VIDEOPLAYER::CProcessInfoGBM::Register();
return true;
}