liveMedia/include/RTPSink.hh

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // "liveMedia"
00017 // Copyright (c) 1996-2013 Live Networks, Inc.  All rights reserved.
00018 // RTP Sinks
00019 // C++ header
00020 
00021 #ifndef _RTP_SINK_HH
00022 #define _RTP_SINK_HH
00023 
00024 #ifndef _MEDIA_SINK_HH
00025 #include "MediaSink.hh"
00026 #endif
00027 #ifndef _RTP_INTERFACE_HH
00028 #include "RTPInterface.hh"
00029 #endif
00030 
00031 class RTPTransmissionStatsDB; // forward
00032 
00033 class RTPSink: public MediaSink {
00034 public:
00035   static Boolean lookupByName(UsageEnvironment& env, char const* sinkName,
00036                               RTPSink*& resultSink);
00037 
00038   // used by RTSP servers:
00039   Groupsock const& groupsockBeingUsed() const { return *(fRTPInterface.gs()); }
00040   Groupsock& groupsockBeingUsed() { return *(fRTPInterface.gs()); }
00041 
00042   unsigned char rtpPayloadType() const { return fRTPPayloadType; }
00043   unsigned rtpTimestampFrequency() const { return fTimestampFrequency; }
00044   void setRTPTimestampFrequency(unsigned freq) {
00045     fTimestampFrequency = freq;
00046   }
00047   char const* rtpPayloadFormatName() const {return fRTPPayloadFormatName;}
00048 
00049   unsigned numChannels() const { return fNumChannels; }
00050 
00051   virtual char const* sdpMediaType() const; // for use in SDP m= lines
00052   virtual char* rtpmapLine() const; // returns a string to be delete[]d
00053   virtual char const* auxSDPLine();
00054       // optional SDP line (e.g. a=fmtp:...)
00055 
00056   u_int16_t currentSeqNo() const { return fSeqNo; }
00057   u_int32_t presetNextTimestamp();
00058       // ensures that the next timestamp to be used will correspond to
00059       // the current 'wall clock' time.
00060 
00061   RTPTransmissionStatsDB& transmissionStatsDB() const {
00062     return *fTransmissionStatsDB;
00063   }
00064 
00065   Boolean nextTimestampHasBeenPreset() const { return fNextTimestampHasBeenPreset; }
00066   Boolean& enableRTCPReports() { return fEnableRTCPReports; }
00067 
00068   void getTotalBitrate(unsigned& outNumBytes, double& outElapsedTime);
00069       // returns the number of bytes sent since the last time that we
00070       // were called, and resets the counter.
00071 
00072   struct timeval const& creationTime() const { return fCreationTime; }
00073   struct timeval const& initialPresentationTime() const { return fInitialPresentationTime; }
00074   struct timeval const& mostRecentPresentationTime() const { return fMostRecentPresentationTime; }
00075   void resetPresentationTimes();
00076 
00077   // Hacks to allow sending RTP over TCP (RFC 2236, section 10.12):
00078   void setStreamSocket(int sockNum, unsigned char streamChannelId) {
00079     fRTPInterface.setStreamSocket(sockNum, streamChannelId);
00080   }
00081   void addStreamSocket(int sockNum, unsigned char streamChannelId) {
00082     fRTPInterface.addStreamSocket(sockNum, streamChannelId);
00083   }
00084   void removeStreamSocket(int sockNum, unsigned char streamChannelId) {
00085     fRTPInterface.removeStreamSocket(sockNum, streamChannelId);
00086   }
00087   void setServerRequestAlternativeByteHandler(int socketNum, ServerRequestAlternativeByteHandler* handler, void* clientData) {
00088     fRTPInterface.setServerRequestAlternativeByteHandler(socketNum, handler, clientData);
00089   }
00090 
00091 protected:
00092   RTPSink(UsageEnvironment& env,
00093           Groupsock* rtpGS, unsigned char rtpPayloadType,
00094           u_int32_t rtpTimestampFrequency,
00095           char const* rtpPayloadFormatName,
00096           unsigned numChannels);
00097         // abstract base class
00098 
00099   virtual ~RTPSink();
00100 
00101   // used by RTCP:
00102   friend class RTCPInstance;
00103   friend class RTPTransmissionStats;
00104   u_int32_t SSRC() const {return fSSRC;}
00105      // later need a means of changing the SSRC if there's a collision #####
00106   u_int32_t convertToRTPTimestamp(struct timeval tv);
00107   unsigned packetCount() const {return fPacketCount;}
00108   unsigned octetCount() const {return fOctetCount;}
00109 
00110 protected:
00111   RTPInterface fRTPInterface;
00112   unsigned char fRTPPayloadType;
00113   unsigned fPacketCount, fOctetCount, fTotalOctetCount /*incl RTP hdr*/;
00114   struct timeval fTotalOctetCountStartTime, fInitialPresentationTime, fMostRecentPresentationTime;
00115   u_int32_t fCurrentTimestamp;
00116   u_int16_t fSeqNo;
00117 
00118 private:
00119   // redefined virtual functions:
00120   virtual Boolean isRTPSink() const;
00121 
00122 private:
00123   u_int32_t fSSRC, fTimestampBase;
00124   unsigned fTimestampFrequency;
00125   Boolean fNextTimestampHasBeenPreset;
00126   Boolean fEnableRTCPReports; // whether RTCP "SR" reports should be sent for this sink (default: True)
00127   char const* fRTPPayloadFormatName;
00128   unsigned fNumChannels;
00129   struct timeval fCreationTime;
00130 
00131   RTPTransmissionStatsDB* fTransmissionStatsDB;
00132 };
00133 
00134 
00135 class RTPTransmissionStats; // forward
00136 
00137 class RTPTransmissionStatsDB {
00138 public:
00139   unsigned numReceivers() const { return fNumReceivers; }
00140 
00141   class Iterator {
00142   public:
00143     Iterator(RTPTransmissionStatsDB& receptionStatsDB);
00144     virtual ~Iterator();
00145 
00146     RTPTransmissionStats* next();
00147         // NULL if none
00148 
00149   private:
00150     HashTable::Iterator* fIter;
00151   };
00152 
00153   // The following is called whenever a RTCP RR packet is received:
00154   void noteIncomingRR(u_int32_t SSRC, struct sockaddr_in const& lastFromAddress,
00155                       unsigned lossStats, unsigned lastPacketNumReceived,
00156                       unsigned jitter, unsigned lastSRTime, unsigned diffSR_RRTime);
00157 
00158   // The following is called when a RTCP BYE packet is received:
00159   void removeRecord(u_int32_t SSRC);
00160 
00161   RTPTransmissionStats* lookup(u_int32_t SSRC) const;
00162 
00163 private: // constructor and destructor, called only by RTPSink:
00164   friend class RTPSink;
00165   RTPTransmissionStatsDB(RTPSink& rtpSink);
00166   virtual ~RTPTransmissionStatsDB();
00167 
00168 private:
00169   void add(u_int32_t SSRC, RTPTransmissionStats* stats);
00170 
00171 private:
00172   friend class Iterator;
00173   unsigned fNumReceivers;
00174     RTPSink& fOurRTPSink;
00175   HashTable* fTable;
00176 };
00177 
00178 class RTPTransmissionStats {
00179 public:
00180   u_int32_t SSRC() const {return fSSRC;}
00181   struct sockaddr_in const& lastFromAddress() const {return fLastFromAddress;}
00182   unsigned lastPacketNumReceived() const {return fLastPacketNumReceived;}
00183   unsigned firstPacketNumReported() const {return fFirstPacketNumReported;}
00184   unsigned totNumPacketsLost() const {return fTotNumPacketsLost;}
00185   unsigned jitter() const {return fJitter;}
00186   unsigned lastSRTime() const { return fLastSRTime; }
00187   unsigned diffSR_RRTime() const { return fDiffSR_RRTime; }
00188   unsigned roundTripDelay() const;
00189       // The round-trip delay (in units of 1/65536 seconds) computed from
00190       // the most recently-received RTCP RR packet.
00191   struct timeval timeCreated() const {return fTimeCreated;}
00192   struct timeval lastTimeReceived() const {return fTimeReceived;}
00193   void getTotalOctetCount(u_int32_t& hi, u_int32_t& lo);
00194   void getTotalPacketCount(u_int32_t& hi, u_int32_t& lo);
00195 
00196   // Information which requires at least two RRs to have been received:
00197   unsigned packetsReceivedSinceLastRR() const;
00198   u_int8_t packetLossRatio() const { return fPacketLossRatio; }
00199      // as an 8-bit fixed-point number
00200   int packetsLostBetweenRR() const;
00201 
00202 private:
00203   // called only by RTPTransmissionStatsDB:
00204   friend class RTPTransmissionStatsDB;
00205   RTPTransmissionStats(RTPSink& rtpSink, u_int32_t SSRC);
00206   virtual ~RTPTransmissionStats();
00207 
00208   void noteIncomingRR(struct sockaddr_in const& lastFromAddress,
00209                       unsigned lossStats, unsigned lastPacketNumReceived,
00210                       unsigned jitter,
00211                       unsigned lastSRTime, unsigned diffSR_RRTime);
00212 
00213 private:
00214   RTPSink& fOurRTPSink;
00215   u_int32_t fSSRC;
00216   struct sockaddr_in fLastFromAddress;
00217   unsigned fLastPacketNumReceived;
00218   u_int8_t fPacketLossRatio;
00219   unsigned fTotNumPacketsLost;
00220   unsigned fJitter;
00221   unsigned fLastSRTime;
00222   unsigned fDiffSR_RRTime;
00223   struct timeval fTimeCreated, fTimeReceived;
00224   Boolean fAtLeastTwoRRsHaveBeenReceived;
00225   unsigned fOldLastPacketNumReceived;
00226   unsigned fOldTotNumPacketsLost;
00227   Boolean fFirstPacket;
00228   unsigned fFirstPacketNumReported;
00229   u_int32_t fLastOctetCount, fTotalOctetCount_hi, fTotalOctetCount_lo;
00230   u_int32_t fLastPacketCount, fTotalPacketCount_hi, fTotalPacketCount_lo;
00231 };
00232 
00233 #endif

Generated on Mon Apr 29 13:28:01 2013 for live by  doxygen 1.5.2