00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00049 #ifndef CCXX_RTP_RTP_H_
00050 #define CCXX_RTP_RTP_H_
00051
00052 #include <ccrtp/cqueue.h>
00053 #include <ccrtp/channel.h>
00054
00055 #ifdef CCXX_NAMESPACES
00056 namespace ost {
00057 #endif
00058
00085 template <class RTPDataChannel = DualRTPUDPIPv4Channel,
00086 class RTCPChannel = DualRTPUDPIPv4Channel,
00087 class ServiceQueue = AVPQueue>
00088 class __EXPORT TRTPSessionBase : public ServiceQueue
00089 {
00090 public:
00100 TRTPSessionBase(const InetHostAddress& ia, tpport_t dataPort,
00101 tpport_t controlPort, uint32 membersSize,
00102 RTPApplication& app) :
00103 ServiceQueue(membersSize,app)
00104 { build(ia,dataPort,controlPort); }
00105
00117 TRTPSessionBase(uint32 ssrc,
00118 const InetHostAddress& ia,
00119 tpport_t dataPort, tpport_t controlPort,
00120 uint32 membersSize, RTPApplication& app):
00121 ServiceQueue(ssrc,membersSize,app)
00122 { build(ia,dataPort,controlPort); }
00123
00136 TRTPSessionBase(const InetMcastAddress& ia, tpport_t dataPort,
00137 tpport_t controlPort, uint32 membersSize,
00138 RTPApplication& app, uint32 iface) :
00139 ServiceQueue(membersSize,app)
00140 { build(ia,dataPort,controlPort,iface); }
00141
00156 TRTPSessionBase(uint32 ssrc,
00157 const InetMcastAddress& ia, tpport_t dataPort,
00158 tpport_t controlPort, uint32 membersSize,
00159 RTPApplication& app, uint32 iface) :
00160 ServiceQueue(ssrc,membersSize,app)
00161 { build(ia,dataPort,controlPort,iface); }
00162
00163 virtual size_t dispatchBYE(const std::string &str)
00164 {
00165 return QueueRTCPManager::dispatchBYE(str);
00166 }
00167
00174 inline Socket::Error
00175 setMcastTTL(uint8 ttl)
00176 {
00177 Socket::Error error = dso->setMulticast(true);
00178 if ( error ) return error;
00179 error = dso->setTimeToLive(ttl);
00180 if ( error ) return error;
00181 error = cso->setMulticast(true);
00182 if ( error ) return error;
00183 return cso->setTimeToLive(ttl);
00184 }
00185
00186 inline virtual
00187 ~TRTPSessionBase()
00188 {
00189 endSocket();
00190 }
00191
00192 inline RTPDataChannel *getDSO(void)
00193 {return dso;}
00194
00195 protected:
00199 inline bool
00200 isPendingData(microtimeout_t timeout)
00201 { return dso->isPendingRecv(timeout); }
00202
00203 InetHostAddress
00204 getDataSender(tpport_t *port = NULL) const
00205 { return dso->getSender(port); }
00206
00207 inline size_t
00208 getNextDataPacketSize() const
00209 { return dso->getNextPacketSize(); }
00210
00220 inline size_t
00221 recvData(unsigned char* buffer, size_t len,
00222 InetHostAddress& na, tpport_t& tp)
00223 { na = dso->getSender(tp); return dso->recv(buffer, len); }
00224
00225 inline void
00226 setDataPeer(const InetAddress &host, tpport_t port)
00227 { dso->setPeer(host,port); }
00228
00229
00234 inline size_t
00235 sendData(const unsigned char* const buffer, size_t len)
00236 { return dso->send(buffer, len); }
00237
00238 inline SOCKET getDataRecvSocket() const
00239 { return dso->getRecvSocket(); }
00240
00245 inline bool
00246 isPendingControl(microtimeout_t timeout)
00247 { return cso->isPendingRecv(timeout); }
00248
00249 InetHostAddress
00250 getControlSender(tpport_t *port = NULL) const
00251 { return cso->getSender(port); }
00252
00262 inline size_t
00263 recvControl(unsigned char *buffer, size_t len,
00264 InetHostAddress& na, tpport_t& tp)
00265 { na = cso->getSender(tp); return cso->recv(buffer,len); }
00266
00267 inline void
00268 setControlPeer(const InetAddress &host, tpport_t port)
00269 { cso->setPeer(host,port); }
00270
00276 inline size_t
00277 sendControl(const unsigned char* const buffer, size_t len)
00278 { return cso->send(buffer,len); }
00279
00280 inline SOCKET getControlRecvSocket() const
00281 { return cso->getRecvSocket(); }
00282
00289 inline Socket::Error
00290 joinGroup(const InetMcastAddress& ia, uint32 iface)
00291 {
00292 Socket::Error error = dso->setMulticast(true);
00293 if ( error ) return error;
00294 error = dso->join(ia,iface);
00295 if ( error ) return error;
00296 error = cso->setMulticast(true);
00297 if ( error ) {
00298 dso->drop(ia);
00299 return error;
00300 }
00301 error = cso->join(ia,iface);
00302 if ( error ) {
00303 dso->drop(ia);
00304 return error;
00305 }
00306 return Socket::errSuccess;
00307 }
00308
00315 inline Socket::Error
00316 leaveGroup(const InetMcastAddress& ia)
00317 {
00318 Socket::Error error = dso->setMulticast(false);
00319 if ( error ) return error;
00320 error = dso->leaveGroup(ia);
00321 if ( error ) return error;
00322 error = cso->setMulticast(false);
00323 if ( error ) return error;
00324 return cso->leaveGroup(ia);
00325 }
00326
00327 inline void
00328 endSocket()
00329 {
00330 if (dso) {
00331 dso->endSocket();
00332 delete dso;
00333 }
00334 dso = NULL;
00335 if (cso) {
00336 cso->endSocket();
00337 delete cso;
00338 }
00339 cso = NULL;
00340 }
00341
00342 private:
00343 void
00344 build(const InetHostAddress& ia, tpport_t dataPort,
00345 tpport_t controlPort)
00346 {
00347 if ( 0 == controlPort ) {
00348 dataBasePort = even_port(dataPort);
00349 controlBasePort = dataBasePort + 1;
00350 } else {
00351 dataBasePort = dataPort;
00352 controlBasePort = controlPort;
00353 }
00354 dso = new RTPDataChannel(ia,dataBasePort);
00355 cso = new RTCPChannel(ia,controlBasePort);
00356 }
00357
00358 void
00359 build(const InetMcastAddress& ia, tpport_t dataPort,
00360 tpport_t controlPort, uint32 iface)
00361 {
00362 if ( 0 == controlPort ) {
00363 dataBasePort = even_port(dataPort);
00364 controlBasePort = dataBasePort + 1;
00365 } else {
00366 dataBasePort = dataPort;
00367 controlBasePort = controlPort;
00368 }
00369 dso = new RTPDataChannel(InetHostAddress("0.0.0.0"),dataBasePort);
00370 cso = new RTCPChannel(InetHostAddress("0.0.0.0"),controlBasePort);
00371 joinGroup(ia,iface);
00372 }
00373
00381 inline tpport_t
00382 odd_port(tpport_t port)
00383 { return (port & 0x01)? (port) : (port - 1); }
00384
00392 inline tpport_t
00393 even_port(tpport_t port)
00394 { return (port & 0x01)? (port - 1) : (port); }
00395
00396 tpport_t dataBasePort;
00397 tpport_t controlBasePort;
00398
00399 protected:
00400 RTPDataChannel* dso;
00401 RTCPChannel* cso;
00402 friend class RTPSessionBaseHandler;
00403 };
00404
00415 template
00416 <class RTPDataChannel = DualRTPUDPIPv4Channel,
00417 class RTCPChannel = DualRTPUDPIPv4Channel,
00418 class ServiceQueue = AVPQueue>
00419 class __EXPORT SingleThreadRTPSession :
00420 protected Thread,
00421 public TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00422 {
00423 public:
00424 SingleThreadRTPSession(const InetHostAddress& ia,
00425 tpport_t dataPort = DefaultRTPDataPort,
00426 tpport_t controlPort = 0,
00427 int pri = 0,
00428 uint32 memberssize =
00429 MembershipBookkeeping::defaultMembersHashSize,
00430 RTPApplication& app = defaultApplication()
00431 #if defined(_MSC_VER) && _MSC_VER >= 1300
00432 );
00433 #else
00434 ):
00435 Thread(pri),
00436 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00437 (ia,dataPort,controlPort,memberssize,app)
00438 { }
00439 #endif
00440
00441 SingleThreadRTPSession(uint32 ssrc, const InetHostAddress& ia,
00442 tpport_t dataPort = DefaultRTPDataPort,
00443 tpport_t controlPort = 0,
00444 int pri = 0,
00445 uint32 memberssize =
00446 MembershipBookkeeping::defaultMembersHashSize,
00447 RTPApplication& app = defaultApplication()
00448 #if defined(_MSC_VER) && _MSC_VER >= 1300
00449 );
00450 #else
00451 ):
00452 Thread(pri),
00453 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00454 (ssrc, ia,dataPort,controlPort,memberssize,app)
00455 { }
00456 #endif
00457
00458 SingleThreadRTPSession(const InetMcastAddress& ia,
00459 tpport_t dataPort = DefaultRTPDataPort,
00460 tpport_t controlPort = 0,
00461 int pri = 0,
00462 uint32 memberssize =
00463 MembershipBookkeeping::defaultMembersHashSize,
00464 RTPApplication& app = defaultApplication(),
00465 uint32 iface = 0
00466 #if defined(_MSC_VER) && _MSC_VER >= 1300
00467 );
00468 #else
00469 ):
00470 Thread(pri),
00471 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00472 (ia,dataPort,controlPort,memberssize,app,iface)
00473 { }
00474 #endif
00475
00476 SingleThreadRTPSession(uint32 ssrc, const InetMcastAddress& ia,
00477 tpport_t dataPort = DefaultRTPDataPort,
00478 tpport_t controlPort = 0,
00479 int pri = 0,
00480 uint32 memberssize =
00481 MembershipBookkeeping::defaultMembersHashSize,
00482 RTPApplication& app = defaultApplication(),
00483 uint32 iface = 0
00484 #if defined(_MSC_VER) && _MSC_VER >= 1300
00485 );
00486 #else
00487 ):
00488 Thread(pri),
00489 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00490 (ssrc,ia,dataPort,controlPort,memberssize,app,iface)
00491 { }
00492 #endif
00493
00494
00495 ~SingleThreadRTPSession()
00496 {
00497 if (isRunning()) {
00498 disableStack(); Thread::join();
00499 }
00500 }
00501
00502 #if defined(_MSC_VER) && _MSC_VER >= 1300
00503 virtual void startRunning();
00504 #else
00505
00508 void
00509 startRunning()
00510 { enableStack(); Thread::start(); }
00511 #endif
00512
00513
00514 protected:
00515 inline void disableStack(void)
00516 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();}
00517
00518 inline void enableStack(void)
00519 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}
00520
00521 inline microtimeout_t getSchedulingTimeout(void)
00522 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}
00523
00524 inline void controlReceptionService(void)
00525 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}
00526
00527 inline void controlTransmissionService(void)
00528 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}
00529
00530 inline timeval getRTCPCheckInterval(void)
00531 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();}
00532
00533 inline size_t dispatchDataPacket(void)
00534 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();}
00535
00536 #if defined(_MSC_VER) && _MSC_VER >= 1300
00537 virtual void run(void);
00538
00539 virtual void timerTick(void);
00540
00541 virtual bool isPendingData(microtimeout_t timeout);
00542 #else
00543
00544 virtual void timerTick(void)
00545 {return;}
00546
00547 virtual bool isPendingData(microtimeout_t timeout)
00548 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}
00549
00554 virtual void run(void)
00555 {
00556 microtimeout_t timeout = 0;
00557 while ( ServiceQueue::isActive() ) {
00558 if ( timeout < 1000 ){
00559 timeout = getSchedulingTimeout();
00560 }
00561 setCancel(cancelDeferred);
00562 controlReceptionService();
00563 controlTransmissionService();
00564 setCancel(cancelImmediate);
00565 microtimeout_t maxWait =
00566 timeval2microtimeout(getRTCPCheckInterval());
00567
00568
00569
00570 timeout = (timeout > maxWait)? maxWait : timeout;
00571 if ( timeout < 1000 ) {
00572 setCancel(cancelDeferred);
00573 dispatchDataPacket();
00574 setCancel(cancelImmediate);
00575 timerTick();
00576 } else {
00577 if ( isPendingData(timeout/1000) ) {
00578 setCancel(cancelDeferred);
00579 if (ServiceQueue::isActive()) {
00580 takeInDataPacket();
00581 }
00582 setCancel(cancelImmediate);
00583 }
00584 timeout = 0;
00585 }
00586 }
00587 dispatchBYE("GNU ccRTP stack finishing.");
00588
00589 }
00590
00591 #endif
00592
00593 inline size_t takeInDataPacket(void)
00594 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}
00595
00596 inline size_t dispatchBYE(const std::string &str)
00597 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
00598 };
00599
00608 typedef SingleThreadRTPSession<> RTPSession;
00609
00615 typedef RTPSession RTPSocket;
00616
00625 typedef SingleThreadRTPSession<SymmetricRTPChannel,
00626 SymmetricRTPChannel> SymmetricRTPSession;
00627
00628 #ifdef CCXX_IPV6
00629
00651 template <class RTPDataChannel = DualRTPUDPIPv6Channel,
00652 class RTCPChannel = DualRTPUDPIPv6Channel,
00653 class ServiceQueue = AVPQueue>
00654 class __EXPORT TRTPSessionBaseIPV6 : public ServiceQueue
00655 {
00656 public:
00666 TRTPSessionBaseIPV6(const IPV6Host& ia, tpport_t dataPort,
00667 tpport_t controlPort, uint32 membersSize,
00668 RTPApplication& app) :
00669 ServiceQueue(membersSize,app)
00670 { build(ia,dataPort,controlPort); }
00671
00683 TRTPSessionBaseIPV6(uint32 ssrc,
00684 const IPV6Host& ia,
00685 tpport_t dataPort, tpport_t controlPort,
00686 uint32 membersSize, RTPApplication& app):
00687 ServiceQueue(ssrc,membersSize,app)
00688 { build(ia,dataPort,controlPort); }
00689
00702 TRTPSessionBaseIPV6(const IPV6Multicast& ia, tpport_t dataPort,
00703 tpport_t controlPort, uint32 membersSize,
00704 RTPApplication& app, uint32 iface) :
00705 ServiceQueue(membersSize,app)
00706 { build(ia,dataPort,controlPort,iface); }
00707
00722 TRTPSessionBaseIPV6(uint32 ssrc,
00723 const IPV6Multicast& ia, tpport_t dataPort,
00724 tpport_t controlPort, uint32 membersSize,
00725 RTPApplication& app, uint32 iface) :
00726 ServiceQueue(ssrc,membersSize,app)
00727 { build(ia,dataPort,controlPort,iface); }
00728
00729 virtual size_t dispatchBYE(const std::string &str)
00730 {
00731 return QueueRTCPManager::dispatchBYE(str);
00732 }
00733
00734 inline virtual
00735 ~TRTPSessionBaseIPV6()
00736 {
00737 endSocket();
00738 }
00739
00740 inline RTPDataChannel *getDSO(void)
00741 {return dso;}
00742
00743 protected:
00747 inline bool
00748 isPendingData(microtimeout_t timeout)
00749 { return dso->isPendingRecv(timeout); }
00750
00751 inline IPV6Host
00752 getDataSender(tpport_t *port = NULL) const
00753 { return dso->getSender(port); }
00754
00755 inline size_t
00756 getNextDataPacketSize() const
00757 { return dso->getNextPacketSize(); }
00758
00768 inline size_t
00769 recvData(unsigned char* buffer, size_t len,
00770 IPV6Host& na, tpport_t& tp)
00771 { na = dso->getSender(tp); return dso->recv(buffer, len); }
00772
00773 inline void
00774 setDataPeerIPV6(const IPV6Host &host, tpport_t port)
00775 { dso->setPeer(host,port); }
00776
00781 inline size_t
00782 sendDataIPV6(const unsigned char* const buffer, size_t len)
00783 { return dso->send(buffer, len); }
00784
00785 inline SOCKET getDataRecvSocket() const
00786 { return dso->getRecvSocket(); }
00787
00792 inline bool
00793 isPendingControl(microtimeout_t timeout)
00794 { return cso->isPendingRecv(timeout); }
00795
00796 inline IPV6Host
00797 getControlSender(tpport_t *port = NULL) const
00798 { return cso->getSender(port); }
00799
00809 inline size_t
00810 recvControl(unsigned char *buffer, size_t len,
00811 IPV6Host& na, tpport_t& tp)
00812 { na = cso->getSender(tp); return cso->recv(buffer,len); }
00813
00814 inline void
00815 setControlPeerIPV6(const IPV6Host &host, tpport_t port)
00816 { cso->setPeer(host,port); }
00817
00823 inline size_t
00824 sendControl(const unsigned char* const buffer, size_t len)
00825 { return cso->send(buffer,len); }
00826
00827 inline SOCKET getControlRecvSocket() const
00828 { return cso->getRecvSocket(); }
00829
00830 inline void
00831 endSocket()
00832 {
00833 dso->endSocket();
00834 cso->endSocket();
00835 if (dso) delete dso;
00836 dso = NULL;
00837 if (cso) delete cso;
00838 cso = NULL;
00839 }
00840
00841 private:
00842 void
00843 build(const IPV6Host& ia, tpport_t dataPort,
00844 tpport_t controlPort)
00845 {
00846 if ( 0 == controlPort ) {
00847 dataBasePort = even_port(dataPort);
00848 controlBasePort = dataBasePort + 1;
00849 } else {
00850 dataBasePort = dataPort;
00851 controlBasePort = controlPort;
00852 }
00853 dso = new RTPDataChannel(ia,dataBasePort);
00854 cso = new RTCPChannel(ia,controlBasePort);
00855 }
00856
00857 void
00858 build(const IPV6Multicast& ia, tpport_t dataPort,
00859 tpport_t controlPort, uint32 iface)
00860 {
00861 if ( 0 == controlPort ) {
00862 dataBasePort = even_port(dataPort);
00863 controlBasePort = dataBasePort + 1;
00864 } else {
00865 dataBasePort = dataPort;
00866 controlBasePort = controlPort;
00867 }
00868 dso = new RTPDataChannel(IPV6Host("0.0.0.0"),dataBasePort);
00869 cso = new RTCPChannel(IPV6Host("0.0.0.0"),controlBasePort);
00870 joinGroup(ia,iface);
00871 }
00872
00879 inline Socket::Error
00880 joinGroup(const IPV6Multicast& ia, uint32 iface)
00881 {
00882 Socket::Error error = dso->setMulticast(true);
00883 if ( error ) return error;
00884 error = dso->join(ia,iface);
00885 if ( error ) return error;
00886 error = cso->setMulticast(true);
00887 if ( error ) {
00888 dso->drop(ia);
00889 return error;
00890 }
00891 error = cso->join(ia,iface);
00892 if ( error ) {
00893 dso->drop(ia);
00894 return error;
00895 }
00896 return Socket::errSuccess;
00897 }
00898
00905 inline Socket::Error
00906 leaveGroup(const IPV6Multicast& ia)
00907 {
00908 Socket::Error error = dso->setMulticast(false);
00909 if ( error ) return error;
00910 error = dso->leaveGroup(ia);
00911 if ( error ) return error;
00912 error = cso->setMulticast(false);
00913 if ( error ) return error;
00914 return cso->leaveGroup(ia);
00915 }
00916
00923 inline Socket::Error
00924 setMcastTTL(uint8 ttl)
00925 {
00926 Socket::Error error = dso->setMulticast(true);
00927 if ( error ) return error;
00928 error = dso->setTimeToLive(ttl);
00929 if ( error ) return error;
00930 error = cso->setMulticast(true);
00931 if ( error ) return error;
00932 return cso->setTimeToLive(ttl);
00933 }
00934
00942 inline tpport_t
00943 odd_port(tpport_t port)
00944 { return (port & 0x01)? (port) : (port - 1); }
00945
00953 inline tpport_t
00954 even_port(tpport_t port)
00955 { return (port & 0x01)? (port - 1) : (port); }
00956
00957 tpport_t dataBasePort;
00958 tpport_t controlBasePort;
00959
00960 protected:
00961 RTPDataChannel* dso;
00962 RTCPChannel* cso;
00963 friend class RTPSessionBaseHandler;
00964 };
00965
00976 template
00977 <class RTPDataChannel = DualRTPUDPIPv6Channel,
00978 class RTCPChannel = DualRTPUDPIPv6Channel,
00979 class ServiceQueue = AVPQueue>
00980 class __EXPORT SingleThreadRTPSessionIPV6 :
00981 protected Thread,
00982 public TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
00983 {
00984 public:
00985 SingleThreadRTPSessionIPV6(const IPV6Host& ia,
00986 tpport_t dataPort = DefaultRTPDataPort,
00987 tpport_t controlPort = 0,
00988 int pri = 0,
00989 uint32 memberssize =
00990 MembershipBookkeeping::defaultMembersHashSize,
00991 RTPApplication& app = defaultApplication()
00992 #if defined(_MSC_VER) && _MSC_VER >= 1300
00993 );
00994 #else
00995 ):
00996 Thread(pri),
00997 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
00998 (ia,dataPort,controlPort,memberssize,app)
00999 { }
01000 #endif
01001
01002 SingleThreadRTPSessionIPV6(const IPV6Multicast& ia,
01003 tpport_t dataPort = DefaultRTPDataPort,
01004 tpport_t controlPort = 0,
01005 int pri = 0,
01006 uint32 memberssize =
01007 MembershipBookkeeping::defaultMembersHashSize,
01008 RTPApplication& app = defaultApplication(),
01009 uint32 iface = 0
01010 #if defined(_MSC_VER) && _MSC_VER >= 1300
01011 );
01012 #else
01013 ):
01014 Thread(pri),
01015 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
01016 (ia,dataPort,controlPort,memberssize,app,iface)
01017 { }
01018 #endif
01019
01020 ~SingleThreadRTPSessionIPV6()
01021 {
01022 if (isRunning()) {
01023 disableStack(); Thread::join();
01024 }
01025 }
01026
01027 #if defined(_MSC_VER) && _MSC_VER >= 1300
01028 virtual void startRunning();
01029 #else
01030
01033 void
01034 startRunning()
01035 { enableStack(); Thread::start(); }
01036 #endif
01037
01038
01039 protected:
01040 inline void enableStack(void)
01041 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}
01042
01043 inline void disableStack(void)
01044 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();}
01045
01046 inline microtimeout_t getSchedulingTimeout(void)
01047 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}
01048
01049 inline void controlReceptionService(void)
01050 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}
01051
01052 inline void controlTransmissionService(void)
01053 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}
01054
01055 inline timeval getRTCPCheckInterval(void)
01056 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();}
01057
01058 inline size_t dispatchDataPacket(void)
01059 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();}
01060
01061 #if defined(_MSC_VER) && _MSC_VER >= 1300
01062 virtual void run(void);
01063
01064 virtual void timerTick(void);
01065
01066 virtual bool isPendingData(microtimeout_t timeout);
01067 #else
01068
01069 virtual void timerTick(void)
01070 {return;}
01071
01072 virtual bool isPendingData(microtimeout_t timeout)
01073 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}
01074
01079 virtual void run(void)
01080 {
01081 microtimeout_t timeout = 0;
01082 while ( ServiceQueue::isActive() ) {
01083 if ( timeout < 1000 ){
01084 timeout = getSchedulingTimeout();
01085 }
01086 setCancel(cancelDeferred);
01087 controlReceptionService();
01088 controlTransmissionService();
01089 setCancel(cancelImmediate);
01090 microtimeout_t maxWait =
01091 timeval2microtimeout(getRTCPCheckInterval());
01092
01093
01094
01095 timeout = (timeout > maxWait)? maxWait : timeout;
01096 if ( timeout < 1000 ) {
01097 setCancel(cancelDeferred);
01098 dispatchDataPacket();
01099 setCancel(cancelImmediate);
01100 timerTick();
01101 } else {
01102 if ( isPendingData(timeout/1000) ) {
01103 setCancel(cancelDeferred);
01104 takeInDataPacket();
01105 setCancel(cancelImmediate);
01106 }
01107 timeout = 0;
01108 }
01109 }
01110 dispatchBYE("GNU ccRTP stack finishing.");
01111 Thread::exit();
01112 }
01113
01114 #endif
01115
01116 inline size_t takeInDataPacket(void)
01117 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}
01118
01119 inline size_t dispatchBYE(const std::string &str)
01120 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
01121 };
01122
01131 typedef SingleThreadRTPSessionIPV6<> RTPSessionIPV6;
01132
01138 typedef RTPSessionIPV6 RTPSocketIPV6;
01139
01148 typedef SingleThreadRTPSessionIPV6<SymmetricRTPChannelIPV6,
01149 SymmetricRTPChannelIPV6> SymmetricRTPSessionIPV6;
01150
01151
01152 #endif
01153
01155
01156 #ifdef CCXX_NAMESPACES
01157 }
01158 #endif
01159
01160 #endif //CCXX_RTP_RTP_H_
01161