diff options
Diffstat (limited to 'examples/example3.cpp')
-rw-r--r-- | examples/example3.cpp | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/examples/example3.cpp b/examples/example3.cpp new file mode 100644 index 0000000..ee852bc --- /dev/null +++ b/examples/example3.cpp @@ -0,0 +1,223 @@ +/* + This IPv4 example listens for incoming packets and automatically adds destinations + for new sources. +*/ + +#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> + +// +// 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; + } +}; + +// +// 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. + + 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(); + + // 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; +} + |