Darwin-Streaming-Server/RTCPUtilitiesLib/RTCPAPPQTSSPacket.cpp
Darren VanBuren 849723c9cf Add even more of the source
This should be about everything needed to build so far?
2017-03-07 17:14:16 -08:00

316 lines
12 KiB
C++

/*
*
* @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: RTCPAPPQTSSPacket.cpp
Contains: RTCPAPPQTSSPacket de-packetizing classes
*/
#include "RTCPAPPQTSSPacket.h"
#include "MyAssert.h"
#include "OS.h"
#include "OSMemory.h"
RTCPCompressedQTSSPacket::RTCPCompressedQTSSPacket(Bool16 debug) :
RTCPAPPPacket(debug),
fReceiverBitRate(0),
fAverageLateMilliseconds(0),
fPercentPacketsLost(0),
fAverageBufferDelayMilliseconds(0),
fIsGettingBetter(false),
fIsGettingWorse(false),
fNumEyes(0),
fNumEyesActive(0),
fNumEyesPaused(0),
fOverbufferWindowSize(kUInt32_Max),
//Proposed - are these there yet?
fTotalPacketsReceived(0),
fTotalPacketsDropped(0),
fTotalPacketsLost(0),
fClientBufferFill(0),
fFrameRate(0),
fExpectedFrameRate(0),
fAudioDryCount(0)
{
}
// use if you don't know what kind of packet this is
Bool16 RTCPCompressedQTSSPacket::ParseCompressedQTSSPacket(UInt8* inPacketBuffer, UInt32 inPacketLength)
{
if (!this->ParseAPPPacket(inPacketBuffer, inPacketLength))
return false;
if (this->GetAppPacketName() != RTCPCompressedQTSSPacket::kCompressedQTSSPacketName)
return false;
if (inPacketLength < kQTSSDataOffset)
return false;
//figure out how many 32-bit words remain in the buffer
UInt32 theMaxDataLen = inPacketLength - kQTSSDataOffset;
theMaxDataLen /= 4;
//if the number of 32 bit words reported in the packet is greater than the theoretical limit,
//return an error
if (this->GetQTSSPacketLength() > theMaxDataLen)
return false;
if (this->GetQTSSPacketVersion() != kSupportedCompressedQTSSVersion)
return false;
if (this->GetReportCount() > 0)
return false;
return true;
}
// You know the packet type and just want to parse it now
Bool16 RTCPCompressedQTSSPacket::ParseAPPData(UInt8* inPacketBuffer, UInt32 inPacketLength)
{
if ( !this->ParseCompressedQTSSPacket(inPacketBuffer, inPacketLength) )
return false;
APPEND_TO_DUMP_ARRAY("%s","\n RTCP APP QTSS Report ");
char printName[5];
(void) this->GetAppPacketName(printName, sizeof(printName));
APPEND_TO_DUMP_ARRAY("H_app_packet_name = %s, ", printName );
APPEND_TO_DUMP_ARRAY("H_ssrc = %"_U32BITARG_", ", this->GetPacketSSRC());
APPEND_TO_DUMP_ARRAY("H_src_ID = %"_U32BITARG_", ", this->GetQTSSReportSourceID());
APPEND_TO_DUMP_ARRAY("H_vers=%d, ", this->GetQTSSPacketVersion());
APPEND_TO_DUMP_ARRAY("H_packt_len=%d", this->GetQTSSPacketLength());
UInt8* qtssDataBuffer = this->GetPacketBuffer()+kQTSSDataOffset;
//packet length is given in words
UInt32 bytesRemaining = this->GetQTSSPacketLength() * 4;
while ( bytesRemaining >= 4 ) //items must be at least 32 bits
{
// DMS - There is no guarentee that qtssDataBuffer will be 4 byte aligned, because
// individual APP packet fields can be 6 bytes or 4 bytes or 8 bytes. So we have to
// use the 4-byte align protection functions. Sparc and MIPS processors will crash otherwise
UInt32 theHeader = ntohl(OS::GetUInt32FromMemory((UInt32*)&qtssDataBuffer[kQTSSItemTypeOffset]));
UInt16 itemType = (UInt16)((theHeader & kQTSSItemTypeMask) >> kQTSSItemTypeShift);
UInt8 itemVersion = (UInt8)((theHeader & kQTSSItemVersionMask) >> kQTSSItemVersionShift);
UInt8 itemLengthInBytes = (UInt8)(theHeader & kQTSSItemLengthMask);
APPEND_TO_DUMP_ARRAY("\n h_type=%.2s(", (char*)&itemType);
APPEND_TO_DUMP_ARRAY(", h_vers=%u", itemVersion);
APPEND_TO_DUMP_ARRAY(", h_size=%u", itemLengthInBytes);
qtssDataBuffer += sizeof(UInt32); //advance past the above UInt16's & UInt8's (point it at the actual item data)
//Update bytesRemaining (move it past current item)
//This itemLengthInBytes is part of the packet and could therefore be bogus.
//Make sure not to overstep the end of the buffer!
bytesRemaining -= sizeof(UInt32);
if (itemLengthInBytes > bytesRemaining)
break; //don't walk off the end of the buffer
//itemLengthInBytes = bytesRemaining;
bytesRemaining -= itemLengthInBytes;
switch (itemType)
{
case TW0_CHARS_TO_INT( 'r', 'r' ): //'rr': //'rrcv':
{
fReceiverBitRate = ntohl(OS::GetUInt32FromMemory((UInt32*)qtssDataBuffer));
qtssDataBuffer += sizeof(fReceiverBitRate);
APPEND_TO_DUMP_ARRAY(", rcvr_bit_rate=%"_U32BITARG_"", fReceiverBitRate);
}
break;
case TW0_CHARS_TO_INT('l', 't'): //'lt': //'late':
{
fAverageLateMilliseconds = ntohs(*(UInt16*)qtssDataBuffer);
qtssDataBuffer += sizeof(fAverageLateMilliseconds);
APPEND_TO_DUMP_ARRAY(", avg_late=%u", fAverageLateMilliseconds);
}
break;
case TW0_CHARS_TO_INT('l', 's'): // 'ls': //'loss':
{
fPercentPacketsLost = ntohs(*(UInt16*)qtssDataBuffer);
qtssDataBuffer += sizeof(fPercentPacketsLost);
APPEND_TO_DUMP_ARRAY(", percent_loss=%u", fPercentPacketsLost);
}
break;
case TW0_CHARS_TO_INT('d', 'l'): //'dl': //'bdly':
{
fAverageBufferDelayMilliseconds = ntohs(*(UInt16*)qtssDataBuffer);
qtssDataBuffer += sizeof(fAverageBufferDelayMilliseconds);
APPEND_TO_DUMP_ARRAY(", avg_buf_delay=%u", fAverageBufferDelayMilliseconds);
}
break;
case TW0_CHARS_TO_INT(':', ')' ): //:)
{
fIsGettingBetter = true;
APPEND_TO_DUMP_ARRAY(", quality=%s","better");
}
break;
case TW0_CHARS_TO_INT(':', '(' ): // ':(':
{
fIsGettingWorse = true;
APPEND_TO_DUMP_ARRAY(", quality=%s","worse");
}
break;
case TW0_CHARS_TO_INT(':', '|' ): // ':|':
{
fIsGettingWorse = true;
APPEND_TO_DUMP_ARRAY(", quality=%s","same");
}
break;
case TW0_CHARS_TO_INT('e', 'y' ): //'ey': //'eyes':
{
fNumEyes = ntohl(OS::GetUInt32FromMemory((UInt32*)qtssDataBuffer));
qtssDataBuffer += sizeof(fNumEyes);
APPEND_TO_DUMP_ARRAY(", eyes=%"_U32BITARG_"", fNumEyes);
if (itemLengthInBytes >= 2)
{
fNumEyesActive = ntohl(OS::GetUInt32FromMemory((UInt32*)qtssDataBuffer));
qtssDataBuffer += sizeof(fNumEyesActive);
APPEND_TO_DUMP_ARRAY(", eyes_actv=%"_U32BITARG_"", fNumEyesActive);
}
if (itemLengthInBytes >= 3)
{
fNumEyesPaused = ntohl(OS::GetUInt32FromMemory((UInt32*)qtssDataBuffer));
qtssDataBuffer += sizeof(fNumEyesPaused);
APPEND_TO_DUMP_ARRAY(", eyes_pausd=%"_U32BITARG_"", fNumEyesPaused);
}
}
break;
case TW0_CHARS_TO_INT('p', 'r' ): // 'pr': //'prcv':
{
fTotalPacketsReceived = ntohl(OS::GetUInt32FromMemory((UInt32*)qtssDataBuffer));
qtssDataBuffer += sizeof(fTotalPacketsReceived);
APPEND_TO_DUMP_ARRAY(", pckts_rcvd=%"_U32BITARG_"", fTotalPacketsReceived);
}
break;
case TW0_CHARS_TO_INT('p', 'd'): //'pd': //'pdrp':
{
fTotalPacketsDropped = ntohs(*(UInt16*)qtssDataBuffer);
qtssDataBuffer += sizeof(fTotalPacketsDropped);
APPEND_TO_DUMP_ARRAY(", pckts_drppd=%u", fTotalPacketsDropped);
}
break;
case TW0_CHARS_TO_INT('p', 'l'): //'pl': //'p???':
{
fTotalPacketsLost = ntohs(*(UInt16*)qtssDataBuffer);
qtssDataBuffer += sizeof(fTotalPacketsLost);
APPEND_TO_DUMP_ARRAY(", ttl_pckts_lost=%u", fTotalPacketsLost);
}
break;
case TW0_CHARS_TO_INT('b', 'l'): //'bl': //'bufl':
{
fClientBufferFill = ntohs(*(UInt16*)qtssDataBuffer);
qtssDataBuffer += sizeof(fClientBufferFill);
APPEND_TO_DUMP_ARRAY(", buffr_fill=%u", fClientBufferFill);
}
break;
case TW0_CHARS_TO_INT('f', 'r'): //'fr': //'frat':
{
fFrameRate = ntohs(*(UInt16*)qtssDataBuffer);
qtssDataBuffer += sizeof(fFrameRate);
APPEND_TO_DUMP_ARRAY(", frame_rate=%u", fFrameRate);
}
break;
case TW0_CHARS_TO_INT('x', 'r'): //'xr': //'xrat':
{
fExpectedFrameRate = ntohs(*(UInt16*)qtssDataBuffer);
qtssDataBuffer += sizeof(fExpectedFrameRate);
APPEND_TO_DUMP_ARRAY(", xpectd_frame_rate=%u", fExpectedFrameRate);
}
break;
case TW0_CHARS_TO_INT('d', '#'): //'d#': //'dry#':
{
fAudioDryCount = ntohs(*(UInt16*)qtssDataBuffer);
qtssDataBuffer += sizeof(fAudioDryCount);
APPEND_TO_DUMP_ARRAY(", aud_dry_count=%u", fAudioDryCount);
}
break;
case TW0_CHARS_TO_INT('o', 'b'): //'ob': // overbuffer window size
{
fOverbufferWindowSize = ntohl(OS::GetUInt32FromMemory((UInt32*)qtssDataBuffer));
qtssDataBuffer += sizeof(fOverbufferWindowSize);
APPEND_TO_DUMP_ARRAY(", ovr_buffr_windw_siz=%"_U32BITARG_"", fOverbufferWindowSize);
}
break;
default:
{
if (fDebug)
{
char s[12] = "";
qtss_sprintf(s, " [%.2s]", (char*)&itemType);
WarnV(false, "Unknown APP('QTSS') item type");
WarnV(false, s);
}
}
break;
} // switch (itemType)
APPEND_TO_DUMP_ARRAY("%s", "), ");
} //while ( bytesRemaining >= 4 )
return true;
}
void RTCPCompressedQTSSPacket::Dump()//Override
{
APPEND_TO_DUMP_ARRAY("%s", "\n");
RTCPAPPPacket::Dump();
}