aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h2
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h2
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp11
-rw-r--r--xbmc/windowing/gbm/drm/DRMObject.cpp30
-rw-r--r--xbmc/windowing/gbm/drm/DRMObject.h3
-rw-r--r--xbmc/windowing/gbm/drm/DRMUtils.cpp169
-rw-r--r--xbmc/windowing/gbm/drm/DRMUtils.h5
10 files changed, 163 insertions, 65 deletions
diff --git a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h
index b83ee8ca68..dca6e82177 100644
--- a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h
+++ b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h
@@ -54,6 +54,8 @@ public:
virtual const VideoPicture& GetPicture() const { return m_picture; }
virtual uint32_t GetWidth() const { return GetPicture().iWidth; }
virtual uint32_t GetHeight() const { return GetPicture().iHeight; }
+ virtual uint32_t GetXOffset() const { return GetPicture().m_xOffset; }
+ virtual uint32_t GetYOffset() const { return GetPicture().m_yOffset; }
virtual AVDRMFrameDescriptor* GetDescriptor() const = 0;
virtual bool IsValid() const { return true; }
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.cpp
index 495d6a25f5..a5468d12a0 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.cpp
@@ -58,6 +58,8 @@ void VideoPicture::Reset()
iWidth = 0;
iHeight = 0;
+ m_xOffset = 0;
+ m_yOffset = 0;
iDisplayWidth = 0;
iDisplayHeight = 0;
}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h
index ca83b1a04f..f3373612e8 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h
@@ -75,6 +75,8 @@ public:
unsigned int iWidth;
unsigned int iHeight;
+ unsigned int m_xOffset{0};
+ unsigned int m_yOffset{0};
unsigned int iDisplayWidth; //< width of the picture without black bars
unsigned int iDisplayHeight; //< height of the picture without black bars
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
index eb2943bb8c..0d407043dd 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
@@ -505,6 +505,8 @@ void CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture)
{
pVideoPicture->iWidth = m_pFrame->width;
pVideoPicture->iHeight = m_pFrame->height;
+ pVideoPicture->m_xOffset = m_pFrame->crop_left;
+ pVideoPicture->m_yOffset = m_pFrame->crop_top;
double aspect_ratio = 0;
AVRational pixel_aspect = m_pFrame->sample_aspect_ratio;
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp
index 66df0e49c7..2ef7f4d521 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.cpp
@@ -77,7 +77,7 @@ CBaseRenderer* CRendererDRMPRIME::Create(CVideoBuffer* buffer)
if (!plane)
return nullptr;
- if (!plane->SupportsFormatAndModifier(format, modifier))
+ if (!drm->FindVideoPlane(format, modifier))
return nullptr;
return new CRendererDRMPRIME();
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp
index 34d1ab6235..33db29b140 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/VideoLayerBridgeDRMPRIME.cpp
@@ -118,9 +118,10 @@ bool CVideoLayerBridgeDRMPRIME::Map(CVideoBufferDRMPRIME* buffer)
flags = DRM_MODE_FB_MODIFIERS;
// add the video frame FB
- ret = drmModeAddFB2WithModifiers(m_DRM->GetFileDescriptor(), buffer->GetWidth(),
- buffer->GetHeight(), layer->format, handles, pitches, offsets,
- modifier, &buffer->m_fb_id, flags);
+ ret = drmModeAddFB2WithModifiers(m_DRM->GetFileDescriptor(),
+ buffer->GetWidth() + buffer->GetXOffset(),
+ buffer->GetHeight() + buffer->GetYOffset(), layer->format,
+ handles, pitches, offsets, modifier, &buffer->m_fb_id, flags);
if (ret < 0)
{
CLog::Log(LOGERROR, "CVideoLayerBridgeDRMPRIME::{} - failed to add fb {}, ret = {}",
@@ -188,8 +189,8 @@ void CVideoLayerBridgeDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer, cons
auto plane = m_DRM->GetVideoPlane();
m_DRM->AddProperty(plane, "FB_ID", buffer->m_fb_id);
m_DRM->AddProperty(plane, "CRTC_ID", m_DRM->GetCrtc()->GetCrtcId());
- m_DRM->AddProperty(plane, "SRC_X", 0);
- m_DRM->AddProperty(plane, "SRC_Y", 0);
+ m_DRM->AddProperty(plane, "SRC_X", buffer->GetXOffset() << 16);
+ m_DRM->AddProperty(plane, "SRC_Y", buffer->GetYOffset() << 16);
m_DRM->AddProperty(plane, "SRC_W", buffer->GetWidth() << 16);
m_DRM->AddProperty(plane, "SRC_H", buffer->GetHeight() << 16);
m_DRM->AddProperty(plane, "CRTC_X", static_cast<int32_t>(destRect.x1) & ~1);
diff --git a/xbmc/windowing/gbm/drm/DRMObject.cpp b/xbmc/windowing/gbm/drm/DRMObject.cpp
index 5ffce40fa3..99dda24490 100644
--- a/xbmc/windowing/gbm/drm/DRMObject.cpp
+++ b/xbmc/windowing/gbm/drm/DRMObject.cpp
@@ -105,6 +105,25 @@ std::optional<uint64_t> CDRMObject::GetPropertyValue(std::string_view name,
return {};
}
+std::optional<std::span<uint64_t, 2>> CDRMObject::GetRangePropertyLimits(std::string_view name)
+{
+ auto property = std::find_if(m_propsInfo.begin(), m_propsInfo.end(),
+ [&name](const auto& prop) { return prop->name == name; });
+
+ if (property == m_propsInfo.end())
+ return {};
+
+ auto prop = property->get();
+
+ if (!static_cast<bool>(drm_property_type_is(prop, DRM_MODE_PROP_RANGE)))
+ return {};
+
+ if (prop->count_values != 2)
+ return {};
+
+ return std::make_optional<std::span<uint64_t, 2>>(prop->values, 2);
+}
+
bool CDRMObject::SetProperty(const std::string& name, uint64_t value)
{
auto property = std::find_if(m_propsInfo.begin(), m_propsInfo.end(),
@@ -130,3 +149,14 @@ bool CDRMObject::SupportsProperty(const std::string& name)
return false;
}
+
+std::optional<bool> CDRMObject::IsPropertyImmutable(std::string_view name)
+{
+ auto property = std::find_if(m_propsInfo.begin(), m_propsInfo.end(),
+ [&name](const auto& prop) { return prop->name == name; });
+
+ if (property == m_propsInfo.end())
+ return {};
+
+ return static_cast<bool>(drm_property_type_is(property->get(), DRM_MODE_PROP_IMMUTABLE));
+}
diff --git a/xbmc/windowing/gbm/drm/DRMObject.h b/xbmc/windowing/gbm/drm/DRMObject.h
index c4200b1a86..39ba28a004 100644
--- a/xbmc/windowing/gbm/drm/DRMObject.h
+++ b/xbmc/windowing/gbm/drm/DRMObject.h
@@ -12,6 +12,7 @@
#include <cstdint>
#include <memory>
#include <optional>
+#include <span>
#include <string_view>
#include <vector>
@@ -40,6 +41,8 @@ public:
bool SetProperty(const std::string& name, uint64_t value);
bool SupportsProperty(const std::string& name);
+ std::optional<bool> IsPropertyImmutable(std::string_view name);
+ std::optional<std::span<uint64_t, 2>> GetRangePropertyLimits(std::string_view name);
protected:
explicit CDRMObject(int fd);
diff --git a/xbmc/windowing/gbm/drm/DRMUtils.cpp b/xbmc/windowing/gbm/drm/DRMUtils.cpp
index 3dd4ee9783..22db758ab6 100644
--- a/xbmc/windowing/gbm/drm/DRMUtils.cpp
+++ b/xbmc/windowing/gbm/drm/DRMUtils.cpp
@@ -181,77 +181,130 @@ bool CDRMUtils::FindPreferredMode()
return true;
}
-bool CDRMUtils::FindPlanes()
+bool CDRMUtils::FindGuiPlane()
{
- for (size_t i = 0; i < m_crtcs.size(); i++)
- {
- if (!(m_encoder->GetPossibleCrtcs() & (1 << i)))
+ /* find the gui plane which support ARGB and 8bit or 10 bit XRGB
+ * prefer the one which does not support NV12, because it can be re-used in future for video
+ * prefer the highest id number because they are listed on top where zpos is not available
+ * and use the gui plane crtc as the crtc
+ * */
+ CDRMPlane* gui_plane_nv12{nullptr};
+ CDRMPlane* gui_plane{nullptr};
+ CDRMCrtc* gui_crtc_nv12{nullptr};
+ CDRMCrtc* gui_crtc{nullptr};
+
+ for (size_t crtc_offset = 0; crtc_offset < m_crtcs.size(); crtc_offset++)
+ {
+ if (!(m_encoder->GetPossibleCrtcs() & (1 << crtc_offset)))
continue;
- auto videoPlane = std::find_if(m_planes.begin(), m_planes.end(), [&i](auto& plane) {
- if (plane->GetPossibleCrtcs() & (1 << i))
- {
- return plane->SupportsFormat(DRM_FORMAT_NV12);
- }
- return false;
- });
-
- uint32_t videoPlaneId{0};
-
- if (videoPlane != m_planes.end())
- videoPlaneId = videoPlane->get()->GetPlaneId();
-
- auto guiPlane =
- std::find_if(m_planes.begin(), m_planes.end(), [&i, &videoPlaneId](auto& plane) {
- if (plane->GetPossibleCrtcs() & (1 << i))
- {
- return (plane->GetPlaneId() != videoPlaneId &&
- (videoPlaneId == 0 || plane->SupportsFormat(DRM_FORMAT_ARGB8888)) &&
- (plane->SupportsFormat(DRM_FORMAT_XRGB2101010) ||
- plane->SupportsFormat(DRM_FORMAT_XRGB8888)));
- }
- return false;
- });
-
- if (videoPlane != m_planes.end() && guiPlane != m_planes.end())
+ for (auto& plane : m_planes)
{
- m_crtc = m_crtcs[i].get();
- m_video_plane = videoPlane->get();
- m_gui_plane = guiPlane->get();
- break;
- }
+ if (!(plane.get()->GetPossibleCrtcs() & (1 << crtc_offset)))
+ continue;
- if (guiPlane != m_planes.end())
- {
- if (!m_crtc && m_encoder->GetCrtcId() == m_crtcs[i]->GetCrtcId())
+ if (plane.get()->SupportsFormat(DRM_FORMAT_ARGB8888) &&
+ (plane.get()->SupportsFormat(DRM_FORMAT_XRGB2101010) ||
+ plane.get()->SupportsFormat(DRM_FORMAT_XRGB8888)))
{
- m_crtc = m_crtcs[i].get();
- m_gui_plane = guiPlane->get();
- m_video_plane = nullptr;
+ if (plane.get()->SupportsFormat(DRM_FORMAT_NV12) &&
+ (gui_plane_nv12 == nullptr || gui_plane_nv12->GetId() < plane.get()->GetId()))
+ {
+ gui_plane_nv12 = plane.get();
+ gui_crtc_nv12 = m_crtcs[crtc_offset].get();
+ }
+ else if (!plane.get()->SupportsFormat(DRM_FORMAT_NV12) &&
+ (gui_plane == nullptr || gui_plane->GetId() < plane.get()->GetId()))
+ {
+ gui_plane = plane.get();
+ gui_crtc = m_crtcs[crtc_offset].get();
+ }
}
}
}
- CLog::Log(LOGINFO, "CDRMUtils::{} - using crtc: {}", __FUNCTION__, m_crtc->GetCrtcId());
-
- // video plane may not be available
- if (m_video_plane)
- CLog::Log(LOGDEBUG, "CDRMUtils::{} - using video plane {}", __FUNCTION__,
- m_video_plane->GetPlaneId());
-
- if (m_gui_plane->SupportsFormat(DRM_FORMAT_XRGB2101010))
+ // fallback to NV12 supporting plane
+ if (gui_plane == nullptr)
{
- m_gui_plane->SetFormat(DRM_FORMAT_XRGB2101010);
- CLog::Log(LOGDEBUG, "CDRMUtils::{} - using 10bit gui plane {}", __FUNCTION__,
- m_gui_plane->GetPlaneId());
+ gui_crtc = gui_crtc_nv12;
+ gui_plane = gui_plane_nv12;
}
- else
+
+ if (gui_plane != nullptr)
{
- m_gui_plane->SetFormat(DRM_FORMAT_XRGB8888);
- CLog::Log(LOGDEBUG, "CDRMUtils::{} - using gui plane {}", __FUNCTION__,
- m_gui_plane->GetPlaneId());
+ m_crtc = gui_crtc;
+ m_gui_plane = gui_plane;
+
+ CLog::Log(LOGINFO, "CDRMUtils::{} - using crtc: {}", __FUNCTION__, m_crtc->GetCrtcId());
+ if (m_gui_plane->SupportsFormat(DRM_FORMAT_XRGB2101010))
+ {
+ m_gui_plane->SetFormat(DRM_FORMAT_XRGB2101010);
+ CLog::Log(LOGDEBUG, "CDRMUtils::{} - using 10bit gui plane {}", __FUNCTION__,
+ m_gui_plane->GetPlaneId());
+ }
+ else
+ {
+ m_gui_plane->SetFormat(DRM_FORMAT_XRGB8888);
+ CLog::Log(LOGDEBUG, "CDRMUtils::{} - using gui plane {}", __FUNCTION__,
+ m_gui_plane->GetPlaneId());
+ }
+ return true;
}
+ CLog::Log(LOGERROR, "CDRMUtils::{} - Can not find a GUI plane", __FUNCTION__);
+ return false;
+}
+
+bool CDRMUtils::FindVideoPlane(uint32_t format, uint64_t modifier)
+{
+ bool supports_zpos = m_gui_plane->SupportsProperty("zpos");
+ bool zpos_immutable = supports_zpos && m_gui_plane->IsPropertyImmutable("zpos").value();
+
+ auto crtc_offset = std::distance(
+ m_crtcs.begin(),
+ std::find_if(m_crtcs.begin(), m_crtcs.end(),
+ [this](auto& crtc) { return crtc->GetCrtcId() == m_crtc->GetCrtcId(); }));
+
+ auto guiplane_id = m_gui_plane->GetId();
+ auto videoPlane = std::find_if(m_planes.begin(), m_planes.end(),
+ [&crtc_offset, &format, &modifier, &guiplane_id](auto& plane)
+ {
+ if (plane->GetPossibleCrtcs() & (1 << crtc_offset))
+ {
+ return (guiplane_id != plane->GetPlaneId() &&
+ plane->SupportsFormatAndModifier(format, modifier));
+ }
+ return false;
+ });
+
+ if (videoPlane == m_planes.end())
+ {
+ CLog::Log(LOGERROR,
+ "CDRMUtils::{} - Can not find a Video Plane plane for format {}, modifier {}",
+ __FUNCTION__, format, modifier);
+ return false;
+ }
+
+ m_video_plane = videoPlane->get();
+ CLog::Log(LOGDEBUG, "CDRMUtils::{} - using video plane {}", __FUNCTION__,
+ m_video_plane->GetPlaneId());
+
+ if (!supports_zpos || zpos_immutable)
+ return true;
+
+ // re-sort the video and gui planes
+ auto limits = m_gui_plane->GetRangePropertyLimits("zpos");
+
+ if (!limits)
+ return true;
+
+ m_gui_plane->SetProperty("zpos", limits.value()[1]);
+ m_video_plane->SetProperty("zpos", limits.value()[0]);
+ CLog::Log(LOGDEBUG, "CDRMUtils::{} - gui plane id,zpos: {}, {}", __FUNCTION__,
+ m_gui_plane->GetId(), limits.value()[1]);
+ CLog::Log(LOGDEBUG, "CDRMUtils::{} - video plane id,zpos: {}, {}", __FUNCTION__,
+ m_video_plane->GetId(), limits.value()[0]);
+
return true;
}
@@ -467,9 +520,11 @@ bool CDRMUtils::InitDrm()
if (!FindCrtc())
return false;
- if (!FindPlanes())
+ if (!FindGuiPlane())
return false;
+ FindVideoPlane(DRM_FORMAT_NV12, DRM_FORMAT_MOD_LINEAR);
+
if (!FindPreferredMode())
return false;
diff --git a/xbmc/windowing/gbm/drm/DRMUtils.h b/xbmc/windowing/gbm/drm/DRMUtils.h
index f92f716fc4..b99a6dc4fe 100644
--- a/xbmc/windowing/gbm/drm/DRMUtils.h
+++ b/xbmc/windowing/gbm/drm/DRMUtils.h
@@ -64,6 +64,8 @@ public:
static uint32_t FourCCWithoutAlpha(uint32_t fourcc);
void SetInFenceFd(int fd) { m_inFenceFd = fd; }
+ bool FindVideoPlane(uint32_t format, uint64_t modifier);
+ bool FindGuiPlane();
int TakeOutFenceFd()
{
int fd{-1};
@@ -89,13 +91,13 @@ protected:
int m_inFenceFd{-1};
int m_outFenceFd{-1};
+ std::vector<std::unique_ptr<CDRMCrtc>> m_crtcs;
std::vector<std::unique_ptr<CDRMPlane>> m_planes;
private:
bool FindConnector();
bool FindEncoder();
bool FindCrtc();
- bool FindPlanes();
bool FindPreferredMode();
bool RestoreOriginalMode();
RESOLUTION_INFO GetResolutionInfo(drmModeModeInfoPtr mode);
@@ -106,7 +108,6 @@ private:
std::vector<std::unique_ptr<CDRMConnector>> m_connectors;
std::vector<std::unique_ptr<CDRMEncoder>> m_encoders;
- std::vector<std::unique_ptr<CDRMCrtc>> m_crtcs;
};
}