From 4cd65bd1684f82a9cee5cdd330d188eb797f3ef1 Mon Sep 17 00:00:00 2001 From: sladro Date: Fri, 26 Dec 2025 14:35:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=98=B6=E6=AE=B52?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 82 +++++++++++++++++++++++++- plugins/preprocess/preprocess_node.cpp | 54 ++++++++++------- 2 files changed, 112 insertions(+), 24 deletions(-) diff --git a/Readme.md b/Readme.md index 1a64e03..a643571 100644 --- a/Readme.md +++ b/Readme.md @@ -576,8 +576,9 @@ GraphMgr 负责: - **硬件平台**:RK3588(4×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/ +``` + --- ## 十一、扩展与演进 diff --git a/plugins/preprocess/preprocess_node.cpp b/plugins/preprocess/preprocess_node.cpp index f769c78..57a9e43 100644 --- a/plugins/preprocess/preprocess_node.cpp +++ b/plugins/preprocess/preprocess_node.cpp @@ -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>(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>(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>(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;