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:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user