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 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 

Generated on 14 Aug 2013 for ccRTP by  doxygen 1.4.7