blob: b193da8cda39d94fa31fead6c2732f9dc84e2784 [file] [log] [blame]
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +00001/*
2 * Copyright (c) 2015 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
kwiberg27f982b2016-03-01 11:52:33 -080011#include <memory>
Åsa Persson4bece9a2017-10-06 10:04:04 +020012#include <string>
kwiberg27f982b2016-03-01 11:52:33 -080013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "call/video_config.h"
15#include "modules/rtp_rtcp/include/rtp_rtcp.h"
16#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
17#include "modules/video_coding/include/video_codec_interface.h"
Åsa Persson4bece9a2017-10-06 10:04:04 +020018#include "test/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "test/gmock.h"
20#include "test/gtest.h"
21#include "video/payload_router.h"
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000022
23using ::testing::_;
24using ::testing::AnyNumber;
Åsa Persson4bece9a2017-10-06 10:04:04 +020025using ::testing::Invoke;
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000026using ::testing::NiceMock;
27using ::testing::Return;
Åsa Persson4bece9a2017-10-06 10:04:04 +020028using ::testing::Unused;
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000029
30namespace webrtc {
Åsa Persson4bece9a2017-10-06 10:04:04 +020031namespace {
32const int8_t kPayloadType = 96;
33const uint32_t kSsrc1 = 12345;
34const uint32_t kSsrc2 = 23456;
Seth Hampson46e31ba2018-01-18 10:39:54 -080035const uint32_t kSsrc3 = 34567;
Åsa Persson4bece9a2017-10-06 10:04:04 +020036const int16_t kPictureId = 123;
37const int16_t kTl0PicIdx = 20;
38const uint8_t kTemporalIdx = 1;
39const int16_t kInitialPictureId1 = 222;
40const int16_t kInitialPictureId2 = 44;
41} // namespace
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000042
Per83d09102016-04-15 14:59:13 +020043TEST(PayloadRouterTest, SendOnOneModule) {
perkjbc75d972016-05-02 06:31:25 -070044 NiceMock<MockRtpRtcp> rtp;
Peter Boström404686a2016-02-11 23:37:26 +010045 std::vector<RtpRtcp*> modules(1, &rtp);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000046
kjellander02b3d272016-04-20 05:05:54 -070047 uint8_t payload = 'a';
kjellander02b3d272016-04-20 05:05:54 -070048 EncodedImage encoded_image;
49 encoded_image._timeStamp = 1;
50 encoded_image.capture_time_ms_ = 2;
51 encoded_image._frameType = kVideoFrameKey;
52 encoded_image._buffer = &payload;
53 encoded_image._length = 1;
54
Åsa Persson4bece9a2017-10-06 10:04:04 +020055 PayloadRouter payload_router(modules, {kSsrc1}, kPayloadType, {});
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000056
Åsa Persson4bece9a2017-10-06 10:04:04 +020057 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070058 encoded_image._timeStamp,
59 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070060 encoded_image._length, nullptr, _, _))
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000061 .Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -070062 EXPECT_NE(
63 EncodedImageCallback::Result::OK,
64 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000065
sprang1a646ee2016-12-01 06:34:11 -080066 payload_router.SetActive(true);
Åsa Persson4bece9a2017-10-06 10:04:04 +020067 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070068 encoded_image._timeStamp,
69 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070070 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -080071 .Times(1)
72 .WillOnce(Return(true));
Seth Hampsoncc7125f2018-02-02 08:46:16 -080073 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
sergeyu2cb155a2016-11-04 11:39:29 -070074 EXPECT_EQ(
75 EncodedImageCallback::Result::OK,
76 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000077
sprang1a646ee2016-12-01 06:34:11 -080078 payload_router.SetActive(false);
Åsa Persson4bece9a2017-10-06 10:04:04 +020079 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070080 encoded_image._timeStamp,
81 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070082 encoded_image._length, nullptr, _, _))
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000083 .Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -070084 EXPECT_NE(
85 EncodedImageCallback::Result::OK,
86 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000087
sprang1a646ee2016-12-01 06:34:11 -080088 payload_router.SetActive(true);
Åsa Persson4bece9a2017-10-06 10:04:04 +020089 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070090 encoded_image._timeStamp,
91 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070092 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -080093 .Times(1)
94 .WillOnce(Return(true));
Seth Hampsoncc7125f2018-02-02 08:46:16 -080095 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
sergeyu2cb155a2016-11-04 11:39:29 -070096 EXPECT_EQ(
97 EncodedImageCallback::Result::OK,
98 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000099}
100
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800101TEST(PayloadRouterTest, SendSimulcastSetActive) {
perkjbc75d972016-05-02 06:31:25 -0700102 NiceMock<MockRtpRtcp> rtp_1;
103 NiceMock<MockRtpRtcp> rtp_2;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200104 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2};
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000105
kjellander02b3d272016-04-20 05:05:54 -0700106 uint8_t payload = 'a';
107 EncodedImage encoded_image;
108 encoded_image._timeStamp = 1;
109 encoded_image.capture_time_ms_ = 2;
110 encoded_image._frameType = kVideoFrameKey;
111 encoded_image._buffer = &payload;
112 encoded_image._length = 1;
113
Åsa Persson4bece9a2017-10-06 10:04:04 +0200114 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000115
kjellander02b3d272016-04-20 05:05:54 -0700116 CodecSpecificInfo codec_info_1;
117 memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
118 codec_info_1.codecType = kVideoCodecVP8;
119 codec_info_1.codecSpecific.VP8.simulcastIdx = 0;
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000120
sprang1a646ee2016-12-01 06:34:11 -0800121 payload_router.SetActive(true);
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800122 EXPECT_CALL(rtp_1, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200123 EXPECT_CALL(rtp_1, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -0700124 encoded_image._timeStamp,
125 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700126 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -0800127 .Times(1)
128 .WillOnce(Return(true));
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700129 EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -0700130 EXPECT_EQ(EncodedImageCallback::Result::OK,
131 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
132 .error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000133
kjellander02b3d272016-04-20 05:05:54 -0700134 CodecSpecificInfo codec_info_2;
135 memset(&codec_info_2, 0, sizeof(CodecSpecificInfo));
136 codec_info_2.codecType = kVideoCodecVP8;
137 codec_info_2.codecSpecific.VP8.simulcastIdx = 1;
138
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800139 EXPECT_CALL(rtp_2, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200140 EXPECT_CALL(rtp_2, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -0700141 encoded_image._timeStamp,
142 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700143 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -0800144 .Times(1)
145 .WillOnce(Return(true));
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700146 EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _))
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000147 .Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -0700148 EXPECT_EQ(EncodedImageCallback::Result::OK,
149 payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
150 .error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000151
mflodman@webrtc.org50e28162015-02-23 07:45:11 +0000152 // Inactive.
sprang1a646ee2016-12-01 06:34:11 -0800153 payload_router.SetActive(false);
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700154 EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _))
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000155 .Times(0);
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700156 EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _))
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000157 .Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -0700158 EXPECT_NE(EncodedImageCallback::Result::OK,
159 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
160 .error);
161 EXPECT_NE(EncodedImageCallback::Result::OK,
162 payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
163 .error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000164}
165
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800166// Tests how setting individual rtp modules to active affects the overall
167// behavior of the payload router. First sets one module to active and checks
168// that outgoing data can be sent on this module, and checks that no data can be
169// sent if both modules are inactive.
170TEST(PayloadRouterTest, SendSimulcastSetActiveModules) {
171 NiceMock<MockRtpRtcp> rtp_1;
172 NiceMock<MockRtpRtcp> rtp_2;
173 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2};
174
175 uint8_t payload = 'a';
176 EncodedImage encoded_image;
177 encoded_image._timeStamp = 1;
178 encoded_image.capture_time_ms_ = 2;
179 encoded_image._frameType = kVideoFrameKey;
180 encoded_image._buffer = &payload;
181 encoded_image._length = 1;
182 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
183 CodecSpecificInfo codec_info_1;
184 memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
185 codec_info_1.codecType = kVideoCodecVP8;
186 codec_info_1.codecSpecific.VP8.simulcastIdx = 0;
187 CodecSpecificInfo codec_info_2;
188 memset(&codec_info_2, 0, sizeof(CodecSpecificInfo));
189 codec_info_2.codecType = kVideoCodecVP8;
190 codec_info_2.codecSpecific.VP8.simulcastIdx = 1;
191
192 // Only setting one stream to active will still set the payload router to
193 // active and allow sending data on the active stream.
194 std::vector<bool> active_modules({true, false});
195 payload_router.SetActiveModules(active_modules);
196
197 EXPECT_CALL(rtp_1, Sending()).WillOnce(Return(true));
198 EXPECT_CALL(rtp_1, SendOutgoingData(encoded_image._frameType, kPayloadType,
199 encoded_image._timeStamp,
200 encoded_image.capture_time_ms_, &payload,
201 encoded_image._length, nullptr, _, _))
202 .Times(1)
203 .WillOnce(Return(true));
204 EXPECT_EQ(EncodedImageCallback::Result::OK,
205 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
206 .error);
207
208 // Setting both streams to inactive will turn the payload router to inactive.
209 active_modules = {false, false};
210 payload_router.SetActiveModules(active_modules);
211 // An incoming encoded image will not ask the module to send outgoing data
212 // because the payload router is inactive.
213 EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
214 EXPECT_CALL(rtp_1, Sending()).Times(0);
215 EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
216 EXPECT_CALL(rtp_2, Sending()).Times(0);
217 EXPECT_NE(EncodedImageCallback::Result::OK,
218 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
219 .error);
220 EXPECT_NE(EncodedImageCallback::Result::OK,
221 payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
222 .error);
223}
224
sprang1a646ee2016-12-01 06:34:11 -0800225TEST(PayloadRouterTest, SimulcastTargetBitrate) {
226 NiceMock<MockRtpRtcp> rtp_1;
227 NiceMock<MockRtpRtcp> rtp_2;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200228 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2};
229
230 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
sprang1a646ee2016-12-01 06:34:11 -0800231 payload_router.SetActive(true);
232
233 BitrateAllocation bitrate;
234 bitrate.SetBitrate(0, 0, 10000);
235 bitrate.SetBitrate(0, 1, 20000);
236 bitrate.SetBitrate(1, 0, 40000);
237 bitrate.SetBitrate(1, 1, 80000);
238
239 BitrateAllocation layer0_bitrate;
240 layer0_bitrate.SetBitrate(0, 0, 10000);
241 layer0_bitrate.SetBitrate(0, 1, 20000);
242
243 BitrateAllocation layer1_bitrate;
244 layer1_bitrate.SetBitrate(0, 0, 40000);
245 layer1_bitrate.SetBitrate(0, 1, 80000);
246
247 EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(layer0_bitrate)).Times(1);
248 EXPECT_CALL(rtp_2, SetVideoBitrateAllocation(layer1_bitrate)).Times(1);
249
250 payload_router.OnBitrateAllocationUpdated(bitrate);
251}
252
Seth Hampson46e31ba2018-01-18 10:39:54 -0800253// If the middle of three streams is inactive the first and last streams should
254// be asked to send the TargetBitrate message.
sprangd0fc37a2017-06-22 05:40:25 -0700255TEST(PayloadRouterTest, SimulcastTargetBitrateWithInactiveStream) {
Seth Hampson46e31ba2018-01-18 10:39:54 -0800256 // Set up three active rtp modules.
sprangd0fc37a2017-06-22 05:40:25 -0700257 NiceMock<MockRtpRtcp> rtp_1;
258 NiceMock<MockRtpRtcp> rtp_2;
Seth Hampson46e31ba2018-01-18 10:39:54 -0800259 NiceMock<MockRtpRtcp> rtp_3;
260 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2, &rtp_3};
261 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2, kSsrc3}, kPayloadType,
262 {});
sprangd0fc37a2017-06-22 05:40:25 -0700263 payload_router.SetActive(true);
264
Seth Hampson46e31ba2018-01-18 10:39:54 -0800265 // Create bitrate allocation with bitrate only for the first and third stream.
sprangd0fc37a2017-06-22 05:40:25 -0700266 BitrateAllocation bitrate;
267 bitrate.SetBitrate(0, 0, 10000);
268 bitrate.SetBitrate(0, 1, 20000);
Seth Hampson46e31ba2018-01-18 10:39:54 -0800269 bitrate.SetBitrate(2, 0, 40000);
270 bitrate.SetBitrate(2, 1, 80000);
sprangd0fc37a2017-06-22 05:40:25 -0700271
Seth Hampson46e31ba2018-01-18 10:39:54 -0800272 BitrateAllocation layer0_bitrate;
273 layer0_bitrate.SetBitrate(0, 0, 10000);
274 layer0_bitrate.SetBitrate(0, 1, 20000);
275
276 BitrateAllocation layer2_bitrate;
277 layer2_bitrate.SetBitrate(0, 0, 40000);
278 layer2_bitrate.SetBitrate(0, 1, 80000);
279
280 // Expect the first and third rtp module to be asked to send a TargetBitrate
sprangd0fc37a2017-06-22 05:40:25 -0700281 // message. (No target bitrate with 0bps sent from the second one.)
Seth Hampson46e31ba2018-01-18 10:39:54 -0800282 EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(layer0_bitrate)).Times(1);
sprangd0fc37a2017-06-22 05:40:25 -0700283 EXPECT_CALL(rtp_2, SetVideoBitrateAllocation(_)).Times(0);
Seth Hampson46e31ba2018-01-18 10:39:54 -0800284 EXPECT_CALL(rtp_3, SetVideoBitrateAllocation(layer2_bitrate)).Times(1);
sprangd0fc37a2017-06-22 05:40:25 -0700285
286 payload_router.OnBitrateAllocationUpdated(bitrate);
287}
288
sprang1a646ee2016-12-01 06:34:11 -0800289TEST(PayloadRouterTest, SvcTargetBitrate) {
290 NiceMock<MockRtpRtcp> rtp_1;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200291 std::vector<RtpRtcp*> modules = {&rtp_1};
292 PayloadRouter payload_router(modules, {kSsrc1}, kPayloadType, {});
sprang1a646ee2016-12-01 06:34:11 -0800293 payload_router.SetActive(true);
294
295 BitrateAllocation bitrate;
296 bitrate.SetBitrate(0, 0, 10000);
297 bitrate.SetBitrate(0, 1, 20000);
298 bitrate.SetBitrate(1, 0, 40000);
299 bitrate.SetBitrate(1, 1, 80000);
300
301 EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(bitrate)).Times(1);
302
303 payload_router.OnBitrateAllocationUpdated(bitrate);
304}
305
Åsa Persson4bece9a2017-10-06 10:04:04 +0200306TEST(PayloadRouterTest, InfoMappedToRtpVideoHeader_Vp8) {
307 NiceMock<MockRtpRtcp> rtp1;
308 NiceMock<MockRtpRtcp> rtp2;
309 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
310 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
311 payload_router.SetActive(true);
312
313 EncodedImage encoded_image;
314 encoded_image.rotation_ = kVideoRotation_90;
315 encoded_image.content_type_ = VideoContentType::SCREENSHARE;
316
317 CodecSpecificInfo codec_info;
318 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
319 codec_info.codecType = kVideoCodecVP8;
320 codec_info.codecSpecific.VP8.simulcastIdx = 1;
321 codec_info.codecSpecific.VP8.pictureId = kPictureId;
322 codec_info.codecSpecific.VP8.temporalIdx = kTemporalIdx;
323 codec_info.codecSpecific.VP8.tl0PicIdx = kTl0PicIdx;
324 codec_info.codecSpecific.VP8.keyIdx = kNoKeyIdx;
325 codec_info.codecSpecific.VP8.layerSync = true;
326 codec_info.codecSpecific.VP8.nonReference = true;
327
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800328 EXPECT_CALL(rtp2, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200329 EXPECT_CALL(rtp2, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
330 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
331 Unused, const RTPVideoHeader* header, Unused) {
332 EXPECT_EQ(kVideoRotation_90, header->rotation);
333 EXPECT_EQ(VideoContentType::SCREENSHARE, header->content_type);
334 EXPECT_EQ(1, header->simulcastIdx);
335 EXPECT_EQ(kRtpVideoVp8, header->codec);
336 EXPECT_EQ(kPictureId, header->codecHeader.VP8.pictureId);
337 EXPECT_EQ(kTemporalIdx, header->codecHeader.VP8.temporalIdx);
338 EXPECT_EQ(kTl0PicIdx, header->codecHeader.VP8.tl0PicIdx);
339 EXPECT_EQ(kNoKeyIdx, header->codecHeader.VP8.keyIdx);
340 EXPECT_TRUE(header->codecHeader.VP8.layerSync);
341 EXPECT_TRUE(header->codecHeader.VP8.nonReference);
342 return true;
343 }));
344
345 EXPECT_EQ(
346 EncodedImageCallback::Result::OK,
347 payload_router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
348}
349
350TEST(PayloadRouterTest, InfoMappedToRtpVideoHeader_H264) {
351 NiceMock<MockRtpRtcp> rtp1;
352 std::vector<RtpRtcp*> modules = {&rtp1};
353 PayloadRouter payload_router(modules, {kSsrc1}, kPayloadType, {});
354 payload_router.SetActive(true);
355
356 EncodedImage encoded_image;
357 CodecSpecificInfo codec_info;
358 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
359 codec_info.codecType = kVideoCodecH264;
360 codec_info.codecSpecific.H264.packetization_mode =
361 H264PacketizationMode::SingleNalUnit;
362
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800363 EXPECT_CALL(rtp1, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200364 EXPECT_CALL(rtp1, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
365 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
366 Unused, const RTPVideoHeader* header, Unused) {
367 EXPECT_EQ(0, header->simulcastIdx);
368 EXPECT_EQ(kRtpVideoH264, header->codec);
369 EXPECT_EQ(H264PacketizationMode::SingleNalUnit,
370 header->codecHeader.H264.packetization_mode);
371 return true;
372 }));
373
374 EXPECT_EQ(
375 EncodedImageCallback::Result::OK,
376 payload_router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
377}
378
379TEST(PayloadRouterTest, CreateWithNoPreviousStates) {
380 NiceMock<MockRtpRtcp> rtp1;
381 NiceMock<MockRtpRtcp> rtp2;
382 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
383 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
384 payload_router.SetActive(true);
385
386 std::map<uint32_t, RtpPayloadState> initial_states =
387 payload_router.GetRtpPayloadStates();
388 EXPECT_EQ(2u, initial_states.size());
389 EXPECT_NE(initial_states.find(kSsrc1), initial_states.end());
390 EXPECT_NE(initial_states.find(kSsrc2), initial_states.end());
391}
392
393TEST(PayloadRouterTest, CreateWithPreviousStates) {
394 RtpPayloadState state1;
395 state1.picture_id = kInitialPictureId1;
396 RtpPayloadState state2;
397 state2.picture_id = kInitialPictureId2;
398 std::map<uint32_t, RtpPayloadState> states = {{kSsrc1, state1},
399 {kSsrc2, state2}};
400
401 NiceMock<MockRtpRtcp> rtp1;
402 NiceMock<MockRtpRtcp> rtp2;
403 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
404 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, states);
405 payload_router.SetActive(true);
406
407 std::map<uint32_t, RtpPayloadState> initial_states =
408 payload_router.GetRtpPayloadStates();
409 EXPECT_EQ(2u, initial_states.size());
410 EXPECT_EQ(kInitialPictureId1, initial_states[kSsrc1].picture_id);
411 EXPECT_EQ(kInitialPictureId2, initial_states[kSsrc2].picture_id);
412}
413
414class PayloadRouterTest : public ::testing::Test {
415 public:
416 explicit PayloadRouterTest(const std::string& field_trials)
417 : override_field_trials_(field_trials) {}
418 virtual ~PayloadRouterTest() {}
419
420 protected:
421 virtual void SetUp() { memset(&codec_info_, 0, sizeof(CodecSpecificInfo)); }
422
423 test::ScopedFieldTrials override_field_trials_;
424 EncodedImage image_;
425 CodecSpecificInfo codec_info_;
426};
427
428class TestWithForcedFallbackDisabled : public PayloadRouterTest {
429 public:
430 TestWithForcedFallbackDisabled()
Åsa Persson45bbc8a2017-11-13 10:16:47 +0100431 : PayloadRouterTest("WebRTC-VP8-Forced-Fallback-Encoder-v2/Disabled/") {}
Åsa Persson4bece9a2017-10-06 10:04:04 +0200432};
433
434class TestWithForcedFallbackEnabled : public PayloadRouterTest {
435 public:
436 TestWithForcedFallbackEnabled()
437 : PayloadRouterTest(
Åsa Persson45bbc8a2017-11-13 10:16:47 +0100438 "WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1,2,3/") {}
Åsa Persson4bece9a2017-10-06 10:04:04 +0200439};
440
441TEST_F(TestWithForcedFallbackDisabled, PictureIdIsNotChangedForVp8) {
442 NiceMock<MockRtpRtcp> rtp;
443 std::vector<RtpRtcp*> modules = {&rtp};
444 PayloadRouter router(modules, {kSsrc1}, kPayloadType, {});
445 router.SetActive(true);
446
447 codec_info_.codecType = kVideoCodecVP8;
448 codec_info_.codecSpecific.VP8.pictureId = kPictureId;
449
450 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
451 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
452 Unused, const RTPVideoHeader* header, Unused) {
453 EXPECT_EQ(kRtpVideoVp8, header->codec);
454 EXPECT_EQ(kPictureId, header->codecHeader.VP8.pictureId);
455 return true;
456 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800457 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200458
459 EXPECT_EQ(EncodedImageCallback::Result::OK,
460 router.OnEncodedImage(image_, &codec_info_, nullptr).error);
461}
462
463TEST_F(TestWithForcedFallbackEnabled, PictureIdIsSetForVp8) {
464 RtpPayloadState state1;
465 state1.picture_id = kInitialPictureId1;
466 RtpPayloadState state2;
467 state2.picture_id = kInitialPictureId2;
468 std::map<uint32_t, RtpPayloadState> states = {{kSsrc1, state1},
469 {kSsrc2, state2}};
470
471 NiceMock<MockRtpRtcp> rtp1;
472 NiceMock<MockRtpRtcp> rtp2;
473 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
474 PayloadRouter router(modules, {kSsrc1, kSsrc2}, kPayloadType, states);
475 router.SetActive(true);
476
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800477 // Modules are sending for this test.
Åsa Persson4bece9a2017-10-06 10:04:04 +0200478 // OnEncodedImage, simulcastIdx: 0.
479 codec_info_.codecType = kVideoCodecVP8;
480 codec_info_.codecSpecific.VP8.pictureId = kPictureId;
481 codec_info_.codecSpecific.VP8.simulcastIdx = 0;
482
483 EXPECT_CALL(rtp1, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
484 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
485 Unused, const RTPVideoHeader* header, Unused) {
486 EXPECT_EQ(kRtpVideoVp8, header->codec);
487 EXPECT_EQ(kInitialPictureId1, header->codecHeader.VP8.pictureId);
488 return true;
489 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800490 EXPECT_CALL(rtp1, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200491
492 EXPECT_EQ(EncodedImageCallback::Result::OK,
493 router.OnEncodedImage(image_, &codec_info_, nullptr).error);
494
495 // OnEncodedImage, simulcastIdx: 1.
496 codec_info_.codecSpecific.VP8.pictureId = kPictureId;
497 codec_info_.codecSpecific.VP8.simulcastIdx = 1;
498
499 EXPECT_CALL(rtp2, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
500 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
501 Unused, const RTPVideoHeader* header, Unused) {
502 EXPECT_EQ(kRtpVideoVp8, header->codec);
503 EXPECT_EQ(kInitialPictureId2, header->codecHeader.VP8.pictureId);
504 return true;
505 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800506 EXPECT_CALL(rtp2, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200507
508 EXPECT_EQ(EncodedImageCallback::Result::OK,
509 router.OnEncodedImage(image_, &codec_info_, nullptr).error);
510
511 // State should hold next picture id to use.
512 states = router.GetRtpPayloadStates();
513 EXPECT_EQ(2u, states.size());
514 EXPECT_EQ(kInitialPictureId1 + 1, states[kSsrc1].picture_id);
515 EXPECT_EQ(kInitialPictureId2 + 1, states[kSsrc2].picture_id);
516}
517
518TEST_F(TestWithForcedFallbackEnabled, PictureIdWraps) {
519 RtpPayloadState state1;
520 state1.picture_id = kMaxTwoBytePictureId;
521
522 NiceMock<MockRtpRtcp> rtp;
523 std::vector<RtpRtcp*> modules = {&rtp};
524 PayloadRouter router(modules, {kSsrc1}, kPayloadType, {{kSsrc1, state1}});
525 router.SetActive(true);
526
527 codec_info_.codecType = kVideoCodecVP8;
528 codec_info_.codecSpecific.VP8.pictureId = kPictureId;
529
530 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
531 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
532 Unused, const RTPVideoHeader* header, Unused) {
533 EXPECT_EQ(kRtpVideoVp8, header->codec);
534 EXPECT_EQ(kMaxTwoBytePictureId, header->codecHeader.VP8.pictureId);
535 return true;
536 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800537 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200538
539 EXPECT_EQ(EncodedImageCallback::Result::OK,
540 router.OnEncodedImage(image_, &codec_info_, nullptr).error);
541
542 // State should hold next picture id to use.
543 std::map<uint32_t, RtpPayloadState> states = router.GetRtpPayloadStates();
544 EXPECT_EQ(1u, states.size());
545 EXPECT_EQ(0, states[kSsrc1].picture_id); // Wrapped.
546}
547
548TEST_F(TestWithForcedFallbackEnabled, PictureIdIsNotSetIfNoPictureId) {
549 NiceMock<MockRtpRtcp> rtp;
550 std::vector<RtpRtcp*> modules = {&rtp};
551 PayloadRouter router(modules, {kSsrc1}, kPayloadType, {});
552 router.SetActive(true);
553
554 codec_info_.codecType = kVideoCodecVP8;
555 codec_info_.codecSpecific.VP8.pictureId = kNoPictureId;
556
557 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
558 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
559 Unused, const RTPVideoHeader* header, Unused) {
560 EXPECT_EQ(kRtpVideoVp8, header->codec);
561 EXPECT_EQ(kNoPictureId, header->codecHeader.VP8.pictureId);
562 return true;
563 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800564 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200565
566 EXPECT_EQ(EncodedImageCallback::Result::OK,
567 router.OnEncodedImage(image_, &codec_info_, nullptr).error);
568}
569
570TEST_F(TestWithForcedFallbackEnabled, PictureIdIsNotSetForVp9) {
571 NiceMock<MockRtpRtcp> rtp;
572 std::vector<RtpRtcp*> modules = {&rtp};
573 PayloadRouter router(modules, {kSsrc1}, kPayloadType, {});
574 router.SetActive(true);
575
576 codec_info_.codecType = kVideoCodecVP9;
577 codec_info_.codecSpecific.VP9.picture_id = kPictureId;
578
579 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
580 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
581 Unused, const RTPVideoHeader* header, Unused) {
582 EXPECT_EQ(kRtpVideoVp9, header->codec);
583 EXPECT_EQ(kPictureId, header->codecHeader.VP9.picture_id);
584 return true;
585 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800586 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200587
588 EXPECT_EQ(EncodedImageCallback::Result::OK,
589 router.OnEncodedImage(image_, &codec_info_, nullptr).error);
590}
591
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000592} // namespace webrtc