This commit is contained in:
cxh 2025-12-17 15:40:48 +08:00
parent 38385c811c
commit 67742b59ee

View File

@ -24,6 +24,9 @@ std::mutex RTSPManager::mounted_factories_mutex;
std::unordered_map<std::string, std::vector<GstRTSPMedia*>> RTSPManager::media_map;
std::mutex RTSPManager::media_map_mutex;
static std::unordered_map<std::string, std::chrono::steady_clock::time_point> last_media_ts;
static std::mutex last_media_ts_mutex;
bool set_v4l2_format(const std::string& dev, int width, int height)
{
int fd = open(dev.c_str(), O_RDWR);
@ -119,7 +122,7 @@ 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());
// 先保持每个客户端独立 pipeline逻辑简单可靠
// 所有客户端共享同一个 pipeline避免频繁拉起 v4l2 / encoder
gst_rtsp_media_factory_set_shared(factory, TRUE);
// 客户端断开时不要乱 reset交给我们自己处理 / 或干脆不动
@ -136,13 +139,14 @@ void RTSPManager::start(const std::vector<Camera>& cams)
server = gst_rtsp_server_new();
gst_rtsp_server_set_service(server, "8554");
// ✅ 在 attach 之前设置 backlog限制 pending 连接队列)
gst_rtsp_server_set_backlog(server, 32);
loop = g_main_loop_new(nullptr, FALSE);
main_context = g_main_loop_get_context(loop);
// 先获取 mountpoints
GstRTSPMountPoints* mounts = gst_rtsp_server_get_mount_points(server);
// 在这里统一挂载所有 enabled 摄像头
for (const auto& cam : cams)
{
if (!cam.enabled) continue;
@ -185,9 +189,26 @@ void RTSPManager::start(const std::vector<Camera>& cams)
void RTSPManager::on_media_created(GstRTSPMediaFactory*, GstRTSPMedia* media, gpointer user_data)
{
const char* cam_name = static_cast<const char*>(user_data);
LOG_INFO(std::string("[RTSP] media-configure for camera: ") + cam_name);
// ✅ 只记录指针,不 g_object_ref生命周期归 gst-rtsp-server
bool suppressed = false;
auto now = std::chrono::steady_clock::now();
{
std::lock_guard<std::mutex> lock(last_media_ts_mutex);
auto& last = last_media_ts[cam_name];
if (last.time_since_epoch().count() != 0 && now - last < std::chrono::seconds(2))
{
suppressed = true; // 只标记,不 return
}
last = now;
}
if (suppressed) { LOG_WARN(std::string("[RTSP] media-configure suppressed (too frequent): ") + cam_name); }
else
{
LOG_INFO(std::string("[RTSP] media-configure for camera: ") + cam_name);
}
// ✅ 生命周期一定要完整绑定
{
std::lock_guard<std::mutex> lock(media_map_mutex);
media_map[cam_name].push_back(media);