Next (#318)
* renaming and restructuring (#282) * Renaming and restructuring * Renaming and restructuring * Renaming and restructuring * Fix gender detection * Implement distance to face debugger * Implement distance to face debugger part2 * Implement distance to face debugger part3 * Mark as next * Fix reference when face_debugger comes first * Use official onnxruntime nightly * CUDA on steroids * CUDA on steroids * Add some testing * Set inswapper_128_fp16 as default * Feat/block until post check (#292) * Block until download is done * Introduce post_check() * Fix webcam * Update dependencies * Add --force-reinstall to installer * Introduce config ini (#298) * Introduce config ini * Fix output video encoder * Revert help listings back to commas, Move SSL hack to download.py * Introduce output-video-preset which defaults to veryfast * Mapping for nvenc encoders * Rework on events and non-blocking UI * Add fast bmp to temp_frame_formats * Add fast bmp to temp_frame_formats * Show total processing time on success * Show total processing time on success * Show total processing time on success * Move are_images, is_image and is_video back to filesystem * Fix some spacings * Pissing everyone of by renaming stuff * Fix seconds output * feat/video output fps (#312) * added output fps slider, removed 'keep fps' option (#311) * added output fps slider, removed 'keep fps' option * now uses passed fps instead of global fps for ffmpeg * fps values are now floats instead of ints * fix previous commit * removed default value from fps slider this is so we can implement a dynamic default value later * Fix seconds output * Some cleanup --------- Co-authored-by: Ran Shaashua <47498956+ranshaa05@users.noreply.github.com> * Allow 0.01 steps for fps * Make fps unregulated * Make fps unregulated * Remove distance from face debugger again (does not work) * Fix gender age * Fix gender age * Hotfix benchmark suite * Warp face normalize (#313) * use normalized kp templates * Update face_helper.py * My 50 cents to warp_face() --------- Co-authored-by: Harisreedhar <46858047+harisreedhar@users.noreply.github.com> * face-swapper-weight (#315) * Move prepare_crop_frame and normalize_crop_frame out of apply_swap * Fix UI bug with different range * feat/output video resolution (#316) * Introduce detect_video_resolution, Rename detect_fps to detect_video_fps * Add calc_video_resolution_range * Make output resolution work, does not auto-select yet * Make output resolution work, does not auto-select yet * Try to keep the origin resolution * Split code into more fragments * Add pack/unpack resolution * Move video_template_sizes to choices * Improve create_video_resolutions * Reword benchmark suite * Optimal speed for benchmark * Introduce different video memory strategies, rename max_memory to max… (#317) * Introduce different video memory strategies, rename max_memory to max_system_memory * Update readme * Fix limit_system_memory call * Apply video_memory_strategy to face debugger * Limit face swapper weight to 3.0 * Remove face swapper weight due bad render outputs * Show/dide logic for output video preset * fix uint8 conversion * Fix whitespace * Finalize layout and update preview * Fix multi renders on face debugger * Restore less restrictive rendering of preview and stream * Fix block mode for model downloads * Add testing * Cosmetic changes * Enforce valid fps and resolution via CLI * Empty config * Cosmetics on args processing * Memory workover (#319) * Cosmetics on args processing * Fix for MacOS * Rename all max_ to _limit * More fixes * Update preview * Fix whitespace --------- Co-authored-by: Ran Shaashua <47498956+ranshaa05@users.noreply.github.com> Co-authored-by: Harisreedhar <46858047+harisreedhar@users.noreply.github.com>
This commit is contained in:
@@ -2,7 +2,6 @@ import subprocess
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
from facefusion import wording
|
||||
from facefusion.download import conditional_download
|
||||
|
||||
|
||||
@@ -21,7 +20,7 @@ def test_image_to_image() -> None:
|
||||
run = subprocess.run(commands, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
|
||||
|
||||
assert run.returncode == 0
|
||||
assert wording.get('processing_image_succeed') in run.stdout.decode()
|
||||
assert 'image succeed' in run.stdout.decode()
|
||||
|
||||
|
||||
def test_image_to_video() -> None:
|
||||
@@ -29,4 +28,4 @@ def test_image_to_video() -> None:
|
||||
run = subprocess.run(commands, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
|
||||
|
||||
assert run.returncode == 0
|
||||
assert wording.get('processing_video_succeed') in run.stdout.decode()
|
||||
assert 'video succeed' in run.stdout.decode()
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
from facefusion.common_helper import create_metavar, create_range
|
||||
from facefusion.common_helper import create_metavar, create_int_range, create_float_range
|
||||
|
||||
|
||||
def test_create_metavar() -> None:
|
||||
assert create_metavar([ 1, 2, 3, 4, 5 ]) == '[1-5]'
|
||||
|
||||
|
||||
def test_create_range() -> None:
|
||||
assert create_range(0.0, 1.0, 0.5) == [ 0.0, 0.5, 1.0 ]
|
||||
assert create_range(0.0, 0.2, 0.05) == [ 0.0, 0.05, 0.10, 0.15, 0.20 ]
|
||||
def test_create_int_range() -> None:
|
||||
assert create_int_range(0, 2, 1) == [ 0, 1, 2 ]
|
||||
assert create_float_range(0, 1, 1) == [ 0, 1 ]
|
||||
|
||||
|
||||
def test_create_float_range() -> None:
|
||||
assert create_float_range(0.0, 1.0, 0.5) == [ 0.0, 0.5, 1.0 ]
|
||||
assert create_float_range(0.0, 0.2, 0.05) == [ 0.0, 0.05, 0.10, 0.15, 0.20 ]
|
||||
|
||||
96
tests/test_config.py
Normal file
96
tests/test_config.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from configparser import ConfigParser
|
||||
import pytest
|
||||
|
||||
from facefusion import config
|
||||
|
||||
|
||||
@pytest.fixture(scope = 'module', autouse = True)
|
||||
def before_all() -> None:
|
||||
config.CONFIG = ConfigParser()
|
||||
config.CONFIG.read_dict(
|
||||
{
|
||||
'str':
|
||||
{
|
||||
'valid': 'a',
|
||||
'unset': ''
|
||||
},
|
||||
'int':
|
||||
{
|
||||
'valid': '1',
|
||||
'unset': ''
|
||||
},
|
||||
'float':
|
||||
{
|
||||
'valid': '1.0',
|
||||
'unset': ''
|
||||
},
|
||||
'bool':
|
||||
{
|
||||
'valid': 'True',
|
||||
'unset': ''
|
||||
},
|
||||
'str_list':
|
||||
{
|
||||
'valid': 'a b c',
|
||||
'unset': ''
|
||||
},
|
||||
'int_list':
|
||||
{
|
||||
'valid': '1 2 3',
|
||||
'unset': ''
|
||||
},
|
||||
'float_list':
|
||||
{
|
||||
'valid': '1.0 2.0 3.0',
|
||||
'unset': ''
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def test_get_str_value() -> None:
|
||||
assert config.get_str_value('str.valid') == 'a'
|
||||
assert config.get_str_value('str.unset', 'b') == 'b'
|
||||
assert config.get_str_value('str.unset') is None
|
||||
assert config.get_str_value('str.invalid') is None
|
||||
|
||||
|
||||
def test_get_int_value() -> None:
|
||||
assert config.get_int_value('int.valid') == 1
|
||||
assert config.get_int_value('int.unset', '1') == 1
|
||||
assert config.get_int_value('int.unset') is None
|
||||
assert config.get_int_value('int.invalid') is None
|
||||
|
||||
|
||||
def test_get_float_value() -> None:
|
||||
assert config.get_float_value('float.valid') == 1.0
|
||||
assert config.get_float_value('float.unset', '1.0') == 1.0
|
||||
assert config.get_float_value('float.unset') is None
|
||||
assert config.get_float_value('float.invalid') is None
|
||||
|
||||
|
||||
def test_get_bool_value() -> None:
|
||||
assert config.get_bool_value('bool.valid') is True
|
||||
assert config.get_bool_value('bool.unset', 'False') is False
|
||||
assert config.get_bool_value('bool.unset') is None
|
||||
assert config.get_bool_value('bool.invalid') is None
|
||||
|
||||
|
||||
def test_get_str_list() -> None:
|
||||
assert config.get_str_list('str_list.valid') == [ 'a', 'b', 'c' ]
|
||||
assert config.get_str_list('str_list.unset', 'c b a') == [ 'c', 'b', 'a' ]
|
||||
assert config.get_str_list('str_list.unset') is None
|
||||
assert config.get_str_list('str_list.invalid') is None
|
||||
|
||||
|
||||
def test_get_int_list() -> None:
|
||||
assert config.get_int_list('int_list.valid') == [ 1, 2, 3 ]
|
||||
assert config.get_int_list('int_list.unset', '3 2 1') == [ 3, 2, 1 ]
|
||||
assert config.get_int_list('int_list.unset') is None
|
||||
assert config.get_int_list('int_list.invalid') is None
|
||||
|
||||
|
||||
def test_get_float_list() -> None:
|
||||
assert config.get_float_list('float_list.valid') == [ 1.0, 2.0, 3.0 ]
|
||||
assert config.get_float_list('float_list.unset', '3.0 2.0 1.0') == [ 3.0, 2.0, 1.0 ]
|
||||
assert config.get_float_list('float_list.unset') is None
|
||||
assert config.get_float_list('float_list.invalid') is None
|
||||
@@ -1,4 +1,4 @@
|
||||
from facefusion.execution_helper import encode_execution_providers, decode_execution_providers
|
||||
from facefusion.execution_helper import encode_execution_providers, decode_execution_providers, apply_execution_provider_options, map_torch_backend
|
||||
|
||||
|
||||
def test_encode_execution_providers() -> None:
|
||||
@@ -7,3 +7,20 @@ def test_encode_execution_providers() -> None:
|
||||
|
||||
def test_decode_execution_providers() -> None:
|
||||
assert decode_execution_providers([ 'cpu' ]) == [ 'CPUExecutionProvider' ]
|
||||
|
||||
|
||||
def test_multiple_execution_providers() -> None:
|
||||
execution_provider_with_options =\
|
||||
[
|
||||
'CPUExecutionProvider',
|
||||
('CUDAExecutionProvider',
|
||||
{
|
||||
'cudnn_conv_algo_search': 'DEFAULT'
|
||||
})
|
||||
]
|
||||
assert apply_execution_provider_options([ 'CPUExecutionProvider', 'CUDAExecutionProvider' ]) == execution_provider_with_options
|
||||
|
||||
|
||||
def test_map_device() -> None:
|
||||
assert map_torch_backend([ 'CPUExecutionProvider' ]) == 'cpu'
|
||||
assert map_torch_backend([ 'CPUExecutionProvider', 'CUDAExecutionProvider' ]) == 'cuda'
|
||||
|
||||
@@ -39,7 +39,7 @@ def test_extract_frames() -> None:
|
||||
temp_directory_path = get_temp_directory_path(target_path)
|
||||
create_temp(target_path)
|
||||
|
||||
assert extract_frames(target_path, 30.0) is True
|
||||
assert extract_frames(target_path, '452x240', 30.0) is True
|
||||
assert len(glob.glob1(temp_directory_path, '*.jpg')) == 324
|
||||
|
||||
clear_temp(target_path)
|
||||
@@ -57,7 +57,7 @@ def test_extract_frames_with_trim_start() -> None:
|
||||
temp_directory_path = get_temp_directory_path(target_path)
|
||||
create_temp(target_path)
|
||||
|
||||
assert extract_frames(target_path, 30.0) is True
|
||||
assert extract_frames(target_path, '452x240', 30.0) is True
|
||||
assert len(glob.glob1(temp_directory_path, '*.jpg')) == frame_total
|
||||
|
||||
clear_temp(target_path)
|
||||
@@ -76,7 +76,7 @@ def test_extract_frames_with_trim_start_and_trim_end() -> None:
|
||||
temp_directory_path = get_temp_directory_path(target_path)
|
||||
create_temp(target_path)
|
||||
|
||||
assert extract_frames(target_path, 30.0) is True
|
||||
assert extract_frames(target_path, '452x240', 30.0) is True
|
||||
assert len(glob.glob1(temp_directory_path, '*.jpg')) == frame_total
|
||||
|
||||
clear_temp(target_path)
|
||||
@@ -94,7 +94,7 @@ def test_extract_frames_with_trim_end() -> None:
|
||||
temp_directory_path = get_temp_directory_path(target_path)
|
||||
create_temp(target_path)
|
||||
|
||||
assert extract_frames(target_path, 30.0) is True
|
||||
assert extract_frames(target_path, '426x240', 30.0) is True
|
||||
assert len(glob.glob1(temp_directory_path, '*.jpg')) == frame_total
|
||||
|
||||
clear_temp(target_path)
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
from facefusion.filesystem import is_file, is_directory, is_image, are_images, is_video
|
||||
import pytest
|
||||
|
||||
from facefusion.download import conditional_download
|
||||
from facefusion.filesystem import is_file, is_directory, is_image, are_images, is_video, list_directory
|
||||
|
||||
|
||||
@pytest.fixture(scope = 'module', autouse = True)
|
||||
def before_all() -> None:
|
||||
conditional_download('.assets/examples',
|
||||
[
|
||||
'https://github.com/facefusion/facefusion-assets/releases/download/examples/source.jpg'
|
||||
])
|
||||
|
||||
|
||||
def test_is_file() -> None:
|
||||
@@ -29,3 +40,9 @@ def test_is_video() -> None:
|
||||
assert is_video('.assets/examples/target-240p.mp4') is True
|
||||
assert is_video('.assets/examples/source.jpg') is False
|
||||
assert is_video('invalid') is False
|
||||
|
||||
|
||||
def test_list_directory() -> None:
|
||||
assert list_directory('.assets/examples')
|
||||
assert list_directory('.assets/examples/source.jpg') is None
|
||||
assert list_directory('invalid') is None
|
||||
|
||||
9
tests/test_memory.py
Normal file
9
tests/test_memory.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import platform
|
||||
|
||||
from facefusion.memory import limit_system_memory
|
||||
|
||||
|
||||
def test_limit_system_memory() -> None:
|
||||
assert limit_system_memory(4) is True
|
||||
if platform.system().lower() == 'darwin' or platform.system().lower() == 'linux':
|
||||
assert limit_system_memory(1024) is False
|
||||
@@ -1,6 +1,6 @@
|
||||
import platform
|
||||
|
||||
from facefusion.normalizer import normalize_output_path, normalize_padding
|
||||
from facefusion.normalizer import normalize_output_path, normalize_padding, normalize_fps
|
||||
|
||||
|
||||
def test_normalize_output_path() -> None:
|
||||
@@ -23,3 +23,10 @@ def test_normalize_padding() -> None:
|
||||
assert normalize_padding([ 1, 2 ]) == (1, 2, 1, 2)
|
||||
assert normalize_padding([ 1, 2, 3 ]) == (1, 2, 3, 2)
|
||||
assert normalize_padding(None) is None
|
||||
|
||||
|
||||
def test_normalize_fps() -> None:
|
||||
assert normalize_fps(0.0) == 1.0
|
||||
assert normalize_fps(25.0) == 25.0
|
||||
assert normalize_fps(61.0) == 60.0
|
||||
assert normalize_fps(None) is None
|
||||
|
||||
@@ -2,7 +2,7 @@ import subprocess
|
||||
import pytest
|
||||
|
||||
from facefusion.download import conditional_download
|
||||
from facefusion.vision import get_video_frame, detect_fps, count_video_frame_total
|
||||
from facefusion.vision import get_video_frame, count_video_frame_total, detect_video_fps, detect_video_resolution, pack_resolution, unpack_resolution, create_video_resolutions
|
||||
|
||||
|
||||
@pytest.fixture(scope = 'module', autouse = True)
|
||||
@@ -10,11 +10,14 @@ def before_all() -> None:
|
||||
conditional_download('.assets/examples',
|
||||
[
|
||||
'https://github.com/facefusion/facefusion-assets/releases/download/examples/source.jpg',
|
||||
'https://github.com/facefusion/facefusion-assets/releases/download/examples/target-240p.mp4'
|
||||
'https://github.com/facefusion/facefusion-assets/releases/download/examples/target-240p.mp4',
|
||||
'https://github.com/facefusion/facefusion-assets/releases/download/examples/target-1080p.mp4'
|
||||
])
|
||||
subprocess.run([ 'ffmpeg', '-i', '.assets/examples/target-240p.mp4', '-vf', 'fps=25', '.assets/examples/target-240p-25fps.mp4' ])
|
||||
subprocess.run([ 'ffmpeg', '-i', '.assets/examples/target-240p.mp4', '-vf', 'fps=30', '.assets/examples/target-240p-30fps.mp4' ])
|
||||
subprocess.run([ 'ffmpeg', '-i', '.assets/examples/target-240p.mp4', '-vf', 'fps=60', '.assets/examples/target-240p-60fps.mp4' ])
|
||||
subprocess.run([ 'ffmpeg', '-i', '.assets/examples/target-240p.mp4', '-vf', 'transpose=0', '.assets/examples/target-240p-90deg.mp4' ])
|
||||
subprocess.run([ 'ffmpeg', '-i', '.assets/examples/target-1080p.mp4', '-vf', 'transpose=0', '.assets/examples/target-1080p-90deg.mp4' ])
|
||||
|
||||
|
||||
def test_get_video_frame() -> None:
|
||||
@@ -22,15 +25,39 @@ def test_get_video_frame() -> None:
|
||||
assert get_video_frame('invalid') is None
|
||||
|
||||
|
||||
def test_detect_fps() -> None:
|
||||
assert detect_fps('.assets/examples/target-240p-25fps.mp4') == 25.0
|
||||
assert detect_fps('.assets/examples/target-240p-30fps.mp4') == 30.0
|
||||
assert detect_fps('.assets/examples/target-240p-60fps.mp4') == 60.0
|
||||
assert detect_fps('invalid') is None
|
||||
|
||||
|
||||
def test_count_video_frame_total() -> None:
|
||||
assert count_video_frame_total('.assets/examples/target-240p-25fps.mp4') == 270
|
||||
assert count_video_frame_total('.assets/examples/target-240p-30fps.mp4') == 324
|
||||
assert count_video_frame_total('.assets/examples/target-240p-60fps.mp4') == 648
|
||||
assert count_video_frame_total('invalid') == 0
|
||||
|
||||
|
||||
def test_detect_video_fps() -> None:
|
||||
assert detect_video_fps('.assets/examples/target-240p-25fps.mp4') == 25.0
|
||||
assert detect_video_fps('.assets/examples/target-240p-30fps.mp4') == 30.0
|
||||
assert detect_video_fps('.assets/examples/target-240p-60fps.mp4') == 60.0
|
||||
assert detect_video_fps('invalid') is None
|
||||
|
||||
|
||||
def test_detect_video_resolution() -> None:
|
||||
assert detect_video_resolution('.assets/examples/target-240p.mp4') == (426.0, 226.0)
|
||||
assert detect_video_resolution('.assets/examples/target-1080p.mp4') == (2048.0, 1080.0)
|
||||
assert detect_video_resolution('invalid') is None
|
||||
|
||||
|
||||
def test_pack_resolution() -> None:
|
||||
assert pack_resolution((1.0, 1.0)) == '0x0'
|
||||
assert pack_resolution((2.0, 2.0)) == '2x2'
|
||||
|
||||
|
||||
def test_unpack_resolution() -> None:
|
||||
assert unpack_resolution('0x0') == (0, 0)
|
||||
assert unpack_resolution('2x2') == (2, 2)
|
||||
|
||||
|
||||
def test_create_video_resolutions() -> None:
|
||||
assert create_video_resolutions('.assets/examples/target-240p.mp4') == [ '426x226', '452x240', '678x360', '904x480', '1018x540', '1358x720', '2036x1080', '2714x1440', '4072x2160' ]
|
||||
assert create_video_resolutions('.assets/examples/target-240p-90deg.mp4') == [ '226x426', '240x452', '360x678', '480x904', '540x1018', '720x1358', '1080x2036', '1440x2714', '2160x4072' ]
|
||||
assert create_video_resolutions('.assets/examples/target-1080p.mp4') == [ '456x240', '682x360', '910x480', '1024x540', '1366x720', '2048x1080', '2730x1440', '4096x2160' ]
|
||||
assert create_video_resolutions('.assets/examples/target-1080p-90deg.mp4') == [ '240x456', '360x682', '480x910', '540x1024', '720x1366', '1080x2048', '1440x2730', '2160x4096' ]
|
||||
assert create_video_resolutions('invalid') is None
|
||||
|
||||
Reference in New Issue
Block a user