Refactoring of the TMMBRSet class, giving it a reasonably tight interface.
The CL also fixes a number of line length and tab issues in touched files.
BUG=
TEST=
Review URL: https://webrtc-codereview.appspot.com/553005
git-svn-id: http://webrtc.googlecode.com/svn/trunk@2168 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver.cc b/src/modules/rtp_rtcp/source/rtcp_receiver.cc
index 9caac86..2fc7c83 100644
--- a/src/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -649,7 +649,7 @@
if ((timeNow - receiveInfo->lastTimeReceived) >
5 * RTCP_INTERVAL_AUDIO_MS) {
// no rtcp packet for the last five regular intervals, reset limitations
- receiveInfo->TmmbrSet.lengthOfSet = 0;
+ receiveInfo->TmmbrSet.clearSet();
// prevent that we call this over and over again
receiveInfo->lastTimeReceived = 0;
// send new TMMBN to all channels using the default codec
@@ -687,23 +687,22 @@
__FUNCTION__);
return -1;
}
- if (receiveInfo->TmmbnBoundingSet.lengthOfSet > 0) {
+ if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
boundingSetRec->VerifyAndAllocateSet(
- receiveInfo->TmmbnBoundingSet.lengthOfSet + 1);
- for(WebRtc_UWord32 i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet; i++) {
- if(receiveInfo->TmmbnBoundingSet.ptrSsrcSet[i] == _SSRC) {
+ receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
+ for(WebRtc_UWord32 i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
+ i++) {
+ if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == _SSRC) {
// owner of bounding set
tmmbrOwner = true;
}
- boundingSetRec->ptrTmmbrSet[i] =
- receiveInfo->TmmbnBoundingSet.ptrTmmbrSet[i];
- boundingSetRec->ptrPacketOHSet[i] =
- receiveInfo->TmmbnBoundingSet.ptrPacketOHSet[i];
- boundingSetRec->ptrSsrcSet[i] =
- receiveInfo->TmmbnBoundingSet.ptrSsrcSet[i];
+ boundingSetRec->SetEntry(i,
+ receiveInfo->TmmbnBoundingSet.Tmmbr(i),
+ receiveInfo->TmmbnBoundingSet.PacketOH(i),
+ receiveInfo->TmmbnBoundingSet.Ssrc(i));
}
}
- return receiveInfo->TmmbnBoundingSet.lengthOfSet;
+ return receiveInfo->TmmbnBoundingSet.lengthOfSet();
}
// no need for critsect we have _criticalSectionRTCPReceiver
@@ -992,13 +991,10 @@
RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
const RTCPUtility::RTCPPacket& rtcpPacket)
{
- const unsigned int idx = receiveInfo.TmmbnBoundingSet.lengthOfSet;
-
- receiveInfo.TmmbnBoundingSet.ptrTmmbrSet[idx] = rtcpPacket.TMMBNItem.MaxTotalMediaBitRate;
- receiveInfo.TmmbnBoundingSet.ptrPacketOHSet[idx] = rtcpPacket.TMMBNItem.MeasuredOverhead;
- receiveInfo.TmmbnBoundingSet.ptrSsrcSet[idx] = rtcpPacket.TMMBNItem.SSRC;
-
- ++receiveInfo.TmmbnBoundingSet.lengthOfSet;
+ receiveInfo.TmmbnBoundingSet.AddEntry(
+ rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
+ rtcpPacket.TMMBNItem.MeasuredOverhead,
+ rtcpPacket.TMMBNItem.SSRC);
}
// no need for critsect we have _criticalSectionRTCPReceiver
@@ -1376,7 +1372,7 @@
return 0;
}
for (WebRtc_UWord32 i = 0;
- (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet); i++) {
+ (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
_clock.GetTimeInMS()) == 0) {
num++;
@@ -1393,7 +1389,7 @@
__FUNCTION__);
return -1;
}
- num += receiveInfo->TmmbrSet.lengthOfSet;
+ num += receiveInfo->TmmbrSet.lengthOfSet();
receiveInfoIt++;
}
}
diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver_help.cc b/src/modules/rtp_rtcp/source/rtcp_receiver_help.cc
index 0058aca..1b74c68 100644
--- a/src/modules/rtp_rtcp/source/rtcp_receiver_help.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_receiver_help.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
@@ -147,40 +147,26 @@
}
}
-// don't use TmmbrSet.VerifyAndAllocate this version keeps the data
+// Increase size of TMMBRSet if needed, and also take care of
+// the _tmmbrSetTimeouts array.
void
RTCPReceiveInformation::VerifyAndAllocateTMMBRSet(const WebRtc_UWord32 minimumSize)
{
- if(minimumSize > TmmbrSet.sizeOfSet)
+ if(minimumSize > TmmbrSet.sizeOfSet())
{
+ TmmbrSet.VerifyAndAllocateSetKeepingData(minimumSize);
// make sure that our buffers are big enough
- WebRtc_UWord32* ptrTmmbrSet = new WebRtc_UWord32[minimumSize];
- WebRtc_UWord32* ptrTmmbrPacketOHSet = new WebRtc_UWord32[minimumSize];
- WebRtc_UWord32* ptrTmmbrSsrcSet = new WebRtc_UWord32[minimumSize];
WebRtc_UWord32* tmmbrSetTimeouts = new WebRtc_UWord32[minimumSize];
- if(TmmbrSet.lengthOfSet > 0)
+ if(TmmbrSet.lengthOfSet() > 0)
{
- // copy old values
- memcpy(ptrTmmbrSet, TmmbrSet.ptrTmmbrSet, sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet);
- memcpy(ptrTmmbrPacketOHSet, TmmbrSet.ptrPacketOHSet, sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet);
- memcpy(ptrTmmbrSsrcSet, TmmbrSet.ptrSsrcSet, sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet);
- memcpy(tmmbrSetTimeouts, _tmmbrSetTimeouts, sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet);
- }
- if(TmmbrSet.ptrTmmbrSet)
- {
- delete [] TmmbrSet.ptrTmmbrSet;
- delete [] TmmbrSet.ptrPacketOHSet;
- delete [] TmmbrSet.ptrSsrcSet;
+ memcpy(tmmbrSetTimeouts, _tmmbrSetTimeouts,
+ sizeof(WebRtc_UWord32) * TmmbrSet.lengthOfSet());
}
if(_tmmbrSetTimeouts)
{
delete [] _tmmbrSetTimeouts;
}
- TmmbrSet.ptrTmmbrSet = ptrTmmbrSet;
- TmmbrSet.ptrPacketOHSet = ptrTmmbrPacketOHSet;
- TmmbrSet.ptrSsrcSet = ptrTmmbrSsrcSet;
- TmmbrSet.sizeOfSet = minimumSize;
_tmmbrSetTimeouts = tmmbrSetTimeouts;
}
}
@@ -191,26 +177,26 @@
const WebRtc_UWord32 currentTimeMS)
{
// serach to see if we have it in our list
- for(WebRtc_UWord32 i = 0; i < TmmbrSet.lengthOfSet; i++)
+ for(WebRtc_UWord32 i = 0; i < TmmbrSet.lengthOfSet(); i++)
{
- if(TmmbrSet.ptrSsrcSet[i] == senderSSRC)
+ if(TmmbrSet.Ssrc(i) == senderSSRC)
{
// we already have this SSRC in our list
// update it
- TmmbrSet.ptrPacketOHSet[i] = TMMBRItem.MeasuredOverhead;
- TmmbrSet.ptrTmmbrSet[i] = TMMBRItem.MaxTotalMediaBitRate;
+ TmmbrSet.SetEntry(i,
+ TMMBRItem.MaxTotalMediaBitRate,
+ TMMBRItem.MeasuredOverhead,
+ senderSSRC);
_tmmbrSetTimeouts[i] = currentTimeMS;
return;
}
}
- VerifyAndAllocateTMMBRSet(TmmbrSet.lengthOfSet+1);
-
- const WebRtc_UWord32 idx = TmmbrSet.lengthOfSet;
- TmmbrSet.ptrPacketOHSet[idx] = TMMBRItem.MeasuredOverhead;
- TmmbrSet.ptrTmmbrSet[idx] = TMMBRItem.MaxTotalMediaBitRate;
- TmmbrSet.ptrSsrcSet[idx] = senderSSRC;
+ const WebRtc_UWord32 idx = TmmbrSet.lengthOfSet();
+ VerifyAndAllocateTMMBRSet(idx+1);
+ TmmbrSet.AddEntry(TMMBRItem.MaxTotalMediaBitRate,
+ TMMBRItem.MeasuredOverhead,
+ senderSSRC);
_tmmbrSetTimeouts[idx] = currentTimeMS;
- TmmbrSet.lengthOfSet++;
}
WebRtc_Word32
@@ -219,11 +205,11 @@
TMMBRSet* candidateSet,
const WebRtc_UWord32 currentTimeMS)
{
- if(sourceIdx >= TmmbrSet.lengthOfSet)
+ if(sourceIdx >= TmmbrSet.lengthOfSet())
{
return -1;
}
- if(targetIdx >= candidateSet->sizeOfSet)
+ if(targetIdx >= candidateSet->sizeOfSet())
{
return -1;
}
@@ -233,21 +219,17 @@
if(timeNow - _tmmbrSetTimeouts[sourceIdx] > 5*RTCP_INTERVAL_AUDIO_MS)
{
// value timed out
- const WebRtc_UWord32 move = TmmbrSet.lengthOfSet - (sourceIdx + 1);
- if(move > 0)
- {
- memmove(&(TmmbrSet.ptrTmmbrSet[sourceIdx]), &(TmmbrSet.ptrTmmbrSet[sourceIdx+1]), move* sizeof(WebRtc_UWord32));
- memmove(&(TmmbrSet.ptrPacketOHSet[sourceIdx]),&(TmmbrSet.ptrPacketOHSet[sourceIdx+1]), move* sizeof(WebRtc_UWord32));
- memmove(&(TmmbrSet.ptrSsrcSet[sourceIdx]),&(TmmbrSet.ptrSsrcSet[sourceIdx+1]), move* sizeof(WebRtc_UWord32));
+ TmmbrSet.RemoveEntry(sourceIdx);
+ const WebRtc_UWord32 move = TmmbrSet.lengthOfSet() - (sourceIdx + 1);
+ if (move > 0) {
memmove(&(_tmmbrSetTimeouts[sourceIdx]),&(_tmmbrSetTimeouts[sourceIdx+1]), move* sizeof(WebRtc_UWord32));
}
- TmmbrSet.lengthOfSet--;
return -1;
}
-
- candidateSet->ptrTmmbrSet[targetIdx] = TmmbrSet.ptrTmmbrSet[sourceIdx];
- candidateSet->ptrPacketOHSet[targetIdx] = TmmbrSet.ptrPacketOHSet[sourceIdx];
- candidateSet->ptrSsrcSet[targetIdx] = TmmbrSet.ptrSsrcSet[sourceIdx];
+ candidateSet->SetEntry(targetIdx,
+ TmmbrSet.Tmmbr(sourceIdx),
+ TmmbrSet.PacketOH(sourceIdx),
+ TmmbrSet.Ssrc(sourceIdx));
return 0;
}
diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver_test.cc b/src/modules/rtp_rtcp/source/rtcp_receiver_test.cc
index ff9ed1a..5bfdb73 100644
--- a/src/modules/rtp_rtcp/source/rtcp_receiver_test.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_receiver_test.cc
@@ -258,8 +258,8 @@
TMMBRSet candidate_set;
candidate_set.VerifyAndAllocateSet(1);
EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(1, 0, &candidate_set));
- EXPECT_LT(0U, candidate_set.ptrTmmbrSet[0]);
- EXPECT_EQ(kMediaRecipientSsrc, candidate_set.ptrSsrcSet[0]);
+ EXPECT_LT(0U, candidate_set.Tmmbr(0));
+ EXPECT_EQ(kMediaRecipientSsrc, candidate_set.Ssrc(0));
}
TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
@@ -328,7 +328,7 @@
TMMBRSet candidate_set;
candidate_set.VerifyAndAllocateSet(3);
EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(3, 0, &candidate_set));
- EXPECT_LT(0U, candidate_set.ptrTmmbrSet[0]);
+ EXPECT_LT(0U, candidate_set.Tmmbr(0));
// We expect the timeout to be 25 seconds. Advance the clock by 12
// seconds, timing out the first packet.
system_clock_->AdvanceClock(12000);
@@ -336,7 +336,7 @@
EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
// Odd behaviour: There's only one left after timeout, not 2.
EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(3, 0, &candidate_set));
- EXPECT_EQ(kMediaRecipientSsrc + 2, candidate_set.ptrSsrcSet[0]);
+ EXPECT_EQ(kMediaRecipientSsrc + 2, candidate_set.Ssrc(0));
}
diff --git a/src/modules/rtp_rtcp/source/rtcp_sender.cc b/src/modules/rtp_rtcp/source/rtcp_sender.cc
index 2fe0380..6383f8f 100644
--- a/src/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -1134,18 +1134,21 @@
// get current bounding set from RTCP receiver
bool tmmbrOwner = false;
- TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet(); // store in candidateSet, allocates one extra slot
+ // store in candidateSet, allocates one extra slot
+ TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet();
- // holding _criticalSectionRTCPSender while calling RTCPreceiver which will accuire _criticalSectionRTCPReceiver
- // is a potental deadlock but since RTCPreceiver is not doing the revese we should be fine
- WebRtc_Word32 lengthOfBoundingSet = _rtpRtcp.BoundingSet(tmmbrOwner, candidateSet);
+ // holding _criticalSectionRTCPSender while calling RTCPreceiver which
+ // will accuire _criticalSectionRTCPReceiver is a potental deadlock but
+ // since RTCPreceiver is not doing the reverse we should be fine
+ WebRtc_Word32 lengthOfBoundingSet
+ = _rtpRtcp.BoundingSet(tmmbrOwner, candidateSet);
if(lengthOfBoundingSet > 0)
{
for (WebRtc_Word32 i = 0; i < lengthOfBoundingSet; i++)
{
- if( candidateSet->ptrTmmbrSet[i] == _tmmbr_Send &&
- candidateSet->ptrPacketOHSet[i] == _packetOH_Send)
+ if( candidateSet->Tmmbr(i) == _tmmbr_Send &&
+ candidateSet->PacketOH(i) == _packetOH_Send)
{
// do not send the same tuple
return 0;
@@ -1155,9 +1158,10 @@
{
// use received bounding set as candidate set
// add current tuple
- candidateSet->ptrTmmbrSet[lengthOfBoundingSet] = _tmmbr_Send;
- candidateSet->ptrPacketOHSet[lengthOfBoundingSet] = _packetOH_Send;
- candidateSet->ptrSsrcSet[lengthOfBoundingSet] = _SSRC;
+ candidateSet->SetEntry(lengthOfBoundingSet,
+ _tmmbr_Send,
+ _packetOH_Send,
+ _SSRC);
int numCandidates = lengthOfBoundingSet+ 1;
// find bounding set
@@ -1236,7 +1240,7 @@
return -1;
}
// sanity
- if(pos + 12 + boundingSet->lengthOfSet*8 >= IP_PACKET_SIZE)
+ if(pos + 12 + boundingSet->lengthOfSet()*8 >= IP_PACKET_SIZE)
{
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
return -2;
@@ -1265,15 +1269,15 @@
// Additional Feedback Control Information (FCI)
int numBoundingSet = 0;
- for(WebRtc_UWord32 n=0; n< boundingSet->lengthOfSet; n++)
+ for(WebRtc_UWord32 n=0; n< boundingSet->lengthOfSet(); n++)
{
- if (boundingSet->ptrTmmbrSet[n] > 0)
+ if (boundingSet->Tmmbr(n) > 0)
{
- WebRtc_UWord32 tmmbrSSRC = boundingSet->ptrSsrcSet[n];
+ WebRtc_UWord32 tmmbrSSRC = boundingSet->Ssrc(n);
ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, tmmbrSSRC);
pos += 4;
- WebRtc_UWord32 bitRate = boundingSet->ptrTmmbrSet[n] * 1000;
+ WebRtc_UWord32 bitRate = boundingSet->Tmmbr(n) * 1000;
WebRtc_UWord32 mmbrExp = 0;
for(int i=0; i<64; i++)
{
@@ -1284,7 +1288,7 @@
}
}
WebRtc_UWord32 mmbrMantissa = (bitRate >> mmbrExp);
- WebRtc_UWord32 measuredOH = boundingSet->ptrPacketOHSet[n];
+ WebRtc_UWord32 measuredOH = boundingSet->PacketOH(n);
rtcpbuffer[pos++]=(WebRtc_UWord8)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03));
rtcpbuffer[pos++]=(WebRtc_UWord8)(mmbrMantissa >> 7);
diff --git a/src/modules/rtp_rtcp/source/rtcp_sender_test.cc b/src/modules/rtp_rtcp/source/rtcp_sender_test.cc
index 59fb71b..2d86682 100644
--- a/src/modules/rtp_rtcp/source/rtcp_sender_test.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_sender_test.cc
@@ -204,13 +204,8 @@
EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
TMMBRSet bounding_set;
bounding_set.VerifyAndAllocateSet(1);
- const WebRtc_UWord32 idx = bounding_set.lengthOfSet;
- // TODO(hta): Make an accessor on TMMBRSet to do this insertion.
const WebRtc_UWord32 kSourceSsrc = 12345;
- bounding_set.ptrPacketOHSet[idx] = 0;
- bounding_set.ptrTmmbrSet[idx] = 32768; // bits per second
- bounding_set.ptrSsrcSet[idx] = kSourceSsrc;
- bounding_set.lengthOfSet++;
+ bounding_set.AddEntry(32768, 0, kSourceSsrc);
EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3));
ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
@@ -224,6 +219,6 @@
// We expect 1 member of the incoming set.
EXPECT_EQ(1, test_transport_->rtcp_receiver_->BoundingSet(owner,
&incoming_set));
- EXPECT_EQ(kSourceSsrc, incoming_set.ptrSsrcSet[0]);
+ EXPECT_EQ(kSourceSsrc, incoming_set.Ssrc(0));
}
} // namespace webrtc
diff --git a/src/modules/rtp_rtcp/source/tmmbr_help.cc b/src/modules/rtp_rtcp/source/tmmbr_help.cc
index 6fba710..50f0e08 100644
--- a/src/modules/rtp_rtcp/source/tmmbr_help.cc
+++ b/src/modules/rtp_rtcp/source/tmmbr_help.cc
@@ -10,56 +10,91 @@
#include "tmmbr_help.h"
+#include <assert.h>
#include <limits>
+#include <string.h>
#include "rtp_rtcp_config.h"
namespace webrtc {
TMMBRSet::TMMBRSet() :
- ptrTmmbrSet(0),
- ptrPacketOHSet(0),
- ptrSsrcSet(0),
- sizeOfSet(0),
- lengthOfSet(0)
+ _sizeOfSet(0),
+ _lengthOfSet(0)
{
}
TMMBRSet::~TMMBRSet()
{
- delete [] ptrTmmbrSet;
- delete [] ptrPacketOHSet;
- delete [] ptrSsrcSet;
- ptrTmmbrSet = 0;
- ptrPacketOHSet = 0;
- ptrSsrcSet = 0;
- sizeOfSet = 0;
- lengthOfSet = 0;
+ _sizeOfSet = 0;
+ _lengthOfSet = 0;
}
void
TMMBRSet::VerifyAndAllocateSet(WebRtc_UWord32 minimumSize)
{
- if(minimumSize > sizeOfSet)
+ if(minimumSize > _sizeOfSet)
{
// make sure that our buffers are big enough
- if(ptrTmmbrSet)
- {
- delete [] ptrTmmbrSet;
- delete [] ptrPacketOHSet;
- delete [] ptrSsrcSet;
- }
- ptrTmmbrSet = new WebRtc_UWord32[minimumSize];
- ptrPacketOHSet = new WebRtc_UWord32[minimumSize];
- ptrSsrcSet = new WebRtc_UWord32[minimumSize];
- sizeOfSet = minimumSize;
+ _data.resize(minimumSize);
+ _sizeOfSet = minimumSize;
}
// reset memory
- for(WebRtc_UWord32 i = 0; i < sizeOfSet; i++)
+ for(WebRtc_UWord32 i = 0; i < _sizeOfSet; i++)
{
- ptrTmmbrSet[i] = 0;
- ptrPacketOHSet[i] = 0;
- ptrSsrcSet[i] = 0;
+ _data.at(i).tmmbr = 0;
+ _data.at(i).packet_oh = 0;
+ _data.at(i).ssrc = 0;
}
- lengthOfSet = 0;
+ _lengthOfSet = 0;
+}
+
+void
+TMMBRSet::VerifyAndAllocateSetKeepingData(WebRtc_UWord32 minimumSize)
+{
+ if(minimumSize > _sizeOfSet)
+ {
+ {
+ _data.resize(minimumSize);
+ }
+ _sizeOfSet = minimumSize;
+ }
+}
+
+void TMMBRSet::SetEntry(unsigned int i,
+ WebRtc_UWord32 tmmbrSet,
+ WebRtc_UWord32 packetOHSet,
+ WebRtc_UWord32 ssrcSet) {
+ assert(i < _sizeOfSet);
+ _data.at(i).tmmbr = tmmbrSet;
+ _data.at(i).packet_oh = packetOHSet;
+ _data.at(i).ssrc = ssrcSet;
+ if (i >= _lengthOfSet) {
+ _lengthOfSet = i + 1;
+ }
+}
+
+void TMMBRSet::AddEntry(WebRtc_UWord32 tmmbrSet,
+ WebRtc_UWord32 packetOHSet,
+ WebRtc_UWord32 ssrcSet) {
+ assert(_lengthOfSet < _sizeOfSet);
+ SetEntry(_lengthOfSet, tmmbrSet, packetOHSet, ssrcSet);
+}
+
+void TMMBRSet::RemoveEntry(WebRtc_UWord32 sourceIdx) {
+ assert(sourceIdx < _lengthOfSet);
+ _data.erase(_data.begin() + sourceIdx);
+ _lengthOfSet--;
+ _data.resize(_sizeOfSet); // Ensure that size remains the same.
+}
+
+void TMMBRSet::SwapEntries(WebRtc_UWord32 i, WebRtc_UWord32 j) {
+ SetElement temp;
+ temp = _data[i];
+ _data[i] = _data[j];
+ _data[j] = temp;
+}
+
+void TMMBRSet::ClearEntry(WebRtc_UWord32 idx) {
+ SetEntry(idx, 0, 0, 0);
}
TMMBRHelp::TMMBRHelp()
@@ -84,7 +119,7 @@
{
CriticalSectionScoped lock(_criticalSection);
- if(minimumSize > _boundingSet.sizeOfSet)
+ if(minimumSize > _boundingSet.sizeOfSet())
{
// make sure that our buffers are big enough
if(_ptrIntersectionBoundingSet)
@@ -111,16 +146,16 @@
if (boundingSetToSend == NULL)
{
- _boundingSetToSend.lengthOfSet = 0;
+ _boundingSetToSend.clearSet();
return 0;
}
- VerifyAndAllocateBoundingSetToSend(boundingSetToSend->lengthOfSet);
-
- for (WebRtc_UWord32 i = 0; i < boundingSetToSend->lengthOfSet; i++)
+ VerifyAndAllocateBoundingSetToSend(boundingSetToSend->lengthOfSet());
+ _boundingSetToSend.clearSet();
+ for (WebRtc_UWord32 i = 0; i < boundingSetToSend->lengthOfSet(); i++)
{
// cap at our configured max bitrate
- WebRtc_UWord32 bitrate = boundingSetToSend->ptrTmmbrSet[i];
+ WebRtc_UWord32 bitrate = boundingSetToSend->Tmmbr(i);
if(maxBitrateKbit)
{
// do we have a configured max bitrate?
@@ -129,12 +164,10 @@
bitrate = maxBitrateKbit;
}
}
-
- _boundingSetToSend.ptrTmmbrSet[i] = bitrate;
- _boundingSetToSend.ptrPacketOHSet[i] = boundingSetToSend->ptrPacketOHSet[i];
- _boundingSetToSend.ptrSsrcSet[i] = boundingSetToSend->ptrSsrcSet[i];
+ _boundingSetToSend.SetEntry(i, bitrate,
+ boundingSetToSend->PacketOH(i),
+ boundingSetToSend->Ssrc(i));
}
- _boundingSetToSend.lengthOfSet = boundingSetToSend->lengthOfSet;
return 0;
}
@@ -175,33 +208,34 @@
// Work on local variable, will be modified
TMMBRSet candidateSet;
- candidateSet.VerifyAndAllocateSet(_candidateSet.sizeOfSet);
+ candidateSet.VerifyAndAllocateSet(_candidateSet.sizeOfSet());
- // Number of set candidates
- WebRtc_Word32 numSetCandidates = 0;
- for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet; i++)
+ // TODO(hta) Figure out if this should be lengthOfSet instead.
+ for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet(); i++)
{
- if(_candidateSet.ptrTmmbrSet[i])
+ if(_candidateSet.Tmmbr(i))
{
- numSetCandidates++;
- candidateSet.ptrTmmbrSet[i] = _candidateSet.ptrTmmbrSet[i];
- candidateSet.ptrPacketOHSet[i] = _candidateSet.ptrPacketOHSet[i];
- candidateSet.ptrSsrcSet[i] = _candidateSet.ptrSsrcSet[i];
+ candidateSet.AddEntry(_candidateSet.Tmmbr(i),
+ _candidateSet.PacketOH(i),
+ _candidateSet.Ssrc(i));
}
else
{
// make sure this is zero if tmmbr = 0
- _candidateSet.ptrPacketOHSet[i] = 0;
+ assert(_candidateSet.PacketOH(i) == 0);
+ // Old code:
+ // _candidateSet.ptrPacketOHSet[i] = 0;
}
}
- candidateSet.lengthOfSet = numSetCandidates;
+ // Number of set candidates
+ WebRtc_Word32 numSetCandidates = candidateSet.lengthOfSet();
// Find bounding set
WebRtc_UWord32 numBoundingSet = 0;
if (numSetCandidates > 0)
{
numBoundingSet = FindTMMBRBoundingSet(numSetCandidates, candidateSet);
- if(numBoundingSet < 1 || (numBoundingSet > _candidateSet.sizeOfSet))
+ if(numBoundingSet < 1 || (numBoundingSet > _candidateSet.sizeOfSet()))
{
return -1;
}
@@ -217,17 +251,18 @@
CriticalSectionScoped lock(_criticalSection);
WebRtc_UWord32 numBoundingSet = 0;
- VerifyAndAllocateBoundingSet(candidateSet.sizeOfSet);
+ VerifyAndAllocateBoundingSet(candidateSet.sizeOfSet());
if (numCandidates == 1)
{
- for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+ // TODO(hta): lengthOfSet instead of sizeOfSet?
+ for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
{
- if(candidateSet.ptrTmmbrSet[i] > 0)
+ if (candidateSet.Tmmbr(i) > 0)
{
- _boundingSet.ptrTmmbrSet[numBoundingSet] = candidateSet.ptrTmmbrSet[i];
- _boundingSet.ptrPacketOHSet[numBoundingSet] = candidateSet.ptrPacketOHSet[i];
- _boundingSet.ptrSsrcSet[numBoundingSet] = candidateSet.ptrSsrcSet[i];
+ _boundingSet.AddEntry(candidateSet.Tmmbr(i),
+ candidateSet.PacketOH(i),
+ candidateSet.Ssrc(i));
numBoundingSet++;
}
}
@@ -238,110 +273,103 @@
} else
{
// 1. Sort by increasing packetOH
- WebRtc_UWord32 temp;
- for (int i = candidateSet.sizeOfSet - 1; i >= 0; i--)
+ for (int i = candidateSet.sizeOfSet() - 1; i >= 0; i--)
{
for (int j = 1; j <= i; j++)
{
- if (candidateSet.ptrPacketOHSet[j-1] > candidateSet.ptrPacketOHSet[j])
+ if (candidateSet.PacketOH(j-1) > candidateSet.PacketOH(j))
{
- temp = candidateSet.ptrPacketOHSet[j-1];
- candidateSet.ptrPacketOHSet[j-1] = candidateSet.ptrPacketOHSet[j];
- candidateSet.ptrPacketOHSet[j] = temp;
- temp = candidateSet.ptrTmmbrSet[j-1];
- candidateSet.ptrTmmbrSet[j-1] = candidateSet.ptrTmmbrSet[j];
- candidateSet.ptrTmmbrSet[j] = temp;
- temp = candidateSet.ptrSsrcSet[j-1];
- candidateSet.ptrSsrcSet[j-1] = candidateSet.ptrSsrcSet[j];
- candidateSet.ptrSsrcSet[j] = temp;
+ candidateSet.SwapEntries(j-1, j);
}
}
}
// 2. For tuples with same OH, keep the one w/ the lowest bitrate
- for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+ for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
{
- if (candidateSet.ptrTmmbrSet[i] > 0)
+ if (candidateSet.Tmmbr(i) > 0)
{
// get min bitrate for packets w/ same OH
- WebRtc_UWord32 currentPacketOH = candidateSet.ptrPacketOHSet[i];
- WebRtc_UWord32 currentMinTMMBR = candidateSet.ptrTmmbrSet[i];
+ WebRtc_UWord32 currentPacketOH = candidateSet.PacketOH(i);
+ WebRtc_UWord32 currentMinTMMBR = candidateSet.Tmmbr(i);
WebRtc_UWord32 currentMinIndexTMMBR = i;
- for (WebRtc_UWord32 j = i+1; j < candidateSet.sizeOfSet; j++)
+ for (WebRtc_UWord32 j = i+1; j < candidateSet.sizeOfSet(); j++)
{
- if(candidateSet.ptrPacketOHSet[j] == currentPacketOH)
+ if(candidateSet.PacketOH(j) == currentPacketOH)
{
- if(candidateSet.ptrTmmbrSet[j] < currentMinTMMBR)
+ if(candidateSet.Tmmbr(j) < currentMinTMMBR)
{
- currentMinTMMBR = candidateSet.ptrTmmbrSet[j];
+ currentMinTMMBR = candidateSet.Tmmbr(j);
currentMinIndexTMMBR = j;
}
}
}
// keep lowest bitrate
- for (WebRtc_UWord32 j = 0; j < candidateSet.sizeOfSet; j++)
+ for (WebRtc_UWord32 j = 0; j < candidateSet.sizeOfSet(); j++)
{
- if(candidateSet.ptrPacketOHSet[j] == currentPacketOH && j != currentMinIndexTMMBR)
+ if(candidateSet.PacketOH(j) == currentPacketOH
+ && j != currentMinIndexTMMBR)
{
- candidateSet.ptrTmmbrSet[j] = 0;
- candidateSet.ptrPacketOHSet[j] = 0;
- candidateSet.ptrSsrcSet[j] = 0;
- numCandidates--;
+ candidateSet.ClearEntry(j);
}
}
}
}
- // 3. Select and remove tuple w/ lowest tmmbr. (If more than 1, choose the one w/ highest OH).
+ // 3. Select and remove tuple w/ lowest tmmbr.
+ // (If more than 1, choose the one w/ highest OH).
WebRtc_UWord32 minTMMBR = 0;
WebRtc_UWord32 minIndexTMMBR = 0;
- for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+ for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
{
- if (candidateSet.ptrTmmbrSet[i] > 0)
+ if (candidateSet.Tmmbr(i) > 0)
{
- minTMMBR = candidateSet.ptrTmmbrSet[i];
+ minTMMBR = candidateSet.Tmmbr(i);
minIndexTMMBR = i;
break;
}
}
- for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+ for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
{
- if (candidateSet.ptrTmmbrSet[i] > 0 && candidateSet.ptrTmmbrSet[i] <= minTMMBR)
+ if (candidateSet.Tmmbr(i) > 0 && candidateSet.Tmmbr(i) <= minTMMBR)
{
// get min bitrate
- minTMMBR = candidateSet.ptrTmmbrSet[i];
+ minTMMBR = candidateSet.Tmmbr(i);
minIndexTMMBR = i;
}
}
// first member of selected list
- _boundingSet.ptrTmmbrSet[numBoundingSet] = candidateSet.ptrTmmbrSet[minIndexTMMBR];
- _boundingSet.ptrPacketOHSet[numBoundingSet] = candidateSet.ptrPacketOHSet[minIndexTMMBR];
- _boundingSet.ptrSsrcSet[numBoundingSet] = candidateSet.ptrSsrcSet[minIndexTMMBR];
+ _boundingSet.SetEntry(numBoundingSet,
+ candidateSet.Tmmbr(minIndexTMMBR),
+ candidateSet.PacketOH(minIndexTMMBR),
+ candidateSet.Ssrc(minIndexTMMBR));
+
// set intersection value
_ptrIntersectionBoundingSet[numBoundingSet] = 0;
// calculate its maximum packet rate (where its line crosses x-axis)
- _ptrMaxPRBoundingSet[numBoundingSet] = _boundingSet.ptrTmmbrSet[numBoundingSet]*1000 / float(8*_boundingSet.ptrPacketOHSet[numBoundingSet]);
+ _ptrMaxPRBoundingSet[numBoundingSet]
+ = _boundingSet.Tmmbr(numBoundingSet) * 1000
+ / float(8 * _boundingSet.PacketOH(numBoundingSet));
numBoundingSet++;
// remove from candidate list
- candidateSet.ptrTmmbrSet[minIndexTMMBR] = 0;
- candidateSet.ptrPacketOHSet[minIndexTMMBR] = 0;
- candidateSet.ptrSsrcSet[minIndexTMMBR] = 0;
+ candidateSet.ClearEntry(minIndexTMMBR);
numCandidates--;
- // 4. Discard from candidate list all tuple w/ lower OH (next tuple must be steeper)
- for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+ // 4. Discard from candidate list all tuple w/ lower OH
+ // (next tuple must be steeper)
+ for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
{
- if(candidateSet.ptrTmmbrSet[i] > 0 && candidateSet.ptrPacketOHSet[i] < _boundingSet.ptrPacketOHSet[0])
+ if(candidateSet.Tmmbr(i) > 0
+ && candidateSet.PacketOH(i) < _boundingSet.PacketOH(0))
{
- candidateSet.ptrTmmbrSet[i] = 0;
- candidateSet.ptrPacketOHSet[i] = 0;
- candidateSet.ptrSsrcSet[i] = 0;
+ candidateSet.ClearEntry(i);
numCandidates--;
}
}
if (numCandidates == 0)
{
- _boundingSet.lengthOfSet = numBoundingSet;
+ // Should be true already:_boundingSet.lengthOfSet = numBoundingSet;
+ assert(_boundingSet.lengthOfSet() == numBoundingSet);
return numBoundingSet;
}
@@ -355,47 +383,54 @@
if (getNewCandidate)
{
// 5. Remove first remaining tuple from candidate list
- for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet; i++)
+ for (WebRtc_UWord32 i = 0; i < candidateSet.sizeOfSet(); i++)
{
- if (candidateSet.ptrTmmbrSet[i] > 0)
+ if (candidateSet.Tmmbr(i) > 0)
{
- curCandidateTMMBR = candidateSet.ptrTmmbrSet[i];
- curCandidatePacketOH = candidateSet.ptrPacketOHSet[i];
- curCandidateSSRC = candidateSet.ptrSsrcSet[i];
+ curCandidateTMMBR = candidateSet.Tmmbr(i);
+ curCandidatePacketOH = candidateSet.PacketOH(i);
+ curCandidateSSRC = candidateSet.Ssrc(i);
curCandidateIndex = i;
- candidateSet.ptrTmmbrSet[curCandidateIndex] = 0;
- candidateSet.ptrPacketOHSet[curCandidateIndex] = 0;
- candidateSet.ptrSsrcSet[curCandidateIndex] = 0;
+ candidateSet.ClearEntry(curCandidateIndex);
break;
}
}
}
- // 6. Calculate packet rate and intersection of the current line with line of last tuple in selected list
- float packetRate = float(curCandidateTMMBR - _boundingSet.ptrTmmbrSet[numBoundingSet-1])*1000 / (8*(curCandidatePacketOH - _boundingSet.ptrPacketOHSet[numBoundingSet-1]));
+ // 6. Calculate packet rate and intersection of the current
+ // line with line of last tuple in selected list
+ float packetRate
+ = float(curCandidateTMMBR
+ - _boundingSet.Tmmbr(numBoundingSet-1))*1000
+ / (8*(curCandidatePacketOH
+ - _boundingSet.PacketOH(numBoundingSet-1)));
- // 7. If the packet rate is equal or lower than intersection of last tuple in selected list,
+ // 7. If the packet rate is equal or lower than intersection of
+ // last tuple in selected list,
// remove last tuple in selected list & go back to step 6
if(packetRate <= _ptrIntersectionBoundingSet[numBoundingSet-1])
{
// remove last tuple and goto step 6
numBoundingSet--;
- _boundingSet.ptrTmmbrSet[numBoundingSet] = 0;
- _boundingSet.ptrPacketOHSet[numBoundingSet] = 0;
- _boundingSet.ptrSsrcSet[numBoundingSet] = 0;
+ _boundingSet.ClearEntry(numBoundingSet);
_ptrIntersectionBoundingSet[numBoundingSet] = 0;
_ptrMaxPRBoundingSet[numBoundingSet] = 0;
getNewCandidate = false;
} else
{
- // 8. If packet rate is lower than maximum packet rate of last tuple in selected list, add current tuple to selected list
+ // 8. If packet rate is lower than maximum packet rate of
+ // last tuple in selected list, add current tuple to selected
+ // list
if (packetRate < _ptrMaxPRBoundingSet[numBoundingSet-1])
{
- _boundingSet.ptrTmmbrSet[numBoundingSet] = curCandidateTMMBR;
- _boundingSet.ptrPacketOHSet[numBoundingSet] = curCandidatePacketOH;
- _boundingSet.ptrSsrcSet[numBoundingSet] = curCandidateSSRC;
+ _boundingSet.SetEntry(numBoundingSet,
+ curCandidateTMMBR,
+ curCandidatePacketOH,
+ curCandidateSSRC);
_ptrIntersectionBoundingSet[numBoundingSet] = packetRate;
- _ptrMaxPRBoundingSet[numBoundingSet] = _boundingSet.ptrTmmbrSet[numBoundingSet]*1000 / float(8*_boundingSet.ptrPacketOHSet[numBoundingSet]);
+ _ptrMaxPRBoundingSet[numBoundingSet]
+ = _boundingSet.Tmmbr(numBoundingSet)*1000
+ / float(8*_boundingSet.PacketOH(numBoundingSet));
numBoundingSet++;
}
numCandidates--;
@@ -405,7 +440,6 @@
// 9. Go back to step 5 if any tuple remains in candidate list
} while (numCandidates > 0);
}
- _boundingSet.lengthOfSet = numBoundingSet;
return numBoundingSet;
}
@@ -417,8 +451,9 @@
// Empty bounding set.
return false;
}
- for(WebRtc_UWord32 i = 0; (i < length) && (i < _boundingSet.sizeOfSet); ++i) {
- if(_boundingSet.ptrSsrcSet[i] == ssrc) {
+ for(WebRtc_UWord32 i = 0;
+ (i < length) && (i < _boundingSet.sizeOfSet()); ++i) {
+ if(_boundingSet.Ssrc(i) == ssrc) {
return true;
}
}
@@ -428,14 +463,14 @@
bool TMMBRHelp::CalcMinBitRate( WebRtc_UWord32* minBitrateKbit) const {
CriticalSectionScoped lock(_criticalSection);
- if (_candidateSet.sizeOfSet == 0) {
+ if (_candidateSet.sizeOfSet() == 0) {
// Empty bounding set.
return false;
}
*minBitrateKbit = std::numeric_limits<uint32_t>::max();
- for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet; ++i) {
- WebRtc_UWord32 curNetBitRateKbit = _candidateSet.ptrTmmbrSet[i];
+ for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet(); ++i) {
+ WebRtc_UWord32 curNetBitRateKbit = _candidateSet.Tmmbr(i);
if (curNetBitRateKbit < MIN_VIDEO_BW_MANAGEMENT_BITRATE) {
curNetBitRateKbit = MIN_VIDEO_BW_MANAGEMENT_BITRATE;
}
diff --git a/src/modules/rtp_rtcp/source/tmmbr_help.h b/src/modules/rtp_rtcp/source/tmmbr_help.h
index 6b3cd97..45ce1c4 100644
--- a/src/modules/rtp_rtcp/source/tmmbr_help.h
+++ b/src/modules/rtp_rtcp/source/tmmbr_help.h
@@ -11,6 +11,7 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_TMMBR_HELP_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_TMMBR_HELP_H_
+#include <vector>
#include "typedefs.h"
#include "critical_section_wrapper.h"
@@ -27,12 +28,55 @@
~TMMBRSet();
void VerifyAndAllocateSet(WebRtc_UWord32 minimumSize);
+ void VerifyAndAllocateSetKeepingData(WebRtc_UWord32 minimumSize);
+ // Number of valid data items in set.
+ WebRtc_UWord32 lengthOfSet() const { return _lengthOfSet; }
+ // Presently allocated max size of set.
+ WebRtc_UWord32 sizeOfSet() const { return _sizeOfSet; }
+ void clearSet() {
+ _lengthOfSet = 0;
+ }
+ WebRtc_UWord32 Tmmbr(int i) const {
+ return _data.at(i).tmmbr;
+ }
+ WebRtc_UWord32 PacketOH(int i) const {
+ return _data.at(i).packet_oh;
+ }
+ WebRtc_UWord32 Ssrc(int i) const {
+ return _data.at(i).ssrc;
+ }
+ void SetEntry(unsigned int i,
+ WebRtc_UWord32 tmmbrSet,
+ WebRtc_UWord32 packetOHSet,
+ WebRtc_UWord32 ssrcSet);
- WebRtc_UWord32* ptrTmmbrSet;
- WebRtc_UWord32* ptrPacketOHSet;
- WebRtc_UWord32* ptrSsrcSet;
- WebRtc_UWord32 sizeOfSet;
- WebRtc_UWord32 lengthOfSet;
+ void AddEntry(WebRtc_UWord32 tmmbrSet,
+ WebRtc_UWord32 packetOHSet,
+ WebRtc_UWord32 ssrcSet);
+
+ // Remove one entry from table, and move all others down.
+ void RemoveEntry(WebRtc_UWord32 sourceIdx);
+
+ void SwapEntries(WebRtc_UWord32 firstIdx,
+ WebRtc_UWord32 secondIdx);
+
+ // Set entry data to zero, but keep it in table.
+ void ClearEntry(WebRtc_UWord32 idx);
+
+ private:
+ class SetElement {
+ public:
+ SetElement() : tmmbr(0), packet_oh(0), ssrc(0) {}
+ WebRtc_UWord32 tmmbr;
+ WebRtc_UWord32 packet_oh;
+ WebRtc_UWord32 ssrc;
+ };
+
+ std::vector<SetElement> _data;
+ // Number of places allocated.
+ WebRtc_UWord32 _sizeOfSet;
+ // NUmber of places currently in use.
+ WebRtc_UWord32 _lengthOfSet;
};
class TMMBRHelp