我怎么能定量测量源和显示设备之间的GStreamer H264延迟?(How can I quant

2019-10-20 04:18发布

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

我们使用RTP,有效载荷96和libx264视频流(无音频)进行编码。

但现在我需要量化之间的等待时间(尽可能接近到)帧获取和显示。

有没有人有使用现有软件的建议?

理想情况下,我想能够运行测试软件了几个小时,以产生足够的统计数据来量化系统。 这意味着我不能在接收显示监视器做一次性测试象点源相机显示高的分辨率和手动计算差...

我当然知道,使用纯纯软件解决方案,我将无法量化的视频采集延迟(即CCD到帧缓冲)。

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

如果有帮助,该项目应用程序是用C ++,这样我就可以用C事件回调,如果他们提供,考虑在自定义标题嵌入系统时间(例如帧XYZ,在时间TTT编码 - 并使用相同的接收器上的信息来计算的差)。

Answer 1:

我已经写一个简单的应用,呈现连续的号码这样做过(说国防部60),并将其显示在屏幕上。 然后你就可以在监控点的摄像头,和你的客户端机器的一个渲染流第二个显示器。 带着你的手机照片,看看这两个数字的计算您的等待时间。



Answer 2:

该延迟时钟的项目已经给了我的注意,我认为它提供了一个更好的解决方案!

它嵌入的当前时间到图像缓冲的二进制表示,并且提取在该解码的二值图像。

显然,系统时钟必须同步!



Answer 3:

我有一个解决这个:我将它传递出去的H.264编码之前写道,节省了当一个帧被捕获(并就视频缓冲标记)的系统时间的GStreamer过滤器插件(基于插件模板)和网络传输。

在接收侧,我找到标记(其为我提供了20 1的索引),并再次注意系统时间。

我希望这将是一个相对简单的运动来进行关联指数和比较系统时间。 只要这两个系统的时钟是合理的同步(或具有已知的差异),我应该能够计算差值(即延迟)。

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

显然,在测试执行我不打算使用本地主机(127.0.0.1)!

我用的是--gst-plugin-path ,因为我还没有安装我的时间过滤器。

该项目需要尽可能小的等待时间 - 最好是100毫秒以下。 现在有一些数字,我就可以开始微调所需的参数,以减少等待时间。



文章来源: How can I quantitatively measure gstreamer H264 latency between source and display?