diff --git a/src/rtmp_manager.cpp b/src/rtmp_manager.cpp index 46422a0..3f1ca5c 100644 --- a/src/rtmp_manager.cpp +++ b/src/rtmp_manager.cpp @@ -115,33 +115,22 @@ GstElement* RTMPManager::create_pipeline(const Camera& cam) { const int fps = 30; const int bitrate = cam.bitrate; // 3.5M~4M - const int gop = 4; + const int gop = fps; // 建议:1 秒一个 IDR const std::string stream_name = cam.name; const std::string rtmp_url = "rtmp://127.0.0.1:1935/" + stream_name; - std::string pipeline_str = "v4l2src name=src device=" + cam.device + - " io-mode=dmabuf " + std::string pipeline_str = "v4l2src device=" + cam.device + + " io-mode=dmabuf do-timestamp=true " - // 原始 4:3 输入 + // ✅ 相机原生格式:完全匹配驱动 "! video/x-raw,format=NV12," - "width=1280,height=960," - "framerate=30/1 " + "width=1280,height=960,framerate=30/1 " - // ⭐ 裁成 16:9(上下各裁 120) - "! videocrop top=120 bottom=120 " + // ✅ 缓冲,只负责解耦,不丢帧 + "! queue max-size-buffers=4 max-size-time=0 max-size-bytes=0 " - // 可选:如果你想输出非 1280x720(比如 960x540) - "! videoscale " - "! video/x-raw," - "width=" + - std::to_string(cam.width) + ",height=" + std::to_string(cam.height) + - " " - - // 队列(建议后面再把 leaky 去掉) - "! queue max-size-buffers=2 max-size-time=0 leaky=downstream " - - // 编码 + // ✅ 硬件编码 "! mpph264enc " "rc-mode=cbr " "bps=" + @@ -150,17 +139,17 @@ GstElement* RTMPManager::create_pipeline(const Camera& cam) "gop=" + std::to_string(gop) + " " - "header-mode=each-idr " "profile=main " + "header-mode=each-idr " + // ✅ H.264 打包 "! h264parse config-interval=1 " "! video/x-h264,stream-format=avc,alignment=au " - "! flvmux streamable=true " + // ✅ FLV / RTMP + "! flvmux streamable=true " "! rtmpsink location=\"" + - rtmp_url + - "\" " - "sync=false async=false"; + rtmp_url + "\" sync=false async=false"; GError* error = nullptr; GstElement* pipeline = gst_parse_launch(pipeline_str.c_str(), &error);