/* * * @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: RTCPAPPNADUPacketFmt.h Some useful things for Generating a 3GPP NADU packet */ #ifndef _RTCPNADUPACKETFMT_H_ #define _RTCPNADUPACKETFMT_H_ #include "StrPtrLen.h" #include "arpa/inet.h" #include "OSHeaders.h" #include "MyAssert.h" class RTCPNADUPacketFmt { enum { RTP_VERSION = 2, RTCP_SR = 200, RTCP_RR = 201, RTCP_SDES = 202, RTCP_BYE = 203, RTCP_APP = 204 }; struct NADUHeader { #if 0 //naduheader unsigned int version:2; /* protocol version */ unsigned int p:1; /* padding flag */ unsigned int subtype:5; /* 0 */ unsigned int pt:8; /* RTCP packet type -- which should be RTCP_APP */ #endif UInt16 naduHeader; UInt16 length; /* packet length in words, minus 1 word */ UInt32 SSRC; /* SSRC of packet sender */ UInt32 name; /* in ASCII */ }; struct NADUBlock { UInt32 SSRC; /* data source being reported */ UInt16 delay; /* the playout delay, in milliseconds */ UInt16 NSN; /* the RTP sequence number of the next ADU to be decoded; if the buffer is empty then the next not yet received sequence number */ UInt16 NUN; /* the unit number of the next ADU to be decoded */ UInt16 FBS; /* the free buffer space, in complete 64 byte blocks */ }; public: RTCPNADUPacketFmt() : fNumNADUBlocks(0) {} RTCPNADUPacketFmt(StrPtrLen &newBuffer) : fNumNADUBlocks(0) { SetBuffer(newBuffer); } RTCPNADUPacketFmt(char *newBuffer, UInt32 bufLen) : fNumNADUBlocks(0) { SetBuffer(newBuffer, bufLen); } //Setting the buffer resets the packet content void SetBuffer(StrPtrLen &newBuffer) { return this->SetBuffer(newBuffer.Ptr, newBuffer.Len); } void SetBuffer(char *newBuffer, UInt32 bufLen) { Assert(sizeof(NADUHeader) == 12); Assert(sizeof(NADUBlock) == 12); Assert(bufLen >= sizeof(NADUHeader)); fBuf.Set(newBuffer, bufLen); fNumNADUBlocks = 0; //fill in the header NADUHeader &header = *reinterpret_cast(fBuf.Ptr); ::memset(&header, 0, sizeof(header)); header.naduHeader = htons(0x80CC); //(RTP_VERSION << 14) + RTCP_APP; header.name = htonl(FOUR_CHARS_TO_INT('P', 'S', 'S', '0')); header.length = htons(GetPacketLen() / 4 - 1); } //units are in milliseconds and in bytes; use a playoutDelay of kUInt32_Max if the buffer is empty void AddNADUBlock(UInt32 SSRC, UInt32 nextSeqNum, UInt8 nextUnitNum, UInt32 freeBufferSpace, UInt32 playoutDelay = kUInt32_Max) { Assert(fBuf.Len >= GetPacketLen() + sizeof(NADUBlock)); NADUBlock &nadu = *reinterpret_cast(fBuf.Ptr + GetPacketLen()); ::memset(&nadu, 0, sizeof(NADUBlock)); fNumNADUBlocks++; reinterpret_cast(fBuf.Ptr)->length = htons(GetPacketLen() / 4 - 1); nadu.SSRC = htonl(SSRC); nadu.NSN = htons(static_cast(nextSeqNum)); nadu.NUN = htons(nextUnitNum & 0x1F); //Use reserved value of 0xffff for undefined playoutDelay = MIN(0xffff, playoutDelay); nadu.delay = htons(static_cast(playoutDelay)); //the free buffer space is reported in 64 bytes blocks, and maximum value is 0xffff freeBufferSpace = MIN(0xffff, freeBufferSpace / 64); nadu.FBS = htons(static_cast(freeBufferSpace)); } void SetSSRC(UInt32 SSRC) { reinterpret_cast(fBuf.Ptr)->SSRC = htonl(SSRC); } //The length of packet written out UInt32 GetPacketLen() { return sizeof(NADUHeader) + sizeof(NADUBlock) * fNumNADUBlocks; } StrPtrLen GetBufferRemaining() { return StrPtrLen(fBuf.Ptr + GetPacketLen(), fBuf.Len - GetPacketLen()); } StrPtrLen GetPacket() { return StrPtrLen(fBuf.Ptr, GetPacketLen()); } private: StrPtrLen fBuf; UInt32 fNumNADUBlocks; }; #endif //_RTCPNADUPACKETFMT_H_