完成阶段2

This commit is contained in:
sladro 2025-12-26 14:35:03 +08:00
parent 3c67625a4c
commit 4cd65bd168
2 changed files with 112 additions and 24 deletions

View File

@ -576,8 +576,9 @@ GraphMgr 负责:
- **硬件平台**RK35884×A76 + 4×A55 + NPU + VPU + RGA
- **工具链**
- 交叉编译:`aarch64-linux-gnu-gcc 12+`
- 构建CMake ≥ 3.20 + Ninja
- 板上编译GCC 10+(推荐)
- 交叉编译:`aarch64-linux-gnu-gcc 12+`(可选)
- 构建CMake ≥ 3.20
- **调试**
- `gdbserver` + VSCode 远程调试
- RKNN Profiler 分析 NPU 利用率
@ -585,6 +586,83 @@ GraphMgr 负责:
- `spdlog` 异步日志
- 日志级别可运行时调整(通过配置或 REST 接口)
### 10.1 板上编译(推荐)
在 RK3588 板子上直接编译,无需配置交叉编译环境。
**依赖安装:**
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install -y build-essential cmake git pkg-config \
libavformat-dev libavcodec-dev libavutil-dev libswscale-dev
```
**编译命令:**
```bash
cd Rk3588Sys
# 配置(启用所有硬件加速)
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DRK3588_ENABLE_FFMPEG=ON \
-DRK3588_ENABLE_MPP=ON \
-DRK3588_ENABLE_RGA=ON \
-DRK3588_ENABLE_ZLMEDIAKIT=ON \
-DRK_ZLMK_API_LIB_PATH=$PWD/third_party/rknpu2/examples/3rdparty/zlmediakit/aarch64/libmk_api.so \
-DRK_ZLMEDIAKIT_INCLUDE_DIR=$PWD/third_party/rknpu2/examples/3rdparty/zlmediakit/include
# 编译
cmake --build build -j$(nproc)
```
**CMake 选项说明:**
| 选项 | 说明 | 默认值 |
|------|------|--------|
| `RK3588_ENABLE_FFMPEG` | 启用 FFmpeg 拉流/软解码 | OFF |
| `RK3588_ENABLE_MPP` | 启用 MPP 硬件编解码 | OFF |
| `RK3588_ENABLE_RGA` | 启用 RGA 硬件图像处理 | OFF |
| `RK3588_ENABLE_ZLMEDIAKIT` | 启用内置 RTSP Server | OFF |
**运行:**
```bash
# 纯转码网关
./build/media-server --config configs/sample_cam1.json
# 带预处理的 pipeline
./build/media-server --config configs/sample_preprocess.json
# 内置 RTSP Server 模式
./build/media-server --config configs/sample_cam1_rtsp_server.json
```
### 10.2 交叉编译(可选)
在 x86 主机上交叉编译,适合 CI/CD 或批量部署。
```bash
# 需要安装交叉编译工具链
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
# 配置
cmake -S . -B build-cross \
-DCMAKE_TOOLCHAIN_FILE=cmake/aarch64-linux-gnu.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DRK3588_ENABLE_FFMPEG=ON \
-DRK3588_ENABLE_MPP=ON \
-DRK3588_ENABLE_RGA=ON
# 编译
cmake --build build-cross -j$(nproc)
# 同步到板子
rsync -avz build-cross/ user@board_ip:/opt/media-server/
```
---
## 十一、扩展与演进

View File

@ -170,61 +170,71 @@ private:
out_h = (out_h + 1) & ~1;
}
size_t out_size = CalcImageSize(out_w, out_h, out_fmt);
if (out_size == 0) {
int src_fmt_rga = ToRgaFormat(frame->format);
int dst_fmt_rga = ToRgaFormat(out_fmt);
bool need_cvt = (src_fmt_rga != dst_fmt_rga);
bool need_resize = (frame->width != out_w || frame->height != out_h);
// If no processing needed, passthrough directly
if (!need_cvt && !need_resize) {
PushToDownstream(frame);
++processed_;
if (processed_ % 100 == 0) {
std::cout << "[preprocess] passthrough frame " << frame->frame_id
<< " " << frame->width << "x" << frame->height << " (no change)\n";
}
continue;
}
auto buffer = std::make_shared<std::vector<uint8_t>>(out_size);
int src_fmt_rga = ToRgaFormat(frame->format);
int dst_fmt_rga = ToRgaFormat(out_fmt);
if (src_fmt_rga == RK_FORMAT_UNKNOWN || dst_fmt_rga == RK_FORMAT_UNKNOWN) {
size_t out_size = CalcImageSize(out_w, out_h, out_fmt);
if (out_size == 0 || src_fmt_rga == RK_FORMAT_UNKNOWN || dst_fmt_rga == RK_FORMAT_UNKNOWN) {
std::cerr << "[preprocess] unsupported format for RGA\n";
PushToDownstream(frame);
continue;
}
int src_stride = frame->planes[0].stride > 0 ? frame->planes[0].stride
: (frame->stride > 0 ? frame->stride : frame->width);
auto buffer = std::make_shared<std::vector<uint8_t>>(out_size);
// Calculate proper strides (RGA requires aligned strides)
int src_wstride = frame->planes[0].stride > 0 ? frame->planes[0].stride
: (frame->stride > 0 ? frame->stride : Align16(frame->width));
int src_hstride = Align16(frame->height);
int dst_wstride = Align16(out_w);
int dst_hstride = Align16(out_h);
rga_buffer_t src_buf{};
rga_buffer_t dst_buf{};
if (frame->dma_fd >= 0) {
src_buf = wrapbuffer_fd_t(frame->dma_fd, frame->width, frame->height,
src_stride, Align16(frame->height), src_fmt_rga);
src_wstride, src_hstride, src_fmt_rga);
} else if (frame->data) {
src_buf = wrapbuffer_virtualaddr_t(frame->data, frame->width, frame->height,
src_stride, Align16(frame->height), src_fmt_rga);
src_wstride, src_hstride, src_fmt_rga);
} else {
PushToDownstream(frame);
continue;
}
dst_buf = wrapbuffer_virtualaddr_t(buffer->data(), out_w, out_h,
out_w, out_h, dst_fmt_rga);
dst_wstride, dst_hstride, dst_fmt_rga);
IM_STATUS status = IM_STATUS_SUCCESS;
bool need_cvt = (src_fmt_rga != dst_fmt_rga);
bool need_resize = (frame->width != out_w || frame->height != out_h);
if (need_resize && need_cvt) {
// Resize + color convert in one call using improcess
status = imresize(src_buf, dst_buf);
// RGA3 can do resize + cvtcolor in one call via improcess
// But for simplicity, do resize first (output same format), then cvtcolor
auto tmp_buf = std::make_shared<std::vector<uint8_t>>(CalcImageSize(out_w, out_h, frame->format));
rga_buffer_t tmp = wrapbuffer_virtualaddr_t(tmp_buf->data(), out_w, out_h,
dst_wstride, dst_hstride, src_fmt_rga);
status = imresize(src_buf, tmp);
if (status == IM_STATUS_SUCCESS) {
// imresize doesn't do color conversion; need separate call
// For simplicity, do resize first then cvtcolor
rga_buffer_t tmp = dst_buf;
status = imcvtcolor(tmp, dst_buf, src_fmt_rga, dst_fmt_rga, IM_COLOR_SPACE_DEFAULT);
}
} else if (need_resize) {
status = imresize(src_buf, dst_buf);
} else if (need_cvt) {
status = imcvtcolor(src_buf, dst_buf, src_fmt_rga, dst_fmt_rga, IM_COLOR_SPACE_DEFAULT);
} else {
status = imcopy(src_buf, dst_buf);
}
if (status != IM_STATUS_SUCCESS) {
@ -237,7 +247,7 @@ private:
out_frame->width = out_w;
out_frame->height = out_h;
out_frame->format = out_fmt;
out_frame->stride = out_w;
out_frame->stride = dst_wstride;
out_frame->data = buffer->data();
out_frame->data_size = buffer->size();
out_frame->data_owner = buffer;