mirror of
https://github.com/hacksider/Deep-Live-Cam.git
synced 2026-07-11 12:46:33 +02:00
Apple Silicon performance: 1.5 → 10+ FPS (zero quality loss)
Fix CoreML execution provider falling back to CPU silently, eliminate redundant per-frame face detection, and optimize the paste-back blend to operate on the face bounding box instead of the full frame. All changes are quality-neutral (pixel-identical output verified) and benefit non-Mac platforms via the shared detection and paste-back improvements. Changes: - Remove unsupported CoreML options (RequireStaticShapes, MaximumCacheSize) that caused ORT 1.24 to silently fall back to CPUExecutionProvider - Add _fast_paste_back(): bbox-restricted erode/blur/blend, skip dead fake_diff code in insightface's inswapper (computed but never used) - process_frame() accepts optional pre-detected target_face to avoid redundant get_one_face() call (~30-40ms saved per frame, all platforms) - In-memory pipeline detects face once and shares across processors - Fix get_face_swapper() to fall back to FP16 model when FP32 absent - Fix pre_start() to accept either model variant (was FP16-only check) - Make tensorflow import conditional (fixes crash on macOS) - Add missing tqdm dep, make tensorflow/pygrabber platform-conditional Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -321,6 +321,8 @@ def _run_pipe_pipeline(
|
||||
bar_fmt = ('{l_bar}{bar}| {n_fmt}/{total_fmt} '
|
||||
'[{elapsed}<{remaining}, {rate_fmt}{postfix}]')
|
||||
|
||||
from modules.face_analyser import get_one_face
|
||||
|
||||
try:
|
||||
with tqdm(total=total_frames, desc='Processing', unit='frame',
|
||||
dynamic_ncols=True, bar_format=bar_fmt) as progress:
|
||||
@@ -339,9 +341,21 @@ def _run_pipe_pipeline(
|
||||
(height, width, 3)
|
||||
).copy()
|
||||
|
||||
# Detect target face once and share across all processors.
|
||||
# This eliminates the redundant detection that each
|
||||
# processor would otherwise do internally.
|
||||
if not modules.globals.many_faces:
|
||||
target_face = get_one_face(frame)
|
||||
else:
|
||||
target_face = None # many_faces mode detects all internally
|
||||
|
||||
# Run frame through every active processor
|
||||
for fp in frame_processors:
|
||||
frame = fp.process_frame(source_face, frame)
|
||||
try:
|
||||
frame = fp.process_frame(source_face, frame, target_face=target_face)
|
||||
except TypeError:
|
||||
# Processor doesn't accept target_face kwarg
|
||||
frame = fp.process_frame(source_face, frame)
|
||||
|
||||
writer.stdin.write(frame.tobytes())
|
||||
processed_count += 1
|
||||
|
||||
Reference in New Issue
Block a user