diff --git a/src/rtmp_manager.cpp b/src/rtmp_manager.cpp index 6a8fc02..ca7a76a 100644 --- a/src/rtmp_manager.cpp +++ b/src/rtmp_manager.cpp @@ -104,45 +104,49 @@ GstElement* RTMPManager::create_pipeline(const Camera& cam) const std::string stream = cam.name + "_main"; const std::string app = "camera"; - // 维持你当前 SRS 的 vhost query 方式,避免改动联动太多 const std::string live_rtmp = "rtmp://36.153.162.171:19435/" + app + "/" + stream + "?vhost=live"; const std::string record_rtmp = "rtmp://127.0.0.1:2935/" + app + "/" + stream + "?vhost=record"; - // 关键:rtmpsink protocol=0 强制 IPv4(减少握手卡住/IPv6 干扰) - // 关键:valve 默认 drop=true,真正放行在 PLAYING 成功后再做(避免 cold-start 饿死) + // 关键调整: + // 1) v4l2src 后先只固定输入格式/原始分辨率,不强绑 framerate + // 2) 加 videorate,真正做降帧 + // 3) 在 mpph264enc 前再次明确 width/height/framerate,避免 encoder 拿到 0/1 + // 4) gop 适当放大,动态场景更稳一点 std::string pipeline_str = "v4l2src device=" + cam.device + " io-mode=dmabuf " - "! video/x-raw,format=NV12,width=1920,height=1080,framerate=" + - std::to_string(cam.fps) + - "/1 " + "! video/x-raw,format=NV12,width=1920,height=1080 " + "! videorate " "! videoscale " - "! video/x-raw,width=" + + "! video/x-raw,format=NV12,width=" + std::to_string(cam.width) + ",height=" + std::to_string(cam.height) + - " " + ",framerate=" + std::to_string(cam.fps) + + "/1 " "! queue max-size-buffers=2 leaky=downstream " "! mpph264enc rc-mode=cbr bps=" + - std::to_string(cam.bitrate) + " gop=" + std::to_string(cam.fps) + + std::to_string(cam.bitrate) + " gop=" + std::to_string(cam.fps * 2) + " header-mode=each-idr profile=baseline " "! h264parse config-interval=1 " "! tee name=t " // ===== record branch ===== - "t. ! queue max-size-buffers=8 leaky=downstream " + "t. ! queue max-size-buffers=2 leaky=downstream " "! valve name=record_valve drop=true " - "! queue max-size-buffers=8 leaky=downstream " + "! queue max-size-buffers=2 leaky=downstream " "! flvmux name=rec_mux streamable=true " "! rtmpsink name=rec_sink location=\"" + record_rtmp + "\" sync=false async=false " // ===== live branch ===== - "t. ! queue max-size-buffers=8 leaky=downstream " + "t. ! queue max-size-buffers=2 leaky=downstream " "! valve name=live_valve drop=true " - "! queue max-size-buffers=8 leaky=downstream " + "! queue max-size-buffers=2 leaky=downstream " "! flvmux name=live_mux streamable=true " "! rtmpsink name=live_sink location=\"" + live_rtmp + "\" sync=false async=false "; + LOG_INFO("[RTMP] pipeline: " + pipeline_str); + GError* err = nullptr; GstElement* pipeline = gst_parse_launch(pipeline_str.c_str(), &err); if (err)