rtp.h

Go to the documentation of this file.
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 #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 
00168         inline virtual
00169         ~TRTPSessionBase()
00170         { 
00171         dispatchBYE("RTP session being destroyed, GNU ccRTP stack finishing.");
00172          endSocket(); 
00173         }
00174 
00175         inline RTPDataChannel *getDSO(void)
00176                 {return dso;};
00177 
00178 protected:
00182         inline bool
00183         isPendingData(microtimeout_t timeout)
00184         { return dso->isPendingRecv(timeout); }
00185 
00186         InetHostAddress
00187         getDataSender(tpport_t *port = NULL) const
00188         { return dso->getSender(port); }
00189 
00190         inline size_t
00191         getNextDataPacketSize() const
00192         { return dso->getNextPacketSize(); }
00193 
00203         inline size_t
00204         recvData(unsigned char* buffer, size_t len, 
00205                  InetHostAddress& na, tpport_t& tp)
00206         { na = dso->getSender(tp); return dso->recv(buffer, len); }
00207 
00208         inline void
00209         setDataPeer(const InetAddress &host, tpport_t port)
00210         { dso->setPeer(host,port); }
00211 
00216         inline size_t
00217         sendData(const unsigned char* const buffer, size_t len)
00218         { return dso->send(buffer, len); }
00219 
00220         inline SOCKET getDataRecvSocket() const
00221         { return dso->getRecvSocket(); }
00222 
00227         inline bool
00228         isPendingControl(microtimeout_t timeout)
00229         { return cso->isPendingRecv(timeout); }
00230 
00231         InetHostAddress
00232         getControlSender(tpport_t *port = NULL) const
00233         { return cso->getSender(port); }
00234 
00244         inline size_t
00245         recvControl(unsigned char *buffer, size_t len,
00246                     InetHostAddress& na, tpport_t& tp)
00247         { na = cso->getSender(tp); return cso->recv(buffer,len); }
00248 
00249         inline void
00250         setControlPeer(const InetAddress &host, tpport_t port)
00251         { cso->setPeer(host,port); }
00252 
00258         inline size_t
00259         sendControl(const unsigned char* const buffer, size_t len)
00260         { return cso->send(buffer,len); }
00261 
00262         inline SOCKET getControlRecvSocket() const
00263         { return cso->getRecvSocket(); }
00264         
00265         inline void
00266         endSocket()
00267         { 
00268                 if (dso) {
00269                  dso->endSocket();
00270                  delete dso;
00271                 }
00272                 dso = NULL;
00273                 if (cso) {
00274                  cso->endSocket();
00275                  delete cso;
00276                 }
00277                 cso = NULL;
00278         }
00279 
00280 private:
00281         void 
00282         build(const InetHostAddress& ia, tpport_t dataPort, 
00283               tpport_t controlPort)
00284         {
00285                 if ( 0 == controlPort ) {
00286                         dataBasePort = even_port(dataPort); 
00287                         controlBasePort = dataBasePort + 1;
00288                 } else {
00289                         dataBasePort = dataPort;
00290                         controlBasePort = controlPort;
00291                 }
00292                 dso = new RTPDataChannel(ia,dataBasePort);
00293                 cso = new RTCPChannel(ia,controlBasePort);
00294         }
00295 
00296         void 
00297         build(const InetMcastAddress& ia, tpport_t dataPort, 
00298               tpport_t controlPort, uint32 iface)
00299         {
00300                 if ( 0 == controlPort ) {
00301                         dataBasePort = even_port(dataPort); 
00302                         controlBasePort = dataBasePort + 1;
00303                 } else {
00304                         dataBasePort = dataPort;
00305                         controlBasePort = controlPort;
00306                 }
00307                 dso = new RTPDataChannel(InetHostAddress("0.0.0.0"),dataBasePort);
00308                 cso = new RTCPChannel(InetHostAddress("0.0.0.0"),controlBasePort);
00309                 joinGroup(ia,iface);
00310         }
00311 
00318         inline Socket::Error
00319         joinGroup(const InetMcastAddress& ia, uint32 iface)
00320         { 
00321                 Socket::Error error  = dso->setMulticast(true);
00322                 if ( error ) return error;
00323                 error = dso->join(ia,iface); 
00324                 if ( error ) return error;
00325                 error = cso->setMulticast(true);
00326                 if ( error ) {
00327                         dso->drop(ia);
00328                         return error;
00329                 }
00330                 error = cso->join(ia,iface);
00331                 if ( error ) {
00332                         dso->drop(ia);
00333                         return error;
00334                 }
00335                 return Socket::errSuccess;
00336         }
00337 
00344         inline Socket::Error
00345         leaveGroup(const InetMcastAddress& ia)
00346         {
00347                 Socket::Error error = dso->setMulticast(false);
00348                 if ( error ) return error;
00349                 error = dso->leaveGroup(ia);
00350                 if ( error ) return error;
00351                 error = cso->setMulticast(false);
00352                 if ( error ) return error;
00353                 return cso->leaveGroup(ia);
00354         }
00355 
00362         inline Socket::Error
00363         setMcastTTL(uint8 ttl)
00364         {
00365                 Socket::Error error = dso->setMulticast(true);
00366                 if ( error ) return error;
00367                 error = dso->setTimeToLive(ttl);
00368                 if ( error ) return error;
00369                 error = cso->setMulticast(true);
00370                 if ( error ) return error;
00371                 return cso->setTimeToLive(ttl);
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(const InetMcastAddress& 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                                uint32 iface = 0)
00449 #if defined(_MSC_VER) && _MSC_VER >= 1300
00450                                    ;
00451 #else
00452                                    :
00453                         Thread(pri),
00454                 TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
00455         (ia,dataPort,controlPort,memberssize,app,iface)
00456         { }
00457 #endif
00458 
00459         ~SingleThreadRTPSession()
00460         { terminate(); }
00461 
00462 #if defined(_MSC_VER) && _MSC_VER >= 1300 
00463         virtual void startRunning();
00464 #else
00465 
00468         void
00469         startRunning()
00470         { enableStack(); Thread::start(); }
00471 #endif
00472 
00473 
00474 protected:
00475         inline void enableStack(void)
00476                 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}
00477 
00478         inline microtimeout_t getSchedulingTimeout(void)
00479                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}
00480 
00481         inline void controlReceptionService(void)
00482                 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}
00483 
00484         inline void controlTransmissionService(void)
00485                 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}
00486 
00487         inline timeval getRTCPCheckInterval(void)
00488                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();};
00489 
00490         inline size_t dispatchDataPacket(void)
00491                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();};
00492 
00493 #if defined(_MSC_VER) && _MSC_VER >= 1300
00494         virtual void run(void);
00495 
00496         virtual void timerTick(void);
00497 
00498         virtual bool isPendingData(microtimeout_t timeout); 
00499 #else
00500 
00501         virtual void timerTick(void)
00502                 {return;}
00503 
00504         virtual bool isPendingData(microtimeout_t timeout)
00505                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}
00506 
00511         virtual void run(void)
00512         {
00513                 microtimeout_t timeout = 0;
00514                 while ( ServiceQueue::isActive() ) {
00515                         if ( timeout < 1000 ){ // !(timeout/1000)
00516                                 timeout = getSchedulingTimeout();
00517                         }
00518                         setCancel(cancelDeferred);
00519                         controlReceptionService();
00520                         controlTransmissionService();
00521                         setCancel(cancelImmediate);
00522                         microtimeout_t maxWait = 
00523                                 timeval2microtimeout(getRTCPCheckInterval());
00524                         // make sure the scheduling timeout is
00525                         // <= the check interval for RTCP
00526                         // packets
00527                         timeout = (timeout > maxWait)? maxWait : timeout;
00528                         if ( timeout < 1000 ) { // !(timeout/1000)
00529                                 setCancel(cancelDeferred);
00530                                 dispatchDataPacket();
00531                                 setCancel(cancelImmediate);
00532                                 timerTick();
00533                         } else {
00534                                 if ( isPendingData(timeout/1000) ) {
00535                                         setCancel(cancelDeferred);
00536                                         takeInDataPacket();
00537                                         setCancel(cancelImmediate);
00538                                 }
00539                                 timeout = 0;
00540                         }
00541                 }
00542                 dispatchBYE("GNU ccRTP stack finishing.");
00543                 sleep((timeout_t)~0);
00544         }
00545 
00546 #endif
00547 
00548         inline size_t takeInDataPacket(void)
00549                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}
00550 
00551         inline size_t dispatchBYE(const std::string &str)
00552                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
00553 };
00554 
00563 typedef SingleThreadRTPSession<> RTPSession;
00564 
00570 typedef RTPSession RTPSocket;
00571 
00580 typedef SingleThreadRTPSession<SymmetricRTPChannel,
00581                                SymmetricRTPChannel> SymmetricRTPSession;
00582 
00583 
00584 #ifdef  CCXX_IPV6
00585 
00607 template <class RTPDataChannel = DualRTPUDPIPv6Channel, 
00608           class RTCPChannel = DualRTPUDPIPv6Channel, 
00609           class ServiceQueue = AVPQueue>
00610 class __EXPORT TRTPSessionBaseIPV6 : public ServiceQueue
00611 {
00612 public:
00622         TRTPSessionBaseIPV6(const IPV6Host& ia, tpport_t dataPort,
00623                          tpport_t controlPort, uint32 membersSize,
00624                          RTPApplication& app) :
00625                 ServiceQueue(membersSize,app)
00626         { build(ia,dataPort,controlPort); }
00627 
00639         TRTPSessionBaseIPV6(uint32 ssrc,
00640                          const IPV6Host& ia, 
00641                          tpport_t dataPort, tpport_t controlPort,
00642                          uint32 membersSize, RTPApplication& app):
00643                          ServiceQueue(ssrc,membersSize,app)
00644         { build(ia,dataPort,controlPort); }
00645                          
00658         TRTPSessionBaseIPV6(const IPV6Multicast& ia, tpport_t dataPort,
00659                         tpport_t controlPort, uint32 membersSize,
00660                          RTPApplication& app, uint32 iface) :
00661                 ServiceQueue(membersSize,app)
00662         { build(ia,dataPort,controlPort,iface); }
00663 
00678         TRTPSessionBaseIPV6(uint32 ssrc,
00679                         const IPV6Multicast& ia, tpport_t dataPort,
00680                         tpport_t controlPort, uint32 membersSize,
00681                          RTPApplication& app, uint32 iface) :
00682                 ServiceQueue(ssrc,membersSize,app)
00683         { build(ia,dataPort,controlPort,iface); }
00684 
00685         virtual size_t dispatchBYE(const std::string &str)
00686         {
00687         return QueueRTCPManager::dispatchBYE(str);
00688         }
00689 
00690         inline virtual
00691         ~TRTPSessionBaseIPV6()
00692         { 
00693         dispatchBYE("RTP session being destroyed, GNU ccRTP stack finishing.");
00694          endSocket(); 
00695         }
00696 
00697         inline RTPDataChannel *getDSO(void)
00698                 {return dso;};
00699 
00700 protected:
00704         inline bool
00705         isPendingData(microtimeout_t timeout)
00706         { return dso->isPendingRecv(timeout); }
00707 
00708         inline IPV6Host
00709         getDataSender(tpport_t *port = NULL) const
00710         { return dso->getSender(port); }
00711 
00712         inline size_t
00713         getNextDataPacketSize() const
00714         { return dso->getNextPacketSize(); }
00715 
00725         inline size_t
00726         recvData(unsigned char* buffer, size_t len, 
00727                  IPV6Host& na, tpport_t& tp)
00728         { na = dso->getSender(tp); return dso->recv(buffer, len); }
00729 
00730         inline void
00731         setDataPeer(const IPV6Host &host, tpport_t port)
00732         { dso->setPeer(host,port); }
00733 
00738         inline size_t
00739         sendData(const unsigned char* const buffer, size_t len)
00740         { return dso->send(buffer, len); }
00741 
00742         inline SOCKET getDataRecvSocket() const
00743         { return dso->getRecvSocket(); }
00744 
00749         inline bool
00750         isPendingControl(microtimeout_t timeout)
00751         { return cso->isPendingRecv(timeout); }
00752 
00753         inline IPV6Host
00754         getControlSender(tpport_t *port = NULL) const
00755         { return cso->getSender(port); }
00756 
00766         inline size_t
00767         recvControl(unsigned char *buffer, size_t len,
00768                     IPV6Host& na, tpport_t& tp)
00769         { na = cso->getSender(tp); return cso->recv(buffer,len); }
00770 
00771         inline void
00772         setControlPeer(const IPV6Host &host, tpport_t port)
00773         { cso->setPeer(host,port); }
00774 
00780         inline size_t
00781         sendControl(const unsigned char* const buffer, size_t len)
00782         { return cso->send(buffer,len); }
00783 
00784         inline SOCKET getControlRecvSocket() const
00785         { return cso->getRecvSocket(); }
00786         
00787         inline void
00788         endSocket()
00789         { 
00790                 dso->endSocket();
00791                 cso->endSocket();
00792                 if (dso) delete dso;
00793                 dso = NULL;
00794                 if (cso) delete cso;
00795                 cso = NULL;
00796         }
00797 
00798 private:
00799         void 
00800         build(const IPV6Host& ia, tpport_t dataPort, 
00801               tpport_t controlPort)
00802         {
00803                 if ( 0 == controlPort ) {
00804                         dataBasePort = even_port(dataPort); 
00805                         controlBasePort = dataBasePort + 1;
00806                 } else {
00807                         dataBasePort = dataPort;
00808                         controlBasePort = controlPort;
00809                 }
00810                 dso = new RTPDataChannel(ia,dataBasePort);
00811                 cso = new RTCPChannel(ia,controlBasePort);
00812         }
00813 
00814         void 
00815         build(const IPV6Multicast& ia, tpport_t dataPort, 
00816               tpport_t controlPort, uint32 iface)
00817         {
00818                 if ( 0 == controlPort ) {
00819                         dataBasePort = even_port(dataPort); 
00820                         controlBasePort = dataBasePort + 1;
00821                 } else {
00822                         dataBasePort = dataPort;
00823                         controlBasePort = controlPort;
00824                 }
00825                 dso = new RTPDataChannel(IPV6Host("0.0.0.0"),dataBasePort);
00826                 cso = new RTCPChannel(IPV6Host("0.0.0.0"),controlBasePort);
00827                 joinGroup(ia,iface);
00828         }
00829 
00836         inline Socket::Error
00837         joinGroup(const IPV6Multicast& ia, uint32 iface)
00838         { 
00839                 Socket::Error error  = dso->setMulticast(true);
00840                 if ( error ) return error;
00841                 error = dso->join(ia,iface); 
00842                 if ( error ) return error;
00843                 error = cso->setMulticast(true);
00844                 if ( error ) {
00845                         dso->drop(ia);
00846                         return error;
00847                 }
00848                 error = cso->join(ia,iface);
00849                 if ( error ) {
00850                         dso->drop(ia);
00851                         return error;
00852                 }
00853                 return Socket::errSuccess;
00854         }
00855 
00862         inline Socket::Error
00863         leaveGroup(const IPV6Multicast& ia)
00864         {
00865                 Socket::Error error = dso->setMulticast(false);
00866                 if ( error ) return error;
00867                 error = dso->leaveGroup(ia);
00868                 if ( error ) return error;
00869                 error = cso->setMulticast(false);
00870                 if ( error ) return error;
00871                 return cso->leaveGroup(ia);
00872         }
00873 
00880         inline Socket::Error
00881         setMcastTTL(uint8 ttl)
00882         {
00883                 Socket::Error error = dso->setMulticast(true);
00884                 if ( error ) return error;
00885                 error = dso->setTimeToLive(ttl);
00886                 if ( error ) return error;
00887                 error = cso->setMulticast(true);
00888                 if ( error ) return error;
00889                 return cso->setTimeToLive(ttl);
00890         }
00891 
00899         inline tpport_t
00900         odd_port(tpport_t port)
00901         { return (port & 0x01)? (port) : (port - 1); }
00902 
00910         inline tpport_t
00911         even_port(tpport_t port)
00912         { return (port & 0x01)? (port - 1) : (port); }
00913 
00914         tpport_t dataBasePort;
00915         tpport_t controlBasePort;
00916 
00917 protected:
00918         RTPDataChannel* dso;
00919         RTCPChannel* cso;
00920         friend class RTPSessionBaseHandler;
00921 };
00922 
00933 template
00934 <class RTPDataChannel = DualRTPUDPIPv6Channel, 
00935  class RTCPChannel = DualRTPUDPIPv6Channel, 
00936  class ServiceQueue = AVPQueue>
00937 class __EXPORT SingleThreadRTPSessionIPV6 : 
00938         protected Thread,
00939         public TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
00940 {
00941 public:
00942         SingleThreadRTPSessionIPV6(const IPV6Host& ia, 
00943                                tpport_t dataPort = DefaultRTPDataPort, 
00944                                tpport_t controlPort = 0,
00945                                int pri = 0,
00946                                uint32 memberssize = 
00947                                MembershipBookkeeping::defaultMembersHashSize,
00948                                RTPApplication& app = defaultApplication()
00949 #if defined(_MSC_VER) && _MSC_VER >= 1300
00950                                    );
00951 #else
00952                                    ):
00953                         Thread(pri),
00954                 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
00955         (ia,dataPort,controlPort,memberssize,app)
00956         { }
00957 #endif
00958         
00959         SingleThreadRTPSessionIPV6(const IPV6Multicast& ia, 
00960                                tpport_t dataPort = DefaultRTPDataPort, 
00961                                tpport_t controlPort = 0, 
00962                                int pri = 0,
00963                                uint32 memberssize = 
00964                                MembershipBookkeeping::defaultMembersHashSize,
00965                                RTPApplication& app = defaultApplication(),
00966                                uint32 iface = 0)
00967 #if defined(_MSC_VER) && _MSC_VER >= 1300
00968                                    ;
00969 #else
00970                                    :
00971                         Thread(pri),
00972                 TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
00973         (ia,dataPort,controlPort,memberssize,app,iface)
00974         { }
00975 #endif
00976 
00977         ~SingleThreadRTPSessionIPV6()
00978         { terminate(); }
00979 
00980 #if defined(_MSC_VER) && _MSC_VER >= 1300 
00981         virtual void startRunning();
00982 #else
00983 
00986         void
00987         startRunning()
00988         { enableStack(); Thread::start(); }
00989 #endif
00990 
00991 
00992 protected:
00993         inline void enableStack(void)
00994                 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}
00995 
00996         inline microtimeout_t getSchedulingTimeout(void)
00997                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}
00998 
00999         inline void controlReceptionService(void)
01000                 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}
01001 
01002         inline void controlTransmissionService(void)
01003                 {TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}
01004 
01005         inline timeval getRTCPCheckInterval(void)
01006                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();};
01007 
01008         inline size_t dispatchDataPacket(void)
01009                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();};
01010 
01011 #if defined(_MSC_VER) && _MSC_VER >= 1300
01012         virtual void run(void);
01013 
01014         virtual void timerTick(void);
01015 
01016         virtual bool isPendingData(microtimeout_t timeout); 
01017 #else
01018 
01019         virtual void timerTick(void)
01020                 {return;}
01021 
01022         virtual bool isPendingData(microtimeout_t timeout)
01023                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}
01024 
01029         virtual void run(void)
01030         {
01031                 microtimeout_t timeout = 0;
01032                 while ( ServiceQueue::isActive() ) {
01033                         if ( timeout < 1000 ){ // !(timeout/1000)
01034                                 timeout = getSchedulingTimeout();
01035                         }
01036                         setCancel(cancelDeferred);
01037                         controlReceptionService();
01038                         controlTransmissionService();
01039                         setCancel(cancelImmediate);
01040                         microtimeout_t maxWait = 
01041                                 timeval2microtimeout(getRTCPCheckInterval());
01042                         // make sure the scheduling timeout is
01043                         // <= the check interval for RTCP
01044                         // packets
01045                         timeout = (timeout > maxWait)? maxWait : timeout;
01046                         if ( timeout < 1000 ) { // !(timeout/1000)
01047                                 setCancel(cancelDeferred);
01048                                 dispatchDataPacket();
01049                                 setCancel(cancelImmediate);
01050                                 timerTick();
01051                         } else {
01052                                 if ( isPendingData(timeout/1000) ) {
01053                                         setCancel(cancelDeferred);
01054                                         takeInDataPacket();
01055                                         setCancel(cancelImmediate);
01056                                 }
01057                                 timeout = 0;
01058                         }
01059                 }
01060                 dispatchBYE("GNU ccRTP stack finishing.");
01061                 sleep((timeout_t)~0);
01062         }
01063 
01064 #endif
01065 
01066         inline size_t takeInDataPacket(void)
01067                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}
01068 
01069         inline size_t dispatchBYE(const std::string &str)
01070                 {return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
01071 };
01072 
01081 typedef SingleThreadRTPSessionIPV6<> RTPSessionIPV6;
01082 
01088 typedef RTPSessionIPV6 RTPSocketIPV6;
01089 \
01098 typedef SingleThreadRTPSessionIPV6<SymmetricRTPChannelIPV6,
01099                                SymmetricRTPChannelIPV6> SymmetricRTPSessionIPV6;
01100 
01101 
01102 #endif
01103  // sessions
01105 
01106 #ifdef  CCXX_NAMESPACES
01107 }
01108 #endif
01109 
01110 #endif  //CCXX_RTP_RTP_H_
01111 

Generated on Wed Oct 4 23:55:38 2006 for ccRTP by  doxygen 1.4.7