fix(iced-video): Update the color matrices and subtract .5 from uv samples to
Some checks failed
build / checks-matrix (push) Has been cancelled
build / checks-build (push) Has been cancelled
build / codecov (push) Has been cancelled
docs / docs (push) Has been cancelled

This commit is contained in:
2026-01-15 17:25:09 +05:30
parent 429371002b
commit e5ef173473
3 changed files with 32 additions and 27 deletions

View File

@@ -3,7 +3,6 @@ pub mod primitive;
pub mod source; pub mod source;
pub mod widget; pub mod widget;
pub use widget::Video; pub use widget::Video;
pub mod yuv;
use error_stack::{Report, ResultExt}; use error_stack::{Report, ResultExt};

View File

@@ -75,17 +75,17 @@ impl Vec3f {
pub const BT2020_TO_RGB: ConversionMatrix = ConversionMatrix { pub const BT2020_TO_RGB: ConversionMatrix = ConversionMatrix {
matrix: [ matrix: [
Vec3f::from([1.0, 0.0, 1.13983]), Vec3f::from([1.0, 0.0, 1.4746]),
Vec3f::from([1.0, -0.39465, -0.58060]), Vec3f::from([1.0, -0.16455, -0.5714]),
Vec3f::from([1.0, 2.03211, 0.0]), Vec3f::from([1.0, 1.8814, 0.0]),
], ],
}; };
pub const BT709_TO_RGB: ConversionMatrix = ConversionMatrix { pub const BT709_TO_RGB: ConversionMatrix = ConversionMatrix {
matrix: [ matrix: [
Vec3f::from([1.0, 0.0, 1.13983]), Vec3f::from([1.0, 0.0, 1.5748]),
Vec3f::from([1.0, -0.39465, -0.58060]), Vec3f::from([1.0, -0.1873, -0.4681]),
Vec3f::from([1.0, 2.03211, 0.0]), Vec3f::from([1.0, 1.8556, 0.0]),
], ],
}; };
@@ -136,18 +136,28 @@ impl iced_wgpu::Primitive for VideoFrame {
}, },
wgpu::BindGroupEntry { wgpu::BindGroupEntry {
binding: 3, 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 { VideoFrameData {
id: self.id.clone(), id: self.id.clone(),
texture, texture,
bind_group, bind_group,
conversion_matrix: BT709_TO_RGB, conversion_matrix: matrix,
ready: Arc::clone(&self.ready), ready: Arc::clone(&self.ready),
} }
}); });
@@ -156,6 +166,8 @@ impl iced_wgpu::Primitive for VideoFrame {
.texture .texture
.resize("iced-video-texture-resized", self.size, device); .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 { let new_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("iced-video-texture-bind-group"), label: Some("iced-video-texture-bind-group"),
layout: &pipeline.bind_group_layout, layout: &pipeline.bind_group_layout,
@@ -175,7 +187,10 @@ impl iced_wgpu::Primitive for VideoFrame {
wgpu::BindGroupEntry { wgpu::BindGroupEntry {
binding: 3, binding: 3,
resource: wgpu::BindingResource::Buffer( 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. /// This assumes that the data is laid out correctly for the texture format.
pub fn write_texture(&self, data: &[u8], queue: &wgpu::Queue) { 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 Self { y, uv, .. } = self;
let y_size = y.size(); let y_size = y.size();
let uv_size = uv.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 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 let uv_data_size = (y_data_size / 2) as usize; // UV is interleaved
// debug_assert_eq!(y_data_size, data.len() / 3 * 2); let y_data = &data[0..y_data_size];
// debug_assert_eq!(uv_data_size, data.len() / 3); let uv_data = &data[y_data_size..y_data_size + uv_data_size];
// 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());
queue.write_texture( queue.write_texture(
wgpu::TexelCopyTextureInfo { wgpu::TexelCopyTextureInfo {
@@ -414,6 +416,10 @@ impl VideoTexture {
bytemuck::bytes_of(matrix), bytemuck::bytes_of(matrix),
); );
} }
pub fn conversion_matrix_buffer(&self) -> &wgpu::Buffer {
&self.conversion_matrix_buffer
}
} }
#[derive(Debug)] #[derive(Debug)]

View File

@@ -25,6 +25,6 @@ fn vs_main(
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> { fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
let y = textureSample(y_texture, texture_sampler, input.tex_coords).r; let y = textureSample(y_texture, texture_sampler, input.tex_coords).r;
let uv = textureSample(uv_texture, texture_sampler, input.tex_coords).rg; 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); return vec4f(yuv * rgb_primaries, 1.0);
} }