diff --git a/docs/module-internals.md b/docs/module-internals.md index 4484965..8919c90 100644 --- a/docs/module-internals.md +++ b/docs/module-internals.md @@ -149,10 +149,11 @@ regeneration. It centralizes container codecs, optional audio stream copying, metadata/chapter policy, encode-failure reporting, and atomic same-directory publication. Each mapped stream is allowed to reach its own end, so a copied audio tail is not shortened to the frame-input duration. -Both the raw-BGR and timestamped-NUT stdin modes cap the video encoder at two -threads. A Linux full-clip trace showed ffmpeg creating dozens of worker stacks -and severely delaying frame-pipe ingestion on a constrained hosted runner. The -bounded codec pool avoids that scheduling collapse while leaving audio stream +Both the raw-BGR and timestamped-NUT stdin modes run the implicit pixel-format +filter graph on one thread and cap the video encoder at two threads. A Linux +full-clip trace showed ffmpeg creating an oversized execution pool and severely +delaying frame-pipe ingestion on a constrained hosted runner. The bounded +filter and codec pools avoid that scheduling collapse while leaving audio stream copy independent. Command regressions cover both supported video codecs; the real Linux full-clip CI job guards process completion. `probe_video_encode_profile` reads the first source video stream with ffprobe diff --git a/src/remove_ai_watermarks/video_encoding.py b/src/remove_ai_watermarks/video_encoding.py index 9f18278..76b19d2 100644 --- a/src/remove_ai_watermarks/video_encoding.py +++ b/src/remove_ai_watermarks/video_encoding.py @@ -21,6 +21,7 @@ if TYPE_CHECKING: log = logging.getLogger(__name__) _PIXEL_FORMATS = frozenset({"yuv420p", "yuv422p", "yuv444p"}) +_VIDEO_FILTER_THREADS = 1 _VIDEO_ENCODER_THREADS = 2 _PIXEL_FORMAT_ALIASES = { "yuvj420p": "yuv420p", @@ -305,6 +306,8 @@ def raw_video_command( ) command = [ ffmpeg, + "-filter_threads", + str(_VIDEO_FILTER_THREADS), "-y", "-loglevel", "error", diff --git a/tests/test_video.py b/tests/test_video.py index 3b3e674..07a1b7f 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -1971,6 +1971,7 @@ class TestVideoVisibleEncoding: profile=video_encoding.VideoEncodeProfile(), ) + assert command[1:3] == ["-filter_threads", "1"] assert command[command.index("-threads:v") + 1] == "2" @staticmethod