這幾天在看關於jrtplib方面的東西。在網上看了不少文章,其中有很大部分使用的jrtplib版本在3.0以下。
語音傳送例項,希望有興趣的朋友一起參詳研究。
-------chuckgao
第一部分 jrtplib的編譯及安裝
無法正常編譯的情況,出現error: 'memcpy' was not declared in this scope的錯誤。這是由於jrtplib編
譯中無法找到memcpy這個函式。在網上有memcpy的patch。內容如下:
diff --git a/src/rtcpcompoundpacketbuilder.cpp b/src/rtcpcompoundpacketbuilder.cpp
index 8172007..8fd4510 100644
--- a/src/rtcpcompoundpacketbuilder.cpp
+++ b/src/rtcpcompoundpacketbuilder.cpp
@@ -30,6 +30,8 @@
*/+#include
+#include "rtcpcompoundpacketbuilder.h"
#include "rtcpsrpacket.h"
#include "rtcprrpacket.h"
diff --git a/src/rtppacket.cpp b/src/rtppacket.cpp
index b6d5fda..8c516c7 100644
--- a/src/rtppacket.cpp
+++ b/src/rtppacket.cpp
@@ -30,6 +30,8 @@
*/+#include
+#include "rtppacket.h"
#include "rtpstructs.h"
#include "rtpdefines.h"
+代表新增,-代表刪除相應內容
第二部分 jrtplib程式設計
下面先**一部分網上的指南,紅色標記是jrtplib-3.7修了後的使用方法
linux 下基於jrtplib庫的實時傳送實現
一、rtp 是進行實時流**傳輸的標準協議和關鍵技術
實時傳輸協議(real-time transport protocol,prt)是在 internet 上處理多**資料流的一種網路協議
,利用它能夠在一對一(unicast,單播)或者一對多(multicast,多播)的網路環境中實現傳流**資料的
實時傳輸。rtp 通常使用 udp 來進行多**資料的傳輸,但如果需要的話可以使用 tcp 或者 atm 等其它協
議。協議分析 :每乙個rtp資料報都由頭部(header)和負載(payload)兩個部分組成,其中頭部前 12 個位元組
rtp 是目前解決流**實時傳輸問題的最好辦法,要在 linux 平台上進行實時傳送程式設計,可以考慮使用
一些開放源**的 rtp 庫,如 librtp、jrtplib 等。jrtplib 是乙個物件導向的 rtp 庫,它完全遵循 rfc
1889 設計,在很多場合下是乙個非常不錯的選擇。jrtplib 是乙個用 c++ 語言實現的 rtp 庫,這個庫使用
作系統上。
二、jrtplib 庫的使用方法及程式實現
(1)jrtplib 函式 的使用
a、在使用 jrtplib 進行實時流**資料傳輸之前,首先應該生成 rtpsession 類的乙個例項來表示此次 rtp
會話,然後呼叫 create() 方法來對其進行初始化操作。rtpsession 類的 create() 方法只有乙個引數,用
來指明此次 rtp 會話所採用的埠號。
rtpsession sess; sess.create(5000);
jrtplib-3.7中已經修改了create(prot)方法。新的create方法被修改為crea(sessparams,&transparams)。其中的兩個引數需要如下先定義:
rtpudpv4transmissionparams transparams;
rtpsessionparams sessparams;
sessparams.setowntimestampunit(1.0/8000.0);/*設定時間戳,1/8000表示1秒鐘取樣8000次,即錄音時的8khz*/
sessparams.setacceptownpackets(true);
transparams.setportbase(portbase);/*本地通訊埠*/
b、設定恰當的時戳單元,是 rtp 會話初始化過程所要進行的另外一項重要工作,這是通過呼叫 rtpsession
類的 settimestampunit() 方法來實現的,前面已經提過。
c、當 rtp 會話成功建立起來之後,接下去就可以開始進行流**資料的實時傳輸了。首先需要設定好資料發
送的目標位址,rtp 協議允許同一會話存在多個目標位址,這可以通過呼叫 rtpsession 類的
adddestination()、deletedestination() 和 cleardestinations() 方法來完成。例如,下面的語句表示的
是讓 rtp 會話將資料傳送到本地主機的 6000 埠:
unsigned long addr = ntohl(inet_addr("127.0.0.1"));
sess.adddestination(addr, 6000);
d、目標位址全部指定之後,接著就可以呼叫 rtpsession 類的 sendpacket() 方法,向所有的目標位址傳送
流**資料。sendpacket() 是 rtpsession 類提供的乙個過載函式
對於同乙個 rtp 會話來講,負載型別、標識和時戳增量通常來講都是相同的,jrtplib 允許將它們設定為會
話的預設引數,這是通過呼叫 rtpsession 類的 setdefaultpayloadtype()、setdefaultmark() 和
setdefaulttimestampincrement() 方法來完成的。為 rtp 會話設定這些預設引數的好處是可以簡化資料的發
送,例如,如果為 rtp 會話設定了預設引數:
sess.setdefaultpayloadtype(0);
sess.setdefaultmark(false);
sess.setdefaulttimestampincrement(10);
之後在進行資料傳送時只需指明要傳送的資料及其長度就可以了:
sess.sendpacket(buffer, 5);
在真正的語音傳輸中,上面的buffer就是我們錄音時所得到的buffer。使用上面的函式可以簡單的傳送,但無法真正的實現rtp傳輸,我們需要呼叫另乙個介面:sess.sendpacket((void *)buffer,sizeof(buffer),0,false,8000);詳細的說明可以檢視jrtplib的說明文件。
e、對於流**資料的接收端,首先需要呼叫 rtpsession 類的 polldata() 方法來接收傳送過來的 rtp 或者
rtcp 資料報。
jrtplib-3.7中修改polldata()方法為poll(),使用都一樣
由於同乙個 rtp 會話中允許有多個參與者(源),你既可以通過呼叫 rtpsession 類的
gotofirstsource() 和 gotonextsource() 方法來遍歷所有的源,也可以通過呼叫 rtpsession 類的
gotofirstsourcewithdata() 和 gotonextsourcewithdata() 方法來遍歷那些攜帶有資料的源。在從 rtp 會
話中檢測出有效的資料來源之後,接下去就可以呼叫 rtpsession 類的 getnextpacket() 方法從中抽取 rtp 數
據報,當接收到的 rtp 資料報處理完之後,一定要記得及時釋放。
jrtplib 為 rtp 資料報定義了三種接收模式,其中每種接收模式都具體規定了哪些到達的 rtp 資料報將會被
接受,而哪些到達的 rtp 資料報將會被拒絕。通過呼叫 rtpsession 類的 setreceivemode() 方法可以設定
下列這些接收模式:
receivemode_all 預設的接收模式,所有到達的 rtp 資料報都將被接受;
receivemode_ignoresome 除了某些特定的傳送者之外,所有到達的 rtp 資料報都將被接受,而被拒絕
的傳送者列表可以通過呼叫 addtoignorelist()、deletefromignorelist() 和 clearignorelist() 方法來進
行設定;
receivemode_acceptsome 除了某些特定的傳送者之外,所有到達的 rtp 資料報都將被拒絕,而被接受
的傳送者列表可以通過呼叫 addtoacceptlist ()、deletefromacceptlist 和 clearacceptlist () 方法來進
行設定。 下面是採用第三種接收模式的程式示例。
if (sess.gotofirstsourcewithdata())
while (sess.gotonextsourcewithdata());
}完整的**中,首先需呼叫poll()方法接收rtp資料報,然後在begindataaccess()和enddataaccess()之間進行資料接收的操作。此時,我們設定程式一直do-while等待並處理資料 do
} while (sess_client.gotonextsourcewithdata());
//return 0; }
sess_client.enddataaccess();
}while(1);
(2)程式流程圖
傳送:獲得接收端的 ip 位址和埠號 建立 rtp 會話 指定 rtp 資料接收端 設定 rtp 會話 預設引數 傳送流**資料
接收:獲得使用者指定的埠號 建立rtp會話 設定接收模式 接受rtp資料 檢索rtp資料來源 獲取rtp資料報 刪除rtp資料報
因為是關於jrtplib的文章,所以貼出的錄音和放音**不多。需要的朋友可以留下郵箱。
jrtplib3 11 1使用摘錄
jrtplib 3.x中有兩種資料接收方式 1 使用jthread庫提供的執行緒自動在後台執行對資料的接收 2 不用jthread,使用者自己定期呼叫rtpsession中的poll方法 官方demo1,3,5,6中均可看到 1 實現自己的onrtppacket方法 該方法裡面不能直接釋放rtp包,...
jrtplib的編譯問題
在vc6下編譯jrtplib,但編譯example1.cpp時產生了很多錯誤,有以下幾種情況 1 use run time library的設定一定要統一。2 vc產生的workspace的debug setting,預設有個gz選項,catch release build errors in de...
交叉編譯jrtplib 問題
問題描述 1 安裝包 jrtplib 3.7.1.tar.gz jthread 1.2.1.tar.gz 2 步驟 分別解壓兩個安裝包 進入jthread 1.2.1使用.configure host arm linux cc arm linux gcc cxx arm linux g 命令配置 m...