最近被RTP的負載類型和時間戳搞郁悶了,一個問題調試了近一周,終於圓滿解決,回頭看看,發現其實主要原因還是自己沒有真正地搞清楚RTP協議中負載類型和時間戳的含義。雖然做RTP傳輸,有著Jrtplib和Ortp這兩個強大的庫支持,一個是c++接口,一個是c語言接口,各有各的特點,各有各的應用環境,但是僅僅有庫就能解決一切問題嗎?可能仿照著一些例子程序,你能夠完成主要的功能,但一旦問題發生了,不清楚原理你是很難定位和解決問題的,所以在此,用我的經驗勸勸大家,磨刀不誤砍柴工,做應用還是先把原理搞清楚再動手吧……
看這篇文章之前,首先你應該知道什麼是RTP協議,可以去看RTP協議原文RFC3550協議),也可以看一些網友對RTP協議的講解的文章,很多,這裡我提供一篇我個人覺得寫得還不錯的:http://blog.csdn.net/bripengandre/archive/2008/04/01/2238818.aspx 。
好,下面言歸正傳,首先談談RTP傳輸中的負載類型吧。
首先,看RTP協議包頭的格式:
10~16 Bit為PT域,指的就是負載類型PayLoad),負載類型定義了RTP負載的格式,協議原文說該域由具體應用決定其解釋。
目前,負載類型主要用來告訴接收端或者播放器)傳輸的是哪種類型的媒體例如G.729,H.264,MPEG-4等),這樣接收端或者播放器)才知道了數據流的格式,才會調用適當的編解碼器去解碼或者播放,這就是負載類型的主要作用。
就ORTP庫本文用的是ortp-0.9.1)而言,負載類型定義如下:
每一種負載類型都有著其獨特的參數,這裡基本上涵蓋了當前主流的一些媒體類型,例如pcmu 、g.729、h.263很奇怪,竟然沒有定義h.264,注:新版本已經添加了對h.264的支持)、mpeg-4等等。Jrtplib庫應該也有相類似的定義,你可以去找找源碼,在此我就不再贅述了。
在ORTP庫和JRTplib庫中,都提供了設置RTP負載類型的函數,千萬要記得根據實際的應用進行設置,我就是當時沒有注意,使用ORTP默認的pcmu音頻的負載類型,傳輸H.264編碼的視頻數據,結果傳輸中一直有問題,困擾我好久好久。
好了,再說說RTP的時間戳吧。
首先,了解幾個基本概念:
時間戳單位:時間戳計算的單位不是秒之類的單位,而是由采樣頻率所代替的單位,這樣做的目的就是為了是時間戳單位更為精准。比如說一個音頻的采樣頻率為8000Hz,那麼我們可以把時間戳單位設為1 / 8000。
時間戳增量:相鄰兩個RTP包之間的時間差以時間戳單位為基准)。
采樣頻率: 每秒鐘抽取樣本的次數,例如音頻的采樣率一般為8000Hz
幀率: 每秒傳輸或者顯示幀數,例如25f/s
再看看RTP時間戳課本中的定義:
RTP包頭的第2個32Bit即為RTP包的時間戳,Time Stamp ,占32位。
時間戳反映了RTP分組中的數據的第一個字節的采樣時刻。在一次會話開始時的時間戳初值也是隨機選擇的。即使是沒有信號發送時,時間戳的數值也要隨時間不斷的增加。接收端使用時間戳可准確知道應當在什麼時間還原哪一個數據塊,從而消除傳輸中的抖動。時間戳還可用來使視頻應用中聲音和圖像同步。
在RTP協議中並沒有規定時間戳的粒度,這取決於有效載荷的類型。因此RTP的時間戳又稱為媒體時間戳,以強調這種時間戳的粒度取決於信號的類型。例如,對於8kHz采樣的話音信號,若每隔20ms構成一個數據塊,則一個數據塊中包含有160個樣本0.02×8000=160)。因此每發送一個RTP分組,其時間戳的值就增加160。
官方的解釋看懂沒?沒看懂?沒關系,我剛開始也沒看懂,那就聽我的解釋吧。
首先,時間戳就是一個值,用來反映某個數據塊的產生采集)時間點的,後采集的數據塊的時間戳肯定是大於先采集的數據塊的。有了這樣一個時間戳,就可以標記數據塊的先後順序。 好了,關於RTP的負載類型和時間戳的介紹就到這裡了,這次通過解決RTP傳輸中的問題學到了不少知識,在此分享希望對大家有用。有說得不正確的地方歡迎高手指教,也可以來信交流:[email protected]
本文出自 “對影成三人” 博客,請務必保留此出處http://ticktick.blog.51cto.com/823160/350142