天天看点

jrtplib3.9.1 example5

*转载时请注明出处。
 
 
  http://blog.csdn.net/str999_cn/article/details/28173559

 
 
  

 
 
  

 
 
      此代码执行时,如果只发送1个数据包,发送和接收完毕,会自动退出。没问题。但一旦发送的数据包等会或超过2个时,则程序执行时会无休无止地分配和释放,还没来得及去搞清为什么是这样的。
 
 
  

 
 
  

 
 
      执行图片如下:
 
 
  
        
jrtplib3.9.1 example5
jrtplib3.9.1 example5
/* This is a modified version of example1.cpp to illustrate the use of a memory manager. 这是对示例1的一个修改版本,用以展示内存管理的使用 */ #include "rtpsession.h" #include "rtppacket.h" #include "rtpudpv4transmitter.h" #include "rtpipv4address.h" #include "rtpsessionparams.h" #include "rtperrors.h" #include "rtpmemorymanager.h" #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> 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 ); } } #ifdef RTP_SUPPORT_THREAD //此处定义了RTP_SUPPORT_THREAD,会用到jthread这个单独的库。所以多定义了一个JMutex mutex;在进行内存分配和释放的时候,需要加锁和解锁。 using namespace jthread ; class MyMemoryManager : public RTPMemoryManager { public: MyMemoryManager () { mutex . Init (); alloccount = 0 ; freecount = 0 ; } ~ MyMemoryManager () { std :: cout << "alloc: " << alloccount << " free: " << freecount << std :: endl ; } void * AllocateBuffer ( size_t numbytes , int memtype ) { mutex . Lock (); void * buf = malloc ( numbytes ); std :: cout << "Allocated " << numbytes << " bytes at location " << buf  << " (memtype = " << memtype << ")" << std :: endl ; alloccount ++ ; mutex . Unlock (); return buf ; } void FreeBuffer ( void * p ) { mutex . Lock (); std :: cout << "Freeing block " << p << std :: endl ; freecount ++ ; free ( p ); mutex . Unlock (); } private: int alloccount , freecount ; JMutex mutex ; }; #else class MyMemoryManager : public RTPMemoryManager { public: MyMemoryManager () { alloccount = 0 ; freecount = 0 ; } ~ MyMemoryManager () { std :: cout << "alloc: " << alloccount << " free: " << freecount << std :: endl ; } void * AllocateBuffer ( size_t numbytes , int memtype ) { void * buf = malloc ( numbytes ); std :: cout << "Allocated " << numbytes << " bytes at location " << buf  << " (memtype = " << memtype << ")" << std :: endl ; alloccount ++ ; return buf ; } void FreeBuffer ( void * p ) { std :: cout << "Freeing block " << p << std :: endl ; freecount ++ ; free ( p ); } private: int alloccount , freecount ; }; #endif // RTP_SUPPORT_THREAD int main ( void ) { #ifdef WIN32 WSADATA dat ; WSAStartup ( MAKEWORD ( 2 , 2 ), & dat ); #endif // WIN32 MyMemoryManager mgr ; RTPSession sess ( 0 , & mgr ); uint16_t portbase , destport ; uint32_t destip ; 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 << "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 ; } // The inet_addr function returns a value in network byte order, but // we need the IP address in host byte order, so we use a call to // ntohl // 函数inet_addr 返回网络字节序的值,但我们需要的IP地址是要主机字节序,所以我们调用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 ; // Now, we'll create a RTP session, set the destination, send some // packets 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 sending 10 samples each second, so we'll // put the timestamp unit to (1.0/10.0) // 重要信息:本地的时间戳单位必须要设置,否则RTCP发送报告信息将会计算错误 // 在本例,我们将每秒发送10个样本,所以我们将时间戳单位设置为(1.0/10.0) 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 ( " \n Sending packet %d/%d \n " , i , num ); // send the packet 发送数据包 status = sess . SendPacket (( void * ) "1234567890" , 10 , 0 , false , 10 ); checkerror ( status ); 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 RTPTime :: Wait ( RTPTime ( 1 , 0 )); } sess . BYEDestroy ( RTPTime ( 10 , 0 ), 0 , 0 ); #ifdef WIN32 WSACleanup (); #endif // WIN32 return 0 ; }