📄 rtp.h
字号:
*/ inline size_t sendData(const unsigned char* const buffer, size_t len) { return dso->send(buffer, len); } inline SOCKET getDataRecvSocket() const { return dso->getRecvSocket(); } /** * @param timeout maximum timeout to wait, in microseconds * @return whether there are packets waiting to be picked */ inline bool isPendingControl(microtimeout_t timeout) { return cso->isPendingRecv(timeout); } inline IPV6Host getControlSender(tpport_t *port = NULL) const { return cso->getSender(port); } /** * Receive data from the control channel/socket. * * @param buffer Buffer where to get data. * @param len Maximum number of octets to get. * @param na Source network address. * @param tp Source transport port. * @return Number of octets actually read. **/ inline size_t recvControl(unsigned char *buffer, size_t len, IPV6Host& na, tpport_t& tp) { na = cso->getSender(tp); return cso->recv(buffer,len); } inline void setControlPeer(const IPV6Host &host, tpport_t port) { cso->setPeer(host,port); } /** * @return number of octets actually written * @param buffer * @param len */ inline size_t sendControl(const unsigned char* const buffer, size_t len) { return cso->send(buffer,len); } inline SOCKET getControlRecvSocket() const { return cso->getRecvSocket(); } inline void endSocket() { dso->endSocket(); cso->endSocket(); if (dso) delete dso; dso = NULL; if (cso) delete cso; cso = NULL; }private: void build(const IPV6Host& ia, tpport_t dataPort, tpport_t controlPort) { if ( 0 == controlPort ) { dataBasePort = even_port(dataPort); controlBasePort = dataBasePort + 1; } else { dataBasePort = dataPort; controlBasePort = controlPort; } dso = new RTPDataChannel(ia,dataBasePort); cso = new RTCPChannel(ia,controlBasePort); } void build(const IPV6Multicast& ia, tpport_t dataPort, tpport_t controlPort, uint32 iface) { if ( 0 == controlPort ) { dataBasePort = even_port(dataPort); controlBasePort = dataBasePort + 1; } else { dataBasePort = dataPort; controlBasePort = controlPort; } dso = new RTPDataChannel(IPV6Host("0.0.0.0"),dataBasePort); cso = new RTCPChannel(IPV6Host("0.0.0.0"),controlBasePort); joinGroup(ia,iface); } /** * Join a multicast group. * * @param ia address of the multicast group * @return error code from the socket operation */ inline Socket::Error joinGroup(const IPV6Multicast& ia, uint32 iface) { Socket::Error error = dso->setMulticast(true); if ( error ) return error; error = dso->join(ia,iface); if ( error ) return error; error = cso->setMulticast(true); if ( error ) { dso->drop(ia); return error; } error = cso->join(ia,iface); if ( error ) { dso->drop(ia); return error; } return Socket::errSuccess; } /** * Leave a multicast group. * * @param ia address of the multicast group * @return error code from the socket operation */ inline Socket::Error leaveGroup(const IPV6Multicast& ia) { Socket::Error error = dso->setMulticast(false); if ( error ) return error; error = dso->leaveGroup(ia); if ( error ) return error; error = cso->setMulticast(false); if ( error ) return error; return cso->leaveGroup(ia); } /** * Set the value of the TTL field in the sent packets. * * @param ttl Time To Live * @return error code from the socket operation */ inline Socket::Error setMcastTTL(uint8 ttl) { Socket::Error error = dso->setMulticast(true); if ( error ) return error; error = dso->setTimeToLive(ttl); if ( error ) return error; error = cso->setMulticast(true); if ( error ) return error; return cso->setTimeToLive(ttl); } /** * Ensure a port number is odd. If it is an even number, return * the next lower (odd) port number. * * @param port number to filter * @return filtered (odd) port number */ inline tpport_t odd_port(tpport_t port) { return (port & 0x01)? (port) : (port - 1); } /** * Ensure a port number is even. If it is an odd number, return * the next lower (even) port number. * * @param port number to filter * @return filtered (even) port number */ inline tpport_t even_port(tpport_t port) { return (port & 0x01)? (port - 1) : (port); } tpport_t dataBasePort; tpport_t controlBasePort;protected: RTPDataChannel* dso; RTCPChannel* cso; friend class RTPSessionBaseHandler;};/** * @class SingleThreadRTPSessionIPV6 * * This template class adds the threading aspect to the RTPSessionBase * template in one of the many possible ways. It inherits from a * single execution thread that schedules sending of outgoing packets * and receipt of incoming packets. * * @author David Sugar <dyfet@gnutelephony.org> **/template<class RTPDataChannel = DualRTPUDPIPv6Channel, class RTCPChannel = DualRTPUDPIPv6Channel, class ServiceQueue = AVPQueue>class __EXPORT SingleThreadRTPSessionIPV6 : protected Thread, public TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>{public: SingleThreadRTPSessionIPV6(const IPV6Host& ia, tpport_t dataPort = DefaultRTPDataPort, tpport_t controlPort = 0, int pri = 0, uint32 memberssize = MembershipBookkeeping::defaultMembersHashSize, RTPApplication& app = defaultApplication()#if defined(_MSC_VER) && _MSC_VER >= 1300 );#else ): Thread(pri), TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue> (ia,dataPort,controlPort,memberssize,app){ }#endifSingleThreadRTPSessionIPV6(const IPV6Multicast& ia, tpport_t dataPort = DefaultRTPDataPort, tpport_t controlPort = 0, int pri = 0, uint32 memberssize = MembershipBookkeeping::defaultMembersHashSize, RTPApplication& app = defaultApplication(), uint32 iface = 0#if defined(_MSC_VER) && _MSC_VER >= 1300 );#else ): Thread(pri), TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue> (ia,dataPort,controlPort,memberssize,app,iface){ }#endif~SingleThreadRTPSessionIPV6(){ if (isRunning()) { disableStack(); Thread::join(); }}#if defined(_MSC_VER) && _MSC_VER >= 1300virtual void startRunning();#else/** * Activate stack and start service thread. **/voidstartRunning(){ enableStack(); Thread::start(); }#endifprotected:inline void enableStack(void){TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}inline void disableStack(void){TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();}inline microtimeout_t getSchedulingTimeout(void){return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}inline void controlReceptionService(void){TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}inline void controlTransmissionService(void){TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}inline timeval getRTCPCheckInterval(void){return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();};inline size_t dispatchDataPacket(void){return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();};#if defined(_MSC_VER) && _MSC_VER >= 1300virtual void run(void);virtual void timerTick(void);virtual bool isPendingData(microtimeout_t timeout);#elsevirtual void timerTick(void){return;}virtual bool isPendingData(microtimeout_t timeout){return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}/** * Single runnable method for this RTP stacks, schedules * outgoing and incoming RTP data and RTCP packets. **/virtual void run(void){ microtimeout_t timeout = 0; while ( ServiceQueue::isActive() ) { if ( timeout < 1000 ){ // !(timeout/1000) timeout = getSchedulingTimeout(); } setCancel(cancelDeferred); controlReceptionService(); controlTransmissionService(); setCancel(cancelImmediate); microtimeout_t maxWait = timeval2microtimeout(getRTCPCheckInterval()); // make sure the scheduling timeout is // <= the check interval for RTCP // packets timeout = (timeout > maxWait)? maxWait : timeout; if ( timeout < 1000 ) { // !(timeout/1000) setCancel(cancelDeferred); dispatchDataPacket(); setCancel(cancelImmediate); timerTick(); } else { if ( isPendingData(timeout/1000) ) { setCancel(cancelDeferred); takeInDataPacket(); setCancel(cancelImmediate); } timeout = 0; } } dispatchBYE("GNU ccRTP stack finishing."); Thread::exit();}#endifinline size_t takeInDataPacket(void){return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}inline size_t dispatchBYE(const std::string &str){return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}};/** * @typedef RTPSession * * Uses two pairs of sockets for RTP data and RTCP * transmission/reception. * * @short UDP/IPv6 RTP Session scheduled by one thread of execution. **/typedef SingleThreadRTPSessionIPV6<> RTPSessionIPV6;/** * @typedef RTPSocket * * Alias for RTPSession. **/typedef RTPSessionIPV6 RTPSocketIPV6;/** * @typedef SymmetricRTPSession * * Uses one pair of sockets, (1) for RTP data and (2) for RTCP * transmission/reception. * * @short Symmetric UDP/IPv6 RTP session scheduled by one thread of execution. **/ typedef SingleThreadRTPSessionIPV6<SymmetricRTPChannelIPV6, SymmetricRTPChannelIPV6> SymmetricRTPSessionIPV6;#endif/** @}*/ // sessions#ifdef CCXX_NAMESPACES}#endif#endif //CCXX_RTP_RTP_H_/** EMACS ** * Local variables: * mode: c++ * c-basic-offset: 8 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -