1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 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
29class BufferedPacket; // forward
30class BufferedPacketFactory; // forward
31
32class MultiFramedRTPSource: public RTPSource {
33protected:
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
50protected:
51 Boolean fCurrentPacketBeginsFrame;
52 Boolean fCurrentPacketCompletesFrame;
53
54protected:
55 // redefined virtual functions:
56 virtual void doGetNextFrame();
57 virtual void doStopGettingFrames();
58
59private:
60 // redefined virtual functions:
61 virtual void setPacketReorderingThresholdTime(unsigned uSeconds);
62
63private:
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
86class BufferedPacket {
87public:
88 BufferedPacket();
89 virtual ~BufferedPacket();
90
91 Boolean hasUsableData() const { return fTail > fHead; }
92 unsigned useCount() const { return fUseCount; }
93
94 Boolean fillInData(RTPInterface& rtpInterface, struct sockaddr_in& 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
108 BufferedPacket*& nextPacket() { return fNextPacket; }
109
110 unsigned short rtpSeqNo() const { return fRTPSeqNo; }
111 struct timeval const& timeReceived() const { return fTimeReceived; }
112
113 unsigned char* data() const { return &fBuf[fHead]; }
114 unsigned dataSize() const { return fTail-fHead; }
115 Boolean rtpMarkerBit() const { return fRTPMarkerBit; }
116 Boolean& isFirstPacket() { return fIsFirstPacket; }
117 unsigned bytesAvailable() const { return fPacketSize - fTail; }
118
119protected:
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
134private:
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
151class BufferedPacketFactory {
152public:
153 BufferedPacketFactory();
154 virtual ~BufferedPacketFactory();
155
156 virtual BufferedPacket* createNewPacket(MultiFramedRTPSource* ourSource);
157};
158
159#endif
160