diff --git a/include/rtsp_manager.hpp b/include/rtsp_manager.hpp index 0010fe0..f35754d 100644 --- a/include/rtsp_manager.hpp +++ b/include/rtsp_manager.hpp @@ -19,6 +19,7 @@ public: static void mount_camera(const Camera &cam); static void unmount_camera(const Camera &cam); static bool is_streaming(const std::string &cam_name); + static bool is_any_streaming(); private: static GMainLoop *loop; diff --git a/src/main.cpp b/src/main.cpp index 786fb29..3599711 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -100,24 +100,16 @@ int main() if (ENABLE_RTSP_THREAD) { - while (!rtsp_thread_exited.load(std::memory_order_relaxed) && - std::chrono::steady_clock::now() < deadline) + RTSPManager::stop(); + + auto stop_deadline = std::chrono::steady_clock::now() + std::chrono::seconds(10); + while (RTSPManager::is_any_streaming() && std::chrono::steady_clock::now() < stop_deadline) { - std::this_thread::sleep_for(poll_interval); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } if (rtsp_thread.joinable()) - { - if (rtsp_thread_exited.load(std::memory_order_relaxed)) - { - rtsp_thread.join(); - LOG_INFO("[MAIN] RTSP thread finished and joined."); - } - else - { - LOG_WARN("[MAIN] RTSP thread did not exit within timeout."); - } - } + rtsp_thread.join(); } // 重置 MQTT 线程等待的截止时间 diff --git a/src/rtsp_manager.cpp b/src/rtsp_manager.cpp index 8dada87..7f5f31b 100644 --- a/src/rtsp_manager.cpp +++ b/src/rtsp_manager.cpp @@ -224,6 +224,29 @@ bool RTSPManager::is_streaming(const std::string &cam_name) // 停止 server void RTSPManager::stop() { + // 先卸载所有挂载摄像头 + std::vector cams_to_unmount; + { + std::lock_guard lock(mounted_factories_mutex); + for (const auto &kv : mounted_factories) + cams_to_unmount.push_back(kv.first); + } + + for (const auto &cam_name : cams_to_unmount) + { + Camera cam; + cam.name = cam_name; + unmount_camera(cam); + } + + // 等待所有流停止(最多 5 秒) + auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5); + while (is_any_streaming() && std::chrono::steady_clock::now() < deadline) + { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + + // 退出 main loop if (loop) { g_main_context_invoke(main_context, [](gpointer data) -> gboolean @@ -232,3 +255,13 @@ void RTSPManager::stop() return G_SOURCE_REMOVE; }, loop); } } + +// 新增接口:检查是否还有摄像头在流 +bool RTSPManager::is_any_streaming() +{ + std::lock_guard lock(mounted_factories_mutex); + for (const auto &kv : streaming_status) + if (kv.second) + return true; + return false; +}