gallium/vl: use common ycbcr helpers
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

This reduces a bit of complexity across the tree.

Reviewed-by: Eric R. Smith <eric.smith@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40175>
This commit is contained in:
Erik Faye-Lund 2026-02-27 09:32:13 +01:00 committed by Marge Bot
parent 28fd6a5789
commit 224a336bf0

View file

@ -27,6 +27,7 @@
#include "util/u_math.h"
#include "util/u_debug.h"
#include "util/u_ycbcr.h"
#include "vl_csc.h"
@ -58,119 +59,59 @@ void vl_csc_get_rgbyuv_matrix(enum pipe_video_vpp_matrix_coefficients coefficien
const bool in_yuv = util_format_is_yuv(in_format);
const bool out_yuv = util_format_is_yuv(out_format);
const unsigned bpc = format_bpc(in_format);
const float scale = (1 << bpc) / ((1 << bpc) - 1.0);
const float y_min = 16.0 / 256.0 * scale;
const float y_max = 235.0 / 256.0 * scale;
const float c_mid = 128.0 / 256.0 * scale;
const float c_max = 240.0 / 256.0 * scale;
float y_scale, c_scale, y_bias, c_bias;
const unsigned bpcs[3] = { bpc, bpc, bpc };
memcpy(matrix, &identity, sizeof(vl_csc_matrix));
if (in_yuv != out_yuv && coefficients == PIPE_VIDEO_VPP_MCF_RGB)
return;
float in_range[3][2];
/* Convert input to full range, chroma to [-0.5,0.5]. */
if (in_color_range == PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_REDUCED) {
y_scale = 1.0 / (y_max - y_min);
c_scale = in_yuv ? 0.5 / (c_max - c_mid) : y_scale;
y_bias = -y_min;
c_bias = in_yuv ? -c_mid : y_bias;
} else if (in_yuv) {
y_scale = 1.0;
c_scale = 0.5 / (1.0 - c_mid);
y_bias = 0.0;
c_bias = -c_mid;
} else {
y_scale = c_scale = 1.0;
y_bias = c_bias = 0.0;
}
if (in_color_range == PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_REDUCED)
util_get_narrow_range_coeffs(in_range, bpcs);
else if (in_yuv)
util_get_full_range_coeffs(in_range, bpcs);
else
util_get_identity_range_coeffs(in_range);
if (in_yuv != out_yuv) {
float cr, cg, cb;
const float *ycbcr_coeffs;
switch (coefficients) {
case PIPE_VIDEO_VPP_MCF_BT470BG:
case PIPE_VIDEO_VPP_MCF_SMPTE170M:
cr = 0.299;
cb = 0.114;
ycbcr_coeffs = util_ycbcr_bt601_coeffs;
break;
case PIPE_VIDEO_VPP_MCF_SMPTE240M:
cr = 0.212;
cb = 0.087;
ycbcr_coeffs = util_ycbcr_smpte240m_coeffs;
break;
case PIPE_VIDEO_VPP_MCF_BT2020_NCL:
cr = 0.2627;
cb = 0.0593;
ycbcr_coeffs = util_ycbcr_bt2020_coeffs;
break;
case PIPE_VIDEO_VPP_MCF_BT709:
default:
cr = 0.2126;
cb = 0.0722;
ycbcr_coeffs = util_ycbcr_bt709_coeffs;
break;
}
cg = 1.0 - cb - cr;
if (in_yuv) {
/* YUV to RGB */
(*matrix)[0][0] = 1.0;
(*matrix)[0][1] = 0.0;
(*matrix)[0][2] = 2.0 - 2.0 * cr;
(*matrix)[0][3] = 0.0;
(*matrix)[1][0] = 1.0;
(*matrix)[1][1] = (-cb / cg) * (2.0 - 2.0 * cb);
(*matrix)[1][2] = (-cr / cg) * (2.0 - 2.0 * cr);
(*matrix)[1][3] = 0.0;
(*matrix)[2][0] = 1.0;
(*matrix)[2][1] = 2.0 - 2.0 * cb;
(*matrix)[2][2] = 0.0;
(*matrix)[2][3] = 0.0;
} else {
/* RGB to YUV */
(*matrix)[0][0] = cr;
(*matrix)[0][1] = cg;
(*matrix)[0][2] = cb;
(*matrix)[0][3] = 0.0;
(*matrix)[1][0] = (0.5 / (cb - 1.0)) * cr;
(*matrix)[1][1] = (0.5 / (cb - 1.0)) * cg;
(*matrix)[1][2] = 0.5;
(*matrix)[1][3] = 0.0;
(*matrix)[2][0] = 0.5;
(*matrix)[2][1] = (0.5 / (cr - 1.0)) * cg;
(*matrix)[2][2] = (0.5 / (cr - 1.0)) * cb;
(*matrix)[2][3] = 0.0;
}
if (in_yuv)
util_get_ycbcr_to_rgb_matrix(*matrix, ycbcr_coeffs);
else
util_get_rgb_to_ycbcr_matrix(*matrix, ycbcr_coeffs);
}
for (unsigned i = 0; i < 3; i++) {
for (unsigned j = 0; j < 3; j++) {
(*matrix)[i][j] *= j == 0 ? y_scale : c_scale;
(*matrix)[i][3] += (*matrix)[i][j] * (j == 0 ? y_bias : c_bias);
}
}
util_ycbcr_adjust_from_range(*matrix, in_range);
/* Convert output to reduced range, chroma to [0.0,1.0]. */
if (out_color_range == PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_REDUCED) {
y_scale = (y_max - y_min) / 1.0;
c_scale = in_yuv ? y_scale : (c_max - c_mid) / 0.5;
y_bias = y_min;
c_bias = in_yuv ? y_bias : c_mid;
} else if (out_yuv) {
y_scale = 1.0;
c_scale = (1.0 - c_mid) / 0.5;
y_bias = 0.0;
c_bias = c_mid;
} else {
y_scale = c_scale = 1.0;
y_bias = c_bias = 0.0;
}
float out_range[3][2];
if (out_color_range == PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_REDUCED)
util_get_narrow_range_coeffs(out_range, bpcs);
else if (out_yuv)
util_get_full_range_coeffs(out_range, bpcs);
else
util_get_identity_range_coeffs(out_range);
for (unsigned i = 0; i < 3; i++) {
for (unsigned j = 0; j < 4; j++)
(*matrix)[i][j] *= i == 0 ? y_scale : c_scale;
(*matrix)[i][3] += i == 0 ? y_bias : c_bias;
}
util_ycbcr_adjust_to_range(*matrix, out_range);
}
void vl_csc_get_primaries_matrix(enum pipe_video_vpp_color_primaries in_color_primaries,