mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-09-12 10:34:24 +08:00
feat: 新增 Amlogic AMLENC 硬件编码支持
- 新增动态加载及 ABI 校验的 AMLENC H.264/H.265 编码器 - 注册 Amlogic 后端并扩展编码器自检 - 并行执行 MJPEG 解码与 AMLENC 编码 - 复用 NV12 缓冲区并移除冗余帧初始化 - 优化低延迟帧分发及 RTCP 关键帧恢复 - 动态调整 AMLENC 码率尚未完成,效果不佳
This commit is contained in:
@@ -3,8 +3,8 @@ use std::sync::mpsc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use super::{
|
||||
EncoderRegistry, H264Config, H264Encoder, H265Config, H265Encoder, VP8Config, VP8Encoder,
|
||||
VP9Config, VP9Encoder, VideoEncoderType,
|
||||
AmlencCodec, AmlencConfig, AmlencEncoder, EncoderRegistry, H264Config, H264Encoder, H265Config,
|
||||
H265Encoder, VP8Config, VP8Encoder, VP9Config, VP9Encoder, VideoEncoderType,
|
||||
};
|
||||
use crate::error::{AppError, Result};
|
||||
use crate::video::format::{PixelFormat, Resolution};
|
||||
@@ -226,6 +226,9 @@ fn run_smoke_test(
|
||||
resolution: Resolution,
|
||||
codec_name_ffmpeg: &str,
|
||||
) -> Result<()> {
|
||||
if codec_name_ffmpeg.contains("amlenc") {
|
||||
return run_amlenc_smoke_test(codec, resolution);
|
||||
}
|
||||
match codec {
|
||||
VideoEncoderType::H264 => run_h264_smoke_test(resolution, codec_name_ffmpeg),
|
||||
VideoEncoderType::H265 => run_h265_smoke_test(resolution, codec_name_ffmpeg),
|
||||
@@ -234,6 +237,37 @@ fn run_smoke_test(
|
||||
}
|
||||
}
|
||||
|
||||
fn run_amlenc_smoke_test(codec: VideoEncoderType, resolution: Resolution) -> Result<()> {
|
||||
let amlenc_codec = match codec {
|
||||
VideoEncoderType::H264 => AmlencCodec::H264,
|
||||
VideoEncoderType::H265 => AmlencCodec::H265,
|
||||
_ => {
|
||||
return Err(AppError::VideoError(
|
||||
"AMLENC only supports H.264 and H.265".to_string(),
|
||||
))
|
||||
}
|
||||
};
|
||||
let mut encoder = AmlencEncoder::new(AmlencConfig {
|
||||
codec: amlenc_codec,
|
||||
resolution,
|
||||
fps: 30,
|
||||
bitrate_kbps: bitrate_kbps_for_resolution(resolution),
|
||||
gop: 30,
|
||||
})?;
|
||||
let frame_len = PixelFormat::Nv12.frame_size(resolution).ok_or_else(|| {
|
||||
AppError::VideoError("Cannot calculate AMLENC NV12 self-check size".to_string())
|
||||
})?;
|
||||
let frame = build_nv12_test_frame(resolution, frame_len);
|
||||
for _ in 0..SELF_CHECK_FRAME_ATTEMPTS {
|
||||
if encoder.encode_raw(&frame)?.is_some() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Err(AppError::VideoError(
|
||||
"AMLENC produced no output after multiple frames".to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
fn run_h264_smoke_test(resolution: Resolution, codec_name_ffmpeg: &str) -> Result<()> {
|
||||
let mut encoder = H264Encoder::with_codec(
|
||||
H264Config::low_latency(resolution, bitrate_kbps_for_resolution(resolution)),
|
||||
|
||||
Reference in New Issue
Block a user