first commit

This commit is contained in:
cxh 2025-09-09 11:31:11 +08:00
parent 9434ecdf92
commit e227a1f5e8
2 changed files with 45 additions and 8 deletions

View File

@ -35,4 +35,7 @@ private:
// --- 静态 mutex 和工厂表 --- // --- 静态 mutex 和工厂表 ---
static std::unordered_map<std::string, GstRTSPMediaFactory *> mounted_factories; static std::unordered_map<std::string, GstRTSPMediaFactory *> mounted_factories;
static std::mutex mounted_factories_mutex; static std::mutex mounted_factories_mutex;
// 新增bus 回调处理 EOS
static GstBusSyncReply bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer user_data);
}; };

View File

@ -28,6 +28,32 @@ GstRTSPMediaFactory *RTSPManager::create_media_factory(const Camera &cam)
GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new(); GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new();
gst_rtsp_media_factory_set_launch(factory, launch_str.c_str()); gst_rtsp_media_factory_set_launch(factory, launch_str.c_str());
gst_rtsp_media_factory_set_shared(factory, TRUE); 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<char*>(data);
std::lock_guard<std::mutex> 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<char*>(data);
}
return TRUE; }, new char[cam.name.size() + 1]{0});
gst_object_unref(bus);
}
return factory; return factory;
} }
@ -114,22 +140,30 @@ gboolean RTSPManager::unmount_camera_in_main(gpointer data)
} }
std::string mount_point = "/" + cam->name; std::string mount_point = "/" + cam->name;
gst_rtsp_mount_points_remove_factory(mounts, mount_point.c_str());
g_object_unref(mounts);
{ {
std::lock_guard<std::mutex> lock(mounted_factories_mutex); std::lock_guard<std::mutex> lock(mounted_factories_mutex);
auto it = mounted_factories.find(cam->name); auto it = mounted_factories.find(cam->name);
if (it != mounted_factories.end()) if (it != mounted_factories.end())
{ {
if (it->second) // 发送 EOS让 pipeline 停止
g_object_unref(it->second); GstRTSPMediaFactory *factory = it->second.factory;
mounted_factories.erase(it); if (factory)
{
GstElement *elem = gst_rtsp_media_factory_get_element(factory);
if (elem)
gst_element_send_event(elem, gst_event_new_eos());
}
// 标记 pending_unmount
it->second.pending_unmount = true;
} }
streaming_status[cam->name] = false;
} }
LOG_INFO("[RTSP] Camera '" + cam->name + "' unmounted."); // 从 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).");
delete cam; delete cam;
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }