diff --git a/src/rtsp_manager.cpp b/src/rtsp_manager.cpp index 9e276b3..82fb19f 100644 --- a/src/rtsp_manager.cpp +++ b/src/rtsp_manager.cpp @@ -24,6 +24,9 @@ std::mutex RTSPManager::mounted_factories_mutex; std::unordered_map> RTSPManager::media_map; std::mutex RTSPManager::media_map_mutex; +static std::unordered_map 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& 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& cams) void RTSPManager::on_media_created(GstRTSPMediaFactory*, GstRTSPMedia* media, gpointer user_data) { const char* cam_name = static_cast(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 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 lock(media_map_mutex); media_map[cam_name].push_back(media);