From d1cbd502d74b641ae347108fea0417d2c61227d2 Mon Sep 17 00:00:00 2001 From: Ivan Korostelev Date: Tue, 11 Jun 2019 18:50:53 +0300 Subject: [PATCH 1/2] [FIX] VideoManager read function failed on multiple videos scene detection if downscale factor was set --- scenedetect/video_manager.py | 9 +++++++-- tests/test_video_manager.py | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/scenedetect/video_manager.py b/scenedetect/video_manager.py index e247e1ed..dda8a74c 100644 --- a/scenedetect/video_manager.py +++ b/scenedetect/video_manager.py @@ -743,8 +743,13 @@ def read(self): if self._curr_cap is not None and self._end_of_video != True: while not read_frame: read_frame, self._last_frame = self._curr_cap.read() - if not read_frame and not self._get_next_cap(): - break + # Switch to the next capture when the current one is over + if not read_frame: + # Break the loop when all the captures are over + if not self._get_next_cap(): + break + # Get frame of the new capture + read_frame, self._last_frame = self._curr_cap.read() if self._downscale_factor > 1: self._last_frame = self._last_frame[ ::self._downscale_factor, ::self._downscale_factor, :] diff --git a/tests/test_video_manager.py b/tests/test_video_manager.py index 6b347d1b..27c09b49 100644 --- a/tests/test_video_manager.py +++ b/tests/test_video_manager.py @@ -51,6 +51,7 @@ import pytest import cv2 +from scenedetect.scene_manager import SceneManager # PySceneDetect Library Imports from scenedetect.video_manager import VideoManager from scenedetect.video_manager import VideoOpenFailure @@ -281,3 +282,19 @@ def test_multiple_videos(test_video_file): # Will release the VideoManagers in vm_list as well. video_manager.release() +def test_many_videos_downscale_detect_scenes(test_video_file): + """ Test VideoManager handling decoding frames across video boundaries. """ + + NUM_FRAMES = 10 + NUM_VIDEOS = 3 + # Open VideoManager and get base timecode. + video_manager = VideoManager([test_video_file] * NUM_VIDEOS) + video_manager.set_downscale_factor() + + try: + video_manager.start() + scene_manager = SceneManager() + scene_manager.detect_scenes(frame_source=video_manager) + finally: + # Will release the VideoManagers in vm_list as well. + video_manager.release() From 50e42118f79b1dae82956d34c875c21495bc08a8 Mon Sep 17 00:00:00 2001 From: Ivan Korostelev Date: Fri, 14 Jun 2019 02:02:38 +0300 Subject: [PATCH 2/2] Pull request conversation changes --- scenedetect/video_manager.py | 22 ++++++++++------------ tests/test_video_manager.py | 5 ++--- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/scenedetect/video_manager.py b/scenedetect/video_manager.py index dda8a74c..39091ad4 100644 --- a/scenedetect/video_manager.py +++ b/scenedetect/video_manager.py @@ -739,20 +739,18 @@ def read(self): if not self._started: raise VideoDecoderNotStarted() - read_frame = False if self._curr_cap is not None and self._end_of_video != True: - while not read_frame: + read_frame, self._last_frame = self._curr_cap.read() + + # Switch to the next capture when the current one is over + if not read_frame and self._get_next_cap(): read_frame, self._last_frame = self._curr_cap.read() - # Switch to the next capture when the current one is over - if not read_frame: - # Break the loop when all the captures are over - if not self._get_next_cap(): - break - # Get frame of the new capture - read_frame, self._last_frame = self._curr_cap.read() - if self._downscale_factor > 1: - self._last_frame = self._last_frame[ - ::self._downscale_factor, ::self._downscale_factor, :] + + # Downscale frame if there was any + if read_frame and self._downscale_factor > 1: + self._last_frame = self._last_frame[ + ::self._downscale_factor, ::self._downscale_factor, :] + if self._end_time is not None and self._curr_time > self._end_time: read_frame = False self._last_frame = None diff --git a/tests/test_video_manager.py b/tests/test_video_manager.py index 27c09b49..aeecea7b 100644 --- a/tests/test_video_manager.py +++ b/tests/test_video_manager.py @@ -283,11 +283,10 @@ def test_multiple_videos(test_video_file): video_manager.release() def test_many_videos_downscale_detect_scenes(test_video_file): - """ Test VideoManager handling decoding frames across video boundaries. """ + """ Test scene detection on multiple videos in VideoManager. """ - NUM_FRAMES = 10 NUM_VIDEOS = 3 - # Open VideoManager and get base timecode. + # Open VideoManager with NUM_VIDEOS test videos video_manager = VideoManager([test_video_file] * NUM_VIDEOS) video_manager.set_downscale_factor()