完成阶段2
This commit is contained in:
parent
3c67625a4c
commit
4cd65bd168
82
Readme.md
82
Readme.md
@ -576,8 +576,9 @@ GraphMgr 负责:
|
|||||||
|
|
||||||
- **硬件平台**:RK3588(4×A76 + 4×A55 + NPU + VPU + RGA)
|
- **硬件平台**:RK3588(4×A76 + 4×A55 + NPU + VPU + RGA)
|
||||||
- **工具链**:
|
- **工具链**:
|
||||||
- 交叉编译:`aarch64-linux-gnu-gcc 12+`
|
- 板上编译:GCC 10+(推荐)
|
||||||
- 构建:CMake ≥ 3.20 + Ninja
|
- 交叉编译:`aarch64-linux-gnu-gcc 12+`(可选)
|
||||||
|
- 构建:CMake ≥ 3.20
|
||||||
- **调试**:
|
- **调试**:
|
||||||
- `gdbserver` + VSCode 远程调试
|
- `gdbserver` + VSCode 远程调试
|
||||||
- RKNN Profiler 分析 NPU 利用率
|
- RKNN Profiler 分析 NPU 利用率
|
||||||
@ -585,6 +586,83 @@ GraphMgr 负责:
|
|||||||
- `spdlog` 异步日志
|
- `spdlog` 异步日志
|
||||||
- 日志级别可运行时调整(通过配置或 REST 接口)
|
- 日志级别可运行时调整(通过配置或 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/
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 十一、扩展与演进
|
## 十一、扩展与演进
|
||||||
|
|||||||
@ -170,61 +170,71 @@ private:
|
|||||||
out_h = (out_h + 1) & ~1;
|
out_h = (out_h + 1) & ~1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t out_size = CalcImageSize(out_w, out_h, out_fmt);
|
int src_fmt_rga = ToRgaFormat(frame->format);
|
||||||
if (out_size == 0) {
|
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);
|
PushToDownstream(frame);
|
||||||
|
++processed_;
|
||||||
|
if (processed_ % 100 == 0) {
|
||||||
|
std::cout << "[preprocess] passthrough frame " << frame->frame_id
|
||||||
|
<< " " << frame->width << "x" << frame->height << " (no change)\n";
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto buffer = std::make_shared<std::vector<uint8_t>>(out_size);
|
size_t out_size = CalcImageSize(out_w, out_h, out_fmt);
|
||||||
int src_fmt_rga = ToRgaFormat(frame->format);
|
if (out_size == 0 || src_fmt_rga == RK_FORMAT_UNKNOWN || dst_fmt_rga == RK_FORMAT_UNKNOWN) {
|
||||||
int dst_fmt_rga = ToRgaFormat(out_fmt);
|
|
||||||
|
|
||||||
if (src_fmt_rga == RK_FORMAT_UNKNOWN || dst_fmt_rga == RK_FORMAT_UNKNOWN) {
|
|
||||||
std::cerr << "[preprocess] unsupported format for RGA\n";
|
std::cerr << "[preprocess] unsupported format for RGA\n";
|
||||||
PushToDownstream(frame);
|
PushToDownstream(frame);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int src_stride = frame->planes[0].stride > 0 ? frame->planes[0].stride
|
auto buffer = std::make_shared<std::vector<uint8_t>>(out_size);
|
||||||
: (frame->stride > 0 ? frame->stride : frame->width);
|
|
||||||
|
// 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 src_buf{};
|
||||||
rga_buffer_t dst_buf{};
|
rga_buffer_t dst_buf{};
|
||||||
|
|
||||||
if (frame->dma_fd >= 0) {
|
if (frame->dma_fd >= 0) {
|
||||||
src_buf = wrapbuffer_fd_t(frame->dma_fd, frame->width, frame->height,
|
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) {
|
} else if (frame->data) {
|
||||||
src_buf = wrapbuffer_virtualaddr_t(frame->data, frame->width, frame->height,
|
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 {
|
} else {
|
||||||
PushToDownstream(frame);
|
PushToDownstream(frame);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_buf = wrapbuffer_virtualaddr_t(buffer->data(), out_w, out_h,
|
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;
|
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) {
|
if (need_resize && need_cvt) {
|
||||||
// Resize + color convert in one call using improcess
|
// RGA3 can do resize + cvtcolor in one call via improcess
|
||||||
status = imresize(src_buf, dst_buf);
|
// 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) {
|
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);
|
status = imcvtcolor(tmp, dst_buf, src_fmt_rga, dst_fmt_rga, IM_COLOR_SPACE_DEFAULT);
|
||||||
}
|
}
|
||||||
} else if (need_resize) {
|
} else if (need_resize) {
|
||||||
status = imresize(src_buf, dst_buf);
|
status = imresize(src_buf, dst_buf);
|
||||||
} else if (need_cvt) {
|
} else if (need_cvt) {
|
||||||
status = imcvtcolor(src_buf, dst_buf, src_fmt_rga, dst_fmt_rga, IM_COLOR_SPACE_DEFAULT);
|
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) {
|
if (status != IM_STATUS_SUCCESS) {
|
||||||
@ -237,7 +247,7 @@ private:
|
|||||||
out_frame->width = out_w;
|
out_frame->width = out_w;
|
||||||
out_frame->height = out_h;
|
out_frame->height = out_h;
|
||||||
out_frame->format = out_fmt;
|
out_frame->format = out_fmt;
|
||||||
out_frame->stride = out_w;
|
out_frame->stride = dst_wstride;
|
||||||
out_frame->data = buffer->data();
|
out_frame->data = buffer->data();
|
||||||
out_frame->data_size = buffer->size();
|
out_frame->data_size = buffer->size();
|
||||||
out_frame->data_owner = buffer;
|
out_frame->data_owner = buffer;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user