如何定量测量源和显示器之间的 gstreamer H264 延迟?

2024-01-06

我有一个项目,我们使用 gstreamer 、 x264 等将视频流通过本地网络多播到多个接收器(连接到显示器的专用计算机)。我们在视频源(摄像机)系统和显示监视器上使用 gstreamer。

我们使用 RTP、有效负载 96 和 libx264 来编码视频流(无音频)。

但现在我需要量化(尽可能接近)帧采集和显示之间的延迟。

有人对使用现有软件有建议吗?

理想情况下,我希望能够运行测试软件几个小时,以生成足够的统计数据来量化系统。这意味着我无法进行一次性测试,例如将源相机指向显示高分辨率的接收显示监视器并手动计算差异......

我确实意识到,使用纯软件解决方案,我将无法量化视频采集延迟(即 CCD 到帧缓冲区)。

我可以安排源系统和显示系统上的系统时钟高精度同步(使用 PTP),因此我将能够信任系统时钟(否则我将使用一些软件来跟踪系统时钟和显示系统时钟之间的差异)从测试结果中删除它)。

如果有帮助的话,项目应用程序是用 C++ 编写的,因此我可以使用 C 事件回调(如果可用)考虑在自定义标头中嵌入系统时间(例如,帧 xyz,在 TTT 时间编码 - 并使用相同的接收器上的信息来计算差异)。


我对此有一个解决方案: 我编写了一个 gstreamer 过滤器插件(基于插件模板),在将帧传递到 H.264 编码器和网络传输之前,它可以在捕获帧(并在视频缓冲区上做标记)时节省系统时间。

在接收端,我找到标记(它为我提供了 20 索引中的 1)并再次记下系统时间。

我希望关联索引和比较系统时间将是一个相对简单的练习。只要两个系统的时钟合理同步(或有已知的差异),我就应该能够计算出差异(即延迟)。

The filter->source在发送器和接收器上设置不同,以确定过滤器的定时行为。

/* chain function
 * this function does the actual processing
 */
static GstFlowReturn
gst_my_filter_chain (GstPad * pad, GstBuffer * buf)
{
  GstMyFilter *filter;
  struct timeval nowTimeval;
  guint8* data;
  int i,j,offset;

  filter = GST_MYFILTER (GST_OBJECT_PARENT (pad));

  if (filter->startTime == 0){
      filter->startTime = GST_BUFFER_TIMESTAMP(buf);
      gettimeofday(&filter->startTimeval, NULL);
      filter->startTimeUL = (filter->startTimeval.tv_sec*1e6 + filter->startTimeval.tv_usec)/1e3; // in milliseconds?
      filter->index = 0;

      GstCaps* caps;
      gint width, height;
      const GstStructure *str;

      caps = GST_BUFFER_CAPS(buf);
      str = gst_caps_get_structure (caps, 0);
      if (!gst_structure_get_int (str, "width", &width) ||
          !gst_structure_get_int (str, "height", &height)) {
        g_print ("No width/height available\n");
      } else {
        g_print ("The video size of this set of capabilities is %dx%d\n",
               width, height);  
        filter->width=width;
        filter->height=height;
      }
  }

  gettimeofday(&nowTimeval, NULL);
  unsigned long timeNow = (nowTimeval.tv_sec*1e6 + nowTimeval.tv_usec)/1e3; // in milliseconds?

  if (filter->silent == FALSE){
    fprintf(filter->ofp, "%20lu,",
            timeNow);
  }

    data = GST_BUFFER_DATA(buf);
    if (filter->source){
      offset = filter->index % 20;
      for (i = 0; i < 10; i++){
          for (j = 0; j < 10; j++){
              data[(i+20)*filter->width+(j+offset*10)*1]=23;
          }
      }
        fprintf(filter->ofp, " %u", offset);
    } else {
        unsigned long avg;
        unsigned int min=(unsigned int)(-1UL);
        unsigned int minpos=0;
        int k=0;

        for (k=0; k < 20; k++){
            avg=0;
            i=5; // in the middle of the box row
            for (j = 0; j < 10; j++){
              avg += data[(i+20)*filter->width+(j+k*10)*1];
            }
            if (avg < min){
                min = avg;
                minpos=k;
            }
        }
        fprintf(filter->ofp, " %u", minpos);
    }

    fprintf(filter->ofp, "\n");

  filter->index++;

  /* just push out the incoming buffer without touching it */
  return gst_pad_push (filter->srcpad, buf);
}

用法如下: 发送者/服务器:

GST_DEBUG="*:2"  gst-launch-0.10 -v --gst-plugin-path=../../src/.libs  videotestsrc num-buffers=100 ! myfilter src=1 ! x264enc tune=zerolatency,speed-preset=fast ! rtph264pay ! udpsink port=3000 host=127.0.0.1

接收者/客户端:

GST_DEBUG="*:2"  gst-launch-0.10 -v --gst-plugin-path=../../src/.libs udpsrc port=3000 ! "application/x-rtp, media=(string)video, encoding-name=(string)H264, payload=(int)96" ! gstrtpjitterbuffer do-lost=true !  rtph264depay  ! ffdec_h264 ! myfilter src=0 ! ffmpegcolorspace ! ximagesink

显然,在测试实现中我不会使用 localhost (127.0.0.1)!

我用--gst-plugin-path因为我还没有安装定时过滤器。

该项目要求延迟尽可能小——最好是 100 毫秒或更小。现在有了一些数字,我可以开始微调所需的参数以最小化延迟。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何定量测量源和显示器之间的 gstreamer H264 延迟? 的相关文章

  • 从 Android 上的 IP 摄像机接收视频流

    我有一个 IP 摄像机 它以 MJPEG 格式传输视频 现在我的目标是接收它并在我自己的自定义 Android 应用程序中显示它 为此 我在 Android 平台上提供了三种编程替代方案 使用内置的 Android MediaPlayer
  • 将多个视频合并为一个

    我有三个视频 用摄像机拍摄的讲座 讲座中使用的计算机的桌面捕获视频 和白板的视频 我想创建一个最终视频 其中这三个组件占据屏幕的特定区域 是否有开源软件可以让我做到这一点 mencoder ffmpeg virtualdub 你推荐哪一个
  • Videomixer 在源上失败,而不是在 Videotestsrc 上失败

    我想在一个视频文件中同时播放两个不同的本地视频文件 窗户 下面的代码在没有解复用器和解码器的情况下工作正常 static void play video GMainLoop loop GstElement pipeline videomix
  • Debian sid下RStudio安装失败:libgstreamer依赖问题

    我使用 Debian sid amd64 每周滚动更新一次 我最近从他们的官方网站下载了 RStudio 的桌面版本 0 99 902 并发布 当然 以 root 身份 dpkg i rstudio 0 99 902 amd64 deb 无
  • MFCreateFMPEG4MediaSink 不生成 MSE 兼容的 MP4

    我正在尝试将 H 264 视频源流式传输到网络浏览器 Media Foundation 用于编码分段的 MPEG4 流 MFCreateFMPEG4MediaSink with MFTranscodeContainerType FMPEG4
  • 时间戳和合成时间偏移

    H 264 缓冲区是否包含时间戳和解码时间戳信息 当我们获得 H 264 nalu 数据时 其中是否包含计时信息 如果您指的是原始 H 264 NAL 单元 那么它们不包含计时信息 如果指的是 PTS DTS 之类的内容 MKV MP4 T
  • 在 Windows 上为 python 2.7 安装 gstreamer 1.0。

    我一直在尝试在 Windows 上安装 gstreamer 1 0 以用作 python 2 7 模块 我从这里安装了sdkhttp docs gstreamer com display GstSDK Installing on Windo
  • H264解析-切片头检测

    我知道在 h264 中我们可以通过位模式检测 NAL 单元0x000001 是否有等效的方法来检测 NAL 单元中的切片标头 如何处理多切片 NAL 单元 目前我正在使用 h264 的解析代码并获取相应结构中的切片标头 切片头语法在第 36
  • 使用 Android MediaCodec 从摄像头编码 H.264

    我正在尝试让它在 Android 4 1 上运行 使用升级的 Asus Transformer 平板电脑 谢谢亚历克斯对我之前问题的回答 https stackoverflow com a 13420558 726156 我已经能够将一些原
  • 使用 gstreamer 进行低延迟音频捕获

    我需要在 Linux 上进行 几乎 实时音频捕获gstreamer 我的问题是我无法将延迟降低到约 210 毫秒以下 我尝试了从麦克风到耳机的简单环回 gst launch 1 0 pulsesrc alsasink gst launch
  • 警告:错误的管道:没有元素“x264enc”

    过去几天我一直在努力让它运行 我有一个需要 x264enc 的 gstreamer 命令 我正在运行一个Mac我似乎无法安装 x264 开发库 我已经安装了gst plugins bad但这没有帮助 我在论坛中读到 在安装之前我需要先安装
  • Html5 视频和 Flash 方法

    研究 HTML5 视频标签 并研究哪些浏览器支持哪些视频文件类型 我最初的想法是事情变得比仅仅使用 Flash 更困难 我想知道是否有人已经找到一些骨架代码 与视频的开发方法相结合 来执行以下操作 如果闪光灯可用 请使用它 如果没有 请尝试
  • C程序中包含的头文件的默认路径是什么?

    看看我是否在任何 c 文件中写入 include header h 然后它会在当前目录中搜索该文件 但是当我写的时候 include
  • 将 H.264 I 帧放入 AVSampleBufferDisplayLayer 但不显示视频图像

    在详细回顾了 WWDC2014 Session513 后 我尝试在 IOS8 0 上编写我的应用程序来解码和显示一个实时 H 264 流 首先 我成功构建了H264参数集 当我得到一个带有 4 位起始代码的帧时 就像 0x00 0x00 0
  • 学习 GObject 和 Glib 的材料 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我对 C 很满意 但需要学习GObject and Glib for gstreamer 我在网上找到
  • gstreamer gst-rtsp-server 是否接受 udpsrc (RTP)?

    我想将 RTP 流输入到 gstreamer gst rtsp server 中 对于初始测试 我使用来自 github 的 test launch c 示例 https github com GStreamer gst rtsp serv
  • Python 使用 Gstreamer 访问 USB 麦克风时遇到问题,以便在 Raspberry Pi 上使用 Pocketsphinx 执行语音识别

    所以Python的表现就好像它根本听不到我的麦克风发出的任何声音 问题就在这里 我有一个Python 2 7 假设使用的脚本Gstreamer通过以下方式访问我的麦克风并为我进行语音识别口袋狮身人面像 我在用着脉冲音频我的设备是树莓派 我的
  • 来自相机的 MediaCodec 视频流方向和颜色错误

    我正在尝试流式传输视频捕获直接从相机适用于 Android 设备 到目前为止 我已经能够从 Android 相机捕获每一帧预览帧 byte data Camera camera 函数 对数据进行编码 然后成功解码数据并显示到表面 我用的是安
  • 在 Ubuntu 中使用 Gstreamer 通过 RTP 协议流式传输 Mp4 视频

    我正在尝试从本地目录获取视频文件 启用来自服务器的流并从客户端捕获这些帧 我使用了以下管道 服务器端 gst launch v filesrc location home gokul Videos Econ TestVideo radioa
  • MediaCodec 创建输入表面

    我想使用 MediaCodec 将 Surface 编码为 H 264 使用 API 18 有一种方法可以通过调用 createInputSurface 然后在该表面上绘图来对表面中的内容进行编码 我在 createInputSurface

随机推荐

  • 我的搜索没有在谷歌地图中显示其标记有什么问题?

    我创建了一个地方搜索谷歌地图 喜欢搜索学校类型等地方 我为私立和公立学校做了标记 搜索框有效 但是当我单击输入时 它不显示公立 私立学校 是这是因为我的代码 在图标上 或标记 唯一的问题是当我单击输入时 它不显示其标记
  • 将连续日期分组在一起

    我在 Excel csv 中有一个请病假的 许多 员工列表 按以下格式列出 每个病假实例都有自己的线路 我想添加另一列 结果 它记录病期的长度 例如 Mon Tues Wed 表示这三个条目中的每一个都标有 3 我是Python新手 我想知
  • 将大型减速机拆分为较小的减速机

    我有一个称为动物的特征减速器 切片减速器 我想将这些减速器分成哺乳动物 鸟类 鱼类等 这部分很简单 因为我可以简单地使用ActionReducerMap 现在假设哺乳动物的减速器状态很大 我想将其分成几个较小的减速器 即猫的家族 狗的家族等
  • 之间有区别吗?和 * 在 cron 表达式中?奇怪的例子

    我的系统中有以下 cron 表达式 0 0 0 1 1 1 你知道吗 我不知道这意味着什么 写这篇文章的人在接下来的两周里正在度假 所以我必须亲自去了解一下 文档可以找到here https docs oracle com cd E1205
  • 递归函数中的全局变量如何保持为零?

    因此 如果我有一个带有全局变量 var 的递归函数 int var void foo if var 3 return else var foo 然后我有一个调用 foo 的函数 如下所示 void bar foo return 每次 foo
  • 在模拟器上运行 iOS 应用程序,无需构建应用程序

    我想知道是否可以在模拟器上 运行 Xcode 项目 而无需先 构建源代码 当我单击 Xcode 4 0 2 中的 运行 按钮时 它首先构建 然后运行它 是否可以在不构建的情况下运行 如果可能的话 你会怎么做 Edit 这听起来可能是一个奇怪
  • AngularJS 1.2 - ngAnimate 不工作

    我刚开始在 AngularJS 1 2 中使用 ng animate 我不确定为什么我的 ng animate 不能使用某个类名 但可以使用我在示例中看到的简单淡入淡出的默认值 在此示例中 我尝试将 ng animate 类设置为 动画 h
  • numba - guvectorize 只比 jit 快一点

    我试图并行化在许多独立数据集上运行的蒙特卡罗模拟 我发现 numba 的并行 guvectorize 实现仅比 numba jit 实现快 30 40 我找到了这些 1 https stackoverflow com questions 3
  • 如何每 5 分钟执行一次 cron 作业?

    JobDetail job1 JobBuilder newJob FirstJob class withIdentity job1 group1 build Trigger trigger1 TriggerBuilder newTrigge
  • 在 Moq 中为返回 void 的方法分配输出参数

    In 这个问题 https stackoverflow com questions 1068095 assigning out ref parameters in moq 我找到了一个这个答案 https stackoverflow com
  • 修改 Firebase - 动态链接的应用程序预览页面

    有人尝试过从 Firebase 修改此应用程序预览页面吗 我们为其中一个应用程序设置了动态链接并启用了预览页面 我们希望翻译默认字符串 有没有办法翻译一下这句话 保存我在应用程序中的位置 将复制链接以继续此操作 页 以及按钮上的文字 OK
  • 泛型构造函数的好处

    为非泛型类提供泛型构造函数有什么好处 Java 规范允许以下内容 class NonGeneric
  • 如果 isAvailableForServiceType 方法返回 NO 我该怎么办

    如果我能做什么isAvailableForServiceType例如 如果是 Twitter 方法会返回 NO if SLComposeViewController isAvailableForServiceType SLServiceTy
  • 是否可以使用 navigator.share 共享文件(PDF)而不是 url?

    我有一个从服务器生成的 pdf 文件 我希望允许用户通过 navigator share 共享该文件 是否可以共享文件而不是 URL navigator share title Web Fundamentals text Check out
  • 删除由于 gnuplot 中突然跳跃而导致的垂直线

    我正在尝试绘制一个包含 gnuplot 中不连续性的函数 结果 gnuplot 自动绘制一条连接跳跃不连续点的垂直线 我想删除这一行 我环顾四周 发现了两种解决方案 但都不起作用 一种解决方案是使用smooth unique绘图时 另一种是
  • 实际类型的值比较不正确

    我有领域REAL输入数据库 我使用 PostgreSQL 和查询 SELECT FROM my table WHERE my field 0 15 不返回包含以下值的行my field is 0 15 但例如查询 SELECT FROM m
  • VSCode 调试 C++:为什么流程不在断点处停止?

    VSCode 版本 1 3 1 操作系统版本 Ubuntu 14 04 我在 Ubuntu 14 04 上调试 C 项目 我运行 cmake 来生成可执行文件并设置 VSCode 配置文件 当我按F5调试时 程序运行良好 但没有停在断点处
  • 如何显示 Google 字体预览

    我正在将 Google 字体系列名称加载到选择列表中 当用户从列表中选择任何字体系列时 我会动态加载该字体 我的代码 get https www googleapis com webfonts v1 webfonts key functio
  • CakePHP 单元测试装置名称约定 啊?

    我一直在用头撞墙 试图找出为什么我的灯具无法正确加载 当我尝试运行测试时 会呈现我的布局 如果我注释掉该装置 测试就会正常运行 我已经把这个问题看了一百遍了 但我似乎看不出哪里出了问题 这是我的 Videosview test php Ap
  • 如何定量测量源和显示器之间的 gstreamer H264 延迟?

    我有一个项目 我们使用 gstreamer x264 等将视频流通过本地网络多播到多个接收器 连接到显示器的专用计算机 我们在视频源 摄像机 系统和显示监视器上使用 gstreamer 我们使用 RTP 有效负载 96 和 libx264