diff --git a/configs/sample_person_shoe_two_stage.json b/configs/sample_person_shoe_two_stage.json index 80a8cf3..f7fc290 100644 --- a/configs/sample_person_shoe_two_stage.json +++ b/configs/sample_person_shoe_two_stage.json @@ -40,6 +40,7 @@ "use_rga": true, "rga_gate": "person_shoe_two_stage", "rga_max_inflight": 4, + "dst_packed": true, "infer_fps": 2, "model_path": "./models/yolov8n-640.rknn", "model_version": "v8", @@ -80,6 +81,7 @@ "use_rga": true, "rga_gate": "person_shoe_two_stage", "rga_max_inflight": 4, + "dst_packed": true, "infer_fps": 1, "model_path": "./models/shoe_detector_openimages_ppe_v1.rknn", "model_w": 640, diff --git a/configs/sample_person_shoe_two_stage_balanced.json b/configs/sample_person_shoe_two_stage_balanced.json index 158f59d..6849a2b 100644 --- a/configs/sample_person_shoe_two_stage_balanced.json +++ b/configs/sample_person_shoe_two_stage_balanced.json @@ -40,6 +40,7 @@ "use_rga": true, "rga_gate": "person_shoe_two_stage_balanced", "rga_max_inflight": 4, + "dst_packed": true, "infer_fps": 2, "model_path": "./models/yolov8n-640.rknn", "model_version": "v8", @@ -80,6 +81,7 @@ "use_rga": true, "rga_gate": "person_shoe_two_stage_balanced", "rga_max_inflight": 4, + "dst_packed": true, "infer_fps": 2, "model_path": "./models/shoe_detector_openimages_ppe_v1.rknn", "model_w": 640, diff --git a/configs/sample_person_shoe_two_stage_recall.json b/configs/sample_person_shoe_two_stage_recall.json index 020520c..263acaf 100644 --- a/configs/sample_person_shoe_two_stage_recall.json +++ b/configs/sample_person_shoe_two_stage_recall.json @@ -40,6 +40,7 @@ "use_rga": true, "rga_gate": "person_shoe_two_stage_recall", "rga_max_inflight": 4, + "dst_packed": true, "infer_fps": 3, "model_path": "./models/yolov8n-640.rknn", "model_version": "v8", @@ -80,6 +81,7 @@ "use_rga": true, "rga_gate": "person_shoe_two_stage_recall", "rga_max_inflight": 4, + "dst_packed": true, "infer_fps": 2, "model_path": "./models/shoe_detector_openimages_ppe_v1.rknn", "model_w": 640, diff --git a/docs/deployment.md b/docs/deployment.md index 9caa944..c39c49d 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -123,6 +123,32 @@ sudo ./scripts/deploy.sh install sudo ./scripts/deploy.sh status ``` +### 3.1 DDR 固频排障 + +当出现 `CPU/NPU` 利用率不高,但 RTSP 输出帧率周期性跌落时,优先检查 DDR devfreq 是否在频繁降频。 + +项目内置了 DDR 模式切换脚本: + +```bash +sudo bash ./scripts/ddr_mode.sh status +sudo bash ./scripts/ddr_mode.sh performance +sudo bash ./scripts/ddr_mode.sh restore +``` + +也可以从运维入口调用: + +```bash +sudo ./scripts/ops.sh ddr-status +sudo ./scripts/ops.sh ddr-performance +sudo ./scripts/ops.sh ddr-restore +``` + +说明: + +- `performance`:保存当前 governor/min/max 后,将 DDR 切到高性能模式 +- `restore`:恢复到切换前保存的 governor/min/max +- 默认节点为 `/sys/class/devfreq/dmc` + ### 4. 卸载 ```bash diff --git a/plugins/ai_shoe_det/ai_shoe_det_node.cpp b/plugins/ai_shoe_det/ai_shoe_det_node.cpp index 964f208..a1cd4c8 100644 --- a/plugins/ai_shoe_det/ai_shoe_det_node.cpp +++ b/plugins/ai_shoe_det/ai_shoe_det_node.cpp @@ -571,6 +571,7 @@ private: const uint8_t* model_input_data = nullptr; size_t model_input_size = 0; + int model_input_dma_fd = -1; if (image_processor_ && win_w > 0 && win_h > 0) { Frame crop_frame; @@ -595,7 +596,11 @@ private: ? resized_frame.planes[0].stride : (resized_frame.stride > 0 ? resized_frame.stride : model_w_ * 3); const size_t packed_size = static_cast(model_w_) * static_cast(model_h_) * 3; - if (resized_data && resized_stride > 0) { + if (resized_frame.DmaFd() >= 0 && resized_data) { + model_input_data = resized_data; + model_input_size = resized_frame.data_size > 0 ? resized_frame.data_size : packed_size; + model_input_dma_fd = resized_frame.DmaFd(); + } else if (resized_data && resized_stride > 0) { if (packed_size > input_buf_.size()) input_buf_.resize(packed_size); for (int row = 0; row < model_h_; ++row) { memcpy(input_buf_.data() + static_cast(row) * static_cast(model_w_) * 3, @@ -622,6 +627,7 @@ private: input.is_nhwc = true; input.data = model_input_data; input.size = model_input_size; + input.dma_fd = model_input_dma_fd; input.type = RKNN_TENSOR_UINT8; auto r = infer_backend_->InferBorrowed(model_handle_, input); diff --git a/plugins/ai_yolo/ai_yolo_node.cpp b/plugins/ai_yolo/ai_yolo_node.cpp index ab57e26..e1a972f 100644 --- a/plugins/ai_yolo/ai_yolo_node.cpp +++ b/plugins/ai_yolo/ai_yolo_node.cpp @@ -929,31 +929,50 @@ private: const int resized_stride = resized_frame.planes[0].stride > 0 ? resized_frame.planes[0].stride : (resized_frame.stride > 0 ? resized_frame.stride : static_cast(input_row)); - if (resized_data && resized_stride > 0) { + if (resized_frame.DmaFd() >= 0 && resized_data) { + input.data = resized_data; + input.size = resized_frame.data_size > 0 ? resized_frame.data_size : input_size; + input.width = model_input_w_; + input.height = model_input_h_; + input.dma_fd = resized_frame.DmaFd(); + input.dma_offset = 0; + } else if (resized_data && resized_stride > 0) { for (int y = 0; y < model_input_h_; ++y) { memcpy(resized_input_.data() + static_cast(y) * input_row, resized_data + static_cast(y) * static_cast(resized_stride), input_row); } + input.data = resized_input_.data(); + input.size = input_size; + input.width = model_input_w_; + input.height = model_input_h_; } else { ResizeRgbBilinear(src, w, h, src_stride, resized_input_.data(), model_input_w_, model_input_h_, static_cast(input_row)); + input.data = resized_input_.data(); + input.size = input_size; + input.width = model_input_w_; + input.height = model_input_h_; } } else { ResizeRgbBilinear(src, w, h, src_stride, resized_input_.data(), model_input_w_, model_input_h_, static_cast(input_row)); + input.data = resized_input_.data(); + input.size = input_size; + input.width = model_input_w_; + input.height = model_input_h_; } } else { ResizeRgbBilinear(src, w, h, src_stride, resized_input_.data(), model_input_w_, model_input_h_, static_cast(input_row)); + input.data = resized_input_.data(); + input.size = input_size; + input.width = model_input_w_; + input.height = model_input_h_; } - input.data = resized_input_.data(); - input.size = input_size; - input.width = model_input_w_; - input.height = model_input_h_; } input.is_nhwc = true; diff --git a/scripts/ddr_mode.sh b/scripts/ddr_mode.sh new file mode 100644 index 0000000..eddc76c --- /dev/null +++ b/scripts/ddr_mode.sh @@ -0,0 +1,102 @@ +#!/bin/bash +set -euo pipefail + +DEV=${DDR_DEV:-/sys/class/devfreq/dmc} +STATE_DIR=${DDR_STATE_DIR:-/tmp/orangepi-ddr-mode} + +usage() { + cat <<'EOF' +Usage: + sudo ./scripts/ddr_mode.sh status + sudo ./scripts/ddr_mode.sh performance + sudo ./scripts/ddr_mode.sh ondemand + sudo ./scripts/ddr_mode.sh restore +EOF +} + +require_dev() { + if [[ ! -d "$DEV" ]]; then + echo "DDR devfreq node not found: $DEV" >&2 + exit 1 + fi +} + +show_status() { + require_dev + echo "DDR devfreq node: $DEV" + [[ -f "$DEV/name" ]] && echo "name: $(cat "$DEV/name")" + [[ -f "$DEV/governor" ]] && echo "governor: $(cat "$DEV/governor")" + [[ -f "$DEV/available_governors" ]] && echo "available_governors: $(cat "$DEV/available_governors")" + [[ -f "$DEV/min_freq" ]] && echo "min_freq: $(cat "$DEV/min_freq")" + [[ -f "$DEV/max_freq" ]] && echo "max_freq: $(cat "$DEV/max_freq")" + [[ -f "$DEV/cur_freq" ]] && echo "cur_freq: $(cat "$DEV/cur_freq")" + [[ -f "$DEV/available_frequencies" ]] && echo "available_frequencies: $(cat "$DEV/available_frequencies")" +} + +save_state() { + mkdir -p "$STATE_DIR" + [[ -f "$DEV/governor" ]] && cat "$DEV/governor" > "$STATE_DIR/governor" + [[ -f "$DEV/min_freq" ]] && cat "$DEV/min_freq" > "$STATE_DIR/min_freq" + [[ -f "$DEV/max_freq" ]] && cat "$DEV/max_freq" > "$STATE_DIR/max_freq" +} + +set_performance() { + require_dev + save_state + if [[ -f "$DEV/available_governors" ]] && grep -qw performance "$DEV/available_governors"; then + echo performance > "$DEV/governor" + elif [[ -f "$DEV/available_frequencies" ]]; then + max=$(tr ' ' '\n' < "$DEV/available_frequencies" | sort -n | tail -n1) + echo "$max" > "$DEV/min_freq" + echo "$max" > "$DEV/max_freq" + else + echo "No performance governor or available_frequencies for $DEV" >&2 + exit 1 + fi + show_status +} + +set_ondemand() { + require_dev + if [[ -f "$DEV/available_governors" ]] && grep -qw dmc_ondemand "$DEV/available_governors"; then + echo dmc_ondemand > "$DEV/governor" + else + echo "dmc_ondemand governor not available for $DEV" >&2 + exit 1 + fi + show_status +} + +restore_state() { + require_dev + if [[ ! -d "$STATE_DIR" ]]; then + echo "No saved DDR state found in $STATE_DIR" >&2 + exit 1 + fi + [[ -f "$STATE_DIR/governor" ]] && cat "$STATE_DIR/governor" > "$DEV/governor" + [[ -f "$STATE_DIR/min_freq" ]] && cat "$STATE_DIR/min_freq" > "$DEV/min_freq" + [[ -f "$STATE_DIR/max_freq" ]] && cat "$STATE_DIR/max_freq" > "$DEV/max_freq" + show_status +} + +case "${1:-status}" in + status) + show_status + ;; + performance) + set_performance + ;; + ondemand) + set_ondemand + ;; + restore) + restore_state + ;; + -h|--help|help) + usage + ;; + *) + usage + exit 1 + ;; +esac diff --git a/scripts/ops.sh b/scripts/ops.sh index 6744c86..b21b351 100755 --- a/scripts/ops.sh +++ b/scripts/ops.sh @@ -2,7 +2,7 @@ # RK3588 Media Server 运维脚本 # 安装后位于 /opt/rk3588-media-server/script/ops.sh # -# 用法: sudo ./ops.sh [status|start|stop|restart|logs|hw] +# 用法: sudo ./ops.sh [status|start|stop|restart|logs|hw|ddr-status|ddr-performance|ddr-ondemand|ddr-restore] set -e @@ -118,6 +118,22 @@ cmd_metrics() { /opt/rk3588-media-server/scripts/monitor_hw.sh } +cmd_ddr_status() { + bash /opt/rk3588-media-server/scripts/ddr_mode.sh status +} + +cmd_ddr_performance() { + bash /opt/rk3588-media-server/scripts/ddr_mode.sh performance +} + +cmd_ddr_ondemand() { + bash /opt/rk3588-media-server/scripts/ddr_mode.sh ondemand +} + +cmd_ddr_restore() { + bash /opt/rk3588-media-server/scripts/ddr_mode.sh restore +} + # 主入口 case "${1:-status}" in status) @@ -138,6 +154,18 @@ case "${1:-status}" in hw) cmd_metrics ;; + ddr-status) + cmd_ddr_status + ;; + ddr-performance) + cmd_ddr_performance + ;; + ddr-ondemand) + cmd_ddr_ondemand + ;; + ddr-restore) + cmd_ddr_restore + ;; *) echo "RK3588 Media Server 运维脚本" echo "" @@ -150,6 +178,10 @@ case "${1:-status}" in echo " restart 重启服务" echo " logs 查看实时日志" echo " hw 查看硬件监控" + echo " ddr-status 查看 DDR 频率策略" + echo " ddr-performance DDR 切到高性能模式" + echo " ddr-ondemand DDR 切回 dmc_ondemand" + echo " ddr-restore 恢复上次保存的 DDR 配置" echo "" echo "示例:" echo " sudo $(basename $0) status"