天天看點

jrtplib3.9.1 example3

用例子1發送,本例接收,運作視窗如下:
 
 
  
        
jrtplib3.9.1 example3
/* This IPv4 example listens for incoming packets and automatically adds destinations for 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 ; } else return ; 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 ; } else return ; 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 ; } else return ; 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 WIN32 WSADATA 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_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 ; }

繼續閱讀