From e5ef173473e06a2c514e508cde1ae063d97497d9 Mon Sep 17 00:00:00 2001 From: servius Date: Thu, 15 Jan 2026 17:25:09 +0530 Subject: [PATCH] fix(iced-video): Update the color matrices and subtract .5 from uv samples to --- crates/iced-video/src/lib.rs | 1 - crates/iced-video/src/primitive.rs | 56 ++++++++++--------- .../iced-video/src/shaders/passthrough.wgsl | 2 +- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/crates/iced-video/src/lib.rs b/crates/iced-video/src/lib.rs index 433d1a9..b23d22a 100644 --- a/crates/iced-video/src/lib.rs +++ b/crates/iced-video/src/lib.rs @@ -3,7 +3,6 @@ pub mod primitive; pub mod source; pub mod widget; pub use widget::Video; -pub mod yuv; use error_stack::{Report, ResultExt}; diff --git a/crates/iced-video/src/primitive.rs b/crates/iced-video/src/primitive.rs index 96dd381..b529db9 100644 --- a/crates/iced-video/src/primitive.rs +++ b/crates/iced-video/src/primitive.rs @@ -75,17 +75,17 @@ impl Vec3f { pub const BT2020_TO_RGB: ConversionMatrix = ConversionMatrix { matrix: [ - Vec3f::from([1.0, 0.0, 1.13983]), - Vec3f::from([1.0, -0.39465, -0.58060]), - Vec3f::from([1.0, 2.03211, 0.0]), + Vec3f::from([1.0, 0.0, 1.4746]), + Vec3f::from([1.0, -0.16455, -0.5714]), + Vec3f::from([1.0, 1.8814, 0.0]), ], }; pub const BT709_TO_RGB: ConversionMatrix = ConversionMatrix { matrix: [ - Vec3f::from([1.0, 0.0, 1.13983]), - Vec3f::from([1.0, -0.39465, -0.58060]), - Vec3f::from([1.0, 2.03211, 0.0]), + Vec3f::from([1.0, 0.0, 1.5748]), + Vec3f::from([1.0, -0.1873, -0.4681]), + Vec3f::from([1.0, 1.8556, 0.0]), ], }; @@ -136,18 +136,28 @@ impl iced_wgpu::Primitive for VideoFrame { }, wgpu::BindGroupEntry { binding: 3, - resource: wgpu::BindingResource::Buffer(buffer.as_entire_buffer_binding()), + resource: wgpu::BindingResource::Buffer( + texture + .conversion_matrix_buffer() + .as_entire_buffer_binding(), + ), }, ], }); - // texture.write_conversion_matrix(&BT709_TO_RGB, queue); + let matrix = if matches!(self.format, VideoFormat::P01010le | VideoFormat::P016Le) { + BT2020_TO_RGB + } else { + BT709_TO_RGB + }; + + texture.write_conversion_matrix(&matrix, queue); VideoFrameData { id: self.id.clone(), texture, bind_group, - conversion_matrix: BT709_TO_RGB, + conversion_matrix: matrix, ready: Arc::clone(&self.ready), } }); @@ -156,6 +166,8 @@ impl iced_wgpu::Primitive for VideoFrame { .texture .resize("iced-video-texture-resized", self.size, device); + new_texture.write_conversion_matrix(&video.conversion_matrix, queue); + let new_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { label: Some("iced-video-texture-bind-group"), layout: &pipeline.bind_group_layout, @@ -175,7 +187,10 @@ impl iced_wgpu::Primitive for VideoFrame { wgpu::BindGroupEntry { binding: 3, resource: wgpu::BindingResource::Buffer( - video.conversion_matrix.as_entire_buffer_binding(), + video + .texture + .conversion_matrix_buffer() + .as_entire_buffer_binding(), ), }, ], @@ -351,11 +366,6 @@ impl VideoTexture { /// This assumes that the data is laid out correctly for the texture format. pub fn write_texture(&self, data: &[u8], queue: &wgpu::Queue) { - // let (y, u, v) = match self.video_format { - // VideoFormat::Nv12 | VideoFormat::P01010le | VideoFormat::P016Le => (4, 1, 1), - // _ => (1, 1), - // }; - let Self { y, uv, .. } = self; let y_size = y.size(); let uv_size = uv.size(); @@ -363,16 +373,8 @@ impl VideoTexture { let y_data_size = (y_size.width * y_size.height * 2) as usize; let uv_data_size = (y_data_size / 2) as usize; // UV is interleaved - // debug_assert_eq!(y_data_size, data.len() / 3 * 2); - // debug_assert_eq!(uv_data_size, data.len() / 3); - // let y_data = &data[0..y_data_size]; - // let uv_data = &data[y_data_size..]; - // dbg!(y_data.len()); - // dbg!(uv_data.len()); - // dbg!(y_data.len() + uv_data.len()); - // dbg!(data.len()); - // dbg!(y.size()); - // dbg!(uv.size()); + let y_data = &data[0..y_data_size]; + let uv_data = &data[y_data_size..y_data_size + uv_data_size]; queue.write_texture( wgpu::TexelCopyTextureInfo { @@ -414,6 +416,10 @@ impl VideoTexture { bytemuck::bytes_of(matrix), ); } + + pub fn conversion_matrix_buffer(&self) -> &wgpu::Buffer { + &self.conversion_matrix_buffer + } } #[derive(Debug)] diff --git a/crates/iced-video/src/shaders/passthrough.wgsl b/crates/iced-video/src/shaders/passthrough.wgsl index d182ade..e7d02df 100644 --- a/crates/iced-video/src/shaders/passthrough.wgsl +++ b/crates/iced-video/src/shaders/passthrough.wgsl @@ -25,6 +25,6 @@ fn vs_main( fn fs_main(input: VertexOutput) -> @location(0) vec4 { let y = textureSample(y_texture, texture_sampler, input.tex_coords).r; let uv = textureSample(uv_texture, texture_sampler, input.tex_coords).rg; - let yuv = vec3f(y, uv); + let yuv = vec3f(y, uv.x - 0.5, uv.y - 0.5); return vec4f(yuv * rgb_primaries, 1.0); }