From 65e7174d8450bca3ac6236e637e0f46fdf64d6e8 Mon Sep 17 00:00:00 2001 From: Janne Mareike Koschinski <janne@kuschku.de> Date: Sun, 22 Jun 2025 15:33:39 +0200 Subject: [PATCH] Avoid decoding packets with no relevant timestamps --- lib/ffmpeg_api/src/api.rs | 4 +++ src/lib.rs | 68 +++++++++++++++++++++++++-------------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/lib/ffmpeg_api/src/api.rs b/lib/ffmpeg_api/src/api.rs index 960b05b..faf934b 100644 --- a/lib/ffmpeg_api/src/api.rs +++ b/lib/ffmpeg_api/src/api.rs @@ -223,6 +223,10 @@ impl AVPacket { unsafe { self.base.as_ref() }.unwrap_or_else(|| panic!("AVPacket base unexpectedly null")) } + pub fn duration(&self) -> i64 { + self.as_ref().duration + } + pub fn pts(&self) -> i64 { self.as_ref().pts } diff --git a/src/lib.rs b/src/lib.rs index 461998f..23bfaaa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ pub fn extract( } else { None }; - + let mut timelens_manager: Option<timelens::TimelensManager> = if let Some(options) = timelens_options { Some(timelens::TimelensManager::new( options, @@ -91,34 +91,52 @@ pub fn extract( while avformat_context.read_frame(&mut packet).is_ok() { if packet.stream_index() == index { - codec_context - .in_packet(&mut packet) - .map_err(|error| format_err!("Could not load packet: {}", error))?; - while codec_context.out_frame(&mut frame).is_ok() { - let timestamp = media_time::MediaTime::from_rational(frame.pts(), &time_base)?; - - println!( - "Frame {}: {} @ {}", - frame.coded_picture_number(), - timestamp, - frame.key_frame() - ); - - if let Some(spritesheet_manager) = &mut spritesheet_manager { - if spritesheet_manager.fulfils_frame_interval(timestamp) { - if !spritesheet_manager.initialized() { - spritesheet_manager.initialize(frame.width() as u32, frame.height() as u32)?; + let duration = media_time::MediaTime::from_rational(packet.duration(), &time_base)?; + let start = media_time::MediaTime::from_rational(packet.pts(), &time_base)?; + let end = start + duration; + + let mut skip = true; + if let Some(spritesheet_manager) = &mut spritesheet_manager { + if spritesheet_manager.fulfils_frame_interval(end) { + skip = false; + } + } + if let Some(timelens_manager) = &mut timelens_manager { + if timelens_manager.fulfils_frame_interval(end) { + skip = false; + } + } + + if !skip { + codec_context + .in_packet(&mut packet) + .map_err(|error| format_err!("Could not load packet: {}", error))?; + while codec_context.out_frame(&mut frame).is_ok() { + let timestamp = media_time::MediaTime::from_rational(frame.pts(), &time_base)?; + + println!( + "Frame {}: {} @ {}", + frame.coded_picture_number(), + timestamp, + frame.key_frame() + ); + + if let Some(spritesheet_manager) = &mut spritesheet_manager { + if spritesheet_manager.fulfils_frame_interval(timestamp) { + if !spritesheet_manager.initialized() { + spritesheet_manager.initialize(frame.width() as u32, frame.height() as u32)?; + } + spritesheet_manager.add_frame(&mut scale_context, scaler, flags, timestamp, &frame)?; } - spritesheet_manager.add_frame(&mut scale_context, scaler, flags, timestamp, &frame)?; } - } - if let Some(timelens_manager) = &mut timelens_manager { - if timelens_manager.fulfils_frame_interval(timestamp) { - if !timelens_manager.initialized() { - timelens_manager.initialize()?; + if let Some(timelens_manager) = &mut timelens_manager { + if timelens_manager.fulfils_frame_interval(timestamp) { + if !timelens_manager.initialized() { + timelens_manager.initialize()?; + } + timelens_manager.add_frame(&mut scale_context, scaler, flags, timestamp, &frame)?; } - timelens_manager.add_frame(&mut scale_context, scaler, flags, timestamp, &frame)?; } } } -- GitLab