00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _MULTI_FRAMED_RTP_SINK_HH
00023 #define _MULTI_FRAMED_RTP_SINK_HH
00024
00025 #ifndef _RTP_SINK_HH
00026 #include "RTPSink.hh"
00027 #endif
00028
00029 class MultiFramedRTPSink: public RTPSink {
00030 public:
00031 void setPacketSizes(unsigned preferredPacketSize, unsigned maxPacketSize);
00032
00033 protected:
00034 MultiFramedRTPSink(UsageEnvironment& env,
00035 Groupsock* rtpgs, unsigned char rtpPayloadType,
00036 unsigned rtpTimestampFrequency,
00037 char const* rtpPayloadFormatName,
00038 unsigned numChannels = 1);
00039
00040
00041 virtual ~MultiFramedRTPSink();
00042
00043 virtual void doSpecialFrameHandling(unsigned fragmentationOffset,
00044 unsigned char* frameStart,
00045 unsigned numBytesInFrame,
00046 struct timeval frameTimestamp,
00047 unsigned numRemainingBytes);
00048
00049 virtual Boolean allowFragmentationAfterStart() const;
00050
00051
00052 virtual Boolean allowOtherFramesAfterLastFragment() const;
00053
00054
00055 virtual Boolean frameCanAppearAfterPacketStart(unsigned char const* frameStart,
00056 unsigned numBytesInFrame) const;
00057
00058 virtual unsigned specialHeaderSize() const;
00059
00060 virtual unsigned frameSpecificHeaderSize() const;
00061
00062
00063
00064
00065 Boolean isFirstPacket() const { return fIsFirstPacket; }
00066 Boolean isFirstFrameInPacket() const { return fNumFramesUsedSoFar == 0; }
00067 Boolean curFragmentationOffset() const { return fCurFragmentationOffset; }
00068 void setMarkerBit();
00069 void setTimestamp(struct timeval timestamp);
00070 void setSpecialHeaderWord(unsigned word,
00071 unsigned wordPosition = 0);
00072 void setSpecialHeaderBytes(unsigned char const* bytes, unsigned numBytes,
00073 unsigned bytePosition = 0);
00074 void setFrameSpecificHeaderWord(unsigned word,
00075 unsigned wordPosition = 0);
00076 void setFrameSpecificHeaderBytes(unsigned char const* bytes, unsigned numBytes,
00077 unsigned bytePosition = 0);
00078 void setFramePadding(unsigned numPaddingBytes);
00079 unsigned numFramesUsedSoFar() const { return fNumFramesUsedSoFar; }
00080
00081 unsigned ourMaxPacketSize() const { return fOurMaxPacketSize; }
00082
00083 protected:
00084 virtual Boolean continuePlaying();
00085 virtual void stopPlaying();
00086
00087 private:
00088 void buildAndSendPacket(Boolean isFirstPacket);
00089 void packFrame();
00090 void sendPacketIfNecessary();
00091 static void sendNext(void* firstArg);
00092 friend void sendNext(void*);
00093
00094 static void afterGettingFrame(void* clientData,
00095 unsigned numBytesRead, unsigned numTruncatedBytes,
00096 struct timeval presentationTime,
00097 unsigned durationInMicroseconds);
00098 void afterGettingFrame1(unsigned numBytesRead, unsigned numTruncatedBytes,
00099 struct timeval presentationTime,
00100 unsigned durationInMicroseconds);
00101 Boolean isTooBigForAPacket(unsigned numBytes) const;
00102
00103 static void ourHandleClosure(void* clientData);
00104
00105 private:
00106 OutPacketBuffer* fOutBuf;
00107
00108 Boolean fNoFramesLeft;
00109 unsigned fNumFramesUsedSoFar;
00110 unsigned fCurFragmentationOffset;
00111 Boolean fPreviousFrameEndedFragmentation;
00112
00113 Boolean fIsFirstPacket;
00114 struct timeval fNextSendTime;
00115 unsigned fTimestampPosition;
00116 unsigned fSpecialHeaderPosition;
00117 unsigned fSpecialHeaderSize;
00118 unsigned fCurFrameSpecificHeaderPosition;
00119 unsigned fCurFrameSpecificHeaderSize;
00120 unsigned fTotalFrameSpecificHeaderSizes;
00121 unsigned fOurMaxPacketSize;
00122 };
00123
00124 #endif