ccRTP
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks. 00003 // Copyright (C) 2015 Cherokees of Idaho. 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with GNU ccRTP. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free software 00019 // library without restriction. Specifically, if other files instantiate 00020 // templates or use macros or inline functions from this file, or you compile 00021 // this file and link it with other files to produce an executable, this 00022 // file does not by itself cause the resulting executable to be covered by 00023 // the GNU General Public License. This exception does not however 00024 // invalidate any other reasons why the executable file might be covered by 00025 // the GNU General Public License. 00026 // 00027 // This exception applies only to the code released under the name GNU 00028 // ccRTP. If you copy code from other releases into a copy of GNU 00029 // ccRTP, as the General Public License permits, the exception does 00030 // not apply to the code that you add in this way. To avoid misleading 00031 // anyone as to the status of such modified files, you must delete 00032 // this exception notice from them. 00033 // 00034 // If you write modifications of your own for GNU ccRTP, it is your choice 00035 // whether to permit this exception to apply to your modifications. 00036 // If you do not wish that, delete this exception notice. 00037 // 00038 00050 #ifndef CCXX_RTP_RTP_H_ 00051 #define CCXX_RTP_RTP_H_ 00052 00053 #include <ccrtp/cqueue.h> 00054 #include <ccrtp/channel.h> 00055 00056 NAMESPACE_COMMONCPP 00057 00084 template <class RTPDataChannel = DualRTPUDPIPv4Channel, 00085 class RTCPChannel = DualRTPUDPIPv4Channel, 00086 class ServiceQueue = AVPQueue> 00087 class __EXPORT TRTPSessionBase : public ServiceQueue 00088 { 00089 public: 00099 TRTPSessionBase(const InetHostAddress& ia, tpport_t dataPort, 00100 tpport_t controlPort, uint32 membersSize, 00101 RTPApplication& app) : 00102 ServiceQueue(membersSize,app) 00103 { build(ia,dataPort,controlPort); } 00104 00116 TRTPSessionBase(uint32 ssrc, 00117 const InetHostAddress& ia, 00118 tpport_t dataPort, tpport_t controlPort, 00119 uint32 membersSize, RTPApplication& app): 00120 ServiceQueue(ssrc,membersSize,app) 00121 { build(ia,dataPort,controlPort); } 00122 00135 TRTPSessionBase(const InetMcastAddress& ia, tpport_t dataPort, 00136 tpport_t controlPort, uint32 membersSize, 00137 RTPApplication& app, uint32 iface) : 00138 ServiceQueue(membersSize,app) 00139 { build(ia,dataPort,controlPort,iface); } 00140 00155 TRTPSessionBase(uint32 ssrc, 00156 const InetMcastAddress& ia, tpport_t dataPort, 00157 tpport_t controlPort, uint32 membersSize, 00158 RTPApplication& app, uint32 iface) : 00159 ServiceQueue(ssrc,membersSize,app) 00160 { build(ia,dataPort,controlPort,iface); } 00161 00162 virtual size_t dispatchBYE(const std::string &str) 00163 { 00164 return QueueRTCPManager::dispatchBYE(str); 00165 } 00166 00173 inline Socket::Error 00174 setMcastTTL(uint8 ttl) 00175 { 00176 Socket::Error error = dso->setMulticast(true); 00177 if ( error ) return error; 00178 error = dso->setTimeToLive(ttl); 00179 if ( error ) return error; 00180 error = cso->setMulticast(true); 00181 if ( error ) return error; 00182 return cso->setTimeToLive(ttl); 00183 } 00184 00185 inline virtual 00186 ~TRTPSessionBase() 00187 { 00188 endSocket(); 00189 } 00190 00191 inline RTPDataChannel *getDSO(void) 00192 {return dso;} 00193 00194 protected: 00198 inline bool 00199 isPendingData(microtimeout_t timeout) 00200 { return dso->isPendingRecv(timeout); } 00201 00202 InetHostAddress 00203 getDataSender(tpport_t *port = NULL) const 00204 { return dso->getSender(port); } 00205 00206 inline size_t 00207 getNextDataPacketSize() const 00208 { return dso->getNextPacketSize(); } 00209 00219 inline size_t 00220 recvData(unsigned char* buffer, size_t len, 00221 InetHostAddress& na, tpport_t& tp) 00222 { na = dso->getSender(tp); return dso->recv(buffer, len); } 00223 00224 inline void 00225 setDataPeer(const InetAddress &host, tpport_t port) 00226 { dso->setPeer(host,port); } 00227 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 ){ // !(timeout/1000) 00558 timeout = getSchedulingTimeout(); 00559 } 00560 controlReceptionService(); 00561 controlTransmissionService(); 00562 microtimeout_t maxWait = 00563 timeval2microtimeout(getRTCPCheckInterval()); 00564 // make sure the scheduling timeout is 00565 // <= the check interval for RTCP 00566 // packets 00567 timeout = (timeout > maxWait)? maxWait : timeout; 00568 if ( timeout < 1000 ) { // !(timeout/1000) 00569 dispatchDataPacket(); 00570 timerTick(); 00571 } else { 00572 if ( isPendingData(timeout/1000) ) { 00573 if (ServiceQueue::isActive()) { // take in only if active 00574 takeInDataPacket(); 00575 } 00576 } 00577 timeout = 0; 00578 } 00579 } 00580 dispatchBYE("GNU ccRTP stack finishing."); 00581 // Thread::exit(); 00582 } 00583 00584 #endif 00585 00586 inline size_t takeInDataPacket(void) 00587 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();} 00588 00589 inline size_t dispatchBYE(const std::string &str) 00590 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);} 00591 }; 00592 00601 typedef SingleThreadRTPSession<> RTPSession; 00602 00608 typedef RTPSession RTPSocket; 00609 00618 typedef SingleThreadRTPSession<SymmetricRTPChannel, 00619 SymmetricRTPChannel> SymmetricRTPSession; 00620 00621 #ifdef CCXX_IPV6 00622 00644 template <class RTPDataChannel = DualRTPUDPIPv6Channel, 00645 class RTCPChannel = DualRTPUDPIPv6Channel, 00646 class ServiceQueue = AVPQueue> 00647 class __EXPORT TRTPSessionBaseIPV6 : public ServiceQueue 00648 { 00649 public: 00659 TRTPSessionBaseIPV6(const IPV6Host& ia, tpport_t dataPort, 00660 tpport_t controlPort, uint32 membersSize, 00661 RTPApplication& app) : 00662 ServiceQueue(membersSize,app) 00663 { build(ia,dataPort,controlPort); } 00664 00676 TRTPSessionBaseIPV6(uint32 ssrc, 00677 const IPV6Host& ia, 00678 tpport_t dataPort, tpport_t controlPort, 00679 uint32 membersSize, RTPApplication& app): 00680 ServiceQueue(ssrc,membersSize,app) 00681 { build(ia,dataPort,controlPort); } 00682 00695 TRTPSessionBaseIPV6(const IPV6Multicast& ia, tpport_t dataPort, 00696 tpport_t controlPort, uint32 membersSize, 00697 RTPApplication& app, uint32 iface) : 00698 ServiceQueue(membersSize,app) 00699 { build(ia,dataPort,controlPort,iface); } 00700 00715 TRTPSessionBaseIPV6(uint32 ssrc, 00716 const IPV6Multicast& ia, tpport_t dataPort, 00717 tpport_t controlPort, uint32 membersSize, 00718 RTPApplication& app, uint32 iface) : 00719 ServiceQueue(ssrc,membersSize,app) 00720 { build(ia,dataPort,controlPort,iface); } 00721 00722 virtual size_t dispatchBYE(const std::string &str) 00723 { 00724 return QueueRTCPManager::dispatchBYE(str); 00725 } 00726 00727 inline virtual 00728 ~TRTPSessionBaseIPV6() 00729 { 00730 endSocket(); 00731 } 00732 00733 inline RTPDataChannel *getDSO(void) 00734 {return dso;} 00735 00736 protected: 00740 inline bool 00741 isPendingData(microtimeout_t timeout) 00742 { return dso->isPendingRecv(timeout); } 00743 00744 inline IPV6Host 00745 getDataSender(tpport_t *port = NULL) const 00746 { return dso->getSender(port); } 00747 00748 inline size_t 00749 getNextDataPacketSize() const 00750 { return dso->getNextPacketSize(); } 00751 00761 inline size_t 00762 recvData(unsigned char* buffer, size_t len, 00763 IPV6Host& na, tpport_t& tp) 00764 { na = dso->getSender(tp); return dso->recv(buffer, len); } 00765 00766 inline void 00767 setDataPeerIPV6(const IPV6Host &host, tpport_t port) 00768 { dso->setPeer(host,port); } 00769 00774 inline size_t 00775 sendDataIPV6(const unsigned char* const buffer, size_t len) 00776 { return dso->send(buffer, len); } 00777 00778 inline SOCKET getDataRecvSocket() const 00779 { return dso->getRecvSocket(); } 00780 00785 inline bool 00786 isPendingControl(microtimeout_t timeout) 00787 { return cso->isPendingRecv(timeout); } 00788 00789 inline IPV6Host 00790 getControlSender(tpport_t *port = NULL) const 00791 { return cso->getSender(port); } 00792 00802 inline size_t 00803 recvControl(unsigned char *buffer, size_t len, 00804 IPV6Host& na, tpport_t& tp) 00805 { na = cso->getSender(tp); return cso->recv(buffer,len); } 00806 00807 inline void 00808 setControlPeerIPV6(const IPV6Host &host, tpport_t port) 00809 { cso->setPeer(host,port); } 00810 00816 inline size_t 00817 sendControl(const unsigned char* const buffer, size_t len) 00818 { return cso->send(buffer,len); } 00819 00820 inline SOCKET getControlRecvSocket() const 00821 { return cso->getRecvSocket(); } 00822 00823 inline void 00824 endSocket() 00825 { 00826 dso->endSocket(); 00827 cso->endSocket(); 00828 if (dso) delete dso; 00829 dso = NULL; 00830 if (cso) delete cso; 00831 cso = NULL; 00832 } 00833 00834 private: 00835 void 00836 build(const IPV6Host& ia, tpport_t dataPort, 00837 tpport_t controlPort) 00838 { 00839 if ( 0 == controlPort ) { 00840 dataBasePort = even_port(dataPort); 00841 controlBasePort = dataBasePort + 1; 00842 } else { 00843 dataBasePort = dataPort; 00844 controlBasePort = controlPort; 00845 } 00846 dso = new RTPDataChannel(ia,dataBasePort); 00847 cso = new RTCPChannel(ia,controlBasePort); 00848 } 00849 00850 void 00851 build(const IPV6Multicast& ia, tpport_t dataPort, 00852 tpport_t controlPort, uint32 iface) 00853 { 00854 if ( 0 == controlPort ) { 00855 dataBasePort = even_port(dataPort); 00856 controlBasePort = dataBasePort + 1; 00857 } else { 00858 dataBasePort = dataPort; 00859 controlBasePort = controlPort; 00860 } 00861 dso = new RTPDataChannel(IPV6Host("0.0.0.0"),dataBasePort); 00862 cso = new RTCPChannel(IPV6Host("0.0.0.0"),controlBasePort); 00863 joinGroup(ia,iface); 00864 } 00865 00872 inline Socket::Error 00873 joinGroup(const IPV6Multicast& ia, uint32 iface) 00874 { 00875 Socket::Error error = dso->setMulticast(true); 00876 if ( error ) return error; 00877 error = dso->join(ia,iface); 00878 if ( error ) return error; 00879 error = cso->setMulticast(true); 00880 if ( error ) { 00881 dso->drop(ia); 00882 return error; 00883 } 00884 error = cso->join(ia,iface); 00885 if ( error ) { 00886 dso->drop(ia); 00887 return error; 00888 } 00889 return Socket::errSuccess; 00890 } 00891 00898 inline Socket::Error 00899 leaveGroup(const IPV6Multicast& ia) 00900 { 00901 Socket::Error error = dso->setMulticast(false); 00902 if ( error ) return error; 00903 error = dso->leaveGroup(ia); 00904 if ( error ) return error; 00905 error = cso->setMulticast(false); 00906 if ( error ) return error; 00907 return cso->leaveGroup(ia); 00908 } 00909 00916 inline Socket::Error 00917 setMcastTTL(uint8 ttl) 00918 { 00919 Socket::Error error = dso->setMulticast(true); 00920 if ( error ) return error; 00921 error = dso->setTimeToLive(ttl); 00922 if ( error ) return error; 00923 error = cso->setMulticast(true); 00924 if ( error ) return error; 00925 return cso->setTimeToLive(ttl); 00926 } 00927 00935 inline tpport_t 00936 odd_port(tpport_t port) 00937 { return (port & 0x01)? (port) : (port - 1); } 00938 00946 inline tpport_t 00947 even_port(tpport_t port) 00948 { return (port & 0x01)? (port - 1) : (port); } 00949 00950 tpport_t dataBasePort; 00951 tpport_t controlBasePort; 00952 00953 protected: 00954 RTPDataChannel* dso; 00955 RTCPChannel* cso; 00956 friend class RTPSessionBaseHandler; 00957 }; 00958 00969 template 00970 <class RTPDataChannel = DualRTPUDPIPv6Channel, 00971 class RTCPChannel = DualRTPUDPIPv6Channel, 00972 class ServiceQueue = AVPQueue> 00973 class __EXPORT SingleThreadRTPSessionIPV6 : 00974 protected Thread, 00975 public TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue> 00976 { 00977 public: 00978 SingleThreadRTPSessionIPV6(const IPV6Host& ia, 00979 tpport_t dataPort = DefaultRTPDataPort, 00980 tpport_t controlPort = 0, 00981 int pri = 0, 00982 uint32 memberssize = 00983 MembershipBookkeeping::defaultMembersHashSize, 00984 RTPApplication& app = defaultApplication() 00985 #if defined(_MSC_VER) && _MSC_VER >= 1300 00986 ); 00987 #else 00988 ): 00989 Thread(pri), 00990 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue> 00991 (ia,dataPort,controlPort,memberssize,app) 00992 { } 00993 #endif 00994 00995 SingleThreadRTPSessionIPV6(const IPV6Multicast& ia, 00996 tpport_t dataPort = DefaultRTPDataPort, 00997 tpport_t controlPort = 0, 00998 int pri = 0, 00999 uint32 memberssize = 01000 MembershipBookkeeping::defaultMembersHashSize, 01001 RTPApplication& app = defaultApplication(), 01002 uint32 iface = 0 01003 #if defined(_MSC_VER) && _MSC_VER >= 1300 01004 ); 01005 #else 01006 ): 01007 Thread(pri), 01008 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue> 01009 (ia,dataPort,controlPort,memberssize,app,iface) 01010 { } 01011 #endif 01012 01013 ~SingleThreadRTPSessionIPV6() 01014 { 01015 if (isRunning()) { 01016 disableStack(); Thread::join(); 01017 } 01018 } 01019 01020 #if defined(_MSC_VER) && _MSC_VER >= 1300 01021 virtual void startRunning(); 01022 #else 01023 01026 void 01027 startRunning() 01028 { enableStack(); Thread::start(); } 01029 #endif 01030 01031 01032 protected: 01033 inline void enableStack(void) 01034 {TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();} 01035 01036 inline void disableStack(void) 01037 {TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();} 01038 01039 inline microtimeout_t getSchedulingTimeout(void) 01040 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();} 01041 01042 inline void controlReceptionService(void) 01043 {TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();} 01044 01045 inline void controlTransmissionService(void) 01046 {TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();} 01047 01048 inline timeval getRTCPCheckInterval(void) 01049 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();} 01050 01051 inline size_t dispatchDataPacket(void) 01052 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();} 01053 01054 #if defined(_MSC_VER) && _MSC_VER >= 1300 01055 virtual void run(void); 01056 01057 virtual void timerTick(void); 01058 01059 virtual bool isPendingData(microtimeout_t timeout); 01060 #else 01061 01062 virtual void timerTick(void) 01063 {return;} 01064 01065 virtual bool isPendingData(microtimeout_t timeout) 01066 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);} 01067 01072 virtual void run(void) 01073 { 01074 microtimeout_t timeout = 0; 01075 while ( ServiceQueue::isActive() ) { 01076 if ( timeout < 1000 ){ // !(timeout/1000) 01077 timeout = getSchedulingTimeout(); 01078 } 01079 controlReceptionService(); 01080 controlTransmissionService(); 01081 microtimeout_t maxWait = 01082 timeval2microtimeout(getRTCPCheckInterval()); 01083 // make sure the scheduling timeout is 01084 // <= the check interval for RTCP 01085 // packets 01086 timeout = (timeout > maxWait)? maxWait : timeout; 01087 if ( timeout < 1000 ) { // !(timeout/1000) 01088 dispatchDataPacket(); 01089 timerTick(); 01090 } else { 01091 if ( isPendingData(timeout/1000) ) { 01092 takeInDataPacket(); 01093 } 01094 timeout = 0; 01095 } 01096 } 01097 dispatchBYE("GNU ccRTP stack finishing."); 01098 Thread::exit(); 01099 } 01100 01101 #endif 01102 01103 inline size_t takeInDataPacket(void) 01104 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();} 01105 01106 inline size_t dispatchBYE(const std::string &str) 01107 {return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);} 01108 }; 01109 01118 typedef SingleThreadRTPSessionIPV6<> RTPSessionIPV6; 01119 01125 typedef RTPSessionIPV6 RTPSocketIPV6; 01126 01135 typedef SingleThreadRTPSessionIPV6<SymmetricRTPChannelIPV6, 01136 SymmetricRTPChannelIPV6> SymmetricRTPSessionIPV6; 01137 01138 01139 #endif 01140 // sessions 01142 01143 END_NAMESPACE 01144 01145 #endif //CCXX_RTP_RTP_H_ 01146