1- use blockhash:: { blockhash256, Blockhash256 } ;
21use crossbeam_channel:: Receiver ;
32use rayon:: ThreadPoolBuilder ;
43use std:: borrow:: Borrow ;
@@ -7,39 +6,12 @@ use std::sync::{Arc, Mutex};
76use std:: time:: { Duration , Instant } ;
87use tempfile:: TempDir ;
98
9+ use crate :: capture:: frame_comparator:: FrameComparator ;
10+ use crate :: capture:: frame_essence:: { FrameDropStrategy , FrameEssence } ;
1011use crate :: capture:: { Framerate , Timecode } ;
1112use crate :: utils:: file_name_for;
1213use crate :: { Frame , PlatformApi , Result , WindowId } ;
1314
14- #[ derive( Eq , PartialEq , Clone ) ]
15- pub enum FrameDropStrategy {
16- DoNotDropAny ,
17- DropIdenticalFrames ,
18- }
19-
20- #[ derive( Clone ) ]
21- struct FrameComparator {
22- last_frames : Vec < ( Timecode , Timecode , Blockhash256 ) > ,
23- _strategy : FrameDropStrategy ,
24- }
25-
26- impl FrameComparator {
27- pub fn should_drop_frame ( & mut self , timecode : & Timecode , frame : & Frame ) -> bool {
28- let hash = blockhash256 ( frame) ;
29- if let Some ( ( _last_time_code, _other_time_code, last_hash) ) = self . last_frames . last ( ) {
30- let last_eq = last_hash == & hash;
31- if !last_eq {
32- self . last_frames . pop ( ) ;
33- self . last_frames . push ( ( timecode. clone ( ) , hash) ) ;
34- }
35- last_eq
36- } else {
37- self . last_frames . push ( ( timecode. clone ( ) , hash) ) ;
38- false
39- }
40- }
41- }
42-
4315/// captures screenshots as file on disk
4416/// collects also the timecodes when they have been captured
4517/// stops once receiving something in rx
@@ -55,23 +27,16 @@ pub fn capture_thread(
5527 let pool = ThreadPoolBuilder :: default ( ) . build ( ) ?;
5628 let duration = Duration :: from_secs ( 1 ) / * framerate. as_ref ( ) ;
5729 let start = Instant :: now ( ) ;
58- // let mut idle_duration = Duration::from_millis(0);
59- // let mut last_frame: Option<ImageOnHeap> = None;
60- // let mut identical_frames = 0;
6130 let mut last_time = Instant :: now ( ) ;
6231 let api = Arc :: new ( api) ;
63- let comp = Arc :: new ( Mutex :: new ( FrameComparator {
64- last_frames : Vec :: new ( ) ,
65- _strategy : frame_drop_strategy. clone ( ) ,
66- } ) ) ;
67- // let rx = Arc::new(rx);
68- // let mut results: Arc<Mutex<Vec<Result<()>>>> = Arc::new(Mutex::new(Vec::new()));
32+ let comparator = Arc :: new ( Mutex :: new ( FrameComparator :: new (
33+ frame_drop_strategy. clone ( ) ,
34+ ) ) ) ;
6935
7036 pool. scope ( |s| {
7137 loop {
7238 let delta = Instant :: now ( ) . saturating_duration_since ( last_time) ;
7339 let sleep_time = duration. sub ( delta) ;
74- // thread::sleep(sleep_time);
7540 // blocks for a timeout
7641 if rx. recv_timeout ( sleep_time) . is_ok ( ) {
7742 if pool. current_thread_has_pending_tasks ( ) . unwrap_or ( false ) {
@@ -85,53 +50,28 @@ pub fn capture_thread(
8550 s. spawn ( {
8651 let api = api. clone ( ) ;
8752 let tempdir = tempdir. clone ( ) ;
88- let comp = comp . clone ( ) ;
53+ let comp = comparator . clone ( ) ;
8954 let time_codes = time_codes. clone ( ) ;
9055 move |_| {
9156 let tc: Timecode = now. saturating_duration_since ( start) . as_millis ( ) . into ( ) ;
92-
93- let frame = api. capture_window_screenshot ( win_id) ;
94- if let Ok ( frame) = frame {
57+ if let Ok ( frame) = api. capture_window_screenshot ( win_id) {
9558 let frame: Frame = frame. into ( ) ;
96- if comp. lock ( ) . unwrap ( ) . should_drop_frame ( & tc, & frame) {
97- return ;
59+ let frame_essence = FrameEssence :: new ( & frame, & tc) ;
60+ {
61+ let mut lock = comp. try_lock ( ) ;
62+ if let Ok ( ref mut mutex) = lock {
63+ if mutex. should_drop_frame ( frame_essence) {
64+ return ;
65+ }
66+ } else {
67+ dbg ! ( " locking failed..." ) ;
68+ }
9869 }
9970 frame. save ( & tc, tempdir. borrow ( ) , file_name_for) . unwrap ( ) ;
10071 time_codes. lock ( ) . unwrap ( ) . push ( tc) ;
101- // results.borrow_mut().lock().unwrap().push(result);
10272 }
10373 }
104- } ) ;
105-
106- /*
107- let image = api.capture_window_screenshot(win_id)?;
108- if frame_drop_strategy == &FrameDropStrategy::DropIdenticalFrames {
109- if last_frame.is_some()
110- && image
111- .samples
112- .as_slice()
113- .eq(last_frame.as_ref().unwrap().samples.as_slice())
114- {
115- identical_frames += 1;
116- } else {
117- identical_frames = 0;
118- }
119- }
120-
121- if identical_frames > 0 {
122- // let's track now the duration as idle
123- idle_duration = idle_duration.add(now.duration_since(last_now));
124- } else {
125- if let Err(e) = save_frame(&image, tc, tempdir.lock().unwrap().borrow(), file_name_for)
126- {
127- eprintln!("{}", &e);
128- return Err(e);
129- }
130- time_codes.lock().unwrap().push(tc);
131- last_frame = Some(image);
132- identical_frames = 0;
133- }
134- */
74+ } ) ;
13575
13676 last_time = now;
13777 }
0 commit comments