1 /**********
2 This library is free software; you can redistribute it and/or modify it under
3 the terms of the GNU Lesser General Public License as published by the
4 Free Software Foundation; either version 3 of the License, or (at your
5 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6 
7 This library is distributed in the hope that it will be useful, but WITHOUT
8 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
10 more details.
11 
12 You should have received a copy of the GNU Lesser General Public License
13 along with this library; if not, write to the Free Software Foundation, Inc.,
14 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
15 **********/
16 // "liveMedia"
17 // Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
18 // RTP source for a common kind of payload format: Those which pack multiple,
19 // complete codec frames (as many as possible) into each RTP packet.
20 // C++ header
21 
22 #ifndef _MULTI_FRAMED_RTP_SOURCE_HH
23 #define _MULTI_FRAMED_RTP_SOURCE_HH
24 
25 #ifndef _RTP_SOURCE_HH
26 #include "RTPSource.hh"
27 #endif
28 
29 class BufferedPacket; // forward
30 class BufferedPacketFactory; // forward
31 
32 class MultiFramedRTPSource: public RTPSource {
33 protected:
34   MultiFramedRTPSource(UsageEnvironment& env, Groupsock* RTPgs,
35 		       unsigned char rtpPayloadFormat,
36 		       unsigned rtpTimestampFrequency,
37 		       BufferedPacketFactory* packetFactory = NULL);
38       // virtual base class
39   virtual ~MultiFramedRTPSource();
40 
41   virtual Boolean processSpecialHeader(BufferedPacket* packet,
42 				       unsigned& resultSpecialHeaderSize);
43       // Subclasses redefine this to handle any special, payload format
44       // specific header that follows the RTP header.
45 
46   virtual Boolean packetIsUsableInJitterCalculation(unsigned char* packet,
47 						    unsigned packetSize);
48       // The default implementation returns True, but this can be redefined
49 
50 protected:
51   Boolean fCurrentPacketBeginsFrame;
52   Boolean fCurrentPacketCompletesFrame;
53 
54 protected:
55   // redefined virtual functions:
56   virtual void doGetNextFrame();
57   virtual void doStopGettingFrames();
58 
59 private:
60   // redefined virtual functions:
61   virtual void setPacketReorderingThresholdTime(unsigned uSeconds);
62 
63 private:
64   void reset();
65   void doGetNextFrame1();
66 
67   static void networkReadHandler(MultiFramedRTPSource* source, int /*mask*/);
68   void networkReadHandler1();
69 
70   Boolean fAreDoingNetworkReads;
71   BufferedPacket* fPacketReadInProgress;
72   Boolean fNeedDelivery;
73   Boolean fPacketLossInFragmentedFrame;
74   unsigned char* fSavedTo;
75   unsigned fSavedMaxSize;
76 
77   // A buffer to (optionally) hold incoming pkts that have been reorderered
78   class ReorderingPacketBuffer* fReorderingBuffer;
79 };
80 
81 
82 // A 'packet data' class that's used to implement the above.
83 // Note that this can be subclassed - if desired - to redefine
84 // "nextEnclosedFrameParameters()".
85 
86 class BufferedPacket {
87 public:
88   BufferedPacket();
89   virtual ~BufferedPacket();
90 
hasUsableData() const91   Boolean hasUsableData() const { return fTail > fHead; }
useCount() const92   unsigned useCount() const { return fUseCount; }
93 
94   Boolean fillInData(RTPInterface& rtpInterface, struct sockaddr_storage& fromAddress, Boolean& packetReadWasIncomplete);
95   void assignMiscParams(unsigned short rtpSeqNo, unsigned rtpTimestamp,
96 			struct timeval presentationTime,
97 			Boolean hasBeenSyncedUsingRTCP,
98 			Boolean rtpMarkerBit, struct timeval timeReceived);
99   void skip(unsigned numBytes); // used to skip over an initial header
100   void removePadding(unsigned numBytes); // used to remove trailing bytes
101   void appendData(unsigned char* newData, unsigned numBytes);
102   void use(unsigned char* to, unsigned toSize,
103 	   unsigned& bytesUsed, unsigned& bytesTruncated,
104 	   unsigned short& rtpSeqNo, unsigned& rtpTimestamp,
105 	   struct timeval& presentationTime,
106 	   Boolean& hasBeenSyncedUsingRTCP, Boolean& rtpMarkerBit);
107 
nextPacket()108   BufferedPacket*& nextPacket() { return fNextPacket; }
109 
rtpSeqNo() const110   unsigned short rtpSeqNo() const { return fRTPSeqNo; }
timeReceived() const111   struct timeval const& timeReceived() const { return fTimeReceived; }
112 
data() const113   unsigned char* data() const { return &fBuf[fHead]; }
dataSize() const114   unsigned dataSize() const { return fTail-fHead; }
rtpMarkerBit() const115   Boolean rtpMarkerBit() const { return fRTPMarkerBit; }
isFirstPacket()116   Boolean& isFirstPacket() { return fIsFirstPacket; }
bytesAvailable() const117   unsigned bytesAvailable() const { return fPacketSize - fTail; }
118 
119 protected:
120   virtual void reset();
121   virtual unsigned nextEnclosedFrameSize(unsigned char*& framePtr,
122 					 unsigned dataSize);
123       // The above function has been deprecated.  Instead, new subclasses should use:
124   virtual void getNextEnclosedFrameParameters(unsigned char*& framePtr,
125 					      unsigned dataSize,
126 					      unsigned& frameSize,
127 					      unsigned& frameDurationInMicroseconds);
128 
129   unsigned fPacketSize;
130   unsigned char* fBuf;
131   unsigned fHead;
132   unsigned fTail;
133 
134 private:
135   BufferedPacket* fNextPacket; // used to link together packets
136 
137   unsigned fUseCount;
138   unsigned short fRTPSeqNo;
139   unsigned fRTPTimestamp;
140   struct timeval fPresentationTime; // corresponding to "fRTPTimestamp"
141   Boolean fHasBeenSyncedUsingRTCP;
142   Boolean fRTPMarkerBit;
143   Boolean fIsFirstPacket;
144   struct timeval fTimeReceived;
145 };
146 
147 // A 'factory' class for creating "BufferedPacket" objects.
148 // If you want to subclass "BufferedPacket", then you'll also
149 // want to subclass this, to redefine createNewPacket()
150 
151 class BufferedPacketFactory {
152 public:
153   BufferedPacketFactory();
154   virtual ~BufferedPacketFactory();
155 
156   virtual BufferedPacket* createNewPacket(MultiFramedRTPSource* ourSource);
157 };
158 
159 #endif
160