mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-01-29 00:51:53 +08:00
refactor(hwcodec): 简化 hwcodec 库以适配 IP-KVM 场景
移除 IP-KVM 场景不需要的功能模块: - 移除 VRAM 模块 (GPU 显存直接编解码) - 移除 Mux 模块 (视频混流) - 移除 macOS/Android 平台支持 - 移除外部 SDK 依赖 (~9MB) - 移除开发工具和示例程序 简化解码器为仅支持 MJPEG (采集卡输出格式) 简化 NVIDIA 检测代码 (使用 dlopen 替代 SDK) 更新版本号至 0.8.0 更新相关技术文档
This commit is contained in:
@@ -7,43 +7,35 @@ libs/hwcodec/
|
||||
├── Cargo.toml # 包配置
|
||||
├── Cargo.lock # 依赖锁定
|
||||
├── build.rs # 构建脚本
|
||||
├── src/ # Rust 源码
|
||||
│ ├── lib.rs # 库入口
|
||||
│ ├── common.rs # 公共定义
|
||||
│ ├── ffmpeg.rs # FFmpeg 集成
|
||||
│ ├── mux.rs # 混流器
|
||||
│ ├── android.rs # Android 支持
|
||||
│ ├── ffmpeg_ram/ # RAM 编解码
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── encode.rs
|
||||
│ │ └── decode.rs
|
||||
│ ├── vram/ # GPU 编解码 (Windows)
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── encode.rs
|
||||
│ │ ├── decode.rs
|
||||
│ │ └── ...
|
||||
│ └── res/ # 测试资源
|
||||
│ ├── 720p.h264
|
||||
│ └── 720p.h265
|
||||
├── cpp/ # C++ 源码
|
||||
│ ├── common/ # 公共代码
|
||||
│ ├── ffmpeg_ram/ # FFmpeg RAM 实现
|
||||
│ ├── ffmpeg_vram/ # FFmpeg VRAM 实现
|
||||
│ ├── nv/ # NVIDIA 实现
|
||||
│ ├── amf/ # AMD 实现
|
||||
│ ├── mfx/ # Intel 实现
|
||||
│ ├── mux/ # 混流实现
|
||||
│ └── yuv/ # YUV 处理
|
||||
├── externals/ # 外部 SDK (Git 子模块)
|
||||
│ ├── nv-codec-headers_n12.1.14.0/
|
||||
│ ├── Video_Codec_SDK_12.1.14/
|
||||
│ ├── AMF_v1.4.35/
|
||||
│ └── MediaSDK_22.5.4/
|
||||
├── dev/ # 开发工具
|
||||
│ ├── capture/ # 捕获工具
|
||||
│ ├── render/ # 渲染工具
|
||||
│ └── tool/ # 通用工具
|
||||
└── examples/ # 示例程序
|
||||
└── src/ # Rust 源码
|
||||
├── lib.rs # 库入口
|
||||
├── common.rs # 公共定义
|
||||
├── ffmpeg.rs # FFmpeg 集成
|
||||
└── ffmpeg_ram/ # RAM 编解码
|
||||
├── mod.rs
|
||||
├── encode.rs
|
||||
└── decode.rs
|
||||
└── cpp/ # C++ 源码
|
||||
├── common/ # 公共代码
|
||||
│ ├── log.cpp
|
||||
│ ├── log.h
|
||||
│ ├── util.cpp
|
||||
│ ├── util.h
|
||||
│ ├── callback.h
|
||||
│ ├── common.h
|
||||
│ └── platform/
|
||||
│ ├── linux/
|
||||
│ │ ├── linux.cpp
|
||||
│ │ └── linux.h
|
||||
│ └── win/
|
||||
│ ├── win.cpp
|
||||
│ └── win.h
|
||||
├── ffmpeg_ram/ # FFmpeg RAM 实现
|
||||
│ ├── ffmpeg_ram_encode.cpp
|
||||
│ ├── ffmpeg_ram_decode.cpp
|
||||
│ └── ffmpeg_ram_ffi.h
|
||||
└── yuv/ # YUV 处理
|
||||
└── yuv.cpp
|
||||
```
|
||||
|
||||
## 2. Cargo 配置
|
||||
@@ -53,12 +45,12 @@ libs/hwcodec/
|
||||
```toml
|
||||
[package]
|
||||
name = "hwcodec"
|
||||
version = "0.7.1"
|
||||
version = "0.8.0"
|
||||
edition = "2021"
|
||||
description = "Hardware video codec for IP-KVM (Windows/Linux)"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
vram = [] # GPU VRAM 直接编解码 (仅 Windows)
|
||||
|
||||
[dependencies]
|
||||
log = "0.4" # 日志
|
||||
@@ -72,26 +64,23 @@ bindgen = "0.59" # FFI 绑定生成
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.10" # 日志输出
|
||||
rand = "0.8" # 随机数
|
||||
```
|
||||
|
||||
### 2.2 Feature 说明
|
||||
### 2.2 与原版的区别
|
||||
|
||||
| Feature | 说明 | 平台 |
|
||||
|---------|------|------|
|
||||
| `default` | 基础功能 | 全平台 |
|
||||
| `vram` | GPU VRAM 直接编解码 | 仅 Windows |
|
||||
| 特性 | 原版 (RustDesk) | 简化版 (One-KVM) |
|
||||
|------|-----------------|------------------|
|
||||
| `vram` feature | ✓ | ✗ (已移除) |
|
||||
| 外部 SDK | 需要 | 不需要 |
|
||||
| 版本号 | 0.7.1 | 0.8.0 |
|
||||
| 目标平台 | Windows/Linux/macOS/Android | Windows/Linux |
|
||||
|
||||
### 2.3 使用方式
|
||||
|
||||
```toml
|
||||
# 基础使用
|
||||
# 在 One-KVM 项目中使用
|
||||
[dependencies]
|
||||
hwcodec = { path = "libs/hwcodec" }
|
||||
|
||||
# 启用 VRAM 功能 (Windows)
|
||||
[dependencies]
|
||||
hwcodec = { path = "libs/hwcodec", features = ["vram"] }
|
||||
```
|
||||
|
||||
## 3. 构建脚本详解 (build.rs)
|
||||
@@ -109,11 +98,7 @@ fn main() {
|
||||
// 2. 构建 FFmpeg 相关模块
|
||||
ffmpeg::build_ffmpeg(&mut builder);
|
||||
|
||||
// 3. 构建 SDK 模块 (Windows + vram feature)
|
||||
#[cfg(all(windows, feature = "vram"))]
|
||||
sdk::build_sdk(&mut builder);
|
||||
|
||||
// 4. 编译生成静态库
|
||||
// 3. 编译生成静态库
|
||||
builder.static_crt(true).compile("hwcodec");
|
||||
}
|
||||
```
|
||||
@@ -139,9 +124,6 @@ fn build_common(builder: &mut Build) {
|
||||
#[cfg(target_os = "linux")]
|
||||
builder.file(common_dir.join("platform/linux/linux.cpp"));
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
builder.file(common_dir.join("platform/mac/mac.mm"));
|
||||
|
||||
// 工具代码
|
||||
builder.files([
|
||||
common_dir.join("log.cpp"),
|
||||
@@ -168,11 +150,8 @@ mod ffmpeg {
|
||||
// 链接系统库
|
||||
link_os();
|
||||
|
||||
// 构建子模块
|
||||
// 构建 FFmpeg RAM 模块
|
||||
build_ffmpeg_ram(builder);
|
||||
#[cfg(feature = "vram")]
|
||||
build_ffmpeg_vram(builder);
|
||||
build_mux(builder);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -186,8 +165,6 @@ fn link_vcpkg(builder: &mut Build, path: PathBuf) -> PathBuf {
|
||||
// 目标平台识别
|
||||
let target = match (target_os, target_arch) {
|
||||
("windows", "x86_64") => "x64-windows-static",
|
||||
("macos", "x86_64") => "x64-osx",
|
||||
("macos", "aarch64") => "arm64-osx",
|
||||
("linux", arch) => format!("{}-linux", arch),
|
||||
_ => panic!("unsupported platform"),
|
||||
};
|
||||
@@ -239,57 +216,12 @@ fn link_os() {
|
||||
let libs: Vec<&str> = match target_os.as_str() {
|
||||
"windows" => vec!["User32", "bcrypt", "ole32", "advapi32"],
|
||||
"linux" => vec!["drm", "X11", "stdc++", "z"],
|
||||
"macos" | "ios" => vec!["c++", "m"],
|
||||
"android" => vec!["z", "m", "android", "atomic", "mediandk"],
|
||||
_ => panic!("unsupported os"),
|
||||
};
|
||||
|
||||
for lib in libs {
|
||||
println!("cargo:rustc-link-lib={}", lib);
|
||||
}
|
||||
|
||||
// macOS 框架
|
||||
if target_os == "macos" || target_os == "ios" {
|
||||
for framework in ["CoreFoundation", "CoreVideo", "CoreMedia",
|
||||
"VideoToolbox", "AVFoundation"] {
|
||||
println!("cargo:rustc-link-lib=framework={}", framework);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.6 SDK 模块构建 (Windows)
|
||||
|
||||
```rust
|
||||
#[cfg(all(windows, feature = "vram"))]
|
||||
mod sdk {
|
||||
pub fn build_sdk(builder: &mut Build) {
|
||||
build_amf(builder); // AMD AMF
|
||||
build_nv(builder); // NVIDIA
|
||||
build_mfx(builder); // Intel MFX
|
||||
}
|
||||
|
||||
fn build_nv(builder: &mut Build) {
|
||||
let sdk_path = externals_dir.join("Video_Codec_SDK_12.1.14");
|
||||
|
||||
// 包含 SDK 头文件
|
||||
builder.includes([
|
||||
sdk_path.join("Interface"),
|
||||
sdk_path.join("Samples/Utils"),
|
||||
sdk_path.join("Samples/NvCodec"),
|
||||
]);
|
||||
|
||||
// 编译 SDK 源文件
|
||||
builder.file(sdk_path.join("Samples/NvCodec/NvEncoder/NvEncoder.cpp"));
|
||||
builder.file(sdk_path.join("Samples/NvCodec/NvEncoder/NvEncoderD3D11.cpp"));
|
||||
builder.file(sdk_path.join("Samples/NvCodec/NvDecoder/NvDecoder.cpp"));
|
||||
|
||||
// 编译封装代码
|
||||
builder.files([
|
||||
nv_dir.join("nv_encode.cpp"),
|
||||
nv_dir.join("nv_decode.cpp"),
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -332,40 +264,10 @@ impl bindgen::callbacks::ParseCallbacks for CommonCallbacks {
|
||||
| `common_ffi.rs` | `common.h`, `callback.h` | 枚举、常量、回调类型 |
|
||||
| `ffmpeg_ffi.rs` | `ffmpeg_ffi.h` | FFmpeg 日志级别、函数 |
|
||||
| `ffmpeg_ram_ffi.rs` | `ffmpeg_ram_ffi.h` | 编解码器函数 |
|
||||
| `mux_ffi.rs` | `mux_ffi.h` | 混流器函数 |
|
||||
|
||||
## 5. 外部依赖管理
|
||||
## 5. 平台构建指南
|
||||
|
||||
### 5.1 Git 子模块
|
||||
|
||||
```bash
|
||||
# 初始化子模块
|
||||
git submodule update --init --recursive
|
||||
|
||||
# 更新子模块
|
||||
git submodule update --remote externals
|
||||
```
|
||||
|
||||
### 5.2 子模块配置 (.gitmodules)
|
||||
|
||||
```
|
||||
[submodule "externals"]
|
||||
path = libs/hwcodec/externals
|
||||
url = https://github.com/rustdesk-org/externals.git
|
||||
```
|
||||
|
||||
### 5.3 依赖版本
|
||||
|
||||
| 依赖 | 版本 | 用途 |
|
||||
|------|------|------|
|
||||
| nv-codec-headers | n12.1.14.0 | NVIDIA FFmpeg 编码头 |
|
||||
| Video_Codec_SDK | 12.1.14 | NVIDIA 编解码 SDK |
|
||||
| AMF | v1.4.35 | AMD Advanced Media Framework |
|
||||
| MediaSDK | 22.5.4 | Intel Media SDK |
|
||||
|
||||
## 6. 平台构建指南
|
||||
|
||||
### 6.1 Linux 构建
|
||||
### 5.1 Linux 构建
|
||||
|
||||
```bash
|
||||
# 安装 FFmpeg 开发库
|
||||
@@ -374,11 +276,14 @@ sudo apt install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev
|
||||
# 安装其他依赖
|
||||
sudo apt install libdrm-dev libx11-dev pkg-config
|
||||
|
||||
# 安装 clang (bindgen 需要)
|
||||
sudo apt install clang libclang-dev
|
||||
|
||||
# 构建
|
||||
cargo build --release -p hwcodec
|
||||
```
|
||||
|
||||
### 6.2 Windows 构建 (VCPKG)
|
||||
### 5.2 Windows 构建 (VCPKG)
|
||||
|
||||
```powershell
|
||||
# 安装 VCPKG
|
||||
@@ -392,26 +297,11 @@ cd vcpkg
|
||||
# 设置环境变量
|
||||
$env:VCPKG_ROOT = "C:\path\to\vcpkg"
|
||||
|
||||
# 构建
|
||||
cargo build --release -p hwcodec --features vram
|
||||
```
|
||||
|
||||
### 6.3 macOS 构建
|
||||
|
||||
```bash
|
||||
# 安装 FFmpeg (Homebrew)
|
||||
brew install ffmpeg pkg-config
|
||||
|
||||
# 或使用 VCPKG
|
||||
export VCPKG_ROOT=/path/to/vcpkg
|
||||
vcpkg install ffmpeg:arm64-osx # Apple Silicon
|
||||
vcpkg install ffmpeg:x64-osx # Intel
|
||||
|
||||
# 构建
|
||||
cargo build --release -p hwcodec
|
||||
```
|
||||
|
||||
### 6.4 交叉编译
|
||||
### 5.3 交叉编译
|
||||
|
||||
```bash
|
||||
# 安装 cross
|
||||
@@ -424,9 +314,9 @@ cross build --release -p hwcodec --target aarch64-unknown-linux-gnu
|
||||
cross build --release -p hwcodec --target armv7-unknown-linux-gnueabihf
|
||||
```
|
||||
|
||||
## 7. 集成到 One-KVM
|
||||
## 6. 集成到 One-KVM
|
||||
|
||||
### 7.1 依赖配置
|
||||
### 6.1 依赖配置
|
||||
|
||||
```toml
|
||||
# Cargo.toml
|
||||
@@ -434,12 +324,12 @@ cross build --release -p hwcodec --target armv7-unknown-linux-gnueabihf
|
||||
hwcodec = { path = "libs/hwcodec" }
|
||||
```
|
||||
|
||||
### 7.2 使用示例
|
||||
### 6.2 使用示例
|
||||
|
||||
```rust
|
||||
use hwcodec::ffmpeg_ram::encode::{Encoder, EncodeContext};
|
||||
use hwcodec::ffmpeg_ram::decode::{Decoder, DecodeContext};
|
||||
use hwcodec::ffmpeg::AVPixelFormat;
|
||||
use hwcodec::ffmpeg::{AVPixelFormat, AVHWDeviceType};
|
||||
|
||||
// 检测可用编码器
|
||||
let encoders = Encoder::available_encoders(ctx, None);
|
||||
@@ -458,31 +348,41 @@ let encoder = Encoder::new(EncodeContext {
|
||||
|
||||
// 编码
|
||||
let frames = encoder.encode(&yuv_data, pts_ms)?;
|
||||
|
||||
// 创建 MJPEG 解码器 (IP-KVM 专用)
|
||||
let decoder = Decoder::new(DecodeContext {
|
||||
name: "mjpeg".to_string(),
|
||||
device_type: AVHWDeviceType::AV_HWDEVICE_TYPE_NONE,
|
||||
thread_count: 4,
|
||||
})?;
|
||||
|
||||
// 解码
|
||||
let frames = decoder.decode(&mjpeg_data)?;
|
||||
```
|
||||
|
||||
### 7.3 日志集成
|
||||
### 6.3 日志集成
|
||||
|
||||
```rust
|
||||
// hwcodec 使用 log crate,与 One-KVM 日志系统兼容
|
||||
use log::{debug, info, warn, error};
|
||||
|
||||
// C++ 层日志通过回调传递
|
||||
// C++ 层日志通过回调传递到 Rust
|
||||
#[no_mangle]
|
||||
pub extern "C" fn hwcodec_log(level: i32, message: *const c_char) {
|
||||
pub extern "C" fn hwcodec_av_log_callback(level: i32, message: *const c_char) {
|
||||
// 转发到 Rust log 系统
|
||||
match level {
|
||||
0 => error!("{}", message),
|
||||
1 => warn!("{}", message),
|
||||
2 => info!("{}", message),
|
||||
3 => debug!("{}", message),
|
||||
4 => trace!("{}", message),
|
||||
AV_LOG_ERROR => error!("{}", message),
|
||||
AV_LOG_WARNING => warn!("{}", message),
|
||||
AV_LOG_INFO => info!("{}", message),
|
||||
AV_LOG_DEBUG => debug!("{}", message),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 故障排除
|
||||
## 7. 故障排除
|
||||
|
||||
### 8.1 编译错误
|
||||
### 7.1 编译错误
|
||||
|
||||
**FFmpeg 未找到**:
|
||||
```
|
||||
@@ -502,7 +402,7 @@ error: failed to run custom build command for `hwcodec`
|
||||
sudo apt install clang libclang-dev
|
||||
```
|
||||
|
||||
### 8.2 链接错误
|
||||
### 7.2 链接错误
|
||||
|
||||
**符号未定义**:
|
||||
```
|
||||
@@ -521,7 +421,7 @@ sudo ldconfig
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
|
||||
```
|
||||
|
||||
### 8.3 运行时错误
|
||||
### 7.3 运行时错误
|
||||
|
||||
**硬件编码器不可用**:
|
||||
```
|
||||
@@ -537,3 +437,41 @@ Encoder h264_vaapi test failed
|
||||
avcodec_receive_frame failed, ret = -11
|
||||
```
|
||||
解决: 这通常表示需要更多输入数据 (EAGAIN),是正常行为
|
||||
|
||||
## 8. 与原版 RustDesk hwcodec 的构建差异
|
||||
|
||||
### 8.1 移除的构建步骤
|
||||
|
||||
| 步骤 | 原因 |
|
||||
|------|------|
|
||||
| `build_mux()` | 移除了 Mux 模块 |
|
||||
| `build_ffmpeg_vram()` | 移除了 VRAM 模块 |
|
||||
| `sdk::build_sdk()` | 移除了外部 SDK 依赖 |
|
||||
| macOS 框架链接 | 移除了 macOS 支持 |
|
||||
| Android NDK 链接 | 移除了 Android 支持 |
|
||||
|
||||
### 8.2 简化的构建流程
|
||||
|
||||
```
|
||||
原版构建流程:
|
||||
build.rs
|
||||
├── build_common()
|
||||
├── ffmpeg::build_ffmpeg()
|
||||
│ ├── build_ffmpeg_ram()
|
||||
│ ├── build_ffmpeg_vram() [已移除]
|
||||
│ └── build_mux() [已移除]
|
||||
└── sdk::build_sdk() [已移除]
|
||||
|
||||
简化版构建流程:
|
||||
build.rs
|
||||
├── build_common()
|
||||
└── ffmpeg::build_ffmpeg()
|
||||
└── build_ffmpeg_ram()
|
||||
```
|
||||
|
||||
### 8.3 优势
|
||||
|
||||
1. **更快的编译**: 无需编译外部 SDK 代码
|
||||
2. **更少的依赖**: 无需下载 ~9MB 的外部 SDK
|
||||
3. **更简单的维护**: 代码量减少约 67%
|
||||
4. **更小的二进制**: 不包含未使用的功能
|
||||
|
||||
Reference in New Issue
Block a user