feat: 适配 RK 原生 HDMI IN 适配采集

This commit is contained in:
mofeng-git
2026-04-01 21:28:15 +08:00
parent 51d7d8b8be
commit abb319068b
36 changed files with 1382 additions and 406 deletions

View File

@@ -25,6 +25,7 @@ enum AVPixelFormat {
AV_PIX_FMT_NV24 = 188,
};
int av_get_pix_fmt(const char *name);
int av_log_get_level(void);
void av_log_set_level(int level);
void hwcodec_set_av_log_callback();

View File

@@ -30,9 +30,15 @@ static int calculate_offset_length(int pix_fmt, int height, const int *linesize,
*length = offset[1] + linesize[2] * height / 2;
break;
case AV_PIX_FMT_NV12:
case AV_PIX_FMT_NV21:
offset[0] = linesize[0] * height;
*length = offset[0] + linesize[1] * height / 2;
break;
case AV_PIX_FMT_NV16:
case AV_PIX_FMT_NV24:
offset[0] = linesize[0] * height;
*length = offset[0] + linesize[1] * height;
break;
case AV_PIX_FMT_YUYV422:
case AV_PIX_FMT_YVYU422:
case AV_PIX_FMT_UYVY422:
@@ -41,6 +47,11 @@ static int calculate_offset_length(int pix_fmt, int height, const int *linesize,
offset[0] = 0; // Only one plane
*length = linesize[0] * height;
break;
case AV_PIX_FMT_RGB24:
case AV_PIX_FMT_BGR24:
offset[0] = 0; // Only one plane
*length = linesize[0] * height;
break;
default:
LOG_ERROR(std::string("unsupported pixfmt") + std::to_string(pix_fmt));
return -1;
@@ -397,9 +408,23 @@ private:
const int *const offset) {
switch (frame->format) {
case AV_PIX_FMT_NV12:
case AV_PIX_FMT_NV21:
if (data_length <
frame->height * (frame->linesize[0] + frame->linesize[1] / 2)) {
LOG_ERROR(std::string("fill_frame: NV12 data length error. data_length:") +
LOG_ERROR(std::string("fill_frame: NV12/NV21 data length error. data_length:") +
std::to_string(data_length) +
", linesize[0]:" + std::to_string(frame->linesize[0]) +
", linesize[1]:" + std::to_string(frame->linesize[1]));
return -1;
}
frame->data[0] = data;
frame->data[1] = data + offset[0];
break;
case AV_PIX_FMT_NV16:
case AV_PIX_FMT_NV24:
if (data_length <
frame->height * (frame->linesize[0] + frame->linesize[1])) {
LOG_ERROR(std::string("fill_frame: NV16/NV24 data length error. data_length:") +
std::to_string(data_length) +
", linesize[0]:" + std::to_string(frame->linesize[0]) +
", linesize[1]:" + std::to_string(frame->linesize[1]));
@@ -436,6 +461,17 @@ private:
}
frame->data[0] = data;
break;
case AV_PIX_FMT_RGB24:
case AV_PIX_FMT_BGR24:
if (data_length < frame->height * frame->linesize[0]) {
LOG_ERROR(std::string("fill_frame: RGB24/BGR24 data length error. data_length:") +
std::to_string(data_length) +
", linesize[0]:" + std::to_string(frame->linesize[0]) +
", height:" + std::to_string(frame->height));
return -1;
}
frame->data[0] = data;
break;
default:
LOG_ERROR(std::string("fill_frame: unsupported format, ") +
std::to_string(frame->format));

View File

@@ -6,7 +6,7 @@
include!(concat!(env!("OUT_DIR"), "/ffmpeg_ffi.rs"));
use serde_derive::{Deserialize, Serialize};
use std::env;
use std::{env, ffi::CString};
#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
pub enum AVHWDeviceType {
@@ -59,6 +59,22 @@ pub(crate) fn init_av_log() {
});
}
pub fn resolve_pixel_format(name: &str, fallback: AVPixelFormat) -> i32 {
let c_name = match CString::new(name) {
Ok(name) => name,
Err(_) => return fallback as i32,
};
unsafe {
let resolved = av_get_pix_fmt(c_name.as_ptr());
if resolved >= 0 {
resolved
} else {
fallback as i32
}
}
}
fn parse_ffmpeg_log_level() -> i32 {
let raw = match env::var("ONE_KVM_FFMPEG_LOG") {
Ok(value) => value,

View File

@@ -243,7 +243,8 @@ fn enumerate_candidate_codecs(ctx: &EncodeContext) -> Vec<CodecInfo> {
}
codecs.retain(|codec| {
!(ctx.pixfmt == AVPixelFormat::AV_PIX_FMT_YUV420P && codec.name.contains("qsv"))
!(ctx.pixfmt == AVPixelFormat::AV_PIX_FMT_YUV420P as i32
&& codec.name.contains("qsv"))
});
codecs
}
@@ -428,7 +429,7 @@ pub struct EncodeContext {
pub mc_name: Option<String>,
pub width: i32,
pub height: i32,
pub pixfmt: AVPixelFormat,
pub pixfmt: i32,
pub align: i32,
pub fps: i32,
pub gop: i32,
@@ -483,7 +484,7 @@ impl Encoder {
CString::new(mc_name.as_str()).map_err(|_| ())?.as_ptr(),
ctx.width,
ctx.height,
ctx.pixfmt as c_int,
ctx.pixfmt,
ctx.align,
ctx.fps,
ctx.gop,

View File

@@ -5,7 +5,6 @@
use crate::common::DataFormat::{self, *};
use crate::ffmpeg::{
AVHWDeviceType::{self, *},
AVPixelFormat,
};
use serde_derive::{Deserialize, Serialize};
use std::ffi::c_int;
@@ -234,7 +233,7 @@ impl CodecInfos {
}
pub fn ffmpeg_linesize_offset_length(
pixfmt: AVPixelFormat,
pixfmt: i32,
width: usize,
height: usize,
align: usize,
@@ -247,7 +246,7 @@ pub fn ffmpeg_linesize_offset_length(
length.resize(1, 0);
unsafe {
if ffmpeg_ram_get_linesize_offset_length(
pixfmt as _,
pixfmt,
width as _,
height as _,
align as _,