1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h" 12 13 #include <assert.h> // assert 14 #include <string.h> // memset 15 16 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" 17 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 18 19 namespace webrtc { 20 namespace RTCPHelp { 21 22 RTCPPacketInformation::RTCPPacketInformation() 23 : rtcpPacketTypeFlags(0), 24 remoteSSRC(0), 25 nackSequenceNumbers(), 26 applicationSubType(0), 27 applicationName(0), 28 applicationData(), 29 applicationLength(0), 30 rtt(0), 31 interArrivalJitter(0), 32 sliPictureId(0), 33 rpsiPictureId(0), 34 receiverEstimatedMaxBitrate(0), 35 ntp_secs(0), 36 ntp_frac(0), 37 rtp_timestamp(0), 38 xr_originator_ssrc(0), 39 xr_dlrr_item(false), 40 VoIPMetric(nullptr) {} 41 42 RTCPPacketInformation::~RTCPPacketInformation() 43 { 44 delete [] applicationData; 45 delete VoIPMetric; 46 } 47 48 void 49 RTCPPacketInformation::AddVoIPMetric(const RTCPVoIPMetric* metric) 50 { 51 VoIPMetric = new RTCPVoIPMetric(); 52 memcpy(VoIPMetric, metric, sizeof(RTCPVoIPMetric)); 53 } 54 55 void RTCPPacketInformation::AddApplicationData(const uint8_t* data, 56 const uint16_t size) { 57 uint8_t* oldData = applicationData; 58 uint16_t oldLength = applicationLength; 59 60 // Don't copy more than kRtcpAppCode_DATA_SIZE bytes. 61 uint16_t copySize = size; 62 if (size > kRtcpAppCode_DATA_SIZE) { 63 copySize = kRtcpAppCode_DATA_SIZE; 64 } 65 66 applicationLength += copySize; 67 applicationData = new uint8_t[applicationLength]; 68 69 if (oldData) 70 { 71 memcpy(applicationData, oldData, oldLength); 72 memcpy(applicationData+oldLength, data, copySize); 73 delete [] oldData; 74 } else 75 { 76 memcpy(applicationData, data, copySize); 77 } 78 } 79 80 void 81 RTCPPacketInformation::ResetNACKPacketIdArray() 82 { 83 nackSequenceNumbers.clear(); 84 } 85 86 void 87 RTCPPacketInformation::AddNACKPacket(const uint16_t packetID) 88 { 89 if (nackSequenceNumbers.size() >= kSendSideNackListSizeSanity) { 90 return; 91 } 92 nackSequenceNumbers.push_back(packetID); 93 } 94 95 void 96 RTCPPacketInformation::AddReportInfo( 97 const RTCPReportBlockInformation& report_block_info) 98 { 99 this->rtt = report_block_info.RTT; 100 report_blocks.push_back(report_block_info.remoteReceiveBlock); 101 } 102 103 RTCPReportBlockInformation::RTCPReportBlockInformation(): 104 remoteReceiveBlock(), 105 remoteMaxJitter(0), 106 RTT(0), 107 minRTT(0), 108 maxRTT(0), 109 avgRTT(0), 110 numAverageCalcs(0) 111 { 112 memset(&remoteReceiveBlock,0,sizeof(remoteReceiveBlock)); 113 } 114 115 RTCPReportBlockInformation::~RTCPReportBlockInformation() 116 { 117 } 118 119 RTCPReceiveInformation::RTCPReceiveInformation() 120 : lastTimeReceived(0), 121 lastFIRSequenceNumber(-1), 122 lastFIRRequest(0), 123 readyForDelete(false) { 124 } 125 126 RTCPReceiveInformation::~RTCPReceiveInformation() { 127 } 128 129 // Increase size of TMMBRSet if needed, and also take care of 130 // the _tmmbrSetTimeouts vector. 131 void RTCPReceiveInformation::VerifyAndAllocateTMMBRSet( 132 const uint32_t minimumSize) { 133 if (minimumSize > TmmbrSet.sizeOfSet()) { 134 TmmbrSet.VerifyAndAllocateSetKeepingData(minimumSize); 135 // make sure that our buffers are big enough 136 _tmmbrSetTimeouts.reserve(minimumSize); 137 } 138 } 139 140 void RTCPReceiveInformation::InsertTMMBRItem( 141 const uint32_t senderSSRC, 142 const RTCPUtility::RTCPPacketRTPFBTMMBRItem& TMMBRItem, 143 const int64_t currentTimeMS) { 144 // serach to see if we have it in our list 145 for (uint32_t i = 0; i < TmmbrSet.lengthOfSet(); i++) { 146 if (TmmbrSet.Ssrc(i) == senderSSRC) { 147 // we already have this SSRC in our list update it 148 TmmbrSet.SetEntry(i, 149 TMMBRItem.MaxTotalMediaBitRate, 150 TMMBRItem.MeasuredOverhead, 151 senderSSRC); 152 _tmmbrSetTimeouts[i] = currentTimeMS; 153 return; 154 } 155 } 156 VerifyAndAllocateTMMBRSet(TmmbrSet.lengthOfSet() + 1); 157 TmmbrSet.AddEntry(TMMBRItem.MaxTotalMediaBitRate, 158 TMMBRItem.MeasuredOverhead, 159 senderSSRC); 160 _tmmbrSetTimeouts.push_back(currentTimeMS); 161 } 162 163 int32_t RTCPReceiveInformation::GetTMMBRSet( 164 const uint32_t sourceIdx, 165 const uint32_t targetIdx, 166 TMMBRSet* candidateSet, 167 const int64_t currentTimeMS) { 168 if (sourceIdx >= TmmbrSet.lengthOfSet()) { 169 return -1; 170 } 171 if (targetIdx >= candidateSet->sizeOfSet()) { 172 return -1; 173 } 174 // use audio define since we don't know what interval the remote peer is using 175 if (currentTimeMS - _tmmbrSetTimeouts[sourceIdx] > 176 5 * RTCP_INTERVAL_AUDIO_MS) { 177 // value timed out 178 TmmbrSet.RemoveEntry(sourceIdx); 179 _tmmbrSetTimeouts.erase(_tmmbrSetTimeouts.begin() + sourceIdx); 180 return -1; 181 } 182 candidateSet->SetEntry(targetIdx, 183 TmmbrSet.Tmmbr(sourceIdx), 184 TmmbrSet.PacketOH(sourceIdx), 185 TmmbrSet.Ssrc(sourceIdx)); 186 return 0; 187 } 188 189 void RTCPReceiveInformation::VerifyAndAllocateBoundingSet( 190 const uint32_t minimumSize) { 191 TmmbnBoundingSet.VerifyAndAllocateSet(minimumSize); 192 } 193 } // namespace RTCPHelp 194 } // namespace webrtc 195