Darwin-Streaming-Server/RTCPUtilitiesLib/RTCPPacket.h

335 lines
10 KiB
C
Raw Normal View History

/*
*
* @APPLE_LICENSE_HEADER_START@
*
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*
*/
/*
File: RTCPPacket.h
Contains: RTCPReceiverPacket de-packetizing classes
*/
//#define DEBUG_RTCP_PACKETS 1
#ifndef _RTCPPACKET_H_
#define _RTCPPACKET_H_
#include <stdlib.h>
#include "SafeStdLib.h"
#ifndef __Win32__
#include <sys/types.h>
#include <netinet/in.h>
#endif
#include "OSHeaders.h"
class RTCPPacket
{
public:
// Packet types
enum
{
kReceiverPacketType = 201, //UInt32
kSDESPacketType = 202, //UInt32
kAPPPacketType = 204 //UInt32
};
RTCPPacket() : fReceiverPacketBuffer(NULL) {}
virtual ~RTCPPacket() {}
//Call this before any accessor method. Returns true if successful, false otherwise
Bool16 ParsePacket(UInt8* inPacketBuffer, UInt32 inPacketLen);
inline int GetVersion();
inline Bool16 GetHasPadding();
inline int GetReportCount();
inline UInt8 GetPacketType();
inline UInt16 GetPacketLength(); //in 32-bit words
inline UInt32 GetPacketSSRC();
inline SInt16 GetHeader();
UInt8* GetPacketBuffer() { return fReceiverPacketBuffer; }
//Bool16 IsValidPacket();
virtual void Dump();
enum
{
kRTCPPacketSizeInBytes = 8, //All are UInt32s
kRTCPHeaderSizeInBytes = 4
};
protected:
UInt8* fReceiverPacketBuffer;
enum
{
kVersionOffset = 0,
kVersionMask = 0xC0000000UL,
kVersionShift = 30,
kHasPaddingOffset = 0,
kHasPaddingMask = 0x20000000UL,
kReportCountOffset = 0,
kReportCountMask = 0x1F000000UL,
kReportCountShift = 24,
kPacketTypeOffset = 0,
kPacketTypeMask = 0x00FF0000UL,
kPacketTypeShift = 16,
kPacketLengthOffset = 0,
kPacketLengthMask = 0x0000FFFFUL,
kPacketSourceIDOffset = 4, //packet sender SSRC
kPacketSourceIDSize = 4, //
kSupportedRTCPVersion = 2
};
};
class SourceDescriptionPacket : public RTCPPacket
{
public:
SourceDescriptionPacket() : RTCPPacket() {}
Bool16 ParseSourceDescription(UInt8* inPacketBuffer, UInt32 inPacketLength)
{ return ParsePacket(inPacketBuffer, inPacketLength); }
private:
};
class RTCPReceiverPacket : public RTCPPacket
{
public:
RTCPReceiverPacket() : RTCPPacket(), fRTCPReceiverReportArray(NULL) {}
//Call this before any accessor method. Returns true if successful, false otherwise
virtual Bool16 ParseReport(UInt8* inPacketBuffer, UInt32 inPacketLength);
inline UInt32 GetReportSourceID(int inReportNum);
UInt8 GetFractionLostPackets(int inReportNum);
UInt32 GetTotalLostPackets(int inReportNum);
inline UInt32 GetHighestSeqNumReceived(int inReportNum);
inline UInt32 GetJitter(int inReportNum);
inline UInt32 GetLastSenderReportTime(int inReportNum);
inline UInt32 GetLastSenderReportDelay(int inReportNum); //expressed in units of 1/65536 seconds
UInt32 GetCumulativeFractionLostPackets();
UInt32 GetCumulativeTotalLostPackets();
UInt32 GetCumulativeJitter();
//Bool16 IsValidPacket();
virtual void Dump(); //Override
protected:
inline int RecordOffset(int inReportNum);
UInt8* fRTCPReceiverReportArray; //points into fReceiverPacketBuffer
enum
{
kReportBlockOffsetSizeInBytes = 24, //All are UInt32s
kReportBlockOffset = kPacketSourceIDOffset + kPacketSourceIDSize,
kReportSourceIDOffset = 0, //SSRC for this report
kFractionLostOffset = 4,
kFractionLostMask = 0xFF000000UL,
kFractionLostShift = 24,
kTotalLostPacketsOffset = 4,
kTotalLostPacketsMask = 0x00FFFFFFUL,
kHighestSeqNumReceivedOffset = 8,
kJitterOffset = 12,
kLastSenderReportOffset = 16,
kLastSenderReportDelayOffset = 20
};
};
class RTCPSenderReportPacket : public RTCPReceiverPacket
{
public:
Bool16 ParseReport(UInt8* inPacketBuffer, UInt32 inPacketLength);
SInt64 GetNTPTimeStamp()
{
UInt32* fieldPtr = (UInt32*)&fReceiverPacketBuffer[kSRPacketNTPTimeStampMSW];
SInt64 timestamp = ntohl(*fieldPtr);
fieldPtr = (UInt32*)&fReceiverPacketBuffer[kSRPacketNTPTimeStampLSW];
return (timestamp << 32) | ntohl(*fieldPtr);
}
UInt32 GetRTPTimeStamp()
{
UInt32* fieldPtr = (UInt32*)&fReceiverPacketBuffer[kSRPacketRTPTimeStamp];
return ntohl(*fieldPtr);
}
protected:
enum
{
kRTCPSRPacketSenderInfoInBytes = 20,
kSRPacketNTPTimeStampMSW = 8,
kSRPacketNTPTimeStampLSW = 12,
kSRPacketRTPTimeStamp = 16
};
};
/************** RTCPPacket inlines **************/
inline int RTCPPacket::GetVersion()
{
UInt32* theVersionPtr = (UInt32*)&fReceiverPacketBuffer[kVersionOffset];
UInt32 theVersion = ntohl(*theVersionPtr);
return (int) ((theVersion & kVersionMask) >> kVersionShift);
}
inline Bool16 RTCPPacket::GetHasPadding()
{
UInt32* theHasPaddingPtr = (UInt32*)&fReceiverPacketBuffer[kHasPaddingOffset];
UInt32 theHasPadding = ntohl(*theHasPaddingPtr);
return (Bool16) (theHasPadding & kHasPaddingMask);
}
inline int RTCPPacket::GetReportCount()
{
UInt32* theReportCountPtr = (UInt32*)&fReceiverPacketBuffer[kReportCountOffset];
UInt32 theReportCount = ntohl(*theReportCountPtr);
return (int) ((theReportCount & kReportCountMask) >> kReportCountShift);
}
inline UInt8 RTCPPacket::GetPacketType()
{
UInt32* thePacketTypePtr = (UInt32*)&fReceiverPacketBuffer[kPacketTypeOffset];
UInt32 thePacketType = ntohl(*thePacketTypePtr);
return (UInt8) ((thePacketType & kPacketTypeMask) >> kPacketTypeShift);
}
inline UInt16 RTCPPacket::GetPacketLength()
{
UInt32* fieldPtr = (UInt32*)&fReceiverPacketBuffer[kPacketLengthOffset];
UInt32 field = ntohl(*fieldPtr);
return (UInt16) (field & kPacketLengthMask);
}
inline UInt32 RTCPPacket::GetPacketSSRC()
{
UInt32* fieldPtr = (UInt32*)&fReceiverPacketBuffer[kPacketSourceIDOffset];
UInt32 field = ntohl(*fieldPtr);
return field;
}
inline SInt16 RTCPPacket::GetHeader(){ return (SInt16) ntohs(*(SInt16*)&fReceiverPacketBuffer[0]) ;}
/************** RTCPReceiverPacket inlines **************/
inline int RTCPReceiverPacket::RecordOffset(int inReportNum)
{
return inReportNum*kReportBlockOffsetSizeInBytes;
}
inline UInt32 RTCPReceiverPacket::GetReportSourceID(int inReportNum)
{
return (UInt32) ntohl(*(UInt32*)&fRTCPReceiverReportArray[this->RecordOffset(inReportNum)+kReportSourceIDOffset]) ;
}
inline UInt8 RTCPReceiverPacket::GetFractionLostPackets(int inReportNum)
{
return (UInt8) ( (ntohl(*(UInt32*)&fRTCPReceiverReportArray[this->RecordOffset(inReportNum)+kFractionLostOffset]) & kFractionLostMask) >> kFractionLostShift );
}
inline UInt32 RTCPReceiverPacket::GetTotalLostPackets(int inReportNum)
{
return (ntohl(*(UInt32*)&fRTCPReceiverReportArray[this->RecordOffset(inReportNum)+kTotalLostPacketsOffset]) & kTotalLostPacketsMask );
}
inline UInt32 RTCPReceiverPacket::GetHighestSeqNumReceived(int inReportNum)
{
return (UInt32) ntohl(*(UInt32*)&fRTCPReceiverReportArray[this->RecordOffset(inReportNum)+kHighestSeqNumReceivedOffset]) ;
}
inline UInt32 RTCPReceiverPacket::GetJitter(int inReportNum)
{
return (UInt32) ntohl(*(UInt32*)&fRTCPReceiverReportArray[this->RecordOffset(inReportNum)+kJitterOffset]) ;
}
inline UInt32 RTCPReceiverPacket::GetLastSenderReportTime(int inReportNum)
{
return (UInt32) ntohl(*(UInt32*)&fRTCPReceiverReportArray[this->RecordOffset(inReportNum)+kLastSenderReportOffset]) ;
}
inline UInt32 RTCPReceiverPacket::GetLastSenderReportDelay(int inReportNum)
{
return (UInt32) ntohl(*(UInt32*)&fRTCPReceiverReportArray[this->RecordOffset(inReportNum)+kLastSenderReportDelayOffset]) ;
}
/*
Receiver Report
---------------
0 1 2 3
0 0 0 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P| RC | PT=RR=201 | length | header
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of packet sender |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| SSRC_1 (SSRC of first source) | report
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
| fraction lost | cumulative number of packets lost | 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| extended highest sequence number received |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| interarrival jitter |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| last SR (LSR) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| delay since last SR (DLSR) |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| SSRC_2 (SSRC of second source) | report
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
: ... : 2
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| profile-specific extensions |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#endif //_RTCPPACKET_H_