用例子1发送,本例接收,运行窗口如下:
/*This IPv4 example listens for incoming packets and automatically adds destinationsfor new sources.本IPv4例子监听发送进来的数据包,并且自动为新的数据源添加目的端口*/
#include "rtpsession.h"#include "rtppacket.h"#include "rtpudpv4transmitter.h"#include "rtpipv4address.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>
using namespace jrtplib ;
//// This function checks if there was a RTP error. If so, it displays an error// message and exists.// 本函数检查是否有RTP错误,如果有,将其显示出来,并且退出
void checkerror ( int rtperr ){if ( rtperr < 0 ){std :: cout << "ERROR: " << RTPGetErrorString ( rtperr ) << std :: endl ;exit ( - 1 );}}
//// The new class routine// 一个新的继承自RTPSession的类
class MyRTPSession : public RTPSession{protected://有新的数据源,将对方的IP地址和端口自动添加到本类void OnNewSource ( RTPSourceData * dat ){if ( dat -> IsOwnSSRC ())return ;
uint32_t ip ;uint16_t port ;
if ( dat -> GetRTPDataAddress () != 0 ){const RTPIPv4Address * addr = ( const RTPIPv4Address * )( dat -> GetRTPDataAddress ());ip = addr -> GetIP ();port = addr -> GetPort ();}else if ( dat -> GetRTCPDataAddress () != 0 ){const RTPIPv4Address * addr = ( const RTPIPv4Address * )( dat -> GetRTCPDataAddress ());ip = addr -> GetIP ();port = addr -> GetPort () - 1 ;}elsereturn ;
RTPIPv4Address dest ( ip , port );AddDestination ( dest );//此处自动添加上数据源的IP地址和端口
struct in_addr inaddr ;inaddr . s_addr = htonl ( ip );std :: cout << "Adding destination " << std :: string ( inet_ntoa ( inaddr )) << ":" << port << std :: endl ;}
//收到BYE数据包(对方主动退出),则将对方ip地址和端口移除void OnBYEPacket ( RTPSourceData * dat ){if ( dat -> IsOwnSSRC ())return ;
uint32_t ip ;uint16_t port ;
if ( dat -> GetRTPDataAddress () != 0 ){const RTPIPv4Address * addr = ( const RTPIPv4Address * )( dat -> GetRTPDataAddress ());ip = addr -> GetIP ();port = addr -> GetPort ();}else if ( dat -> GetRTCPDataAddress () != 0 ){const RTPIPv4Address * addr = ( const RTPIPv4Address * )( dat -> GetRTCPDataAddress ());ip = addr -> GetIP ();port = addr -> GetPort () - 1 ;}elsereturn ;
RTPIPv4Address 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 ;}
//主动移除数据源,也应将对方的IP地址端口等删除void OnRemoveSource ( RTPSourceData * dat ){if ( dat -> IsOwnSSRC ())return ;if ( dat -> ReceivedBYE ())return ;
uint32_t ip ;uint16_t port ;
if ( dat -> GetRTPDataAddress () != 0 ){const RTPIPv4Address * addr = ( const RTPIPv4Address * )( dat -> GetRTPDataAddress ());ip = addr -> GetIP ();port = addr -> GetPort ();}else if ( dat -> GetRTCPDataAddress () != 0 ){const RTPIPv4Address * addr = ( const RTPIPv4Address * )( dat -> GetRTCPDataAddress ());ip = addr -> GetIP ();port = addr -> GetPort () - 1 ;}elsereturn ;
RTPIPv4Address 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 WIN32WSADATA dat ;WSAStartup ( MAKEWORD ( 2 , 2 ), & dat );#endif // WIN32
MyRTPSession sess ;uint16_t portbase ;std :: string ipstr ;int status , i , num ;
// 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 ;
// Now, we'll create a RTP session, set the destination// and poll for incoming data.// 现在,创建一个RTP会话,设置目的端点,并且轮询等待发送进来的数据
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.// 重要:本地的时间戳单位必须要设定,否则RTCP发送报告信息将会计算错误。本例中,我们就用每秒8000个样本。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 ();
// 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_THREADstatus = sess . Poll ();checkerror ( status );#endif // RTP_SUPPORT_THREAD
RTPTime :: Wait ( RTPTime ( 1 , 0 ));}
sess . BYEDestroy ( RTPTime ( 10 , 0 ), 0 , 0 );
#ifdef WIN32WSACleanup ();#endif // WIN32return 0 ;}
jrtplib3.9.1 example3
最新推荐文章于 2022-11-18 22:46:16 发布