jrtplib的文檔翻譯

1 從RTPSession類開始session

全部的類和函數都是jrtplib名字空間的一部分,爲了簡化代碼,咱們聲明咱們使用的是以下的名字空間:dom

using namespace jrtplib;函數

爲了使用RTP,首先要建立一個RTPSession對象.這個構造函數接受兩個參數:一個RTPRandom類的實例,一個RTPMemoryManager類的實例.如今,咱們使用最簡單的默認的設置,以下:ui

RTPSession session;

1.1 建立Sessionspa

調用帶有三個參數的Create函數.線程

參數1指針

RTPSessionParams類型.指定這個session的大概的選項.這個類裏面的一個參數必需要設置好,不然session就會建立失敗.就是你要發送的數據的時間戳的單位,這個參數能夠用一個時間段內的採樣數去除以這個時間段的長度.所以,假設咱們要發送一個8000Hz的語音數據,能夠用以下的代碼:code

RTPSessionParams sessionParams;
sessionParams.SetOwnTimestampUnit(1.0/8000.0);

參數2對象

這個參數就真的取決於你想要一塊兒用的RTP profile.繼承

它是一個指向RTPTransmissionParams實例的指針,而且爲傳輸部分描述參數.

參數3

選擇要使用的傳輸組件,默認狀況下,使用UDP經過IPV4的transmitter,而且對於這個特定的transmitter,那麼參數2中的傳輸參數應該設爲RTPUDPv4TransmissionParams類型的.所以,假設咱們使用8000端口,咱們可使用以下的代碼:

RTPUDPv4TransmissionParams transparams;
 
 transparams.SetPortbase(8000);

如今咱們能夠調用RTPSession類的Create成員函數,代碼以下:

int status = session.Create(sessionparams,&transparams); if (status < 0)
 {
        std::cerr << RTPGetErrorString(status) << std::endl;
        exit(-1);
 }

若是Create函數出錯,那麼返回一個負值,它指出出錯了.能夠用RTPGetErrorString()函數來得到.

當session建立成功了,此時,要設置RTP和RTCP數據要發送的目的地.這是經過調用RTPSession的成員函數AddDestination來實現的.這個函數帶一個RTPAddress類型的參數,RTPAddress是一個抽象類,對於UDP經過IPV4的transmitter,真正的子類是RTPIPv4Address.假設把數據向運行在9000端口的進程發送,那麼代碼以下:

 uint8_t localip[]={127,0,0,1};
 RTPIPv4Address addr(localip,9000);

 status = session.AddDestination(addr); if (status < 0)
 {
        std::cerr << RTPGetErrorString(status) << std::endl;
        exit(-1);
 }

若是這個庫是用JThread支持編譯的,那麼收到的數據是在後臺處理的.如下兩種狀況:

A JThread支持沒有在編譯時使能

B 在session參數中指定不使用poll線程

下,必須使用RTPSession的成員函數Poll來處理到達的數據而且必要時發送RTCP數據.

如今,咱們先假定咱們使能了poll線程.

假設在一分鐘內,咱們想要發送包含20ms(160個採樣)的silence,而且咱們想要當一個從其餘地方來的包被接收的時候可以被指出來.一樣假定咱們有L8數據,而且要使用負荷類型爲96.首先,咱們將要設定一些默認值:

 session.SetDefaultPayloadType(96);
 session.SetDefaultMark(false);
 session.SetDefaultTimestampIncrement(160);

下一步,咱們要建立包含160個silence採樣的緩衝區,而且建立一個表示20ms的RTPTime實例.咱們也保存當前時間,這樣咱們能夠知道什麼時候1分鐘已經走完了.

uint8_t silencebuffer[160]; 
 for (int i = 0 ; i < 160 ; i++)
        silencebuffer[i] = 128;
 
 RTPTime delay(0.020);
 RTPTime starttime = RTPTime::CurrentTime();

下一步,是主循環.這個循環中,要發送一個包含160字節的負載數據.而後,數據處理開始進行,這個稍後闡述.最終,咱們等待20ms並檢測是否60s已通過去.

 bool done = false;
 while (!done)
 {
        status = session.SendPacket(silencebuffer,160);        
        if (status < 0)
        {
                std::cerr << RTPGetErrorString(status) << std::endl;
                exit(-1);
        }        
        //
        // Inspect incoming data here
        //
        
        RTPTime::Wait(delay);
        
        RTPTime t = RTPTime::CurrentTime();
        t -= starttime;        
        if (t > RTPTime(60.0))
                done = true;
 }

關於會話參與者的信息,以及得到包等的信息,都必須在調用成員函數BeginDataAccess和EndDataAccess之間完成.這樣能夠保證後臺線程不會在你在訪問數據的時候,同時改變你的數據.咱們逐個訪問會話的參與者經過GotoFirstSource和GotoNextSource成員函數.從當前選中的參與者中取得數據包,能夠經過成員函數GetNextPacket,這個函數能夠返回一個指向RTPPacket類的實例的指針.當你再也不須要這個packet的時候,你要delete它.處理到達的數據的過程能夠以下:

session.BeginDataAccess(); 
if (session.GotoFirstSource())
 {        
       do
        {
                RTPPacket *packet;                
                while ((packet = session.GetNextPacket()) != 0)
                {
                        std::cout << "Got packet with extended sequence number " 
                                  << packet->GetExtendedSequenceNumber() 
                                          << " from SSRC " << packet->GetSSRC() 
                                          << std::endl;
                        session.DeletePacket(packet);
                }
        } while (session.GotoNextSource());
 }
 session.EndDataAccess();

當前選中的源的信息能夠經過GetCurrentSourceInfo成員函數RTPSession類的來獲取.這個函數返回一個指針指向RTPSourceData的指針,這個對象包括了全部的關於source的信息:從那個源來的sender reports,receiver reports,SDES信息等等.

當主循環結束的時候,咱們發送一個BYE包來告訴其餘參與者咱們的分離,而且清理RTPSession類.一樣咱們須要等最多10s來讓BYE包被髮送出去,不然,咱們只是簡單地離開會話,而沒有發送BYE包.

 delay = RTPTime(10.0);
 session.BYEDestroy(delay,"Time's up",9);



2 錯誤碼

除非特意指定的,不然都是0或者正返回值表示成功,負值表示出錯.能夠用RTPGetErrorString獲取.

3 內存管理

能夠經過繼承RTPMemoryManager來寫本身的內存管理類.下面是一個簡化的實現代碼:

class MyMemoryManager : public RTPMemoryManager
 { public:
        MyMemoryManager() { }
        ~MyMemoryManager() { }        
        void *AllocateBuffer(size_t numbytes, int memtype)
        {                return malloc(numbytes);
        }        void FreeBuffer(void *p)
        {
                free(p);
        }
 };

在RTPSession類的構造函數中,能夠指定想要使用這個內存管理:

MyMemoryManager mgr;
 RTPSession session(0, &mgr);

此時,全部的內存分配和聲明均可以經過使用mgr的AllocateBuffer和FreeBuffer來完成.

相關文章
相關標籤/搜索