Greatly improve performance
yippie!
This commit is contained in:
@@ -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()
|
||||
|
Reference in New Issue
Block a user