[vlc-devel] [PATCH 4/7] opengl: refactor color range for 2-bytes pixels
Romain Vimont
rom1v at videolabs.io
Wed Jan 22 13:33:46 CET 2020
Apply the range conversion via the conversion matrix.
---
.../video_output/opengl/fragment_shaders.c | 51 ++++++++++++-------
1 file changed, 32 insertions(+), 19 deletions(-)
diff --git a/modules/video_output/opengl/fragment_shaders.c b/modules/video_output/opengl/fragment_shaders.c
index 7fbbca81c7..fa8c238d86 100644
--- a/modules/video_output/opengl/fragment_shaders.c
+++ b/modules/video_output/opengl/fragment_shaders.c
@@ -127,31 +127,44 @@ tc_yuv_base_init(opengl_tex_converter_t *tc, vlc_fourcc_t chroma,
video_color_space_t yuv_space,
bool *swap_uv)
{
- float yuv_range_correction = 1.0;
- if (desc->pixel_size == 2)
- {
- /* Do a bit shift if samples are stored on LSB */
- if (chroma != VLC_CODEC_P010 && chroma != VLC_CODEC_P016)
- yuv_range_correction = (float)((1 << 16) - 1)
- / ((1 << desc->pixel_bits) - 1);
- }
-
/* The current implementation always converts from limited to full range. */
const video_color_range_t range = COLOR_RANGE_LIMITED;
float matrix[4*4];
init_conv_matrix(matrix, yuv_space, range);
+ if (desc->pixel_size == 2)
+ {
+ if (chroma != VLC_CODEC_P010 && chroma != VLC_CODEC_P016) {
+ /* Do a bit shift if samples are stored on LSB. */
+ float yuv_range_correction = (float)((1 << 16) - 1)
+ / ((1 << desc->pixel_bits) - 1);
+ /* We want to transform the input color (y, u, v, 1) to
+ * (r*y, r*u, r*v, 1), where r = yuv_range_correction.
+ *
+ * This can be done by left-multiplying the color vector by a
+ * matrix R:
+ *
+ * R
+ * / r*y \ / r 0 0 0 \ / y \
+ * | r*u | = | 0 r 0 0 | * | u |
+ * | r*v | | 0 0 r 0 | | v |
+ * \ 1 / \ 0 0 0 1 / \ 1 /
+ *
+ * Combine this transformation with the color conversion matrix:
+ *
+ * matrix := matrix * R
+ *
+ * This is equivalent to multipying the 3 first rows by r
+ * (yuv_range_conversion).
+ */
+ for (int i = 0; i < 4*3; ++i)
+ matrix[i] *= yuv_range_correction;
+ }
+ }
+
for (int i = 0; i < 4; i++) {
- float correction = i < 3 ? yuv_range_correction : 1.f;
- /* We place coefficient values for coefficient[4] in one array from
- * matrix values. Notice that we fill values from top down instead
- * of left to right.*/
- for (int j = 0; j < 3; j++)
- tc->yuv_coefficients[i*4+j] = correction * matrix[j*4+i];
- tc->yuv_coefficients[3] = 0.f;
- tc->yuv_coefficients[7] = 0.f;
- tc->yuv_coefficients[11] = 0.f;
- tc->yuv_coefficients[15] = 1.f;
+ for (int j = 0; j < 4; j++)
+ tc->yuv_coefficients[i*4+j] = matrix[j*4+i];
}
tc->yuv_color = true;
--
2.25.0
More information about the vlc-devel
mailing list