mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-05 22:57:40 +03:00
use hardware encode presets
This commit is contained in:
parent
eeb17ae2b8
commit
f67297ed58
@ -15,6 +15,10 @@ from frigate.api.auth import require_camera_access, require_role
|
|||||||
from frigate.api.defs.tags import Tags
|
from frigate.api.defs.tags import Tags
|
||||||
from frigate.config import FrigateConfig
|
from frigate.config import FrigateConfig
|
||||||
from frigate.const import PROCESS_PRIORITY_LOW
|
from frigate.const import PROCESS_PRIORITY_LOW
|
||||||
|
from frigate.ffmpeg_presets import (
|
||||||
|
EncodeTypeEnum,
|
||||||
|
parse_preset_hardware_acceleration_encode,
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -83,51 +87,29 @@ def _build_ffmpeg_cmd(
|
|||||||
output_playlist = os.path.join(output_dir, "master.m3u8")
|
output_playlist = os.path.join(output_dir, "master.m3u8")
|
||||||
segment_pattern = os.path.join(output_dir, "segment-%d.ts")
|
segment_pattern = os.path.join(output_dir, "segment-%d.ts")
|
||||||
|
|
||||||
return [
|
hwaccel_args = config.ffmpeg.hwaccel_args
|
||||||
|
|
||||||
|
input_args = (
|
||||||
|
f"-loglevel warning -y -protocol_whitelist pipe,file,http,tcp -i {input_url}"
|
||||||
|
)
|
||||||
|
output_args = (
|
||||||
|
f"-c:a aac -b:a 128k"
|
||||||
|
f" -f hls -hls_time 6 -hls_list_size 0"
|
||||||
|
f" -hls_segment_type mpegts"
|
||||||
|
f" -hls_flags independent_segments+append_list"
|
||||||
|
f" -hls_segment_filename {segment_pattern}"
|
||||||
|
f" {output_playlist}"
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd_str = parse_preset_hardware_acceleration_encode(
|
||||||
config.ffmpeg.ffmpeg_path,
|
config.ffmpeg.ffmpeg_path,
|
||||||
"-hide_banner",
|
hwaccel_args,
|
||||||
"-loglevel",
|
input_args,
|
||||||
"warning",
|
output_args,
|
||||||
"-y",
|
EncodeTypeEnum.transcode,
|
||||||
"-protocol_whitelist",
|
)
|
||||||
"pipe,file,http,tcp",
|
|
||||||
"-i",
|
return cmd_str.split(" ")
|
||||||
input_url,
|
|
||||||
# Scale down to 720p max, preserve aspect ratio
|
|
||||||
"-vf",
|
|
||||||
"scale=-2:'min(720,ih)'",
|
|
||||||
# Encode to H.264 (software — universally available)
|
|
||||||
"-c:v",
|
|
||||||
"libx264",
|
|
||||||
"-preset",
|
|
||||||
"ultrafast",
|
|
||||||
"-crf",
|
|
||||||
"26",
|
|
||||||
"-profile:v",
|
|
||||||
"high",
|
|
||||||
"-level:v",
|
|
||||||
"4.1",
|
|
||||||
"-pix_fmt",
|
|
||||||
"yuv420p",
|
|
||||||
"-c:a",
|
|
||||||
"aac",
|
|
||||||
"-b:a",
|
|
||||||
"128k",
|
|
||||||
# Output as HLS with MPEG-TS segments
|
|
||||||
"-f",
|
|
||||||
"hls",
|
|
||||||
"-hls_time",
|
|
||||||
"6",
|
|
||||||
"-hls_list_size",
|
|
||||||
"0",
|
|
||||||
"-hls_segment_type",
|
|
||||||
"mpegts",
|
|
||||||
"-hls_flags",
|
|
||||||
"independent_segments+append_list",
|
|
||||||
"-hls_segment_filename",
|
|
||||||
segment_pattern,
|
|
||||||
output_playlist,
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
async def _wait_for_playlist(session_id: str) -> bool:
|
async def _wait_for_playlist(session_id: str) -> bool:
|
||||||
|
|||||||
@ -208,6 +208,37 @@ PRESETS_HW_ACCEL_ENCODE_PREVIEW = {
|
|||||||
"default": "{0} -hide_banner {1} -c:v libx264 -profile:v baseline -preset:v ultrafast {2}",
|
"default": "{0} -hide_banner {1} -c:v libx264 -profile:v baseline -preset:v ultrafast {2}",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Presets for on-demand H.265 to H.264 transcode playback
|
||||||
|
PRESETS_HW_ACCEL_ENCODE_TRANSCODE = {
|
||||||
|
# Based on birdseye presets with 720p scaling added
|
||||||
|
"preset-rpi-64-h264": "{0} -hide_banner {1} -c:v h264_v4l2m2m -vf scale=-2:'min(720,ih)' {2}",
|
||||||
|
"preset-rpi-64-h265": "{0} -hide_banner {1} -c:v h264_v4l2m2m -vf scale=-2:'min(720,ih)' {2}",
|
||||||
|
FFMPEG_HWACCEL_VAAPI: "{0} -hide_banner -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device {3} {1} -c:v h264_vaapi -bf 0 -profile:v high -level:v 4.1 -vf format=vaapi|nv12,hwupload,scale_vaapi=w=-2:h=720 {2}",
|
||||||
|
"preset-intel-qsv-h264": "{0} -hide_banner {1} -c:v h264_qsv -profile:v high -level:v 4.1 -async_depth:v 1 -vf scale=-2:'min(720,ih)' {2}",
|
||||||
|
"preset-intel-qsv-h265": "{0} -hide_banner {1} -c:v h264_qsv -profile:v high -level:v 4.1 -async_depth:v 1 -vf scale=-2:'min(720,ih)' {2}",
|
||||||
|
FFMPEG_HWACCEL_NVIDIA: "{0} -hide_banner -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 8 {1} -c:v h264_nvenc -profile:v high -preset:v p2 -tune:v ll -vf scale_cuda=w=-2:h=720 {2}",
|
||||||
|
"preset-jetson-h264": "{0} -hide_banner {1} -c:v h264_nvmpi -profile high -vf scale=-2:'min(720,ih)' {2}",
|
||||||
|
"preset-jetson-h265": "{0} -hide_banner {1} -c:v h264_nvmpi -profile high -vf scale=-2:'min(720,ih)' {2}",
|
||||||
|
FFMPEG_HWACCEL_RKMPP: "{0} -hide_banner {1} -c:v h264_rkmpp -profile:v high -vf scale=-2:'min(720,ih)' {2}",
|
||||||
|
FFMPEG_HWACCEL_AMF: "{0} -hide_banner {1} -c:v h264_amf -profile:v high -vf scale=-2:'min(720,ih)' {2}",
|
||||||
|
"default": "{0} -hide_banner {1} -c:v libx264 -preset:v ultrafast -crf 26 -profile:v high -level:v 4.1 -pix_fmt yuv420p -vf scale=-2:'min(720,ih)' {2}",
|
||||||
|
}
|
||||||
|
PRESETS_HW_ACCEL_ENCODE_TRANSCODE["preset-nvidia-h264"] = (
|
||||||
|
PRESETS_HW_ACCEL_ENCODE_TRANSCODE[FFMPEG_HWACCEL_NVIDIA]
|
||||||
|
)
|
||||||
|
PRESETS_HW_ACCEL_ENCODE_TRANSCODE["preset-nvidia-h265"] = (
|
||||||
|
PRESETS_HW_ACCEL_ENCODE_TRANSCODE[FFMPEG_HWACCEL_NVIDIA]
|
||||||
|
)
|
||||||
|
PRESETS_HW_ACCEL_ENCODE_TRANSCODE[f"{FFMPEG_HWACCEL_RKMPP}-no-dump_extra"] = (
|
||||||
|
PRESETS_HW_ACCEL_ENCODE_TRANSCODE[FFMPEG_HWACCEL_RKMPP]
|
||||||
|
)
|
||||||
|
PRESETS_HW_ACCEL_ENCODE_TRANSCODE["preset-rk-h264"] = PRESETS_HW_ACCEL_ENCODE_TRANSCODE[
|
||||||
|
FFMPEG_HWACCEL_RKMPP
|
||||||
|
]
|
||||||
|
PRESETS_HW_ACCEL_ENCODE_TRANSCODE["preset-rk-h265"] = PRESETS_HW_ACCEL_ENCODE_TRANSCODE[
|
||||||
|
FFMPEG_HWACCEL_RKMPP
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def parse_preset_hardware_acceleration_decode(
|
def parse_preset_hardware_acceleration_decode(
|
||||||
arg: Any,
|
arg: Any,
|
||||||
@ -251,6 +282,7 @@ class EncodeTypeEnum(str, Enum):
|
|||||||
birdseye = "birdseye"
|
birdseye = "birdseye"
|
||||||
preview = "preview"
|
preview = "preview"
|
||||||
timelapse = "timelapse"
|
timelapse = "timelapse"
|
||||||
|
transcode = "transcode"
|
||||||
|
|
||||||
|
|
||||||
def parse_preset_hardware_acceleration_encode(
|
def parse_preset_hardware_acceleration_encode(
|
||||||
@ -267,6 +299,8 @@ def parse_preset_hardware_acceleration_encode(
|
|||||||
arg_map = PRESETS_HW_ACCEL_ENCODE_PREVIEW
|
arg_map = PRESETS_HW_ACCEL_ENCODE_PREVIEW
|
||||||
elif type == EncodeTypeEnum.timelapse:
|
elif type == EncodeTypeEnum.timelapse:
|
||||||
arg_map = PRESETS_HW_ACCEL_ENCODE_TIMELAPSE
|
arg_map = PRESETS_HW_ACCEL_ENCODE_TIMELAPSE
|
||||||
|
elif type == EncodeTypeEnum.transcode:
|
||||||
|
arg_map = PRESETS_HW_ACCEL_ENCODE_TRANSCODE
|
||||||
|
|
||||||
if not isinstance(arg, str):
|
if not isinstance(arg, str):
|
||||||
return arg_map["default"].format(ffmpeg_path, input, output)
|
return arg_map["default"].format(ffmpeg_path, input, output)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user