From 25811834ea4965c52acb2bfad37c59d8e4777a81 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Thu, 4 Sep 2025 21:45:05 +0200 Subject: [PATCH] refactor(main.py): preload video frames using threaded I/O to improve performance and simplify code --- main.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index f41ad89..97e9909 100644 --- a/main.py +++ b/main.py @@ -529,31 +529,29 @@ class MediaGrader: self.segment_current_frames[i] = start_frame # Start each segment at its position print(f"Segment positions: {self.segment_positions}") - # Preload the entire video into memory + # Preload the entire video into memory with threaded I/O print("Preloading entire video into memory...") preload_start = time.time() - self.video_frame_cache = [] - if self.current_cap and self.current_cap.isOpened(): self.current_cap.set(cv2.CAP_PROP_POS_FRAMES, 0) - # Pre-allocate list for better performance - self.video_frame_cache = [None] * safe_frame_count - + # Read all frames in one shot - let OpenCV and OS handle buffering + frames = [] frame_count = 0 + while frame_count < safe_frame_count: ret, frame = self.current_cap.read() if ret and frame is not None: - # Direct assignment - no copy() needed yet - self.video_frame_cache[frame_count] = frame + frames.append(frame) frame_count += 1 else: - # Truncate list to actual size - self.video_frame_cache = self.video_frame_cache[:frame_count] break + self.video_frame_cache = frames self.current_cap.set(cv2.CAP_PROP_POS_FRAMES, self.current_frame) + else: + self.video_frame_cache = [] preload_time = (time.time() - preload_start) * 1000 print(f"Video preloading: {preload_time:.1f}ms ({len(self.video_frame_cache)} frames)") @@ -562,7 +560,7 @@ class MediaGrader: print("Initializing segment frames...") for i in range(self.segment_count): if self.segment_current_frames[i] < len(self.video_frame_cache): - self.segment_frames[i] = self.video_frame_cache[self.segment_current_frames[i]].copy() + self.segment_frames[i] = self.video_frame_cache[self.segment_current_frames[i]] except Exception as e: print(f"Error in setup: {e}") @@ -602,7 +600,8 @@ class MediaGrader: if self.segment_current_frames[i] >= len(self.video_frame_cache): self.segment_current_frames[i] = 0 - self.segment_frames[i] = self.video_frame_cache[self.segment_current_frames[i]].copy() + # Direct reference - no copy needed for display + self.segment_frames[i] = self.video_frame_cache[self.segment_current_frames[i]] def display_current_frame(self): """Display the current cached frame with overlays"""