mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-17 14:11:33 +00:00
Add color properties to DRM renderer
This commit is contained in:
@@ -31,9 +31,16 @@ DrmRenderer::DrmRenderer()
|
|||||||
m_DrmFd(-1),
|
m_DrmFd(-1),
|
||||||
m_SdlOwnsDrmFd(false),
|
m_SdlOwnsDrmFd(false),
|
||||||
m_SupportsDirectRendering(false),
|
m_SupportsDirectRendering(false),
|
||||||
|
m_ConnectorId(0),
|
||||||
|
m_EncoderId(0),
|
||||||
m_CrtcId(0),
|
m_CrtcId(0),
|
||||||
m_PlaneId(0),
|
m_PlaneId(0),
|
||||||
m_CurrentFbId(0)
|
m_CurrentFbId(0),
|
||||||
|
m_LastColorRange(AVCOL_RANGE_UNSPECIFIED),
|
||||||
|
m_LastColorSpace(AVCOL_SPC_UNSPECIFIED),
|
||||||
|
m_ColorEncodingProp(nullptr),
|
||||||
|
m_ColorRangeProp(nullptr),
|
||||||
|
m_HdrOutputMetadataProp(nullptr)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_EGL
|
#ifdef HAVE_EGL
|
||||||
m_EGLExtDmaBuf = false;
|
m_EGLExtDmaBuf = false;
|
||||||
@@ -50,6 +57,18 @@ DrmRenderer::~DrmRenderer()
|
|||||||
drmModeRmFB(m_DrmFd, m_CurrentFbId);
|
drmModeRmFB(m_DrmFd, m_CurrentFbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_ColorEncodingProp != nullptr) {
|
||||||
|
drmModeFreeProperty(m_ColorEncodingProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_ColorRangeProp != nullptr) {
|
||||||
|
drmModeFreeProperty(m_ColorRangeProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_HdrOutputMetadataProp != nullptr) {
|
||||||
|
drmModeFreeProperty(m_HdrOutputMetadataProp);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_HwContext != nullptr) {
|
if (m_HwContext != nullptr) {
|
||||||
av_buffer_unref(&m_HwContext);
|
av_buffer_unref(&m_HwContext);
|
||||||
}
|
}
|
||||||
@@ -176,19 +195,21 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look for a connected connector and get the associated encoder
|
// Look for a connected connector and get the associated encoder
|
||||||
uint32_t encoderId = 0;
|
m_ConnectorId = 0;
|
||||||
for (i = 0; i < resources->count_connectors && encoderId == 0; i++) {
|
m_EncoderId = 0;
|
||||||
|
for (i = 0; i < resources->count_connectors && m_EncoderId == 0; i++) {
|
||||||
drmModeConnector* connector = drmModeGetConnector(m_DrmFd, resources->connectors[i]);
|
drmModeConnector* connector = drmModeGetConnector(m_DrmFd, resources->connectors[i]);
|
||||||
if (connector != nullptr) {
|
if (connector != nullptr) {
|
||||||
if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) {
|
if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) {
|
||||||
encoderId = connector->encoder_id;
|
m_ConnectorId = resources->connectors[i];
|
||||||
|
m_EncoderId = connector->encoder_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
drmModeFreeConnector(connector);
|
drmModeFreeConnector(connector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoderId == 0) {
|
if (m_EncoderId == 0) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"No connected displays found!");
|
"No connected displays found!");
|
||||||
drmModeFreeResources(resources);
|
drmModeFreeResources(resources);
|
||||||
@@ -200,7 +221,7 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params)
|
|||||||
for (i = 0; i < resources->count_encoders && m_CrtcId == 0; i++) {
|
for (i = 0; i < resources->count_encoders && m_CrtcId == 0; i++) {
|
||||||
drmModeEncoder* encoder = drmModeGetEncoder(m_DrmFd, resources->encoders[i]);
|
drmModeEncoder* encoder = drmModeGetEncoder(m_DrmFd, resources->encoders[i]);
|
||||||
if (encoder != nullptr) {
|
if (encoder != nullptr) {
|
||||||
if (encoder->encoder_id == encoderId) {
|
if (encoder->encoder_id == m_EncoderId) {
|
||||||
m_CrtcId = encoder->crtc_id;
|
m_CrtcId = encoder->crtc_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,14 +304,22 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params)
|
|||||||
if ((plane->possible_crtcs & (1 << crtcIndex)) && plane->crtc_id == 0) {
|
if ((plane->possible_crtcs & (1 << crtcIndex)) && plane->crtc_id == 0) {
|
||||||
drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(m_DrmFd, planeRes->planes[i], DRM_MODE_OBJECT_PLANE);
|
drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(m_DrmFd, planeRes->planes[i], DRM_MODE_OBJECT_PLANE);
|
||||||
if (props != nullptr) {
|
if (props != nullptr) {
|
||||||
for (uint32_t j = 0; j < props->count_props && m_PlaneId == 0; j++) {
|
for (uint32_t j = 0; j < props->count_props; j++) {
|
||||||
drmModePropertyPtr prop = drmModeGetProperty(m_DrmFd, props->props[j]);
|
drmModePropertyPtr prop = drmModeGetProperty(m_DrmFd, props->props[j]);
|
||||||
if (prop != nullptr) {
|
if (prop != nullptr) {
|
||||||
if (!strcmp(prop->name, "type") && props->prop_values[j] == DRM_PLANE_TYPE_OVERLAY) {
|
if (!strcmp(prop->name, "type") && props->prop_values[j] == DRM_PLANE_TYPE_OVERLAY) {
|
||||||
m_PlaneId = plane->plane_id;
|
m_PlaneId = plane->plane_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
drmModeFreeProperty(prop);
|
if (!strcmp(prop->name, "COLOR_ENCODING")) {
|
||||||
|
m_ColorEncodingProp = prop;
|
||||||
|
}
|
||||||
|
else if (!strcmp(prop->name, "COLOR_RANGE")) {
|
||||||
|
m_ColorRangeProp = prop;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,6 +339,23 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params)
|
|||||||
return DIRECT_RENDERING_INIT_FAILED;
|
return DIRECT_RENDERING_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(m_DrmFd, m_ConnectorId, DRM_MODE_OBJECT_CONNECTOR);
|
||||||
|
if (props != nullptr) {
|
||||||
|
for (uint32_t j = 0; j < props->count_props; j++) {
|
||||||
|
drmModePropertyPtr prop = drmModeGetProperty(m_DrmFd, props->props[j]);
|
||||||
|
if (prop != nullptr) {
|
||||||
|
if (!strcmp(prop->name, "HDR_OUTPUT_METADATA")) {
|
||||||
|
m_HdrOutputMetadataProp = prop;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFreeObjectProperties(props);
|
||||||
|
}
|
||||||
|
|
||||||
// If we got this far, we can do direct rendering via the DRM FD.
|
// If we got this far, we can do direct rendering via the DRM FD.
|
||||||
m_SupportsDirectRendering = true;
|
m_SupportsDirectRendering = true;
|
||||||
|
|
||||||
@@ -397,6 +443,50 @@ void DrmRenderer::renderFrame(AVFrame* frame)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame->color_range != m_LastColorRange) {
|
||||||
|
const char* desiredValue = getDrmColorRangeValue(frame);
|
||||||
|
|
||||||
|
if (m_ColorRangeProp != nullptr && desiredValue != nullptr) {
|
||||||
|
for (int i = 0; i < m_ColorRangeProp->count_enums; i++) {
|
||||||
|
if (!strcmp(desiredValue, m_ColorRangeProp->enums[i].name)) {
|
||||||
|
err = drmModeObjectSetProperty(m_DrmFd, m_PlaneId, DRM_MODE_OBJECT_PLANE,
|
||||||
|
m_ColorRangeProp->prop_id, m_ColorRangeProp->enums[i].value);
|
||||||
|
if (err < 0) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"drmModeObjectSetProperty(%s) failed: %d",
|
||||||
|
m_ColorRangeProp->name,
|
||||||
|
errno);
|
||||||
|
// Non-fatal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LastColorRange = frame->color_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame->colorspace != m_LastColorSpace) {
|
||||||
|
const char* desiredValue = getDrmColorEncodingValue(frame);
|
||||||
|
|
||||||
|
if (m_ColorEncodingProp != nullptr && desiredValue != nullptr) {
|
||||||
|
for (int i = 0; i < m_ColorEncodingProp->count_enums; i++) {
|
||||||
|
if (!strcmp(desiredValue, m_ColorEncodingProp->enums[i].name)) {
|
||||||
|
err = drmModeObjectSetProperty(m_DrmFd, m_PlaneId, DRM_MODE_OBJECT_PLANE,
|
||||||
|
m_ColorEncodingProp->prop_id, m_ColorEncodingProp->enums[i].value);
|
||||||
|
if (err < 0) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"drmModeObjectSetProperty(%s) failed: %d",
|
||||||
|
m_ColorEncodingProp->name,
|
||||||
|
errno);
|
||||||
|
// Non-fatal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LastColorSpace = frame->colorspace;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the overlay
|
// Update the overlay
|
||||||
err = drmModeSetPlane(m_DrmFd, m_PlaneId, m_CrtcId, m_CurrentFbId, 0,
|
err = drmModeSetPlane(m_DrmFd, m_PlaneId, m_CrtcId, m_CurrentFbId, 0,
|
||||||
dst.x, dst.y,
|
dst.x, dst.y,
|
||||||
@@ -427,6 +517,32 @@ bool DrmRenderer::isDirectRenderingSupported()
|
|||||||
return m_SupportsDirectRendering;
|
return m_SupportsDirectRendering;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* DrmRenderer::getDrmColorEncodingValue(AVFrame* frame)
|
||||||
|
{
|
||||||
|
switch (frame->colorspace) {
|
||||||
|
case AVCOL_SPC_SMPTE170M:
|
||||||
|
return "ITU-R BT.601 YCbCr";
|
||||||
|
case AVCOL_SPC_BT709:
|
||||||
|
return "ITU-R BT.709 YCbCr";
|
||||||
|
case AVCOL_SPC_BT2020_NCL:
|
||||||
|
return "ITU-R BT.2020 YCbCr";
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* DrmRenderer::getDrmColorRangeValue(AVFrame* frame)
|
||||||
|
{
|
||||||
|
switch (frame->color_range) {
|
||||||
|
case AVCOL_RANGE_MPEG:
|
||||||
|
return "YCbCr limited range";
|
||||||
|
case AVCOL_RANGE_JPEG:
|
||||||
|
return "YCbCr full range";
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_EGL
|
#ifdef HAVE_EGL
|
||||||
|
|
||||||
bool DrmRenderer::canExportEGL() {
|
bool DrmRenderer::canExportEGL() {
|
||||||
|
|||||||
@@ -25,13 +25,23 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const char* getDrmColorEncodingValue(AVFrame* frame);
|
||||||
|
const char* getDrmColorRangeValue(AVFrame* frame);
|
||||||
|
|
||||||
AVBufferRef* m_HwContext;
|
AVBufferRef* m_HwContext;
|
||||||
int m_DrmFd;
|
int m_DrmFd;
|
||||||
bool m_SdlOwnsDrmFd;
|
bool m_SdlOwnsDrmFd;
|
||||||
bool m_SupportsDirectRendering;
|
bool m_SupportsDirectRendering;
|
||||||
|
uint32_t m_ConnectorId;
|
||||||
|
uint32_t m_EncoderId;
|
||||||
uint32_t m_CrtcId;
|
uint32_t m_CrtcId;
|
||||||
uint32_t m_PlaneId;
|
uint32_t m_PlaneId;
|
||||||
uint32_t m_CurrentFbId;
|
uint32_t m_CurrentFbId;
|
||||||
|
AVColorRange m_LastColorRange;
|
||||||
|
AVColorSpace m_LastColorSpace;
|
||||||
|
drmModePropertyPtr m_ColorEncodingProp;
|
||||||
|
drmModePropertyPtr m_ColorRangeProp;
|
||||||
|
drmModePropertyPtr m_HdrOutputMetadataProp;
|
||||||
SDL_Rect m_OutputRect;
|
SDL_Rect m_OutputRect;
|
||||||
|
|
||||||
#ifdef HAVE_EGL
|
#ifdef HAVE_EGL
|
||||||
|
|||||||
Reference in New Issue
Block a user