我目前正在开发使用VP8和V4L2的视频流软件,但是我在帧评级的关键概念上苦苦挣扎。

我有一个基本的工作实现,可以循环获取帧,对其进行编码并通过RTP发送(尽可能快)。
但是,我不了解如何控制视频的帧频或调节采样。

基本上可以总结如下:

while (true) {
    ioctl(fd, VIDIOC_DQBUF, buf); // Get the V4L buffer
    vpx_codec_encode(...);        // VP8 encode using pts and timebase
    sendto();                     // Send through RTP with the correct timestamp
}


特别是,我不知道如何正确设置:


V4L2捕获循环(是否需要计时器以定期获取帧?)
V4L2中的FRAME INTERVAL设置(是强制性的吗?)
libvpx时基(我应该使用1 / fps吗?1001/30000吗?)
pts值(是否必须是帧号*(1 / fps)* 90000?)
RTP时间戳(我可以在此处使用pt吗?)
可以考虑的任何其他配置设置...

最佳答案

V4L2捕获循环(是否需要计时器以定期获取帧?)


要么,要么找到一种方法直到新数据到达之前阻塞线程(例如,使用select()


V4L2中的FRAME INTERVAL设置(是强制性的吗?)


这不是强制性的。设置FRAME_INTERVAL时,您告诉设备以指定的时间间隔对数据进行采样。
设备可能会简单地忽略该请求(例如,因为它无法以给定的采样率捕获)。
还请注意,设备的内部时钟可能不正确和/或与系统上的其他时钟不同。


libvpx时基(我应该使用1 / fps吗?1001/30000吗?)


显然,这取决于您的帧速率。

vpx-documentation在这里很清楚:


指示广告联盟使用的最小时间间隔(以秒为单位)
流。对于固定帧频材料或可变帧频材料
帧以给定时钟的倍数计时(例如:视频
捕获),则RECOMMENDED方法是将时基设置为
帧速率的倒数(例如:对于29.970 Hz NTSC为1001/30000)。这个
允许pt对应于帧号,这很方便。
要使用绝对时间时间戳对来自容器的视频进行重新编码,
建议的方法是将时基设置为父级的时基
容器或多媒体框架(例如:1/1000 for ms,如FLV中所示)。


由于时基的类型为vpx_rational,因此您需要将其表示为两个整数之间的比率。例如您不能将1/fps用作NTSC的怪异率。


pts值(是否必须是帧号*(1 / fps)* 90000?)


不完全不是(见上文)。它可以像frame_num一样简单。


RTP时间戳(我可以在此处使用pt吗?)


是。

07-24 09:28