2010-03-13 469 views
6

我对h264 RTP数据包的时间戳有困惑。我知道我在SIP SDP中定义的视频挂钟频率是90KHz。我的编码器的帧速率不完全是30 FPS,它是可变的。它在飞行中从15 FPS到30 FPS不等。所以,我不能使用任何固定的时间戳。h264 RTP时间戳

任何人都可以告诉我下面的编码数据包的时间戳。
经过0毫秒编码后的RTP时间戳= 0(让开始时间戳0)
经过50毫秒编码后的RTP时间戳=?
经过40毫秒编码后的RTP时间戳=?
经过33毫秒编码后的RTP时间戳=?

当编码帧速率可变时,公式是什么?

预先感谢您。

回答

12

无论您的编码器是以10FPS还是30FPS编码视频,使用RTP时间戳,您都可以告诉接收器两帧之间的暂停时间。因此,您可以确定每一帧的动态。这样你可以在一秒内发送10帧(10fps),而在另一秒中,你可以发送30帧(30帧/秒)。您只需要正确设置RTP时间戳。如果我得到您的问题,您不确定如何做到这一点...

让开始时间戳为0,您添加挂钟时间以毫秒为单位乘以100到最后一个RTP时间戳,或者您可以使用你想要的任何时间尺度。为了使30fps的解码器解码10fps的视频,添加至333000 RTP时间戳每个包......但让我们看看你的例子:

Frame #  RTP Time Time between frames [ms] 
[ 1]    0 0 
[ 2]   50000 50 
[ 3]   90000 40 
[ 4]   420000 33 

所以,如果你设置RTP时间戳这样(Time in ms * 100000)你会做解码器负载并对帧1进行解码,然后对帧2进行加载和解码,但在帧2和帧2之间将会休眠50ms(帧1和帧2之间的时间差),依此类推...

而就你可以看到,解码器使用RTP时间戳来知道何时显示每一个,并且它不介意视频是以30或10fps编码的。另外,如果视频为30 fps,那并不意味着每秒钟会有30个RTP数据包。有时候可能会超过100个,所以你不能有一个公式来确保正确的RTP时间戳计算。

我想,这是你所需要的...希望我帮助,不要-1我,如果我没有...... =)

+1

这并不是说我清楚。我有一个[比特流(http://stackoverflow.com/questions/10562549/send-android-h264-capture-over-a-rtp-stream)在那里我试图解析NALU,并将它们发送trhough RTP。问题是我必须自己计算时间戳。目前我很确定我做错了(timestamp-lasttimestamp)* 100000。每次我从比特流中读取新的nalu时,我都会设置新的时间戳,但是这种形式会使得数据包和时间戳之间的时间戳发生变化,而数据包A的时间戳可能比数据包B更大! – FlaPer87 2012-05-15 10:54:01

+0

除了帧之间的时间差,RTP时间戳还会告诉绝对时间。 否则,它不能用于音频和视频之间的同步。 – 2018-01-08 20:13:55

+0

@RioWing不,您不能在32位整数字段中可靠地设置绝对64位时间值。这是更好地使之相对于0点是时间戳应该线性增加,相同的时间戳值应匹配AV帧,你应该保持时钟速率值考虑设置时间戳时,所以在1个AV第二个'last_frame_timestamp - first_frame_timestamp = CLOCK_RATE'。你有RTP扩展头来存储你想要的任何其他数据,比如正确的时间戳(ticks)等。 – Cipi 2018-01-09 14:49:47

2

目前对此没有简单的公式。

用于采样编码之前的帧的时刻被称为PTS(呈现时间戳)。它超出了编码器的范围,当捕获帧时,您必须在数据流中记住它。

从那里,你有2种可能性:

  1. 的H264编码器不产生B帧,则RTP时间戳应该是PTS +随机偏移(同样为所有流会话)
  2. 如果编码器生成B帧(或B片),则解码顺序需要修改,因为B帧需要解码下一帧,所以它必须先发送。

在后一种情况下,RFC6184指出您有多种方式来流式编码的NAL单元。

大多数流媒体软件都会使用称为“非交错”的模式,其中,您必须将RTP时间戳设置为PTS +偏移量,但将其按解码顺序发送,以便时间戳不会单调递增。 这也意味着客户端将不得不按接收到的顺序进行解码,而不是按照PTS顺序对帧进行重新排序。

我不使用术语DTS这里是有原因的,因为你并不需要为这个解码时间戳工作,只有顺序。

在RFC6184中描述的最后一个模式是所谓的交织序,您可以重新排序NAL单元。在这种情况下,您必须实现一些应用程序逻辑来重新排列单位,详情请参阅RFC6184。