Real-time transfer implementation based on the jrtplib library in Linux

Source: Internet
Author: User
Real-time transfer implementation based on the jrtplib library in Linux
I. RTP is a standard protocol and Key Technology for Real-Time Streaming Media transmission.
Real-Time Transport Protocol (PRT) is a network protocol used to process multimedia data streams over the Internet. It can be used in one-to-one (unicast, unicast) scenarios) or you can transmit streaming media data in real time in a one-to-multiple (Multi-play) network environment. RTP usually uses UDP for multimedia data transmission, but other protocols such as TCP or ATM can be used if necessary.
Protocol Analysis: Each RTP datagram consists of the header and payload. The meaning of the first 12 bytes of the header is fixed, the load can be audio or video data.

RTP is currently the best solution to the problem of real-time transmission of streaming media. To program real-time transmission on the Linux platform, you can consider using open-source RTP libraries, such as librtp and jrtplib. Jrtplib is an object-oriented RTP database. It fully complies with RFC 1889 and is a good choice in many cases. Jrtplib is a RTP Library implemented in C ++, this library uses the socket mechanism for network communication, so it can run on Windows, Linux, FreeBSD, Solaris, UNIX, and VxWorks.
Ii. jrtplib library usage and program implementation
(1) Use of the jrtplib Function
A. Before using jrtplib for Real-Time Streaming Media data transmission, you should first generate an rtpsession instance to represent the RTP session, and then call the CREATE () method to initialize it. The create () method of the rtpsession class has only one parameter to specify the port number used for this RTP session.
Rtpsession sess; sess. Create (5000 );

B. Setting an appropriate timestamp unit is another important task in the RTP Session Initialization Process. This is achieved by calling the settimestampunit () method of the rtpsession class, this method also has only one parameter, indicating the timestamp unit in seconds.
Sess. settimestampunit (1.0/8000.0 );

C. After the RTP session is successfully established, the streaming media data can be transmitted in real time. First, you need to set the destination address for data transmission. The RTP protocol allows multiple destination addresses for the same session. You can call the adddestination (), deletedestination (), and cleardestinations () of the rtpsession class () method. For example, the following statement indicates that the RTP session sends data to Port 6000 of the local host:

Unsigned long ADDR = ntohl (inet_addr ("127.0.0.1 "));
Sess. adddestination (ADDR, 6000 );
 
D. After specifying all target addresses, you can call the sendpacket () method of the rtpsession class to send streaming media data to all target addresses. Sendpacket () is an overload function provided by the rtpsession class.
For the same RTP Session, the load type, identifier, and timestamp increment are usually the same. jrtplib allows you to set them as the default parameters of the session. This is done by calling setdefaultpayloadtype () of the rtpsession class () setdefamark mark () and setdefatimetimestampincrement () methods. Setting these default parameters for RTP sessions can simplify data transmission. For example, if you set the default parameters for RTP sessions:

Sess. setdefapaypayloadtype (0 );
Sess. setdefamark mark (false );
Sess. setdefatimetimestampincrement (10 );
 

Then, when sending data, you only need to specify the data to be sent and its length:

Sess. sendpacket (buffer, 5 );

E. For the receiver of streaming media data, you must first call the polldata () method of the rtpsession class to receive the RTP or RTCP datagram sent. Since multiple participants (sources) are allowed in the same RTP session, you can call the gotofirstsource () and gotonextsource () Methods of the rtpsession class to traverse all sources, you can also use the gotofirstsourcewithdata () and gotonextsourcewithdata () Methods of the rtpsession class to traverse those sources with data. After the valid data source is detected from the RTP session, you can call the getnextpacket () method of the rtpsession class to extract the RTP datagram from it. After the received RTP datagram is processed, remember to release it in time.

Jrtplib defines three receiving modes for RTP datagram, each of which specifies which RTP datagram will be accepted and which RTP datagram will be rejected. You can set the following receiving modes by calling the setreceivemode () method of the rtpsession class:
? Receivemode_all: the default receiving mode. All received RTP data packets are accepted;
? Receivemode_ignoresome except some specific senders, all incoming RTP datagram data will be accepted, and the list of rejected senders can be called by addtoignorelist (), deletefromignorelist (), and clearignorelist () method;
? Receivemode_acceptsome except for some specific senders, all incoming RTP datagram data will be rejected, and the list of accepted senders can be called by addtoacceptlist (), deletefromacceptlist, and clearacceptlist () method. The following is a program example using the third receiving mode.
If (sess. gotofirstsourcewithdata ()){
Do {
Sess. addtoacceptlist (remoteip, allports, portbase );
Sess. setreceivemode (receivemode_acceptsome );
 
Rtppacket * pack;
Pack = sess. getnextpacket (); // process received data
Delete pack ;}
While (sess. gotonextsourcewithdata ());
}

(2) program flowchart
Sending: Obtain the IP address and port number of the receiving end to create an RTP session. Specify the RTP data receiving end. Set the default parameter of the RTP session to send streaming media data.
Receive: Get the user-specified port number, create RTP session, set the receiving mode, accept RTP data retrieval, RTP data source, get RTP datagram, delete RTP Datagram

Iii. Environment setup and compilation methods
(1) toolchain Installation
First find the xscale-arm-toolchain.tgz file, assuming that the package is under/tmp/
# Cd/
# Tar-zxvf/tmp/xscale-arm-toolchain.tgz
Set the environment variable
# Export Path =/usr/local/ARM-Linux/bin: $ path
Finally, check whether the cross-compilation tool is successfully installed.
# Arm-Linux-G ++ -- version
Check whether the arm-Linux-G ++ version is displayed. If yes, the installation is successful.
(2) Cross-compilation and installation of the jrtplib Library
First from the jrtplib website (Http://lumumba.luc.ac.be/jori/jrtplib/jrtplib.htmll) Download the latest source code package, which uses jrtplib-2.8.tar. If the downloaded source code package is placed under/tmp, run the following command to decompress it:
# Cd/tmp
# Tar-zxvf jrtplib-2.8.tar
Then configure and compile jrtplib.
# Cd jrtplib-2.8
#./Configure cc = arm-Linux-G ++ cross-compile = Yes
Modify makefile
Change the connection commands LD and AR to arm-Linux-LD and arm-Linux-ar.
# Make
Run the following command to install jrtplib:
# Make install
(3) program Compilation
A. Configure the compiling environment
You can use export or makefile. Makefile is used here.
Compile makeFile &:
Incl =-I/usr/local/include
Cflags =-pipe-O2-fno-strength-Reduce
Lflags =/usr/local/lib/libjrtp. A-L/usr/x11r6/lib
Libs =-lx11-lxext/usr/local/lib/libjrtp.
Cc = arm-Linux-G ++

Main: Main. o
$ (CC) $ (lflags) $ (incl)-O main. o $ (libs)
Main. O: Main. cpp

Clean:
Rm-F Main
Rm-f *. o
 
. Suffixes:. cpp
. Cpp. O:
$ (CC)-C $ (cflags) $ (incl)-o $ </* $ @ indicates the complete name of the target */
/* $ <Indicates the name of the first dependent file */
B. Compile
Assume that the sending and receiving programs are stored in the/tmp/send and/tmp/receive directories respectively.
# Cd/tmp/send
# Make
# Cd/tmp/receive
# Make

4. easy error and attention
1. Some basic standard header files cannot be found.
The main reason is that the toolchain path is not correctly installed and must be installed in strict accordance with the steps.
2. Some header files in the jrtplib library cannot be found.
In the jrtplib installation directory, no other directories can be found in the include path.
3. The recieve function cannot correctly extract the required data from the received data packets.
Since each RTP datagram consists of the header and payload, if getrawdata () is used to return the data of the entire data packet, it contains the type, format, serial number, timestamp, and additional data of the media to be transmitted. The getpayload () function returns the data sent. The two must be distinguished.
4. After the receivemode_acceptsome receiving mode is set, the receiver of the running program cannot receive packets.
The IP address format is incorrect. The iner_addr () and ntohl () functions need to use a pair. Otherwise, the parameter cannot be passed in and there is no value in the acceptance list. Of course, the data packet cannot be received.
5. The compilation is successful, but the receiving end cannot receive data during the test.
It may be that the receiver firewall is not disabled. Run:
# Iptables-F
It may be that the IP address is not properly configured. Run:
# Ifocnfig eth0 *. * netmask *.*.*.*
6. When using the jrtolib library, it is best to add the path of the library after include in the program.
V. Procedures

Send:

# Include <stdio. h>
# Include <string. h>
# Include "rtpsession. H"

// Error handling function
Void checkerror (int err)
{
If (ERR <0 ){
Char * errstr = rtpgeterrorstring (ERR );
Printf ("error: % S // n", errstr );
Exit (-1 );
}
}

Int main (INT argc, char ** argv)
{
Rtpsession sess;
Unsigned long destip;
Int destport;
Int portbase = 6000;
Int status, index;
Char buffer [128];

If (argc! = 3 ){
Printf ("Usage:./sender destip destport // n ");
Return-1;
}

// Obtain the IP address and port number of the acceptor.
Destip = inet_addr (argv [1]);
If (destip = inaddr_none ){
Printf ("Bad IP address specified. // n ");
Return-1;
}
Destip = ntohl (destip );
Destport = atoi (argv [2]);

// Create an RTP session
Status = sess. Create (portbase );
Checkerror (Status );

// Specify the RTP data receiving end
Status = sess. adddestination (destip, destport );
Checkerror (Status );

// Set the default parameters of the RTP session
Sess. setdefapaypayloadtype (0 );
Sess. setdefamark mark (false );
Sess. setdefatimetimestampincrement (10 );

// Send streaming media data
Index = 1;
Do {
Sprintf (buffer, "% d: RTP packet", index ++ );
Sess. sendpacket (buffer, strlen (buffer ));
Printf ("Send packet! // N ");
} While (1 );

Return 0;
}

Receive:

# Include <stdio. h>
# Include "rtpsession. H"
# Include "rtppacket. H"

// Error handling function
Void checkerror (int err)
{
If (ERR <0 ){
Char * errstr = rtpgeterrorstring (ERR );
Printf ("error: % S // n", errstr );
Exit (-1 );
}
}

Int main (INT argc, char ** argv)
{
Rtpsession sess;
Int localport, portbase;
Int status;
Unsigned long remoteip;
If (argc! = 4 ){
Printf ("Usage:./sender localport // n ");
Return-1;
}

// Obtain the user-specified port number

Remoteip = inet_addr (argv [1]);
Localport = atoi (argv [2]);
Portbase = atoi (argv [3]);
// Create an RTP session
Status = sess. Create (localport );
Checkerror (Status );

// Rtpheader * rtphdr;
Unsigned long timestamp1;
Unsigned char * rawdata;
Unsigned char temp [30];
Int lengh, I;
Bool allports = 1;

Sess. addtoacceptlist (remoteip, allports, portbase );

Do {
// Set the receiving mode
Sess. setreceivemode (receivemode_acceptsome );
Sess. addtoacceptlist (remoteip, allports, portbase );

// Accept RTP data
Status = sess. polldata ();


// Retrieve the RTP data source
If (sess. gotofirstsourcewithdata ()){
Do {

Rtppacket * packet;
// Obtain the RTP Datagram
While (packet = sess. getnextpacket ())! = NULL ){
Printf ("got packet! /N ");

Timestamp1 = packet-> gettimestamp ();
Lengh = packet-> getpayloadlength ();
Rawdata = packet-> getpayload ();

For (I = 0; I <lengh; I ++ ){
Temp [I] = rawdata [I];
Printf ("% C", temp [I]);
}
Temp [I] = '/0 ';
Printf ("timestamp: % d lengh = % d Data: % s/n", timestamp1, lengh, & temp );
// Delete the RTP Datagram

Delete packet;
}
} While (sess. gotonextsourcewithdata ());
}
} While (1 );

Return 0;
}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.