RTP over TCP/UDP example in jrtplib

昨天写了一段rtp over tcp, 还没来得及调试,突然想起来jrtplib里会不会有现成的,进去一顿翻,靠,真有一个,🤮

 

https://research.edm.uhasselt.be/jori/page/Cs/JrtplibOld.html 

 

1) 安装库文件

_install.sh

cmake -DCMAKE_INSTALL_PREFIX=./_install
make
make install

 交叉编译

cmake -DCMAKE_INSTALL_PREFIX=./_install -DCMAKE_C_COMPILER=/usr/local/gcc-linaro-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -DCMAKE_CXX_COMPILER=/usr/local/gcc-linaro-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
make
make install

或者直接在根目录下的CMakeLists.txt文件首行加上

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_C_COMPILER "arm-linux-gnueabihf-gcc")
SET(CMAKE_CXX_COMPILER "arm-linux-gnueabihf-g++")
SET(CMAKE_INSTALL_PREFIX "./_INSTALL")

 

2) rtp over tcp

jrtplib-3.11.1/tests/tcptest.cpp

#include "rtpconfig.h"
#include "rtpsocketutil.h"
#include "rtpsocketutilinternal.h"
#include "rtpsession.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
#include "rtpsourcedata.h"
#include "rtptcpaddress.h"
#include "rtptcptransmitter.h"
#include "rtppacket.h"
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <vector>

using namespace std;
using namespace jrtplib;

inline void checkerror(int rtperr)
{
    if (rtperr < 0)
    {
        cerr << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
        exit(-1);
    }
}

class MyRTPSession : public RTPSession
{
public:
    MyRTPSession() : RTPSession() { }
    ~MyRTPSession() { }
protected:
    void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled)
    {
        printf("SSRC %x Got packet (%d bytes) in OnValidatedRTPPacket from source 0x%04x!\n", GetLocalSSRC(), 
               (int)rtppack->GetPayloadLength(), srcdat->GetSSRC());
        DeletePacket(rtppack);
        *ispackethandled = true;
    }

    void OnRTCPSDESItem(RTPSourceData *srcdat, RTCPSDESPacket::ItemType t, const void *itemdata, size_t itemlength)
    {
        char msg[1024];

        memset(msg, 0, sizeof(msg));
        if (itemlength >= sizeof(msg))
            itemlength = sizeof(msg)-1;

        memcpy(msg, itemdata, itemlength);
        printf("SSRC %x Received SDES item (%d): %s from SSRC %x\n", GetLocalSSRC(), (int)t, msg, srcdat->GetSSRC());
    }
};

class MyTCPTransmitter : public RTPTCPTransmitter
{
public:
    MyTCPTransmitter(const string &name) : RTPTCPTransmitter(0), m_name(name) { }

    void OnSendError(SocketType sock)
    {
        cout << m_name << ": Error sending over socket " << sock << ", removing destination" << endl;
        DeleteDestination(RTPTCPAddress(sock));
    }
    
    void OnReceiveError(SocketType sock)
    {
        cout << m_name << ": Error receiving from socket " << sock << ", removing destination" << endl;
        DeleteDestination(RTPTCPAddress(sock));
    }
private:
    string m_name;
};

void runTest(int sock1, int sock2)
{
    const int packSize = 1500;
    RTPSessionParams sessParams;
    MyTCPTransmitter trans1("Transmitter1"), trans2("Transmitter2");
    MyRTPSession sess1, sess2;

    sessParams.SetProbationType(RTPSources::NoProbation);
    sessParams.SetOwnTimestampUnit(1.0/packSize);
    sessParams.SetMaximumPacketSize(packSize + 64); // some extra room for rtp header

    bool threadsafe = false;
#ifdef RTP_SUPPORT_THREAD
    threadsafe = true;
#endif // RTP_SUPPORT_THREAD

    checkerror(trans1.Init(threadsafe));
    checkerror(trans2.Init(threadsafe));
    checkerror(trans1.Create(65535, 0));
    checkerror(trans2.Create(65535, 0));

    checkerror(sess1.Create(sessParams, &trans1));
    cout << "Session 1 created " << endl;
    checkerror(sess2.Create(sessParams, &trans2));
    cout << "Session 2 created " << endl;

    checkerror(sess1.AddDestination(RTPTCPAddress(sock1)));
    checkerror(sess2.AddDestination(RTPTCPAddress(sock2)));

    vector<uint8_t> pack(packSize);

    int num = 10;
    for (int i = 1 ; i <= num ; i++)
    {
        printf("\nSending packet %d/%d\n",i,num);
        
        // send a packet, alternating between a large packet and a zero length one
        //int len = (i%2 == 0)?pack.size():0;
        int len = 1500;
        checkerror(sess1.SendPacket((void *)&pack[0],len,0,false,10));

        //if (i == 10)
        //    RTPCLOSE(sock1); // Induce an error when sending/receiving

        // Either the background thread or the poll function itself will
        // cause the OnValidatedRTPPacket and OnRTCPSDESItem functions to
        // be called, so in this loop there's not much left to do. 

        sess2.BeginDataAccess();
        
        // check incoming packets
        if (sess2.GotoFirstSourceWithData())
        {
            do
            {
                RTPPacket *pack;
                
                while ((pack = sess2.GetNextPacket()) != NULL)
                {
                    // You can examine the data here
                    printf("Got packet !\n");
                    
                    // we don't longer need the packet, so
                    // we'll delete it
                    sess2.DeletePacket(pack);
                }
            } while (sess2.GotoNextSourceWithData());
        }
        
        sess2.EndDataAccess();
        
#ifndef RTP_SUPPORT_THREAD
        checkerror(sess1.Poll());
        checkerror(sess2.Poll());
#endif // RTP_SUPPORT_THREAD
        
        //RTPTime::Wait(RTPTime(1,0));
    }
    sess1.BYEDestroy(RTPTime(10,0),0,0);
    sess2.BYEDestroy(RTPTime(10,0),0,0);
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        cerr << "Usage: " << argv[0] << " portnumber" << endl;
        return -1;
    }

    // Create a listener socket and listen on it
    SocketType listener = socket(AF_INET, SOCK_STREAM, 0);
    if (listener == RTPSOCKERR)
    {
        cerr << "Can't create listener socket" << endl;
        return -1;
    }

    struct sockaddr_in servAddr;

    memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(atoi(argv[1]));

    if (bind(listener, (struct sockaddr *)&servAddr, sizeof(servAddr)) != 0)
    {
        cerr << "Can't bind listener socket" << endl;
        return -1;
    }

    listen(listener, 1);

    // Create a client socket and connect to the listener
    SocketType client = socket(AF_INET, SOCK_STREAM, 0);
    if (client == RTPSOCKERR)
    {
        cerr << "Can't create client socket" << endl;
        return -1;
    }

    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (connect(client, (struct sockaddr *)&servAddr, sizeof(servAddr)) != 0)
    {
        cerr << "Can't connect to the listener socket" << endl;
        return -1;
    }

    SocketType server = accept(listener, 0, 0);
    if (server == RTPSOCKERR)
    {
        cerr << "Can't accept incoming connection" << endl;
        return -1;
    }
    RTPCLOSE(listener);

    cout << "Got connected socket pair" << endl;

    runTest(server, client);

    cout << "Done." << endl;
    RTPCLOSE(server);
    RTPCLOSE(client);

    return 0;
}

build.sh

export LD_LIBRARY_PATH=$(pwd)/_install/lib:$LD_LIBRARY_PATH

rm ./example1 ./tcptest

g++ example1.cpp -I./_install/include -I./_install/include/jrtplib3 -L./_install/lib -g -o example1 -lpthread -ljrtp -lm
g++ tcptest.cpp -I./_install/include -I./_install/include/jrtplib3 -L./_install/lib -g -o tcptest -lpthread -ljrtp -lm

dong@ubuntu:~/jrtplib_example$ ./tcptest 15000
Got connected socket pair
Session 1 created
Session 2 created

Sending packet 1/10
SSRC fed93305 Got packet (1500 bytes) in OnValidatedRTPPacket from source 0xd244e47a!

Sending packet 2/10
SSRC fed93305 Got packet (1500 bytes) in OnValidatedRTPPacket from source 0xd244e47a!

Sending packet 3/10
SSRC fed93305 Got packet (1500 bytes) in OnValidatedRTPPacket from source 0xd244e47a!

Sending packet 4/10
SSRC fed93305 Got packet (1500 bytes) in OnValidatedRTPPacket from source 0xd244e47a!

Sending packet 5/10
SSRC fed93305 Got packet (1500 bytes) in OnValidatedRTPPacket from source 0xd244e47a!

Sending packet 6/10
SSRC fed93305 Got packet (1500 bytes) in OnValidatedRTPPacket from source 0xd244e47a!

Sending packet 7/10
SSRC fed93305 Got packet (1500 bytes) in OnValidatedRTPPacket from source 0xd244e47a!

Sending packet 8/10
SSRC fed93305 Got packet (1500 bytes) in OnValidatedRTPPacket from source 0xd244e47a!

Sending packet 9/10
SSRC fed93305 Got packet (1500 bytes) in OnValidatedRTPPacket from source 0xd244e47a!

Sending packet 10/10
Done.
dong@ubuntu:~/jrtplib_example$

 

将jrtplib-3.11.1/test2/tcptest.cpp拆分成发送和接收

tcptest1.cpp

#include "rtpconfig.h"
#include "rtpsocketutil.h"
#include "rtpsocketutilinternal.h"
#include "rtpsession.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
#include "rtpsourcedata.h"
#include "rtptcpaddress.h"
#include "rtptcptransmitter.h"
#include "rtppacket.h"
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
 
using namespace jrtplib;
 
int main()
{
    RTPSession session;
    RTPAbortDescriptors m_descriptors;
 
    RTPSessionParams sessionparams;
    sessionparams.SetAcceptOwnPackets(true);
    sessionparams.SetOwnTimestampUnit(1.0/10.0);
 
    m_descriptors.Init();
 
    RTPTCPTransmissionParams transparams;
    transparams.SetCreatedAbortDescriptors(&m_descriptors);
    int status = session.Create(sessionparams,&transparams,RTPTransmitter::TCPProto);
 
    if (status < 0)
    {
        //std::cerr << "[session.Create]" << QString::fromStdString(RTPGetErrorString(status));
        std::cout << "ERROR: " << RTPGetErrorString(status) << std::endl;
        return -1;
    }
 
    //初始化socket
    SocketType sockSrv = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addrSrv;
    addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");
    //addrSrv.sin_addr.s_addr = inet_addr("172.16.23.240");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(15000);
 
    //连接服务器
    connect( sockSrv, (struct sockaddr*)&addrSrv, sizeof(struct sockaddr));
 
    RTPTCPAddress addr(sockSrv);
 
    status = session.AddDestination(addr);
    if (status < 0)
    {
        //std::cerr << "session.AddDestination" << QString::fromStdString(RTPGetErrorString(status));
        std::cout << "ERROR: " << RTPGetErrorString(status) << std::endl;
        return -1;
    }
 
    session.SetDefaultPayloadType(96);
    session.SetDefaultMark(false);
    session.SetDefaultTimestampIncrement(160);
 
    //发送数据
    std::vector<uint8_t> pack(1500);
    int len = 1200;

    int num = 10;
    for (int i = 1 ; i <= num ; i++)
    {
        session.SendPacket((void *)&pack[0],len,0,false,10);
        //session.SendPacket((void *)&pack[0],len,0,false,10);
     
        //RTPTime delay(0.020);
        RTPTime::Wait(RTPTime(1,0));
    }
    //session.BYEDestroy(delay,"Client End",9);
    session.BYEDestroy(RTPTime(10,0),0,0);

    //RTPCLOSE(sock1); 
    RTPCLOSE(sockSrv);

    return 0;
}

tcptest2.cpp

#include "rtpconfig.h"
#include "rtpsocketutil.h"
#include "rtpsocketutilinternal.h"
#include "rtpsession.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
#include "rtpsourcedata.h"
#include "rtptcpaddress.h"
#include "rtptcptransmitter.h"
#include "rtppacket.h"
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <vector>

using namespace std;
using namespace jrtplib;

inline void checkerror(int rtperr)
{
    if (rtperr < 0)
    {
        cerr << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
        exit(-1);
    }
}

/*
class MyRTPSession : public RTPSession
{
public:
    MyRTPSession() : RTPSession() { }
    ~MyRTPSession() { }
protected:
    void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled)
    {
        printf("SSRC %x Got packet (%d bytes) in OnValidatedRTPPacket from source 0x%04x!\n", GetLocalSSRC(), 
               (int)rtppack->GetPayloadLength(), srcdat->GetSSRC());
        DeletePacket(rtppack);
        *ispackethandled = true;
    }


    void OnRTCPSDESItem(RTPSourceData *srcdat, RTCPSDESPacket::ItemType t, const void *itemdata, size_t itemlength)
    {
        char msg[1024];

        memset(msg, 0, sizeof(msg));
        if (itemlength >= sizeof(msg))
            itemlength = sizeof(msg)-1;

        memcpy(msg, itemdata, itemlength);
        printf("SSRC %x Received SDES item (%d): %s from SSRC %x\n", GetLocalSSRC(), (int)t, msg, srcdat->GetSSRC());
    }

};

class MyTCPTransmitter : public RTPTCPTransmitter
{
public:
    MyTCPTransmitter(const string &name) : RTPTCPTransmitter(0), m_name(name) { }

    
    void OnSendError(SocketType sock)
    {
        cout << m_name << ": Error sending over socket " << sock << ", removing destination" << endl;
        DeleteDestination(RTPTCPAddress(sock));
    }
    
    void OnReceiveError(SocketType sock)
    {
        cout << m_name << ": Error receiving from socket " << sock << ", removing destination" << endl;
        DeleteDestination(RTPTCPAddress(sock));
    }
private:
    string m_name;
};
*/

void runTest(/*int sock1, */int sock2)
{
    const int packSize = 1500;
    RTPSessionParams sessParams;
    //MyTCPTransmitter trans1("Transmitter1"), trans2("Transmitter2");
    RTPTCPTransmitter trans2 = RTPTCPTransmitter(0);
    //MyRTPSession sess1, sess2;
    RTPSession sess2;

    sessParams.SetProbationType(RTPSources::NoProbation);
    sessParams.SetOwnTimestampUnit(1.0/packSize);
    sessParams.SetMaximumPacketSize(packSize + 64); // some extra room for rtp header

    bool threadsafe = false;
#ifdef RTP_SUPPORT_THREAD
    threadsafe = true;
#endif // RTP_SUPPORT_THREAD

    //checkerror(trans1.Init(threadsafe));
    checkerror(trans2.Init(threadsafe));
    //checkerror(trans1.Create(65535, 0));
    checkerror(trans2.Create(65535, 0));

    //checkerror(sess1.Create(sessParams, &trans1));
    //cout << "Session 1 created " << endl;
    checkerror(sess2.Create(sessParams, &trans2));
    cout << "Session 2 created " << endl;

    //checkerror(sess1.AddDestination(RTPTCPAddress(sock1)));
    checkerror(sess2.AddDestination(RTPTCPAddress(sock2)));

    vector<uint8_t> pack(packSize);

    //int num = 10;
    //for (int i = 1 ; i <= num ; i++)
    while(1)
    {
        //printf("\nSending packet %d/%d\n",i,num);
        
        // send a packet, alternating between a large packet and a zero length one
        //int len = (i%2 == 0)?pack.size():0;
        //int len = 1500;
        //checkerror(sess1.SendPacket((void *)&pack[0],len,0,false,10));

        //if (i == 10)
        //    RTPCLOSE(sock1); // Induce an error when sending/receiving

        // Either the background thread or the poll function itself will
        // cause the OnValidatedRTPPacket and OnRTCPSDESItem functions to
        // be called, so in this loop there's not much left to do. 

        sess2.BeginDataAccess();
        
        // check incoming packets
        if (sess2.GotoFirstSourceWithData())
        {
            do
            {
                RTPPacket *pack;
                
                while ((pack = sess2.GetNextPacket()) != NULL)
                {
                    // You can examine the data here
                    printf("Got packet !\n");
                    
                    // we don't longer need the packet, so
                    // we'll delete it
                    sess2.DeletePacket(pack);
                }
            } while (sess2.GotoNextSourceWithData());
        }
        
        sess2.EndDataAccess();
        
#ifndef RTP_SUPPORT_THREAD
        //checkerror(sess1.Poll());
        checkerror(sess2.Poll());
#endif // RTP_SUPPORT_THREAD
        
        //RTPTime::Wait(RTPTime(1,0));
        //you need add timeout
    }
    //sess1.BYEDestroy(RTPTime(10,0),0,0);
    sess2.BYEDestroy(RTPTime(10,0),0,0);
}

int main(int argc, char *argv[])
{
    // Create a listener socket and listen on it
    SocketType listener = socket(AF_INET, SOCK_STREAM, 0);
    if (listener == RTPSOCKERR)
    {
        cerr << "Can't create listener socket" << endl;
        return -1;
    }

    struct sockaddr_in servAddr;

    memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(15000);

    if (bind(listener, (struct sockaddr *)&servAddr, sizeof(servAddr)) != 0)
    {
        cerr << "Can't bind listener socket" << endl;
        return -1;
    }

    listen(listener, 1);

    // Create a client socket and connect to the listener
    /*
    SocketType client = socket(AF_INET, SOCK_STREAM, 0);
    if (client == RTPSOCKERR)
    {
        cerr << "Can't create client socket" << endl;
        return -1;
    }

    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (connect(client, (struct sockaddr *)&servAddr, sizeof(servAddr)) != 0)
    {
        cerr << "Can't connect to the listener socket" << endl;
        return -1;
    }
    */
    SocketType server = accept(listener, 0, 0);
    if (server == RTPSOCKERR)
    {
        cerr << "Can't accept incoming connection" << endl;
        return -1;
    }
    RTPCLOSE(listener);

    cout << "Got connected socket pair" << endl;

    runTest(server);

    cout << "Done." << endl;
    RTPCLOSE(server);
    //RTPCLOSE(client);

    return 0;
}

build.sh

export LD_LIBRARY_PATH=$(pwd)/_install/lib:$LD_LIBRARY_PATH

rm ./tcptest ./tcptest1 ./tcptest2

g++ tcptest.cpp -I./_install/include -I./_install/include/jrtplib3 -L./_install/lib -g -o tcptest -lpthread -ljrtp -lm
g++ tcptest1.cpp -I./_install/include -I./_install/include/jrtplib3 -L./_install/lib -g -o tcptest1 -lpthread -ljrtp -lm
g++ tcptest2.cpp -I./_install/include -I./_install/include/jrtplib3 -L./_install/lib -g -o tcptest2 -lpthread -ljrtp -lm

tcp accept非阻塞模式需要改下socket配置

    SocketType listener = socket(PF_INET, SOCK_STREAM, 0);
    int flags = fcntl(listener, F_GETFL, 0);
    fcntl(listener, F_SETFL, flags | O_NONBLOCK);

要用这个代码就自己清理吧,我就是随手改的,也懒得整理了。

 

3)rtp over udp

jrtplib-3.11.1/example/example1.cpp

_build.sh

export LD_LIBRARY_PATH=$(pwd)/_install/lib:$LD_LIBRARY_PATH

rm ./test

g++ example1.cpp -I./_install/include/jrtplib3 -L./_install/lib -g -o test -ljrtp

 dong@ubuntu:~/sip/jrtplib/example$ ls
_build.sh  example1.cpp  _install  test
dong@ubuntu:~/sip/jrtplib/example$ ./test
Using version 3.11.1
Enter local portbase:
4000

Enter the destination IP address
127.0.0.1
Enter the destination port
4000

Number of packets you wish to be sent:
10

Sending packet 1/10

Sending packet 2/10
Got packet !

Sending packet 3/10
Got packet !

Sending packet 4/10
Got packet !

Sending packet 5/10
Got packet !

Sending packet 6/10
Got packet !

Sending packet 7/10
Got packet !

Sending packet 8/10
Got packet !

Sending packet 9/10
Got packet !

Sending packet 10/10
Got packet !
dong@ubuntu:~/sip/jrtplib/example$

 

将jrtplib-3.11.1/examples/example1.cpp拆分成发送和接收

send.cpp

/*
   Here's a small IPv4 example: it asks for a portbase and a destination and 
   starts sending packets to that destination.
*/

#include "rtpsession.h"
#include "rtpudpv4transmitter.h"
#include "rtpipv4address.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
#include "rtplibraryversion.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>

using namespace jrtplib;

void checkerror(int rtperr)
{
    if (rtperr < 0)
    {
        std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
        exit(-1);
    }
}

int main(void)
{
    
    RTPSession sess;
    uint16_t portbase = 3000;
    uint16_t destport = 4000;
    uint32_t destip;

    int status,i;
    int num = 10;

    destip = inet_addr("127.0.0.1");
    if (destip == INADDR_NONE)
    {
        std::cerr << "Bad IP address specified" << std::endl;
        return -1;
    }
    
    destip = ntohl(destip);
        
    RTPUDPv4TransmissionParams transparams;
    RTPSessionParams sessparams;
    
    sessparams.SetOwnTimestampUnit(1.0/10.0);            
    sessparams.SetAcceptOwnPackets(true);

    transparams.SetPortbase(portbase);

    status = sess.Create(sessparams,&transparams);    
    checkerror(status);
    
    RTPIPv4Address addr(destip,destport);    
    status = sess.AddDestination(addr);
    checkerror(status);
    
    for (i = 1 ; i <= num ; i++)
    {
        printf("\nSending packet %d/%d\n",i,num);
        
        // send the packet
        status = sess.SendPacket((void *)"1234567890",10,0,false,10);
        checkerror(status);        
        
        RTPTime::Wait(RTPTime(1,0));
    }
    
    sess.BYEDestroy(RTPTime(10,0),0,0);

    return 0;
}

recv.cpp

/*
   Here's a small IPv4 example: it asks for a portbase and a destination and 
   starts sending packets to that destination.
*/

#include "rtpsession.h"
#include "rtpudpv4transmitter.h"
#include "rtpipv4address.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
#include "rtplibraryversion.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>

using namespace jrtplib;

void checkerror(int rtperr)
{
    if (rtperr < 0)
    {
        std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
        exit(-1);
    }
}

int main(void)
{    
    RTPSession sess;
    uint16_t portbase = 4000;

    int status;
        
    RTPUDPv4TransmissionParams transparams;
    RTPSessionParams sessparams;
    
    sessparams.SetOwnTimestampUnit(1.0/10.0);        
    sessparams.SetAcceptOwnPackets(true);

    transparams.SetPortbase(portbase);

    status = sess.Create(sessparams,&transparams);    
    checkerror(status);
    
    while(1)
    {
        
        sess.BeginDataAccess();
        
        // check incoming packets
        if (sess.GotoFirstSourceWithData())
        {
            do
            {
                RTPPacket *pack;
                
                while ((pack = sess.GetNextPacket()) != NULL)
                {
                    // You can examine the data here
                    printf("Got packet !\n");
                    
                    // we don't longer need the packet, so
                    // we'll delete it
                    sess.DeletePacket(pack);
                }
            } while (sess.GotoNextSourceWithData());
        }
        
        sess.EndDataAccess();


#ifndef RTP_SUPPORT_THREAD
        status = sess.Poll();
        checkerror(status);
#endif // RTP_SUPPORT_THREAD

    }
    
    sess.BYEDestroy(RTPTime(10,0),0,0);

    return 0;
}

_build.sh

export LD_LIBRARY_PATH=$(pwd)/_install/lib:$LD_LIBRARY_PATH

rm ./send ./recv

g++ send.cpp -I./_install/include/jrtplib3 -L./_install/lib -g -o send -ljrtp
g++ recv.cpp -I./_install/include/jrtplib3 -L./_install/lib -g -o recv -ljrtp

 

4)jrtplib的rtp大小端问题

README.md里有一句话

- `RTP_BIG_ENDIAN`: If set, assume big-endian byte ordering.

CMakeLists.txt里有一段代码

if (CMAKE_CROSSCOMPILING)
    option (JRTPLIB_USE_BIGENDIAN "Target platform is big endian" ON)
    if (JRTPLIB_USE_BIGENDIAN)
        set(RTP_ENDIAN "#define RTP_BIG_ENDIAN")
    else (JRTPLIB_USE_BIGENDIAN)
        set(RTP_ENDIAN "// Little endian system")
    endif (JRTPLIB_USE_BIGENDIAN)
else (CMAKE_CROSSCOMPILING)
    test_big_endian(JRTPLIB_BIGENDIAN)
    if (JRTPLIB_BIGENDIAN)
        set(RTP_ENDIAN "#define RTP_BIG_ENDIAN")
    else (JRTPLIB_BIGENDIAN)
        set(RTP_ENDIAN "// Little endian system")
    endif (JRTPLIB_BIGENDIAN)
endif (CMAKE_CROSSCOMPILING)

从以上信息可以确认默认是大端模式

注释掉jrtplib-3.11.1/src/rtpconfig.h.in的56行就是小端模式

//${RTP_ENDIAN}

 

5) ERR_RTP_SESSION_CANTGETLOGINNAME

如果因为login不能创建会话,rtpsession.cpp文件的1593行直接填个root

    if (!gotlogin)
    {
        //char *logname = getenv("LOGNAME");
        const char *logname = "root";
        if (logname == 0)
            return ERR_RTP_SESSION_CANTGETLOGINNAME;
        strncpy((char *)buffer,logname,*bufferlength);
    }

 

参考文献

jrtplib-3.11.1/doc/jrtplib.h

jrtplib-3.11.1/tests/tcptest.cpp

jrtplib-3.11.1/example/example1.cpp

 

posted @ 2020-01-11 15:17  dong1  阅读(4725)  评论(0编辑  收藏  举报