mirror of
https://github.com/hacksider/Deep-Live-Cam.git
synced 2026-06-11 14:57:46 +02:00
Speed optimization
This commit is contained in:
@@ -59,7 +59,7 @@ def camera_backends() -> List[Tuple[int, int]]:
|
||||
|
||||
|
||||
def accelerator_label() -> str:
|
||||
if HAS_TORCH_CUDA and HAS_CUDA_PROVIDER:
|
||||
if HAS_CUDA_PROVIDER:
|
||||
return "CUDA (NVIDIA)"
|
||||
if IS_APPLE_SILICON and HAS_COREML_PROVIDER:
|
||||
return "CoreML (Apple Neural Engine)"
|
||||
|
||||
+5
-1
@@ -1240,7 +1240,11 @@ def create_webcam_preview(camera_index: int):
|
||||
global preview_label, PREVIEW
|
||||
|
||||
cap = VideoCapturer(camera_index)
|
||||
if not cap.start(1920, 1080, 60):
|
||||
# Capture at preview window size — drops USB bandwidth and processing cost
|
||||
# vs. capturing at 1080p and downscaling. The camera negotiates the closest
|
||||
# mode it supports, which is usually a clean 16:9 resolution at least this
|
||||
# size; cv2 downscales the rest on the fly.
|
||||
if not cap.start(PREVIEW_DEFAULT_WIDTH, PREVIEW_DEFAULT_HEIGHT, 60):
|
||||
update_status("Failed to start camera")
|
||||
return
|
||||
|
||||
|
||||
+31
-15
@@ -38,19 +38,35 @@ class VideoCapturer:
|
||||
"""Initialize and start video capture"""
|
||||
try:
|
||||
if platform.system() == "Windows":
|
||||
# Windows-specific capture methods.
|
||||
# MSMF (Media Foundation) is preferred — DirectShow often
|
||||
# caps at 30fps even when the camera supports 60fps.
|
||||
# device_index comes from pygrabber.FilterGraph (DirectShow
|
||||
# enumeration), so open with DSHOW first to preserve mapping.
|
||||
# MSMF and DirectShow enumerate cameras in different orders, so
|
||||
# opening MSMF with a DSHOW index silently selects the wrong
|
||||
# camera. MSMF/ANY remain as fallbacks for cameras DSHOW can't
|
||||
# open.
|
||||
#
|
||||
# Pass codec + resolution + fps as construction params (OpenCV
|
||||
# 4.6+). DSHOW locks the pixel format at open time and ignores
|
||||
# later cap.set(CAP_PROP_FOURCC, ...) — without this, DSHOW
|
||||
# falls back to uncompressed YUYV at 1080p, which is USB-
|
||||
# bandwidth-limited to ~5 fps. Setting MJPG at construction
|
||||
# negotiates compressed frames from the first read.
|
||||
mjpg = cv2.VideoWriter_fourcc(*'MJPG')
|
||||
open_params = [
|
||||
cv2.CAP_PROP_FOURCC, mjpg,
|
||||
cv2.CAP_PROP_FRAME_WIDTH, width,
|
||||
cv2.CAP_PROP_FRAME_HEIGHT, height,
|
||||
cv2.CAP_PROP_FPS, fps,
|
||||
]
|
||||
capture_methods = [
|
||||
(self.device_index, cv2.CAP_MSMF), # Media Foundation first
|
||||
(self.device_index, cv2.CAP_DSHOW), # DirectShow fallback
|
||||
(self.device_index, cv2.CAP_DSHOW),
|
||||
(self.device_index, cv2.CAP_MSMF),
|
||||
(self.device_index, cv2.CAP_ANY),
|
||||
(0, cv2.CAP_ANY),
|
||||
]
|
||||
|
||||
for dev_id, backend in capture_methods:
|
||||
try:
|
||||
self.cap = cv2.VideoCapture(dev_id, backend)
|
||||
self.cap = cv2.VideoCapture(dev_id, backend, open_params)
|
||||
if self.cap.isOpened():
|
||||
break
|
||||
self.cap.release()
|
||||
@@ -63,14 +79,14 @@ class VideoCapturer:
|
||||
if not self.cap or not self.cap.isOpened():
|
||||
raise RuntimeError("Failed to open camera")
|
||||
|
||||
# Try MJPEG first — avoids USB bandwidth limits with
|
||||
# uncompressed YUV at high resolutions. Falls back silently
|
||||
# if the camera/backend doesn't support it.
|
||||
self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
|
||||
# Request desired resolution and frame rate
|
||||
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
|
||||
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
|
||||
self.cap.set(cv2.CAP_PROP_FPS, fps)
|
||||
# Belt-and-braces: also set via cap.set() for backends that honor
|
||||
# post-open changes (MSMF, V4L2). DSHOW ignores these, but the
|
||||
# construction params above already handled it.
|
||||
if platform.system() != "Windows":
|
||||
self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
|
||||
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
|
||||
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
|
||||
self.cap.set(cv2.CAP_PROP_FPS, fps)
|
||||
|
||||
# Read back resolution (usually reliable)
|
||||
self.actual_width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||
|
||||
Reference in New Issue
Block a user