diff --git a/lib/ffmpeg_api/src/api.rs b/lib/ffmpeg_api/src/api.rs index 960b05b26e0dc06902c7df968b5c6648849ab793..faf934b1996f344af35c3111fc852b42091d99ff 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 461998fee572fb60ac79bd18b8805de127ea4d52..23bfaaa24cb2e36ac7c0cea336aaacfdb1d93e91 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)?; } } }