blob: 9c3e1deac2a02212c8079d5efa9a24561b81b29b [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;
Åsa Persson4bece9a2017-10-06 10:04:04 +020034const int16_t kInitialPictureId1 = 222;
35const int16_t kInitialPictureId2 = 44;
Niels Möllerbb894ff2018-03-15 12:28:53 +010036const int16_t kInitialTl0PicIdx1 = 99;
37const int16_t kInitialTl0PicIdx2 = 199;
Åsa Persson4bece9a2017-10-06 10:04:04 +020038} // namespace
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000039
Per83d09102016-04-15 14:59:13 +020040TEST(PayloadRouterTest, SendOnOneModule) {
perkjbc75d972016-05-02 06:31:25 -070041 NiceMock<MockRtpRtcp> rtp;
Peter Boström404686a2016-02-11 23:37:26 +010042 std::vector<RtpRtcp*> modules(1, &rtp);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000043
kjellander02b3d272016-04-20 05:05:54 -070044 uint8_t payload = 'a';
kjellander02b3d272016-04-20 05:05:54 -070045 EncodedImage encoded_image;
46 encoded_image._timeStamp = 1;
47 encoded_image.capture_time_ms_ = 2;
48 encoded_image._frameType = kVideoFrameKey;
49 encoded_image._buffer = &payload;
50 encoded_image._length = 1;
51
Åsa Persson4bece9a2017-10-06 10:04:04 +020052 PayloadRouter payload_router(modules, {kSsrc1}, kPayloadType, {});
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000053
Åsa Persson4bece9a2017-10-06 10:04:04 +020054 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070055 encoded_image._timeStamp,
56 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070057 encoded_image._length, nullptr, _, _))
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000058 .Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -070059 EXPECT_NE(
60 EncodedImageCallback::Result::OK,
61 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000062
sprang1a646ee2016-12-01 06:34:11 -080063 payload_router.SetActive(true);
Åsa Persson4bece9a2017-10-06 10:04:04 +020064 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070065 encoded_image._timeStamp,
66 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070067 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -080068 .Times(1)
69 .WillOnce(Return(true));
Seth Hampsoncc7125f2018-02-02 08:46:16 -080070 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
sergeyu2cb155a2016-11-04 11:39:29 -070071 EXPECT_EQ(
72 EncodedImageCallback::Result::OK,
73 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000074
sprang1a646ee2016-12-01 06:34:11 -080075 payload_router.SetActive(false);
Åsa Persson4bece9a2017-10-06 10:04:04 +020076 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070077 encoded_image._timeStamp,
78 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070079 encoded_image._length, nullptr, _, _))
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000080 .Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -070081 EXPECT_NE(
82 EncodedImageCallback::Result::OK,
83 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000084
sprang1a646ee2016-12-01 06:34:11 -080085 payload_router.SetActive(true);
Åsa Persson4bece9a2017-10-06 10:04:04 +020086 EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -070087 encoded_image._timeStamp,
88 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -070089 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -080090 .Times(1)
91 .WillOnce(Return(true));
Seth Hampsoncc7125f2018-02-02 08:46:16 -080092 EXPECT_CALL(rtp, Sending()).WillOnce(Return(true));
sergeyu2cb155a2016-11-04 11:39:29 -070093 EXPECT_EQ(
94 EncodedImageCallback::Result::OK,
95 payload_router.OnEncodedImage(encoded_image, nullptr, nullptr).error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000096}
97
Seth Hampsoncc7125f2018-02-02 08:46:16 -080098TEST(PayloadRouterTest, SendSimulcastSetActive) {
perkjbc75d972016-05-02 06:31:25 -070099 NiceMock<MockRtpRtcp> rtp_1;
100 NiceMock<MockRtpRtcp> rtp_2;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200101 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2};
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000102
kjellander02b3d272016-04-20 05:05:54 -0700103 uint8_t payload = 'a';
104 EncodedImage encoded_image;
105 encoded_image._timeStamp = 1;
106 encoded_image.capture_time_ms_ = 2;
107 encoded_image._frameType = kVideoFrameKey;
108 encoded_image._buffer = &payload;
109 encoded_image._length = 1;
110
Åsa Persson4bece9a2017-10-06 10:04:04 +0200111 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000112
kjellander02b3d272016-04-20 05:05:54 -0700113 CodecSpecificInfo codec_info_1;
114 memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
115 codec_info_1.codecType = kVideoCodecVP8;
116 codec_info_1.codecSpecific.VP8.simulcastIdx = 0;
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000117
sprang1a646ee2016-12-01 06:34:11 -0800118 payload_router.SetActive(true);
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800119 EXPECT_CALL(rtp_1, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200120 EXPECT_CALL(rtp_1, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -0700121 encoded_image._timeStamp,
122 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700123 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -0800124 .Times(1)
125 .WillOnce(Return(true));
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700126 EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -0700127 EXPECT_EQ(EncodedImageCallback::Result::OK,
128 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
129 .error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000130
kjellander02b3d272016-04-20 05:05:54 -0700131 CodecSpecificInfo codec_info_2;
132 memset(&codec_info_2, 0, sizeof(CodecSpecificInfo));
133 codec_info_2.codecType = kVideoCodecVP8;
134 codec_info_2.codecSpecific.VP8.simulcastIdx = 1;
135
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800136 EXPECT_CALL(rtp_2, Sending()).WillOnce(Return(true));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200137 EXPECT_CALL(rtp_2, SendOutgoingData(encoded_image._frameType, kPayloadType,
kjellander02b3d272016-04-20 05:05:54 -0700138 encoded_image._timeStamp,
139 encoded_image.capture_time_ms_, &payload,
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700140 encoded_image._length, nullptr, _, _))
sergeyu7b9feee2016-11-17 16:16:14 -0800141 .Times(1)
142 .WillOnce(Return(true));
Yves Gerey665174f2018-06-19 15:03:05 +0200143 EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -0700144 EXPECT_EQ(EncodedImageCallback::Result::OK,
145 payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
146 .error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000147
mflodman@webrtc.org50e28162015-02-23 07:45:11 +0000148 // Inactive.
sprang1a646ee2016-12-01 06:34:11 -0800149 payload_router.SetActive(false);
Yves Gerey665174f2018-06-19 15:03:05 +0200150 EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
151 EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
sergeyu2cb155a2016-11-04 11:39:29 -0700152 EXPECT_NE(EncodedImageCallback::Result::OK,
153 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
154 .error);
155 EXPECT_NE(EncodedImageCallback::Result::OK,
156 payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
157 .error);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000158}
159
Seth Hampsoncc7125f2018-02-02 08:46:16 -0800160// Tests how setting individual rtp modules to active affects the overall
161// behavior of the payload router. First sets one module to active and checks
162// that outgoing data can be sent on this module, and checks that no data can be
163// sent if both modules are inactive.
164TEST(PayloadRouterTest, SendSimulcastSetActiveModules) {
165 NiceMock<MockRtpRtcp> rtp_1;
166 NiceMock<MockRtpRtcp> rtp_2;
167 std::vector<RtpRtcp*> modules = {&rtp_1, &rtp_2};
168
169 uint8_t payload = 'a';
170 EncodedImage encoded_image;
171 encoded_image._timeStamp = 1;
172 encoded_image.capture_time_ms_ = 2;
173 encoded_image._frameType = kVideoFrameKey;
174 encoded_image._buffer = &payload;
175 encoded_image._length = 1;
176 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
177 CodecSpecificInfo codec_info_1;
178 memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
179 codec_info_1.codecType = kVideoCodecVP8;
180 codec_info_1.codecSpecific.VP8.simulcastIdx = 0;
181 CodecSpecificInfo codec_info_2;
182 memset(&codec_info_2, 0, sizeof(CodecSpecificInfo));
183 codec_info_2.codecType = kVideoCodecVP8;
184 codec_info_2.codecSpecific.VP8.simulcastIdx = 1;
185
186 // Only setting one stream to active will still set the payload router to
187 // active and allow sending data on the active stream.
188 std::vector<bool> active_modules({true, false});
189 payload_router.SetActiveModules(active_modules);
190
191 EXPECT_CALL(rtp_1, Sending()).WillOnce(Return(true));
192 EXPECT_CALL(rtp_1, SendOutgoingData(encoded_image._frameType, kPayloadType,
193 encoded_image._timeStamp,
194 encoded_image.capture_time_ms_, &payload,
195 encoded_image._length, nullptr, _, _))
196 .Times(1)
197 .WillOnce(Return(true));
198 EXPECT_EQ(EncodedImageCallback::Result::OK,
199 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
200 .error);
201
202 // Setting both streams to inactive will turn the payload router to inactive.
203 active_modules = {false, false};
204 payload_router.SetActiveModules(active_modules);
205 // An incoming encoded image will not ask the module to send outgoing data
206 // because the payload router is inactive.
207 EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
208 EXPECT_CALL(rtp_1, Sending()).Times(0);
209 EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _, _)).Times(0);
210 EXPECT_CALL(rtp_2, Sending()).Times(0);
211 EXPECT_NE(EncodedImageCallback::Result::OK,
212 payload_router.OnEncodedImage(encoded_image, &codec_info_1, nullptr)
213 .error);
214 EXPECT_NE(EncodedImageCallback::Result::OK,
215 payload_router.OnEncodedImage(encoded_image, &codec_info_2, nullptr)
216 .error);
217}
218
Åsa Persson4bece9a2017-10-06 10:04:04 +0200219TEST(PayloadRouterTest, CreateWithNoPreviousStates) {
220 NiceMock<MockRtpRtcp> rtp1;
221 NiceMock<MockRtpRtcp> rtp2;
222 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
223 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, {});
224 payload_router.SetActive(true);
225
226 std::map<uint32_t, RtpPayloadState> initial_states =
227 payload_router.GetRtpPayloadStates();
228 EXPECT_EQ(2u, initial_states.size());
229 EXPECT_NE(initial_states.find(kSsrc1), initial_states.end());
230 EXPECT_NE(initial_states.find(kSsrc2), initial_states.end());
231}
232
233TEST(PayloadRouterTest, CreateWithPreviousStates) {
234 RtpPayloadState state1;
235 state1.picture_id = kInitialPictureId1;
Niels Möllerbb894ff2018-03-15 12:28:53 +0100236 state1.tl0_pic_idx = kInitialTl0PicIdx1;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200237 RtpPayloadState state2;
238 state2.picture_id = kInitialPictureId2;
Niels Möllerbb894ff2018-03-15 12:28:53 +0100239 state2.tl0_pic_idx = kInitialTl0PicIdx2;
Åsa Persson4bece9a2017-10-06 10:04:04 +0200240 std::map<uint32_t, RtpPayloadState> states = {{kSsrc1, state1},
241 {kSsrc2, state2}};
242
243 NiceMock<MockRtpRtcp> rtp1;
244 NiceMock<MockRtpRtcp> rtp2;
245 std::vector<RtpRtcp*> modules = {&rtp1, &rtp2};
246 PayloadRouter payload_router(modules, {kSsrc1, kSsrc2}, kPayloadType, states);
247 payload_router.SetActive(true);
248
249 std::map<uint32_t, RtpPayloadState> initial_states =
250 payload_router.GetRtpPayloadStates();
251 EXPECT_EQ(2u, initial_states.size());
252 EXPECT_EQ(kInitialPictureId1, initial_states[kSsrc1].picture_id);
Niels Möllerbb894ff2018-03-15 12:28:53 +0100253 EXPECT_EQ(kInitialTl0PicIdx1, initial_states[kSsrc1].tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200254 EXPECT_EQ(kInitialPictureId2, initial_states[kSsrc2].picture_id);
Niels Möllerbb894ff2018-03-15 12:28:53 +0100255 EXPECT_EQ(kInitialTl0PicIdx2, initial_states[kSsrc2].tl0_pic_idx);
Åsa Persson4bece9a2017-10-06 10:04:04 +0200256}
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +0000257} // namespace webrtc