Skip to content

Commit be1fd92

Browse files
committed
perf: implement zero-copy frame rendering via Arc and non-blocking frame-dropping channels
1 parent 2a8e40e commit be1fd92

2 files changed

Lines changed: 13 additions & 11 deletions

File tree

crates/media-sort-backend/src/media/mpv_context.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ pub enum VideoEvent {
342342
path: std::path::PathBuf,
343343
width: u32,
344344
height: u32,
345-
rgba: Vec<u8>,
345+
rgba: std::sync::Arc<Vec<u8>>,
346346
},
347347
PlaybackProgress {
348348
position: f64,
@@ -380,7 +380,7 @@ pub async fn run_video_worker(
380380
player.register_callback(wakeup_tx);
381381
}
382382

383-
let mut buffer = Vec::new();
383+
384384
let mut current_video_path = std::path::PathBuf::new();
385385
let mut last_position = -1.0;
386386
let mut last_muted = false;
@@ -452,7 +452,7 @@ pub async fn run_video_worker(
452452
}
453453
}
454454

455-
if should_render {
455+
if should_render && event_tx.capacity() > 0 {
456456
let flags = unsafe {
457457
mpv_render_context_update(player.render_ctx)
458458
};
@@ -466,17 +466,15 @@ pub async fn run_video_worker(
466466
let render_h = (h as f64 * scale) as i32;
467467

468468
let size = (render_w * render_h * 4) as usize;
469-
if buffer.len() != size {
470-
buffer.resize(size, 0);
471-
}
469+
let mut frame_buffer = vec![0u8; size];
472470

473-
if player.render_frame(render_w, render_h, &mut buffer).is_ok() {
474-
let _ = event_tx.send(VideoEvent::FrameReady {
471+
if player.render_frame(render_w, render_h, &mut frame_buffer).is_ok() {
472+
let _ = event_tx.try_send(VideoEvent::FrameReady {
475473
path: current_video_path.clone(),
476474
width: render_w as u32,
477475
height: render_h as u32,
478-
rgba: buffer.clone(),
479-
}).await;
476+
rgba: std::sync::Arc::new(frame_buffer),
477+
});
480478
}
481479
}
482480
}

crates/media-sort-gui/src/app.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ pub fn update(state: &mut AppState, message: Message) -> Task<Message> {
3030
let current_path = state.selected_index
3131
.and_then(|idx| state.filtered_media_entries().get(idx).map(|e| e.path.clone()));
3232
if Some(path) == current_path {
33-
state.video_frame = Some(iced::widget::image::Handle::from_rgba(width, height, rgba));
33+
let pixels = match std::sync::Arc::try_unwrap(rgba) {
34+
Ok(vec) => vec,
35+
Err(arc) => (*arc).clone(),
36+
};
37+
state.video_frame = Some(iced::widget::image::Handle::from_rgba(width, height, pixels));
3438
}
3539
}
3640
media_sort_backend::media::mpv_context::VideoEvent::PlaybackProgress { position, duration } => {

0 commit comments

Comments
 (0)