1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <assert.h>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <limits>
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h>
16cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h"
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRSet::TMMBRSet() :
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _sizeOfSet(0),
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _lengthOfSet(0)
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRSet::~TMMBRSet()
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _sizeOfSet = 0;
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _lengthOfSet = 0;
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
32b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgTMMBRSet::VerifyAndAllocateSet(uint32_t minimumSize)
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(minimumSize > _sizeOfSet)
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // make sure that our buffers are big enough
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _data.resize(minimumSize);
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _sizeOfSet = minimumSize;
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // reset memory
41b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    for(uint32_t i = 0; i < _sizeOfSet; i++)
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _data.at(i).tmmbr = 0;
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _data.at(i).packet_oh = 0;
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _data.at(i).ssrc = 0;
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _lengthOfSet = 0;
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
51b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgTMMBRSet::VerifyAndAllocateSetKeepingData(uint32_t minimumSize)
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(minimumSize > _sizeOfSet)
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          _data.resize(minimumSize);
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _sizeOfSet = minimumSize;
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid TMMBRSet::SetEntry(unsigned int i,
63b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                         uint32_t tmmbrSet,
64b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                         uint32_t packetOHSet,
65b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                         uint32_t ssrcSet) {
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(i < _sizeOfSet);
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _data.at(i).tmmbr = tmmbrSet;
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _data.at(i).packet_oh = packetOHSet;
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _data.at(i).ssrc = ssrcSet;
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (i >= _lengthOfSet) {
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _lengthOfSet = i + 1;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
75b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgvoid TMMBRSet::AddEntry(uint32_t tmmbrSet,
76b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                        uint32_t packetOHSet,
77b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                        uint32_t ssrcSet) {
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(_lengthOfSet < _sizeOfSet);
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SetEntry(_lengthOfSet, tmmbrSet, packetOHSet, ssrcSet);
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
82b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgvoid TMMBRSet::RemoveEntry(uint32_t sourceIdx) {
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(sourceIdx < _lengthOfSet);
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _data.erase(_data.begin() + sourceIdx);
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _lengthOfSet--;
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _data.resize(_sizeOfSet);  // Ensure that size remains the same.
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
89b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgvoid TMMBRSet::SwapEntries(uint32_t i, uint32_t j) {
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    SetElement temp;
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    temp = _data[i];
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _data[i] = _data[j];
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _data[j] = temp;
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
96b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgvoid TMMBRSet::ClearEntry(uint32_t idx) {
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SetEntry(idx, 0, 0, 0);
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRHelp::TMMBRHelp()
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : _criticalSection(CriticalSectionWrapper::CreateCriticalSection()),
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _candidateSet(),
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _boundingSet(),
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _boundingSetToSend(),
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _ptrIntersectionBoundingSet(NULL),
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _ptrMaxPRBoundingSet(NULL) {
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRHelp::~TMMBRHelp() {
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  delete [] _ptrIntersectionBoundingSet;
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  delete [] _ptrMaxPRBoundingSet;
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _ptrIntersectionBoundingSet = 0;
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _ptrMaxPRBoundingSet = 0;
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  delete _criticalSection;
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRSet*
118b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgTMMBRHelp::VerifyAndAllocateBoundingSet(uint32_t minimumSize)
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped lock(_criticalSection);
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(minimumSize > _boundingSet.sizeOfSet())
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // make sure that our buffers are big enough
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(_ptrIntersectionBoundingSet)
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            delete [] _ptrIntersectionBoundingSet;
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            delete [] _ptrMaxPRBoundingSet;
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _ptrIntersectionBoundingSet = new float[minimumSize];
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _ptrMaxPRBoundingSet = new float[minimumSize];
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _boundingSet.VerifyAndAllocateSet(minimumSize);
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return &_boundingSet;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRSet* TMMBRHelp::BoundingSet() {
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return &_boundingSet;
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
141b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRHelp::SetTMMBRBoundingSetToSend(const TMMBRSet* boundingSetToSend,
143b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                                     const uint32_t maxBitrateKbit)
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped lock(_criticalSection);
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (boundingSetToSend == NULL)
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _boundingSetToSend.clearSet();
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VerifyAndAllocateBoundingSetToSend(boundingSetToSend->lengthOfSet());
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _boundingSetToSend.clearSet();
155b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    for (uint32_t i = 0; i < boundingSetToSend->lengthOfSet(); i++)
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // cap at our configured max bitrate
158b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        uint32_t bitrate = boundingSetToSend->Tmmbr(i);
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(maxBitrateKbit)
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // do we have a configured max bitrate?
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if(bitrate > maxBitrateKbit)
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                bitrate = maxBitrateKbit;
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _boundingSetToSend.SetEntry(i, bitrate,
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    boundingSetToSend->PacketOH(i),
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    boundingSetToSend->Ssrc(i));
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
174b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t
175b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgTMMBRHelp::VerifyAndAllocateBoundingSetToSend(uint32_t minimumSize)
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped lock(_criticalSection);
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _boundingSetToSend.VerifyAndAllocateSet(minimumSize);
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRSet*
184b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgTMMBRHelp::VerifyAndAllocateCandidateSet(uint32_t minimumSize)
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped lock(_criticalSection);
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _candidateSet.VerifyAndAllocateSet(minimumSize);
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return &_candidateSet;
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRSet*
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRHelp::CandidateSet()
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return &_candidateSet;
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRSet*
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRHelp::BoundingSetToSend()
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return &_boundingSetToSend;
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
204b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTMMBRHelp::FindTMMBRBoundingSet(TMMBRSet*& boundingSet)
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped lock(_criticalSection);
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Work on local variable, will be modified
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TMMBRSet    candidateSet;
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    candidateSet.VerifyAndAllocateSet(_candidateSet.sizeOfSet());
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // TODO(hta) Figure out if this should be lengthOfSet instead.
214b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    for (uint32_t i = 0; i < _candidateSet.sizeOfSet(); i++)
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(_candidateSet.Tmmbr(i))
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            candidateSet.AddEntry(_candidateSet.Tmmbr(i),
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                  _candidateSet.PacketOH(i),
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                  _candidateSet.Ssrc(i));
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        else
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // make sure this is zero if tmmbr = 0
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            assert(_candidateSet.PacketOH(i) == 0);
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // Old code:
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // _candidateSet.ptrPacketOHSet[i] = 0;
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Number of set candidates
232b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    int32_t numSetCandidates = candidateSet.lengthOfSet();
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Find bounding set
234b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    uint32_t numBoundingSet = 0;
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (numSetCandidates > 0)
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        numBoundingSet =  FindTMMBRBoundingSet(numSetCandidates, candidateSet);
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(numBoundingSet < 1 || (numBoundingSet > _candidateSet.sizeOfSet()))
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return -1;
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        boundingSet = &_boundingSet;
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return numBoundingSet;
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
248b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t
249b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgTMMBRHelp::FindTMMBRBoundingSet(int32_t numCandidates, TMMBRSet& candidateSet)
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped lock(_criticalSection);
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
253b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    uint32_t numBoundingSet = 0;
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VerifyAndAllocateBoundingSet(candidateSet.sizeOfSet());
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (numCandidates == 1)
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // TODO(hta): lengthOfSet instead of sizeOfSet?
259b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++)
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (candidateSet.Tmmbr(i) > 0)
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                _boundingSet.AddEntry(candidateSet.Tmmbr(i),
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    candidateSet.PacketOH(i),
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    candidateSet.Ssrc(i));
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                numBoundingSet++;
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
2699fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        return (numBoundingSet == 1) ? 1 : -1;
2709fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    }
2719fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org
2729fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // 1. Sort by increasing packetOH
2739fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    for (int i = candidateSet.sizeOfSet() - 1; i >= 0; i--)
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
2759fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        for (int j = 1; j <= i; j++)
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
2779fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            if (candidateSet.PacketOH(j-1) > candidateSet.PacketOH(j))
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
2799fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                candidateSet.SwapEntries(j-1, j);
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
2829fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    }
2839fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // 2. For tuples with same OH, keep the one w/ the lowest bitrate
2849fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++)
2859fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    {
2869fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        if (candidateSet.Tmmbr(i) > 0)
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
2889fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            // get min bitrate for packets w/ same OH
2899fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            uint32_t currentPacketOH = candidateSet.PacketOH(i);
2909fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            uint32_t currentMinTMMBR = candidateSet.Tmmbr(i);
2919fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            uint32_t currentMinIndexTMMBR = i;
2929fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            for (uint32_t j = i+1; j < candidateSet.sizeOfSet(); j++)
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
2949fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                if(candidateSet.PacketOH(j) == currentPacketOH)
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
2969fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    if(candidateSet.Tmmbr(j) < currentMinTMMBR)
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    {
2989fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                        currentMinTMMBR = candidateSet.Tmmbr(j);
2999fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                        currentMinIndexTMMBR = j;
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    }
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
3029fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            }
3039fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            // keep lowest bitrate
3049fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            for (uint32_t j = 0; j < candidateSet.sizeOfSet(); j++)
3059fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            {
3069fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org              if(candidateSet.PacketOH(j) == currentPacketOH
3079fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                  && j != currentMinIndexTMMBR)
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
3099fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    candidateSet.ClearEntry(j);
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
3139fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    }
3149fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // 3. Select and remove tuple w/ lowest tmmbr.
3159fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // (If more than 1, choose the one w/ highest OH).
3169fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    uint32_t minTMMBR = 0;
3179fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    uint32_t minIndexTMMBR = 0;
3189fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++)
3199fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    {
3209fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        if (candidateSet.Tmmbr(i) > 0)
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
3229fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            minTMMBR = candidateSet.Tmmbr(i);
3239fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            minIndexTMMBR = i;
3249fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            break;
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
3269fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    }
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3289fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++)
3299fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    {
3309fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        if (candidateSet.Tmmbr(i) > 0 && candidateSet.Tmmbr(i) <= minTMMBR)
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
3329fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            // get min bitrate
3339fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            minTMMBR = candidateSet.Tmmbr(i);
3349fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            minIndexTMMBR = i;
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
3369fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    }
3379fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // first member of selected list
3389fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    _boundingSet.SetEntry(numBoundingSet,
3399fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                          candidateSet.Tmmbr(minIndexTMMBR),
3409fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                          candidateSet.PacketOH(minIndexTMMBR),
3419fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                          candidateSet.Ssrc(minIndexTMMBR));
3429fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org
3439fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // set intersection value
3449fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    _ptrIntersectionBoundingSet[numBoundingSet] = 0;
3459fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // calculate its maximum packet rate (where its line crosses x-axis)
3469fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    _ptrMaxPRBoundingSet[numBoundingSet]
3479fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        = _boundingSet.Tmmbr(numBoundingSet) * 1000
3489fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        / float(8 * _boundingSet.PacketOH(numBoundingSet));
3499fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    numBoundingSet++;
3509fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // remove from candidate list
3519fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    candidateSet.ClearEntry(minIndexTMMBR);
3529fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    numCandidates--;
3539fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org
3549fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // 4. Discard from candidate list all tuple w/ lower OH
3559fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    // (next tuple must be steeper)
3569fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++)
3579fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    {
3589fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        if(candidateSet.Tmmbr(i) > 0
3599fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            && candidateSet.PacketOH(i) < _boundingSet.PacketOH(0))
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
3619fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            candidateSet.ClearEntry(i);
3629fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            numCandidates--;
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
3649fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    }
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3669fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    if (numCandidates == 0)
3679fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    {
3689fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        // Should be true already:_boundingSet.lengthOfSet = numBoundingSet;
3699fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        assert(_boundingSet.lengthOfSet() == numBoundingSet);
3709fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        return numBoundingSet;
3719fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    }
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3739fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    bool getNewCandidate = true;
3749fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    int curCandidateTMMBR = 0;
3759fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    int curCandidateIndex = 0;
3769fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    int curCandidatePacketOH = 0;
3779fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    int curCandidateSSRC = 0;
3789fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    do
3799fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    {
3809fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        if (getNewCandidate)
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
3829fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            // 5. Remove first remaining tuple from candidate list
3839fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++)
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
3859fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                if (candidateSet.Tmmbr(i) > 0)
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
3879fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    curCandidateTMMBR    = candidateSet.Tmmbr(i);
3889fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    curCandidatePacketOH = candidateSet.PacketOH(i);
3899fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    curCandidateSSRC     = candidateSet.Ssrc(i);
3909fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    curCandidateIndex    = i;
3919fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    candidateSet.ClearEntry(curCandidateIndex);
3929fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    break;
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
3959fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        }
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3979fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        // 6. Calculate packet rate and intersection of the current
3989fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        // line with line of last tuple in selected list
3999fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        float packetRate
4009fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            = float(curCandidateTMMBR
4019fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    - _boundingSet.Tmmbr(numBoundingSet-1))*1000
4029fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            / (8*(curCandidatePacketOH
4039fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                  - _boundingSet.PacketOH(numBoundingSet-1)));
4049fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org
4059fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        // 7. If the packet rate is equal or lower than intersection of
4069fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        //    last tuple in selected list,
4079fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        //    remove last tuple in selected list & go back to step 6
4089fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        if(packetRate <= _ptrIntersectionBoundingSet[numBoundingSet-1])
4099fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        {
4109fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            // remove last tuple and goto step 6
4119fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            numBoundingSet--;
4129fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            _boundingSet.ClearEntry(numBoundingSet);
4139fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            _ptrIntersectionBoundingSet[numBoundingSet] = 0;
4149fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            _ptrMaxPRBoundingSet[numBoundingSet]        = 0;
4159fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            getNewCandidate = false;
4169fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        } else
4179fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        {
4189fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            // 8. If packet rate is lower than maximum packet rate of
4199fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            // last tuple in selected list, add current tuple to selected
4209fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            // list
4219fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            if (packetRate < _ptrMaxPRBoundingSet[numBoundingSet-1])
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
4239fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                _boundingSet.SetEntry(numBoundingSet,
4249fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                                      curCandidateTMMBR,
4259fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                                      curCandidatePacketOH,
4269fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                                      curCandidateSSRC);
4279fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                _ptrIntersectionBoundingSet[numBoundingSet] = packetRate;
4289fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                _ptrMaxPRBoundingSet[numBoundingSet]
4299fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    = _boundingSet.Tmmbr(numBoundingSet)*1000
4309fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                    / float(8*_boundingSet.PacketOH(numBoundingSet));
4319fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org                numBoundingSet++;
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
4339fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            numCandidates--;
4349fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org            getNewCandidate = true;
4359fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        }
4369fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org
4379fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org        // 9. Go back to step 5 if any tuple remains in candidate list
4389fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org    } while (numCandidates > 0);
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return numBoundingSet;
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
443b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgbool TMMBRHelp::IsOwner(const uint32_t ssrc,
444b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                        const uint32_t length) const {
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  CriticalSectionScoped lock(_criticalSection);
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (length == 0) {
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Empty bounding set.
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
451b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org  for(uint32_t i = 0;
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      (i < length) && (i < _boundingSet.sizeOfSet()); ++i) {
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(_boundingSet.Ssrc(i) == ssrc) {
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return false;
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
460b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgbool TMMBRHelp::CalcMinBitRate( uint32_t* minBitrateKbit) const {
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  CriticalSectionScoped lock(_criticalSection);
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (_candidateSet.sizeOfSet() == 0) {
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Empty bounding set.
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  *minBitrateKbit = std::numeric_limits<uint32_t>::max();
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
469b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org  for (uint32_t i = 0; i < _candidateSet.lengthOfSet(); ++i) {
470b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    uint32_t curNetBitRateKbit = _candidateSet.Tmmbr(i);
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (curNetBitRateKbit < MIN_VIDEO_BW_MANAGEMENT_BITRATE) {
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      curNetBitRateKbit = MIN_VIDEO_BW_MANAGEMENT_BITRATE;
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    *minBitrateKbit = curNetBitRateKbit < *minBitrateKbit ?
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        curNetBitRateKbit : *minBitrateKbit;
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
4793b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace webrtc
480