mirror of
https://github.com/facefusion/facefusion.git
synced 2026-07-27 12:30:55 +02:00
multi reader approach
This commit is contained in:
@@ -4,12 +4,12 @@ from typing import Tuple
|
||||
import numpy
|
||||
from tqdm import tqdm
|
||||
|
||||
from facefusion import inference_manager, state_manager, translator
|
||||
from facefusion import inference_manager, state_manager, translator, video_manager
|
||||
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
|
||||
from facefusion.filesystem import resolve_relative_path
|
||||
from facefusion.thread_helper import conditional_thread_semaphore
|
||||
from facefusion.types import Detection, DownloadScope, DownloadSet, Fps, InferencePool, ModelSet, VisionFrame
|
||||
from facefusion.vision import detect_video_fps, fit_contain_frame, read_image, read_video_frame
|
||||
from facefusion.vision import detect_video_fps, fit_contain_frame, read_image
|
||||
|
||||
STREAM_COUNTER = 0
|
||||
|
||||
@@ -161,13 +161,15 @@ def analyse_video(video_path : str, trim_frame_start : int, trim_frame_end : int
|
||||
rate = 0.0
|
||||
total = 0
|
||||
counter = 0
|
||||
video_reader = video_manager.get_reader(video_path, 'analyse_video')
|
||||
video_manager.seek_video_reader(video_reader, trim_frame_start)
|
||||
|
||||
with tqdm(total = len(frame_range), desc = translator.get('analysing'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||
|
||||
for frame_number in frame_range:
|
||||
if frame_number % int(video_fps) == 0:
|
||||
vision_frame = read_video_frame(video_path, frame_number)
|
||||
vision_frame = video_manager.read_video_frame(video_reader)
|
||||
|
||||
if frame_number % int(video_fps) == 0:
|
||||
if numpy.any(vision_frame):
|
||||
total += 1
|
||||
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ def pre_check() -> bool:
|
||||
def common_pre_check() -> bool:
|
||||
content_analyser_content = inspect.getsource(content_analyser).encode()
|
||||
|
||||
return hash_helper.create_hash(content_analyser_content) == '975d67d6'
|
||||
return hash_helper.create_hash(content_analyser_content) == '5f04e67c'
|
||||
|
||||
|
||||
def processors_pre_check() -> bool:
|
||||
|
||||
+13
-21
@@ -1,3 +1,4 @@
|
||||
import hashlib
|
||||
import uuid
|
||||
from typing import Optional
|
||||
|
||||
@@ -14,40 +15,31 @@ VIDEO_POOL_SET : VideoPoolSet =\
|
||||
}
|
||||
|
||||
|
||||
def get_reader(video_path : str) -> VideoReader:
|
||||
if video_path not in VIDEO_POOL_SET.get('reader'):
|
||||
def get_reader(video_path : str, context : str) -> VideoReader:
|
||||
reader_id = hashlib.sha1((video_path + '_' + context).encode()).hexdigest()
|
||||
|
||||
if reader_id not in VIDEO_POOL_SET.get('reader'):
|
||||
video_metadata = ffprobe.extract_static_video_metadata(video_path)
|
||||
|
||||
VIDEO_POOL_SET['reader'][video_path] =\
|
||||
VIDEO_POOL_SET['reader'][reader_id] =\
|
||||
{
|
||||
'id': uuid.uuid4().hex,
|
||||
'id': reader_id,
|
||||
'file_path': video_path,
|
||||
'process': ffmpeg.create_video_reader(video_path, 0, video_metadata),
|
||||
'metadata': video_metadata,
|
||||
'frame_number': 0
|
||||
}
|
||||
|
||||
return VIDEO_POOL_SET.get('reader').get(video_path)
|
||||
|
||||
|
||||
def conditional_seek_video_reader(video_reader : VideoReader, frame_number : int = 0) -> None:
|
||||
frame_number = min(video_reader.get('metadata').get('frame_total'), frame_number)
|
||||
skip_total = frame_number - video_reader.get('frame_number')
|
||||
skip_margin = 128
|
||||
|
||||
if 0 < skip_total <= skip_margin:
|
||||
for _ in range(skip_total):
|
||||
read_video_frame(video_reader)
|
||||
|
||||
if not video_reader.get('frame_number') == frame_number:
|
||||
seek_video_reader(video_reader, frame_number)
|
||||
return VIDEO_POOL_SET.get('reader').get(reader_id)
|
||||
|
||||
|
||||
def seek_video_reader(video_reader : VideoReader, frame_number : int = 0) -> None:
|
||||
close_video_reader(video_reader)
|
||||
frame_number = min(video_reader.get('metadata').get('frame_total'), frame_number)
|
||||
|
||||
video_reader['process'] = ffmpeg.create_video_reader(video_reader.get('file_path'), frame_number, video_reader.get('metadata'))
|
||||
video_reader['frame_number'] = frame_number
|
||||
if not video_reader.get('frame_number') == frame_number:
|
||||
close_video_reader(video_reader)
|
||||
video_reader['process'] = ffmpeg.create_video_reader(video_reader.get('file_path'), frame_number, video_reader.get('metadata'))
|
||||
video_reader['frame_number'] = frame_number
|
||||
|
||||
|
||||
#todo: needs review - [decoding] [critical: high] partial pipe read returns none and desyncs position from the actual stream
|
||||
|
||||
@@ -77,10 +77,10 @@ def read_static_video_frame(video_path : str, frame_number : int = 0) -> Optiona
|
||||
|
||||
def read_video_frame(video_path : str, frame_number : int = 0) -> Optional[VisionFrame]:
|
||||
if is_video(video_path):
|
||||
video_reader = video_manager.get_reader(video_path)
|
||||
video_reader = video_manager.get_reader(video_path, 'read_video_frame')
|
||||
|
||||
with thread_semaphore():
|
||||
video_manager.conditional_seek_video_reader(video_reader, frame_number)
|
||||
video_manager.seek_video_reader(video_reader, frame_number)
|
||||
return video_manager.read_video_frame(video_reader)
|
||||
|
||||
return None
|
||||
@@ -93,7 +93,7 @@ def select_video_frames(video_path : str, frame_number : int = 0, frame_offset :
|
||||
|
||||
if is_video(video_path):
|
||||
with thread_lock():
|
||||
video_reader = video_manager.get_reader(video_path)
|
||||
video_reader = video_manager.get_reader(video_path, 'select_video_frames')
|
||||
frame_set = video_manager.read_video_frames(video_reader, max(frame_start, 0), frame_end)
|
||||
|
||||
for frame_number in range(frame_start, frame_end + 1):
|
||||
|
||||
+11
-28
@@ -9,7 +9,7 @@ from facefusion.download import conditional_download
|
||||
from facefusion.ffprobe import extract_video_metadata
|
||||
from facefusion.frame_store import get_frame_store
|
||||
from facefusion.temp_helper import create_temp_directory, get_temp_file_path
|
||||
from facefusion.video_manager import clear_video_pool, close_video_writer, conditional_seek_video_reader, get_reader, get_writer, read_video_frame, read_video_frames, seek_video_reader, write_video_frame
|
||||
from facefusion.video_manager import clear_video_pool, close_video_writer, get_reader, get_writer, read_video_frame, read_video_frames, seek_video_reader, write_video_frame
|
||||
from .helper import get_test_example_file, get_test_examples_directory
|
||||
|
||||
|
||||
@@ -46,38 +46,21 @@ def before_each() -> None:
|
||||
#todo: needs review - [testing] question if the assertions are good
|
||||
#todo: run mutation testing, strip down to the minimum, test with real data
|
||||
def test_get_reader() -> None:
|
||||
video_reader = get_reader(get_test_example_file('target-240p-25fps.mp4'))
|
||||
video_reader = get_reader(get_test_example_file('target-240p-25fps.mp4'), 'read_video_frame')
|
||||
video_metadata = video_reader.get('metadata')
|
||||
|
||||
assert video_metadata.get('resolution') == (426, 226)
|
||||
assert video_metadata.get('fps') == 25.0
|
||||
assert video_metadata.get('frame_total') == 270
|
||||
assert video_reader.get('frame_number') == 0
|
||||
assert get_reader(get_test_example_file('target-240p-25fps.mp4')) is video_reader
|
||||
|
||||
|
||||
#todo: needs review - [testing] question if the assertions are good
|
||||
#todo: run mutation testing, strip down to the minimum, test with real data
|
||||
def test_conditional_seek_video_reader() -> None:
|
||||
video_reader = get_reader(get_test_example_file('target-240p-25fps.mp4'))
|
||||
|
||||
conditional_seek_video_reader(video_reader, 50)
|
||||
|
||||
assert video_reader.get('frame_number') == 50
|
||||
|
||||
conditional_seek_video_reader(video_reader, 10)
|
||||
|
||||
assert video_reader.get('frame_number') == 10
|
||||
|
||||
conditional_seek_video_reader(video_reader, 200)
|
||||
|
||||
assert video_reader.get('frame_number') == 200
|
||||
assert get_reader(get_test_example_file('target-240p-25fps.mp4'), 'read_video_frame') is video_reader
|
||||
assert not get_reader(get_test_example_file('target-240p-25fps.mp4'), 'select_video_frames').get('id') == video_reader.get('id')
|
||||
|
||||
|
||||
#todo: needs review - [testing] question if the assertions are good
|
||||
#todo: run mutation testing, strip down to the minimum, test with real data
|
||||
def test_seek_video_reader() -> None:
|
||||
video_reader = get_reader(get_test_example_file('target-240p-25fps.mp4'))
|
||||
video_reader = get_reader(get_test_example_file('target-240p-25fps.mp4'), 'read_video_frame')
|
||||
sequential_frames = {}
|
||||
|
||||
for frame_number in range(30):
|
||||
@@ -93,13 +76,13 @@ def test_seek_video_reader() -> None:
|
||||
#todo: needs review - [testing] question if the assertions are good
|
||||
#todo: run mutation testing, strip down to the minimum, test with real data
|
||||
def test_read_video_frame() -> None:
|
||||
video_reader = get_reader(get_test_example_file('target-240p-25fps.mp4'))
|
||||
video_reader = get_reader(get_test_example_file('target-240p-25fps.mp4'), 'read_video_frame')
|
||||
vision_frame = read_video_frame(video_reader)
|
||||
|
||||
assert vision_frame.shape == (226, 426, 3)
|
||||
assert video_reader.get('frame_number') == 1
|
||||
|
||||
conditional_seek_video_reader(video_reader, 269)
|
||||
seek_video_reader(video_reader, 269)
|
||||
vision_frame = read_video_frame(video_reader)
|
||||
|
||||
assert vision_frame.shape == (226, 426, 3)
|
||||
@@ -109,7 +92,7 @@ def test_read_video_frame() -> None:
|
||||
#todo: needs review - [testing] question if the assertions are good
|
||||
#todo: run mutation testing, strip down to the minimum, test with real data
|
||||
def test_read_video_frames() -> None:
|
||||
video_reader = get_reader(get_test_example_file('target-240p-25fps.mp4'))
|
||||
video_reader = get_reader(get_test_example_file('target-240p-25fps.mp4'), 'read_video_frame')
|
||||
frame_set = read_video_frames(video_reader, 0, 4)
|
||||
|
||||
assert sorted(frame_set) == [ 0, 1, 2, 3, 4 ]
|
||||
@@ -145,7 +128,7 @@ def test_get_writer() -> None:
|
||||
def test_write_video_frame() -> None:
|
||||
target_path = get_test_example_file('target-240p-25fps.mp4')
|
||||
create_temp_directory(target_path)
|
||||
video_reader = get_reader(target_path)
|
||||
video_reader = get_reader(target_path, 'read_video_frame')
|
||||
video_writer = get_writer(target_path, 25.0, (426, 226), (426, 226), 25.0)
|
||||
|
||||
for frame_number in range(25):
|
||||
@@ -168,7 +151,7 @@ def test_write_video_frame() -> None:
|
||||
def test_close_video_writer() -> None:
|
||||
target_path = get_test_example_file('target-240p-30fps.mp4')
|
||||
create_temp_directory(target_path)
|
||||
video_reader = get_reader(target_path)
|
||||
video_reader = get_reader(target_path, 'read_video_frame')
|
||||
video_writer = get_writer(target_path, 30.0, (426, 226), (426, 226), 30.0)
|
||||
vision_frame = read_video_frame(video_reader)
|
||||
write_video_frame(video_writer, vision_frame)
|
||||
@@ -181,7 +164,7 @@ def test_close_video_writer() -> None:
|
||||
def test_clear_video_pool() -> None:
|
||||
target_path = get_test_example_file('target-240p-25fps.mp4')
|
||||
create_temp_directory(target_path)
|
||||
video_reader = get_reader(target_path)
|
||||
video_reader = get_reader(target_path, 'read_video_frame')
|
||||
video_writer = get_writer(target_path, 25.0, (426, 226), (426, 226), 25.0)
|
||||
vision_frame = read_video_frame(video_reader)
|
||||
write_video_frame(video_writer, vision_frame)
|
||||
|
||||
Reference in New Issue
Block a user