diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11.h index fe851708fb..55bd124f6f 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_fwd.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_fwd.h index 259b1b3640..e4601aee25 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_fwd.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_fwd.h @@ -59,5 +59,9 @@ typedef struct _GstD3D11StagingBufferPoolPrivate GstD3D11StagingBufferPoolPrivat typedef struct _GstD3D11Format GstD3D11Format; +typedef struct _GstD3D11Converter GstD3D11Converter; +typedef struct _GstD3D11ConverterClass GstD3D11ConverterClass; +typedef struct _GstD3D11ConverterPrivate GstD3D11ConverterPrivate; + G_END_DECLS diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h index c6ab986835..8b34760f54 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h @@ -111,6 +111,37 @@ static const GstD3D11Format _gst_d3d11_default_format_map[] = { #define GST_D3D11_N_FORMATS G_N_ELEMENTS(_gst_d3d11_default_format_map) +typedef struct _GstD3D11ColorMatrix +{ + gdouble matrix[3][3]; + gdouble offset[3]; + gdouble min[3]; + gdouble max[3]; +} GstD3D11ColorMatrix; + +GST_D3D11_API +gchar * gst_d3d11_dump_color_matrix (GstD3D11ColorMatrix * matrix); + +GST_D3D11_API +gboolean gst_d3d11_color_range_adjust_matrix_unorm (const GstVideoInfo * in_info, + const GstVideoInfo * out_info, + GstD3D11ColorMatrix * matrix); + +GST_D3D11_API +gboolean gst_d3d11_yuv_to_rgb_matrix_unorm (const GstVideoInfo * in_yuv_info, + const GstVideoInfo * out_rgb_info, + GstD3D11ColorMatrix * matrix); + +GST_D3D11_API +gboolean gst_d3d11_rgb_to_yuv_matrix_unorm (const GstVideoInfo * in_rgb_info, + const GstVideoInfo * out_yuv_info, + GstD3D11ColorMatrix * matrix); + +GST_D3D11_API +gboolean gst_d3d11_color_primaries_matrix_unorm (const GstVideoColorPrimariesInfo * in_info, + const GstVideoColorPrimariesInfo * out_info, + GstD3D11ColorMatrix * matrix); + G_END_DECLS #ifdef __cplusplus diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11converter.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11converter.cpp similarity index 98% rename from subprojects/gst-plugins-bad/sys/d3d11/gstd3d11converter.cpp rename to subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11converter.cpp index edd60b8209..eb6ee03253 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11converter.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11converter.cpp @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) <2019> Seungha Yang * Copyright (C) <2019> Jeongki Kim + * Copyright (C) <2022> Seungha Yang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,8 +23,13 @@ # include #endif +#include "gstd3d11_private.h" #include "gstd3d11converter.h" -#include "gstd3d11pluginutils.h" +#include "gstd3d11device.h" +#include "gstd3d11utils.h" +#include "gstd3d11memory.h" +#include "gstd3d11compile.h" +#include "gstd3d11bufferpool.h" #include #include #include @@ -2860,6 +2866,23 @@ gst_d3d11_converter_setup_processor (GstD3D11Converter * self) return TRUE; } +/** + * gst_d3d11_converter_new: + * @device: a #GstD3D11Device + * @in_info: a #GstVideoInfo + * @out_info: a #GstVideoInfo + * @method: (inout) (optional) (nullable): a #GstD3D11ConverterMethod + + * Create a new converter object to convert between @in_info and @out_info + * with @method. When @method is not specified, converter will configure + * conversion path for all available method. Otherwise, converter will configure + * conversion path only for specified method(s) and set @method will be updated + * with supported method. + * + * Returns: a #GstD3D11Converter or %NULL if conversion is not possible + * + * Since: 1.22 + */ GstD3D11Converter * gst_d3d11_converter_new (GstD3D11Device * device, const GstVideoInfo * in_info, const GstVideoInfo * out_info, GstStructure * config) @@ -3815,6 +3838,18 @@ out: return ret; } +/** + * gst_d3d11_converter_convert_buffer: + * @converter: a #GstD3D11Converter + * @in_buf: a #GstBuffer + * @out_buf: a #GstBuffer + * + * Converts @in_buf into @out_buf + * + * Returns: %TRUE if conversion is successful + * + * Since: 1.22 + */ gboolean gst_d3d11_converter_convert_buffer (GstD3D11Converter * converter, GstBuffer * in_buf, GstBuffer * out_buf) @@ -3829,6 +3864,21 @@ gst_d3d11_converter_convert_buffer (GstD3D11Converter * converter, in_buf, out_buf); } +/** + * gst_d3d11_converter_convert_buffer_unlocked: + * @converter: a #GstD3D11Converter + * @in_buf: a #GstBuffer + * @out_buf: a #GstBuffer + * + * Converts @in_buf into @out_buf. Caller should take d3d11 device lock + * in case that multiple threads can perform GPU processing using the + * same #GstD3D11Device + * + * Returns: %TRUE if conversion is successful + * + * Since: 1.22 + */ + gboolean gst_d3d11_converter_convert_buffer_unlocked (GstD3D11Converter * converter, GstBuffer * in_buf, GstBuffer * out_buf) diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11converter.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11converter.h similarity index 83% rename from subprojects/gst-plugins-bad/sys/d3d11/gstd3d11converter.h rename to subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11converter.h index 2478e7a927..1273579eb6 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11converter.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11converter.h @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) <2019> Seungha Yang + * Copyright (C) <2022> Seungha Yang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,12 +18,11 @@ * Boston, MA 02110-1301, USA. */ -#ifndef __GST_D3D11_COLOR_CONVERTER_H__ -#define __GST_D3D11_COLOR_CONVERTER_H__ +#pragma once #include #include -#include +#include G_BEGIN_DECLS @@ -34,17 +34,31 @@ G_BEGIN_DECLS #define GST_IS_D3D11_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_D3D11_CONVERTER)) #define GST_D3D11_CONVERTER_CAST(obj) ((GstD3D11Converter*)(obj)) -typedef struct _GstD3D11Converter GstD3D11Converter; -typedef struct _GstD3D11ConverterClass GstD3D11ConverterClass; -typedef struct _GstD3D11ConverterPrivate GstD3D11ConverterPrivate; - +/** + * GstD3D11ConverterMethod: + * @GST_D3D11_CONVERTER_METHOD_SHADER: Performs conversion using pixel shader + * @GST_D3D11_CONVERTER_METHOD_VIDEO_PROCESSOR: Performs conversion using video processor + * + * Since: 1.22 + */ typedef enum { GST_D3D11_CONVERTER_BACKEND_SHADER = (1 << 0), GST_D3D11_CONVERTER_BACKEND_VIDEO_PROCESSOR = (1 << 1), } GstD3D11ConverterBackend; + +GST_D3D11_API +GType gst_d3d11_converter_backend_get_type (void); #define GST_TYPE_D3D11_CONVERTER_BACKEND (gst_d3d11_converter_backend_get_type()) +/** + * GST_D3D11_CONVERTER_OPT_BACKEND: + * + * #GstD3D11ConverterBackend, the conversion backend + * (e.g., pixel shader and/or video processor) to use + * + * Since: 1.22 + */ #define GST_D3D11_CONVERTER_OPT_BACKEND "GstD3D11Converter.backend" struct _GstD3D11Converter @@ -66,23 +80,23 @@ struct _GstD3D11ConverterClass gpointer _gst_reserved[GST_PADDING]; }; -GType gst_d3d11_converter_backend_get_type (void); - +GST_D3D11_API GType gst_d3d11_converter_get_type (void); +GST_D3D11_API GstD3D11Converter * gst_d3d11_converter_new (GstD3D11Device * device, const GstVideoInfo * in_info, const GstVideoInfo * out_info, GstStructure * config); +GST_D3D11_API gboolean gst_d3d11_converter_convert_buffer (GstD3D11Converter * converter, GstBuffer * in_buf, GstBuffer * out_buf); +GST_D3D11_API gboolean gst_d3d11_converter_convert_buffer_unlocked (GstD3D11Converter * converter, GstBuffer * in_buf, GstBuffer * out_buf); G_END_DECLS - -#endif /* __GST_D3D11_COLOR_CONVERTER_H__ */ diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.cpp index 242b620e43..ae8b3c5a63 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.cpp @@ -913,3 +913,758 @@ gst_video_info_apply_dxgi_color_space (DXGI_COLOR_SPACE_TYPE color_space, return TRUE; } + +gchar * +gst_d3d11_dump_color_matrix (GstD3D11ColorMatrix * matrix) +{ + /* *INDENT-OFF* */ + static const gchar format[] = + "[MATRIX]\n" + "|% .6f, % .6f, % .6f|\n" + "|% .6f, % .6f, % .6f|\n" + "|% .6f, % .6f, % .6f|\n" + "[OFFSET]\n" + "|% .6f, % .6f, % .6f|\n" + "[MIN]\n" + "|% .6f, % .6f, % .6f|\n" + "[MAX]\n" + "|% .6f, % .6f, % .6f|"; + /* *INDENT-ON* */ + + g_return_val_if_fail (matrix != nullptr, nullptr); + + return g_strdup_printf (format, + matrix->matrix[0][0], matrix->matrix[0][1], matrix->matrix[0][2], + matrix->matrix[1][0], matrix->matrix[1][1], matrix->matrix[1][2], + matrix->matrix[2][0], matrix->matrix[2][1], matrix->matrix[2][2], + matrix->offset[0], matrix->offset[1], matrix->offset[2], + matrix->min[0], matrix->min[1], matrix->min[2], + matrix->max[0], matrix->max[1], matrix->max[2]); +} + +static void +color_matrix_copy (GstD3D11ColorMatrix * dst, const GstD3D11ColorMatrix * src) +{ + for (guint i = 0; i < 3; i++) { + for (guint j = 0; j < 3; j++) { + dst->matrix[i][j] = src->matrix[i][j]; + } + } +} + +static void +color_matrix_multiply (GstD3D11ColorMatrix * dst, GstD3D11ColorMatrix * a, + GstD3D11ColorMatrix * b) +{ + GstD3D11ColorMatrix tmp; + + for (guint i = 0; i < 3; i++) { + for (guint j = 0; j < 3; j++) { + gdouble val = 0; + for (guint k = 0; k < 3; k++) { + val += a->matrix[i][k] * b->matrix[k][j]; + } + + tmp.matrix[i][j] = val; + } + } + + color_matrix_copy (dst, &tmp); +} + +static void +color_matrix_identity (GstD3D11ColorMatrix * m) +{ + for (guint i = 0; i < 3; i++) { + for (guint j = 0; j < 3; j++) { + if (i == j) + m->matrix[i][j] = 1.0; + else + m->matrix[i][j] = 0; + } + } +} + +static gboolean +color_matrix_invert (GstD3D11ColorMatrix * dst, GstD3D11ColorMatrix * src) +{ + GstD3D11ColorMatrix tmp; + gdouble det; + + color_matrix_identity (&tmp); + for (guint j = 0; j < 3; j++) { + for (guint i = 0; i < 3; i++) { + tmp.matrix[j][i] = + src->matrix[(i + 1) % 3][(j + 1) % 3] * + src->matrix[(i + 2) % 3][(j + 2) % 3] - + src->matrix[(i + 1) % 3][(j + 2) % 3] * + src->matrix[(i + 2) % 3][(j + 1) % 3]; + } + } + + det = tmp.matrix[0][0] * src->matrix[0][0] + + tmp.matrix[0][1] * src->matrix[1][0] + + tmp.matrix[0][2] * src->matrix[2][0]; + if (det == 0) + return FALSE; + + for (guint j = 0; j < 3; j++) { + for (guint i = 0; i < 3; i++) { + tmp.matrix[i][j] /= det; + } + } + + color_matrix_copy (dst, &tmp); + + return TRUE; +} + +/** + * gst_d3d11_color_range_adjust_matrix_unorm: + * @in_info: a #GstVideoInfo + * @out_info: a #GstVideoInfo + * @matrix: a #GstD3D11ColorMatrix + * + * Calculates matrix for color range adjustment. Both input and output + * signals are in normalized [0.0..1.0] space. + * + * Resulting values can be calculated by + * | Yout | | Yin | | matrix.offset[0] | + * | Uout | = clamp ( matrix.matrix * | Uin | + | matrix.offset[1] |, matrix.min, matrix.max ) + * | Vout | | Vin | | matrix.offset[2] | + * + * Returns: %TRUE if successful + */ +gboolean +gst_d3d11_color_range_adjust_matrix_unorm (const GstVideoInfo * in_info, + const GstVideoInfo * out_info, GstD3D11ColorMatrix * matrix) +{ + gboolean in_rgb, out_rgb; + gint in_offset[GST_VIDEO_MAX_COMPONENTS]; + gint in_scale[GST_VIDEO_MAX_COMPONENTS]; + gint out_offset[GST_VIDEO_MAX_COMPONENTS]; + gint out_scale[GST_VIDEO_MAX_COMPONENTS]; + GstVideoColorRange in_range; + GstVideoColorRange out_range; + gdouble src_fullscale, dst_fullscale; + + g_return_val_if_fail (in_info != nullptr, FALSE); + g_return_val_if_fail (out_info != nullptr, FALSE); + g_return_val_if_fail (matrix != nullptr, FALSE); + + memset (matrix, 0, sizeof (GstD3D11ColorMatrix)); + for (guint i = 0; i < 3; i++) { + matrix->matrix[i][i] = 1.0; + matrix->matrix[i][i] = 1.0; + matrix->matrix[i][i] = 1.0; + matrix->max[i] = 1.0; + } + + in_rgb = GST_VIDEO_INFO_IS_RGB (in_info); + out_rgb = GST_VIDEO_INFO_IS_RGB (out_info); + + if (in_rgb != out_rgb) { + GST_WARNING ("Invalid format conversion"); + return FALSE; + } + + in_range = in_info->colorimetry.range; + out_range = out_info->colorimetry.range; + + if (in_range == GST_VIDEO_COLOR_RANGE_UNKNOWN) { + GST_WARNING ("Unknown input color range"); + if (in_rgb || GST_VIDEO_INFO_IS_GRAY (in_info)) + in_range = GST_VIDEO_COLOR_RANGE_0_255; + else + in_range = GST_VIDEO_COLOR_RANGE_16_235; + } + + if (out_range == GST_VIDEO_COLOR_RANGE_UNKNOWN) { + GST_WARNING ("Unknown output color range"); + if (out_rgb || GST_VIDEO_INFO_IS_GRAY (out_info)) + out_range = GST_VIDEO_COLOR_RANGE_0_255; + else + out_range = GST_VIDEO_COLOR_RANGE_16_235; + } + + src_fullscale = (gdouble) ((1 << in_info->finfo->depth[0]) - 1); + dst_fullscale = (gdouble) ((1 << out_info->finfo->depth[0]) - 1); + + gst_video_color_range_offsets (in_range, in_info->finfo, in_offset, in_scale); + gst_video_color_range_offsets (out_range, + out_info->finfo, out_offset, out_scale); + + matrix->min[0] = matrix->min[1] = matrix->min[2] = + (gdouble) out_offset[0] / dst_fullscale; + + matrix->max[0] = (out_scale[0] + out_offset[0]) / dst_fullscale; + matrix->max[1] = matrix->max[2] = + (out_scale[1] + out_offset[0]) / dst_fullscale; + + if (in_info->colorimetry.range == out_info->colorimetry.range) { + GST_DEBUG ("Same color range"); + return TRUE; + } + + /* Formula + * + * 1) Scales and offset compensates input to [0..1] range + * SRC_NORM[i] = (src[i] * src_fullscale - in_offset[i]) / in_scale[i] + * = (src[i] * src_fullscale / in_scale[i]) - in_offset[i] / in_scale[i] + * + * 2) Reverse to output UNIT scale + * DST_UINT[i] = SRC_NORM[i] * out_scale[i] + out_offset[i] + * = src[i] * src_fullscale * out_scale[i] / in_scale[i] + * - in_offset[i] * out_scale[i] / in_scale[i] + * + out_offset[i] + * + * 3) Back to [0..1] scale + * dst[i] = DST_UINT[i] / dst_fullscale + * = COEFF[i] * src[i] + OFF[i] + * where + * src_fullscale * out_scale[i] + * COEFF[i] = ------------------------------ + * dst_fullscale * in_scale[i] + * + * out_offset[i] in_offset[i] * out_scale[i] + * OFF[i] = -------------- - ------------------------------ + * dst_fullscale dst_fullscale * in_scale[i] + */ + for (guint i = 0; i < 3; i++) { + matrix->matrix[i][i] = (src_fullscale * out_scale[i]) / + (dst_fullscale * in_scale[i]); + matrix->offset[i] = (out_offset[i] / dst_fullscale) - + ((gdouble) in_offset[i] * out_scale[i] / (dst_fullscale * in_scale[i])); + } + + return TRUE; +} + +/** + * gst_d3d11_yuv_to_rgb_matrix_unorm: + * @in_yuv_info: a #GstVideoInfo of input YUV signal + * @out_rgb_info: a #GstVideoInfo of output RGB signal + * @matrix: a #GstD3D11ColorMatrix + * + * Calculates transform matrix from YUV to RGB conversion. Both input and output + * signals are in normalized [0.0..1.0] space and additional gamma decoding + * or primary/transfer function transform is not performed by this matrix. + * + * Resulting non-linear RGB values can be calculated by + * | R' | | Y' | | matrix.offset[0] | + * | G' | = clamp ( matrix.matrix * | Cb | + | matrix.offset[1] | matrix.min, matrix.max ) + * | B' | | Cr | | matrix.offset[2] | + * + * Returns: %TRUE if successful + */ +gboolean +gst_d3d11_yuv_to_rgb_matrix_unorm (const GstVideoInfo * in_yuv_info, + const GstVideoInfo * out_rgb_info, GstD3D11ColorMatrix * matrix) +{ + gint offset[4], scale[4]; + gdouble Kr, Kb, Kg; + + g_return_val_if_fail (in_yuv_info != nullptr, FALSE); + g_return_val_if_fail (out_rgb_info != nullptr, FALSE); + g_return_val_if_fail (matrix != nullptr, FALSE); + + /* + * + * + * Input: Unsigned normalized Y'CbCr(unorm), [0.0..1.0] range + * Output: Unsigned normalized non-linear R'G'B'(unorm), [0.0..1.0] range + * + * 1) Y'CbCr(unorm) to scaled Y'CbCr + * | Y' | | Y'(unorm) | + * | Cb | = S | Cb(unorm) | + * | Cb | | Cr(unorm) | + * where S = (2 ^ bitdepth) - 1 + * + * 2) Y'CbCr to YPbPr + * Y = (Y' - offsetY ) / scaleY + * Pb = [(Cb - offsetCbCr) / scaleCbCr] + * Pr = [(Cr - offsetCrCr) / scaleCrCr] + * => + * Y = Y'(unorm) * Sy + Oy + * Pb = Cb(unorm) * Suv + Ouv + * Pb = Cr(unorm) * Suv + Ouv + * where + * Sy = S / scaleY + * Suv = S / scaleCbCr + * Oy = -(offsetY / scaleY) + * Ouv = -(offsetCbCr / scaleCbCr) + * + * 3) YPbPr to R'G'B' + * | R' | | Y | + * | G' | = M *| Pb | + * | B' | | Pr | + * where + * | vecR | + * M = | vecG | + * | vecB | + * vecR = | 1, 0 , 2(1 - Kr) | + * vecG = | 1, -(Kb/Kg) * 2(1 - Kb), -(Kr/Kg) * 2(1 - Kr) | + * vecB = | 1, 2(1 - Kb) , 0 | + * => + * R' = dot(vecR, (Syuv * Y'CbCr(unorm))) + dot(vecR, Offset) + * G' = dot(vecG, (Svuy * Y'CbCr(unorm))) + dot(vecG, Offset) + * B' = dot(vecB, (Syuv * Y'CbCr(unorm)) + dot(vecB, Offset) + * where + * | Sy, 0, 0 | + * Syuv = | 0, Suv, 0 | + * | 0 0, Suv | + * + * | Oy | + * Offset = | Ouv | + * | Ouv | + * + * 4) YUV -> RGB matrix + * | R' | | Y'(unorm) | | offsetA | + * | G' | = Matrix * | Cb(unorm) | + | offsetB | + * | B' | | Cr(unorm) | | offsetC | + * + * where + * | vecR | + * Matrix = | vecG | * Syuv + * | vecB | + * + * offsetA = dot(vecR, Offset) + * offsetB = dot(vecG, Offset) + * offsetC = dot(vecB, Offset) + * + * 4) Consider 16-235 scale RGB + * RGBfull(0..255) -> RGBfull(16..235) matrix is represented by + * | Rs | | Rf | | Or | + * | Gs | = Ms | Gf | + | Og | + * | Bs | | Bf | | Ob | + * + * Combining all matrix into + * | Rs | | Y'(unorm) | | offsetA | | Or | + * | Gs | = Ms * ( Matrix * | Cb(unorm) | + | offsetB | ) + | Og | + * | Bs | | Cr(unorm) | | offsetC | | Ob | + * + * | Y'(unorm) | | offsetA | | Or | + * = Ms * Matrix * | Cb(unorm) | + Ms | offsetB | + | Og | + * | Cr(unorm) | | offsetC | | Ob | + */ + + memset (matrix, 0, sizeof (GstD3D11ColorMatrix)); + for (guint i = 0; i < 3; i++) + matrix->max[i] = 1.0; + + gst_video_color_range_offsets (in_yuv_info->colorimetry.range, + in_yuv_info->finfo, offset, scale); + + if (gst_video_color_matrix_get_Kr_Kb (in_yuv_info->colorimetry.matrix, + &Kr, &Kb)) { + guint S; + gdouble Sy, Suv; + gdouble Oy, Ouv; + gdouble vecR[3], vecG[3], vecB[3]; + + Kg = 1.0 - Kr - Kb; + + vecR[0] = 1.0; + vecR[1] = 0; + vecR[2] = 2 * (1 - Kr); + + vecG[0] = 1.0; + vecG[1] = -(Kb / Kg) * 2 * (1 - Kb); + vecG[2] = -(Kr / Kg) * 2 * (1 - Kr); + + vecB[0] = 1.0; + vecB[1] = 2 * (1 - Kb); + vecB[2] = 0; + + /* Assume all components has the same bitdepth */ + S = (1 << in_yuv_info->finfo->depth[0]) - 1; + Sy = (gdouble) S / scale[0]; + Suv = (gdouble) S / scale[1]; + Oy = -((gdouble) offset[0] / scale[0]); + Ouv = -((gdouble) offset[1] / scale[1]); + + matrix->matrix[0][0] = Sy * vecR[0]; + matrix->matrix[1][0] = Sy * vecG[0]; + matrix->matrix[2][0] = Sy * vecB[0]; + + matrix->matrix[0][1] = Suv * vecR[1]; + matrix->matrix[1][1] = Suv * vecG[1]; + matrix->matrix[2][1] = Suv * vecB[1]; + + matrix->matrix[0][2] = Suv * vecR[2]; + matrix->matrix[1][2] = Suv * vecG[2]; + matrix->matrix[2][2] = Suv * vecB[2]; + + matrix->offset[0] = vecR[0] * Oy + vecR[1] * Ouv + vecR[2] * Ouv; + matrix->offset[1] = vecG[0] * Oy + vecG[1] * Ouv + vecG[2] * Ouv; + matrix->offset[2] = vecB[0] * Oy + vecB[1] * Ouv + vecB[2] * Ouv; + + /* Apply RGB range scale matrix */ + if (out_rgb_info->colorimetry.range == GST_VIDEO_COLOR_RANGE_16_235) { + GstD3D11ColorMatrix scale_matrix, rst; + GstVideoInfo full_rgb = *out_rgb_info; + + full_rgb.colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255; + + if (gst_d3d11_color_range_adjust_matrix_unorm (&full_rgb, + out_rgb_info, &scale_matrix)) { + /* Ms * Matrix */ + color_matrix_multiply (&rst, &scale_matrix, matrix); + + /* Ms * transform offsets */ + for (guint i = 0; i < 3; i++) { + gdouble val = 0; + for (guint j = 0; j < 3; j++) { + val += scale_matrix.matrix[i][j] * matrix->offset[j]; + } + rst.offset[i] = val + scale_matrix.offset[i]; + } + + /* copy back to output matrix */ + for (guint i = 0; i < 3; i++) { + for (guint j = 0; j < 3; j++) { + matrix->matrix[i][j] = rst.matrix[i][j]; + } + matrix->offset[i] = rst.offset[i]; + matrix->min[i] = scale_matrix.min[i]; + matrix->max[i] = scale_matrix.max[i]; + } + } + } + } else { + /* Unknown matrix */ + matrix->matrix[0][0] = 1.0; + matrix->matrix[1][1] = 1.0; + matrix->matrix[2][2] = 1.0; + } + + return TRUE; +} + +/** + * gst_d3d11_rgb_to_yuv_matrix_unorm: + * @in_rgb_info: a #GstVideoInfo of input RGB signal + * @out_yuv_info: a #GstVideoInfo of output YUV signal + * @matrix: a #GstD3D11ColorMatrix + * + * Calculates transform matrix from RGB to YUV conversion. Both input and output + * signals are in normalized [0.0..1.0] space and additional gamma decoding + * or primary/transfer function transform is not performed by this matrix. + * + * Resulting RGB values can be calculated by + * | Y' | | R' | | matrix.offset[0] | + * | Cb | = clamp ( matrix.matrix * | G' | + | matrix.offset[1] |, matrix.min, matrix.max ) + * | Cr | | B' | | matrix.offset[2] | + * + * Returns: %TRUE if successful + */ +gboolean +gst_d3d11_rgb_to_yuv_matrix_unorm (const GstVideoInfo * in_rgb_info, + const GstVideoInfo * out_yuv_info, GstD3D11ColorMatrix * matrix) +{ + gint offset[4], scale[4]; + gdouble Kr, Kb, Kg; + + g_return_val_if_fail (in_rgb_info != nullptr, FALSE); + g_return_val_if_fail (out_yuv_info != nullptr, FALSE); + g_return_val_if_fail (matrix != nullptr, FALSE); + + /* + * + * + * Input: Unsigned normalized non-linear R'G'B'(unorm), [0.0..1.0] range + * Output: Unsigned normalized Y'CbCr(unorm), [0.0..1.0] range + * + * 1) R'G'B' to YPbPr + * | Y | | R' | + * | Pb | = M *| G' | + * | Pr | | B' | + * where + * | vecY | + * M = | vecU | + * | vecV | + * vecY = | Kr , Kg , Kb | + * vecU = | -0.5*Kr/(1-Kb), -0.5*Kg/(1-Kb), 0.5 | + * vecV = | 0.5 , -0.5*Kg/(1-Kr), -0.5*Kb(1-Kr) | + * + * 2) YPbPr to Y'CbCr(unorm) + * Y'(unorm) = (Y * scaleY + offsetY) / S + * Cb(unorm) = (Pb * scaleCbCr + offsetCbCr) / S + * Cr(unorm) = (Pr * scaleCbCr + offsetCbCr) / S + * => + * Y'(unorm) = (Y * scaleY / S) + (offsetY / S) + * Cb(unorm) = (Pb * scaleCbCr / S) + (offsetCbCr / S) + * Cr(unorm) = (Pb * scaleCbCr / S) + (offsetCbCr / S) + * where S = (2 ^ bitdepth) - 1 + * + * 3) RGB -> YUV matrix + * | Y'(unorm) | | R' | | offsetA | + * | Cb(unorm) | = Matrix * | G' | + | offsetB | + * | Cr(unorm) | | B' | | offsetC | + * + * where + * | (scaleY/S) * vecY | + * Matrix = | (scaleCbCr/S) * vecU | + * | (scaleCbCr/S) * vecV | + * + * offsetA = offsetY / S + * offsetB = offsetCbCr / S + * offsetC = offsetCbCr / S + * + * 4) Consider 16-235 scale RGB + * RGBstudio(16..235) -> RGBfull(0..255) matrix is represented by + * | Rf | | Rs | | Or | + * | Gf | = Ms | Gs | + | Og | + * | Bf | | Bs | | Ob | + * + * Combining all matrix into + * | Y'(unorm) | | Rs | | Or | | offsetA | + * | Cb(unorm) | = Matrix * ( Ms | Gs | + | Og | ) + | offsetB | + * | Cr(unorm) | | Bs | | Ob | | offsetC | + * + * | Rs | | Or | | offsetA | + * = Matrix * Ms | Gs | + Matrix | Og | + | offsetB | + * | Bs | | Ob | | offsetB | + */ + + memset (matrix, 0, sizeof (GstD3D11ColorMatrix)); + for (guint i = 0; i < 3; i++) + matrix->max[i] = 1.0; + + gst_video_color_range_offsets (out_yuv_info->colorimetry.range, + out_yuv_info->finfo, offset, scale); + + if (gst_video_color_matrix_get_Kr_Kb (out_yuv_info->colorimetry.matrix, + &Kr, &Kb)) { + guint S; + gdouble Sy, Suv; + gdouble Oy, Ouv; + gdouble vecY[3], vecU[3], vecV[3]; + + Kg = 1.0 - Kr - Kb; + + vecY[0] = Kr; + vecY[1] = Kg; + vecY[2] = Kb; + + vecU[0] = -0.5 * Kr / (1 - Kb); + vecU[1] = -0.5 * Kg / (1 - Kb); + vecU[2] = 0.5; + + vecV[0] = 0.5; + vecV[1] = -0.5 * Kg / (1 - Kr); + vecV[2] = -0.5 * Kb / (1 - Kr); + + /* Assume all components has the same bitdepth */ + S = (1 << out_yuv_info->finfo->depth[0]) - 1; + Sy = (gdouble) scale[0] / S; + Suv = (gdouble) scale[1] / S; + Oy = (gdouble) offset[0] / S; + Ouv = (gdouble) offset[1] / S; + + for (guint i = 0; i < 3; i++) { + matrix->matrix[0][i] = Sy * vecY[i]; + matrix->matrix[1][i] = Suv * vecU[i]; + matrix->matrix[2][i] = Suv * vecV[i]; + } + + matrix->offset[0] = Oy; + matrix->offset[1] = Ouv; + matrix->offset[2] = Ouv; + + matrix->min[0] = Oy; + matrix->min[1] = Oy; + matrix->min[2] = Oy; + + matrix->max[0] = ((gdouble) scale[0] + offset[0]) / S; + matrix->max[1] = ((gdouble) scale[1] + offset[0]) / S; + matrix->max[2] = ((gdouble) scale[1] + offset[0]) / S; + + /* Apply RGB range scale matrix */ + if (in_rgb_info->colorimetry.range == GST_VIDEO_COLOR_RANGE_16_235) { + GstD3D11ColorMatrix scale_matrix, rst; + GstVideoInfo full_rgb = *in_rgb_info; + + full_rgb.colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255; + + if (gst_d3d11_color_range_adjust_matrix_unorm (in_rgb_info, + &full_rgb, &scale_matrix)) { + /* Matrix * Ms */ + color_matrix_multiply (&rst, matrix, &scale_matrix); + + /* Matrix * scale offsets */ + for (guint i = 0; i < 3; i++) { + gdouble val = 0; + for (guint j = 0; j < 3; j++) { + val += matrix->matrix[i][j] * scale_matrix.offset[j]; + } + rst.offset[i] = val + matrix->offset[i]; + } + + /* copy back to output matrix */ + for (guint i = 0; i < 3; i++) { + for (guint j = 0; j < 3; j++) { + matrix->matrix[i][j] = rst.matrix[i][j]; + } + matrix->offset[i] = rst.offset[i]; + } + } + } + } else { + /* Unknown matrix */ + matrix->matrix[0][0] = 1.0; + matrix->matrix[1][1] = 1.0; + matrix->matrix[2][2] = 1.0; + } + + return TRUE; +} + +static gboolean +rgb_to_xyz_matrix (const GstVideoColorPrimariesInfo * info, + GstD3D11ColorMatrix * matrix) +{ + GstD3D11ColorMatrix m, im; + gdouble Sr, Sg, Sb; + gdouble Xw, Yw, Zw; + + if (info->Rx == 0 || info->Gx == 0 || info->By == 0 || info->Wy == 0) + return FALSE; + + color_matrix_identity (&m); + + m.matrix[0][0] = info->Rx / info->Ry; + m.matrix[1][0] = 1.0; + m.matrix[2][0] = (1.0 - info->Rx - info->Ry) / info->Ry; + + m.matrix[0][1] = info->Gx / info->Gy; + m.matrix[1][1] = 1.0; + m.matrix[2][1] = (1.0 - info->Gx - info->Gy) / info->Gy; + + m.matrix[0][2] = info->Bx / info->By; + m.matrix[1][2] = 1.0; + m.matrix[2][2] = (1.0 - info->Bx - info->By) / info->By; + + if (!color_matrix_invert (&im, &m)) + return FALSE; + + Xw = info->Wx / info->Wy; + Yw = 1.0; + Zw = (1.0 - info->Wx - info->Wy) / info->Wy; + + Sr = im.matrix[0][0] * Xw + im.matrix[0][1] * Yw + im.matrix[0][2] * Zw; + Sg = im.matrix[1][0] * Xw + im.matrix[1][1] * Yw + im.matrix[1][2] * Zw; + Sb = im.matrix[2][0] * Xw + im.matrix[2][1] * Yw + im.matrix[2][2] * Zw; + + for (guint i = 0; i < 3; i++) { + m.matrix[i][0] *= Sr; + m.matrix[i][1] *= Sg; + m.matrix[i][2] *= Sb; + } + + color_matrix_copy (matrix, &m); + + return TRUE; +} + +/** + * gst_d3d11_color_primaries_matrix_unorm: + * @in_info: a #GstVideoColorPrimariesInfo of input signal + * @out_info: a #GstVideoColorPrimariesInfo of output signal + * @matrix: a #GstD3D11ColorMatrix + * + * Calculates color primaries conversion matrix + * + * Resulting RGB values can be calculated by + * | Rout | | Rin | + * | Gout | = saturate ( matrix.matrix * | Gin | ) + * | Bout | | Bin | + * + * Returns: %TRUE if successful + */ +gboolean +gst_d3d11_color_primaries_matrix_unorm (const GstVideoColorPrimariesInfo * + in_info, const GstVideoColorPrimariesInfo * out_info, + GstD3D11ColorMatrix * matrix) +{ + GstD3D11ColorMatrix Ms, invMd, ret; + + g_return_val_if_fail (in_info != nullptr, FALSE); + g_return_val_if_fail (out_info != nullptr, FALSE); + g_return_val_if_fail (matrix != nullptr, FALSE); + + /* + * + * + * 1) RGB -> XYZ conversion + * | X | | R | + * | Y | = M | G | + * | Z | | B | + * where + * | SrXr, SgXg, SbXb | + * M = | SrYr, SgYg, SbYb | + * | SrZr, SgZg, SbZb | + * + * Xr = xr / yr + * Yr = 1 + * Zr = (1 - xr - yr) / yr + * xr and yr are xy coordinates of red primary in the CIE 1931 color space. + * And its applied to G and B components + * + * | Sr | | Xr, Xg, Xb | | Xw | + * | Sg | = inv( | Yr, Yg, Yb | ) * | Yw | + * | Sb | | Zr, Zg, Zb | | Zw | + * + * 2) XYZsrc -> XYZdst conversion + * Apply chromatic adaptation + * | Xdst | | Xsrc | + * | Ydst | = Mc | Ysrc | + * | Zdst | | Zsrc | + * where + * | Xwdst / Xwsrc, 0 , 0 | + * Mc = | 0 , Ywdst / Ywsrc, 0 | + * | 0 , 0 , Zwdst / Zwsrc | + * + * where + * + * 3) Final matrix + * | Rd | | Rs | + * | Gd | = inv (Md) * Mc * Ms | Gs | + * | Bd | | Bs | + */ + + memset (matrix, 0, sizeof (GstD3D11ColorMatrix)); + for (guint i = 0; i < 3; i++) + matrix->max[i] = 1.0; + + if (!rgb_to_xyz_matrix (in_info, &Ms)) { + GST_WARNING ("Failed to get src XYZ matrix"); + return FALSE; + } + + if (!rgb_to_xyz_matrix (out_info, &invMd) || + !color_matrix_invert (&invMd, &invMd)) { + GST_WARNING ("Failed to get dst XYZ matrix"); + return FALSE; + } + + if (in_info->Wx != out_info->Wx || in_info->Wy != out_info->Wy) { + GstD3D11ColorMatrix Mc; + + color_matrix_identity (&Mc); + Mc.matrix[0][0] = (out_info->Wx / out_info->Wy) / + (in_info->Wx / in_info->Wy); + /* Yw == 1.0 */ + Mc.matrix[2][2] = ((1.0 - out_info->Wx - out_info->Wy) / out_info->Wy) / + ((1.0 - in_info->Wx - in_info->Wy) / in_info->Wy); + + color_matrix_multiply (&ret, &Mc, &Ms); + } else { + color_matrix_copy (&ret, &Ms); + } + + color_matrix_multiply (&ret, &invMd, &ret); + color_matrix_copy (matrix, &ret); + + return TRUE; +} diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/meson.build b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/meson.build index abb3c833ad..65d54f16e7 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/meson.build +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/meson.build @@ -1,6 +1,7 @@ d3d11_sources = [ 'gstd3d11bufferpool.cpp', 'gstd3d11compile.cpp', + 'gstd3d11converter.cpp', 'gstd3d11device.cpp', 'gstd3d11format.cpp', 'gstd3d11memory.cpp', @@ -12,6 +13,7 @@ d3d11_headers = [ 'gstd3d11_fwd.h', 'gstd3d11.h', 'gstd3d11bufferpool.h', + 'gstd3d11converter.h', 'gstd3d11device.h', 'gstd3d11format.h', 'gstd3d11memory.h', @@ -21,6 +23,7 @@ d3d11_headers = [ d3d11_enum_types_headers = [ 'gstd3d11_fwd.h', 'gstd3d11bufferpool.h', + 'gstd3d11converter.h', 'gstd3d11device.h', 'gstd3d11format.h', 'gstd3d11memory.h', diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11compositor.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11compositor.cpp index d91c88778f..fab6e67ac9 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11compositor.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11compositor.cpp @@ -43,7 +43,6 @@ #endif #include "gstd3d11compositor.h" -#include "gstd3d11converter.h" #include "gstd3d11pluginutils.h" #include #include diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11convert.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11convert.cpp index 8530e9a034..39d355d3ce 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11convert.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11convert.cpp @@ -27,7 +27,6 @@ #endif #include "gstd3d11convert.h" -#include "gstd3d11converter.h" #include "gstd3d11pluginutils.h" GST_DEBUG_CATEGORY_STATIC (gst_d3d11_convert_debug); diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11decoder.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11decoder.cpp index fd000c04c8..9405b69f8f 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11decoder.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11decoder.cpp @@ -52,7 +52,6 @@ #endif #include "gstd3d11decoder.h" -#include "gstd3d11converter.h" #include "gstd3d11pluginutils.h" #include #include diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.cpp index da495cd552..02fa4b37bd 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.cpp @@ -655,758 +655,3 @@ gst_d3d11_buffer_pool_new_with_options (GstD3D11Device * device, return pool; } - -gchar * -gst_d3d11_dump_color_matrix (GstD3D11ColorMatrix * matrix) -{ - /* *INDENT-OFF* */ - static const gchar format[] = - "[MATRIX]\n" - "|% .6f, % .6f, % .6f|\n" - "|% .6f, % .6f, % .6f|\n" - "|% .6f, % .6f, % .6f|\n" - "[OFFSET]\n" - "|% .6f, % .6f, % .6f|\n" - "[MIN]\n" - "|% .6f, % .6f, % .6f|\n" - "[MAX]\n" - "|% .6f, % .6f, % .6f|"; - /* *INDENT-ON* */ - - g_return_val_if_fail (matrix != nullptr, nullptr); - - return g_strdup_printf (format, - matrix->matrix[0][0], matrix->matrix[0][1], matrix->matrix[0][2], - matrix->matrix[1][0], matrix->matrix[1][1], matrix->matrix[1][2], - matrix->matrix[2][0], matrix->matrix[2][1], matrix->matrix[2][2], - matrix->offset[0], matrix->offset[1], matrix->offset[2], - matrix->min[0], matrix->min[1], matrix->min[2], - matrix->max[0], matrix->max[1], matrix->max[2]); -} - -static void -color_matrix_copy (GstD3D11ColorMatrix * dst, const GstD3D11ColorMatrix * src) -{ - for (guint i = 0; i < 3; i++) { - for (guint j = 0; j < 3; j++) { - dst->matrix[i][j] = src->matrix[i][j]; - } - } -} - -static void -color_matrix_multiply (GstD3D11ColorMatrix * dst, GstD3D11ColorMatrix * a, - GstD3D11ColorMatrix * b) -{ - GstD3D11ColorMatrix tmp; - - for (guint i = 0; i < 3; i++) { - for (guint j = 0; j < 3; j++) { - gdouble val = 0; - for (guint k = 0; k < 3; k++) { - val += a->matrix[i][k] * b->matrix[k][j]; - } - - tmp.matrix[i][j] = val; - } - } - - color_matrix_copy (dst, &tmp); -} - -static void -color_matrix_identity (GstD3D11ColorMatrix * m) -{ - for (guint i = 0; i < 3; i++) { - for (guint j = 0; j < 3; j++) { - if (i == j) - m->matrix[i][j] = 1.0; - else - m->matrix[i][j] = 0; - } - } -} - -static gboolean -color_matrix_invert (GstD3D11ColorMatrix * dst, GstD3D11ColorMatrix * src) -{ - GstD3D11ColorMatrix tmp; - gdouble det; - - color_matrix_identity (&tmp); - for (guint j = 0; j < 3; j++) { - for (guint i = 0; i < 3; i++) { - tmp.matrix[j][i] = - src->matrix[(i + 1) % 3][(j + 1) % 3] * - src->matrix[(i + 2) % 3][(j + 2) % 3] - - src->matrix[(i + 1) % 3][(j + 2) % 3] * - src->matrix[(i + 2) % 3][(j + 1) % 3]; - } - } - - det = tmp.matrix[0][0] * src->matrix[0][0] + - tmp.matrix[0][1] * src->matrix[1][0] + - tmp.matrix[0][2] * src->matrix[2][0]; - if (det == 0) - return FALSE; - - for (guint j = 0; j < 3; j++) { - for (guint i = 0; i < 3; i++) { - tmp.matrix[i][j] /= det; - } - } - - color_matrix_copy (dst, &tmp); - - return TRUE; -} - -/** - * gst_d3d11_color_range_adjust_matrix_unorm: - * @in_info: a #GstVideoInfo - * @out_info: a #GstVideoInfo - * @matrix: a #GstD3D11ColorMatrix - * - * Calculates matrix for color range adjustment. Both input and output - * signals are in normalized [0.0..1.0] space. - * - * Resulting values can be calculated by - * | Yout | | Yin | | matrix.offset[0] | - * | Uout | = clamp ( matrix.matrix * | Uin | + | matrix.offset[1] |, matrix.min, matrix.max ) - * | Vout | | Vin | | matrix.offset[2] | - * - * Returns: %TRUE if successful - */ -gboolean -gst_d3d11_color_range_adjust_matrix_unorm (const GstVideoInfo * in_info, - const GstVideoInfo * out_info, GstD3D11ColorMatrix * matrix) -{ - gboolean in_rgb, out_rgb; - gint in_offset[GST_VIDEO_MAX_COMPONENTS]; - gint in_scale[GST_VIDEO_MAX_COMPONENTS]; - gint out_offset[GST_VIDEO_MAX_COMPONENTS]; - gint out_scale[GST_VIDEO_MAX_COMPONENTS]; - GstVideoColorRange in_range; - GstVideoColorRange out_range; - gdouble src_fullscale, dst_fullscale; - - g_return_val_if_fail (in_info != nullptr, FALSE); - g_return_val_if_fail (out_info != nullptr, FALSE); - g_return_val_if_fail (matrix != nullptr, FALSE); - - memset (matrix, 0, sizeof (GstD3D11ColorMatrix)); - for (guint i = 0; i < 3; i++) { - matrix->matrix[i][i] = 1.0; - matrix->matrix[i][i] = 1.0; - matrix->matrix[i][i] = 1.0; - matrix->max[i] = 1.0; - } - - in_rgb = GST_VIDEO_INFO_IS_RGB (in_info); - out_rgb = GST_VIDEO_INFO_IS_RGB (out_info); - - if (in_rgb != out_rgb) { - GST_WARNING ("Invalid format conversion"); - return FALSE; - } - - in_range = in_info->colorimetry.range; - out_range = out_info->colorimetry.range; - - if (in_range == GST_VIDEO_COLOR_RANGE_UNKNOWN) { - GST_WARNING ("Unknown input color range"); - if (in_rgb || GST_VIDEO_INFO_IS_GRAY (in_info)) - in_range = GST_VIDEO_COLOR_RANGE_0_255; - else - in_range = GST_VIDEO_COLOR_RANGE_16_235; - } - - if (out_range == GST_VIDEO_COLOR_RANGE_UNKNOWN) { - GST_WARNING ("Unknown output color range"); - if (out_rgb || GST_VIDEO_INFO_IS_GRAY (out_info)) - out_range = GST_VIDEO_COLOR_RANGE_0_255; - else - out_range = GST_VIDEO_COLOR_RANGE_16_235; - } - - src_fullscale = (gdouble) ((1 << in_info->finfo->depth[0]) - 1); - dst_fullscale = (gdouble) ((1 << out_info->finfo->depth[0]) - 1); - - gst_video_color_range_offsets (in_range, in_info->finfo, in_offset, in_scale); - gst_video_color_range_offsets (out_range, - out_info->finfo, out_offset, out_scale); - - matrix->min[0] = matrix->min[1] = matrix->min[2] = - (gdouble) out_offset[0] / dst_fullscale; - - matrix->max[0] = (out_scale[0] + out_offset[0]) / dst_fullscale; - matrix->max[1] = matrix->max[2] = - (out_scale[1] + out_offset[0]) / dst_fullscale; - - if (in_info->colorimetry.range == out_info->colorimetry.range) { - GST_DEBUG ("Same color range"); - return TRUE; - } - - /* Formula - * - * 1) Scales and offset compensates input to [0..1] range - * SRC_NORM[i] = (src[i] * src_fullscale - in_offset[i]) / in_scale[i] - * = (src[i] * src_fullscale / in_scale[i]) - in_offset[i] / in_scale[i] - * - * 2) Reverse to output UNIT scale - * DST_UINT[i] = SRC_NORM[i] * out_scale[i] + out_offset[i] - * = src[i] * src_fullscale * out_scale[i] / in_scale[i] - * - in_offset[i] * out_scale[i] / in_scale[i] - * + out_offset[i] - * - * 3) Back to [0..1] scale - * dst[i] = DST_UINT[i] / dst_fullscale - * = COEFF[i] * src[i] + OFF[i] - * where - * src_fullscale * out_scale[i] - * COEFF[i] = ------------------------------ - * dst_fullscale * in_scale[i] - * - * out_offset[i] in_offset[i] * out_scale[i] - * OFF[i] = -------------- - ------------------------------ - * dst_fullscale dst_fullscale * in_scale[i] - */ - for (guint i = 0; i < 3; i++) { - matrix->matrix[i][i] = (src_fullscale * out_scale[i]) / - (dst_fullscale * in_scale[i]); - matrix->offset[i] = (out_offset[i] / dst_fullscale) - - ((gdouble) in_offset[i] * out_scale[i] / (dst_fullscale * in_scale[i])); - } - - return TRUE; -} - -/** - * gst_d3d11_yuv_to_rgb_matrix_unorm: - * @in_yuv_info: a #GstVideoInfo of input YUV signal - * @out_rgb_info: a #GstVideoInfo of output RGB signal - * @matrix: a #GstD3D11ColorMatrix - * - * Calculates transform matrix from YUV to RGB conversion. Both input and output - * signals are in normalized [0.0..1.0] space and additional gamma decoding - * or primary/transfer function transform is not performed by this matrix. - * - * Resulting non-linear RGB values can be calculated by - * | R' | | Y' | | matrix.offset[0] | - * | G' | = clamp ( matrix.matrix * | Cb | + | matrix.offset[1] | matrix.min, matrix.max ) - * | B' | | Cr | | matrix.offset[2] | - * - * Returns: %TRUE if successful - */ -gboolean -gst_d3d11_yuv_to_rgb_matrix_unorm (const GstVideoInfo * in_yuv_info, - const GstVideoInfo * out_rgb_info, GstD3D11ColorMatrix * matrix) -{ - gint offset[4], scale[4]; - gdouble Kr, Kb, Kg; - - g_return_val_if_fail (in_yuv_info != nullptr, FALSE); - g_return_val_if_fail (out_rgb_info != nullptr, FALSE); - g_return_val_if_fail (matrix != nullptr, FALSE); - - /* - * - * - * Input: Unsigned normalized Y'CbCr(unorm), [0.0..1.0] range - * Output: Unsigned normalized non-linear R'G'B'(unorm), [0.0..1.0] range - * - * 1) Y'CbCr(unorm) to scaled Y'CbCr - * | Y' | | Y'(unorm) | - * | Cb | = S | Cb(unorm) | - * | Cb | | Cr(unorm) | - * where S = (2 ^ bitdepth) - 1 - * - * 2) Y'CbCr to YPbPr - * Y = (Y' - offsetY ) / scaleY - * Pb = [(Cb - offsetCbCr) / scaleCbCr] - * Pr = [(Cr - offsetCrCr) / scaleCrCr] - * => - * Y = Y'(unorm) * Sy + Oy - * Pb = Cb(unorm) * Suv + Ouv - * Pb = Cr(unorm) * Suv + Ouv - * where - * Sy = S / scaleY - * Suv = S / scaleCbCr - * Oy = -(offsetY / scaleY) - * Ouv = -(offsetCbCr / scaleCbCr) - * - * 3) YPbPr to R'G'B' - * | R' | | Y | - * | G' | = M *| Pb | - * | B' | | Pr | - * where - * | vecR | - * M = | vecG | - * | vecB | - * vecR = | 1, 0 , 2(1 - Kr) | - * vecG = | 1, -(Kb/Kg) * 2(1 - Kb), -(Kr/Kg) * 2(1 - Kr) | - * vecB = | 1, 2(1 - Kb) , 0 | - * => - * R' = dot(vecR, (Syuv * Y'CbCr(unorm))) + dot(vecR, Offset) - * G' = dot(vecG, (Svuy * Y'CbCr(unorm))) + dot(vecG, Offset) - * B' = dot(vecB, (Syuv * Y'CbCr(unorm)) + dot(vecB, Offset) - * where - * | Sy, 0, 0 | - * Syuv = | 0, Suv, 0 | - * | 0 0, Suv | - * - * | Oy | - * Offset = | Ouv | - * | Ouv | - * - * 4) YUV -> RGB matrix - * | R' | | Y'(unorm) | | offsetA | - * | G' | = Matrix * | Cb(unorm) | + | offsetB | - * | B' | | Cr(unorm) | | offsetC | - * - * where - * | vecR | - * Matrix = | vecG | * Syuv - * | vecB | - * - * offsetA = dot(vecR, Offset) - * offsetB = dot(vecG, Offset) - * offsetC = dot(vecB, Offset) - * - * 4) Consider 16-235 scale RGB - * RGBfull(0..255) -> RGBfull(16..235) matrix is represented by - * | Rs | | Rf | | Or | - * | Gs | = Ms | Gf | + | Og | - * | Bs | | Bf | | Ob | - * - * Combining all matrix into - * | Rs | | Y'(unorm) | | offsetA | | Or | - * | Gs | = Ms * ( Matrix * | Cb(unorm) | + | offsetB | ) + | Og | - * | Bs | | Cr(unorm) | | offsetC | | Ob | - * - * | Y'(unorm) | | offsetA | | Or | - * = Ms * Matrix * | Cb(unorm) | + Ms | offsetB | + | Og | - * | Cr(unorm) | | offsetC | | Ob | - */ - - memset (matrix, 0, sizeof (GstD3D11ColorMatrix)); - for (guint i = 0; i < 3; i++) - matrix->max[i] = 1.0; - - gst_video_color_range_offsets (in_yuv_info->colorimetry.range, - in_yuv_info->finfo, offset, scale); - - if (gst_video_color_matrix_get_Kr_Kb (in_yuv_info->colorimetry.matrix, - &Kr, &Kb)) { - guint S; - gdouble Sy, Suv; - gdouble Oy, Ouv; - gdouble vecR[3], vecG[3], vecB[3]; - - Kg = 1.0 - Kr - Kb; - - vecR[0] = 1.0; - vecR[1] = 0; - vecR[2] = 2 * (1 - Kr); - - vecG[0] = 1.0; - vecG[1] = -(Kb / Kg) * 2 * (1 - Kb); - vecG[2] = -(Kr / Kg) * 2 * (1 - Kr); - - vecB[0] = 1.0; - vecB[1] = 2 * (1 - Kb); - vecB[2] = 0; - - /* Assume all components has the same bitdepth */ - S = (1 << in_yuv_info->finfo->depth[0]) - 1; - Sy = (gdouble) S / scale[0]; - Suv = (gdouble) S / scale[1]; - Oy = -((gdouble) offset[0] / scale[0]); - Ouv = -((gdouble) offset[1] / scale[1]); - - matrix->matrix[0][0] = Sy * vecR[0]; - matrix->matrix[1][0] = Sy * vecG[0]; - matrix->matrix[2][0] = Sy * vecB[0]; - - matrix->matrix[0][1] = Suv * vecR[1]; - matrix->matrix[1][1] = Suv * vecG[1]; - matrix->matrix[2][1] = Suv * vecB[1]; - - matrix->matrix[0][2] = Suv * vecR[2]; - matrix->matrix[1][2] = Suv * vecG[2]; - matrix->matrix[2][2] = Suv * vecB[2]; - - matrix->offset[0] = vecR[0] * Oy + vecR[1] * Ouv + vecR[2] * Ouv; - matrix->offset[1] = vecG[0] * Oy + vecG[1] * Ouv + vecG[2] * Ouv; - matrix->offset[2] = vecB[0] * Oy + vecB[1] * Ouv + vecB[2] * Ouv; - - /* Apply RGB range scale matrix */ - if (out_rgb_info->colorimetry.range == GST_VIDEO_COLOR_RANGE_16_235) { - GstD3D11ColorMatrix scale_matrix, rst; - GstVideoInfo full_rgb = *out_rgb_info; - - full_rgb.colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255; - - if (gst_d3d11_color_range_adjust_matrix_unorm (&full_rgb, - out_rgb_info, &scale_matrix)) { - /* Ms * Matrix */ - color_matrix_multiply (&rst, &scale_matrix, matrix); - - /* Ms * transform offsets */ - for (guint i = 0; i < 3; i++) { - gdouble val = 0; - for (guint j = 0; j < 3; j++) { - val += scale_matrix.matrix[i][j] * matrix->offset[j]; - } - rst.offset[i] = val + scale_matrix.offset[i]; - } - - /* copy back to output matrix */ - for (guint i = 0; i < 3; i++) { - for (guint j = 0; j < 3; j++) { - matrix->matrix[i][j] = rst.matrix[i][j]; - } - matrix->offset[i] = rst.offset[i]; - matrix->min[i] = scale_matrix.min[i]; - matrix->max[i] = scale_matrix.max[i]; - } - } - } - } else { - /* Unknown matrix */ - matrix->matrix[0][0] = 1.0; - matrix->matrix[1][1] = 1.0; - matrix->matrix[2][2] = 1.0; - } - - return TRUE; -} - -/** - * gst_d3d11_rgb_to_yuv_matrix_unorm: - * @in_rgb_info: a #GstVideoInfo of input RGB signal - * @out_yuv_info: a #GstVideoInfo of output YUV signal - * @matrix: a #GstD3D11ColorMatrix - * - * Calculates transform matrix from RGB to YUV conversion. Both input and output - * signals are in normalized [0.0..1.0] space and additional gamma decoding - * or primary/transfer function transform is not performed by this matrix. - * - * Resulting RGB values can be calculated by - * | Y' | | R' | | matrix.offset[0] | - * | Cb | = clamp ( matrix.matrix * | G' | + | matrix.offset[1] |, matrix.min, matrix.max ) - * | Cr | | B' | | matrix.offset[2] | - * - * Returns: %TRUE if successful - */ -gboolean -gst_d3d11_rgb_to_yuv_matrix_unorm (const GstVideoInfo * in_rgb_info, - const GstVideoInfo * out_yuv_info, GstD3D11ColorMatrix * matrix) -{ - gint offset[4], scale[4]; - gdouble Kr, Kb, Kg; - - g_return_val_if_fail (in_rgb_info != nullptr, FALSE); - g_return_val_if_fail (out_yuv_info != nullptr, FALSE); - g_return_val_if_fail (matrix != nullptr, FALSE); - - /* - * - * - * Input: Unsigned normalized non-linear R'G'B'(unorm), [0.0..1.0] range - * Output: Unsigned normalized Y'CbCr(unorm), [0.0..1.0] range - * - * 1) R'G'B' to YPbPr - * | Y | | R' | - * | Pb | = M *| G' | - * | Pr | | B' | - * where - * | vecY | - * M = | vecU | - * | vecV | - * vecY = | Kr , Kg , Kb | - * vecU = | -0.5*Kr/(1-Kb), -0.5*Kg/(1-Kb), 0.5 | - * vecV = | 0.5 , -0.5*Kg/(1-Kr), -0.5*Kb(1-Kr) | - * - * 2) YPbPr to Y'CbCr(unorm) - * Y'(unorm) = (Y * scaleY + offsetY) / S - * Cb(unorm) = (Pb * scaleCbCr + offsetCbCr) / S - * Cr(unorm) = (Pr * scaleCbCr + offsetCbCr) / S - * => - * Y'(unorm) = (Y * scaleY / S) + (offsetY / S) - * Cb(unorm) = (Pb * scaleCbCr / S) + (offsetCbCr / S) - * Cr(unorm) = (Pb * scaleCbCr / S) + (offsetCbCr / S) - * where S = (2 ^ bitdepth) - 1 - * - * 3) RGB -> YUV matrix - * | Y'(unorm) | | R' | | offsetA | - * | Cb(unorm) | = Matrix * | G' | + | offsetB | - * | Cr(unorm) | | B' | | offsetC | - * - * where - * | (scaleY/S) * vecY | - * Matrix = | (scaleCbCr/S) * vecU | - * | (scaleCbCr/S) * vecV | - * - * offsetA = offsetY / S - * offsetB = offsetCbCr / S - * offsetC = offsetCbCr / S - * - * 4) Consider 16-235 scale RGB - * RGBstudio(16..235) -> RGBfull(0..255) matrix is represented by - * | Rf | | Rs | | Or | - * | Gf | = Ms | Gs | + | Og | - * | Bf | | Bs | | Ob | - * - * Combining all matrix into - * | Y'(unorm) | | Rs | | Or | | offsetA | - * | Cb(unorm) | = Matrix * ( Ms | Gs | + | Og | ) + | offsetB | - * | Cr(unorm) | | Bs | | Ob | | offsetC | - * - * | Rs | | Or | | offsetA | - * = Matrix * Ms | Gs | + Matrix | Og | + | offsetB | - * | Bs | | Ob | | offsetB | - */ - - memset (matrix, 0, sizeof (GstD3D11ColorMatrix)); - for (guint i = 0; i < 3; i++) - matrix->max[i] = 1.0; - - gst_video_color_range_offsets (out_yuv_info->colorimetry.range, - out_yuv_info->finfo, offset, scale); - - if (gst_video_color_matrix_get_Kr_Kb (out_yuv_info->colorimetry.matrix, - &Kr, &Kb)) { - guint S; - gdouble Sy, Suv; - gdouble Oy, Ouv; - gdouble vecY[3], vecU[3], vecV[3]; - - Kg = 1.0 - Kr - Kb; - - vecY[0] = Kr; - vecY[1] = Kg; - vecY[2] = Kb; - - vecU[0] = -0.5 * Kr / (1 - Kb); - vecU[1] = -0.5 * Kg / (1 - Kb); - vecU[2] = 0.5; - - vecV[0] = 0.5; - vecV[1] = -0.5 * Kg / (1 - Kr); - vecV[2] = -0.5 * Kb / (1 - Kr); - - /* Assume all components has the same bitdepth */ - S = (1 << out_yuv_info->finfo->depth[0]) - 1; - Sy = (gdouble) scale[0] / S; - Suv = (gdouble) scale[1] / S; - Oy = (gdouble) offset[0] / S; - Ouv = (gdouble) offset[1] / S; - - for (guint i = 0; i < 3; i++) { - matrix->matrix[0][i] = Sy * vecY[i]; - matrix->matrix[1][i] = Suv * vecU[i]; - matrix->matrix[2][i] = Suv * vecV[i]; - } - - matrix->offset[0] = Oy; - matrix->offset[1] = Ouv; - matrix->offset[2] = Ouv; - - matrix->min[0] = Oy; - matrix->min[1] = Oy; - matrix->min[2] = Oy; - - matrix->max[0] = ((gdouble) scale[0] + offset[0]) / S; - matrix->max[1] = ((gdouble) scale[1] + offset[0]) / S; - matrix->max[2] = ((gdouble) scale[1] + offset[0]) / S; - - /* Apply RGB range scale matrix */ - if (in_rgb_info->colorimetry.range == GST_VIDEO_COLOR_RANGE_16_235) { - GstD3D11ColorMatrix scale_matrix, rst; - GstVideoInfo full_rgb = *in_rgb_info; - - full_rgb.colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255; - - if (gst_d3d11_color_range_adjust_matrix_unorm (in_rgb_info, - &full_rgb, &scale_matrix)) { - /* Matrix * Ms */ - color_matrix_multiply (&rst, matrix, &scale_matrix); - - /* Matrix * scale offsets */ - for (guint i = 0; i < 3; i++) { - gdouble val = 0; - for (guint j = 0; j < 3; j++) { - val += matrix->matrix[i][j] * scale_matrix.offset[j]; - } - rst.offset[i] = val + matrix->offset[i]; - } - - /* copy back to output matrix */ - for (guint i = 0; i < 3; i++) { - for (guint j = 0; j < 3; j++) { - matrix->matrix[i][j] = rst.matrix[i][j]; - } - matrix->offset[i] = rst.offset[i]; - } - } - } - } else { - /* Unknown matrix */ - matrix->matrix[0][0] = 1.0; - matrix->matrix[1][1] = 1.0; - matrix->matrix[2][2] = 1.0; - } - - return TRUE; -} - -static gboolean -rgb_to_xyz_matrix (const GstVideoColorPrimariesInfo * info, - GstD3D11ColorMatrix * matrix) -{ - GstD3D11ColorMatrix m, im; - gdouble Sr, Sg, Sb; - gdouble Xw, Yw, Zw; - - if (info->Rx == 0 || info->Gx == 0 || info->By == 0 || info->Wy == 0) - return FALSE; - - color_matrix_identity (&m); - - m.matrix[0][0] = info->Rx / info->Ry; - m.matrix[1][0] = 1.0; - m.matrix[2][0] = (1.0 - info->Rx - info->Ry) / info->Ry; - - m.matrix[0][1] = info->Gx / info->Gy; - m.matrix[1][1] = 1.0; - m.matrix[2][1] = (1.0 - info->Gx - info->Gy) / info->Gy; - - m.matrix[0][2] = info->Bx / info->By; - m.matrix[1][2] = 1.0; - m.matrix[2][2] = (1.0 - info->Bx - info->By) / info->By; - - if (!color_matrix_invert (&im, &m)) - return FALSE; - - Xw = info->Wx / info->Wy; - Yw = 1.0; - Zw = (1.0 - info->Wx - info->Wy) / info->Wy; - - Sr = im.matrix[0][0] * Xw + im.matrix[0][1] * Yw + im.matrix[0][2] * Zw; - Sg = im.matrix[1][0] * Xw + im.matrix[1][1] * Yw + im.matrix[1][2] * Zw; - Sb = im.matrix[2][0] * Xw + im.matrix[2][1] * Yw + im.matrix[2][2] * Zw; - - for (guint i = 0; i < 3; i++) { - m.matrix[i][0] *= Sr; - m.matrix[i][1] *= Sg; - m.matrix[i][2] *= Sb; - } - - color_matrix_copy (matrix, &m); - - return TRUE; -} - -/** - * gst_d3d11_color_primaries_matrix_unorm: - * @in_info: a #GstVideoColorPrimariesInfo of input signal - * @out_info: a #GstVideoColorPrimariesInfo of output signal - * @matrix: a #GstD3D11ColorMatrix - * - * Calculates color primaries conversion matrix - * - * Resulting RGB values can be calculated by - * | Rout | | Rin | - * | Gout | = saturate ( matrix.matrix * | Gin | ) - * | Bout | | Bin | - * - * Returns: %TRUE if successful - */ -gboolean -gst_d3d11_color_primaries_matrix_unorm (const GstVideoColorPrimariesInfo * - in_info, const GstVideoColorPrimariesInfo * out_info, - GstD3D11ColorMatrix * matrix) -{ - GstD3D11ColorMatrix Ms, invMd, ret; - - g_return_val_if_fail (in_info != nullptr, FALSE); - g_return_val_if_fail (out_info != nullptr, FALSE); - g_return_val_if_fail (matrix != nullptr, FALSE); - - /* - * - * - * 1) RGB -> XYZ conversion - * | X | | R | - * | Y | = M | G | - * | Z | | B | - * where - * | SrXr, SgXg, SbXb | - * M = | SrYr, SgYg, SbYb | - * | SrZr, SgZg, SbZb | - * - * Xr = xr / yr - * Yr = 1 - * Zr = (1 - xr - yr) / yr - * xr and yr are xy coordinates of red primary in the CIE 1931 color space. - * And its applied to G and B components - * - * | Sr | | Xr, Xg, Xb | | Xw | - * | Sg | = inv( | Yr, Yg, Yb | ) * | Yw | - * | Sb | | Zr, Zg, Zb | | Zw | - * - * 2) XYZsrc -> XYZdst conversion - * Apply chromatic adaptation - * | Xdst | | Xsrc | - * | Ydst | = Mc | Ysrc | - * | Zdst | | Zsrc | - * where - * | Xwdst / Xwsrc, 0 , 0 | - * Mc = | 0 , Ywdst / Ywsrc, 0 | - * | 0 , 0 , Zwdst / Zwsrc | - * - * where - * - * 3) Final matrix - * | Rd | | Rs | - * | Gd | = inv (Md) * Mc * Ms | Gs | - * | Bd | | Bs | - */ - - memset (matrix, 0, sizeof (GstD3D11ColorMatrix)); - for (guint i = 0; i < 3; i++) - matrix->max[i] = 1.0; - - if (!rgb_to_xyz_matrix (in_info, &Ms)) { - GST_WARNING ("Failed to get src XYZ matrix"); - return FALSE; - } - - if (!rgb_to_xyz_matrix (out_info, &invMd) || - !color_matrix_invert (&invMd, &invMd)) { - GST_WARNING ("Failed to get dst XYZ matrix"); - return FALSE; - } - - if (in_info->Wx != out_info->Wx || in_info->Wy != out_info->Wy) { - GstD3D11ColorMatrix Mc; - - color_matrix_identity (&Mc); - Mc.matrix[0][0] = (out_info->Wx / out_info->Wy) / - (in_info->Wx / in_info->Wy); - /* Yw == 1.0 */ - Mc.matrix[2][2] = ((1.0 - out_info->Wx - out_info->Wy) / out_info->Wy) / - ((1.0 - in_info->Wx - in_info->Wy) / in_info->Wy); - - color_matrix_multiply (&ret, &Mc, &Ms); - } else { - color_matrix_copy (&ret, &Ms); - } - - color_matrix_multiply (&ret, &invMd, &ret); - color_matrix_copy (matrix, &ret); - - return TRUE; -} diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.h b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.h index c378a41e12..5915d51396 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.h +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.h @@ -38,14 +38,6 @@ typedef enum GST_D3D11_DEVICE_VENDOR_XBOX, } GstD3D11DeviceVendor; -typedef struct _GstD3D11ColorMatrix -{ - gdouble matrix[3][3]; - gdouble offset[3]; - gdouble min[3]; - gdouble max[3]; -} GstD3D11ColorMatrix; - void gst_d3d11_plugin_utils_init (D3D_FEATURE_LEVEL feature_level); GstCaps * gst_d3d11_get_updated_template_caps (GstStaticCaps * template_caps); @@ -95,24 +87,6 @@ GstBufferPool * gst_d3d11_buffer_pool_new_with_options (GstD3D11Device * device guint min_buffers, guint max_buffers); -gchar * gst_d3d11_dump_color_matrix (GstD3D11ColorMatrix * matrix); - -gboolean gst_d3d11_color_range_adjust_matrix_unorm (const GstVideoInfo * in_info, - const GstVideoInfo * out_info, - GstD3D11ColorMatrix * matrix); - -gboolean gst_d3d11_yuv_to_rgb_matrix_unorm (const GstVideoInfo * in_yuv_info, - const GstVideoInfo * out_rgb_info, - GstD3D11ColorMatrix * matrix); - -gboolean gst_d3d11_rgb_to_yuv_matrix_unorm (const GstVideoInfo * in_rgb_info, - const GstVideoInfo * out_yuv_info, - GstD3D11ColorMatrix * matrix); - -gboolean gst_d3d11_color_primaries_matrix_unorm (const GstVideoColorPrimariesInfo * in_info, - const GstVideoColorPrimariesInfo * out_info, - GstD3D11ColorMatrix * matrix); - G_END_DECLS #endif /* __GST_D3D11_PLUGIN_UTILS_H__ */ diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11testsrc.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11testsrc.cpp index afc964de9b..5724e31cac 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11testsrc.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11testsrc.cpp @@ -38,7 +38,6 @@ #include "gstd3d11testsrc.h" #include "gstd3d11pluginutils.h" -#include "gstd3d11converter.h" #include #include diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h index 8f47cda9a3..3a4bfdcc01 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h @@ -25,7 +25,6 @@ #include #include #include -#include "gstd3d11converter.h" #include "gstd3d11overlaycompositor.h" #include "gstd3d11pluginutils.h" diff --git a/subprojects/gst-plugins-bad/sys/d3d11/meson.build b/subprojects/gst-plugins-bad/sys/d3d11/meson.build index 2a780b523e..9084c68b66 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/meson.build +++ b/subprojects/gst-plugins-bad/sys/d3d11/meson.build @@ -3,7 +3,6 @@ d3d11_sources = [ 'gstd3d11basefilter.cpp', 'gstd3d11compositor.cpp', 'gstd3d11convert.cpp', - 'gstd3d11converter.cpp', 'gstd3d11decoder.cpp', 'gstd3d11deinterlace.cpp', 'gstd3d11download.cpp',