From 7a03ef45c2fa7f416a26955593fda34c4521f123 Mon Sep 17 00:00:00 2001 From: Jacob Wischnat Date: Wed, 3 Jul 2024 20:08:28 +1000 Subject: [PATCH] LibMedia: Support videos with BT470BG color matrix --- .../Libraries/LibMedia/Color/ColorConverter.cpp | 17 +++++++++-------- Userland/Libraries/LibMedia/PlaybackManager.cpp | 4 +++- Userland/Libraries/LibMedia/VideoFrame.cpp | 5 +++-- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibMedia/Color/ColorConverter.cpp b/Userland/Libraries/LibMedia/Color/ColorConverter.cpp index 4bad8a6a66d..99da5c49612 100644 --- a/Userland/Libraries/LibMedia/Color/ColorConverter.cpp +++ b/Userland/Libraries/LibMedia/Color/ColorConverter.cpp @@ -76,14 +76,7 @@ DecoderErrorOr ColorConverter::create(u8 bit_depth, CodingIndepe // https://kdashg.github.io/misc/colors/from-coeffs.html switch (input_cicp.matrix_coefficients()) { - case MatrixCoefficients::BT709: - color_conversion_matrix = { - 1.0f, 0.0f, 0.78740f, 0.0f, // y - 1.0f, -0.09366f, -0.23406f, 0.0f, // u - 1.0f, 0.92780f, 0.0f, 0.0f, // v - 0.0f, 0.0f, 0.0f, 1.0f, // w - }; - break; + case MatrixCoefficients::BT470BG: case MatrixCoefficients::BT601: color_conversion_matrix = { 1.0f, 0.0f, 0.70100f, 0.0f, // y @@ -92,6 +85,14 @@ DecoderErrorOr ColorConverter::create(u8 bit_depth, CodingIndepe 0.0f, 0.0f, 0.0f, 1.0f, // w }; break; + case MatrixCoefficients::BT709: + color_conversion_matrix = { + 1.0f, 0.0f, 0.78740f, 0.0f, // y + 1.0f, -0.09366f, -0.23406f, 0.0f, // u + 1.0f, 0.92780f, 0.0f, 0.0f, // v + 0.0f, 0.0f, 0.0f, 1.0f, // w + }; + break; case MatrixCoefficients::BT2020ConstantLuminance: case MatrixCoefficients::BT2020NonConstantLuminance: color_conversion_matrix = { diff --git a/Userland/Libraries/LibMedia/PlaybackManager.cpp b/Userland/Libraries/LibMedia/PlaybackManager.cpp index 1a28f32e31d..6ce3ad76044 100644 --- a/Userland/Libraries/LibMedia/PlaybackManager.cpp +++ b/Userland/Libraries/LibMedia/PlaybackManager.cpp @@ -250,11 +250,13 @@ void PlaybackManager::decode_and_queue_one_sample() cicp.adopt_specified_values(container_cicp); cicp.default_code_points_if_unspecified({ ColorPrimaries::BT709, TransferCharacteristics::BT709, MatrixCoefficients::BT709, VideoFullRangeFlag::Studio }); - // BT.601, BT.709 and BT.2020 have a similar transfer function to sRGB, so other applications + // BT.470 M, B/G, BT.601, BT.709 and BT.2020 have a similar transfer function to sRGB, so other applications // (Chromium, VLC) forgo transfer characteristics conversion. We will emulate that behavior by // handling those as sRGB instead, which causes no transfer function change in the output, // unless display color management is later implemented. switch (cicp.transfer_characteristics()) { + case TransferCharacteristics::BT470BG: + case TransferCharacteristics::BT470M: case TransferCharacteristics::BT601: case TransferCharacteristics::BT709: case TransferCharacteristics::BT2020BitDepth10: diff --git a/Userland/Libraries/LibMedia/VideoFrame.cpp b/Userland/Libraries/LibMedia/VideoFrame.cpp index a7d39b80c42..318c3960aef 100644 --- a/Userland/Libraries/LibMedia/VideoFrame.cpp +++ b/Userland/Libraries/LibMedia/VideoFrame.cpp @@ -185,10 +185,11 @@ static ALWAYS_INLINE DecoderErrorOr convert_to_bitmap_selecting_converter( if (bit_depth == 8 && cicp.transfer_characteristics() == output_cicp.transfer_characteristics() && cicp.color_primaries() == output_cicp.color_primaries() && cicp.video_full_range_flag() == VideoFullRangeFlag::Studio) { switch (cicp.matrix_coefficients()) { - case MatrixCoefficients::BT709: - return convert_to_bitmap_subsampled([](T y, T u, T v) { return ColorConverter::convert_simple_yuv_to_rgb(y, u, v); }, width, height, plane_y, plane_u, plane_v, bitmap); + case MatrixCoefficients::BT470BG: case MatrixCoefficients::BT601: return convert_to_bitmap_subsampled([](T y, T u, T v) { return ColorConverter::convert_simple_yuv_to_rgb(y, u, v); }, width, height, plane_y, plane_u, plane_v, bitmap); + case MatrixCoefficients::BT709: + return convert_to_bitmap_subsampled([](T y, T u, T v) { return ColorConverter::convert_simple_yuv_to_rgb(y, u, v); }, width, height, plane_y, plane_u, plane_v, bitmap); default: break; }