diff --git a/src/rknn/video_service.cc b/src/rknn/video_service.cc index bc6d2b4..08cf2d3 100644 --- a/src/rknn/video_service.cc +++ b/src/rknn/video_service.cc @@ -5,17 +5,14 @@ #include "rknn/rkYolov5s.hpp" #include "rknn/rknnPool.hpp" #include "spdlog/spdlog.h" -#include // (新增) 用于计时 -#include // (新增) - -// (新增) 报警接口函数 (从 rkYolov5s.cc 移入) +#include +#include 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::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>(t_read - t_start).count(); + double infer_ms = std::chrono::duration_cast>(t_infer - t_read).count(); + double track_ms = std::chrono::duration_cast>(t_track_draw - t_infer).count(); + double write_ms = std::chrono::duration_cast>(t_write - t_track_draw).count(); + double total_ms = std::chrono::duration_cast>(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."); } \ No newline at end of file