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
This commit is contained in:
parent
3bc38c86e8
commit
54536bb6d4
@ -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++;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 @@ 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<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;
|
||||
}
|
||||
|
@ -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 @@ 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<SetElement> _data;
|
||||
// Number of places allocated.
|
||||
WebRtc_UWord32 _sizeOfSet;
|
||||
// NUmber of places currently in use.
|
||||
WebRtc_UWord32 _lengthOfSet;
|
||||
};
|
||||
|
||||
class TMMBRHelp
|
||||
|
Loading…
Reference in New Issue
Block a user