4

我目前正在使用 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 值(是否需要为 frame num * (1/fps) * 90000 ?)
  • RTP 时间戳(我可以在这里使用 pts 吗?)
  • 可以考虑的任何其他配置设置...
4

1 回答 1

1

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

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

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

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

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

显然这取决于你的帧率。

vpx 文档在这里很清楚:

指示流使用的最小时间间隔,以秒为单位。对于固定帧速率素材,或帧以给定时钟的倍数计时的可变帧速率素材(例如:视频捕获),推荐的方法是将时基设置为帧速率的倒数(例如:1001/30000对于 29.970 赫兹 NTSC)。这样可以让pts对应帧号,可以很方便。对于从具有绝对时间戳的容器重新编码视频,推荐的方法是将时基设置为父容器或多媒体框架的时基(例如:1/1000 用于 ms,如 FLV 中)。

由于 timebase 是 type vpx_rational,您需要将其表示为两个整数之间的比率。例如,您不能1/fps用于 NTSC 的怪异率。

pts 值(是否需要为 frame num * (1/fps) * 90000 ?)

不,不是真的(见上文)。它可以很简单frame_num

RTP 时间戳(我可以在这里使用 pts 吗?)

是的。

于 2013-07-27T14:06:59.670 回答