JRTPLIB使用例項

2021-04-30 18:54:48 字數 5000 閱讀 8345

這幾天在看關於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...