2010-03-13 117 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。