/* This IPv4 example listens for incoming packets and automatically adds destinations for new sources. */ #include "rtpsession.h" #include "rtppacket.h" #include "rtpudpv4transmitter.h" #include "rtptcptransmitter.h" #include "rtpipv4address.h" #include "rtptcpaddress.h" #include "rtpsessionparams.h" #include "rtperrors.h" #include "rtpsourcedata.h" #include #include #include #include using namespace jrtplib; using namespace std; // // This function checks if there was a RTP error. If so, it displays an error // message and exists. // void checkerror(int rtperr) { if (rtperr < 0) { std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl; exit(-1); } } // // The new class routine // class MyRTPSession : public RTPSession { protected: 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); 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; 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; } 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; } void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled) { printf("SSRC %x Got packet (%d bytes) in OnValidatedRTPPacket from source 0x%04x!\n", GetLocalSSRC(), (int)rtppack->GetPayloadLength(), srcdat->GetSSRC()); DeletePacket(rtppack); *ispackethandled = true; } void OnRTCPSDESItem(RTPSourceData *srcdat, RTCPSDESPacket::ItemType t, const void *itemdata, size_t itemlength) { char msg[1024]; memset(msg, 0, sizeof(msg)); if (itemlength >= sizeof(msg)) itemlength = sizeof(msg)-1; memcpy(msg, itemdata, itemlength); printf("SSRC %x Received SDES item (%d): %s from SSRC %x\n", GetLocalSSRC(), (int)t, msg, srcdat->GetSSRC()); } }; class MyTCPTransmitter : public RTPTCPTransmitter { public: MyTCPTransmitter() : RTPTCPTransmitter(0){ } void OnSendError(SocketType sock) { cout << ": Error sending over socket " << sock << ", removing destination" << endl; DeleteDestination(RTPTCPAddress(sock)); } void OnReceiveError(SocketType sock) { cout << ": Error receiving from socket " << sock << ", removing destination" << endl; DeleteDestination(RTPTCPAddress(sock)); } }; int udp_mode(int port){ MyRTPSession sess; std::string ipstr; int status,i,num; num = 1000000*30; // Now, we'll create a RTP session, set the destination // and poll for incoming data. 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(port); status = sess.Create(sessparams,&transparams); checkerror(status); std::cout << "begin.." << std::endl; 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(0,1)); } sess.BYEDestroy(RTPTime(10,0),0,0); return 0; } int tcp_mode(int port){ int nListener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (nListener < 0) { return -1; } sockaddr_in serverAddr; memset(&serverAddr, 0, sizeof(sockaddr_in)); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(port); serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); int nRet = bind(nListener, (sockaddr*)&serverAddr, sizeof(serverAddr)); if (nRet == -1) { return -1; } if (listen(nListener, 1) == -1) { return -1; } sockaddr_in clientAddr; int nLen = sizeof(sockaddr_in); int nServer = accept(nListener, (sockaddr*)&clientAddr, (socklen_t * ) &nLen); if (nServer == -1) { return -1; } int nPackSize = 45678; RTPSessionParams sessparams; sessparams.SetProbationType(RTPSources::NoProbation); sessparams.SetOwnTimestampUnit(90000.0 / 25.0); sessparams.SetMaximumPacketSize(nPackSize + 64); MyTCPTransmitter trans; int status = trans.Init(true); status = trans.Create(65535, NULL); MyRTPSession sess; status = sess.Create(sessparams, &trans); if (status < 0) { std::cout << "create session error!!" << std::endl; return -1; } sess.AddDestination(RTPTCPAddress(nServer)); std::cout << "begin.." << std::endl; while (true) { RTPTime::Wait(RTPTime(1,0)); } while(true){ 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); return 0; } // // The main routine // int main(int argc, char* argv[]){ int port = atoi(argv[1]); std::cout << "port:" << port << std::endl; while (true) { int ch = getchar(); if (ch == 'q') { break; } switch (ch) { case 'u': udp_mode(port); break; case 't': tcp_mode(port); break; default: break; } /* code */ } return 0; }