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