From c5f892e76c3e83bdf753f8f0124acedd314af9b1 Mon Sep 17 00:00:00 2001 From: Harisreedhar <46858047+harisreedhar@users.noreply.github.com> Date: Fri, 24 Jul 2026 20:06:48 +0530 Subject: [PATCH] route chunk read through frame_store (#1198) * vision integration * Deleted read_video_chunk + read_static_video_chunk --- .../processors/modules/age_modifier/core.py | 3 +- .../modules/background_remover/core.py | 3 +- .../processors/modules/deep_swapper/core.py | 3 +- .../modules/expression_restorer/core.py | 3 +- .../processors/modules/face_debugger/core.py | 3 +- .../processors/modules/face_editor/core.py | 3 +- .../processors/modules/face_enhancer/core.py | 3 +- .../processors/modules/face_swapper/core.py | 3 +- .../modules/frame_colorizer/core.py | 3 +- .../processors/modules/frame_enhancer/core.py | 3 +- .../processors/modules/lip_syncer/core.py | 3 +- facefusion/vision.py | 33 +------------------ tests/test_face_tracker.py | 7 ++-- tests/test_vision.py | 7 +--- 14 files changed, 16 insertions(+), 64 deletions(-) diff --git a/facefusion/processors/modules/age_modifier/core.py b/facefusion/processors/modules/age_modifier/core.py index ceb6832d..daffa284 100755 --- a/facefusion/processors/modules/age_modifier/core.py +++ b/facefusion/processors/modules/age_modifier/core.py @@ -23,7 +23,7 @@ from facefusion.processors.types import ProcessorOutputs from facefusion.program_helper import find_argument_group from facefusion.thread_helper import thread_semaphore from facefusion.types import ApplyStateItem, Args, DownloadScope, Face, InferencePool, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import match_frame_color, read_static_image, read_static_video_chunk, read_static_video_frame +from facefusion.vision import match_frame_color, read_static_image, read_static_video_frame @lru_cache() @@ -166,7 +166,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]: diff --git a/facefusion/processors/modules/background_remover/core.py b/facefusion/processors/modules/background_remover/core.py index 11f3ca26..2ff10aa9 100644 --- a/facefusion/processors/modules/background_remover/core.py +++ b/facefusion/processors/modules/background_remover/core.py @@ -22,7 +22,7 @@ from facefusion.program_helper import find_argument_group from facefusion.sanitizer import sanitize_int_range from facefusion.thread_helper import thread_semaphore from facefusion.types import ApplyStateItem, Args, DownloadScope, InferencePool, InferenceProvider, Mask, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import read_static_image, read_static_video_chunk, read_static_video_frame +from facefusion.vision import read_static_image, read_static_video_frame @lru_cache() @@ -539,7 +539,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]: diff --git a/facefusion/processors/modules/deep_swapper/core.py b/facefusion/processors/modules/deep_swapper/core.py index 8c3661dc..5164ad16 100755 --- a/facefusion/processors/modules/deep_swapper/core.py +++ b/facefusion/processors/modules/deep_swapper/core.py @@ -23,7 +23,7 @@ from facefusion.processors.types import ProcessorOutputs from facefusion.program_helper import find_argument_group from facefusion.thread_helper import thread_semaphore from facefusion.types import ApplyStateItem, Args, DownloadScope, Face, InferencePool, Mask, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import conditional_match_frame_color, read_static_image, read_static_video_chunk, read_static_video_frame +from facefusion.vision import conditional_match_frame_color, read_static_image, read_static_video_frame @lru_cache() @@ -320,7 +320,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]: diff --git a/facefusion/processors/modules/expression_restorer/core.py b/facefusion/processors/modules/expression_restorer/core.py index ed94fd91..320f6224 100755 --- a/facefusion/processors/modules/expression_restorer/core.py +++ b/facefusion/processors/modules/expression_restorer/core.py @@ -23,7 +23,7 @@ from facefusion.processors.types import LivePortraitExpression, LivePortraitFeat from facefusion.program_helper import find_argument_group from facefusion.thread_helper import conditional_thread_semaphore, thread_semaphore from facefusion.types import ApplyStateItem, Args, DownloadScope, Face, InferencePool, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import read_static_image, read_static_video_chunk, read_static_video_frame +from facefusion.vision import read_static_image, read_static_video_frame @lru_cache() @@ -146,7 +146,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]: diff --git a/facefusion/processors/modules/face_debugger/core.py b/facefusion/processors/modules/face_debugger/core.py index 6ff15310..be6138ab 100755 --- a/facefusion/processors/modules/face_debugger/core.py +++ b/facefusion/processors/modules/face_debugger/core.py @@ -19,7 +19,7 @@ from facefusion.processors.modules.face_debugger.types import FaceDebuggerInputs from facefusion.processors.types import ProcessorOutputs from facefusion.program_helper import find_argument_group from facefusion.types import ApplyStateItem, Args, Face, InferencePool, ProcessMode, VisionFrame -from facefusion.vision import read_static_image, read_static_video_chunk, read_static_video_frame +from facefusion.vision import read_static_image, read_static_video_frame def get_inference_pool() -> InferencePool: @@ -68,7 +68,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') == 'strict': diff --git a/facefusion/processors/modules/face_editor/core.py b/facefusion/processors/modules/face_editor/core.py index 78e1e303..835f562f 100755 --- a/facefusion/processors/modules/face_editor/core.py +++ b/facefusion/processors/modules/face_editor/core.py @@ -23,7 +23,7 @@ from facefusion.processors.types import LivePortraitExpression, LivePortraitFeat from facefusion.program_helper import find_argument_group from facefusion.thread_helper import conditional_thread_semaphore, thread_semaphore from facefusion.types import ApplyStateItem, Args, DownloadScope, Face, FaceLandmark68, InferencePool, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import read_static_image, read_static_video_chunk, read_static_video_frame +from facefusion.vision import read_static_image, read_static_video_frame @lru_cache() @@ -197,7 +197,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]: diff --git a/facefusion/processors/modules/face_enhancer/core.py b/facefusion/processors/modules/face_enhancer/core.py index b81cfe67..04af4cf8 100755 --- a/facefusion/processors/modules/face_enhancer/core.py +++ b/facefusion/processors/modules/face_enhancer/core.py @@ -21,7 +21,7 @@ from facefusion.processors.types import ProcessorOutputs from facefusion.program_helper import find_argument_group from facefusion.thread_helper import thread_semaphore from facefusion.types import ApplyStateItem, Args, DownloadScope, Face, InferencePool, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import blend_frame, read_static_image, read_static_video_chunk, read_static_video_frame +from facefusion.vision import blend_frame, read_static_image, read_static_video_frame @lru_cache() @@ -337,7 +337,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]: diff --git a/facefusion/processors/modules/face_swapper/core.py b/facefusion/processors/modules/face_swapper/core.py index 058c12aa..31dec34f 100755 --- a/facefusion/processors/modules/face_swapper/core.py +++ b/facefusion/processors/modules/face_swapper/core.py @@ -26,7 +26,7 @@ from facefusion.processors.types import ProcessorOutputs from facefusion.program_helper import find_argument_group from facefusion.thread_helper import conditional_thread_semaphore from facefusion.types import ApplyStateItem, Args, DownloadScope, Embedding, Face, InferencePool, InferenceProvider, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import read_static_image, read_static_images, read_static_video_chunk, read_static_video_frame, unpack_resolution +from facefusion.vision import read_static_image, read_static_images, read_static_video_frame, unpack_resolution @lru_cache() @@ -588,7 +588,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]: diff --git a/facefusion/processors/modules/frame_colorizer/core.py b/facefusion/processors/modules/frame_colorizer/core.py index f5bcc623..87a9a357 100644 --- a/facefusion/processors/modules/frame_colorizer/core.py +++ b/facefusion/processors/modules/frame_colorizer/core.py @@ -20,7 +20,7 @@ from facefusion.processors.types import ProcessorOutputs from facefusion.program_helper import find_argument_group from facefusion.thread_helper import thread_semaphore from facefusion.types import ApplyStateItem, Args, DownloadScope, InferencePool, InferenceProvider, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import blend_frame, read_static_image, read_static_video_chunk, read_static_video_frame, unpack_resolution +from facefusion.vision import blend_frame, read_static_image, read_static_video_frame, unpack_resolution @lru_cache() @@ -230,7 +230,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]: diff --git a/facefusion/processors/modules/frame_enhancer/core.py b/facefusion/processors/modules/frame_enhancer/core.py index 36461e63..8b1506a5 100644 --- a/facefusion/processors/modules/frame_enhancer/core.py +++ b/facefusion/processors/modules/frame_enhancer/core.py @@ -20,7 +20,7 @@ from facefusion.processors.types import ProcessorOutputs from facefusion.program_helper import find_argument_group from facefusion.thread_helper import conditional_thread_semaphore from facefusion.types import ApplyStateItem, Args, DownloadScope, InferencePool, InferenceProvider, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import blend_frame, create_tile_frames, merge_tile_frames, read_static_image, read_static_video_chunk, read_static_video_frame +from facefusion.vision import blend_frame, create_tile_frames, merge_tile_frames, read_static_image, read_static_video_frame @lru_cache() @@ -623,7 +623,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() video_manager.clear_video_pool() if state_manager.get_item('video_memory_strategy') in [ 'strict', 'moderate' ]: diff --git a/facefusion/processors/modules/lip_syncer/core.py b/facefusion/processors/modules/lip_syncer/core.py index 914288a8..af4f4606 100755 --- a/facefusion/processors/modules/lip_syncer/core.py +++ b/facefusion/processors/modules/lip_syncer/core.py @@ -23,7 +23,7 @@ from facefusion.processors.types import ProcessorOutputs from facefusion.program_helper import find_argument_group from facefusion.thread_helper import conditional_thread_semaphore from facefusion.types import ApplyStateItem, Args, AudioFrame, DownloadScope, Face, InferencePool, ModelOptions, ModelSet, ProcessMode, VisionFrame -from facefusion.vision import read_static_image, read_static_video_chunk, read_static_video_frame +from facefusion.vision import read_static_image, read_static_video_frame @lru_cache() @@ -169,7 +169,6 @@ def pre_process(mode : ProcessMode) -> bool: def post_process() -> None: read_static_image.cache_clear() read_static_video_frame.cache_clear() - read_static_video_chunk.cache_clear() read_static_voice.cache_clear() video_manager.clear_video_pool() diff --git a/facefusion/vision.py b/facefusion/vision.py index 3d61c41f..7b01ccd8 100644 --- a/facefusion/vision.py +++ b/facefusion/vision.py @@ -10,7 +10,7 @@ from facefusion import ffprobe, video_manager from facefusion.common_helper import is_windows from facefusion.filesystem import get_file_extension, is_image, is_video from facefusion.thread_helper import thread_lock, thread_semaphore -from facefusion.types import ColorMode, Duration, Fps, Mask, Orientation, Resolution, Scale, VisionFrame, VisionFrameSet +from facefusion.types import ColorMode, Duration, Fps, Mask, Orientation, Resolution, Scale, VisionFrame def read_static_images(image_paths : List[str], color_mode : ColorMode = 'rgb') -> List[VisionFrame]: @@ -90,37 +90,6 @@ def read_video_frame(video_path : str, frame_number : int = 0) -> Optional[Visio return None -@lru_cache(maxsize = 2) -def read_static_video_chunk(video_path : str, chunk_number : int, chunk_size : int) -> VisionFrameSet: - return read_video_chunk(video_path, chunk_number, chunk_size) - - -#todo: needs review - [decoding] [critical: medium] chunk end clamped by the ffprobe frame_total estimate -def read_video_chunk(video_path : str, chunk_number : int, chunk_size : int) -> VisionFrameSet: - video_frame_chunk = {} - - if is_video(video_path) and chunk_number > -1: - video_reader = video_manager.get_reader(video_path) - - if video_reader: - video_frame_position = chunk_number * chunk_size - video_frame_end = video_frame_position + chunk_size - - if video_reader.get('metadata').get('frame_total') > 0: - video_frame_end = min(video_frame_end, video_reader.get('metadata').get('frame_total')) - - with thread_semaphore(): - video_manager.conditional_set_video_reader_position(video_reader, video_frame_position) - - for frame_number in range(video_frame_position, video_frame_end): - vision_frame = video_manager.read_video_reader_frame(video_reader) - - if numpy.any(vision_frame): - video_frame_chunk[frame_number] = vision_frame - - return video_frame_chunk - - #todo: needs review - [decoding] [critical: high] window read replaces the chunk cache, out of range frames fall back to empty vision frames #todo: question to restore the chunk_size approach over the window read def select_video_frames(video_path : str, frame_number : int = 0, frame_offset : int = 2) -> List[VisionFrame]: diff --git a/tests/test_face_tracker.py b/tests/test_face_tracker.py index 66991a5b..ade6e2f7 100644 --- a/tests/test_face_tracker.py +++ b/tests/test_face_tracker.py @@ -7,7 +7,7 @@ from facefusion.download import conditional_download from facefusion.face_creator import get_many_faces, get_one_face from facefusion.face_store import clear_faces from facefusion.face_tracker import create_face_tracks, select_face_track, track_faces -from facefusion.vision import read_static_video_chunk, read_static_video_frame +from facefusion.vision import read_static_video_frame, select_video_frames from .helper import get_test_example_file, get_test_examples_directory @@ -47,8 +47,7 @@ def before_each() -> None: def test_track_faces() -> None: target_path = get_test_example_file('target-240p.mp4') - video_frame_chunk = read_static_video_chunk(target_path, 0, 7) - target_vision_frames = [ video_frame_chunk.get(frame_number) for frame_number in sorted(video_frame_chunk) ] + target_vision_frames = select_video_frames(target_path, 3, 3) empty_vision_frame = numpy.zeros_like(get_first(target_vision_frames)) target_vision_frames[2] = empty_vision_frame @@ -58,7 +57,7 @@ def test_track_faces() -> None: assert len(track_faces(target_vision_frames, 0.3)) == 1 - target_vision_frames = [ video_frame_chunk.get(frame_number) for frame_number in sorted(video_frame_chunk)[:5] ] + target_vision_frames = select_video_frames(target_path, 3, 3)[:5] target_vision_frames[0] = empty_vision_frame target_vision_frames[1] = empty_vision_frame target_vision_frames[2] = empty_vision_frame diff --git a/tests/test_vision.py b/tests/test_vision.py index 7c6006fc..9a4c3b1a 100644 --- a/tests/test_vision.py +++ b/tests/test_vision.py @@ -6,7 +6,7 @@ import pytest from facefusion import ffmpeg, ffmpeg_builder, process_manager from facefusion.common_helper import is_linux from facefusion.download import conditional_download -from facefusion.vision import calculate_histogram_difference, count_trim_frame_total, count_video_frame_total, detect_image_resolution, detect_video_duration, detect_video_fps, detect_video_resolution, match_frame_color, normalize_resolution, pack_resolution, predict_video_frame_total, read_image, read_video_chunk, read_video_frame, restrict_image_resolution, restrict_trim_frame, restrict_video_fps, restrict_video_resolution, scale_resolution, select_video_frames, unpack_resolution, write_image +from facefusion.vision import calculate_histogram_difference, count_trim_frame_total, count_video_frame_total, detect_image_resolution, detect_video_duration, detect_video_fps, detect_video_resolution, match_frame_color, normalize_resolution, pack_resolution, predict_video_frame_total, read_image, read_video_frame, restrict_image_resolution, restrict_trim_frame, restrict_video_fps, restrict_video_resolution, scale_resolution, select_video_frames, unpack_resolution, write_image from .helper import get_test_example_file, get_test_examples_directory, get_test_output_file, prepare_test_output_directory @@ -138,11 +138,6 @@ def test_read_video_frame() -> None: assert read_video_frame('invalid') is None -def test_read_video_chunk() -> None: - assert len(read_video_chunk(get_test_example_file('target-240p-25fps.mp4'), 1, 40)) == 40 - assert read_video_chunk('invalid', 1, 40) == {} - - def test_select_video_frames() -> None: assert len(select_video_frames(get_test_example_file('target-240p-25fps.mp4'), 50, 5)) == 11 assert len(select_video_frames(get_test_example_file('target-240p-25fps.mp4'), 1, 5)) == 11