diff --git a/facefusion/ffmpeg_builder.py b/facefusion/ffmpeg_builder.py index f5fb817a..53b1bd40 100644 --- a/facefusion/ffmpeg_builder.py +++ b/facefusion/ffmpeg_builder.py @@ -191,6 +191,10 @@ def set_audio_volume(audio_volume : int) -> List[Command]: return [ '-filter:a', 'volume=' + str(audio_volume / 100) ] +def set_thread_count(thread_count : int) -> List[Command]: + return [ '-threads', str(thread_count) ] + + def set_video_encoder(video_encoder : str) -> List[Command]: return [ '-c:v', video_encoder ] diff --git a/facefusion/video_manager.py b/facefusion/video_manager.py index cc773049..fe1ad843 100644 --- a/facefusion/video_manager.py +++ b/facefusion/video_manager.py @@ -116,6 +116,7 @@ def create_video_writer_process(target_path : str, temp_video_fps : Fps, temp_vi temp_video_path = get_temp_file_path(target_path) temp_video_format = cast(VideoFormat, get_file_format(temp_video_path)) output_video_encoder = ffmpeg_builder.fix_video_encoder(temp_video_format, output_video_encoder) + encoder_thread_count = 16 commands = ffmpeg_builder.chain( ffmpeg_builder.set_output_format('rawvideo'), ffmpeg_builder.enforce_pixel_format('bgr24'), @@ -124,6 +125,7 @@ def create_video_writer_process(target_path : str, temp_video_fps : Fps, temp_vi ffmpeg_builder.set_input('pipe:0'), ffmpeg_builder.set_media_resolution(pack_video_resolution(output_video_resolution)), ffmpeg_builder.set_video_encoder(output_video_encoder), + ffmpeg_builder.set_thread_count(encoder_thread_count), ffmpeg_builder.set_video_tag(output_video_encoder, temp_video_format), ffmpeg_builder.set_video_quality(output_video_encoder, output_video_quality), ffmpeg_builder.set_video_preset(output_video_encoder, output_video_preset), diff --git a/facefusion/workflows/image_to_video.py b/facefusion/workflows/image_to_video.py index 2e957b18..1339592b 100644 --- a/facefusion/workflows/image_to_video.py +++ b/facefusion/workflows/image_to_video.py @@ -99,7 +99,11 @@ def process_stream_frames() -> ErrorCode: with ThreadPoolExecutor(max_workers = state_manager.get_item('execution_thread_count')) as executor: futures = [] - frame_look_ahead = state_manager.get_item('execution_thread_count') * 2 + # TODO: review - this has to be a dedicated method + width, height = temp_video_resolution + frame_memory_budget = 3 * 1024 ** 3 + frame_memory_usage = width * height * 3 * 6 + frame_look_ahead = min(state_manager.get_item('execution_thread_count') * 2, max(2, frame_memory_budget // frame_memory_usage)) for frame_number in frame_range: futures.append(executor.submit(process_stream_frame, frame_number, temp_video_resolution))