mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-01-31 00:18:55 +01:00
Auto select gpu for hwaccel presets (#5406)
* Add ability to GPU device to be automatically detected when multiple exist * Add logging info * Fix access * Fix * Formatting * Fix path of device * Use log error instead of raise * Remove log which could apply to other caess * Set default value * rework logic and support auto gpu selection for encoding gpu as well
This commit is contained in:
parent
babd976533
commit
562e2627c2
@ -1,14 +1,52 @@
|
|||||||
"""Handles inserting and maintaining ffmpeg presets."""
|
"""Handles inserting and maintaining ffmpeg presets."""
|
||||||
|
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from frigate.version import VERSION
|
from frigate.version import VERSION
|
||||||
from frigate.const import BTBN_PATH
|
from frigate.const import BTBN_PATH
|
||||||
|
from frigate.util import vainfo_hwaccel
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class LibvaGpuSelector:
|
||||||
|
"Automatically selects the correct libva GPU."
|
||||||
|
|
||||||
|
_selected_gpu = None
|
||||||
|
|
||||||
|
def get_selected_gpu(self) -> str:
|
||||||
|
"""Get selected libva GPU."""
|
||||||
|
if not os.path.exists("/dev/dri"):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
if self._selected_gpu:
|
||||||
|
return self._selected_gpu
|
||||||
|
|
||||||
|
devices = list(filter(lambda d: d.startswith("render"), os.listdir("/dev/dri")))
|
||||||
|
|
||||||
|
if len(devices) < 2:
|
||||||
|
self._selected_gpu = "/dev/dri/renderD128"
|
||||||
|
return self._selected_gpu
|
||||||
|
|
||||||
|
for device in devices:
|
||||||
|
check = vainfo_hwaccel(device_name=device)
|
||||||
|
|
||||||
|
logger.debug(f"{device} return vainfo status code: {check.returncode}")
|
||||||
|
|
||||||
|
if check.returncode == 0:
|
||||||
|
self._selected_gpu = f"/dev/dri/{device}"
|
||||||
|
return self._selected_gpu
|
||||||
|
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
TIMEOUT_PARAM = "-timeout" if os.path.exists(BTBN_PATH) else "-stimeout"
|
TIMEOUT_PARAM = "-timeout" if os.path.exists(BTBN_PATH) else "-stimeout"
|
||||||
|
|
||||||
|
_gpu_selector = LibvaGpuSelector()
|
||||||
_user_agent_args = [
|
_user_agent_args = [
|
||||||
"-user_agent",
|
"-user_agent",
|
||||||
f"FFmpeg Frigate/{VERSION}",
|
f"FFmpeg Frigate/{VERSION}",
|
||||||
@ -23,7 +61,7 @@ PRESETS_HW_ACCEL_DECODE = {
|
|||||||
"-hwaccel",
|
"-hwaccel",
|
||||||
"vaapi",
|
"vaapi",
|
||||||
"-hwaccel_device",
|
"-hwaccel_device",
|
||||||
"/dev/dri/renderD128",
|
_gpu_selector.get_selected_gpu(),
|
||||||
"-hwaccel_output_format",
|
"-hwaccel_output_format",
|
||||||
"vaapi",
|
"vaapi",
|
||||||
],
|
],
|
||||||
@ -31,7 +69,7 @@ PRESETS_HW_ACCEL_DECODE = {
|
|||||||
"-hwaccel",
|
"-hwaccel",
|
||||||
"qsv",
|
"qsv",
|
||||||
"-qsv_device",
|
"-qsv_device",
|
||||||
"/dev/dri/renderD128",
|
_gpu_selector.get_selected_gpu(),
|
||||||
"-hwaccel_output_format",
|
"-hwaccel_output_format",
|
||||||
"qsv",
|
"qsv",
|
||||||
"-c:v",
|
"-c:v",
|
||||||
@ -43,7 +81,7 @@ PRESETS_HW_ACCEL_DECODE = {
|
|||||||
"-hwaccel",
|
"-hwaccel",
|
||||||
"qsv",
|
"qsv",
|
||||||
"-qsv_device",
|
"-qsv_device",
|
||||||
"/dev/dri/renderD128",
|
_gpu_selector.get_selected_gpu(),
|
||||||
"-hwaccel_output_format",
|
"-hwaccel_output_format",
|
||||||
"qsv",
|
"qsv",
|
||||||
"-c:v",
|
"-c:v",
|
||||||
@ -95,7 +133,7 @@ PRESETS_HW_ACCEL_SCALE = {
|
|||||||
PRESETS_HW_ACCEL_ENCODE = {
|
PRESETS_HW_ACCEL_ENCODE = {
|
||||||
"preset-rpi-32-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m -g 50 -bf 0 {1}",
|
"preset-rpi-32-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m -g 50 -bf 0 {1}",
|
||||||
"preset-rpi-64-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m -g 50 -bf 0 {1}",
|
"preset-rpi-64-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m -g 50 -bf 0 {1}",
|
||||||
"preset-vaapi": "ffmpeg -hide_banner -hwaccel vaapi -hwaccel_output_format vaapi {0} -c:v h264_vaapi -g 50 -bf 0 -profile:v high -level:v 4.1 -sei:v 0 -an -vf format=vaapi|nv12,hwupload {1}",
|
"preset-vaapi": "ffmpeg -hide_banner -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device {2} {0} -c:v h264_vaapi -g 50 -bf 0 -profile:v high -level:v 4.1 -sei:v 0 -an -vf format=vaapi|nv12,hwupload {1}",
|
||||||
"preset-intel-qsv-h264": "ffmpeg -hide_banner {0} -c:v h264_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}",
|
"preset-intel-qsv-h264": "ffmpeg -hide_banner {0} -c:v h264_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}",
|
||||||
"preset-intel-qsv-h265": "ffmpeg -hide_banner {0} -c:v h264_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}",
|
"preset-intel-qsv-h265": "ffmpeg -hide_banner {0} -c:v h264_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}",
|
||||||
"preset-nvidia-h264": "ffmpeg -hide_banner {0} -c:v h264_nvenc -g 50 -profile:v high -level:v auto -preset:v p2 -tune:v ll {1}",
|
"preset-nvidia-h264": "ffmpeg -hide_banner {0} -c:v h264_nvenc -g 50 -profile:v high -level:v auto -preset:v p2 -tune:v ll {1}",
|
||||||
@ -143,6 +181,7 @@ def parse_preset_hardware_acceleration_encode(arg: Any, input: str, output: str)
|
|||||||
return PRESETS_HW_ACCEL_ENCODE.get(arg, PRESETS_HW_ACCEL_ENCODE["default"]).format(
|
return PRESETS_HW_ACCEL_ENCODE.get(arg, PRESETS_HW_ACCEL_ENCODE["default"]).format(
|
||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
|
_gpu_selector.get_selected_gpu(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ from abc import ABC, abstractmethod
|
|||||||
from collections import Counter
|
from collections import Counter
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
from multiprocessing import shared_memory
|
from multiprocessing import shared_memory
|
||||||
from typing import Any, AnyStr, Tuple
|
from typing import Any, AnyStr, Optional, Tuple
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -976,9 +976,13 @@ def ffprobe_stream(path: str) -> sp.CompletedProcess:
|
|||||||
return sp.run(ffprobe_cmd, capture_output=True)
|
return sp.run(ffprobe_cmd, capture_output=True)
|
||||||
|
|
||||||
|
|
||||||
def vainfo_hwaccel() -> sp.CompletedProcess:
|
def vainfo_hwaccel(device_name: Optional[str] = None) -> sp.CompletedProcess:
|
||||||
"""Run vainfo."""
|
"""Run vainfo."""
|
||||||
ffprobe_cmd = ["vainfo"]
|
ffprobe_cmd = (
|
||||||
|
["vainfo"]
|
||||||
|
if not device_name
|
||||||
|
else ["vainfo", "--display", "drm", "--device", f"/dev/dri/{device_name}"]
|
||||||
|
)
|
||||||
return sp.run(ffprobe_cmd, capture_output=True)
|
return sp.run(ffprobe_cmd, capture_output=True)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user