ccRTP
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // 00003 // This program is free software; you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation; either version 2 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // This program is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program; if not, write to the Free Software 00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00016 // 00017 // As a special exception, you may use this file as part of a free software 00018 // library without restriction. Specifically, if other files instantiate 00019 // templates or use macros or inline functions from this file, or you compile 00020 // this file and link it with other files to produce an executable, this 00021 // file does not by itself cause the resulting executable to be covered by 00022 // the GNU General Public License. This exception does not however 00023 // invalidate any other reasons why the executable file might be covered by 00024 // the GNU General Public License. 00025 // 00026 // This exception applies only to the code released under the name GNU 00027 // ccRTP. If you copy code from other releases into a copy of GNU 00028 // ccRTP, as the General Public License permits, the exception does 00029 // not apply to the code that you add in this way. To avoid misleading 00030 // anyone as to the status of such modified files, you must delete 00031 // this exception notice from them. 00032 // 00033 // If you write modifications of your own for GNU ccRTP, it is your choice 00034 // whether to permit this exception to apply to your modifications. 00035 // If you do not wish that, delete this exception notice. 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 NAMESPACE_COMMONCPP 00056 00083 template <class RTPDataChannel = DualRTPUDPIPv4Channel, 00084 class RTCPChannel = DualRTPUDPIPv4Channel, 00085 class ServiceQueue = AVPQueue> 00086 class __EXPORT TRTPSessionBase : public ServiceQueue 00087 { 00088 public: 00098 TRTPSessionBase(const InetHostAddress& ia, tpport_t dataPort, 00099 tpport_t controlPort, uint32 membersSize, 00100 RTPApplication& app) : 00101 ServiceQueue(membersSize,app) 00102 { build(ia,dataPort,controlPort); } 00103 00115 TRTPSessionBase(uint32 ssrc, 00116 const InetHostAddress& ia, 00117 tpport_t dataPort, tpport_t controlPort, 00118 uint32 membersSize, RTPApplication& app): 00119 ServiceQueue(ssrc,membersSize,app) 00120 { build(ia,dataPort,controlPort); } 00121 00134 TRTPSessionBase(const InetMcastAddress& ia, tpport_t dataPort, 00135 tpport_t controlPort, uint32 membersSize, 00136 RTPApplication& app, uint32 iface) : 00137 ServiceQueue(membersSize,app) 00138 { build(ia,dataPort,controlPort,iface); } 00139 00154 TRTPSessionBase(uint32 ssrc, 00155 const InetMcastAddress& ia, tpport_t dataPort, 00156 tpport_t controlPort, uint32 membersSize, 00157 RTPApplication& app, uint32 iface) : 00158 ServiceQueue(ssrc,membersSize,app) 00159 { build(ia,dataPort,controlPort,iface); } 00160 00161 virtual size_t dispatchBYE(const std::string &str) 00162 { 00163 return QueueRTCPManager::dispatchBYE(str); 00164 } 00165 00172 inline Socket::Error 00173 setMcastTTL(uint8 ttl) 00174 { 00175 Socket::Error error = dso->setMulticast(true); 00176 if ( error ) return error; 00177 error = dso->setTimeToLive(ttl); 00178 if ( error ) return error; 00179 error = cso->setMulticast(true); 00180 if ( error ) return error; 00181 return cso->setTimeToLive(ttl); 00182 } 00183 00184 inline virtual 00185 ~TRTPSessionBase() 00186 { 00187 endSocket(); 00188 } 00189 00190 inline RTPDataChannel *getDSO(void) 00191 {return dso;} 00192 00193 protected: 00197 inline bool 00198 isPendingData(microtimeout_t timeout) 00199 { return dso->isPendingRecv(timeout); } 00200 00201 InetHostAddress 00202 getDataSender(tpport_t *port = NULL) const 00203 { return dso->getSender(port); } 00204 00205 inline size_t 00206 getNextDataPacketSize() const 00207 { return dso->getNextPacketSize(); } 00208 00218 inline size_t 00219 recvData(unsigned char* buffer, size_t len, 00220 InetHostAddress& na, tpport_t& tp) 00221 { na = dso->getSender(tp); return dso->recv(buffer, len); } 00222 00223 inline void 00224 setDataPeer(const InetAddress &host, tpport_t port) 00225 { dso->setPeer(host,port); } 00226 00227 00232 inline size_t 00233 sendData(const unsigned char* const buffer, size_t len) 00234 { return dso->send(buffer, len); } 00235 00236 inline SOCKET getDataRecvSocket() const 00237 { return dso->getRecvSocket(); } 00238 00243 inline bool 00244 isPendingControl(microtimeout_t timeout) 00245 { return cso->isPendingRecv(timeout); } 00246 00247 InetHostAddress 00248 getControlSender(tpport_t *port = NULL) const 00249 { return cso->getSender(port); } 00250 00260 inline size_t 00261 recvControl(unsigned char *buffer, size_t len, 00262 InetHostAddress& na, tpport_t& tp) 00263 { na = cso->getSender(tp); return cso->recv(buffer,len); } 00264 00265 inline void 00266 setControlPeer(const InetAddress &host, tpport_t port) 00267 { cso->setPeer(host,port); } 00268 00274 inline size_t 00275 sendControl(const unsigned char* const buffer, size_t len) 00276 { return cso->send(buffer,len); } 00277 00278 inline SOCKET getControlRecvSocket() const 00279 { return cso->getRecvSocket(); } 00280 00287 inline Socket::Error 00288 joinGroup(const InetMcastAddress& ia, uint32 iface) 00289 { 00290 Socket::Error error = dso->setMulticast(true); 00291 if ( error ) return error; 00292 error = dso->join(ia,iface); 00293 if ( error ) return error; 00294 error = cso->setMulticast(true); 00295 if ( error ) { 00296 dso->drop(ia); 00297 return error; 00298 } 00299 error = cso->join(ia,iface); 00300 if ( error ) { 00301 dso->drop(ia); 00302 return error; 00303 } 00304 return Socket::errSuccess; 00305 } 00306 00313 inline Socket::Error 00314 leaveGroup(const InetMcastAddress& ia) 00315 { 00316 Socket::Error error = dso->setMulticast(false); 00317 if ( error ) return error; 00318 error = dso->leaveGroup(ia); 00319 if ( error ) return error; 00320 error = cso->setMulticast(false); 00321 if ( error ) return error; 00322 return cso->leaveGroup(ia); 00323 } 00324 00325 inline void 00326 endSocket() 00327 { 00328 if (dso) { 00329 dso->endSocket(); 00330 delete dso; 00331 } 00332 dso = NULL; 00333 if (cso) { 00334 cso->endSocket(); 00335 delete cso; 00336 } 00337 cso = NULL; 00338 } 00339 00340 private: 00341 void 00342 build(const InetHostAddress& ia, tpport_t dataPort, 00343 tpport_t controlPort) 00344 { 00345 if ( 0 == controlPort ) { 00346 dataBasePort = even_port(dataPort); 00347 controlBasePort = dataBasePort + 1; 00348 } else { 00349 dataBasePort = dataPort; 00350 controlBasePort = controlPort; 00351 } 00352 dso = new RTPDataChannel(ia,dataBasePort); 00353 cso = new RTCPChannel(ia,controlBasePort); 00354 } 00355 00356 void 00357 build(const InetMcastAddress& ia, tpport_t dataPort, 00358 tpport_t controlPort, uint32 iface) 00359 { 00360 if ( 0 == controlPort ) { 00361 dataBasePort = even_port(dataPort); 00362 controlBasePort = dataBasePort + 1; 00363 } else { 00364 dataBasePort = dataPort; 00365 controlBasePort = controlPort; 00366 } 00367 dso = new RTPDataChannel(InetHostAddress("0.0.0.0"),dataBasePort); 00368 cso = new RTCPChannel(InetHostAddress("0.0.0.0"),controlBasePort); 00369 joinGroup(ia,iface); 00370 } 00371 00379 inline tpport_t 00380 odd_port(tpport_t port) 00381 { return (port & 0x01)? (port) : (port - 1); } 00382 00390 inline tpport_t 00391 even_port(tpport_t port) 00392 { return (port & 0x01)? (port - 1) : (port); } 00393 00394 tpport_t dataBasePort; 00395 tpport_t controlBasePort; 00396 00397 protected: 00398 RTPDataChannel* dso; 00399 RTCPChannel* cso; 00400 friend class RTPSessionBaseHandler; 00401 }; 00402 00413 template 00414 <class RTPDataChannel = DualRTPUDPIPv4Channel, 00415 class RTCPChannel = DualRTPUDPIPv4Channel, 00416 class ServiceQueue = AVPQueue> 00417 class __EXPORT SingleThreadRTPSession : 00418 protected Thread, 00419 public TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue> 00420 { 00421 public: 00422 SingleThreadRTPSession(const InetHostAddress& ia, 00423 tpport_t dataPort = DefaultRTPDataPort, 00424 tpport_t controlPort = 0, 00425 int pri = 0, 00426 uint32 memberssize = 00427 MembershipBookkeeping::defaultMembersHashSize, 00428 RTPApplication& app = defaultApplication() 00429 #if defined(_MSC_VER) && _MSC_VER >= 1300 00430 ); 00431 #else 00432 ): 00433 Thread(pri), 00434 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue> 00435 (ia,dataPort,controlPort,memberssize,app) 00436 { } 00437 #endif 00438 00439 SingleThreadRTPSession(uint32 ssrc, const InetHostAddress& ia, 00440 tpport_t dataPort = DefaultRTPDataPort, 00441 tpport_t controlPort = 0, 00442 int pri = 0, 00443 uint32 memberssize = 00444 MembershipBookkeeping::defaultMembersHashSize, 00445 RTPApplication& app = defaultApplication() 00446 #if defined(_MSC_VER) && _MSC_VER >= 1300 00447 ); 00448 #else 00449 ): 00450 Thread(pri), 00451 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue> 00452 (ssrc, ia,dataPort,controlPort,memberssize,app) 00453 { } 00454 #endif 00455 00456 SingleThreadRTPSession(const InetMcastAddress& ia, 00457 tpport_t dataPort = DefaultRTPDataPort, 00458 tpport_t controlPort = 0, 00459 int pri = 0, 00460 uint32 memberssize = 00461 MembershipBookkeeping::defaultMembersHashSize, 00462 RTPApplication& app = defaultApplication(), 00463 uint32 iface = 0 00464 #if defined(_MSC_VER) && _MSC_VER >= 1300 00465 ); 00466 #else 00467 ): 00468 Thread(pri), 00469 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue> 00470 (ia,dataPort,controlPort,memberssize,app,iface) 00471 { } 00472 #endif 00473 00474 SingleThreadRTPSession(uint32 ssrc, const InetMcastAddress& ia, 00475 tpport_t dataPort = DefaultRTPDataPort, 00476 tpport_t controlPort = 0, 00477 int pri = 0, 00478 uint32 memberssize = 00479 MembershipBookkeeping::defaultMembersHashSize, 00480 RTPApplication& app = defaultApplication(), 00481 uint32 iface = 0 00482 #if defined(_MSC_VER) && _MSC_VER >= 1300 00483 ); 00484 #else 00485 ): 00486 Thread(pri), 00487 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue> 00488 (ssrc,ia,dataPort,controlPort,memberssize,app,iface) 00489 { } 00490 #endif 00491 00492 00493 ~SingleThreadRTPSession() 00494 { 00495 if (isRunning()) { 00496 disableStack(); Thread::join(); 00497 } 00498 } 00499 00500 #if defined(_MSC_VER) && _MSC_VER >= 1300 00501 virtual void startRunning(); 00502 #else 00503 00506 void 00507 startRunning() 00508 { enableStack(); Thread::start(); } 00509 #endif 00510 00511 00512 protected: 00513 inline void disableStack(void) 00514 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();} 00515 00516 inline void enableStack(void) 00517 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();} 00518 00519 inline microtimeout_t getSchedulingTimeout(void) 00520 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();} 00521 00522 inline void controlReceptionService(void) 00523 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();} 00524 00525 inline void controlTransmissionService(void) 00526 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();} 00527 00528 inline timeval getRTCPCheckInterval(void) 00529 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();} 00530 00531 inline size_t dispatchDataPacket(void) 00532 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();} 00533 00534 #if defined(_MSC_VER) && _MSC_VER >= 1300 00535 virtual void run(void); 00536 00537 virtual void timerTick(void); 00538 00539 virtual bool isPendingData(microtimeout_t timeout); 00540 #else 00541 00542 virtual void timerTick(void) 00543 {return;} 00544 00545 virtual bool isPendingData(microtimeout_t timeout) 00546 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);} 00547 00552 virtual void run(void) 00553 { 00554 microtimeout_t timeout = 0; 00555 while ( ServiceQueue::isActive() ) { 00556 if ( timeout < 1000 ){ // !(timeout/1000) 00557 timeout = getSchedulingTimeout(); 00558 } 00559 controlReceptionService(); 00560 controlTransmissionService(); 00561 microtimeout_t maxWait = 00562 timeval2microtimeout(getRTCPCheckInterval()); 00563 // make sure the scheduling timeout is 00564 // <= the check interval for RTCP 00565 // packets 00566 timeout = (timeout > maxWait)? maxWait : timeout; 00567 if ( timeout < 1000 ) { // !(timeout/1000) 00568 dispatchDataPacket(); 00569 timerTick(); 00570 } else { 00571 if ( isPendingData(timeout/1000) ) { 00572 if (ServiceQueue::isActive()) { // take in only if active 00573 takeInDataPacket(); 00574 } 00575 } 00576 timeout = 0; 00577 } 00578 } 00579 dispatchBYE("GNU ccRTP stack finishing."); 00580 // Thread::exit(); 00581 } 00582 00583 #endif 00584 00585 inline size_t takeInDataPacket(void) 00586 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();} 00587 00588 inline size_t dispatchBYE(const std::string &str) 00589 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);} 00590 }; 00591 00600 typedef SingleThreadRTPSession<> RTPSession; 00601 00607 typedef RTPSession RTPSocket; 00608 00617 typedef SingleThreadRTPSession<SymmetricRTPChannel, 00618 SymmetricRTPChannel> SymmetricRTPSession; 00619 00620 #ifdef CCXX_IPV6 00621 00643 template <class RTPDataChannel = DualRTPUDPIPv6Channel, 00644 class RTCPChannel = DualRTPUDPIPv6Channel, 00645 class ServiceQueue = AVPQueue> 00646 class __EXPORT TRTPSessionBaseIPV6 : public ServiceQueue 00647 { 00648 public: 00658 TRTPSessionBaseIPV6(const IPV6Host& ia, tpport_t dataPort, 00659 tpport_t controlPort, uint32 membersSize, 00660 RTPApplication& app) : 00661 ServiceQueue(membersSize,app) 00662 { build(ia,dataPort,controlPort); } 00663 00675 TRTPSessionBaseIPV6(uint32 ssrc, 00676 const IPV6Host& ia, 00677 tpport_t dataPort, tpport_t controlPort, 00678 uint32 membersSize, RTPApplication& app): 00679 ServiceQueue(ssrc,membersSize,app) 00680 { build(ia,dataPort,controlPort); } 00681 00694 TRTPSessionBaseIPV6(const IPV6Multicast& ia, tpport_t dataPort, 00695 tpport_t controlPort, uint32 membersSize, 00696 RTPApplication& app, uint32 iface) : 00697 ServiceQueue(membersSize,app) 00698 { build(ia,dataPort,controlPort,iface); } 00699 00714 TRTPSessionBaseIPV6(uint32 ssrc, 00715 const IPV6Multicast& ia, tpport_t dataPort, 00716 tpport_t controlPort, uint32 membersSize, 00717 RTPApplication& app, uint32 iface) : 00718 ServiceQueue(ssrc,membersSize,app) 00719 { build(ia,dataPort,controlPort,iface); } 00720 00721 virtual size_t dispatchBYE(const std::string &str) 00722 { 00723 return QueueRTCPManager::dispatchBYE(str); 00724 } 00725 00726 inline virtual 00727 ~TRTPSessionBaseIPV6() 00728 { 00729 endSocket(); 00730 } 00731 00732 inline RTPDataChannel *getDSO(void) 00733 {return dso;} 00734 00735 protected: 00739 inline bool 00740 isPendingData(microtimeout_t timeout) 00741 { return dso->isPendingRecv(timeout); } 00742 00743 inline IPV6Host 00744 getDataSender(tpport_t *port = NULL) const 00745 { return dso->getSender(port); } 00746 00747 inline size_t 00748 getNextDataPacketSize() const 00749 { return dso->getNextPacketSize(); } 00750 00760 inline size_t 00761 recvData(unsigned char* buffer, size_t len, 00762 IPV6Host& na, tpport_t& tp) 00763 { na = dso->getSender(tp); return dso->recv(buffer, len); } 00764 00765 inline void 00766 setDataPeerIPV6(const IPV6Host &host, tpport_t port) 00767 { dso->setPeer(host,port); } 00768 00773 inline size_t 00774 sendDataIPV6(const unsigned char* const buffer, size_t len) 00775 { return dso->send(buffer, len); } 00776 00777 inline SOCKET getDataRecvSocket() const 00778 { return dso->getRecvSocket(); } 00779 00784 inline bool 00785 isPendingControl(microtimeout_t timeout) 00786 { return cso->isPendingRecv(timeout); } 00787 00788 inline IPV6Host 00789 getControlSender(tpport_t *port = NULL) const 00790 { return cso->getSender(port); } 00791 00801 inline size_t 00802 recvControl(unsigned char *buffer, size_t len, 00803 IPV6Host& na, tpport_t& tp) 00804 { na = cso->getSender(tp); return cso->recv(buffer,len); } 00805 00806 inline void 00807 setControlPeerIPV6(const IPV6Host &host, tpport_t port) 00808 { cso->setPeer(host,port); } 00809 00815 inline size_t 00816 sendControl(const unsigned char* const buffer, size_t len) 00817 { return cso->send(buffer,len); } 00818 00819 inline SOCKET getControlRecvSocket() const 00820 { return cso->getRecvSocket(); } 00821 00822 inline void 00823 endSocket() 00824 { 00825 dso->endSocket(); 00826 cso->endSocket(); 00827 if (dso) delete dso; 00828 dso = NULL; 00829 if (cso) delete cso; 00830 cso = NULL; 00831 } 00832 00833 private: 00834 void 00835 build(const IPV6Host& ia, tpport_t dataPort, 00836 tpport_t controlPort) 00837 { 00838 if ( 0 == controlPort ) { 00839 dataBasePort = even_port(dataPort); 00840 controlBasePort = dataBasePort + 1; 00841 } else { 00842 dataBasePort = dataPort; 00843 controlBasePort = controlPort; 00844 } 00845 dso = new RTPDataChannel(ia,dataBasePort); 00846 cso = new RTCPChannel(ia,controlBasePort); 00847 } 00848 00849 void 00850 build(const IPV6Multicast& ia, tpport_t dataPort, 00851 tpport_t controlPort, uint32 iface) 00852 { 00853 if ( 0 == controlPort ) { 00854 dataBasePort = even_port(dataPort); 00855 controlBasePort = dataBasePort + 1; 00856 } else { 00857 dataBasePort = dataPort; 00858 controlBasePort = controlPort; 00859 } 00860 dso = new RTPDataChannel(IPV6Host("0.0.0.0"),dataBasePort); 00861 cso = new RTCPChannel(IPV6Host("0.0.0.0"),controlBasePort); 00862 joinGroup(ia,iface); 00863 } 00864 00871 inline Socket::Error 00872 joinGroup(const IPV6Multicast& ia, uint32 iface) 00873 { 00874 Socket::Error error = dso->setMulticast(true); 00875 if ( error ) return error; 00876 error = dso->join(ia,iface); 00877 if ( error ) return error; 00878 error = cso->setMulticast(true); 00879 if ( error ) { 00880 dso->drop(ia); 00881 return error; 00882 } 00883 error = cso->join(ia,iface); 00884 if ( error ) { 00885 dso->drop(ia); 00886 return error; 00887 } 00888 return Socket::errSuccess; 00889 } 00890 00897 inline Socket::Error 00898 leaveGroup(const IPV6Multicast& ia) 00899 { 00900 Socket::Error error = dso->setMulticast(false); 00901 if ( error ) return error; 00902 error = dso->leaveGroup(ia); 00903 if ( error ) return error; 00904 error = cso->setMulticast(false); 00905 if ( error ) return error; 00906 return cso->leaveGroup(ia); 00907 } 00908 00915 inline Socket::Error 00916 setMcastTTL(uint8 ttl) 00917 { 00918 Socket::Error error = dso->setMulticast(true); 00919 if ( error ) return error; 00920 error = dso->setTimeToLive(ttl); 00921 if ( error ) return error; 00922 error = cso->setMulticast(true); 00923 if ( error ) return error; 00924 return cso->setTimeToLive(ttl); 00925 } 00926 00934 inline tpport_t 00935 odd_port(tpport_t port) 00936 { return (port & 0x01)? (port) : (port - 1); } 00937 00945 inline tpport_t 00946 even_port(tpport_t port) 00947 { return (port & 0x01)? (port - 1) : (port); } 00948 00949 tpport_t dataBasePort; 00950 tpport_t controlBasePort; 00951 00952 protected: 00953 RTPDataChannel* dso; 00954 RTCPChannel* cso; 00955 friend class RTPSessionBaseHandler; 00956 }; 00957 00968 template 00969 <class RTPDataChannel = DualRTPUDPIPv6Channel, 00970 class RTCPChannel = DualRTPUDPIPv6Channel, 00971 class ServiceQueue = AVPQueue> 00972 class __EXPORT SingleThreadRTPSessionIPV6 : 00973 protected Thread, 00974 public TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue> 00975 { 00976 public: 00977 SingleThreadRTPSessionIPV6(const IPV6Host& ia, 00978 tpport_t dataPort = DefaultRTPDataPort, 00979 tpport_t controlPort = 0, 00980 int pri = 0, 00981 uint32 memberssize = 00982 MembershipBookkeeping::defaultMembersHashSize, 00983 RTPApplication& app = defaultApplication() 00984 #if defined(_MSC_VER) && _MSC_VER >= 1300 00985 ); 00986 #else 00987 ): 00988 Thread(pri), 00989 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue> 00990 (ia,dataPort,controlPort,memberssize,app) 00991 { } 00992 #endif 00993 00994 SingleThreadRTPSessionIPV6(const IPV6Multicast& ia, 00995 tpport_t dataPort = DefaultRTPDataPort, 00996 tpport_t controlPort = 0, 00997 int pri = 0, 00998 uint32 memberssize = 00999 MembershipBookkeeping::defaultMembersHashSize, 01000 RTPApplication& app = defaultApplication(), 01001 uint32 iface = 0 01002 #if defined(_MSC_VER) && _MSC_VER >= 1300 01003 ); 01004 #else 01005 ): 01006 Thread(pri), 01007 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue> 01008 (ia,dataPort,controlPort,memberssize,app,iface) 01009 { } 01010 #endif 01011 01012 ~SingleThreadRTPSessionIPV6() 01013 { 01014 if (isRunning()) { 01015 disableStack(); Thread::join(); 01016 } 01017 } 01018 01019 #if defined(_MSC_VER) && _MSC_VER >= 1300 01020 virtual void startRunning(); 01021 #else 01022 01025 void 01026 startRunning() 01027 { enableStack(); Thread::start(); } 01028 #endif 01029 01030 01031 protected: 01032 inline void enableStack(void) 01033 {TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();} 01034 01035 inline void disableStack(void) 01036 {TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();} 01037 01038 inline microtimeout_t getSchedulingTimeout(void) 01039 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();} 01040 01041 inline void controlReceptionService(void) 01042 {TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();} 01043 01044 inline void controlTransmissionService(void) 01045 {TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();} 01046 01047 inline timeval getRTCPCheckInterval(void) 01048 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();} 01049 01050 inline size_t dispatchDataPacket(void) 01051 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();} 01052 01053 #if defined(_MSC_VER) && _MSC_VER >= 1300 01054 virtual void run(void); 01055 01056 virtual void timerTick(void); 01057 01058 virtual bool isPendingData(microtimeout_t timeout); 01059 #else 01060 01061 virtual void timerTick(void) 01062 {return;} 01063 01064 virtual bool isPendingData(microtimeout_t timeout) 01065 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);} 01066 01071 virtual void run(void) 01072 { 01073 microtimeout_t timeout = 0; 01074 while ( ServiceQueue::isActive() ) { 01075 if ( timeout < 1000 ){ // !(timeout/1000) 01076 timeout = getSchedulingTimeout(); 01077 } 01078 controlReceptionService(); 01079 controlTransmissionService(); 01080 microtimeout_t maxWait = 01081 timeval2microtimeout(getRTCPCheckInterval()); 01082 // make sure the scheduling timeout is 01083 // <= the check interval for RTCP 01084 // packets 01085 timeout = (timeout > maxWait)? maxWait : timeout; 01086 if ( timeout < 1000 ) { // !(timeout/1000) 01087 dispatchDataPacket(); 01088 timerTick(); 01089 } else { 01090 if ( isPendingData(timeout/1000) ) { 01091 takeInDataPacket(); 01092 } 01093 timeout = 0; 01094 } 01095 } 01096 dispatchBYE("GNU ccRTP stack finishing."); 01097 Thread::exit(); 01098 } 01099 01100 #endif 01101 01102 inline size_t takeInDataPacket(void) 01103 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();} 01104 01105 inline size_t dispatchBYE(const std::string &str) 01106 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);} 01107 }; 01108 01117 typedef SingleThreadRTPSessionIPV6<> RTPSessionIPV6; 01118 01124 typedef RTPSessionIPV6 RTPSocketIPV6; 01125 01134 typedef SingleThreadRTPSessionIPV6<SymmetricRTPChannelIPV6, 01135 SymmetricRTPChannelIPV6> SymmetricRTPSessionIPV6; 01136 01137 01138 #endif 01139 // sessions 01141 01142 END_NAMESPACE 01143 01144 #endif //CCXX_RTP_RTP_H_ 01145