Greatly improve performance

yippie!
This commit is contained in:
2025-09-04 20:59:27 +02:00
parent df103e4070
commit 6e9bb9ad8e

View File

@@ -180,9 +180,32 @@ class VideoEditor:
self.cap.release()
self.video_path = video_path
self.cap = cv2.VideoCapture(str(self.video_path))
if not self.cap.isOpened():
# Try different backends for better performance
# Order of preference: DirectShow (Windows), FFmpeg, any available
backends_to_try = []
if hasattr(cv2, 'CAP_DSHOW'): # Windows DirectShow
backends_to_try.append(cv2.CAP_DSHOW)
if hasattr(cv2, 'CAP_FFMPEG'): # FFmpeg
backends_to_try.append(cv2.CAP_FFMPEG)
backends_to_try.append(cv2.CAP_ANY) # Fallback
self.cap = None
for backend in backends_to_try:
try:
self.cap = cv2.VideoCapture(str(self.video_path), backend)
if self.cap.isOpened():
# Optimize buffer settings for better performance
self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # Minimize buffer to reduce latency
# Try to set hardware acceleration if available
if hasattr(cv2, 'CAP_PROP_HW_ACCELERATION'):
self.cap.set(cv2.CAP_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY)
break
self.cap.release()
except:
continue
if not self.cap or not self.cap.isOpened():
raise ValueError(f"Could not open video file: {video_path}")
# Video properties
@@ -191,6 +214,13 @@ class VideoEditor:
self.frame_width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self.frame_height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# Get codec information for debugging
fourcc = int(self.cap.get(cv2.CAP_PROP_FOURCC))
codec = "".join([chr((fourcc >> 8 * i) & 0xFF) for i in range(4)])
# Get backend information
backend = self.cap.getBackendName()
# Reset playback state for new video
self.current_frame = 0
self.is_playing = False
@@ -212,6 +242,16 @@ class VideoEditor:
print(
f"Loaded video: {self.video_path.name} ({self.current_video_index + 1}/{len(self.video_files)})"
)
print(f" Codec: {codec} | Backend: {backend} | Resolution: {self.frame_width}x{self.frame_height}")
print(f" FPS: {self.fps:.2f} | Frames: {self.total_frames} | Duration: {self.total_frames/self.fps:.1f}s")
# Performance warning for known problematic cases
if codec in ['H264', 'H.264', 'AVC1', 'avc1'] and self.total_frames > 10000:
print(f" Warning: Large H.264 video detected - seeking may be slow")
if self.frame_width * self.frame_height > 1920 * 1080:
print(f" Warning: High resolution video - decoding may be slow")
if self.fps > 60:
print(f" Warning: High framerate video - may impact playback smoothness")
def switch_to_video(self, index: int):
"""Switch to a specific video by index"""
@@ -271,15 +311,23 @@ class VideoEditor:
self.load_current_frame()
def advance_frame(self) -> bool:
"""Advance to next frame"""
"""Advance to next frame - optimized to avoid seeking"""
if not self.is_playing:
return True
self.current_frame += 1
if self.current_frame >= self.total_frames:
self.current_frame = 0 # Loop
self.current_frame = 0 # Loop - this will require a seek
return self.load_current_frame()
return self.load_current_frame()
# For sequential playback, just read the next frame without seeking
ret, frame = self.cap.read()
if ret:
self.current_display_frame = frame
return True
else:
# If sequential read failed, fall back to seeking (might be end of file or codec issue)
return self.load_current_frame()
def apply_crop_zoom_and_rotation(self, frame):
"""Apply current crop, zoom, rotation, and brightness/contrast settings to frame"""
@@ -1245,6 +1293,7 @@ class VideoEditor:
self.load_current_frame()
while True:
# Only update display if needed
self.display_current_frame()
delay = self.calculate_frame_delay() if self.is_playing else 30
@@ -1355,7 +1404,6 @@ class VideoEditor:
print(f"Contracted crop from left by {self.crop_size_step}px")
# Auto advance frame when playing
if self.is_playing:
self.advance_frame()