From 53dcd1b93ebff5421854a22440a8cafb0559425d Mon Sep 17 00:00:00 2001 From: cxh Date: Tue, 9 Sep 2025 11:34:17 +0800 Subject: [PATCH] first commit --- include/rtsp_manager.hpp | 8 ++---- src/rtsp_manager.cpp | 62 ++++++++++++---------------------------- 2 files changed, 20 insertions(+), 50 deletions(-) diff --git a/include/rtsp_manager.hpp b/include/rtsp_manager.hpp index 396c6de..83d9a26 100644 --- a/include/rtsp_manager.hpp +++ b/include/rtsp_manager.hpp @@ -1,4 +1,3 @@ -// rtsp_manager.hpp #pragma once #include @@ -28,14 +27,11 @@ private: // 工厂创建函数 static GstRTSPMediaFactory *create_media_factory(const Camera &cam); - // --- 把挂载/卸载函数变成私有静态成员 --- + // 挂载/卸载函数 static gboolean mount_camera_in_main(gpointer data); static gboolean unmount_camera_in_main(gpointer data); - // --- 静态 mutex 和工厂表 --- + // 静态 mutex 和工厂表 static std::unordered_map mounted_factories; static std::mutex mounted_factories_mutex; - - // 新增:bus 回调处理 EOS - static GstBusSyncReply bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer user_data); }; diff --git a/src/rtsp_manager.cpp b/src/rtsp_manager.cpp index 9019568..8ae3c31 100644 --- a/src/rtsp_manager.cpp +++ b/src/rtsp_manager.cpp @@ -28,32 +28,6 @@ GstRTSPMediaFactory *RTSPManager::create_media_factory(const Camera &cam) GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new(); gst_rtsp_media_factory_set_launch(factory, launch_str.c_str()); gst_rtsp_media_factory_set_shared(factory, TRUE); - - // 为 factory 添加 bus 监听 EOS - GstElement *element = gst_rtsp_media_factory_get_element(factory); - if (element) - { - GstBus *bus = gst_element_get_bus(element); - gst_bus_add_watch(bus, [](GstBus *bus, GstMessage *msg, gpointer data) -> gboolean - { - if(GST_MESSAGE_TYPE(msg) == GST_MESSAGE_EOS) - { - std::string cam_name = static_cast(data); - std::lock_guard lock(mounted_factories_mutex); - auto it = mounted_factories.find(cam_name); - if(it != mounted_factories.end() && it->second.pending_unmount) - { - if(it->second.factory) g_object_unref(it->second.factory); - mounted_factories.erase(it); - streaming_status.erase(cam_name); - LOG_INFO("[RTSP] Camera '" + cam_name + "' factory cleaned up after EOS."); - } - delete[] static_cast(data); - } - return TRUE; }, new char[cam.name.size() + 1]{0}); - gst_object_unref(bus); - } - return factory; } @@ -83,7 +57,7 @@ void RTSPManager::start(const std::vector &cameras) LOG_INFO("[RTSP] Server stopped."); } -// --- 静态成员实现 --- +// 挂载摄像头 gboolean RTSPManager::mount_camera_in_main(gpointer data) { Camera *cam = static_cast(data); @@ -123,6 +97,7 @@ gboolean RTSPManager::mount_camera_in_main(gpointer data) return G_SOURCE_REMOVE; } +// 卸载摄像头(发送 EOS 停止 pipeline) gboolean RTSPManager::unmount_camera_in_main(gpointer data) { Camera *cam = static_cast(data); @@ -133,37 +108,36 @@ gboolean RTSPManager::unmount_camera_in_main(gpointer data) } GstRTSPMountPoints *mounts = gst_rtsp_server_get_mount_points(server); - if (!mounts) + if (mounts) { - delete cam; - return G_SOURCE_REMOVE; + std::string mount_point = "/" + cam->name; + gst_rtsp_mount_points_remove_factory(mounts, mount_point.c_str()); + g_object_unref(mounts); } - std::string mount_point = "/" + cam->name; - { std::lock_guard lock(mounted_factories_mutex); auto it = mounted_factories.find(cam->name); if (it != mounted_factories.end()) { - // 发送 EOS,让 pipeline 停止 - GstRTSPMediaFactory *factory = it->second.factory; + GstRTSPMediaFactory *factory = it->second; if (factory) { - GstElement *elem = gst_rtsp_media_factory_get_element(factory); - if (elem) - gst_element_send_event(elem, gst_event_new_eos()); + // 创建 element 并发送 EOS + GstElement *element = gst_rtsp_media_factory_create_element(factory); + if (element) + { + gst_element_send_event(element, gst_event_new_eos()); + gst_object_unref(element); + } + g_object_unref(factory); } - // 标记 pending_unmount - it->second.pending_unmount = true; + mounted_factories.erase(it); } + streaming_status[cam->name] = false; } - // 从 mount points 立即移除,让客户端断流,但 factory 还保留 - gst_rtsp_mount_points_remove_factory(mounts, mount_point.c_str()); - g_object_unref(mounts); - - LOG_INFO("[RTSP] Camera '" + cam->name + "' unmount requested (EOS sent)."); + LOG_INFO("[RTSP] Camera '" + cam->name + "' unmounted."); delete cam; return G_SOURCE_REMOVE; }