| /********** |
| This library is free software; you can redistribute it and/or modify it under |
| the terms of the GNU Lesser General Public License as published by the |
| Free Software Foundation; either version 3 of the License, or (at your |
| option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) |
| |
| This library is distributed in the hope that it will be useful, but WITHOUT |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for |
| more details. |
| |
| You should have received a copy of the GNU Lesser General Public License |
| along with this library; if not, write to the Free Software Foundation, Inc., |
| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| **********/ |
| // "liveMedia" |
| // Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved. |
| // RTP source for a common kind of payload format: Those which pack multiple, |
| // complete codec frames (as many as possible) into each RTP packet. |
| // C++ header |
| |
| #ifndef _MULTI_FRAMED_RTP_SOURCE_HH |
| #define _MULTI_FRAMED_RTP_SOURCE_HH |
| |
| #ifndef _RTP_SOURCE_HH |
| #include "RTPSource.hh" |
| #endif |
| |
| class BufferedPacket; // forward |
| class BufferedPacketFactory; // forward |
| |
| class MultiFramedRTPSource: public RTPSource { |
| protected: |
| MultiFramedRTPSource(UsageEnvironment& env, Groupsock* RTPgs, |
| unsigned char rtpPayloadFormat, |
| unsigned rtpTimestampFrequency, |
| BufferedPacketFactory* packetFactory = NULL); |
| // virtual base class |
| virtual ~MultiFramedRTPSource(); |
| |
| virtual Boolean processSpecialHeader(BufferedPacket* packet, |
| unsigned& resultSpecialHeaderSize); |
| // Subclasses redefine this to handle any special, payload format |
| // specific header that follows the RTP header. |
| |
| virtual Boolean packetIsUsableInJitterCalculation(unsigned char* packet, |
| unsigned packetSize); |
| // The default implementation returns True, but this can be redefined |
| |
| protected: |
| Boolean fCurrentPacketBeginsFrame; |
| Boolean fCurrentPacketCompletesFrame; |
| |
| protected: |
| // redefined virtual functions: |
| virtual void doGetNextFrame(); |
| virtual void doStopGettingFrames(); |
| |
| private: |
| // redefined virtual functions: |
| virtual void setPacketReorderingThresholdTime(unsigned uSeconds); |
| |
| private: |
| void reset(); |
| void doGetNextFrame1(); |
| |
| static void networkReadHandler(MultiFramedRTPSource* source, int /*mask*/); |
| void networkReadHandler1(); |
| |
| Boolean fAreDoingNetworkReads; |
| BufferedPacket* fPacketReadInProgress; |
| Boolean fNeedDelivery; |
| Boolean fPacketLossInFragmentedFrame; |
| unsigned char* fSavedTo; |
| unsigned fSavedMaxSize; |
| |
| // A buffer to (optionally) hold incoming pkts that have been reorderered |
| class ReorderingPacketBuffer* fReorderingBuffer; |
| }; |
| |
| |
| // A 'packet data' class that's used to implement the above. |
| // Note that this can be subclassed - if desired - to redefine |
| // "nextEnclosedFrameParameters()". |
| |
| class BufferedPacket { |
| public: |
| BufferedPacket(); |
| virtual ~BufferedPacket(); |
| |
| Boolean hasUsableData() const { return fTail > fHead; } |
| unsigned useCount() const { return fUseCount; } |
| |
| Boolean fillInData(RTPInterface& rtpInterface, struct sockaddr_in& fromAddress, Boolean& packetReadWasIncomplete); |
| void assignMiscParams(unsigned short rtpSeqNo, unsigned rtpTimestamp, |
| struct timeval presentationTime, |
| Boolean hasBeenSyncedUsingRTCP, |
| Boolean rtpMarkerBit, struct timeval timeReceived); |
| void skip(unsigned numBytes); // used to skip over an initial header |
| void removePadding(unsigned numBytes); // used to remove trailing bytes |
| void appendData(unsigned char* newData, unsigned numBytes); |
| void use(unsigned char* to, unsigned toSize, |
| unsigned& bytesUsed, unsigned& bytesTruncated, |
| unsigned short& rtpSeqNo, unsigned& rtpTimestamp, |
| struct timeval& presentationTime, |
| Boolean& hasBeenSyncedUsingRTCP, Boolean& rtpMarkerBit); |
| |
| BufferedPacket*& nextPacket() { return fNextPacket; } |
| |
| unsigned short rtpSeqNo() const { return fRTPSeqNo; } |
| struct timeval const& timeReceived() const { return fTimeReceived; } |
| |
| unsigned char* data() const { return &fBuf[fHead]; } |
| unsigned dataSize() const { return fTail-fHead; } |
| Boolean rtpMarkerBit() const { return fRTPMarkerBit; } |
| Boolean& isFirstPacket() { return fIsFirstPacket; } |
| unsigned bytesAvailable() const { return fPacketSize - fTail; } |
| |
| protected: |
| virtual void reset(); |
| virtual unsigned nextEnclosedFrameSize(unsigned char*& framePtr, |
| unsigned dataSize); |
| // The above function has been deprecated. Instead, new subclasses should use: |
| virtual void getNextEnclosedFrameParameters(unsigned char*& framePtr, |
| unsigned dataSize, |
| unsigned& frameSize, |
| unsigned& frameDurationInMicroseconds); |
| |
| unsigned fPacketSize; |
| unsigned char* fBuf; |
| unsigned fHead; |
| unsigned fTail; |
| |
| private: |
| BufferedPacket* fNextPacket; // used to link together packets |
| |
| unsigned fUseCount; |
| unsigned short fRTPSeqNo; |
| unsigned fRTPTimestamp; |
| struct timeval fPresentationTime; // corresponding to "fRTPTimestamp" |
| Boolean fHasBeenSyncedUsingRTCP; |
| Boolean fRTPMarkerBit; |
| Boolean fIsFirstPacket; |
| struct timeval fTimeReceived; |
| }; |
| |
| // A 'factory' class for creating "BufferedPacket" objects. |
| // If you want to subclass "BufferedPacket", then you'll also |
| // want to subclass this, to redefine createNewPacket() |
| |
| class BufferedPacketFactory { |
| public: |
| BufferedPacketFactory(); |
| virtual ~BufferedPacketFactory(); |
| |
| virtual BufferedPacket* createNewPacket(MultiFramedRTPSource* ourSource); |
| }; |
| |
| #endif |