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
RTCPPacketInformation()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
~RTCPPacketInformation()42 RTCPPacketInformation::~RTCPPacketInformation()
43 {
44 delete [] applicationData;
45 delete VoIPMetric;
46 }
47
48 void
AddVoIPMetric(const RTCPVoIPMetric * metric)49 RTCPPacketInformation::AddVoIPMetric(const RTCPVoIPMetric* metric)
50 {
51 VoIPMetric = new RTCPVoIPMetric();
52 memcpy(VoIPMetric, metric, sizeof(RTCPVoIPMetric));
53 }
54
AddApplicationData(const uint8_t * data,const uint16_t size)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
ResetNACKPacketIdArray()81 RTCPPacketInformation::ResetNACKPacketIdArray()
82 {
83 nackSequenceNumbers.clear();
84 }
85
86 void
AddNACKPacket(const uint16_t packetID)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
AddReportInfo(const RTCPReportBlockInformation & report_block_info)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
RTCPReportBlockInformation()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
~RTCPReportBlockInformation()115 RTCPReportBlockInformation::~RTCPReportBlockInformation()
116 {
117 }
118
RTCPReceiveInformation()119 RTCPReceiveInformation::RTCPReceiveInformation()
120 : lastTimeReceived(0),
121 lastFIRSequenceNumber(-1),
122 lastFIRRequest(0),
123 readyForDelete(false) {
124 }
125
~RTCPReceiveInformation()126 RTCPReceiveInformation::~RTCPReceiveInformation() {
127 }
128
129 // Increase size of TMMBRSet if needed, and also take care of
130 // the _tmmbrSetTimeouts vector.
VerifyAndAllocateTMMBRSet(const uint32_t minimumSize)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
InsertTMMBRItem(const uint32_t senderSSRC,const RTCPUtility::RTCPPacketRTPFBTMMBRItem & TMMBRItem,const int64_t currentTimeMS)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
GetTMMBRSet(const uint32_t sourceIdx,const uint32_t targetIdx,TMMBRSet * candidateSet,const int64_t currentTimeMS)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
VerifyAndAllocateBoundingSet(const uint32_t minimumSize)189 void RTCPReceiveInformation::VerifyAndAllocateBoundingSet(
190 const uint32_t minimumSize) {
191 TmmbnBoundingSet.VerifyAndAllocateSet(minimumSize);
192 }
193 } // namespace RTCPHelp
194 } // namespace webrtc
195