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