RTP programming routine Based on jrtplib

Source: Internet
Author: User

This example demonstrates how to use the jrtplib library to encapsulate the RTP protocol in Linux. This routine can be used as a basic routine for streaming media transmission.

Only the source code is provided here (these can be found in the official jrtplib files)

Sender:

/*
* Sending Program (for Windows and Linux)
* For IPv4-based transmission routines, a port number and destination address must be provided.
* Reference: http://blog.csdn.net/ipromiseu/article/details/4531656
*/
# Include "rtpsession. H" // defines some rtpsession implementations
# Include "rtppacket. H" // defines rtppacket packets
# Include "rtpudpv4transmitter. H" // defines the second parameter class of rtpsession
# Include "rtp00004address. H" // defines rtp00004address
# Include "rtpsessionparams. H" // defines the first parameter class of rtpsession.
# Include "rtperrors. H" // defines the error message in RTP.
# Ifndef Win32
# Include <netinet/in. h>
# Include <ARPA/inet. h>
# Else
# Include <winsock2.h>
# Endif // Win32
# Include <stdlib. h>
# Include <stdio. h>
# Include <iostream>
# Include <string>

// Check whether an RTP error occurs. If an error occurs, the error message is printed.
Void checkerror (INT rtperr)
{
If (rtperr <0)
{
STD: cout <"error:" <rtpgterrorstring (rtperr) <STD: Endl;
Exit (-1 );
}
}

// Main Loop
Int main (void)
{
// In Windows, We need to load the socket for the first time.
# Ifdef Win32
Wsadata dat;
Wsastartup (makeword (2, 2), & dat );
# Endif // Win32

Rtpsession sess;
// Rtpsession class to instantiate this RTP session
Uint16_t portbase, destport;
// Local port number, destination port number
Uint32_t destip;
// Destination IP address
STD: String ipstr;
Int status, I, num;

// Obtain required information first
STD: cout <"enter local portbase:" <STD: Endl;
STD: CIN> portbase;
STD: cout <STD: Endl;

STD: cout <"Enter the destination IP address" <STD: Endl;
STD: CIN> ipstr;
Destip = inet_addr (ipstr. c_str ());
If (destip = inaddr_none)
{
STD: cerr <"Bad IP address specified" <STD: Endl;
Return-1;
}

// Inet_addr returns a network-based byte sequence. What we need is a native byte sequence,
// You also need to use ntohl
Destip = ntohl (destip );

STD: cout <"Enter the destination port" <STD: Endl;
STD: CIN> destport;

STD: cout <STD: Endl;
STD: cout <"number of packets you wish to be sent:" <STD: Endl;
STD: CIN> num;

// Create an RTP session below to send incoming data packets
// This is the second parameter class of rtpsession. Its member function can set the listening port.
Rtpudpv4transmissionparams transparams;
// This is the first parameter class of rtpsession. Its member functions can be used to set an appropriate timestamp unit.
Rtpsessionparams sessparams;


// Set the appropriate timestamp unit. We need to send 10 times per second, so the parameter is 1.0/10.
Sessparams. setowntimestampunit (1.0/10.0 );
// Set whether to receive custom data packets.
Sessparams. setacceptownpackets (true );
// Set the local port
Transparams. setportbase (portbase );
// Initialize and create a RTP session
Status = sess. Create (sessparams, & transparams );
Checkerror (Status );
// Combine the destination address
Rtp00004address ADDR (destip, destport );
// Set the destination address and add the destination address for sending. Of course, you can add many addresses for multicast.
// You can also use deletedestination () and cleardestinations () to delete and clear the target address.
// It can also be written as unsigned long ADDR = ntohl (inet_addr ("127.0.0.1 "));
// Sess. adddestination (ADDR, 6000 );
Status = sess. adddestination (ADDR );
Checkerror (Status );

For (I = 1; I <= num; I ++)
{
Printf ("\ nsending packet % d/% d \ n", I, num );

// Send streaming media data. The first parameter is the sent data, the second parameter is the data length, followed by the RTP load type, identifier, and timestamp.
// Of course, jrtplib allows them to be set as the default parameter of the session. This is done by calling the setdefapaypayloadtype () and setdefaultmark methods of the rtpsession class. If this is done, we can send data like this:
// Status = sess. sendpacket (void *) "1234567890", 10 );
Status = sess. sendpacket (void *) "1234567890", false, 10 );
Checkerror (Status );

/*
Sess. begindataaccess ();
// The received message traverses all the data sources (because one RTP session allows multiple participants (sources ))
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

Rtptime: Wait (rtptime (1, 0 ));
}

Sess. byedestroy (rtptime (10, 0), 0, 0 );
// In Windows, we have finally uninstalled the socket.
# Ifdef Win32
Wsacleanup ();
# Endif // Win32
Return 0;
}
Acceptor:

/*
* Jrtplib data receiving routine
* Http://blog.sina.com.cn/s/blog_57e2e18901008s4h.html
*/

# Include "rtpsession. H"
# Include "rtppacket. H"
# Include "rtpudpv4transmitter. H"
# Include "rtp00004address. H"
# Include "rtpsessionparams. H"
# Include "rtperrors. H"
# Ifndef Win32
# Include <netinet/in. h>
# Include <ARPA/inet. h>
# Else
# Include <winsock2.h>
# Endif // Win32
# Include "rtpsourcedata. H"
# Include <stdlib. h>
# Include <stdio. h>
# Include <iostream>
# Include <string>

// Check for errors
Void checkerror (INT rtperr)
{
If (rtperr <0)
{
STD: cout <"error:" <rtpgterrorstring (rtperr) <STD: Endl;
Exit (-1 );
}
}

// Re-encapsulate a class
Class myrtpsession: Public rtpsession
{
Protected:
Void onnewsource (rtpsourcedata * dat)
{
If (dat-> isownssrc ())
Return;

Uint32_t IP address;
Uint16_t port;

If (dat-> getrtpdataaddress ()! = 0)
{
Const rtp00004address * ADDR = (const rtp00004address *) (dat-> getrtpdataaddress ());
IP = ADDR-> getip ();
Port = ADDR-> getport ();
}
Else if (dat-> getrtcpdataaddress ()! = 0)
{
Const rtp00004address * ADDR = (const rtp00004address *) (dat-> getrtcpdataaddress ());
IP = ADDR-> getip ();
Port = ADDR-> getport ()-1;
}
Else
Return;

Rtp00004address DEST (IP, Port );
Adddestination (DEST );

Struct in_addr inaddr;
Inaddr. s_addr = htonl (IP );
STD: cout <"adding destination" <STD: string (inet_ntoa (inaddr) <":" <port <STD: Endl;
}

Void onbyepacket (rtpsourcedata * dat)
{
If (dat-> isownssrc ())
Return;

Uint32_t IP address;
Uint16_t port;

If (dat-> getrtpdataaddress ()! = 0)
{
Const rtp00004address * ADDR = (const rtp00004address *) (dat-> getrtpdataaddress ());
IP = ADDR-> getip ();
Port = ADDR-> getport ();
}
Else if (dat-> getrtcpdataaddress ()! = 0)
{
Const rtp00004address * ADDR = (const rtp00004address *) (dat-> getrtcpdataaddress ());
IP = ADDR-> getip ();
Port = ADDR-> getport ()-1;
}
Else
Return;

Rtp00004address DEST (IP, Port );
Deletedestination (DEST );

Struct in_addr inaddr;
Inaddr. s_addr = htonl (IP );
STD: cout <"deleting destination" <STD: string (inet_ntoa (inaddr) <":" <port <STD: Endl;
}

Void onremovesource (rtpsourcedata * dat)
{
If (dat-> isownssrc ())
Return;
If (dat-> receivedbye ())
Return;

Uint32_t IP address;
Uint16_t port;

If (dat-> getrtpdataaddress ()! = 0)
{
Const rtp00004address * ADDR = (const rtp00004address *) (dat-> getrtpdataaddress ());
IP = ADDR-> getip ();
Port = ADDR-> getport ();
}
Else if (dat-> getrtcpdataaddress ()! = 0)
{
Const rtp00004address * ADDR = (const rtp00004address *) (dat-> getrtcpdataaddress ());
IP = ADDR-> getip ();
Port = ADDR-> getport ()-1;
}
Else
Return;

Rtp00004address DEST (IP, Port );
Deletedestination (DEST );

Struct in_addr inaddr;
Inaddr. s_addr = htonl (IP );
STD: cout <"deleting destination" <STD: string (inet_ntoa (inaddr) <":" <port <STD: Endl;
}
};

//
// The main routine
//

Int main (void)
{
# Ifdef Win32
Wsadata dat;
Wsastartup (makeword (2, 2), & dat );
# Endif // Win32

Myrtpsession sess;
Uint16_t portbase;
STD: String ipstr;
Int status, I, num;

Unsigned char * payloadpointer;
Int J, Len;
// First, we'll ask for the necessary information

STD: cout <"enter local portbase:" <STD: Endl;
STD: CIN> portbase;
STD: cout <STD: Endl;

STD: cout <STD: Endl;
STD: cout <"number of seconds you wish to wait:" <STD: Endl;
STD: CIN> num;


Rtpudpv4transmissionparams transparams;
Rtpsessionparams sessparams;

// Important: the local timestamp unit must be set, otherwise
// RTCP Sender report info will be calculated wrong
// In this case, we'll be just use 8000 samples per second.
Sessparams. setowntimestampunit (1.0/8000.0 );

Sessparams. setacceptownpackets (true );
Transparams. setportbase (portbase );
Status = sess. Create (sessparams, & transparams );
Checkerror (Status );

For (I = 1; I <= num; I ++)
{
Sess. begindataaccess ();

// Traverse all data sources
If (sess. gotofirstsourcewithdata ())
{
Do
{
Rtppacket * pack;

While (pack = sess. getnextpacket ())! = NULL)
{
// You can examine the data here
Printf ("got packet! \ N ");
Payloadpointer = pack-> getpayloaddata (); // get the Data Pointer
Len = pack-> getpayloadlength (); // obtain the Data Length

For (j = 0; j <Len; j ++)
{
Printf ("% C", * (payloadpointer + J); // print data
}

Printf ("\ n ");
// Delete the obtained data
Sess. deletepacket (pack );
}
} While (sess. gotonextsourcewithdata ());
}

Sess. enddataaccess ();

# Ifndef rtp_support_thread
Status = sess. Poll ();
Checkerror (Status );
# Endif // rtp_support_thread

Rtptime: Wait (rtptime (1, 0 ));
}

Sess. byedestroy (rtptime (10, 0), 0, 0 );

# Ifdef Win32
Wsacleanup ();
# Endif // Win32
Return 0;
}

Compile: G ++-O example1 example1.cpp-I/usr/local/include/jrtplib3/-ljrtp

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.