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
00233 inline size_t
00234 sendData(const unsigned char* const buffer, size_t len)
00235 { return dso->send(buffer, len); }
00236
00237 inline SOCKET getDataRecvSocket() const
00238 { return dso->getRecvSocket(); }
00239
00244 inline bool
00245 isPendingControl(microtimeout_t timeout)
00246 { return cso->isPendingRecv(timeout); }
00247
00248 InetHostAddress
00249 getControlSender(tpport_t *port = NULL) const
00250 { return cso->getSender(port); }
00251
00261 inline size_t
00262 recvControl(unsigned char *buffer, size_t len,
00263 InetHostAddress& na, tpport_t& tp)
00264 { na = cso->getSender(tp); return cso->recv(buffer,len); }
00265
00266 inline void
00267 setControlPeer(const InetAddress &host, tpport_t port)
00268 { cso->setPeer(host,port); }
00269
00275 inline size_t
00276 sendControl(const unsigned char* const buffer, size_t len)
00277 { return cso->send(buffer,len); }
00278
00279 inline SOCKET getControlRecvSocket() const
00280 { return cso->getRecvSocket(); }
00281
00288 inline Socket::Error
00289 joinGroup(const InetMcastAddress& ia, uint32 iface)
00290 {
00291 Socket::Error error = dso->setMulticast(true);
00292 if ( error ) return error;
00293 error = dso->join(ia,iface);
00294 if ( error ) return error;
00295 error = cso->setMulticast(true);
00296 if ( error ) {
00297 dso->drop(ia);
00298 return error;
00299 }
00300 error = cso->join(ia,iface);
00301 if ( error ) {
00302 dso->drop(ia);
00303 return error;
00304 }
00305 return Socket::errSuccess;
00306 }
00307
00314 inline Socket::Error
00315 leaveGroup(const InetMcastAddress& ia)
00316 {
00317 Socket::Error error = dso->setMulticast(false);
00318 if ( error ) return error;
00319 error = dso->leaveGroup(ia);
00320 if ( error ) return error;
00321 error = cso->setMulticast(false);
00322 if ( error ) return error;
00323 return cso->leaveGroup(ia);
00324 }
00325
00326 inline void
00327 endSocket()
00328 {
00329 if (dso) {
00330 dso->endSocket();
00331 delete dso;
00332 }
00333 dso = NULL;
00334 if (cso) {
00335 cso->endSocket();
00336 delete cso;
00337 }
00338 cso = NULL;
00339 }
00340
00341 private:
00342 void
00343 build(const InetHostAddress& ia, tpport_t dataPort,
00344 tpport_t controlPort)
00345 {
00346 if ( 0 == controlPort ) {
00347 dataBasePort = even_port(dataPort);
00348 controlBasePort = dataBasePort + 1;
00349 } else {
00350 dataBasePort = dataPort;
00351 controlBasePort = controlPort;
00352 }
00353 dso = new RTPDataChannel(ia,dataBasePort);
00354 cso = new RTCPChannel(ia,controlBasePort);
00355 }
00356
00357 void
00358 build(const InetMcastAddress& ia, tpport_t dataPort,
00359 tpport_t controlPort, uint32 iface)
00360 {
00361 if ( 0 == controlPort ) {
00362 dataBasePort = even_port(dataPort);
00363 controlBasePort = dataBasePort + 1;
00364 } else {
00365 dataBasePort = dataPort;
00366 controlBasePort = controlPort;
00367 }
00368 dso = new RTPDataChannel(InetHostAddress("0.0.0.0"),dataBasePort);
00369 cso = new RTCPChannel(InetHostAddress("0.0.0.0"),controlBasePort);
00370 joinGroup(ia,iface);
00371 }
00372
00380 inline tpport_t
00381 odd_port(tpport_t port)
00382 { return (port & 0x01)? (port) : (port - 1); }
00383
00391 inline tpport_t
00392 even_port(tpport_t port)
00393 { return (port & 0x01)? (port - 1) : (port); }
00394
00395 tpport_t dataBasePort;
00396 tpport_t controlBasePort;
00397
00398 protected:
00399 RTPDataChannel* dso;
00400 RTCPChannel* cso;
00401 friend class RTPSessionBaseHandler;
00402 };
00403
00414 template
00415 <class RTPDataChannel = DualRTPUDPIPv4Channel,
00416 class RTCPChannel = DualRTPUDPIPv4Channel,
00417 class ServiceQueue = AVPQueue>
00418 class __EXPORT SingleThreadRTPSession :
00419 protected Thread,
00420 public TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00421 {
00422 public:
00423 SingleThreadRTPSession(const InetHostAddress& ia,
00424 tpport_t dataPort = DefaultRTPDataPort,
00425 tpport_t controlPort = 0,
00426 int pri = 0,
00427 uint32 memberssize =
00428 MembershipBookkeeping::defaultMembersHashSize,
00429 RTPApplication& app = defaultApplication()
00430 #if defined(_MSC_VER) && _MSC_VER >= 1300
00431 );
00432 #else
00433 ):
00434 Thread(pri),
00435 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00436 (ia,dataPort,controlPort,memberssize,app)
00437 { }
00438 #endif
00439
00440 SingleThreadRTPSession(uint32 ssrc, const InetHostAddress& ia,
00441 tpport_t dataPort = DefaultRTPDataPort,
00442 tpport_t controlPort = 0,
00443 int pri = 0,
00444 uint32 memberssize =
00445 MembershipBookkeeping::defaultMembersHashSize,
00446 RTPApplication& app = defaultApplication()
00447 #if defined(_MSC_VER) && _MSC_VER >= 1300
00448 );
00449 #else
00450 ):
00451 Thread(pri),
00452 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00453 (ssrc, ia,dataPort,controlPort,memberssize,app)
00454 { }
00455 #endif
00456
00457 SingleThreadRTPSession(const InetMcastAddress& ia,
00458 tpport_t dataPort = DefaultRTPDataPort,
00459 tpport_t controlPort = 0,
00460 int pri = 0,
00461 uint32 memberssize =
00462 MembershipBookkeeping::defaultMembersHashSize,
00463 RTPApplication& app = defaultApplication(),
00464 uint32 iface = 0
00465 #if defined(_MSC_VER) && _MSC_VER >= 1300
00466 );
00467 #else
00468 ):
00469 Thread(pri),
00470 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00471 (ia,dataPort,controlPort,memberssize,app,iface)
00472 { }
00473 #endif
00474
00475 SingleThreadRTPSession(uint32 ssrc, const InetMcastAddress& ia,
00476 tpport_t dataPort = DefaultRTPDataPort,
00477 tpport_t controlPort = 0,
00478 int pri = 0,
00479 uint32 memberssize =
00480 MembershipBookkeeping::defaultMembersHashSize,
00481 RTPApplication& app = defaultApplication(),
00482 uint32 iface = 0
00483 #if defined(_MSC_VER) && _MSC_VER >= 1300
00484 );
00485 #else
00486 ):
00487 Thread(pri),
00488 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00489 (ssrc,ia,dataPort,controlPort,memberssize,app,iface)
00490 { }
00491 #endif
00492
00493
00494 ~SingleThreadRTPSession()
00495 {
00496 if (isRunning()) {
00497 disableStack(); Thread::join();
00498 }
00499 }
00500
00501 #if defined(_MSC_VER) && _MSC_VER >= 1300
00502 virtual void startRunning();
00503 #else
00504
00507 void
00508 startRunning()
00509 { enableStack(); Thread::start(); }
00510 #endif
00511
00512
00513 protected:
00514 inline void disableStack(void)
00515 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();}
00516
00517 inline void enableStack(void)
00518 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}
00519
00520 inline microtimeout_t getSchedulingTimeout(void)
00521 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}
00522
00523 inline void controlReceptionService(void)
00524 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}
00525
00526 inline void controlTransmissionService(void)
00527 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}
00528
00529 inline timeval getRTCPCheckInterval(void)
00530 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();};
00531
00532 inline size_t dispatchDataPacket(void)
00533 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();};
00534
00535 #if defined(_MSC_VER) && _MSC_VER >= 1300
00536 virtual void run(void);
00537
00538 virtual void timerTick(void);
00539
00540 virtual bool isPendingData(microtimeout_t timeout);
00541 #else
00542
00543 virtual void timerTick(void)
00544 {return;}
00545
00546 virtual bool isPendingData(microtimeout_t timeout)
00547 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}
00548
00553 virtual void run(void)
00554 {
00555 microtimeout_t timeout = 0;
00556 while ( ServiceQueue::isActive() ) {
00557 if ( timeout < 1000 ){
00558 timeout = getSchedulingTimeout();
00559 }
00560 setCancel(cancelDeferred);
00561 controlReceptionService();
00562 controlTransmissionService();
00563 setCancel(cancelImmediate);
00564 microtimeout_t maxWait =
00565 timeval2microtimeout(getRTCPCheckInterval());
00566
00567
00568
00569 timeout = (timeout > maxWait)? maxWait : timeout;
00570 if ( timeout < 1000 ) {
00571 setCancel(cancelDeferred);
00572 dispatchDataPacket();
00573 setCancel(cancelImmediate);
00574 timerTick();
00575 } else {
00576 if ( isPendingData(timeout/1000) ) {
00577 setCancel(cancelDeferred);
00578 if (ServiceQueue::isActive()) {
00579 takeInDataPacket();
00580 }
00581 setCancel(cancelImmediate);
00582 }
00583 timeout = 0;
00584 }
00585 }
00586 dispatchBYE("GNU ccRTP stack finishing.");
00587 Thread::exit();
00588 }
00589
00590 #endif
00591
00592 inline size_t takeInDataPacket(void)
00593 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}
00594
00595 inline size_t dispatchBYE(const std::string &str)
00596 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
00597 };
00598
00607 typedef SingleThreadRTPSession<> RTPSession;
00608
00614 typedef RTPSession RTPSocket;
00615
00624 typedef SingleThreadRTPSession<SymmetricRTPChannel,
00625 SymmetricRTPChannel> SymmetricRTPSession;
00626
00627 #ifdef CCXX_IPV6
00628
00650 template <class RTPDataChannel = DualRTPUDPIPv6Channel,
00651 class RTCPChannel = DualRTPUDPIPv6Channel,
00652 class ServiceQueue = AVPQueue>
00653 class __EXPORT TRTPSessionBaseIPV6 : public ServiceQueue
00654 {
00655 public:
00665 TRTPSessionBaseIPV6(const IPV6Host& ia, tpport_t dataPort,
00666 tpport_t controlPort, uint32 membersSize,
00667 RTPApplication& app) :
00668 ServiceQueue(membersSize,app)
00669 { build(ia,dataPort,controlPort); }
00670
00682 TRTPSessionBaseIPV6(uint32 ssrc,
00683 const IPV6Host& ia,
00684 tpport_t dataPort, tpport_t controlPort,
00685 uint32 membersSize, RTPApplication& app):
00686 ServiceQueue(ssrc,membersSize,app)
00687 { build(ia,dataPort,controlPort); }
00688
00701 TRTPSessionBaseIPV6(const IPV6Multicast& ia, tpport_t dataPort,
00702 tpport_t controlPort, uint32 membersSize,
00703 RTPApplication& app, uint32 iface) :
00704 ServiceQueue(membersSize,app)
00705 { build(ia,dataPort,controlPort,iface); }
00706
00721 TRTPSessionBaseIPV6(uint32 ssrc,
00722 const IPV6Multicast& ia, tpport_t dataPort,
00723 tpport_t controlPort, uint32 membersSize,
00724 RTPApplication& app, uint32 iface) :
00725 ServiceQueue(ssrc,membersSize,app)
00726 { build(ia,dataPort,controlPort,iface); }
00727
00728 virtual size_t dispatchBYE(const std::string &str)
00729 {
00730 return QueueRTCPManager::dispatchBYE(str);
00731 }
00732
00733 inline virtual
00734 ~TRTPSessionBaseIPV6()
00735 {
00736 endSocket();
00737 }
00738
00739 inline RTPDataChannel *getDSO(void)
00740 {return dso;};
00741
00742 protected:
00746 inline bool
00747 isPendingData(microtimeout_t timeout)
00748 { return dso->isPendingRecv(timeout); }
00749
00750 inline IPV6Host
00751 getDataSender(tpport_t *port = NULL) const
00752 { return dso->getSender(port); }
00753
00754 inline size_t
00755 getNextDataPacketSize() const
00756 { return dso->getNextPacketSize(); }
00757
00767 inline size_t
00768 recvData(unsigned char* buffer, size_t len,
00769 IPV6Host& na, tpport_t& tp)
00770 { na = dso->getSender(tp); return dso->recv(buffer, len); }
00771
00772 inline void
00773 setDataPeer(const IPV6Host &host, tpport_t port)
00774 { dso->setPeer(host,port); }
00775
00780 inline size_t
00781 sendData(const unsigned char* const buffer, size_t len)
00782 { return dso->send(buffer, len); }
00783
00784 inline SOCKET getDataRecvSocket() const
00785 { return dso->getRecvSocket(); }
00786
00791 inline bool
00792 isPendingControl(microtimeout_t timeout)
00793 { return cso->isPendingRecv(timeout); }
00794
00795 inline IPV6Host
00796 getControlSender(tpport_t *port = NULL) const
00797 { return cso->getSender(port); }
00798
00808 inline size_t
00809 recvControl(unsigned char *buffer, size_t len,
00810 IPV6Host& na, tpport_t& tp)
00811 { na = cso->getSender(tp); return cso->recv(buffer,len); }
00812
00813 inline void
00814 setControlPeer(const IPV6Host &host, tpport_t port)
00815 { cso->setPeer(host,port); }
00816
00822 inline size_t
00823 sendControl(const unsigned char* const buffer, size_t len)
00824 { return cso->send(buffer,len); }
00825
00826 inline SOCKET getControlRecvSocket() const
00827 { return cso->getRecvSocket(); }
00828
00829 inline void
00830 endSocket()
00831 {
00832 dso->endSocket();
00833 cso->endSocket();
00834 if (dso) delete dso;
00835 dso = NULL;
00836 if (cso) delete cso;
00837 cso = NULL;
00838 }
00839
00840 private:
00841 void
00842 build(const IPV6Host& ia, tpport_t dataPort,
00843 tpport_t controlPort)
00844 {
00845 if ( 0 == controlPort ) {
00846 dataBasePort = even_port(dataPort);
00847 controlBasePort = dataBasePort + 1;
00848 } else {
00849 dataBasePort = dataPort;
00850 controlBasePort = controlPort;
00851 }
00852 dso = new RTPDataChannel(ia,dataBasePort);
00853 cso = new RTCPChannel(ia,controlBasePort);
00854 }
00855
00856 void
00857 build(const IPV6Multicast& ia, tpport_t dataPort,
00858 tpport_t controlPort, uint32 iface)
00859 {
00860 if ( 0 == controlPort ) {
00861 dataBasePort = even_port(dataPort);
00862 controlBasePort = dataBasePort + 1;
00863 } else {
00864 dataBasePort = dataPort;
00865 controlBasePort = controlPort;
00866 }
00867 dso = new RTPDataChannel(IPV6Host("0.0.0.0"),dataBasePort);
00868 cso = new RTCPChannel(IPV6Host("0.0.0.0"),controlBasePort);
00869 joinGroup(ia,iface);
00870 }
00871
00878 inline Socket::Error
00879 joinGroup(const IPV6Multicast& ia, uint32 iface)
00880 {
00881 Socket::Error error = dso->setMulticast(true);
00882 if ( error ) return error;
00883 error = dso->join(ia,iface);
00884 if ( error ) return error;
00885 error = cso->setMulticast(true);
00886 if ( error ) {
00887 dso->drop(ia);
00888 return error;
00889 }
00890 error = cso->join(ia,iface);
00891 if ( error ) {
00892 dso->drop(ia);
00893 return error;
00894 }
00895 return Socket::errSuccess;
00896 }
00897
00904 inline Socket::Error
00905 leaveGroup(const IPV6Multicast& ia)
00906 {
00907 Socket::Error error = dso->setMulticast(false);
00908 if ( error ) return error;
00909 error = dso->leaveGroup(ia);
00910 if ( error ) return error;
00911 error = cso->setMulticast(false);
00912 if ( error ) return error;
00913 return cso->leaveGroup(ia);
00914 }
00915
00922 inline Socket::Error
00923 setMcastTTL(uint8 ttl)
00924 {
00925 Socket::Error error = dso->setMulticast(true);
00926 if ( error ) return error;
00927 error = dso->setTimeToLive(ttl);
00928 if ( error ) return error;
00929 error = cso->setMulticast(true);
00930 if ( error ) return error;
00931 return cso->setTimeToLive(ttl);
00932 }
00933
00941 inline tpport_t
00942 odd_port(tpport_t port)
00943 { return (port & 0x01)? (port) : (port - 1); }
00944
00952 inline tpport_t
00953 even_port(tpport_t port)
00954 { return (port & 0x01)? (port - 1) : (port); }
00955
00956 tpport_t dataBasePort;
00957 tpport_t controlBasePort;
00958
00959 protected:
00960 RTPDataChannel* dso;
00961 RTCPChannel* cso;
00962 friend class RTPSessionBaseHandler;
00963 };
00964
00975 template
00976 <class RTPDataChannel = DualRTPUDPIPv6Channel,
00977 class RTCPChannel = DualRTPUDPIPv6Channel,
00978 class ServiceQueue = AVPQueue>
00979 class __EXPORT SingleThreadRTPSessionIPV6 :
00980 protected Thread,
00981 public TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
00982 {
00983 public:
00984 SingleThreadRTPSessionIPV6(const IPV6Host& ia,
00985 tpport_t dataPort = DefaultRTPDataPort,
00986 tpport_t controlPort = 0,
00987 int pri = 0,
00988 uint32 memberssize =
00989 MembershipBookkeeping::defaultMembersHashSize,
00990 RTPApplication& app = defaultApplication()
00991 #if defined(_MSC_VER) && _MSC_VER >= 1300
00992 );
00993 #else
00994 ):
00995 Thread(pri),
00996 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
00997 (ia,dataPort,controlPort,memberssize,app)
00998 { }
00999 #endif
01000
01001 SingleThreadRTPSessionIPV6(const IPV6Multicast& ia,
01002 tpport_t dataPort = DefaultRTPDataPort,
01003 tpport_t controlPort = 0,
01004 int pri = 0,
01005 uint32 memberssize =
01006 MembershipBookkeeping::defaultMembersHashSize,
01007 RTPApplication& app = defaultApplication(),
01008 uint32 iface = 0
01009 #if defined(_MSC_VER) && _MSC_VER >= 1300
01010 );
01011 #else
01012 ):
01013 Thread(pri),
01014 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
01015 (ia,dataPort,controlPort,memberssize,app,iface)
01016 { }
01017 #endif
01018
01019 ~SingleThreadRTPSessionIPV6()
01020 {
01021 if (isRunning()) {
01022 disableStack(); Thread::join();
01023 }
01024 }
01025
01026 #if defined(_MSC_VER) && _MSC_VER >= 1300
01027 virtual void startRunning();
01028 #else
01029
01032 void
01033 startRunning()
01034 { enableStack(); Thread::start(); }
01035 #endif
01036
01037
01038 protected:
01039 inline void enableStack(void)
01040 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}
01041
01042 inline void disableStack(void)
01043 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();}
01044
01045 inline microtimeout_t getSchedulingTimeout(void)
01046 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}
01047
01048 inline void controlReceptionService(void)
01049 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}
01050
01051 inline void controlTransmissionService(void)
01052 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}
01053
01054 inline timeval getRTCPCheckInterval(void)
01055 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();};
01056
01057 inline size_t dispatchDataPacket(void)
01058 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();};
01059
01060 #if defined(_MSC_VER) && _MSC_VER >= 1300
01061 virtual void run(void);
01062
01063 virtual void timerTick(void);
01064
01065 virtual bool isPendingData(microtimeout_t timeout);
01066 #else
01067
01068 virtual void timerTick(void)
01069 {return;}
01070
01071 virtual bool isPendingData(microtimeout_t timeout)
01072 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}
01073
01078 virtual void run(void)
01079 {
01080 microtimeout_t timeout = 0;
01081 while ( ServiceQueue::isActive() ) {
01082 if ( timeout < 1000 ){
01083 timeout = getSchedulingTimeout();
01084 }
01085 setCancel(cancelDeferred);
01086 controlReceptionService();
01087 controlTransmissionService();
01088 setCancel(cancelImmediate);
01089 microtimeout_t maxWait =
01090 timeval2microtimeout(getRTCPCheckInterval());
01091
01092
01093
01094 timeout = (timeout > maxWait)? maxWait : timeout;
01095 if ( timeout < 1000 ) {
01096 setCancel(cancelDeferred);
01097 dispatchDataPacket();
01098 setCancel(cancelImmediate);
01099 timerTick();
01100 } else {
01101 if ( isPendingData(timeout/1000) ) {
01102 setCancel(cancelDeferred);
01103 takeInDataPacket();
01104 setCancel(cancelImmediate);
01105 }
01106 timeout = 0;
01107 }
01108 }
01109 dispatchBYE("GNU ccRTP stack finishing.");
01110 Thread::exit();
01111 }
01112
01113 #endif
01114
01115 inline size_t takeInDataPacket(void)
01116 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}
01117
01118 inline size_t dispatchBYE(const std::string &str)
01119 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
01120 };
01121
01130 typedef SingleThreadRTPSessionIPV6<> RTPSessionIPV6;
01131
01137 typedef RTPSessionIPV6 RTPSocketIPV6;
01138
01147 typedef SingleThreadRTPSessionIPV6<SymmetricRTPChannelIPV6,
01148 SymmetricRTPChannelIPV6> SymmetricRTPSessionIPV6;
01149
01150
01151 #endif
01152
01154
01155 #ifdef CCXX_NAMESPACES
01156 }
01157 #endif
01158
01159 #endif //CCXX_RTP_RTP_H_
01160