diff --git a/crates/store/re_video/src/decode/av1.rs b/crates/store/re_video/src/decode/av1.rs index d3982b3be503..2409199753a9 100644 --- a/crates/store/re_video/src/decode/av1.rs +++ b/crates/store/re_video/src/decode/av1.rs @@ -231,8 +231,7 @@ fn yuv_matrix_coefficients(debug_name: &str, picture: &dav1d::Picture) -> YuvMat // Quotes are from https://wiki.x266.mov/docs/colorimetry/matrix (if not noted otherwise) #[allow(clippy::match_same_arms)] match picture.matrix_coefficients() { - // TODO(andreas) This one we should probably support! Afaik this means to just interpret YUV as RGB (or is there a swizzle?). - dav1d::pixel::MatrixCoefficients::Identity => YuvMatrixCoefficients::Bt709, + dav1d::pixel::MatrixCoefficients::Identity => YuvMatrixCoefficients::Identity, dav1d::pixel::MatrixCoefficients::BT709 => YuvMatrixCoefficients::Bt709, diff --git a/crates/store/re_video/src/decode/mod.rs b/crates/store/re_video/src/decode/mod.rs index b938836f2e3f..e7082e8a4a23 100644 --- a/crates/store/re_video/src/decode/mod.rs +++ b/crates/store/re_video/src/decode/mod.rs @@ -26,14 +26,13 @@ //! * weirdly enough, DO NOT CLAMP! a lot of software may say it's limited but then use the so-called foot and head space anyways to go outside the regular colors //! * reportedly (read this on some forums ;-)) some players _do_ clamp, so let's not get too concerned about this //! * it's a remnant of the analog age, but it's still very common! -//! * TODO(andreas): It may actually be non-downsampled RGB as well, so skip the entire YUV conversion step! Haven't figured out yet how to determine that. -//! //! //! ### Given a normalized YUV triplet, how do we get color? //! //! * `picture.matrix_coefficients()` (see ) //! * this tells us what to multiply the incoming YUV data with to get SOME RGB data //! * there's various standards of how to do this, but the most common is BT.709 +//! * here's a fun special one: `identity` means it's not actually YUV, but GBR! //! * `picture.primaries()` //! * now we have RGB but we kinda have no idea what that means! //! * the color primaries tell us which space we're in @@ -178,6 +177,10 @@ pub enum YuvRange { /// For details see `re_renderer`'s `YuvMatrixCoefficients` type. #[derive(Debug)] pub enum YuvMatrixCoefficients { + /// Interpret YUV as GBR. + Identity, + Bt601, + Bt709, } diff --git a/crates/viewer/re_renderer/shader/conversions/yuv_converter.wgsl b/crates/viewer/re_renderer/shader/conversions/yuv_converter.wgsl index 731c632dcb62..38b423c34018 100644 --- a/crates/viewer/re_renderer/shader/conversions/yuv_converter.wgsl +++ b/crates/viewer/re_renderer/shader/conversions/yuv_converter.wgsl @@ -25,8 +25,9 @@ const YUV_LAYOUT_YUYV422 = 200u; const YUV_LAYOUT_Y400 = 300u; // see `enum YuvMatrixCoefficients`. -const COEFFS_BT601 = 0u; -const COEFFS_BT709 = 1u; +const COEFFS_IDENTITY = 0u; +const COEFFS_BT601 = 1u; +const COEFFS_BT709 = 2u; // see `enum YuvRange`. const YUV_RANGE_LIMITED = 0u; @@ -73,6 +74,11 @@ fn srgb_from_yuv(yuv: vec3f, yuv_matrix_coefficients: u32, range: u32) -> vec3f var rgb: vec3f; switch (yuv_matrix_coefficients) { + case COEFFS_IDENTITY: { + // u & v have a range from -0.5 to 0.5. Bring them back to 0-1. + rgb = vec3f(v + 0.5, y, u + 0.5); + } + // BT.601 (aka. SDTV, aka. Rec.601). wiki: https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion // Also note according to https://en.wikipedia.org/wiki/SRGB#sYCC_extended-gamut_transformation // > Although the RGB color primaries are based on BT.709, diff --git a/crates/viewer/re_renderer/src/resource_managers/yuv_converter.rs b/crates/viewer/re_renderer/src/resource_managers/yuv_converter.rs index bd0237bac2ff..428a5f7b6c18 100644 --- a/crates/viewer/re_renderer/src/resource_managers/yuv_converter.rs +++ b/crates/viewer/re_renderer/src/resource_managers/yuv_converter.rs @@ -187,10 +187,13 @@ pub enum YuvPixelLayout { /// …which means for the moment we pretty much only care about the (actually quite) different YUV conversion matrices! #[derive(Clone, Copy, Debug)] pub enum YuvMatrixCoefficients { + /// Identity matrix, interpret YUV as GBR. + Identity = 0, + /// BT.601 (aka. SDTV, aka. Rec.601) /// /// Wiki: - Bt601 = 0, + Bt601 = 1, /// BT.709 (aka. HDTV, aka. Rec.709) /// @@ -203,7 +206,7 @@ pub enum YuvMatrixCoefficients { /// but for all other purposes they are the same. /// (The only reason for us to convert to optical units ("linear" instead of "gamma") is for /// lighting & tonemapping where we typically start out with an sRGB image!) - Bt709 = 1, + Bt709 = 2, // // Not yet supported. These vary a lot more from the other two! // diff --git a/crates/viewer/re_renderer/src/video/decoder/native_decoder.rs b/crates/viewer/re_renderer/src/video/decoder/native_decoder.rs index b99385e2f51e..266a77b66712 100644 --- a/crates/viewer/re_renderer/src/video/decoder/native_decoder.rs +++ b/crates/viewer/re_renderer/src/video/decoder/native_decoder.rs @@ -178,6 +178,9 @@ fn copy_video_frame_to_texture( re_video::decode::YuvPixelLayout::Y400 => YuvPixelLayout::Y400, }, coefficients: match coefficients { + re_video::decode::YuvMatrixCoefficients::Identity => { + YuvMatrixCoefficients::Identity + } re_video::decode::YuvMatrixCoefficients::Bt601 => YuvMatrixCoefficients::Bt601, re_video::decode::YuvMatrixCoefficients::Bt709 => YuvMatrixCoefficients::Bt709, },