| 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 | |