如何定量测量源和显示器之间的 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 延迟? 的相关文章

随机推荐

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

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

    我在 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