diff --git a/src/main.rs b/src/main.rs index dafa6b15747bd3c27dc80ccf922d80126da81e5c..df06960d065567667e1b58f8d37d35f1b8f80a4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ pub(crate) mod spritesheet; use crate::ffmpeg_api::enums::*; use crate::ffmpeg_api::api::*; -use image::{ImageBuffer}; +use crate::media_time::MediaTime; fn main() -> Result<(), std::io::Error> { let mut before = std::time::SystemTime::now(); @@ -25,6 +25,7 @@ fn main() -> Result<(), std::io::Error> { let mut spritesheet_manager = spritesheet::SpritesheetManager::new( 160, 5, 5, + MediaTime::from_seconds(10), output, ); @@ -89,42 +90,44 @@ fn main() -> Result<(), std::io::Error> { println!("Reading Time: {:#?}", before.elapsed().unwrap()); before = std::time::SystemTime::now(); - if !spritesheet_manager.initialized() { - spritesheet_manager.initialize(frame.width() as u32, frame.height() as u32); - output_frame.init( - spritesheet_manager.sprite_width() as i32, - spritesheet_manager.sprite_height() as i32, - AVPixelFormat::RGB24, - ).unwrap_or_else(|error| { - panic!("Could not init output frame: {:?}", error) - }); - scale_context.reinit( - &frame, - &output_frame, - SwsScaler::FastBilinear, - ).unwrap_or_else(|error| { - panic!("Could not reinit scale context: {:?}", error) - }); + if spritesheet_manager.fulfils_frame_interval(stream.timestamp(frame.pts())) { + if !spritesheet_manager.initialized() { + spritesheet_manager.initialize(frame.width() as u32, frame.height() as u32); + output_frame.init( + spritesheet_manager.sprite_width() as i32, + spritesheet_manager.sprite_height() as i32, + AVPixelFormat::RGB24, + ).unwrap_or_else(|error| { + panic!("Could not init output frame: {:?}", error) + }); + scale_context.reinit( + &frame, + &output_frame, + SwsScaler::FastBilinear, + ).unwrap_or_else(|error| { + panic!("Could not reinit scale context: {:?}", error) + }); + } + + scale_context.scale(&frame, &mut output_frame); + + println!("Processing Time: {:#?}", before.elapsed().unwrap()); + before = std::time::SystemTime::now(); + + spritesheet_manager.add_image( + stream.timestamp(frame.pts()), + image::ImageBuffer::from_raw( + output_frame.width() as u32, + output_frame.height() as u32, + output_frame.data(0).to_vec(), + ).unwrap_or_else(|| { + panic!("Could not process frame") + }), + ); + + println!("Writing Time: {:#?}", before.elapsed().unwrap()); + before = std::time::SystemTime::now(); } - - scale_context.scale(&frame, &mut output_frame); - - println!("Processing Time: {:#?}", before.elapsed().unwrap()); - before = std::time::SystemTime::now(); - - spritesheet_manager.add_image( - stream.timestamp(frame.pts()), - ImageBuffer::from_raw( - output_frame.width() as u32, - output_frame.height() as u32, - output_frame.data(0).to_vec(), - ).unwrap_or_else(|| { - panic!("Could not process frame") - }), - ); - - println!("Writing Time: {:#?}", before.elapsed().unwrap()); - before = std::time::SystemTime::now(); } } } diff --git a/src/media_time.rs b/src/media_time.rs index f5d257cb1a62051613fa6f2d3b3bdb8fcc3a3c17..32edd38dfc6422cf106b82953237752b8e646ba8 100644 --- a/src/media_time.rs +++ b/src/media_time.rs @@ -1,6 +1,6 @@ use fraction::Fraction; -#[derive(Copy,Clone,Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct MediaTime(time::Duration); impl MediaTime { @@ -40,4 +40,20 @@ impl std::fmt::Display for MediaTime { write!(f, "{:02}:{:02}:{:02}.{:03}", h, m, s, z) } } +} + +impl std::ops::Add for MediaTime { + type Output = Self; + + fn add(self, other: Self) -> Self { + Self(self.0 + other.0) + } +} + +impl std::ops::Sub for MediaTime { + type Output = Self; + + fn sub(self, other: Self) -> Self { + Self(self.0 - other.0) + } } \ No newline at end of file diff --git a/src/spritesheet.rs b/src/spritesheet.rs index c55a2f5c823b91a5f631fd4d4ab6e9b5f066aead..96ec0a4d9cbae724847e01d3d8ec5e293958f520 100644 --- a/src/spritesheet.rs +++ b/src/spritesheet.rs @@ -11,13 +11,14 @@ pub struct SpritesheetManager { spritesheet: RgbImage, current_image: u32, last_timestamp: MediaTime, + frame_interval: MediaTime, metadata: WebVTTFile, output_path: std::string::String, initialized: bool, } impl SpritesheetManager { - pub fn new<T: AsRef<str>>(max_side: u32, num_horizontal: u32, num_vertical: u32, output_path: T) -> SpritesheetManager { + pub fn new<T: AsRef<str>>(max_side: u32, num_horizontal: u32, num_vertical: u32, frame_interval: MediaTime, output_path: T) -> SpritesheetManager { SpritesheetManager { num_horizontal, num_vertical, @@ -27,6 +28,7 @@ impl SpritesheetManager { spritesheet: ImageBuffer::new(0, 0), current_image: 0, last_timestamp: MediaTime::from_millis(0), + frame_interval, metadata: WebVTTFile::new(), output_path: std::string::String::from(output_path.as_ref()), initialized: false, @@ -82,6 +84,10 @@ impl SpritesheetManager { index * self.sprite_height } + pub fn fulfils_frame_interval(&self, timestamp: MediaTime) -> bool { + timestamp - self.last_timestamp > self.frame_interval + } + pub fn add_image(&mut self, timestamp: MediaTime, image: RgbImage) { if image.width() != self.sprite_width || image.height() != self.sprite_height { panic!(