From 5b0b6c1c65ea501a125c1fa6a6e455b4e38f6437 Mon Sep 17 00:00:00 2001 From: cxh Date: Fri, 9 Jan 2026 10:49:24 +0800 Subject: [PATCH] 1 --- src/rtmp_manager.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/rtmp_manager.cpp b/src/rtmp_manager.cpp index 525d26e..b03c4c4 100644 --- a/src/rtmp_manager.cpp +++ b/src/rtmp_manager.cpp @@ -52,36 +52,44 @@ std::string RTMPManager::make_key(const std::string& name) { return name + "_mai // ========== 创建 RTMP Pipeline ========== GstElement* RTMPManager::create_pipeline(const Camera& cam) { - const int gop = 15; - const std::string rtmp_url = "rtmp://127.0.0.1:1935/" + cam.name; std::string pipeline_str = "v4l2src device=" + cam.device + " io-mode=dmabuf " + // ⭐ 强制打时间戳(关键) + "! identity do-timestamp=true " + + // 原始 4:3 输入 "! video/x-raw,format=NV12,width=1280,height=960,framerate=30/1 " + // 裁成 16:9 "! videocrop top=120 bottom=120 " + // 缩放到目标分辨率 "! videoscale " "! video/x-raw,width=" + std::to_string(cam.width) + ",height=" + std::to_string(cam.height) + " " + // 缓冲(只在这里允许丢帧) "! queue max-size-buffers=12 max-size-time=0 leaky=downstream " + // 编码 "! mpph264enc rc-mode=cbr " "bps=" + std::to_string(cam.bitrate) + " " "gop=30 " - "header-mode=each-idr profile=main " + "header-mode=each-idr " + "profile=main " - "! h264parse config-interval=1 " + // 解析 + 帧探针位置 + "! h264parse name=parse config-interval=1 " "! video/x-h264,stream-format=avc,alignment=au " + // RTMP "! flvmux streamable=true " - "! rtmpsink location=\"" + rtmp_url + "\" " @@ -97,6 +105,7 @@ GstElement* RTMPManager::create_pipeline(const Camera& cam) g_error_free(error); return nullptr; } + return pipeline; } @@ -105,8 +114,8 @@ void RTMPManager::stream_loop(Camera cam, StreamContext* ctx) { const std::string key = make_key(cam.name); - constexpr int64_t START_TIMEOUT_MS = 12000; // ⭐ 启动宽限期 - constexpr int64_t NO_FRAME_TIMEOUT_MS = 10000; + constexpr int64_t START_TIMEOUT_MS = 12000; // 启动宽限 + constexpr int64_t NO_FRAME_TIMEOUT_MS = 15000; // 运行期宽限 while (ctx->thread_running) { @@ -129,7 +138,7 @@ void RTMPManager::stream_loop(Camera cam, StreamContext* ctx) ctx->last_frame_ms.store(0, std::memory_order_relaxed); - // ⭐ 帧探测挂在 h264parse + // ⭐ 帧探针挂在 h264parse src if (GstElement* parse = gst_bin_get_by_name(GST_BIN(pipeline), "parse")) { if (GstPad* pad = gst_element_get_static_pad(parse, "src")) @@ -187,9 +196,8 @@ void RTMPManager::stream_loop(Camera cam, StreamContext* ctx) else if (std::chrono::duration_cast(now - launch_tp).count() > START_TIMEOUT_MS) { - LOG_ERROR("[RTMP] " + key + " - no frames during startup"); - need_restart = true; - break; + // ⭐ 启动阶段允许慢,不重启 + LOG_WARN("[RTMP] " + key + " - no frames yet during startup (tolerated)"); } } else