From b3931999f48234044c1db2085ae7ae10eaf55b5a Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 20 May 2024 14:07:41 +0200 Subject: [PATCH] pipewire: updates buffer metadata in correct order --- src/pipewire/pw_ifs/pw_client_node.rs | 8 +-- src/portal/ptl_screencast.rs | 85 +++++++++++++-------------- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/src/pipewire/pw_ifs/pw_client_node.rs b/src/pipewire/pw_ifs/pw_client_node.rs index ac139ac1..33b3f1e5 100644 --- a/src/pipewire/pw_ifs/pw_client_node.rs +++ b/src/pipewire/pw_ifs/pw_client_node.rs @@ -120,7 +120,7 @@ pub struct PwClientNodePort { pub buffer_config: Cell>, - pub io_buffers: CopyHashMap>>, + pub io_buffers: CloneCell>>>, pub serial: Cell, } @@ -705,12 +705,12 @@ impl PwClientNode { let size = p2.read_uint()?; let port = self.get_port(direction, port_id)?; match id { - SPA_IO_Buffers => { + SPA_IO_Buffers if mix_id == 0 => { if mem_id == !0 { - port.io_buffers.remove(&mix_id); + port.io_buffers.take(); } else { port.io_buffers - .set(mix_id, self.con.mem.map(mem_id, offset, size)?.typed()); + .set(Some(self.con.mem.map(mem_id, offset, size)?.typed())); } } _ => {} diff --git a/src/portal/ptl_screencast.rs b/src/portal/ptl_screencast.rs index fafc706b..4b954000 100644 --- a/src/portal/ptl_screencast.rs +++ b/src/portal/ptl_screencast.rs @@ -405,54 +405,53 @@ impl UsrJayScreencastOwner for StartedScreencast { fn ready(&self, ev: &Ready) { let idx = ev.idx as usize; - if !self.buffers_valid.get() { + let buffers = &*self.buffers.borrow(); + let pbuffers = self.port.buffers.borrow(); + let buffer = &buffers[idx]; + let discard_buffer = || { self.jay_screencast.release_buffer(idx); + }; + if !self.buffers_valid.get() { + discard_buffer(); return; } - unsafe { - let mut used = false; - if let Some(io) = self.port.io_buffers.lock().values().next() { - let io = io.write(); - let status = io.status.load(Acquire); - if status != SPA_STATUS_HAVE_DATA.0 { - used = true; - let buffer_id = io.buffer_id.load(Relaxed); - if buffer_id != ev.idx { - if (buffer_id as usize) < self.buffers.borrow_mut().len() { - self.jay_screencast.release_buffer(buffer_id as usize); - } - } - io.buffer_id.store(ev.idx, Relaxed); - io.status.store(SPA_STATUS_HAVE_DATA.0, Release); - } - } - if !used { - self.jay_screencast.release_buffer(idx); - } - { - let pbuffers = self.port.buffers.borrow_mut(); - let buffers = self.buffers.borrow_mut(); - if let Some(pbuffer) = pbuffers.get(idx) { - let buffer = &buffers[idx]; - for (chunk, plane) in pbuffer.chunks.iter().zip(buffer.planes.iter()) { - let chunk = chunk.write(); - chunk.flags = SpaChunkFlags::none(); - chunk.offset = plane.offset; - chunk.stride = plane.stride; - chunk.size = plane.stride * buffer.height as u32; - } - if let Some(crop) = &pbuffer.meta_video_crop { - crop.write().region = spa_region { - position: spa_point { x: 0, y: 0 }, - size: spa_rectangle { - width: buffer.width as _, - height: buffer.height as _, - }, - }; - } - } + let Some(io) = self.port.io_buffers.get() else { + discard_buffer(); + return; + }; + let Some(pbuffer) = pbuffers.get(idx) else { + discard_buffer(); + return; + }; + let io = unsafe { io.read() }; + if io.status.load(Acquire) == SPA_STATUS_HAVE_DATA.0 { + discard_buffer(); + return; + } + for (chunk, plane) in pbuffer.chunks.iter().zip(buffer.planes.iter()) { + let chunk = unsafe { chunk.write() }; + chunk.flags = SpaChunkFlags::none(); + chunk.offset = plane.offset; + chunk.stride = plane.stride; + chunk.size = plane.stride * buffer.height as u32; + } + if let Some(crop) = &pbuffer.meta_video_crop { + unsafe { crop.write() }.region = spa_region { + position: spa_point { x: 0, y: 0 }, + size: spa_rectangle { + width: buffer.width as _, + height: buffer.height as _, + }, + }; + } + let buffer_id = io.buffer_id.load(Relaxed) as usize; + if buffer_id != idx { + if buffer_id < buffers.len() { + self.jay_screencast.release_buffer(buffer_id); } } + io.buffer_id.store(ev.idx, Relaxed); + io.status.store(SPA_STATUS_HAVE_DATA.0, Release); if let Some(wfd) = self.port.node.transport_out.get() { let _ = uapi::eventfd_write(wfd.raw(), 1); }