1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11
12// This file includes unit tests for ViERemb.
13
14#include <vector>
15
16#include "testing/gmock/include/gmock/gmock.h"
17#include "testing/gtest/include/gtest/gtest.h"
18#include "webrtc/base/scoped_ptr.h"
19#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
20#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
21#include "webrtc/modules/utility/include/mock/mock_process_thread.h"
22#include "webrtc/system_wrappers/include/tick_util.h"
23#include "webrtc/video/vie_remb.h"
24
25using ::testing::_;
26using ::testing::AnyNumber;
27using ::testing::NiceMock;
28using ::testing::Return;
29
30namespace webrtc {
31
32class ViERembTest : public ::testing::Test {
33 public:
34  ViERembTest() : fake_clock_(12345) {}
35
36 protected:
37  virtual void SetUp() {
38    process_thread_.reset(new NiceMock<MockProcessThread>);
39    vie_remb_.reset(new VieRemb(&fake_clock_));
40  }
41  SimulatedClock fake_clock_;
42  rtc::scoped_ptr<MockProcessThread> process_thread_;
43  rtc::scoped_ptr<VieRemb> vie_remb_;
44};
45
46TEST_F(ViERembTest, OneModuleTestForSendingRemb) {
47  MockRtpRtcp rtp;
48  vie_remb_->AddReceiveChannel(&rtp);
49  vie_remb_->AddRembSender(&rtp);
50
51  const unsigned int bitrate_estimate = 456;
52  unsigned int ssrc = 1234;
53  std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
54
55  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
56
57  fake_clock_.AdvanceTimeMilliseconds(1000);
58  EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, ssrcs))
59      .Times(1);
60  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
61
62  // Lower bitrate to send another REMB packet.
63  EXPECT_CALL(rtp, SetREMBData(bitrate_estimate - 100, ssrcs))
64        .Times(1);
65  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate - 100);
66
67  vie_remb_->RemoveReceiveChannel(&rtp);
68  vie_remb_->RemoveRembSender(&rtp);
69}
70
71TEST_F(ViERembTest, LowerEstimateToSendRemb) {
72  MockRtpRtcp rtp;
73  vie_remb_->AddReceiveChannel(&rtp);
74  vie_remb_->AddRembSender(&rtp);
75
76  unsigned int bitrate_estimate = 456;
77  unsigned int ssrc = 1234;
78  std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
79
80  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
81  // Call OnReceiveBitrateChanged twice to get a first estimate.
82  fake_clock_.AdvanceTimeMilliseconds(1000);
83  EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, ssrcs))
84        .Times(1);
85  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
86
87  // Lower the estimate with more than 3% to trigger a call to SetREMBData right
88  // away.
89  bitrate_estimate = bitrate_estimate - 100;
90  EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, ssrcs))
91      .Times(1);
92  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
93}
94
95TEST_F(ViERembTest, VerifyIncreasingAndDecreasing) {
96  MockRtpRtcp rtp_0;
97  MockRtpRtcp rtp_1;
98  vie_remb_->AddReceiveChannel(&rtp_0);
99  vie_remb_->AddRembSender(&rtp_0);
100  vie_remb_->AddReceiveChannel(&rtp_1);
101
102  unsigned int bitrate_estimate[] = { 456, 789 };
103  unsigned int ssrc[] = { 1234, 5678 };
104  std::vector<unsigned int> ssrcs(ssrc, ssrc + sizeof(ssrc) / sizeof(ssrc[0]));
105
106  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[0]);
107
108  // Call OnReceiveBitrateChanged twice to get a first estimate.
109  EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate[0], ssrcs))
110        .Times(1);
111  fake_clock_.AdvanceTimeMilliseconds(1000);
112  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[0]);
113
114  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[1] + 100);
115
116  // Lower the estimate to trigger a callback.
117  EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate[1], ssrcs))
118      .Times(1);
119  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[1]);
120
121  vie_remb_->RemoveReceiveChannel(&rtp_0);
122  vie_remb_->RemoveRembSender(&rtp_0);
123  vie_remb_->RemoveReceiveChannel(&rtp_1);
124}
125
126TEST_F(ViERembTest, NoRembForIncreasedBitrate) {
127  MockRtpRtcp rtp_0;
128  MockRtpRtcp rtp_1;
129  vie_remb_->AddReceiveChannel(&rtp_0);
130  vie_remb_->AddRembSender(&rtp_0);
131  vie_remb_->AddReceiveChannel(&rtp_1);
132
133  unsigned int bitrate_estimate = 456;
134  unsigned int ssrc[] = { 1234, 5678 };
135  std::vector<unsigned int> ssrcs(ssrc, ssrc + sizeof(ssrc) / sizeof(ssrc[0]));
136
137  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
138  // Call OnReceiveBitrateChanged twice to get a first estimate.
139  fake_clock_.AdvanceTimeMilliseconds(1000);
140  EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate, ssrcs))
141      .Times(1);
142  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
143
144  // Increased estimate shouldn't trigger a callback right away.
145  EXPECT_CALL(rtp_0, SetREMBData(_, _))
146      .Times(0);
147  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate + 1);
148
149  // Decreasing the estimate less than 3% shouldn't trigger a new callback.
150  EXPECT_CALL(rtp_0, SetREMBData(_, _))
151      .Times(0);
152  int lower_estimate = bitrate_estimate * 98 / 100;
153  vie_remb_->OnReceiveBitrateChanged(ssrcs, lower_estimate);
154
155  vie_remb_->RemoveReceiveChannel(&rtp_1);
156  vie_remb_->RemoveReceiveChannel(&rtp_0);
157  vie_remb_->RemoveRembSender(&rtp_0);
158}
159
160TEST_F(ViERembTest, ChangeSendRtpModule) {
161  MockRtpRtcp rtp_0;
162  MockRtpRtcp rtp_1;
163  vie_remb_->AddReceiveChannel(&rtp_0);
164  vie_remb_->AddRembSender(&rtp_0);
165  vie_remb_->AddReceiveChannel(&rtp_1);
166
167  unsigned int bitrate_estimate = 456;
168  unsigned int ssrc[] = { 1234, 5678 };
169  std::vector<unsigned int> ssrcs(ssrc, ssrc + sizeof(ssrc) / sizeof(ssrc[0]));
170
171  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
172  // Call OnReceiveBitrateChanged twice to get a first estimate.
173  fake_clock_.AdvanceTimeMilliseconds(1000);
174  EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate, ssrcs))
175      .Times(1);
176  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
177
178  // Decrease estimate to trigger a REMB.
179  bitrate_estimate = bitrate_estimate - 100;
180  EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate, ssrcs))
181      .Times(1);
182  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
183
184  // Remove the sending module, add it again -> should get remb on the second
185  // module.
186  vie_remb_->RemoveRembSender(&rtp_0);
187  vie_remb_->AddRembSender(&rtp_1);
188  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
189
190  bitrate_estimate = bitrate_estimate - 100;
191  EXPECT_CALL(rtp_1, SetREMBData(bitrate_estimate, ssrcs))
192        .Times(1);
193  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
194
195  vie_remb_->RemoveReceiveChannel(&rtp_0);
196  vie_remb_->RemoveReceiveChannel(&rtp_1);
197}
198
199TEST_F(ViERembTest, OnlyOneRembForDoubleProcess) {
200  MockRtpRtcp rtp;
201  unsigned int bitrate_estimate = 456;
202  unsigned int ssrc = 1234;
203  std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
204
205  vie_remb_->AddReceiveChannel(&rtp);
206  vie_remb_->AddRembSender(&rtp);
207  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
208  // Call OnReceiveBitrateChanged twice to get a first estimate.
209  fake_clock_.AdvanceTimeMilliseconds(1000);
210  EXPECT_CALL(rtp, SetREMBData(_, _))
211        .Times(1);
212  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
213
214  // Lower the estimate, should trigger a call to SetREMBData right away.
215  bitrate_estimate = bitrate_estimate - 100;
216  EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, ssrcs))
217      .Times(1);
218  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
219
220  // Call OnReceiveBitrateChanged again, this should not trigger a new callback.
221  EXPECT_CALL(rtp, SetREMBData(_, _))
222      .Times(0);
223  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
224  vie_remb_->RemoveReceiveChannel(&rtp);
225  vie_remb_->RemoveRembSender(&rtp);
226}
227
228// Only register receiving modules and make sure we fallback to trigger a REMB
229// packet on this one.
230TEST_F(ViERembTest, NoSendingRtpModule) {
231  MockRtpRtcp rtp;
232  vie_remb_->AddReceiveChannel(&rtp);
233
234  unsigned int bitrate_estimate = 456;
235  unsigned int ssrc = 1234;
236  std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
237
238  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
239
240  // Call OnReceiveBitrateChanged twice to get a first estimate.
241  fake_clock_.AdvanceTimeMilliseconds(1000);
242  EXPECT_CALL(rtp, SetREMBData(_, _))
243      .Times(1);
244  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
245
246  // Lower the estimate to trigger a new packet REMB packet.
247  bitrate_estimate = bitrate_estimate - 100;
248  EXPECT_CALL(rtp, SetREMBData(_, _))
249      .Times(1);
250  vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
251}
252
253}  // namespace webrtc
254