Debug: 视频15s延迟解决

This commit is contained in:
GuanYuankai 2025-10-27 01:19:46 +00:00
parent 07e692970f
commit 998991d7e5
1 changed files with 22 additions and 16 deletions

View File

@ -5,17 +5,14 @@
#include "rknn/rkYolov5s.hpp"
#include "rknn/rknnPool.hpp"
#include "spdlog/spdlog.h"
#include <chrono> // (新增) 用于计时
#include <algorithm> // (新增)
// (新增) 报警接口函数 (从 rkYolov5s.cc 移入)
#include <chrono>
#include <algorithm>
void VideoService::trigger_alarm(int person_id, const cv::Rect& box) {
printf("[ALARM] Intrusion detected! Person ID: %d at location (%d, %d, %d, %d)\n",
person_id, box.x, box.y, box.width, box.height);
// TODO: 在这里实现真正的报警逻辑,例如发送网络消息、写入数据库等。
}
// (新增) 获取当前时间的函数 (从 rkYolov5s.cc 移入)
double VideoService::get_current_time_seconds() {
return std::chrono::duration_cast<std::chrono::duration<double>>(
std::chrono::high_resolution_clock::now().time_since_epoch()
@ -249,47 +246,56 @@ void VideoService::draw_results(cv::Mat& frame)
// (关键修改) 彻底重写处理循环为 "一进一出" 模式
void VideoService::processing_loop() {
cv::Mat frame;
detect_result_group_t detection_results; // (修改) 存储推理结果
detect_result_group_t detection_results;
while (running_) {
auto t_start = std::chrono::high_resolution_clock::now();
if (!capture_.read(frame)) {
spdlog::warn("VideoService: Failed to read frame from capture. Stopping capture.");
running_ = false; // 停止循环
running_ = false;
break;
}
auto t_read = std::chrono::high_resolution_clock::now();
if (frame.empty()) {
continue;
}
// 1. (并行) 将原始帧放入池中进行推理
if (rknn_pool_->put(frame) != 0) {
spdlog::error("VideoService: Failed to put frame into rknnPool. Stopping.");
running_ = false;
break;
}
// 2. (串行) 立刻取回该帧的推理结果
// 这保证了 跟踪 和 绘图 总是按顺序在主线程中执行
if (rknn_pool_->get(detection_results) != 0) {
spdlog::error("VideoService: Failed to get frame from rknnPool. Stopping.");
running_ = false;
break;
}
// 3. (串行) 在主循环中更新唯一的跟踪器
auto t_infer = std::chrono::high_resolution_clock::now();
this->update_tracker(detection_results, frame.size());
// 4. (串行) 在主循环中将跟踪结果绘制到帧上
this->draw_results(frame);
// 5. (串行) 将处理和绘制完毕的帧推流
auto t_track_draw = std::chrono::high_resolution_clock::now();
if (writer_.isOpened()) {
writer_.write(frame);
}
// 打印详细耗时
auto t_write = std::chrono::high_resolution_clock::now();
// (新增) 打印耗时
double read_ms = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(t_read - t_start).count();
double infer_ms = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(t_infer - t_read).count();
double track_ms = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(t_track_draw - t_infer).count();
double write_ms = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(t_write - t_track_draw).count();
double total_ms = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(t_write - t_start).count();
printf("Loop time: Total=%.1fms [Read=%.1f, Infer=%.1f, Track=%.1f, Write=%.1f]\n",
total_ms, read_ms, infer_ms, track_ms, write_ms);
}
// (修改) 移除排空循环 (Draining loop)
// 新的 "一进一出" 逻辑不需要排空,退出即停止
spdlog::info("VideoService: Processing loop finished.");
}