You've already forked FrameTour-RenderWorker
feat(video): 添加硬件加速支持
- 定义硬件加速类型常量(none、qsv、cuda) - 配置QSV和CUDA编码参数及预设 - 在WorkerConfig中添加硬件加速配置选项 - 实现基于硬件加速类型的编码参数动态获取 - 添加FFmpeg硬件加速解码和滤镜参数 - 检测并报告系统硬件加速支持信息 - 在API客户端中上报硬件加速配置和支持状态
This commit is contained in:
167
util/system.py
167
util/system.py
@@ -8,10 +8,10 @@
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
from typing import Optional
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
import psutil
|
||||
from constant import SOFTWARE_VERSION, DEFAULT_CAPABILITIES
|
||||
from constant import SOFTWARE_VERSION, DEFAULT_CAPABILITIES, HW_ACCEL_NONE, HW_ACCEL_QSV, HW_ACCEL_CUDA
|
||||
|
||||
|
||||
def get_sys_info():
|
||||
@@ -101,3 +101,166 @@ def get_ffmpeg_version() -> str:
|
||||
pass
|
||||
|
||||
return 'unknown'
|
||||
|
||||
|
||||
def check_ffmpeg_encoder(encoder: str) -> bool:
|
||||
"""
|
||||
检查 FFmpeg 是否支持指定的编码器
|
||||
|
||||
Args:
|
||||
encoder: 编码器名称,如 'h264_nvenc', 'h264_qsv'
|
||||
|
||||
Returns:
|
||||
bool: 是否支持该编码器
|
||||
"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['ffmpeg', '-hide_banner', '-encoders'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return encoder in result.stdout
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def check_ffmpeg_decoder(decoder: str) -> bool:
|
||||
"""
|
||||
检查 FFmpeg 是否支持指定的解码器
|
||||
|
||||
Args:
|
||||
decoder: 解码器名称,如 'h264_cuvid', 'h264_qsv'
|
||||
|
||||
Returns:
|
||||
bool: 是否支持该解码器
|
||||
"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['ffmpeg', '-hide_banner', '-decoders'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return decoder in result.stdout
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def check_ffmpeg_hwaccel(hwaccel: str) -> bool:
|
||||
"""
|
||||
检查 FFmpeg 是否支持指定的硬件加速方法
|
||||
|
||||
Args:
|
||||
hwaccel: 硬件加速方法,如 'cuda', 'qsv', 'dxva2', 'd3d11va'
|
||||
|
||||
Returns:
|
||||
bool: 是否支持该硬件加速方法
|
||||
"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['ffmpeg', '-hide_banner', '-hwaccels'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return hwaccel in result.stdout
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def detect_hw_accel_support() -> Dict[str, Any]:
|
||||
"""
|
||||
检测系统的硬件加速支持情况
|
||||
|
||||
Returns:
|
||||
dict: 硬件加速支持信息
|
||||
{
|
||||
'cuda': {
|
||||
'available': bool,
|
||||
'gpu': str or None,
|
||||
'encoder': bool, # h264_nvenc
|
||||
'decoder': bool, # h264_cuvid
|
||||
},
|
||||
'qsv': {
|
||||
'available': bool,
|
||||
'encoder': bool, # h264_qsv
|
||||
'decoder': bool, # h264_qsv
|
||||
},
|
||||
'recommended': str # 推荐的加速方式: 'cuda', 'qsv', 'none'
|
||||
}
|
||||
"""
|
||||
result = {
|
||||
'cuda': {
|
||||
'available': False,
|
||||
'gpu': None,
|
||||
'encoder': False,
|
||||
'decoder': False,
|
||||
},
|
||||
'qsv': {
|
||||
'available': False,
|
||||
'encoder': False,
|
||||
'decoder': False,
|
||||
},
|
||||
'recommended': HW_ACCEL_NONE
|
||||
}
|
||||
|
||||
# 检测 CUDA/NVENC 支持
|
||||
gpu_info = get_gpu_info()
|
||||
if gpu_info:
|
||||
result['cuda']['gpu'] = gpu_info
|
||||
result['cuda']['available'] = check_ffmpeg_hwaccel('cuda')
|
||||
result['cuda']['encoder'] = check_ffmpeg_encoder('h264_nvenc')
|
||||
result['cuda']['decoder'] = check_ffmpeg_decoder('h264_cuvid')
|
||||
|
||||
# 检测 QSV 支持
|
||||
result['qsv']['available'] = check_ffmpeg_hwaccel('qsv')
|
||||
result['qsv']['encoder'] = check_ffmpeg_encoder('h264_qsv')
|
||||
result['qsv']['decoder'] = check_ffmpeg_decoder('h264_qsv')
|
||||
|
||||
# 推荐硬件加速方式(优先 CUDA,其次 QSV)
|
||||
if result['cuda']['available'] and result['cuda']['encoder']:
|
||||
result['recommended'] = HW_ACCEL_CUDA
|
||||
elif result['qsv']['available'] and result['qsv']['encoder']:
|
||||
result['recommended'] = HW_ACCEL_QSV
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_hw_accel_info_str() -> str:
|
||||
"""
|
||||
获取硬件加速支持信息的可读字符串
|
||||
|
||||
Returns:
|
||||
str: 硬件加速支持信息描述
|
||||
"""
|
||||
support = detect_hw_accel_support()
|
||||
|
||||
parts = []
|
||||
|
||||
if support['cuda']['available']:
|
||||
gpu = support['cuda']['gpu'] or 'Unknown GPU'
|
||||
status = 'encoder+decoder' if support['cuda']['encoder'] and support['cuda']['decoder'] else (
|
||||
'encoder only' if support['cuda']['encoder'] else 'decoder only' if support['cuda']['decoder'] else 'hwaccel only'
|
||||
)
|
||||
parts.append(f"CUDA({gpu}, {status})")
|
||||
|
||||
if support['qsv']['available']:
|
||||
status = 'encoder+decoder' if support['qsv']['encoder'] and support['qsv']['decoder'] else (
|
||||
'encoder only' if support['qsv']['encoder'] else 'decoder only' if support['qsv']['decoder'] else 'hwaccel only'
|
||||
)
|
||||
parts.append(f"QSV({status})")
|
||||
|
||||
if not parts:
|
||||
return "No hardware acceleration available"
|
||||
|
||||
return ', '.join(parts) + f" [recommended: {support['recommended']}]"
|
||||
|
||||
Reference in New Issue
Block a user