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 (BufferedPacket* packet, |
42 | unsigned& ); |
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 | |
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 | |
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 | |