c++ - Gstreamer H264 管道滞后

标签 c++ c gstreamer

我正在使用gst-rtsp-server具有以下管道:

gst_rtsp_media_factory_set_launch(factory, "( "
    "appsrc name=mysrc "
    "! videoconvert " 
    "! videoscale "
    "! video/x-raw,format=I420,width=350,height=250 " // fps
    "! x264enc bitrate=128 speed-preset=ultrafast tune=zerolatency byte-stream=true threads=4 key-int-max=15 intra-refresh=true "
    "! video/x-h264,profile=baseline "
    "! rtph264pay name=pay0 pt=96 mtu=1300 "
")");

传输 H264 视频流(我对 gstreamer 完全陌生)。我正在推送模式下运行:

g_object_set(appsrc, "stream-type", GST_APP_STREAM_TYPE_STREAM, NULL);

并且仅通过需求数据回调进行推送。大多数情况下一切都按预期进行。当我运行我的服务器时 - 我的摄像机流传输正常,只是我的流经历了 2 秒(大约)的延迟。

无论我使用任何设置组合,这种延迟都是一致的。

不同

  • 比特率
  • 相机分辨率
  • 以 4 fps 运行:GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1, GST_SECOND, 4);
  • 以 30 fps 运行:GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1, GST_SECOND, 30);

都具有相同的效果。就好像我的流累计了 2 秒的延迟,并且从那时起就永久偏移了。就好像 gstreamer 在开始广播之前将其内部缓冲区累积到特定大小。

由于我对 gstreamer 缺乏经验,我对此感到困惑。如果有人有任何想法或提示来指引我继续调试这个某个方向,我将不胜感激。


编辑:

为了完整性(以防其他人涉及这个问题),在 @peter 的指导下,我必须修改我的管道以适应 VLC 现在较小的缓冲区。我不知道这是否是“正确的方法”,但它对我有用。

我基本上让我的“制作者”(我的程序)以 60fps 进行制作,然后将其缩小到 30fps,以便使用 videorate 模块在管道中传输。这样我就可以为 VLC 提供 200 毫秒的缓冲。这是我的新管道。

gst_rtsp_media_factory_set_launch(factory, "( "
    "appsrc name=mysrc "
    "! videoconvert " 
    "! videoscale "
    "! videorate "
    "! video/x-raw,format=I420,width=350,height=250,framerate=30/1 " // fps
    "! x264enc bitrate=128 speed-preset=ultrafast tune=zerolatency byte-stream=true threads=4 key-int-max=15 intra-refresh=true "
    "! video/x-h264,profile=baseline "
    "! rtph264pay name=pay0 pt=96 mtu=1300 "
")");

再次感谢@peter。

最佳答案

您的发件人可能 100% 没问题。如果我是一个赌徒,我敢打赌问题出在接收器上。

一些接收器(如 VLC)会想要缓冲视频以防止卡顿。如果您的目标是减少延迟,我会查看您接收器上的选项,尽可能关闭这些选项。

编辑添加:

看看这个:http://www.groovypost.com/howto/change-vlc-streaming-buffer/ 默认情况下,VLC 有 1500 毫秒(1.5 秒)缓存。

关于c++ - Gstreamer H264 管道滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36819187/

相关文章:

c - fscanf C 生成 "program stopped working"

c - SSE 未对齐负载内在是否比 x64_64 Intel CPU 上的对齐负载内在慢?

android - Android 上的 GStreamer x264enc 和 SIGSEGV

video - 更改 USB 摄像头的比特率

ubuntu-12.04 - 使用 gstreamer 流式传输 h.264 视频

c++ - 使用 C++ 插件调用 Require

c++ - 将三位值存储到 unsigned char 数组

c# - 当我调用 DLL 中的函数时会发生什么

c++ - nullptr 和指针算法

c - 使用数组初始值设定项作为静态数组