diff --git a/src/pipeline.rs b/src/pipeline.rs index be6894d..5ddd8a4 100644 --- a/src/pipeline.rs +++ b/src/pipeline.rs @@ -1,7 +1,7 @@ use iced_wgpu::primitive::Primitive; use iced_wgpu::wgpu; use std::{ - collections::BTreeMap, + collections::{btree_map::Entry, BTreeMap}, sync::{ atomic::{AtomicBool, Ordering}, Arc, Mutex, @@ -13,20 +13,19 @@ struct Uniforms { rect: [f32; 4], } +struct VideoEntry { + texture_y: wgpu::Texture, + texture_uv: wgpu::Texture, + uniforms: wgpu::Buffer, + bg0: wgpu::BindGroup, + alive: Arc, +} + struct VideoPipeline { pipeline: wgpu::RenderPipeline, bg0_layout: wgpu::BindGroupLayout, sampler: wgpu::Sampler, - textures: BTreeMap< - u64, - ( - wgpu::Texture, - wgpu::Texture, - wgpu::Buffer, - wgpu::BindGroup, - Arc, - ), - >, + videos: BTreeMap, } impl VideoPipeline { @@ -130,7 +129,7 @@ impl VideoPipeline { pipeline, bg0_layout, sampler, - textures: BTreeMap::new(), + videos: BTreeMap::new(), } } @@ -143,7 +142,7 @@ impl VideoPipeline { (width, height): (u32, u32), frame: &[u8], ) { - if !self.textures.contains_key(&video_id) { + if let Entry::Vacant(entry) = self.videos.entry(video_id) { let texture_y = device.create_texture(&wgpu::TextureDescriptor { label: Some("iced_video_player texture"), size: wgpu::Extent3d { @@ -230,13 +229,20 @@ impl VideoPipeline { ], }); - self.textures.insert( - video_id, - (texture_y, texture_uv, buffer, bind_group, Arc::clone(alive)), - ); + entry.insert(VideoEntry { + texture_y, + texture_uv, + uniforms: buffer, + bg0: bind_group, + alive: Arc::clone(alive), + }); } - let (texture_y, texture_uv, _, _, _) = self.textures.get(&video_id).unwrap(); + let VideoEntry { + texture_y, + texture_uv, + .. + } = self.videos.get(&video_id).unwrap(); queue.write_texture( wgpu::ImageCopyTexture { @@ -281,21 +287,21 @@ impl VideoPipeline { fn cleanup(&mut self) { let ids: Vec<_> = self - .textures + .videos .iter() - .filter_map(|(id, (_, _, _, _, alive))| (!alive.load(Ordering::SeqCst)).then_some(*id)) + .filter_map(|(id, entry)| (!entry.alive.load(Ordering::SeqCst)).then_some(*id)) .collect(); for id in ids { - if let Some((texture_y, texture_uv, buffer, _, _)) = self.textures.remove(&id) { - texture_y.destroy(); - texture_uv.destroy(); - buffer.destroy(); + if let Some(video) = self.videos.remove(&id) { + video.texture_y.destroy(); + video.texture_uv.destroy(); + video.uniforms.destroy(); } } } fn prepare(&mut self, queue: &wgpu::Queue, video_id: u64, bounds: &iced::Rectangle) { - if let Some((_, _, buffer, _, _)) = self.textures.get(&video_id) { + if let Some(video) = self.videos.get(&video_id) { let uniforms = Uniforms { rect: [ bounds.x, @@ -304,7 +310,7 @@ impl VideoPipeline { bounds.y + bounds.height, ], }; - queue.write_buffer(buffer, 0, unsafe { + queue.write_buffer(&video.uniforms, 0, unsafe { std::slice::from_raw_parts( &uniforms as *const _ as *const u8, std::mem::size_of::(), @@ -322,7 +328,7 @@ impl VideoPipeline { viewport: &iced::Rectangle, video_id: u64, ) { - if let Some((_, _, _, bind_group, _)) = self.textures.get(&video_id) { + if let Some(video) = self.videos.get(&video_id) { let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("iced_video_player render pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { @@ -339,7 +345,7 @@ impl VideoPipeline { }); pass.set_pipeline(&self.pipeline); - pass.set_bind_group(0, bind_group, &[]); + pass.set_bind_group(0, &video.bg0, &[]); pass.set_viewport( viewport.x as _, viewport.y as _, diff --git a/src/video.rs b/src/video.rs index c7de2b0..2306c56 100644 --- a/src/video.rs +++ b/src/video.rs @@ -206,7 +206,7 @@ impl Video { .map_err(|_| Error::Cast)?; let video_sink: gst::Element = pipeline.property("video-sink"); - let pad = video_sink.pads().get(0).cloned().unwrap(); + let pad = video_sink.pads().first().cloned().unwrap(); let pad = pad.dynamic_cast::().unwrap(); let bin = pad .parent_element() @@ -328,7 +328,7 @@ impl Video { upload_frame_ref.swap(true, Ordering::SeqCst); - if let Some(at) = clear_subtitles_at.clone() { + if let Some(at) = clear_subtitles_at { if Instant::now() >= at { *subtitle_text_ref .lock() @@ -607,5 +607,5 @@ fn yuv_to_rgba(yuv: &[u8], width: u32, height: u32, downscale: u32) -> Vec { } } - return rgba; + rgba } diff --git a/src/video_player.rs b/src/video_player.rs index 2d8e44f..2c66a15 100644 --- a/src/video_player.rs +++ b/src/video_player.rs @@ -187,7 +187,7 @@ where let last_frame_time = inner .last_frame_time .lock() - .map(|time| time.clone()) + .map(|time| *time) .unwrap_or_else(|_| Instant::now()); inner.set_av_offset(Instant::now() - last_frame_time); } @@ -270,7 +270,7 @@ where if let Some(on_subtitle_text) = &self.on_subtitle_text { if inner.upload_text.swap(false, Ordering::SeqCst) { - if let Some(text) = inner.subtitle_text.try_lock().ok() { + if let Ok(text) = inner.subtitle_text.try_lock() { shell.publish(on_subtitle_text(text.clone())); } }