first commit

This commit is contained in:
cxh 2025-09-09 13:38:23 +08:00
parent 76bdd6f77b
commit 014a5b4b6d

View File

@ -2,6 +2,7 @@
#include "rtsp_manager.hpp" #include "rtsp_manager.hpp"
#include "logger.hpp" #include "logger.hpp"
#include <iostream> #include <iostream>
#include <algorithm>
// 静态变量定义 // 静态变量定义
GMainLoop *RTSPManager::loop = nullptr; GMainLoop *RTSPManager::loop = nullptr;
@ -19,6 +20,7 @@ void RTSPManager::init()
LOG_INFO("[RTSP] GStreamer initialized."); LOG_INFO("[RTSP] GStreamer initialized.");
} }
// 创建 media factory
GstRTSPMediaFactory *RTSPManager::create_media_factory(const Camera &cam) GstRTSPMediaFactory *RTSPManager::create_media_factory(const Camera &cam)
{ {
std::string launch_str = std::string launch_str =
@ -32,13 +34,14 @@ GstRTSPMediaFactory *RTSPManager::create_media_factory(const Camera &cam)
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);
// 连接 media-created 信号,跟踪媒体对象 // 使用 media-configure 信号代替 media-created
g_signal_connect_data(factory, "media-created", G_CALLBACK(on_media_created), g_strdup(cam.name.c_str()), g_signal_connect_data(factory, "media-configure", G_CALLBACK(on_media_created),
(GClosureNotify)g_free, static_cast<GConnectFlags>(0)); g_strdup(cam.name.c_str()), (GClosureNotify)g_free, static_cast<GConnectFlags>(0));
return factory; return factory;
} }
// 启动 RTSP server
void RTSPManager::start(const std::vector<Camera> &cameras) void RTSPManager::start(const std::vector<Camera> &cameras)
{ {
server = gst_rtsp_server_new(); server = gst_rtsp_server_new();
@ -62,26 +65,31 @@ void RTSPManager::start(const std::vector<Camera> &cameras)
g_main_loop_unref(loop); g_main_loop_unref(loop);
loop = nullptr; loop = nullptr;
} }
LOG_INFO("[RTSP] Server stopped."); LOG_INFO("[RTSP] Server stopped.");
} }
// 媒体创建信号处理函数 // media-configure 信号处理
void RTSPManager::on_media_created(GstRTSPMediaFactory *factory, GstRTSPMedia *media, gpointer user_data) void RTSPManager::on_media_created(GstRTSPMediaFactory *factory, GstRTSPMedia *media, gpointer user_data)
{ {
const char *cam_name = static_cast<const char *>(user_data); const char *cam_name = static_cast<const char *>(user_data);
g_object_ref(media); // 增加引用计数,防止被提前销毁
{
std::lock_guard<std::mutex> lock(media_map_mutex); std::lock_guard<std::mutex> lock(media_map_mutex);
media_map[cam_name].push_back(media); media_map[cam_name].push_back(media);
g_object_ref(media); // 增加引用计数,防止意外销毁 }
// 连接 unprepared 信号,以便在媒体销毁时从列表中移除 // 连接 unprepared 信号,当 pipeline 被销毁时移除
g_signal_connect_data(media, "unprepared", G_CALLBACK(on_media_unprepared), g_signal_connect_data(media, "unprepared", G_CALLBACK(on_media_unprepared),
g_strdup(cam_name), (GClosureNotify)g_free, static_cast<GConnectFlags>(0)); g_strdup(cam_name), (GClosureNotify)g_free, static_cast<GConnectFlags>(0));
} }
// 媒体 unprepared 信号处理函数 // unprepared 信号处理
void RTSPManager::on_media_unprepared(GstRTSPMedia *media, gpointer user_data) void RTSPManager::on_media_unprepared(GstRTSPMedia *media, gpointer user_data)
{ {
const char *cam_name = static_cast<const char *>(user_data); const char *cam_name = static_cast<const char *>(user_data);
{
std::lock_guard<std::mutex> lock(media_map_mutex); std::lock_guard<std::mutex> lock(media_map_mutex);
auto it = media_map.find(cam_name); auto it = media_map.find(cam_name);
if (it != media_map.end()) if (it != media_map.end())
@ -93,7 +101,8 @@ void RTSPManager::on_media_unprepared(GstRTSPMedia *media, gpointer user_data)
media_map.erase(it); media_map.erase(it);
} }
} }
g_object_unref(media); // 释放我们在 on_media_created 中增加的引用 }
g_object_unref(media); // 释放引用
} }
// 挂载摄像头 // 挂载摄像头
@ -136,7 +145,7 @@ gboolean RTSPManager::mount_camera_in_main(gpointer data)
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
// 卸载摄像头(停止所有媒体会话) // 卸载摄像头
gboolean RTSPManager::unmount_camera_in_main(gpointer data) gboolean RTSPManager::unmount_camera_in_main(gpointer data)
{ {
Camera *cam = static_cast<Camera *>(data); Camera *cam = static_cast<Camera *>(data);
@ -145,11 +154,26 @@ gboolean RTSPManager::unmount_camera_in_main(gpointer data)
delete cam; delete cam;
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
std::string cam_name = cam->name; std::string cam_name = cam->name;
std::string mount_point = "/" + cam_name; std::string mount_point = "/" + cam_name;
// 卸载 factory自动断开客户端 // 停止所有媒体
{
std::lock_guard<std::mutex> lock(media_map_mutex);
auto it = media_map.find(cam_name);
if (it != media_map.end())
{
for (GstRTSPMedia *media : it->second)
{
gst_element_set_state(gst_rtsp_media_get_element(media), GST_STATE_NULL);
g_object_unref(media);
}
it->second.clear();
media_map.erase(it);
}
}
// 卸载 factory
GstRTSPMountPoints *mounts = gst_rtsp_server_get_mount_points(server); GstRTSPMountPoints *mounts = gst_rtsp_server_get_mount_points(server);
if (mounts) if (mounts)
{ {
@ -157,13 +181,6 @@ gboolean RTSPManager::unmount_camera_in_main(gpointer data)
g_object_unref(mounts); g_object_unref(mounts);
} }
// 清理 media_map
{
std::lock_guard<std::mutex> lock(media_map_mutex);
media_map.erase(cam_name);
}
// 释放 factory 对象
{ {
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);
@ -181,6 +198,7 @@ gboolean RTSPManager::unmount_camera_in_main(gpointer data)
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
// 公共挂载/卸载接口
void RTSPManager::mount_camera(const Camera &cam) void RTSPManager::mount_camera(const Camera &cam)
{ {
Camera *camCopy = new Camera(cam); Camera *camCopy = new Camera(cam);
@ -195,6 +213,7 @@ void RTSPManager::unmount_camera(const Camera &cam)
{ return RTSPManager::unmount_camera_in_main(data); }, camCopy); { return RTSPManager::unmount_camera_in_main(data); }, camCopy);
} }
// 是否正在流
bool RTSPManager::is_streaming(const std::string &cam_name) bool RTSPManager::is_streaming(const std::string &cam_name)
{ {
std::lock_guard<std::mutex> lock(mounted_factories_mutex); std::lock_guard<std::mutex> lock(mounted_factories_mutex);
@ -202,6 +221,7 @@ bool RTSPManager::is_streaming(const std::string &cam_name)
return it != streaming_status.end() ? it->second : false; return it != streaming_status.end() ? it->second : false;
} }
// 停止 server
void RTSPManager::stop() void RTSPManager::stop()
{ {
if (loop) if (loop)