gst: Set matrix coefficients

This is needed to use our color conversion machinery successfully.

We need some heuristics to determine what coefficients and range
to use when gstreamer gives us an 'unspecified' value. For that,
we look at the fourcc.
This commit is contained in:
Matthias Clasen
2024-07-26 23:38:25 -04:00
parent 3445d2c12a
commit c53f791cb3

View File

@@ -24,6 +24,8 @@
#include "gtkgstpaintableprivate.h"
#include "gdk/gdkdmabuffourccprivate.h"
#if GST_GL_HAVE_WINDOW_X11 && (GST_GL_HAVE_PLATFORM_GLX || GST_GL_HAVE_PLATFORM_EGL) && defined (GDK_WINDOWING_X11)
#define HAVE_GST_X11_SUPPORT
#include <gdk/x11/gdkx.h>
@@ -156,9 +158,72 @@ add_drm_formats_and_modifiers (GstCaps *caps,
&dmabuf_list);
}
#ifdef HAVE_GSTREAMER_DRM
static inline gboolean
dmabuf_fourcc_is_yuv (guint32 fourcc)
{
switch (fourcc)
{
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_VYUY:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_AYUV:
case DRM_FORMAT_AVUY8888:
case DRM_FORMAT_XYUV8888:
case DRM_FORMAT_XVUY8888:
case DRM_FORMAT_VUY888:
case DRM_FORMAT_VUY101010:
case DRM_FORMAT_Y210:
case DRM_FORMAT_Y212:
case DRM_FORMAT_Y216:
case DRM_FORMAT_Y410:
case DRM_FORMAT_Y412:
case DRM_FORMAT_Y416:
case DRM_FORMAT_XVYU2101010:
case DRM_FORMAT_XVYU12_16161616:
case DRM_FORMAT_XVYU16161616:
case DRM_FORMAT_Y0L0:
case DRM_FORMAT_X0L0:
case DRM_FORMAT_Y0L2:
case DRM_FORMAT_X0L2:
case DRM_FORMAT_YUV420_8BIT:
case DRM_FORMAT_YUV420_10BIT:
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
case DRM_FORMAT_NV24:
case DRM_FORMAT_NV42:
case DRM_FORMAT_NV15:
case DRM_FORMAT_P210:
case DRM_FORMAT_P010:
case DRM_FORMAT_P012:
case DRM_FORMAT_P016:
case DRM_FORMAT_P030:
case DRM_FORMAT_Q410:
case DRM_FORMAT_Q401:
case DRM_FORMAT_YUV410:
case DRM_FORMAT_YVU410:
case DRM_FORMAT_YUV411:
case DRM_FORMAT_YVU411:
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
case DRM_FORMAT_YUV422:
case DRM_FORMAT_YVU422:
case DRM_FORMAT_YUV444:
case DRM_FORMAT_YVU444:
return TRUE;
default:
return FALSE;
}
}
#endif
static GdkColorState *
gtk_gst_color_state_from_colorimetry (GtkGstSink *self,
const GstVideoColorimetry *colorimetry)
const GstVideoColorimetry *colorimetry,
gconstpointer drm)
{
GdkCicpParams *params;
GdkColorState *color_state;
@@ -176,18 +241,40 @@ gtk_gst_color_state_from_colorimetry (GtkGstSink *self,
else
gdk_cicp_params_set_transfer_function (params, gst_video_transfer_function_to_iso (colorimetry->transfer));
#if 0
gdk_cicp_params_set_range (params, colorimetry->range == GST_VIDEO_COLOR_RANGE_16_235 ? GDK_CICP_RANGE_NARROW : GDK_CICP_RANGE_FULL);
if (colorimetry->matrix == GST_VIDEO_COLOR_MATRIX_UNKNOWN)
gdk_cicp_params_set_matrix_coefficients (params, 6);
{
gdk_cicp_params_set_matrix_coefficients (params, 0);
#ifdef HAVE_GSTREAMER_DRM
const GstVideoInfoDmaDrm *drm_info = drm;
if (drm_info)
{
if (dmabuf_fourcc_is_yuv (drm_info->drm_fourcc))
{
GST_DEBUG_OBJECT (self, "Assuming fourcc %.*s is yuv", 4, (char *)&drm_info->drm_fourcc);
gdk_cicp_params_set_matrix_coefficients (params, 6);
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_NARROW);
}
}
#endif
}
else
gdk_cicp_params_set_matrix_coefficients (params, gst_video_color_matrix_to_iso (colorimetry->matrix));
gdk_cicp_params_set_range (params, colorimetry->range == GST_VIDEO_COLOR_RANGE_0_255 ? GDK_CICP_RANGE_FULL : GDK_CICP_RANGE_NARROW);
#else
gdk_cicp_params_set_matrix_coefficients (params, 0);
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
#endif
color_state = gdk_cicp_params_build_color_state (params, &error);
GST_DEBUG_OBJECT (self, "cicp received: %u/%u/%u/%u",
gst_video_color_primaries_to_iso (colorimetry->primaries),
gst_video_transfer_function_to_iso (colorimetry->transfer),
gst_video_color_matrix_to_iso (colorimetry->matrix),
colorimetry->range == GST_VIDEO_COLOR_RANGE_0_255);
GST_DEBUG_OBJECT (self, "cicp used: %u/%u/%u/%u",
gdk_cicp_params_get_color_primaries (params),
gdk_cicp_params_get_transfer_function (params),
gdk_cicp_params_get_matrix_coefficients (params),
gdk_cicp_params_get_range (params));
g_object_unref (params);
if (color_state == NULL)
@@ -266,7 +353,14 @@ gtk_gst_sink_set_caps (GstBaseSink *bsink,
}
g_clear_pointer (&self->color_state, gdk_color_state_unref);
self->color_state = gtk_gst_color_state_from_colorimetry (self, &self->v_info.colorimetry);
self->color_state = gtk_gst_color_state_from_colorimetry (self,
&self->v_info.colorimetry,
#ifdef HAVE_GSTREAMER_DRM
&self->drm_info
#else
NULL
#endif
);
if (self->color_state == NULL)
return FALSE;