gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 03:14:40 33 4
gpt4 key购买 nike

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

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

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

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

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

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

我可以安排源系统和显示系统上的系统时钟同步到高精度(使用 PTP),这样我就可以信任系统时钟(否则我会使用一些软件来跟踪两者之间的差异系统时钟并将其从测试结果中删除)。

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

最佳答案

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

在接收方,我找到标记(它为我提供了 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 毫秒或更短。现在有了一些数字,我可以开始微调所需的参数以最大限度地减少延迟。

关于gstreamer - 如何定量测量源和显示器之间的 gstreamer H264 延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23869562/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com