blob: bd19ad35ddb50c3e513ea4cdc402e820dc8eec99 [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
Stefan Holmera2f15332018-07-11 17:11:31 +020014#include "call/payload_router.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#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"
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000021
22using ::testing::_;
23using ::testing::AnyNumber;
Åsa Persson4bece9a2017-10-06 10:04:04 +020024using ::testing::Invoke;
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000025using ::testing::NiceMock;
26using ::testing::Return;
Åsa Persson4bece9a2017-10-06 10:04:04 +020027using ::testing::Unused;
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000028
29namespace webrtc {
Åsa Persson4bece9a2017-10-06 10:04:04 +020030namespace {
31const int8_t kPayloadType = 96;
32const uint32_t kSsrc1 = 12345;
33const uint32_t kSsrc2 = 23456;
Seth Hampson46e31ba2018-01-18 10:39:54 -080034const uint32_t kSsrc3 = 34567;
Åsa Persson4bece9a2017-10-06 10:04:04 +020035const int16_t kPictureId = 123;
36const int16_t kTl0PicIdx = 20;
37const uint8_t kTemporalIdx = 1;
38const int16_t kInitialPictureId1 = 222;
39const int16_t kInitialPictureId2 = 44;
Niels Möllerbb894ff2018-03-15 12:28:53 +010040const int16_t kInitialTl0PicIdx1 = 99;
41const int16_t kInitialTl0PicIdx2 = 199;
Åsa Persson4bece9a2017-10-06 10:04:04 +020042} // namespace
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000043
Per83d09102016-04-15 14:59:13 +020044TEST(PayloadRouterTest, SendOnOneModule) {
perkjbc75d972016-05-02 06:31:25 -070045 NiceMock<MockRtpRtcp> rtp;
Peter Boström404686a2016-02-11 23:37:26 +010046 std::vector<RtpRtcp*> modules(1, &rtp);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000047
kjellander02b3d272016-04-20 05:05:54 -070048 uint8_t payload = 'a';
kjellander02b3d272016-04-20 05:05:54 -070049 EncodedImage encoded_image;
50 encoded_image._timeStamp = 1;
51 encoded_image.capture_time_ms_ = 2;
52 encoded_image._frameType = kVideoFrameKey;
53 encoded_image._buffer = &payload;
54 encoded_image._length = 1;
55
Åsa Persson4bece9a2017-10-06 10:04:04 +020056 PayloadRouter payload_router(modules, {kSsrc1}, kPayloadType, {});
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000057
Åsa Persson4bece9a2017-10-06 10:04:04 +020058 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070059 encoded_image._timeStamp,
60 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070061 encoded_image._length, nullptr, _, _))
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000062 .Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -070063 EXPECT_NE(
64 EncodedImageCallback::Result::OK,
65 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000066
sprang1a646ee2016-12-01 06:34:11 -080067 payload_router.SetActive(true);
Åsa Persson4bece9a2017-10-06 10:04:04 +020068 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070069 encoded_image._timeStamp,
70 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070071 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -080072 .Times(1)
73 .WillOnce(Return(true));
Seth Hampsoncc7125f2018-02-02 08:46:16 -080074 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
sergeyu2cb155a2016-11-04 11:39:29 -070075 EXPECT_EQ(
76 EncodedImageCallback::Result::OK,
77 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000078
sprang1a646ee2016-12-01 06:34:11 -080079 payload_router.SetActive(false);
Åsa Persson4bece9a2017-10-06 10:04:04 +020080 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070081 encoded_image._timeStamp,
82 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070083 encoded_image._length, nullptr, _, _))
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000084 .Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -070085 EXPECT_NE(
86 EncodedImageCallback::Result::OK,
87 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000088
sprang1a646ee2016-12-01 06:34:11 -080089 payload_router.SetActive(true);
Åsa Persson4bece9a2017-10-06 10:04:04 +020090 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070091 encoded_image._timeStamp,
92 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070093 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -080094 .Times(1)
95 .WillOnce(Return(true));
Seth Hampsoncc7125f2018-02-02 08:46:16 -080096 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
sergeyu2cb155a2016-11-04 11:39:29 -070097 EXPECT_EQ(
98 EncodedImageCallback::Result::OK,
99 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000100}
101
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800102TEST(PayloadRouterTest, SendSimulcastSetActive) {
perkjbc75d972016-05-02 06:31:25 -0700103 NiceMock<MockRtpRtcp> rtp_1;
104 NiceMock<MockRtpRtcp> rtp_2;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200105 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2};
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000106
kjellander02b3d272016-04-20 05:05:54 -0700107 uint8_t payload = 'a';
108 EncodedImage encoded_image;
109 encoded_image._timeStamp = 1;
110 encoded_image.capture_time_ms_ = 2;
111 encoded_image._frameType = kVideoFrameKey;
112 encoded_image._buffer = &payload;
113 encoded_image._length = 1;
114
Åsa Persson4bece9a2017-10-06 10:04:04 +0200115 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000116
kjellander02b3d272016-04-20 05:05:54 -0700117 CodecSpecificInfo codec_info_1;
118 memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
119 codec_info_1.codecType = kVideoCodecVP8;
120 codec_info_1.codecSpecific.VP8.simulcastIdx = 0;
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000121
sprang1a646ee2016-12-01 06:34:11 -0800122 payload_router.SetActive(true);
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800123 EXPECT_CALL(rtp_1, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200124 EXPECT_CALL(rtp_1, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -0700125 encoded_image._timeStamp,
126 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700127 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -0800128 .Times(1)
129 .WillOnce(Return(true));
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700130 EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -0700131 EXPECT_EQ(EncodedImageCallback::Result::OK,
132 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
133 .error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000134
kjellander02b3d272016-04-20 05:05:54 -0700135 CodecSpecificInfo codec_info_2;
136 memset(&codec_info_2, 0, sizeof(CodecSpecificInfo));
137 codec_info_2.codecType = kVideoCodecVP8;
138 codec_info_2.codecSpecific.VP8.simulcastIdx = 1;
139
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800140 EXPECT_CALL(rtp_2, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200141 EXPECT_CALL(rtp_2, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -0700142 encoded_image._timeStamp,
143 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700144 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -0800145 .Times(1)
146 .WillOnce(Return(true));
Yves Gerey665174f2018-06-19 15:03:05 +0200147 EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _)).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);
Yves Gerey665174f2018-06-19 15:03:05 +0200154 EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
155 EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -0700156 EXPECT_NE(EncodedImageCallback::Result::OK,
157 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
158 .error);
159 EXPECT_NE(EncodedImageCallback::Result::OK,
160 payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
161 .error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000162}
163
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800164// Tests how setting individual rtp modules to active affects the overall
165// behavior of the payload router. First sets one module to active and checks
166// that outgoing data can be sent on this module, and checks that no data can be
167// sent if both modules are inactive.
168TEST(PayloadRouterTest, SendSimulcastSetActiveModules) {
169 NiceMock<MockRtpRtcp> rtp_1;
170 NiceMock<MockRtpRtcp> rtp_2;
171 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2};
172
173 uint8_t payload = 'a';
174 EncodedImage encoded_image;
175 encoded_image._timeStamp = 1;
176 encoded_image.capture_time_ms_ = 2;
177 encoded_image._frameType = kVideoFrameKey;
178 encoded_image._buffer = &payload;
179 encoded_image._length = 1;
180 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
181 CodecSpecificInfo codec_info_1;
182 memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
183 codec_info_1.codecType = kVideoCodecVP8;
184 codec_info_1.codecSpecific.VP8.simulcastIdx = 0;
185 CodecSpecificInfo codec_info_2;
186 memset(&codec_info_2, 0, sizeof(CodecSpecificInfo));
187 codec_info_2.codecType = kVideoCodecVP8;
188 codec_info_2.codecSpecific.VP8.simulcastIdx = 1;
189
190 // Only setting one stream to active will still set the payload router to
191 // active and allow sending data on the active stream.
192 std::vector<bool> active_modules({true, false});
193 payload_router.SetActiveModules(active_modules);
194
195 EXPECT_CALL(rtp_1, Sending()).WillOnce(Return(true));
196 EXPECT_CALL(rtp_1, SendOutgoingData(encoded_image._frameType, kPayloadType,
197 encoded_image._timeStamp,
198 encoded_image.capture_time_ms_, &payload,
199 encoded_image._length, nullptr, _, _))
200 .Times(1)
201 .WillOnce(Return(true));
202 EXPECT_EQ(EncodedImageCallback::Result::OK,
203 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
204 .error);
205
206 // Setting both streams to inactive will turn the payload router to inactive.
207 active_modules = {false, false};
208 payload_router.SetActiveModules(active_modules);
209 // An incoming encoded image will not ask the module to send outgoing data
210 // because the payload router is inactive.
211 EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
212 EXPECT_CALL(rtp_1, Sending()).Times(0);
213 EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
214 EXPECT_CALL(rtp_2, Sending()).Times(0);
215 EXPECT_NE(EncodedImageCallback::Result::OK,
216 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
217 .error);
218 EXPECT_NE(EncodedImageCallback::Result::OK,
219 payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
220 .error);
221}
222
sprang1a646ee2016-12-01 06:34:11 -0800223TEST(PayloadRouterTest, SimulcastTargetBitrate) {
224 NiceMock<MockRtpRtcp> rtp_1;
225 NiceMock<MockRtpRtcp> rtp_2;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200226 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2};
227
228 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
sprang1a646ee2016-12-01 06:34:11 -0800229 payload_router.SetActive(true);
230
Erik Språng566124a2018-04-23 12:32:22 +0200231 VideoBitrateAllocation bitrate;
sprang1a646ee2016-12-01 06:34:11 -0800232 bitrate.SetBitrate(0, 0, 10000);
233 bitrate.SetBitrate(0, 1, 20000);
234 bitrate.SetBitrate(1, 0, 40000);
235 bitrate.SetBitrate(1, 1, 80000);
236
Erik Språng566124a2018-04-23 12:32:22 +0200237 VideoBitrateAllocation layer0_bitrate;
sprang1a646ee2016-12-01 06:34:11 -0800238 layer0_bitrate.SetBitrate(0, 0, 10000);
239 layer0_bitrate.SetBitrate(0, 1, 20000);
240
Erik Språng566124a2018-04-23 12:32:22 +0200241 VideoBitrateAllocation layer1_bitrate;
sprang1a646ee2016-12-01 06:34:11 -0800242 layer1_bitrate.SetBitrate(0, 0, 40000);
243 layer1_bitrate.SetBitrate(0, 1, 80000);
244
245 EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(layer0_bitrate)).Times(1);
246 EXPECT_CALL(rtp_2, SetVideoBitrateAllocation(layer1_bitrate)).Times(1);
247
248 payload_router.OnBitrateAllocationUpdated(bitrate);
249}
250
Seth Hampson46e31ba2018-01-18 10:39:54 -0800251// If the middle of three streams is inactive the first and last streams should
252// be asked to send the TargetBitrate message.
sprangd0fc37a2017-06-22 05:40:25 -0700253TEST(PayloadRouterTest, SimulcastTargetBitrateWithInactiveStream) {
Seth Hampson46e31ba2018-01-18 10:39:54 -0800254 // Set up three active rtp modules.
sprangd0fc37a2017-06-22 05:40:25 -0700255 NiceMock<MockRtpRtcp> rtp_1;
256 NiceMock<MockRtpRtcp> rtp_2;
Seth Hampson46e31ba2018-01-18 10:39:54 -0800257 NiceMock<MockRtpRtcp> rtp_3;
258 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2, &rtp_3};
259 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2, kSsrc3}, kPayloadType,
260 {});
sprangd0fc37a2017-06-22 05:40:25 -0700261 payload_router.SetActive(true);
262
Seth Hampson46e31ba2018-01-18 10:39:54 -0800263 // Create bitrate allocation with bitrate only for the first and third stream.
Erik Språng566124a2018-04-23 12:32:22 +0200264 VideoBitrateAllocation bitrate;
sprangd0fc37a2017-06-22 05:40:25 -0700265 bitrate.SetBitrate(0, 0, 10000);
266 bitrate.SetBitrate(0, 1, 20000);
Seth Hampson46e31ba2018-01-18 10:39:54 -0800267 bitrate.SetBitrate(2, 0, 40000);
268 bitrate.SetBitrate(2, 1, 80000);
sprangd0fc37a2017-06-22 05:40:25 -0700269
Erik Språng566124a2018-04-23 12:32:22 +0200270 VideoBitrateAllocation layer0_bitrate;
Seth Hampson46e31ba2018-01-18 10:39:54 -0800271 layer0_bitrate.SetBitrate(0, 0, 10000);
272 layer0_bitrate.SetBitrate(0, 1, 20000);
273
Erik Språng566124a2018-04-23 12:32:22 +0200274 VideoBitrateAllocation layer2_bitrate;
Seth Hampson46e31ba2018-01-18 10:39:54 -0800275 layer2_bitrate.SetBitrate(0, 0, 40000);
276 layer2_bitrate.SetBitrate(0, 1, 80000);
277
278 // Expect the first and third rtp module to be asked to send a TargetBitrate
sprangd0fc37a2017-06-22 05:40:25 -0700279 // message. (No target bitrate with 0bps sent from the second one.)
Seth Hampson46e31ba2018-01-18 10:39:54 -0800280 EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(layer0_bitrate)).Times(1);
sprangd0fc37a2017-06-22 05:40:25 -0700281 EXPECT_CALL(rtp_2, SetVideoBitrateAllocation(_)).Times(0);
Seth Hampson46e31ba2018-01-18 10:39:54 -0800282 EXPECT_CALL(rtp_3, SetVideoBitrateAllocation(layer2_bitrate)).Times(1);
sprangd0fc37a2017-06-22 05:40:25 -0700283
284 payload_router.OnBitrateAllocationUpdated(bitrate);
285}
286
sprang1a646ee2016-12-01 06:34:11 -0800287TEST(PayloadRouterTest, SvcTargetBitrate) {
288 NiceMock<MockRtpRtcp> rtp_1;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200289 std::vector<RtpRtcp*> modules = {&rtp_1};
290 PayloadRouter payload_router(modules, {kSsrc1}, kPayloadType, {});
sprang1a646ee2016-12-01 06:34:11 -0800291 payload_router.SetActive(true);
292
Erik Språng566124a2018-04-23 12:32:22 +0200293 VideoBitrateAllocation bitrate;
sprang1a646ee2016-12-01 06:34:11 -0800294 bitrate.SetBitrate(0, 0, 10000);
295 bitrate.SetBitrate(0, 1, 20000);
296 bitrate.SetBitrate(1, 0, 40000);
297 bitrate.SetBitrate(1, 1, 80000);
298
299 EXPECT_CALL(rtp_1, SetVideoBitrateAllocation(bitrate)).Times(1);
300
301 payload_router.OnBitrateAllocationUpdated(bitrate);
302}
303
Åsa Persson4bece9a2017-10-06 10:04:04 +0200304TEST(PayloadRouterTest, InfoMappedToRtpVideoHeader_Vp8) {
305 NiceMock<MockRtpRtcp> rtp1;
306 NiceMock<MockRtpRtcp> rtp2;
307 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
Niels Möllerbb894ff2018-03-15 12:28:53 +0100308 RtpPayloadState state2;
309 state2.picture_id = kPictureId;
310 state2.tl0_pic_idx = kTl0PicIdx;
311 std::map<uint32_t, RtpPayloadState> states = {{kSsrc2, state2}};
312
313 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, states);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200314 payload_router.SetActive(true);
315
316 EncodedImage encoded_image;
317 encoded_image.rotation_ = kVideoRotation_90;
318 encoded_image.content_type_ = VideoContentType::SCREENSHARE;
319
320 CodecSpecificInfo codec_info;
321 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
322 codec_info.codecType = kVideoCodecVP8;
323 codec_info.codecSpecific.VP8.simulcastIdx = 1;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200324 codec_info.codecSpecific.VP8.temporalIdx = kTemporalIdx;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200325 codec_info.codecSpecific.VP8.keyIdx = kNoKeyIdx;
326 codec_info.codecSpecific.VP8.layerSync = true;
327 codec_info.codecSpecific.VP8.nonReference = true;
328
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800329 EXPECT_CALL(rtp2, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200330 EXPECT_CALL(rtp2, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
331 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
332 Unused, const RTPVideoHeader* header, Unused) {
333 EXPECT_EQ(kVideoRotation_90, header->rotation);
334 EXPECT_EQ(VideoContentType::SCREENSHARE, header->content_type);
335 EXPECT_EQ(1, header->simulcastIdx);
Niels Möller520ca4e2018-06-04 11:14:38 +0200336 EXPECT_EQ(kVideoCodecVP8, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200337 EXPECT_EQ(kPictureId + 1, header->vp8().pictureId);
338 EXPECT_EQ(kTemporalIdx, header->vp8().temporalIdx);
339 EXPECT_EQ(kTl0PicIdx, header->vp8().tl0PicIdx);
340 EXPECT_EQ(kNoKeyIdx, header->vp8().keyIdx);
341 EXPECT_TRUE(header->vp8().layerSync);
342 EXPECT_TRUE(header->vp8().nonReference);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200343 return true;
344 }));
345
346 EXPECT_EQ(
347 EncodedImageCallback::Result::OK,
348 payload_router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
349}
350
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200351TEST(PayloadRouterTest, InfoMappedToRtpVideoHeader_Vp9) {
352 RtpPayloadState state;
353 state.picture_id = kPictureId;
354 state.tl0_pic_idx = kTl0PicIdx;
355 std::map<uint32_t, RtpPayloadState> states = {{kSsrc1, state}};
356
357 NiceMock<MockRtpRtcp> rtp;
358 std::vector<RtpRtcp*> modules = {&rtp};
359 PayloadRouter router(modules, {kSsrc1}, kPayloadType, states);
360 router.SetActive(true);
361
362 EncodedImage encoded_image;
363 encoded_image.rotation_ = kVideoRotation_90;
364 encoded_image.content_type_ = VideoContentType::SCREENSHARE;
365
366 CodecSpecificInfo codec_info;
367 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
368 codec_info.codecType = kVideoCodecVP9;
369 codec_info.codecSpecific.VP9.num_spatial_layers = 3;
370 codec_info.codecSpecific.VP9.first_frame_in_picture = true;
371 codec_info.codecSpecific.VP9.spatial_idx = 0;
372 codec_info.codecSpecific.VP9.temporal_idx = 2;
Sergey Silkinbc0f0d32018-04-24 21:29:14 +0200373 codec_info.codecSpecific.VP9.end_of_picture = false;
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200374
375 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
376 .WillOnce(
377 Invoke([&codec_info](Unused, Unused, Unused, Unused, Unused, Unused,
378 Unused, const RTPVideoHeader* header, Unused) {
379 EXPECT_EQ(kVideoRotation_90, header->rotation);
380 EXPECT_EQ(VideoContentType::SCREENSHARE, header->content_type);
Niels Möller520ca4e2018-06-04 11:14:38 +0200381 EXPECT_EQ(kVideoCodecVP9, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200382 EXPECT_EQ(kPictureId + 1, header->vp9().picture_id);
383 EXPECT_EQ(kTl0PicIdx, header->vp9().tl0_pic_idx);
384 EXPECT_EQ(header->vp9().temporal_idx,
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200385 codec_info.codecSpecific.VP9.temporal_idx);
philipel5ab67a52018-07-05 12:27:04 +0200386 EXPECT_EQ(header->vp9().spatial_idx,
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200387 codec_info.codecSpecific.VP9.spatial_idx);
philipel5ab67a52018-07-05 12:27:04 +0200388 EXPECT_EQ(header->vp9().num_spatial_layers,
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200389 codec_info.codecSpecific.VP9.num_spatial_layers);
philipel5ab67a52018-07-05 12:27:04 +0200390 EXPECT_EQ(header->vp9().end_of_picture,
Sergey Silkinbc0f0d32018-04-24 21:29:14 +0200391 codec_info.codecSpecific.VP9.end_of_picture);
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200392 return true;
393 }));
394 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
395
396 EXPECT_EQ(EncodedImageCallback::Result::OK,
397 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
398
399 // Next spatial layer.
400 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
401 codec_info.codecSpecific.VP9.spatial_idx += 1;
Sergey Silkinbc0f0d32018-04-24 21:29:14 +0200402 codec_info.codecSpecific.VP9.end_of_picture = true;
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200403
404 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
405 .WillOnce(
406 Invoke([&codec_info](Unused, Unused, Unused, Unused, Unused, Unused,
407 Unused, const RTPVideoHeader* header, Unused) {
408 EXPECT_EQ(kVideoRotation_90, header->rotation);
409 EXPECT_EQ(VideoContentType::SCREENSHARE, header->content_type);
Niels Möller520ca4e2018-06-04 11:14:38 +0200410 EXPECT_EQ(kVideoCodecVP9, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200411 EXPECT_EQ(kPictureId + 1, header->vp9().picture_id);
412 EXPECT_EQ(kTl0PicIdx, header->vp9().tl0_pic_idx);
413 EXPECT_EQ(header->vp9().temporal_idx,
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200414 codec_info.codecSpecific.VP9.temporal_idx);
philipel5ab67a52018-07-05 12:27:04 +0200415 EXPECT_EQ(header->vp9().spatial_idx,
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200416 codec_info.codecSpecific.VP9.spatial_idx);
philipel5ab67a52018-07-05 12:27:04 +0200417 EXPECT_EQ(header->vp9().num_spatial_layers,
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200418 codec_info.codecSpecific.VP9.num_spatial_layers);
philipel5ab67a52018-07-05 12:27:04 +0200419 EXPECT_EQ(header->vp9().end_of_picture,
Sergey Silkinbc0f0d32018-04-24 21:29:14 +0200420 codec_info.codecSpecific.VP9.end_of_picture);
Sergey Silkin2a1f1832018-04-04 11:45:41 +0200421 return true;
422 }));
423 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
424
425 EXPECT_EQ(EncodedImageCallback::Result::OK,
426 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
427}
428
Åsa Persson4bece9a2017-10-06 10:04:04 +0200429TEST(PayloadRouterTest, InfoMappedToRtpVideoHeader_H264) {
430 NiceMock<MockRtpRtcp> rtp1;
431 std::vector<RtpRtcp*> modules = {&rtp1};
432 PayloadRouter payload_router(modules, {kSsrc1}, kPayloadType, {});
433 payload_router.SetActive(true);
434
435 EncodedImage encoded_image;
436 CodecSpecificInfo codec_info;
437 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
438 codec_info.codecType = kVideoCodecH264;
439 codec_info.codecSpecific.H264.packetization_mode =
440 H264PacketizationMode::SingleNalUnit;
441
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800442 EXPECT_CALL(rtp1, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200443 EXPECT_CALL(rtp1, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
444 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
445 Unused, const RTPVideoHeader* header, Unused) {
446 EXPECT_EQ(0, header->simulcastIdx);
Niels Möller520ca4e2018-06-04 11:14:38 +0200447 EXPECT_EQ(kVideoCodecH264, header->codec);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200448 EXPECT_EQ(H264PacketizationMode::SingleNalUnit,
philipel5ab67a52018-07-05 12:27:04 +0200449 header->h264().packetization_mode);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200450 return true;
451 }));
452
453 EXPECT_EQ(
454 EncodedImageCallback::Result::OK,
455 payload_router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
456}
457
458TEST(PayloadRouterTest, CreateWithNoPreviousStates) {
459 NiceMock<MockRtpRtcp> rtp1;
460 NiceMock<MockRtpRtcp> rtp2;
461 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
462 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
463 payload_router.SetActive(true);
464
465 std::map<uint32_t, RtpPayloadState> initial_states =
466 payload_router.GetRtpPayloadStates();
467 EXPECT_EQ(2u, initial_states.size());
468 EXPECT_NE(initial_states.find(kSsrc1), initial_states.end());
469 EXPECT_NE(initial_states.find(kSsrc2), initial_states.end());
470}
471
472TEST(PayloadRouterTest, CreateWithPreviousStates) {
473 RtpPayloadState state1;
474 state1.picture_id = kInitialPictureId1;
Niels Möllerbb894ff2018-03-15 12:28:53 +0100475 state1.tl0_pic_idx = kInitialTl0PicIdx1;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200476 RtpPayloadState state2;
477 state2.picture_id = kInitialPictureId2;
Niels Möllerbb894ff2018-03-15 12:28:53 +0100478 state2.tl0_pic_idx = kInitialTl0PicIdx2;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200479 std::map<uint32_t, RtpPayloadState> states = {{kSsrc1, state1},
480 {kSsrc2, state2}};
481
482 NiceMock<MockRtpRtcp> rtp1;
483 NiceMock<MockRtpRtcp> rtp2;
484 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
485 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, states);
486 payload_router.SetActive(true);
487
488 std::map<uint32_t, RtpPayloadState> initial_states =
489 payload_router.GetRtpPayloadStates();
490 EXPECT_EQ(2u, initial_states.size());
491 EXPECT_EQ(kInitialPictureId1, initial_states[kSsrc1].picture_id);
Niels Möllerbb894ff2018-03-15 12:28:53 +0100492 EXPECT_EQ(kInitialTl0PicIdx1, initial_states[kSsrc1].tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200493 EXPECT_EQ(kInitialPictureId2, initial_states[kSsrc2].picture_id);
Niels Möllerbb894ff2018-03-15 12:28:53 +0100494 EXPECT_EQ(kInitialTl0PicIdx2, initial_states[kSsrc2].tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200495}
496
Niels Möllerbb894ff2018-03-15 12:28:53 +0100497TEST(PayloadRouterTest, PictureIdIsSetForVp8) {
Åsa Persson4bece9a2017-10-06 10:04:04 +0200498 RtpPayloadState state1;
499 state1.picture_id = kInitialPictureId1;
Niels Möllerbb894ff2018-03-15 12:28:53 +0100500 state1.tl0_pic_idx = kInitialTl0PicIdx1;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200501 RtpPayloadState state2;
502 state2.picture_id = kInitialPictureId2;
Niels Möllerbb894ff2018-03-15 12:28:53 +0100503 state2.tl0_pic_idx = kInitialTl0PicIdx2;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200504 std::map<uint32_t, RtpPayloadState> states = {{kSsrc1, state1},
505 {kSsrc2, state2}};
506
507 NiceMock<MockRtpRtcp> rtp1;
508 NiceMock<MockRtpRtcp> rtp2;
509 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
510 PayloadRouter router(modules, {kSsrc1, kSsrc2}, kPayloadType, states);
511 router.SetActive(true);
512
Niels Möllerbb894ff2018-03-15 12:28:53 +0100513 EncodedImage encoded_image;
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800514 // Modules are sending for this test.
Åsa Persson4bece9a2017-10-06 10:04:04 +0200515 // OnEncodedImage, simulcastIdx: 0.
Niels Möllerbb894ff2018-03-15 12:28:53 +0100516 CodecSpecificInfo codec_info;
517 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
518 codec_info.codecType = kVideoCodecVP8;
519 codec_info.codecSpecific.VP8.simulcastIdx = 0;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200520
521 EXPECT_CALL(rtp1, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
522 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
523 Unused, const RTPVideoHeader* header, Unused) {
Niels Möller520ca4e2018-06-04 11:14:38 +0200524 EXPECT_EQ(kVideoCodecVP8, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200525 EXPECT_EQ(kInitialPictureId1 + 1, header->vp8().pictureId);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200526 return true;
527 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800528 EXPECT_CALL(rtp1, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200529
530 EXPECT_EQ(EncodedImageCallback::Result::OK,
Niels Möllerbb894ff2018-03-15 12:28:53 +0100531 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200532
533 // OnEncodedImage, simulcastIdx: 1.
Niels Möllerbb894ff2018-03-15 12:28:53 +0100534 codec_info.codecSpecific.VP8.simulcastIdx = 1;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200535
536 EXPECT_CALL(rtp2, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
537 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
538 Unused, const RTPVideoHeader* header, Unused) {
Niels Möller520ca4e2018-06-04 11:14:38 +0200539 EXPECT_EQ(kVideoCodecVP8, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200540 EXPECT_EQ(kInitialPictureId2 + 1, header->vp8().pictureId);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200541 return true;
542 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800543 EXPECT_CALL(rtp2, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200544
545 EXPECT_EQ(EncodedImageCallback::Result::OK,
Niels Möllerbb894ff2018-03-15 12:28:53 +0100546 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200547
Niels Möllerbb894ff2018-03-15 12:28:53 +0100548 // State should hold latest used picture id and tl0_pic_idx.
Åsa Persson4bece9a2017-10-06 10:04:04 +0200549 states = router.GetRtpPayloadStates();
550 EXPECT_EQ(2u, states.size());
551 EXPECT_EQ(kInitialPictureId1 + 1, states[kSsrc1].picture_id);
Niels Möllerbb894ff2018-03-15 12:28:53 +0100552 EXPECT_EQ(kInitialTl0PicIdx1 + 1, states[kSsrc1].tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200553 EXPECT_EQ(kInitialPictureId2 + 1, states[kSsrc2].picture_id);
Niels Möllerbb894ff2018-03-15 12:28:53 +0100554 EXPECT_EQ(kInitialTl0PicIdx2 + 1, states[kSsrc2].tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200555}
556
Niels Möllerbb894ff2018-03-15 12:28:53 +0100557TEST(PayloadRouterTest, PictureIdWraps) {
Åsa Persson4bece9a2017-10-06 10:04:04 +0200558 RtpPayloadState state1;
559 state1.picture_id = kMaxTwoBytePictureId;
Niels Möllerbb894ff2018-03-15 12:28:53 +0100560 state1.tl0_pic_idx = kInitialTl0PicIdx1;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200561
562 NiceMock<MockRtpRtcp> rtp;
563 std::vector<RtpRtcp*> modules = {&rtp};
564 PayloadRouter router(modules, {kSsrc1}, kPayloadType, {{kSsrc1, state1}});
565 router.SetActive(true);
566
Niels Möllerbb894ff2018-03-15 12:28:53 +0100567 EncodedImage encoded_image;
568 CodecSpecificInfo codec_info;
569 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
570 codec_info.codecType = kVideoCodecVP8;
571 codec_info.codecSpecific.VP8.temporalIdx = kNoTemporalIdx;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200572
573 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
574 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
575 Unused, const RTPVideoHeader* header, Unused) {
Niels Möller520ca4e2018-06-04 11:14:38 +0200576 EXPECT_EQ(kVideoCodecVP8, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200577 EXPECT_EQ(0, header->vp8().pictureId);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200578 return true;
579 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800580 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200581
582 EXPECT_EQ(EncodedImageCallback::Result::OK,
Niels Möllerbb894ff2018-03-15 12:28:53 +0100583 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200584
Niels Möllerbb894ff2018-03-15 12:28:53 +0100585 // State should hold latest used picture id and tl0_pic_idx.
Åsa Persson4bece9a2017-10-06 10:04:04 +0200586 std::map<uint32_t, RtpPayloadState> states = router.GetRtpPayloadStates();
587 EXPECT_EQ(1u, states.size());
588 EXPECT_EQ(0, states[kSsrc1].picture_id); // Wrapped.
Niels Möllerbb894ff2018-03-15 12:28:53 +0100589 EXPECT_EQ(kInitialTl0PicIdx1, states[kSsrc1].tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200590}
591
Niels Möllerbb894ff2018-03-15 12:28:53 +0100592TEST(PayloadRouterTest, Tl0PicIdxUpdatedForVp8) {
593 RtpPayloadState state;
594 state.picture_id = kInitialPictureId1;
595 state.tl0_pic_idx = kInitialTl0PicIdx1;
596 std::map<uint32_t, RtpPayloadState> states = {{kSsrc1, state}};
597
Åsa Persson4bece9a2017-10-06 10:04:04 +0200598 NiceMock<MockRtpRtcp> rtp;
599 std::vector<RtpRtcp*> modules = {&rtp};
Niels Möllerbb894ff2018-03-15 12:28:53 +0100600 PayloadRouter router(modules, {kSsrc1}, kPayloadType, states);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200601 router.SetActive(true);
602
Niels Möllerbb894ff2018-03-15 12:28:53 +0100603 EncodedImage encoded_image;
604 // Modules are sending for this test.
605 // OnEncodedImage, temporalIdx: 1.
606 CodecSpecificInfo codec_info;
607 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
608 codec_info.codecType = kVideoCodecVP8;
609 codec_info.codecSpecific.VP8.temporalIdx = 1;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200610
611 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
612 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
613 Unused, const RTPVideoHeader* header, Unused) {
Niels Möller520ca4e2018-06-04 11:14:38 +0200614 EXPECT_EQ(kVideoCodecVP8, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200615 EXPECT_EQ(kInitialPictureId1 + 1, header->vp8().pictureId);
616 EXPECT_EQ(kInitialTl0PicIdx1, header->vp8().tl0PicIdx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200617 return true;
618 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800619 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200620
621 EXPECT_EQ(EncodedImageCallback::Result::OK,
Niels Möllerbb894ff2018-03-15 12:28:53 +0100622 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
623
624 // OnEncodedImage, temporalIdx: 0.
625 codec_info.codecSpecific.VP8.temporalIdx = 0;
626
627 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
628 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
629 Unused, const RTPVideoHeader* header, Unused) {
Niels Möller520ca4e2018-06-04 11:14:38 +0200630 EXPECT_EQ(kVideoCodecVP8, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200631 EXPECT_EQ(kInitialPictureId1 + 2, header->vp8().pictureId);
632 EXPECT_EQ(kInitialTl0PicIdx1 + 1, header->vp8().tl0PicIdx);
Niels Möllerbb894ff2018-03-15 12:28:53 +0100633 return true;
634 }));
635 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
636
637 EXPECT_EQ(EncodedImageCallback::Result::OK,
638 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
639
640 // State should hold latest used picture id and tl0_pic_idx.
641 states = router.GetRtpPayloadStates();
642 EXPECT_EQ(1u, states.size());
643 EXPECT_EQ(kInitialPictureId1 + 2, states[kSsrc1].picture_id);
644 EXPECT_EQ(kInitialTl0PicIdx1 + 1, states[kSsrc1].tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200645}
646
Niels Möllerbb894ff2018-03-15 12:28:53 +0100647TEST(PayloadRouterTest, Tl0PicIdxUpdatedForVp9) {
648 RtpPayloadState state;
649 state.picture_id = kInitialPictureId1;
650 state.tl0_pic_idx = kInitialTl0PicIdx1;
651 std::map<uint32_t, RtpPayloadState> states = {{kSsrc1, state}};
652
Åsa Persson4bece9a2017-10-06 10:04:04 +0200653 NiceMock<MockRtpRtcp> rtp;
654 std::vector<RtpRtcp*> modules = {&rtp};
Niels Möllerbb894ff2018-03-15 12:28:53 +0100655 PayloadRouter router(modules, {kSsrc1}, kPayloadType, states);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200656 router.SetActive(true);
657
Niels Möllerbb894ff2018-03-15 12:28:53 +0100658 EncodedImage encoded_image;
659 // Modules are sending for this test.
660 // OnEncodedImage, temporalIdx: 1.
661 CodecSpecificInfo codec_info;
662 memset(&codec_info, 0, sizeof(CodecSpecificInfo));
663 codec_info.codecType = kVideoCodecVP9;
664 codec_info.codecSpecific.VP9.temporal_idx = 1;
665 codec_info.codecSpecific.VP9.first_frame_in_picture = true;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200666
667 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
668 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
669 Unused, const RTPVideoHeader* header, Unused) {
Niels Möller520ca4e2018-06-04 11:14:38 +0200670 EXPECT_EQ(kVideoCodecVP9, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200671 EXPECT_EQ(kInitialPictureId1 + 1, header->vp9().picture_id);
672 EXPECT_EQ(kInitialTl0PicIdx1, header->vp9().tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200673 return true;
674 }));
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800675 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200676
677 EXPECT_EQ(EncodedImageCallback::Result::OK,
Niels Möllerbb894ff2018-03-15 12:28:53 +0100678 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
679
680 // OnEncodedImage, temporalIdx: 0.
681 codec_info.codecSpecific.VP9.temporal_idx = 0;
682
683 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
684 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
685 Unused, const RTPVideoHeader* header, Unused) {
Niels Möller520ca4e2018-06-04 11:14:38 +0200686 EXPECT_EQ(kVideoCodecVP9, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200687 EXPECT_EQ(kInitialPictureId1 + 2, header->vp9().picture_id);
688 EXPECT_EQ(kInitialTl0PicIdx1 + 1, header->vp9().tl0_pic_idx);
Niels Möllerbb894ff2018-03-15 12:28:53 +0100689 return true;
690 }));
691 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
692
693 EXPECT_EQ(EncodedImageCallback::Result::OK,
694 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
695
696 // OnEncodedImage, first_frame_in_picture = false
697 codec_info.codecSpecific.VP9.first_frame_in_picture = false;
698
699 EXPECT_CALL(rtp, SendOutgoingData(_, _, _, _, _, _, nullptr, _, _))
700 .WillOnce(Invoke([](Unused, Unused, Unused, Unused, Unused, Unused,
701 Unused, const RTPVideoHeader* header, Unused) {
Niels Möller520ca4e2018-06-04 11:14:38 +0200702 EXPECT_EQ(kVideoCodecVP9, header->codec);
philipel5ab67a52018-07-05 12:27:04 +0200703 EXPECT_EQ(kInitialPictureId1 + 2, header->vp9().picture_id);
704 EXPECT_EQ(kInitialTl0PicIdx1 + 1, header->vp9().tl0_pic_idx);
Niels Möllerbb894ff2018-03-15 12:28:53 +0100705 return true;
706 }));
707 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
708
709 EXPECT_EQ(EncodedImageCallback::Result::OK,
710 router.OnEncodedImage(encoded_image, &codec_info, nullptr).error);
711
712 // State should hold latest used picture id and tl0_pic_idx.
713 states = router.GetRtpPayloadStates();
714 EXPECT_EQ(1u, states.size());
715 EXPECT_EQ(kInitialPictureId1 + 2, states[kSsrc1].picture_id);
716 EXPECT_EQ(kInitialTl0PicIdx1 + 1, states[kSsrc1].tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200717}
718
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000719} // namespace webrtc