RTP傳輸中的負載型別和時間戳

2021-07-22 08:25:31 字數 2282 閱讀 1577

最近被rtp的負載型別和時間戳搞鬱悶了,乙個問題除錯了近一周,終於圓滿解決,回頭看看,發現其實主要原因還是自己沒有真正地搞清楚rtp協議中負載型別和時間戳的含義。雖然做rtp傳輸,有著jrtplib和ortp這兩個強大的庫支援,乙個是c++介面,乙個是c語言介面,各有各的特點,各有各的應用環境,但是僅僅有庫就能解決一切問題嗎?可能仿照著一些例子程式,你能夠完成主要的功能,但一旦問題發生了,不清楚原理你是很難定位和解決問題的,所以在此,用我的經驗勸勸大家,磨刀不誤砍柴工,做應用還是先把原理搞清楚再動手吧……

看這篇文章之前,首先你應該知道什麼是rtp協議,可以去看rtp協議原文(rfc3550協議),也可以看一些網友對rtp協議的講解的文章,很多,這裡我提供一篇我個人覺得寫得還不錯的:

下面言歸正傳,首先談談rtp傳輸中的負載型別吧。

首先,看rtp協議包頭的格式:

10~16 bit為pt域,指的就是負載型別(payload),負載型別定義了rtp負載的格式,協議原文說該域由具體應用決定其解釋。

就ortp庫(本文用的是ortp-0.9.1)而言,負載型別定義如下:

每一種負載型別都有著其獨特的引數,這裡基本上涵蓋了當前主流的一些**型別,例如pcmu 、g.729、h.263(很奇怪,竟然沒有定義h.264,注:新版本已經新增了對h.264的支援)、mpeg-4等等。jrtplib庫應該也有相類似的定義,你可以去找找原始碼,在此我就不再贅述了。。

再說說rtp的時間戳吧。

首先,了解幾個基本概念:

時間戳單位:時間戳計算的單位不是秒之類的單位,而是由取樣頻率所代替的單位,這樣做的目的就是為了是時間戳單位更為精準。比如說乙個音訊的取樣頻率為8000hz,那麼我們可以把時間戳單位設為1 / 8000。

時間戳增量:相鄰兩個rtp包之間的時間差(以時間戳單位為基準)。

取樣頻率:每秒鐘抽取樣本的次數,例如音訊的取樣率:8000hz、44100hz、48000hz等

幀率:每秒傳輸或者顯示幀數,例如25f/s

再看看rtp時間戳課本中的定義:

rtp包頭的第2個32bit即為rtp包的時間戳,time stamp ,佔32位。

在rtp協議中並沒有規定時間戳的粒度,這取決於有效載荷的型別。因此rtp的時間戳又稱為**時間戳,以強調這種時間戳的粒度取決於訊號的型別。例如,對於8khz取樣的話音訊號,若每隔20ms構成乙個資料塊,則乙個資料塊中包含有160個樣本(0.02×8000=160)。因此每傳送乙個rtp分組,其時間戳的值就增加160。

官方的解釋看懂沒?沒看懂?沒關係,我剛開始也沒看懂,那就聽我的解釋吧。

首先,時間戳就是乙個值,用來反映某個資料塊的產生(採集)時間點的,後採集的資料塊的時間戳肯定是大於先採集的資料塊的。有了這樣乙個時間戳,就可以標記資料塊的先後順序。

第二,在實時流傳輸中,資料採集後立刻傳遞到rtp模組進行傳送,那麼,其實,資料塊的採集時間戳就直接作為rtp包的時間戳。

第三,如果用rtp來傳輸固定的檔案,則這個時間戳就是讀檔案的時間點,依次遞增。這個不再我們當前的討論範圍內,暫時不考慮。

第五,時間戳增量是指兩個rtp包之間的時間間隔,詳細點說,就是傳送第二個rtp包相距傳送第乙個rtp包時的時間間隔(單位是時間戳單位)。

如果取樣頻率為90000hz,則由上面討論可知,時間戳單位為1/90000,我們就假設1s鐘被劃分了90000個時間塊,那麼,如果每秒傳送25幀,那麼,每乙個幀的傳送佔多少個時間塊呢?當然是 90000/25 = 3600。因此,我們根據定義「時間戳增量是傳送第二個rtp包相距傳送第乙個rtp包時的時間間隔」,故時間戳增量應該為3600。

【補充】:最近思考了一下,又有了新的體會和解釋,可能對大家更容易地去理解這個時間戳增量會有所幫助,補充在下面吧:

其實,網路傳送重點關注的是流量的平衡,即均勻地利用網路頻寬,為了實現這一點,需要滿足:資料採集的速率與資料網路傳輸的速率盡量保持一致。時間戳增量的設定影響的是rtp包的網路傳輸的速率,時間戳增量越小,傳送速度越快。

下面再進一步解釋一下時間戳增量是怎麼計算出來的:

在jrtplib中好像不需要自己管理時間戳的遞增,由庫內部管理。但在ortp中每次資料的傳送都需要自己傳入時間戳的值,即自己需要每次發完乙個rtp包後,累加時間戳增量,不是很方便,這就需要自己對rtp的時間戳有比較深刻地理解,我剛開始就是因為沒搞清楚,隨時設定時間戳增量導致傳輸一直有問題,困擾我好久。

本文出自 「jhuster的專欄」 部落格,請務必保留此出處

談談RTP傳輸中的負載型別和時間戳

最近被rtp的負載型別和時間戳搞鬱悶了,乙個問題除錯了近一周,終於圓滿解決,回頭看看,發現其實主要原因還是自己沒有真正地搞清楚rtp協議中負載型別和時間戳的含義。雖然做rtp傳輸,有著 jrtplib和 ortp這兩個強大的庫支援,乙個是c 介面,乙個是c語言介面,各有各的特點,各有各的應用環境,但...

談談RTP傳輸中的負載型別和時間戳

最近被rtp的負載型別和時間戳搞鬱悶了,乙個問題除錯了近一周,終於圓滿解決,回頭看看,發現其實主要原因還是自己沒有真正地搞清楚rtp協議中負載型別和時間戳的含義。雖然做rtp傳輸,有著jrtplib和ortp這兩個強大的庫支援,乙個是c 介面,乙個是c語言介面,各有各的特點,各有各的應用環境,但是僅...

談談RTP傳輸中的負載型別和時間戳

最近被rtp的負載型別和時間戳搞鬱悶了,乙個問題除錯了近一周,終於圓滿解決,回頭看看,發現其實主要原因還是自己沒有真正地搞清楚rtp協議中負載型別和時間戳的含義。雖然做rtp傳輸,有著jrtplib和ortp這兩個強大的庫支援,乙個是c 介面,乙個是c語言介面,各有各的特點,各有各的應用環境,但是僅...