From 5fac470b8f9cdff170171f0aec8493a4b77f2d07 Mon Sep 17 00:00:00 2001 From: rnissl Date: Sun, 31 Mar 2024 11:34:31 +0200 Subject: [PATCH] generate select filter as binary search for less stack consumption during evaluation --- mapillary_tools/ffmpeg.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mapillary_tools/ffmpeg.py b/mapillary_tools/ffmpeg.py index 9ade31ee..1cc68f40 100644 --- a/mapillary_tools/ffmpeg.py +++ b/mapillary_tools/ffmpeg.py @@ -195,6 +195,21 @@ def extract_frames( self._run_ffmpeg(cmd) + def generate_binary_search( + self, + sorted_frame_indices: T.Set[int] + ) -> str: + length = len(sorted_frame_indices) + + if length == 0: + return "0" + + if length == 1: + return f"eq(n\\,{ sorted_frame_indices[0] })" + + middle = length // 2 + return f"if(lt(n\\,{ sorted_frame_indices[middle] })\\,{ self.generate_binary_search(sorted_frame_indices[:middle]) }\\,{ self.generate_binary_search(sorted_frame_indices[middle:]) })" + def extract_specified_frames( self, video_path: Path, @@ -226,7 +241,7 @@ def extract_specified_frames( # the maximum command line length for the CreateProcess function is 32767 characters # https://devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553 - eqs = "+".join(f"eq(n\\,{idx})" for idx in sorted(frame_indices)) + eqs = self.generate_binary_search(sorted(frame_indices)) # https://github.com/mapillary/mapillary_tools/issues/503 if sys.platform in ["win32"]: