jrtplib 分包處理
轉載自:http://blog.csdn.net/sxcong/article/details/3736354
聽說jrtplib寫的不錯,終于找到時間下來看看。
下載,直接用VC6編譯,很容易。
然后打開VC,建立工程,測試examples下那幾個收發程序,的確用起來很簡單。想想以前都是自己封裝UDP,現在的程序員真幸福。
不過,在發送視頻數據時出了問題,跟蹤進去看了一下,里面設置最大幀數據長度為1400。于是自己設置最大為32X1024,跟進去還不行。
原來是內部沒有分包處理,超過上限就不允許發了。
隨便搜了一個,有個叫SmartView的視頻會議源碼,是改寫jrtplib的RTPSession的SendPacket,在這里分包。很不錯的想法。
不過又一想,jrtplib,本身是做為lib提供的,雖然可以改寫其代碼,但肯定與作者初衷不符。
于是找到利用這個庫的同作者寫的開源項目emiplib,夠復雜的,把ffmpeg也集進來了。先不管,直接搜索關鍵字RTPSession和SendPacket,發現他發
送的是自己封裝的一個類MIPRTPSendMessage,其父類是MIPMessage??吹竭@想都不用想,作者肯定是在發送之前先進行了處理,形成了自己定義格式的Message再發送。
收到后在形成MIPRTPRecvMessage。這應該是是最正規的寫法。
不過,想想這個庫,雖然沒用過,但很多年前就聽人說過,肯定考慮過這些問題。沒有文件,就仔細看頭文件,終于發現了SendPacketEx這個函數,一大堆英文說明,
剛才沒仔細看:
/** Sends the RTP packet with payload /c data which has length /c len.
* The packet will contain a header extension with identifier /c hdrextID and containing data
* /c hdrextdata. The length of this data is given by /c numhdrextwords and is specified in a
* number of 32-bit words. The used payload type, marker and timestamp increment will be those that
* have been set using the /c SetDefault member functions.
*/
這回看清楚了吧,對,就是那個hdrextdata,是分包的數據,是長度,hdrextID是其ID。這樣,發送數據的時候,先分好包,再調用SendPacketEx就行了。
發送沒問題了,再說接收。也不看類結構了,參考亞歷山大方法,直接搜索recvfrom。在
RTPUDPv4Transmitter::PollSocket這里找到了,然后緊接就是RTPRawPacket *pack;pack = RTPNew(....
很好,收到后先封裝成了RTPRawPacket。但是,最終和用戶打交道的是RTPPacket,于是看它的頭文件,一眼就看到:
/** If a header extension is present, this function returns the extension identifier. */
uint16_t GetExtensionID() const { return extid; }
/** Returns the length of the header extension data. */
uint8_t *GetExtensionData() const { return extension; }
/** Returns the length of the header extension data. */
size_t GetExtensionLength() const { return extensionlength; }
對頭,這就是我們需要的。
但是,這三個值是怎么出現的呢?回頭再看從RTPRawPacket-->RTPPacket.
處理的過程看起來比較復雜,就先找外面的回調,應該在ProcessPolledData里面。
然后,看到了ProcessRawPacket(...),參數都不用看,從函數名就知道這是我們想要了解的東西了。其實不知道這個也沒關系,我們只需要調用上面那三個函數
就可以在外面重新組包了。
兩瓶酒的時間分析結束。不過只是聽說這個庫寫的不錯,隨手記下來看看,實在沒興趣動手用代碼來實現了。有哪位兄弟能寫出代碼附上就好了。
聽說jrtplib寫的不錯,終于找到時間下來看看。
下載,直接用VC6編譯,很容易。
然后打開VC,建立工程,測試examples下那幾個收發程序,的確用起來很簡單。想想以前都是自己封裝UDP,現在的程序員真幸福。
不過,在發送視頻數據時出了問題,跟蹤進去看了一下,里面設置最大幀數據長度為1400。于是自己設置最大為32X1024,跟進去還不行。
原來是內部沒有分包處理,超過上限就不允許發了。
隨便搜了一個,有個叫SmartView的視頻會議源碼,是改寫jrtplib的RTPSession的SendPacket,在這里分包。很不錯的想法。
不過又一想,jrtplib,本身是做為lib提供的,雖然可以改寫其代碼,但肯定與作者初衷不符。
于是找到利用這個庫的同作者寫的開源項目emiplib,夠復雜的,把ffmpeg也集進來了。先不管,直接搜索關鍵字RTPSession和SendPacket,發現他發
送的是自己封裝的一個類MIPRTPSendMessage,其父類是MIPMessage??吹竭@想都不用想,作者肯定是在發送之前先進行了處理,形成了自己定義格式的Message再發送。
收到后在形成MIPRTPRecvMessage。這應該是是最正規的寫法。
不過,想想這個庫,雖然沒用過,但很多年前就聽人說過,肯定考慮過這些問題。沒有文件,就仔細看頭文件,終于發現了SendPacketEx這個函數,一大堆英文說明,
剛才沒仔細看:
/** Sends the RTP packet with payload /c data which has length /c len.
* The packet will contain a header extension with identifier /c hdrextID and containing data
* /c hdrextdata. The length of this data is given by /c numhdrextwords and is specified in a
* number of 32-bit words. The used payload type, marker and timestamp increment will be those that
* have been set using the /c SetDefault member functions.
*/
這回看清楚了吧,對,就是那個hdrextdata,是分包的數據,是長度,hdrextID是其ID。這樣,發送數據的時候,先分好包,再調用SendPacketEx就行了。
發送沒問題了,再說接收。也不看類結構了,參考亞歷山大方法,直接搜索recvfrom。在
RTPUDPv4Transmitter::PollSocket這里找到了,然后緊接就是RTPRawPacket *pack;pack = RTPNew(....
很好,收到后先封裝成了RTPRawPacket。但是,最終和用戶打交道的是RTPPacket,于是看它的頭文件,一眼就看到:
/** If a header extension is present, this function returns the extension identifier. */
uint16_t GetExtensionID() const { return extid; }
/** Returns the length of the header extension data. */
uint8_t *GetExtensionData() const { return extension; }
/** Returns the length of the header extension data. */
size_t GetExtensionLength() const { return extensionlength; }
對頭,這就是我們需要的。
但是,這三個值是怎么出現的呢?回頭再看從RTPRawPacket-->RTPPacket.
處理的過程看起來比較復雜,就先找外面的回調,應該在ProcessPolledData里面。
然后,看到了ProcessRawPacket(...),參數都不用看,從函數名就知道這是我們想要了解的東西了。其實不知道這個也沒關系,我們只需要調用上面那三個函數
就可以在外面重新組包了。
兩瓶酒的時間分析結束。不過只是聽說這個庫寫的不錯,隨手記下來看看,實在沒興趣動手用代碼來實現了。有哪位兄弟能寫出代碼附上就好了。

