From 54536bb6d4073c35524579e6be58888213398af4 Mon Sep 17 00:00:00 2001 From: "hta@webrtc.org" Date: Thu, 3 May 2012 14:07:23 +0000 Subject: [PATCH] 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 --- src/modules/rtp_rtcp/source/rtcp_receiver.cc | 38 +-- .../rtp_rtcp/source/rtcp_receiver_help.cc | 74 ++--- .../rtp_rtcp/source/rtcp_receiver_test.cc | 8 +- src/modules/rtp_rtcp/source/rtcp_sender.cc | 34 +- .../rtp_rtcp/source/rtcp_sender_test.cc | 9 +- src/modules/rtp_rtcp/source/tmmbr_help.cc | 295 ++++++++++-------- src/modules/rtp_rtcp/source/tmmbr_help.h | 54 +++- 7 files changed, 284 insertions(+), 228 deletions(-) diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver.cc b/src/modules/rtp_rtcp/source/rtcp_receiver.cc index 9caac861d..2fc7c8393 100644 --- a/src/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/src/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -649,7 +649,7 @@ bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() { 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 @@ WebRtc_Word32 RTCPReceiver::BoundingSet(bool &tmmbrOwner, __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 @@ void 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 @@ WebRtc_Word32 RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size, 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 @@ WebRtc_Word32 RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size, __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 0058acabb..1b74c685a 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 @@ RTCPReceiveInformation::~RTCPReceiveInformation() } } -// 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 @@ RTCPReceiveInformation::InsertTMMBRItem(const WebRtc_UWord32 senderSSRC, 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 @@ RTCPReceiveInformation::GetTMMBRSet(const WebRtc_UWord32 sourceIdx, 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 @@ RTCPReceiveInformation::GetTMMBRSet(const WebRtc_UWord32 sourceIdx, 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 ff9ed1a75..5bfdb7344 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 @@ TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) { 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 @@ TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) { 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 @@ TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) { 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 2fe0380d5..6383f8f36 100644 --- a/src/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/src/modules/rtp_rtcp/source/rtcp_sender.cc @@ -1134,18 +1134,21 @@ RTCPSender::BuildTMMBR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) // 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 @@ RTCPSender::BuildTMMBR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) { // 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 @@ RTCPSender::BuildTMMBN(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) 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 @@ RTCPSender::BuildTMMBN(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) // 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 @@ RTCPSender::BuildTMMBN(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) } } 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 59fb71b57..2d86682ba 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 @@ TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndValid) { 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 @@ TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndValid) { // 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 6fba71013..50f0e0804 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 #include +#include #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 @@ TMMBRHelp::VerifyAndAllocateBoundingSet(WebRtc_UWord32 minimumSize) { 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 @@ TMMBRHelp::SetTMMBRBoundingSetToSend(const TMMBRSet* boundingSetToSend, 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 @@ TMMBRHelp::SetTMMBRBoundingSetToSend(const TMMBRSet* boundingSetToSend, 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 @@ TMMBRHelp::FindTMMBRBoundingSet(TMMBRSet*& boundingSet) // 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 @@ TMMBRHelp::FindTMMBRBoundingSet(WebRtc_Word32 numCandidates, TMMBRSet& candidate 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 @@ TMMBRHelp::FindTMMBRBoundingSet(WebRtc_Word32 numCandidates, TMMBRSet& candidate } 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 @@ TMMBRHelp::FindTMMBRBoundingSet(WebRtc_Word32 numCandidates, TMMBRSet& candidate 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 @@ TMMBRHelp::FindTMMBRBoundingSet(WebRtc_Word32 numCandidates, TMMBRSet& candidate // 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 @@ bool TMMBRHelp::IsOwner(const WebRtc_UWord32 ssrc, // 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::IsOwner(const WebRtc_UWord32 ssrc, 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::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 6b3cd975e..45ce1c47a 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 #include "typedefs.h" #include "critical_section_wrapper.h" @@ -27,12 +28,55 @@ public: ~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 _data; + // Number of places allocated. + WebRtc_UWord32 _sizeOfSet; + // NUmber of places currently in use. + WebRtc_UWord32 _lengthOfSet; }; class TMMBRHelp