blob: 61ca9f0f9e5a73760d73f0a186eb44b709c6f91c [file] [log] [blame]
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00001/*
2 * Copyright (c) 2013 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 */
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +000010#include <algorithm> // max
kwiberg27f982b2016-03-01 11:52:33 -080011#include <memory>
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +000012#include <vector>
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +000013
Per9b3f56e2015-04-09 13:44:16 +020014#include "webrtc/base/bind.h"
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +000015#include "webrtc/base/checks.h"
Peter Boströmff019b02015-04-30 14:16:07 +020016#include "webrtc/base/criticalsection.h"
Peter Boström5811a392015-12-10 13:02:50 +010017#include "webrtc/base/event.h"
Peter Boström415d2cd2015-10-26 11:35:17 +010018#include "webrtc/base/logging.h"
pbos12411ef2015-11-23 14:47:56 -080019#include "webrtc/base/platform_thread.h"
Erik Språng737336d2016-07-29 12:59:36 +020020#include "webrtc/base/rate_limiter.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000021#include "webrtc/call.h"
Peter Boström5c389d32015-09-25 13:58:30 +020022#include "webrtc/call/transport_adapter.h"
pbosa96b60b2016-04-18 21:12:48 -070023#include "webrtc/common_video/include/frame_callback.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010024#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
25#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000026#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
pbos@webrtc.org013d9942013-08-22 09:42:17 +000027#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
philipel0f9af012015-09-01 07:01:51 -070028#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h"
philipel7fabd462015-09-03 04:42:32 -070029#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010030#include "webrtc/system_wrappers/include/sleep.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000031#include "webrtc/test/call_test.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000032#include "webrtc/test/configurable_frame_size_encoder.h"
Peter Boströmeb66e802015-06-05 11:08:03 +020033#include "webrtc/test/fake_texture_frame.h"
perkja49cbd32016-09-16 07:53:41 -070034#include "webrtc/test/frame_generator.h"
nisse26acec42016-04-15 03:43:39 -070035#include "webrtc/test/frame_utils.h"
kwibergac9f8762016-09-30 22:29:43 -070036#include "webrtc/test/gtest.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000037#include "webrtc/test/null_transport.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000038#include "webrtc/test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070039
pbos@webrtc.org273a4142014-12-01 15:23:21 +000040#include "webrtc/video/send_statistics_proxy.h"
Thiago Farina9bfe3da2015-04-10 12:52:13 +020041#include "webrtc/video_frame.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000042#include "webrtc/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000043
44namespace webrtc {
45
sprang@webrtc.org346094c2014-02-18 08:40:33 +000046enum VideoFormat { kGeneric, kVP8, };
47
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070048void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
49 const std::vector<VideoFrame>& frames2);
50VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000051
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000052class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000053 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000054 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000055 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000056 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010057
58 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
59 uint8_t num_spatial_layers);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000060};
61
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000062TEST_F(VideoSendStreamTest, CanStartStartedStream) {
skvlad11a9cbf2016-10-07 11:53:05 -070063 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000064
solenberg4fbae2b2015-08-28 04:07:10 -070065 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +010066 CreateSendConfig(1, 0, &transport);
67 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080068 video_send_stream_->Start();
69 video_send_stream_->Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000070 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000071}
72
73TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
skvlad11a9cbf2016-10-07 11:53:05 -070074 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000075
solenberg4fbae2b2015-08-28 04:07:10 -070076 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +010077 CreateSendConfig(1, 0, &transport);
78 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080079 video_send_stream_->Stop();
80 video_send_stream_->Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000081 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000082}
83
pbos@webrtc.org013d9942013-08-22 09:42:17 +000084TEST_F(VideoSendStreamTest, SupportsCName) {
85 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000086 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000087 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000088 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +000089
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000090 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000091 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000092 RTCPUtility::RTCPParserV2 parser(packet, length, true);
93 EXPECT_TRUE(parser.IsValid());
94
95 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
Erik Språng242e22b2015-05-11 10:17:43 +020096 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
97 if (packet_type == RTCPUtility::RTCPPacketTypes::kSdesChunk) {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000098 EXPECT_EQ(parser.Packet().CName.CName, kCName);
Peter Boström5811a392015-12-10 13:02:50 +010099 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000100 }
101
102 packet_type = parser.Iterate();
103 }
104
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000105 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000106 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000107
stefanff483612015-12-21 03:14:00 -0800108 void ModifyVideoConfigs(
109 VideoSendStream::Config* send_config,
110 std::vector<VideoReceiveStream::Config>* receive_configs,
111 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000112 send_config->rtp.c_name = kCName;
113 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000114
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000115 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100116 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000117 }
118 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000119
stefane74eef12016-01-08 06:47:13 -0800120 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000121}
122
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000123TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000124 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000125 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000126 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000127 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100128 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000129 }
130
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000131 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000132 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000133 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000134
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000135 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
136 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
137 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700138 if (header.extension.absoluteSendTime != 0) {
139 // Wait for at least one packet with a non-zero send time. The send time
140 // is a 16-bit value derived from the system clock, and it is valid
141 // for a packet to have a zero send time. To tell that from an
142 // unpopulated value we'll wait for a packet with non-zero send time.
143 observation_complete_.Set();
144 } else {
145 LOG(LS_WARNING) << "Got a packet with zero absoluteSendTime, waiting"
146 " for another packet...";
147 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000148
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000149 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000150 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000151
stefanff483612015-12-21 03:14:00 -0800152 void ModifyVideoConfigs(
153 VideoSendStream::Config* send_config,
154 std::vector<VideoReceiveStream::Config>* receive_configs,
155 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200156 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100157 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700158 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000159 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000160
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000161 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100162 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000163 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000164 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000165
stefane74eef12016-01-08 06:47:13 -0800166 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000167}
168
pbos@webrtc.org29023282013-09-11 10:14:56 +0000169TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000170 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000171 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000172 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000173 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000174 : SendTest(kDefaultTimeoutMs),
175 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000176 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100177 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000178 }
179
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000180 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000181 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000182 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000183 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000184
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000185 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
186 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000187 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000188 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100189 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000190
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000191 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000192 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000193
stefanff483612015-12-21 03:14:00 -0800194 void ModifyVideoConfigs(
195 VideoSendStream::Config* send_config,
196 std::vector<VideoReceiveStream::Config>* receive_configs,
197 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000198 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100199 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700200 send_config->rtp.extensions.push_back(RtpExtension(
201 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000202 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000203
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000204 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100205 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000206 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000207
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000208 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000209 } test;
210
stefane74eef12016-01-08 06:47:13 -0800211 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000212}
213
sprang867fb522015-08-03 04:38:41 -0700214TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700215 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700216 class TransportWideSequenceNumberObserver : public test::SendTest {
217 public:
218 TransportWideSequenceNumberObserver()
219 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
220 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
221 kRtpExtensionTransportSequenceNumber, kExtensionId));
222 }
223
224 private:
225 Action OnSendRtp(const uint8_t* packet, size_t length) override {
226 RTPHeader header;
227 EXPECT_TRUE(parser_->Parse(packet, length, &header));
228
229 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
230 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
231 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
232
Peter Boström5811a392015-12-10 13:02:50 +0100233 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700234
235 return SEND_PACKET;
236 }
237
stefanff483612015-12-21 03:14:00 -0800238 void ModifyVideoConfigs(
239 VideoSendStream::Config* send_config,
240 std::vector<VideoReceiveStream::Config>* receive_configs,
241 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700242 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100243 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700244 send_config->rtp.extensions.push_back(RtpExtension(
245 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
sprang867fb522015-08-03 04:38:41 -0700246 }
247
248 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100249 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700250 }
251
252 test::FakeEncoder encoder_;
253 } test;
254
stefane74eef12016-01-08 06:47:13 -0800255 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700256}
257
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000258class FakeReceiveStatistics : public NullReceiveStatistics {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000259 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000260 FakeReceiveStatistics(uint32_t send_ssrc,
261 uint32_t last_sequence_number,
262 uint32_t cumulative_lost,
263 uint8_t fraction_lost)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000264 : lossy_stats_(new LossyStatistician(last_sequence_number,
265 cumulative_lost,
266 fraction_lost)) {
267 stats_map_[send_ssrc] = lossy_stats_.get();
268 }
269
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000270 StatisticianMap GetActiveStatisticians() const override { return stats_map_; }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000271
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000272 StreamStatistician* GetStatistician(uint32_t ssrc) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000273 return lossy_stats_.get();
274 }
275
276 private:
277 class LossyStatistician : public StreamStatistician {
278 public:
279 LossyStatistician(uint32_t extended_max_sequence_number,
280 uint32_t cumulative_lost,
281 uint8_t fraction_lost) {
282 stats_.fraction_lost = fraction_lost;
283 stats_.cumulative_lost = cumulative_lost;
284 stats_.extended_max_sequence_number = extended_max_sequence_number;
285 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000286 bool GetStatistics(RtcpStatistics* statistics, bool reset) override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000287 *statistics = stats_;
288 return true;
289 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000290 void GetDataCounters(size_t* bytes_received,
291 uint32_t* packets_received) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000292 *bytes_received = 0;
293 *packets_received = 0;
294 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000295 void GetReceiveStreamDataCounters(
296 StreamDataCounters* data_counters) const override {}
297 uint32_t BitrateReceived() const override { return 0; }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000298 bool IsRetransmitOfOldPacket(const RTPHeader& header,
299 int64_t min_rtt) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000300 return false;
301 }
302
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000303 bool IsPacketInOrder(uint16_t sequence_number) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000304 return true;
305 }
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000306
307 RtcpStatistics stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000308 };
309
kwiberg27f982b2016-03-01 11:52:33 -0800310 std::unique_ptr<LossyStatistician> lossy_stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000311 StatisticianMap stats_map_;
312};
313
Peter Boström39593972016-02-15 11:27:15 +0100314class FecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100315 public:
Peter Boström39593972016-02-15 11:27:15 +0100316 FecObserver(bool header_extensions_enabled,
317 bool use_nack,
318 bool expect_red,
stefan8f4c77f2016-06-03 00:16:45 -0700319 bool expect_fec,
Peter Boström39593972016-02-15 11:27:15 +0100320 const std::string& codec)
321 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
322 payload_name_(codec),
323 use_nack_(use_nack),
324 expect_red_(expect_red),
stefan8f4c77f2016-06-03 00:16:45 -0700325 expect_fec_(expect_fec),
Stefan Holmer4654d202015-12-08 09:10:43 +0100326 send_count_(0),
327 received_media_(false),
328 received_fec_(false),
Peter Boström39593972016-02-15 11:27:15 +0100329 header_extensions_enabled_(header_extensions_enabled) {
330 if (codec == "H264") {
331 encoder_.reset(new test::FakeH264Encoder(Clock::GetRealTimeClock()));
332 } else if (codec == "VP8") {
333 encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8));
334 } else if (codec == "VP9") {
335 encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp9));
336 } else {
337 RTC_NOTREACHED();
338 }
339 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100340
341 private:
342 Action OnSendRtp(const uint8_t* packet, size_t length) override {
343 RTPHeader header;
344 EXPECT_TRUE(parser_->Parse(packet, length, &header));
345
Peter Boström39593972016-02-15 11:27:15 +0100346 ++send_count_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100347 int encapsulated_payload_type = -1;
348 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100349 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100350 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
351 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100352 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100353 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
354 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100355 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100356 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100357 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
358 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100359 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
360 length) {
361 // Not padding-only, media received outside of RED.
362 EXPECT_FALSE(expect_red_);
363 received_media_ = true;
364 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100365 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000366
Stefan Holmer4654d202015-12-08 09:10:43 +0100367 if (header_extensions_enabled_) {
368 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
369 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
370 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
371 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
372 // 24 bits wrap.
373 EXPECT_GT(prev_header_.extension.absoluteSendTime,
374 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000375 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100376 EXPECT_GE(header.extension.absoluteSendTime,
377 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200378 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100379 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
380 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
381 prev_header_.extension.transportSequenceNumber;
382 EXPECT_EQ(1, seq_num_diff);
383 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200384
Stefan Holmer4654d202015-12-08 09:10:43 +0100385 if (encapsulated_payload_type != -1) {
386 if (encapsulated_payload_type ==
387 VideoSendStreamTest::kUlpfecPayloadType) {
stefan8f4c77f2016-06-03 00:16:45 -0700388 EXPECT_TRUE(expect_fec_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100389 received_fec_ = true;
390 } else {
391 received_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000392 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000393 }
394
Peter Boström39593972016-02-15 11:27:15 +0100395 if (send_count_ > 100 && received_media_) {
stefan8f4c77f2016-06-03 00:16:45 -0700396 if (received_fec_ || !expect_fec_)
Peter Boström39593972016-02-15 11:27:15 +0100397 observation_complete_.Set();
398 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000399
Stefan Holmer4654d202015-12-08 09:10:43 +0100400 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000401
Stefan Holmer4654d202015-12-08 09:10:43 +0100402 return SEND_PACKET;
403 }
404
Peter Boström39593972016-02-15 11:27:15 +0100405 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
406 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
407 // Configure some network delay.
408 const int kNetworkDelayMs = 100;
409 FakeNetworkPipe::Config config;
410 config.loss_percent = 50;
411 config.queue_delay_ms = kNetworkDelayMs;
412 return new test::PacketTransport(sender_call, this,
413 test::PacketTransport::kSender, config);
414 }
415
stefanff483612015-12-21 03:14:00 -0800416 void ModifyVideoConfigs(
417 VideoSendStream::Config* send_config,
418 std::vector<VideoReceiveStream::Config>* receive_configs,
419 VideoEncoderConfig* encoder_config) override {
Stefan Holmer4654d202015-12-08 09:10:43 +0100420 transport_adapter_.reset(
421 new internal::TransportAdapter(send_config->send_transport));
422 transport_adapter_->Enable();
Peter Boström39593972016-02-15 11:27:15 +0100423 if (use_nack_) {
424 send_config->rtp.nack.rtp_history_ms =
425 (*receive_configs)[0].rtp.nack.rtp_history_ms =
426 VideoSendStreamTest::kNackRtpHistoryMs;
427 }
428 send_config->encoder_settings.encoder = encoder_.get();
429 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700430 send_config->rtp.ulpfec.red_payload_type =
431 VideoSendStreamTest::kRedPayloadType;
432 send_config->rtp.ulpfec.ulpfec_payload_type =
433 VideoSendStreamTest::kUlpfecPayloadType;
Stefan Holmer4654d202015-12-08 09:10:43 +0100434 if (header_extensions_enabled_) {
435 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700436 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100437 send_config->rtp.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700438 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
Stefan Holmer4654d202015-12-08 09:10:43 +0100439 test::kTransportSequenceNumberExtensionId));
440 }
brandtrb5f2c3f2016-10-04 23:28:39 -0700441 (*receive_configs)[0].rtp.ulpfec.red_payload_type =
442 send_config->rtp.ulpfec.red_payload_type;
443 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type =
444 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100445 }
446
447 void PerformTest() override {
448 EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets.";
449 }
450
kwiberg27f982b2016-03-01 11:52:33 -0800451 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
452 std::unique_ptr<VideoEncoder> encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100453 const std::string payload_name_;
454 const bool use_nack_;
455 const bool expect_red_;
stefan8f4c77f2016-06-03 00:16:45 -0700456 const bool expect_fec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100457 int send_count_;
458 bool received_media_;
459 bool received_fec_;
460 bool header_extensions_enabled_;
461 RTPHeader prev_header_;
462};
463
464TEST_F(VideoSendStreamTest, SupportsFecWithExtensions) {
stefan8f4c77f2016-06-03 00:16:45 -0700465 FecObserver test(true, false, true, true, "VP8");
stefane74eef12016-01-08 06:47:13 -0800466 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100467}
468
469TEST_F(VideoSendStreamTest, SupportsFecWithoutExtensions) {
stefan8f4c77f2016-06-03 00:16:45 -0700470 FecObserver test(false, false, true, true, "VP8");
Peter Boström39593972016-02-15 11:27:15 +0100471 RunBaseTest(&test);
472}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000473
Peter Boström39593972016-02-15 11:27:15 +0100474// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
475// since we'll still have to re-request FEC packets, effectively wasting
476// bandwidth since the receiver has to wait for FEC retransmissions to determine
477// that the received state is actually decodable.
stefan8f4c77f2016-06-03 00:16:45 -0700478TEST_F(VideoSendStreamTest, DoesNotUtilizeFecForH264WithNackEnabled) {
479 FecObserver test(false, true, true, false, "H264");
Peter Boström39593972016-02-15 11:27:15 +0100480 RunBaseTest(&test);
481}
482
483// Without retransmissions FEC for H264 is fine.
484TEST_F(VideoSendStreamTest, DoesUtilizeRedForH264WithoutNackEnabled) {
stefan8f4c77f2016-06-03 00:16:45 -0700485 FecObserver test(false, false, true, true, "H264");
Peter Boström39593972016-02-15 11:27:15 +0100486 RunBaseTest(&test);
487}
488
489TEST_F(VideoSendStreamTest, DoesUtilizeRedForVp8WithNackEnabled) {
stefan8f4c77f2016-06-03 00:16:45 -0700490 FecObserver test(false, true, true, true, "VP8");
Peter Boström39593972016-02-15 11:27:15 +0100491 RunBaseTest(&test);
492}
493
Peter Boström12996152016-05-14 02:03:18 +0200494#if !defined(RTC_DISABLE_VP9)
Peter Boström39593972016-02-15 11:27:15 +0100495TEST_F(VideoSendStreamTest, DoesUtilizeRedForVp9WithNackEnabled) {
stefan8f4c77f2016-06-03 00:16:45 -0700496 FecObserver test(false, true, true, true, "VP9");
stefane74eef12016-01-08 06:47:13 -0800497 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000498}
Peter Boström12996152016-05-14 02:03:18 +0200499#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000500
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000501void VideoSendStreamTest::TestNackRetransmission(
502 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000503 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000504 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000505 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000506 explicit NackObserver(uint32_t retransmit_ssrc,
507 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000508 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000509 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000510 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000511 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000512 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000513 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000514
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000515 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000516 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000517 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000518 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000519
520 // Nack second packet after receiving the third one.
521 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000522 uint16_t nack_sequence_number = header.sequenceNumber - 1;
523 nacked_sequence_number_ = nack_sequence_number;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000524 NullReceiveStatistics null_stats;
Peter Boströmac547a62015-09-17 23:03:57 +0200525 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), &null_stats,
terelius429c3452016-01-21 05:42:04 -0800526 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000527
pbosda903ea2015-10-02 02:36:56 -0700528 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100529 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000530
531 RTCPSender::FeedbackState feedback_state;
532
533 EXPECT_EQ(0,
534 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000535 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000536 }
537
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000538 uint16_t sequence_number = header.sequenceNumber;
539
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000540 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100541 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
542 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000543 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000544 const uint8_t* rtx_header = packet + header.headerLength;
545 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
546 }
547
548 if (sequence_number == nacked_sequence_number_) {
549 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000550 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100551 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000552 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000553
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000554 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000555 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000556
stefanff483612015-12-21 03:14:00 -0800557 void ModifyVideoConfigs(
558 VideoSendStream::Config* send_config,
559 std::vector<VideoReceiveStream::Config>* receive_configs,
560 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700561 transport_adapter_.reset(
562 new internal::TransportAdapter(send_config->send_transport));
563 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000564 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000565 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100566 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000567 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
568 }
569
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000570 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100571 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000572 }
573
kwiberg27f982b2016-03-01 11:52:33 -0800574 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000575 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000576 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000577 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000578 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000579 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000580
stefane74eef12016-01-08 06:47:13 -0800581 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000582}
583
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000584TEST_F(VideoSendStreamTest, RetransmitsNack) {
585 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100586 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000587}
588
589TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
590 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000591 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000592}
593
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000594void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
595 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000596 // Use a fake encoder to output a frame of every size in the range [90, 290],
597 // for each size making sure that the exact number of payload bytes received
598 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000599 static const size_t kMaxPacketSize = 128;
600 static const size_t start = 90;
601 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000602
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000603 // Observer that verifies that the expected number of packets and bytes
604 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000605 class FrameFragmentationTest : public test::SendTest,
606 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000607 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000608 FrameFragmentationTest(size_t max_packet_size,
609 size_t start_size,
610 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000611 bool test_generic_packetization,
612 bool use_fec)
613 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000614 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000615 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000616 stop_size_(stop_size),
617 test_generic_packetization_(test_generic_packetization),
618 use_fec_(use_fec),
619 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000620 accumulated_size_(0),
621 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000622 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000623 current_size_rtp_(start_size),
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000624 current_size_frame_(static_cast<int32_t>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000625 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000626 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700627 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000628 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000629
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000630 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000631 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000632 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000633 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000634 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000635
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000636 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000637
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000638 if (use_fec_) {
639 uint8_t payload_type = packet[header.headerLength];
640 bool is_fec = header.payloadType == kRedPayloadType &&
641 payload_type == kUlpfecPayloadType;
642 if (is_fec) {
643 fec_packet_received_ = true;
644 return SEND_PACKET;
645 }
646 }
647
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000648 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000649
650 if (use_fec_)
651 TriggerLossReport(header);
652
653 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200654 size_t overhead = header.headerLength + header.paddingLength;
655 // Only remove payload header and RED header if the packet actually
656 // contains payload.
657 if (length > overhead) {
658 overhead += (1 /* Generic header */);
659 if (use_fec_)
660 overhead += 1; // RED for FEC header.
661 }
662 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000663 accumulated_payload_ += length - overhead;
664 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000665
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000666 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000667 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000668 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
669 // With FEC enabled, frame size is incremented asynchronously, so
670 // "old" frames one byte too small may arrive. Accept, but don't
671 // increase expected frame size.
672 accumulated_size_ = 0;
673 accumulated_payload_ = 0;
674 return SEND_PACKET;
675 }
676
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000677 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000678 if (test_generic_packetization_) {
679 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
680 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000681
682 // Last packet of frame; reset counters.
683 accumulated_size_ = 0;
684 accumulated_payload_ = 0;
685 if (current_size_rtp_ == stop_size_) {
686 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100687 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000688 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000689 // Increase next expected frame size. If testing with FEC, make sure
690 // a FEC packet has been received for this frame size before
691 // proceeding, to make sure that redundancy packets don't exceed
692 // size limit.
693 if (!use_fec_) {
694 ++current_size_rtp_;
695 } else if (fec_packet_received_) {
696 fec_packet_received_ = false;
697 ++current_size_rtp_;
698 ++current_size_frame_;
699 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000700 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000701 }
702
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000703 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000704 }
705
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000706 void TriggerLossReport(const RTPHeader& header) {
707 // Send lossy receive reports to trigger FEC enabling.
708 if (packet_count_++ % 2 != 0) {
709 // Receive statistics reporting having lost 50% of the packets.
710 FakeReceiveStatistics lossy_receive_stats(
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100711 kVideoSendSsrcs[0], header.sequenceNumber, packet_count_ / 2, 127);
Peter Boströmac547a62015-09-17 23:03:57 +0200712 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800713 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700714 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000715
pbosda903ea2015-10-02 02:36:56 -0700716 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100717 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000718
719 RTCPSender::FeedbackState feedback_state;
720
721 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
722 }
723 }
724
nisseef8b61e2016-04-29 06:09:15 -0700725 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000726 // Increase frame size for next encoded frame, in the context of the
727 // encoder thread.
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000728 if (!use_fec_ &&
729 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000730 ++current_size_frame_;
731 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000732 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value()));
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000733 }
734
Stefan Holmere5904162015-03-26 11:11:06 +0100735 Call::Config GetSenderCallConfig() override {
skvlad11a9cbf2016-10-07 11:53:05 -0700736 Call::Config config(&event_log_);
Stefan Holmere5904162015-03-26 11:11:06 +0100737 const int kMinBitrateBps = 30000;
738 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
739 return config;
740 }
741
stefanff483612015-12-21 03:14:00 -0800742 void ModifyVideoConfigs(
743 VideoSendStream::Config* send_config,
744 std::vector<VideoReceiveStream::Config>* receive_configs,
745 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700746 transport_adapter_.reset(
747 new internal::TransportAdapter(send_config->send_transport));
748 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000749 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -0700750 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
751 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000752 }
753
754 if (!test_generic_packetization_)
755 send_config->encoder_settings.payload_name = "VP8";
756
757 send_config->encoder_settings.encoder = &encoder_;
758 send_config->rtp.max_packet_size = kMaxPacketSize;
759 send_config->post_encode_callback = this;
760
Erik Språng95261872015-04-10 11:58:49 +0200761 // Make sure there is at least one extension header, to make the RTP
762 // header larger than the base length of 12 bytes.
763 EXPECT_FALSE(send_config->rtp.extensions.empty());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000764 }
765
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000766 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100767 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000768 }
769
kwiberg27f982b2016-03-01 11:52:33 -0800770 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000771 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000772
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000773 const size_t max_packet_size_;
774 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000775 const bool test_generic_packetization_;
776 const bool use_fec_;
777
778 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000779 size_t accumulated_size_;
780 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000781 bool fec_packet_received_;
782
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000783 size_t current_size_rtp_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000784 Atomic32 current_size_frame_;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000785 };
786
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000787 // Don't auto increment if FEC is used; continue sending frame size until
788 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000789 FrameFragmentationTest test(
790 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000791
stefane74eef12016-01-08 06:47:13 -0800792 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000793}
794
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000795// TODO(sprang): Is there any way of speeding up these tests?
796TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
797 TestPacketFragmentationSize(kGeneric, false);
798}
799
800TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
801 TestPacketFragmentationSize(kGeneric, true);
802}
803
804TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
805 TestPacketFragmentationSize(kVP8, false);
806}
807
808TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
809 TestPacketFragmentationSize(kVP8, true);
810}
811
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000812// The test will go through a number of phases.
813// 1. Start sending packets.
814// 2. As soon as the RTP stream has been detected, signal a low REMB value to
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000815// suspend the stream.
816// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000817// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000818// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000819// When the stream is detected again, and the stats show that the stream
820// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000821TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
822 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000823
nissed30a1112016-04-18 05:15:22 -0700824 class RembObserver : public test::SendTest,
825 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000826 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000827 RembObserver()
828 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000829 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +0200830 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000831 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000832 rtp_count_(0),
833 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000834 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000835 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +0200836 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000837
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000838 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000839 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +0200840 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000841 ++rtp_count_;
842 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000843 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000844 last_sequence_number_ = header.sequenceNumber;
845
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000846 if (test_state_ == kBeforeSuspend) {
847 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000848 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000849 test_state_ = kDuringSuspend;
850 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +0000851 if (header.paddingLength == 0) {
852 // Received non-padding packet during suspension period. Reset the
853 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +0000854 suspended_frame_count_ = 0;
855 }
stefanf116bd02015-10-27 08:29:42 -0700856 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000857 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +0000858 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000859 // Non-padding packet observed. Test is almost complete. Will just
860 // have to wait for the stats to change.
861 test_state_ = kWaitingForStats;
862 }
stefanf116bd02015-10-27 08:29:42 -0700863 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000864 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000865 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000866 if (stats.suspended == false) {
867 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +0100868 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +0000869 }
stefanf116bd02015-10-27 08:29:42 -0700870 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000871 }
872
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000873 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000874 }
875
perkj26091b12016-09-01 01:17:40 -0700876 // This method implements the rtc::VideoSinkInterface. This is called when
877 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -0700878 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +0200879 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000880 if (test_state_ == kDuringSuspend &&
881 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000882 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000883 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000884 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000885 test_state_ = kWaitingForPacket;
886 }
887 }
888
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000889 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200890 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000891 low_remb_bps_ = value;
892 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000893
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000894 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200895 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000896 high_remb_bps_ = value;
897 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000898
stefanff483612015-12-21 03:14:00 -0800899 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000900 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000901 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000902 stream_ = send_stream;
903 }
904
stefanff483612015-12-21 03:14:00 -0800905 void ModifyVideoConfigs(
906 VideoSendStream::Config* send_config,
907 std::vector<VideoReceiveStream::Config>* receive_configs,
908 VideoEncoderConfig* encoder_config) override {
perkjfa10b552016-10-02 23:45:26 -0700909 RTC_DCHECK_EQ(1u, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -0700910 transport_adapter_.reset(
911 new internal::TransportAdapter(send_config->send_transport));
912 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000913 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000914 send_config->pre_encode_callback = this;
915 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -0700916 int min_bitrate_bps =
917 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000918 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +0200919 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -0700920 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000921 min_bitrate_bps + threshold_window + 5000);
922 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
923 }
924
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000925 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100926 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000927 }
928
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000929 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000930 kBeforeSuspend,
931 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000932 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000933 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000934 };
935
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000936 virtual void SendRtcpFeedback(int remb_value)
937 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100938 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
939 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -0800940 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700941 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000942
pbosda903ea2015-10-02 02:36:56 -0700943 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100944 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000945 if (remb_value > 0) {
946 rtcp_sender.SetREMBStatus(true);
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +0000947 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000948 }
949 RTCPSender::FeedbackState feedback_state;
950 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
951 }
952
kwiberg27f982b2016-03-01 11:52:33 -0800953 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000954 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000955 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000956
Peter Boströmf2f82832015-05-01 13:00:41 +0200957 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000958 TestState test_state_ GUARDED_BY(crit_);
959 int rtp_count_ GUARDED_BY(crit_);
960 int last_sequence_number_ GUARDED_BY(crit_);
961 int suspended_frame_count_ GUARDED_BY(crit_);
962 int low_remb_bps_ GUARDED_BY(crit_);
963 int high_remb_bps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000964 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000965
stefane74eef12016-01-08 06:47:13 -0800966 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000967}
968
perkj71ee44c2016-06-15 00:47:53 -0700969// This test that padding stops being send after a while if the Camera stops
970// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +0000971TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000972 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +0000973 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000974 NoPaddingWhenVideoIsMuted()
975 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +0000976 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000977 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000978 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000979 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +0000980
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000981 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000982 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +0200983 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +0000984 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -0700985
986 RTPHeader header;
987 parser_->Parse(packet, length, &header);
988 const bool only_padding =
989 header.headerLength + header.paddingLength == length;
990
991 if (test_state_ == kBeforeStopCapture) {
992 capturer_->Stop();
993 test_state_ = kWaitingForPadding;
994 } else if (test_state_ == kWaitingForPadding && only_padding) {
995 test_state_ = kWaitingForNoPackets;
996 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
997 only_padding) {
998 observation_complete_.Set();
999 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001000 return SEND_PACKET;
1001 }
1002
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001003 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001004 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001005 const int kNoPacketsThresholdMs = 2000;
1006 if (test_state_ == kWaitingForNoPackets &&
1007 (last_packet_time_ms_ > 0 &&
1008 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1009 kNoPacketsThresholdMs)) {
1010 capturer_->Start();
1011 test_state_ = kWaitingForPaddingAfterCameraRestart;
1012 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001013 return SEND_PACKET;
1014 }
1015
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001016 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001017
nisseef8b61e2016-04-29 06:09:15 -07001018 void OnFrameGeneratorCapturerCreated(
1019 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001020 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001021 capturer_ = frame_generator_capturer;
1022 }
1023
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001024 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001025 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001026 << "Timed out while waiting for RTP packets to stop being sent.";
1027 }
1028
perkj71ee44c2016-06-15 00:47:53 -07001029 enum TestState {
1030 kBeforeStopCapture,
1031 kWaitingForPadding,
1032 kWaitingForNoPackets,
1033 kWaitingForPaddingAfterCameraRestart
1034 };
1035
1036 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001037 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001038 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001039 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001040 int64_t last_packet_time_ms_ GUARDED_BY(crit_);
1041 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001042 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001043
stefane74eef12016-01-08 06:47:13 -08001044 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001045}
1046
isheriffcc5903e2016-10-04 08:29:38 -07001047TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1048 const int kCapacityKbps = 10000; // 10 Mbps
1049 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1050 public:
1051 PaddingIsPrimarilyRetransmissions()
1052 : EndToEndTest(kDefaultTimeoutMs),
1053 clock_(Clock::GetRealTimeClock()),
1054 padding_length_(0),
1055 total_length_(0),
1056 call_(nullptr) {}
1057
1058 private:
1059 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1060 call_ = sender_call;
1061 }
1062
1063 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1064 rtc::CritScope lock(&crit_);
1065
1066 RTPHeader header;
1067 parser_->Parse(packet, length, &header);
1068 padding_length_ += header.paddingLength;
1069 total_length_ += length;
1070 return SEND_PACKET;
1071 }
1072
1073 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
1074 const int kNetworkDelayMs = 50;
1075 FakeNetworkPipe::Config config;
1076 config.loss_percent = 10;
1077 config.link_capacity_kbps = kCapacityKbps;
1078 config.queue_delay_ms = kNetworkDelayMs;
1079 return new test::PacketTransport(sender_call, this,
1080 test::PacketTransport::kSender, config);
1081 }
1082
1083 void ModifyVideoConfigs(
1084 VideoSendStream::Config* send_config,
1085 std::vector<VideoReceiveStream::Config>* receive_configs,
1086 VideoEncoderConfig* encoder_config) override {
1087 send_config->rtp.extensions.clear();
1088 send_config->rtp.extensions.push_back(
1089 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
1090 test::kTransportSequenceNumberExtensionId));
1091 // Turn on RTX.
1092 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1093 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
1094
1095 (*receive_configs)[0].rtp.extensions.clear();
1096 (*receive_configs)[0].rtp.extensions.push_back(
1097 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
1098 test::kTransportSequenceNumberExtensionId));
1099 (*receive_configs)[0].rtp.transport_cc = true;
1100 }
1101
1102 void PerformTest() override {
1103 // TODO(isheriff): Some platforms do not ramp up as expected to full
1104 // capacity due to packet scheduling delays. Fix that before getting
1105 // rid of this.
1106 SleepMs(5000);
1107 {
1108 rtc::CritScope lock(&crit_);
1109 // Expect padding to be a small percentage of total bytes sent.
1110 EXPECT_LT(padding_length_, .1 * total_length_);
1111 }
1112 }
1113
1114 rtc::CriticalSection crit_;
1115 Clock* const clock_;
1116 size_t padding_length_ GUARDED_BY(crit_);
1117 size_t total_length_ GUARDED_BY(crit_);
1118 Call* call_;
1119 } test;
1120
1121 RunBaseTest(&test);
1122}
1123
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001124// This test first observes "high" bitrate use at which point it sends a REMB to
1125// indicate that it should be lowered significantly. The test then observes that
1126// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1127// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001128//
1129// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1130// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001131TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1132 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001133 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001134 static const int kRembBitrateBps = 80000;
1135 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001136 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001137 public:
1138 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001139 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001140 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1141 stream_(nullptr),
1142 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001143
1144 private:
nisseef8b61e2016-04-29 06:09:15 -07001145 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001146 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001147 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001148
1149 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001150 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001151 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001152 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001153 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001154 if (!stats.substreams.empty()) {
1155 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001156 int total_bitrate_bps =
1157 stats.substreams.begin()->second.total_bitrate_bps;
1158 test::PrintResult("bitrate_stats_",
1159 "min_transmit_bitrate_low_remb",
1160 "bitrate_bps",
1161 static_cast<size_t>(total_bitrate_bps),
1162 "bps",
1163 false);
1164 if (total_bitrate_bps > kHighBitrateBps) {
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001165 rtp_rtcp_->SetREMBData(kRembBitrateBps,
1166 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001167 rtp_rtcp_->Process();
1168 bitrate_capped_ = true;
1169 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001170 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001171 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001172 }
1173 }
stefanf116bd02015-10-27 08:29:42 -07001174 // Packets don't have to be delivered since the test is the receiver.
1175 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001176 }
1177
stefanff483612015-12-21 03:14:00 -08001178 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001179 VideoSendStream* send_stream,
1180 const std::vector<VideoReceiveStream*>& receive_streams) override {
1181 stream_ = send_stream;
1182 RtpRtcp::Configuration config;
1183 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001184 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001185 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1186 rtp_rtcp_->SetREMBStatus(true);
1187 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001188 }
1189
stefanff483612015-12-21 03:14:00 -08001190 void ModifyVideoConfigs(
1191 VideoSendStream::Config* send_config,
1192 std::vector<VideoReceiveStream::Config>* receive_configs,
1193 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001194 feedback_transport_.reset(
1195 new internal::TransportAdapter(send_config->send_transport));
1196 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001197 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001198 }
1199
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001200 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001201 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001202 << "Timeout while waiting for low bitrate stats after REMB.";
1203 }
1204
kwiberg27f982b2016-03-01 11:52:33 -08001205 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1206 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001207 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001208 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001209 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001210 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001211
stefane74eef12016-01-08 06:47:13 -08001212 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001213}
1214
Stefan Holmer280de9e2016-09-30 10:06:51 +02001215TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1216 static const int kStartBitrateBps = 300000;
1217 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001218 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001219 class ChangingNetworkRouteTest : public test::EndToEndTest {
1220 public:
Stefan Holmerbe402962016-07-08 16:16:41 +02001221 ChangingNetworkRouteTest()
Stefan Holmer280de9e2016-09-30 10:06:51 +02001222 : EndToEndTest(test::CallTest::kDefaultTimeoutMs), call_(nullptr) {
1223 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1224 kRtpExtensionTransportSequenceNumber, kExtensionId));
1225 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001226
1227 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1228 call_ = sender_call;
1229 }
1230
Stefan Holmer280de9e2016-09-30 10:06:51 +02001231 void ModifyVideoConfigs(
1232 VideoSendStream::Config* send_config,
1233 std::vector<VideoReceiveStream::Config>* receive_configs,
1234 VideoEncoderConfig* encoder_config) override {
1235 send_config->rtp.extensions.clear();
1236 send_config->rtp.extensions.push_back(RtpExtension(
1237 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1238 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1239 (*receive_configs)[0].rtp.transport_cc = true;
1240 }
1241
1242 void ModifyAudioConfigs(
1243 AudioSendStream::Config* send_config,
1244 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1245 send_config->rtp.extensions.clear();
1246 send_config->rtp.extensions.push_back(RtpExtension(
1247 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1248 (*receive_configs)[0].rtp.extensions.clear();
1249 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1250 (*receive_configs)[0].rtp.transport_cc = true;
1251 }
1252
Stefan Holmerbe402962016-07-08 16:16:41 +02001253 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1254 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1255 observation_complete_.Set();
1256 }
1257
1258 return SEND_PACKET;
1259 }
1260
1261 void PerformTest() override {
1262 rtc::NetworkRoute new_route(true, 10, 20, -1);
1263 call_->OnNetworkRouteChanged("transport", new_route);
1264 Call::Config::BitrateConfig bitrate_config;
1265 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1266 call_->SetBitrateConfig(bitrate_config);
1267 EXPECT_TRUE(Wait())
1268 << "Timed out while waiting for start bitrate to be exceeded.";
1269
1270 bitrate_config.start_bitrate_bps = -1;
1271 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1272 call_->SetBitrateConfig(bitrate_config);
1273 // TODO(holmer): We should set the last sent packet id here and verify
1274 // that we correctly ignore any packet loss reported prior to that id.
1275 ++new_route.local_network_id;
1276 call_->OnNetworkRouteChanged("transport", new_route);
stefan01bbc3c2016-10-25 04:19:48 -07001277 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
Stefan Holmerbe402962016-07-08 16:16:41 +02001278 }
1279
1280 private:
1281 Call* call_;
1282 } test;
1283
1284 RunBaseTest(&test);
1285}
1286
sprang9c0b5512016-07-06 00:54:28 -07001287class MaxPaddingSetTest : public test::SendTest {
1288 public:
1289 static const uint32_t kMinTransmitBitrateBps = 400000;
1290 static const uint32_t kActualEncodeBitrateBps = 40000;
1291 static const uint32_t kMinPacketsToSend = 50;
1292
1293 explicit MaxPaddingSetTest(bool test_switch_content_type)
1294 : SendTest(test::CallTest::kDefaultTimeoutMs),
1295 call_(nullptr),
1296 send_stream_(nullptr),
1297 packets_sent_(0),
1298 running_without_padding_(test_switch_content_type) {}
1299
1300 void OnVideoStreamsCreated(
1301 VideoSendStream* send_stream,
1302 const std::vector<VideoReceiveStream*>& receive_streams) override {
1303 send_stream_ = send_stream;
1304 }
1305
1306 void ModifyVideoConfigs(
1307 VideoSendStream::Config* send_config,
1308 std::vector<VideoReceiveStream::Config>* receive_configs,
1309 VideoEncoderConfig* encoder_config) override {
perkjfa10b552016-10-02 23:45:26 -07001310 RTC_DCHECK_EQ(1u, encoder_config->number_of_streams);
sprang9c0b5512016-07-06 00:54:28 -07001311 if (running_without_padding_) {
1312 encoder_config->min_transmit_bitrate_bps = 0;
1313 encoder_config->content_type =
1314 VideoEncoderConfig::ContentType::kRealtimeVideo;
1315 } else {
1316 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1317 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1318 }
perkj26091b12016-09-01 01:17:40 -07001319 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001320 }
1321
1322 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1323 call_ = sender_call;
1324 }
1325
1326 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1327 rtc::CritScope lock(&crit_);
1328
1329 if (running_without_padding_)
1330 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1331
1332 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1333 // we have reliable data.
1334 if (++packets_sent_ < kMinPacketsToSend)
1335 return SEND_PACKET;
1336
1337 if (running_without_padding_) {
1338 // We've sent kMinPacketsToSend packets with default configuration, switch
1339 // to enabling screen content and setting min transmit bitrate.
1340 packets_sent_ = 0;
1341 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1342 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
perkj26091b12016-09-01 01:17:40 -07001343 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
sprang9c0b5512016-07-06 00:54:28 -07001344 running_without_padding_ = false;
1345 return SEND_PACKET;
1346 }
1347
1348 // Make sure the pacer has been configured with a min transmit bitrate.
1349 if (call_->GetStats().max_padding_bitrate_bps > 0)
1350 observation_complete_.Set();
1351
1352 return SEND_PACKET;
1353 }
1354
1355 void PerformTest() override {
1356 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1357 }
1358
1359 private:
1360 rtc::CriticalSection crit_;
1361 Call* call_;
1362 VideoSendStream* send_stream_;
1363 VideoEncoderConfig encoder_config_;
1364 uint32_t packets_sent_ GUARDED_BY(crit_);
1365 bool running_without_padding_;
1366};
1367
1368TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
1369 MaxPaddingSetTest test(false);
1370 RunBaseTest(&test);
1371}
1372
1373TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
1374 MaxPaddingSetTest test(true);
1375 RunBaseTest(&test);
1376}
1377
perkjfa10b552016-10-02 23:45:26 -07001378// This test verifies that new frame sizes reconfigures encoders even though not
1379// (yet) sending. The purpose of this is to permit encoding as quickly as
1380// possible once we start sending. Likely the frames being input are from the
1381// same source that will be sent later, which just means that we're ready
1382// earlier.
1383TEST_F(VideoSendStreamTest,
1384 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1385 class EncoderObserver : public test::FakeEncoder {
1386 public:
1387 EncoderObserver()
1388 : FakeEncoder(Clock::GetRealTimeClock()),
1389 init_encode_called_(false, false),
1390 number_of_initializations_(0),
1391 last_initialized_frame_width_(0),
1392 last_initialized_frame_height_(0) {}
1393
1394 void WaitForResolution(int width, int height) {
1395 {
1396 rtc::CritScope lock(&crit_);
1397 if (last_initialized_frame_width_ == width &&
1398 last_initialized_frame_height_ == height) {
1399 return;
1400 }
1401 }
1402 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1403 {
1404 rtc::CritScope lock(&crit_);
1405 EXPECT_EQ(width, last_initialized_frame_width_);
1406 EXPECT_EQ(height, last_initialized_frame_height_);
1407 }
1408 }
1409
1410 private:
1411 int32_t InitEncode(const VideoCodec* config,
1412 int32_t number_of_cores,
1413 size_t max_payload_size) override {
1414 rtc::CritScope lock(&crit_);
1415 last_initialized_frame_width_ = config->width;
1416 last_initialized_frame_height_ = config->height;
1417 ++number_of_initializations_;
1418 // First time InitEncode is called, the frame size is unknown.
1419 if (number_of_initializations_ > 1)
1420 init_encode_called_.Set();
1421 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1422 }
1423
1424 int32_t Encode(const VideoFrame& input_image,
1425 const CodecSpecificInfo* codec_specific_info,
1426 const std::vector<FrameType>* frame_types) override {
1427 ADD_FAILURE()
1428 << "Unexpected Encode call since the send stream is not started";
1429 return 0;
1430 }
1431
1432 rtc::CriticalSection crit_;
1433 rtc::Event init_encode_called_;
1434 size_t number_of_initializations_ GUARDED_BY(&crit_);
1435 int last_initialized_frame_width_ GUARDED_BY(&crit_);
1436 int last_initialized_frame_height_ GUARDED_BY(&crit_);
1437 };
1438
skvlad11a9cbf2016-10-07 11:53:05 -07001439 CreateSenderCall(Call::Config(&event_log_));
perkjfa10b552016-10-02 23:45:26 -07001440 test::NullTransport transport;
1441 CreateSendConfig(1, 0, &transport);
1442 EncoderObserver encoder;
1443 video_send_config_.encoder_settings.encoder = &encoder;
1444 CreateVideoStreams();
1445 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1446 kDefaultHeight);
1447 frame_generator_capturer_->Start();
1448
1449 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
1450 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1451 kDefaultHeight * 2);
1452 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
1453 DestroyStreams();
1454}
1455
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001456TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1457 class StartBitrateObserver : public test::FakeEncoder {
1458 public:
1459 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001460 : FakeEncoder(Clock::GetRealTimeClock()),
1461 start_bitrate_changed_(false, false),
1462 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001463 int32_t InitEncode(const VideoCodec* config,
1464 int32_t number_of_cores,
1465 size_t max_payload_size) override {
1466 rtc::CritScope lock(&crit_);
1467 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001468 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001469 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1470 }
1471
1472 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1473 rtc::CritScope lock(&crit_);
1474 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001475 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001476 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1477 }
1478
1479 int GetStartBitrateKbps() const {
1480 rtc::CritScope lock(&crit_);
1481 return start_bitrate_kbps_;
1482 }
1483
pbos14fe7082016-04-20 06:35:56 -07001484 bool WaitForStartBitrate() {
1485 return start_bitrate_changed_.Wait(
1486 VideoSendStreamTest::kDefaultTimeoutMs);
1487 }
1488
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001489 private:
pbos5ad935c2016-01-25 03:52:44 -08001490 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001491 rtc::Event start_bitrate_changed_;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001492 int start_bitrate_kbps_ GUARDED_BY(crit_);
1493 };
1494
skvlad11a9cbf2016-10-07 11:53:05 -07001495 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001496
solenberg4fbae2b2015-08-28 04:07:10 -07001497 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001498 CreateSendConfig(1, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001499
1500 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001501 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001502 sender_call_->SetBitrateConfig(bitrate_config);
1503
1504 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001505 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001506 // Since this test does not use a capturer, set |internal_source| = true.
1507 // Encoder configuration is otherwise updated on the next video frame.
1508 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001509
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001510 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001511
pbos14fe7082016-04-20 06:35:56 -07001512 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001513 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001514 encoder.GetStartBitrateKbps());
1515
perkjfa10b552016-10-02 23:45:26 -07001516 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001517 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001518
1519 // New bitrate should be reconfigured above the previous max. As there's no
1520 // network connection this shouldn't be flaky, as no bitrate should've been
1521 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001522 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001523 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1524 encoder.GetStartBitrateKbps());
1525
1526 DestroyStreams();
1527}
1528
perkj57c21f92016-06-17 07:27:16 -07001529// This test that if the encoder use an internal source, VideoEncoder::SetRates
1530// will be called with zero bitrate during initialization and that
1531// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1532// with zero bitrate.
1533TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1534 class StartStopBitrateObserver : public test::FakeEncoder {
1535 public:
1536 StartStopBitrateObserver()
1537 : FakeEncoder(Clock::GetRealTimeClock()),
1538 encoder_init_(false, false),
1539 bitrate_changed_(false, false),
1540 bitrate_kbps_(0) {}
1541 int32_t InitEncode(const VideoCodec* config,
1542 int32_t number_of_cores,
1543 size_t max_payload_size) override {
1544 rtc::CritScope lock(&crit_);
1545 bitrate_kbps_ = config->startBitrate;
1546 encoder_init_.Set();
1547 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1548 }
1549
1550 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1551 rtc::CritScope lock(&crit_);
1552 bitrate_kbps_ = new_target_bitrate;
1553 bitrate_changed_.Set();
1554 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1555 }
1556
1557 int GetBitrateKbps() const {
1558 rtc::CritScope lock(&crit_);
1559 return bitrate_kbps_;
1560 }
1561
1562 bool WaitForEncoderInit() {
1563 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1564 }
1565 bool WaitBitrateChanged() {
1566 return bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1567 }
1568
1569 private:
1570 rtc::CriticalSection crit_;
1571 rtc::Event encoder_init_;
1572 rtc::Event bitrate_changed_;
1573 int bitrate_kbps_ GUARDED_BY(crit_);
1574 };
1575
skvlad11a9cbf2016-10-07 11:53:05 -07001576 CreateSenderCall(Call::Config(&event_log_));
perkj57c21f92016-06-17 07:27:16 -07001577
1578 test::NullTransport transport;
1579 CreateSendConfig(1, 0, &transport);
1580
1581 StartStopBitrateObserver encoder;
1582 video_send_config_.encoder_settings.encoder = &encoder;
1583 video_send_config_.encoder_settings.internal_source = true;
1584
1585 CreateVideoStreams();
1586
1587 EXPECT_TRUE(encoder.WaitForEncoderInit());
1588 EXPECT_GT(encoder.GetBitrateKbps(), 0);
1589 video_send_stream_->Start();
1590 EXPECT_TRUE(encoder.WaitBitrateChanged());
1591 EXPECT_GT(encoder.GetBitrateKbps(), 0);
1592 video_send_stream_->Stop();
1593 EXPECT_TRUE(encoder.WaitBitrateChanged());
1594 EXPECT_EQ(0, encoder.GetBitrateKbps());
1595 video_send_stream_->Start();
1596 EXPECT_TRUE(encoder.WaitBitrateChanged());
1597 EXPECT_GT(encoder.GetBitrateKbps(), 0);
1598
1599 DestroyStreams();
1600}
1601
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001602TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07001603 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001604 public:
Peter Boström5811a392015-12-10 13:02:50 +01001605 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001606
nissed30a1112016-04-18 05:15:22 -07001607 void OnFrame(const VideoFrame& video_frame) override {
1608 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01001609 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001610 }
1611
1612 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01001613 const int kWaitFrameTimeoutMs = 3000;
1614 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001615 << "Timeout while waiting for output frames.";
1616 }
1617
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001618 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001619 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001620 }
1621
1622 private:
1623 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001624 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001625
1626 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01001627 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001628 };
1629
1630 // Initialize send stream.
skvlad11a9cbf2016-10-07 11:53:05 -07001631 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001632
solenberg4fbae2b2015-08-28 04:07:10 -07001633 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001634 CreateSendConfig(1, 0, &transport);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001635 FrameObserver observer;
stefanff483612015-12-21 03:14:00 -08001636 video_send_config_.pre_encode_callback = &observer;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001637 CreateVideoStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001638
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001639 // Prepare five input frames. Send ordinary VideoFrame and texture frames
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001640 // alternatively.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001641 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07001642 int width = 168;
1643 int height = 132;
1644
Peter Boströmeb66e802015-06-05 11:08:03 +02001645 test::FakeNativeHandle* handle1 = new test::FakeNativeHandle();
1646 test::FakeNativeHandle* handle2 = new test::FakeNativeHandle();
1647 test::FakeNativeHandle* handle3 = new test::FakeNativeHandle();
Peter Boström13f61df2016-01-04 22:36:38 +01001648 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001649 handle1, width, height, 1, 1, kVideoRotation_0));
Peter Boström13f61df2016-01-04 22:36:38 +01001650 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001651 handle2, width, height, 2, 2, kVideoRotation_0));
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001652 input_frames.push_back(CreateVideoFrame(width, height, 3));
1653 input_frames.push_back(CreateVideoFrame(width, height, 4));
Peter Boström13f61df2016-01-04 22:36:38 +01001654 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001655 handle3, width, height, 5, 5, kVideoRotation_0));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001656
stefanff483612015-12-21 03:14:00 -08001657 video_send_stream_->Start();
perkja49cbd32016-09-16 07:53:41 -07001658 test::FrameForwarder forwarder;
1659 video_send_stream_->SetSource(&forwarder);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001660 for (size_t i = 0; i < input_frames.size(); i++) {
perkja49cbd32016-09-16 07:53:41 -07001661 forwarder.IncomingCapturedFrame(input_frames[i]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001662 // Wait until the output frame is received before sending the next input
1663 // frame. Or the previous input frame may be replaced without delivering.
1664 observer.WaitOutputFrame();
1665 }
stefanff483612015-12-21 03:14:00 -08001666 video_send_stream_->Stop();
perkja49cbd32016-09-16 07:53:41 -07001667 video_send_stream_->SetSource(nullptr);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001668
1669 // Test if the input and output frames are the same. render_time_ms and
1670 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001671 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001672
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001673 DestroyStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001674}
1675
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001676void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
1677 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001678 EXPECT_EQ(frames1.size(), frames2.size());
1679 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07001680 // Compare frame buffers, since we don't care about differing timestamps.
1681 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
1682 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001683}
1684
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001685VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001686 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08001687 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001688 memset(buffer.get(), data, kSizeY);
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001689 VideoFrame frame;
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001690 frame.CreateFrame(buffer.get(), buffer.get(), buffer.get(), width, height,
Niels Möller739fcb92016-02-29 13:11:45 +01001691 width, width / 2, width / 2, kVideoRotation_0);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001692 frame.set_timestamp(data);
1693 frame.set_render_time_ms(data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001694 return frame;
1695}
1696
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001697TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
1698 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
1699 public:
1700 EncoderStateObserver()
1701 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001702 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001703 initialized_(false),
1704 callback_registered_(false),
1705 num_releases_(0),
1706 released_(false) {}
1707
1708 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001709 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001710 return released_;
1711 }
1712
1713 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001714 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001715 return initialized_ && callback_registered_;
1716 }
1717
1718 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001719 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001720 return num_releases_;
1721 }
1722
1723 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001724 int32_t InitEncode(const VideoCodec* codecSettings,
1725 int32_t numberOfCores,
1726 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001727 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001728 EXPECT_FALSE(initialized_);
1729 initialized_ = true;
1730 released_ = false;
1731 return 0;
1732 }
1733
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001734 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001735 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07001736 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001737 EXPECT_TRUE(IsReadyForEncode());
1738
Peter Boström5811a392015-12-10 13:02:50 +01001739 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001740 return 0;
1741 }
1742
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001743 int32_t RegisterEncodeCompleteCallback(
1744 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001745 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001746 EXPECT_TRUE(initialized_);
1747 callback_registered_ = true;
1748 return 0;
1749 }
1750
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001751 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001752 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001753 EXPECT_TRUE(IsReadyForEncode());
1754 EXPECT_FALSE(released_);
1755 initialized_ = false;
1756 callback_registered_ = false;
1757 released_ = true;
1758 ++num_releases_;
1759 return 0;
1760 }
1761
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001762 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001763 EXPECT_TRUE(IsReadyForEncode());
1764 return 0;
1765 }
1766
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001767 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001768 EXPECT_TRUE(IsReadyForEncode());
1769 return 0;
1770 }
1771
stefanff483612015-12-21 03:14:00 -08001772 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001773 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001774 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001775 stream_ = send_stream;
1776 }
1777
stefanff483612015-12-21 03:14:00 -08001778 void ModifyVideoConfigs(
1779 VideoSendStream::Config* send_config,
1780 std::vector<VideoReceiveStream::Config>* receive_configs,
1781 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001782 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07001783 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001784 }
1785
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001786 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001787 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
Per21d45d22016-10-30 21:37:57 +01001788 EXPECT_EQ(0u, num_releases());
perkj26091b12016-09-01 01:17:40 -07001789 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Per21d45d22016-10-30 21:37:57 +01001790 EXPECT_EQ(0u, num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001791 stream_->Stop();
1792 // Encoder should not be released before destroying the VideoSendStream.
1793 EXPECT_FALSE(IsReleased());
1794 EXPECT_TRUE(IsReadyForEncode());
1795 stream_->Start();
1796 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01001797 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001798 }
1799
Peter Boströmf2f82832015-05-01 13:00:41 +02001800 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001801 VideoSendStream* stream_;
1802 bool initialized_ GUARDED_BY(crit_);
1803 bool callback_registered_ GUARDED_BY(crit_);
1804 size_t num_releases_ GUARDED_BY(crit_);
1805 bool released_ GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001806 VideoEncoderConfig encoder_config_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001807 } test_encoder;
1808
stefane74eef12016-01-08 06:47:13 -08001809 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001810
1811 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01001812 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001813}
1814
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001815TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
1816 class VideoCodecConfigObserver : public test::SendTest,
1817 public test::FakeEncoder {
1818 public:
1819 VideoCodecConfigObserver()
1820 : SendTest(kDefaultTimeoutMs),
1821 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07001822 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02001823 num_initializations_(0),
1824 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001825
1826 private:
stefanff483612015-12-21 03:14:00 -08001827 void ModifyVideoConfigs(
1828 VideoSendStream::Config* send_config,
1829 std::vector<VideoReceiveStream::Config>* receive_configs,
1830 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001831 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07001832 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001833 }
1834
stefanff483612015-12-21 03:14:00 -08001835 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001836 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001837 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001838 stream_ = send_stream;
1839 }
1840
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001841 int32_t InitEncode(const VideoCodec* config,
1842 int32_t number_of_cores,
1843 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01001844 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001845 // Verify default values.
1846 EXPECT_EQ(kRealtimeVideo, config->mode);
1847 } else {
1848 // Verify that changed values are propagated.
1849 EXPECT_EQ(kScreensharing, config->mode);
1850 }
1851 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01001852 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001853 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1854 }
1855
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001856 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07001857 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01001858 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001859
Erik Språng143cec12015-04-28 10:01:41 +02001860 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
perkj26091b12016-09-01 01:17:40 -07001861 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07001862 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01001863 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001864 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
1865 "new encoder settings.";
1866 }
1867
pbos14fe7082016-04-20 06:35:56 -07001868 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001869 size_t num_initializations_;
1870 VideoSendStream* stream_;
1871 VideoEncoderConfig encoder_config_;
1872 } test;
1873
stefane74eef12016-01-08 06:47:13 -08001874 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001875}
1876
Peter Boström53eda3d2015-03-27 15:53:18 +01001877static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
1878template <typename T>
1879class VideoCodecConfigObserver : public test::SendTest,
1880 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01001881 public:
1882 VideoCodecConfigObserver(VideoCodecType video_codec_type,
1883 const char* codec_name)
1884 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
1885 FakeEncoder(Clock::GetRealTimeClock()),
1886 video_codec_type_(video_codec_type),
1887 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07001888 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02001889 num_initializations_(0),
1890 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01001891 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
1892 }
1893
1894 private:
perkjfa10b552016-10-02 23:45:26 -07001895 class VideoStreamFactory
1896 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1897 public:
1898 VideoStreamFactory() {}
1899
1900 private:
1901 std::vector<VideoStream> CreateEncoderStreams(
1902 int width,
1903 int height,
1904 const VideoEncoderConfig& encoder_config) override {
1905 std::vector<VideoStream> streams =
1906 test::CreateVideoStreams(width, height, encoder_config);
1907 for (size_t i = 0; i < streams.size(); ++i) {
1908 streams[i].temporal_layer_thresholds_bps.resize(
1909 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
1910 }
1911 return streams;
1912 }
1913 };
1914
stefanff483612015-12-21 03:14:00 -08001915 void ModifyVideoConfigs(
1916 VideoSendStream::Config* send_config,
1917 std::vector<VideoReceiveStream::Config>* receive_configs,
1918 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01001919 send_config->encoder_settings.encoder = this;
1920 send_config->encoder_settings.payload_name = codec_name_;
1921
kthelgason29a44e32016-09-27 03:52:02 -07001922 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07001923 encoder_config->video_stream_factory =
1924 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07001925 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01001926 }
1927
stefanff483612015-12-21 03:14:00 -08001928 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01001929 VideoSendStream* send_stream,
1930 const std::vector<VideoReceiveStream*>& receive_streams) override {
1931 stream_ = send_stream;
1932 }
1933
1934 int32_t InitEncode(const VideoCodec* config,
1935 int32_t number_of_cores,
1936 size_t max_payload_size) override {
1937 EXPECT_EQ(video_codec_type_, config->codecType);
1938 VerifyCodecSpecifics(*config);
1939 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01001940 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01001941 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1942 }
1943
1944 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07001945 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
1946 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01001947
1948 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07001949 EXPECT_TRUE(
1950 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01001951 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01001952
1953 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07001954 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07001955 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07001956 ASSERT_TRUE(
1957 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01001958 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01001959 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
1960 "new encoder settings.";
1961 }
1962
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001963 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01001964 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07001965 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01001966 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
1967 return 0;
1968 }
1969
1970 T encoder_settings_;
1971 const VideoCodecType video_codec_type_;
1972 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07001973 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01001974 size_t num_initializations_;
1975 VideoSendStream* stream_;
1976 VideoEncoderConfig encoder_config_;
1977};
1978
1979template <>
1980void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
1981 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07001982 EXPECT_EQ(
1983 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01001984}
kthelgason29a44e32016-09-27 03:52:02 -07001985
1986template <>
1987rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
1988VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
1989 return new rtc::RefCountedObject<
1990 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
1991}
1992
Peter Boström53eda3d2015-03-27 15:53:18 +01001993template <>
1994void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
1995 const VideoCodec& config) const {
1996 // Check that the number of temporal layers has propagated properly to
1997 // VideoCodec.
1998 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07001999 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002000
2001 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2002 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2003 config.simulcastStream[i].numberOfTemporalLayers);
2004 }
2005
2006 // Set expected temporal layers as they should have been set when
2007 // reconfiguring the encoder and not match the set config.
2008 VideoCodecVP8 encoder_settings = encoder_settings_;
2009 encoder_settings.numberOfTemporalLayers =
2010 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002011 EXPECT_EQ(
2012 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002013}
kthelgason29a44e32016-09-27 03:52:02 -07002014
2015template <>
2016rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2017VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2018 return new rtc::RefCountedObject<
2019 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2020}
2021
Peter Boström53eda3d2015-03-27 15:53:18 +01002022template <>
2023void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2024 const VideoCodec& config) const {
2025 // Check that the number of temporal layers has propagated properly to
2026 // VideoCodec.
2027 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002028 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002029
2030 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2031 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2032 config.simulcastStream[i].numberOfTemporalLayers);
2033 }
2034
2035 // Set expected temporal layers as they should have been set when
2036 // reconfiguring the encoder and not match the set config.
2037 VideoCodecVP9 encoder_settings = encoder_settings_;
2038 encoder_settings.numberOfTemporalLayers =
2039 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002040 EXPECT_EQ(
2041 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002042}
2043
kthelgason29a44e32016-09-27 03:52:02 -07002044template <>
2045rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2046VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2047 return new rtc::RefCountedObject<
2048 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2049}
2050
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002051TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002052 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002053 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002054}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002055
Peter Boström53eda3d2015-03-27 15:53:18 +01002056TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2057 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002058 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002059}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002060
Peter Boström53eda3d2015-03-27 15:53:18 +01002061TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2062 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002063 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002064}
2065
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002066TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002067 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002068 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002069 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2070 rtp_packets_sent_(0),
2071 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002072
2073 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002074 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002075 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002076 RTPHeader header;
2077 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002078 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002079 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2080 return SEND_PACKET;
2081 }
2082
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002083 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002084 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002085 RTCPUtility::RTCPParserV2 parser(packet, length, true);
2086 EXPECT_TRUE(parser.IsValid());
2087
2088 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
Erik Språng242e22b2015-05-11 10:17:43 +02002089 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
2090 if (packet_type == RTCPUtility::RTCPPacketTypes::kSr) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002091 // Only compare sent media bytes if SenderPacketCount matches the
2092 // number of sent rtp packets (a new rtp packet could be sent before
2093 // the rtcp packet).
2094 if (parser.Packet().SR.SenderOctetCount > 0 &&
2095 parser.Packet().SR.SenderPacketCount == rtp_packets_sent_) {
2096 EXPECT_EQ(media_bytes_sent_, parser.Packet().SR.SenderOctetCount);
Peter Boström5811a392015-12-10 13:02:50 +01002097 observation_complete_.Set();
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002098 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002099 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002100 packet_type = parser.Iterate();
2101 }
2102
2103 return SEND_PACKET;
2104 }
2105
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002106 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002107 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002108 }
2109
stefan4b569042015-11-11 06:39:57 -08002110 rtc::CriticalSection crit_;
2111 size_t rtp_packets_sent_ GUARDED_BY(&crit_);
2112 size_t media_bytes_sent_ GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002113 } test;
2114
stefane74eef12016-01-08 06:47:13 -08002115 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002116}
2117
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002118TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2119 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002120
2121 class VideoStreamFactory
2122 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2123 public:
2124 VideoStreamFactory() {}
2125
2126 private:
2127 std::vector<VideoStream> CreateEncoderStreams(
2128 int width,
2129 int height,
2130 const VideoEncoderConfig& encoder_config) override {
2131 std::vector<VideoStream> streams =
2132 test::CreateVideoStreams(width, height, encoder_config);
2133 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2134 streams[0].temporal_layer_thresholds_bps.push_back(
2135 kScreencastTargetBitrateKbps * 1000);
2136 return streams;
2137 }
2138 };
2139
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002140 class ScreencastTargetBitrateTest : public test::SendTest,
2141 public test::FakeEncoder {
2142 public:
2143 ScreencastTargetBitrateTest()
2144 : SendTest(kDefaultTimeoutMs),
2145 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2146
2147 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002148 int32_t InitEncode(const VideoCodec* config,
2149 int32_t number_of_cores,
2150 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002151 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2152 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002153 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002154 return test::FakeEncoder::InitEncode(
2155 config, number_of_cores, max_payload_size);
2156 }
stefanff483612015-12-21 03:14:00 -08002157 void ModifyVideoConfigs(
2158 VideoSendStream::Config* send_config,
2159 std::vector<VideoReceiveStream::Config>* receive_configs,
2160 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002161 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002162 EXPECT_EQ(1u, encoder_config->number_of_streams);
2163 encoder_config->video_stream_factory =
2164 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002165 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002166 }
2167
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002168 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002169 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002170 << "Timed out while waiting for the encoder to be initialized.";
2171 }
2172 } test;
2173
stefane74eef12016-01-08 06:47:13 -08002174 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002175}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002176
philipelc6957c72016-04-28 15:52:49 +02002177TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002178 // These are chosen to be "kind of odd" to not be accidentally checked against
2179 // default values.
2180 static const int kMinBitrateKbps = 137;
2181 static const int kStartBitrateKbps = 345;
2182 static const int kLowerMaxBitrateKbps = 312;
2183 static const int kMaxBitrateKbps = 413;
2184 static const int kIncreasedStartBitrateKbps = 451;
2185 static const int kIncreasedMaxBitrateKbps = 597;
2186 class EncoderBitrateThresholdObserver : public test::SendTest,
2187 public test::FakeEncoder {
2188 public:
2189 EncoderBitrateThresholdObserver()
2190 : SendTest(kDefaultTimeoutMs),
2191 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002192 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002193 bitrate_changed_event_(false, false),
2194 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002195 num_initializations_(0),
2196 call_(nullptr),
2197 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002198
2199 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002200 int32_t InitEncode(const VideoCodec* codecSettings,
2201 int32_t numberOfCores,
2202 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002203 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2204 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002205 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002206 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2207 codecSettings->minBitrate);
2208 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2209 codecSettings->startBitrate);
2210 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2211 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002212 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002213 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002214 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2215 codecSettings->maxBitrate);
2216 // The start bitrate should be kept (-1) and capped to the max bitrate.
2217 // Since this is not an end-to-end call no receiver should have been
2218 // returning a REMB that could lower this estimate.
2219 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002220 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002221 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2222 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002223 // The start bitrate will be whatever the rate BitRateController
2224 // has currently configured but in the span of the set max and min
2225 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002226 }
2227 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002228 init_encode_event_.Set();
2229
pbos@webrtc.org00873182014-11-25 14:03:34 +00002230 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2231 maxPayloadSize);
2232 }
2233
perkj26091b12016-09-01 01:17:40 -07002234 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
2235 {
2236 rtc::CritScope lock(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002237 if (target_bitrate_ == newBitRate) {
2238 return FakeEncoder::SetRates(newBitRate, frameRate);
2239 }
perkj26091b12016-09-01 01:17:40 -07002240 target_bitrate_ = newBitRate;
2241 }
2242 bitrate_changed_event_.Set();
2243 return FakeEncoder::SetRates(newBitRate, frameRate);
2244 }
2245
2246 void WaitForSetRates(uint32_t expected_bitrate) {
2247 EXPECT_TRUE(
2248 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2249 << "Timed out while waiting encoder rate to be set.";
2250 rtc::CritScope lock(&crit_);
2251 EXPECT_EQ(expected_bitrate, target_bitrate_);
2252 }
2253
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002254 Call::Config GetSenderCallConfig() override {
skvlad11a9cbf2016-10-07 11:53:05 -07002255 Call::Config config(&event_log_);
Stefan Holmere5904162015-03-26 11:11:06 +01002256 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2257 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2258 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002259 return config;
2260 }
2261
perkjfa10b552016-10-02 23:45:26 -07002262 class VideoStreamFactory
2263 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2264 public:
2265 explicit VideoStreamFactory(int min_bitrate_bps)
2266 : min_bitrate_bps_(min_bitrate_bps) {}
2267
2268 private:
2269 std::vector<VideoStream> CreateEncoderStreams(
2270 int width,
2271 int height,
2272 const VideoEncoderConfig& encoder_config) override {
2273 std::vector<VideoStream> streams =
2274 test::CreateVideoStreams(width, height, encoder_config);
2275 streams[0].min_bitrate_bps = min_bitrate_bps_;
2276 return streams;
2277 }
2278
2279 const int min_bitrate_bps_;
2280 };
2281
stefanff483612015-12-21 03:14:00 -08002282 void ModifyVideoConfigs(
2283 VideoSendStream::Config* send_config,
2284 std::vector<VideoReceiveStream::Config>* receive_configs,
2285 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002286 send_config->encoder_settings.encoder = this;
2287 // Set bitrates lower/higher than min/max to make sure they are properly
2288 // capped.
perkjfa10b552016-10-02 23:45:26 -07002289 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2290 // Create a new StreamFactory to be able to set
2291 // |VideoStream.min_bitrate_bps|.
2292 encoder_config->video_stream_factory =
2293 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002294 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002295 }
2296
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002297 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002298 call_ = sender_call;
2299 }
2300
stefanff483612015-12-21 03:14:00 -08002301 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002302 VideoSendStream* send_stream,
2303 const std::vector<VideoReceiveStream*>& receive_streams) override {
2304 send_stream_ = send_stream;
2305 }
2306
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002307 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002308 ASSERT_TRUE(
2309 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002310 << "Timed out while waiting for encoder to be configured.";
2311 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002312 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002313 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2314 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2315 call_->SetBitrateConfig(bitrate_config);
perkj26091b12016-09-01 01:17:40 -07002316 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2317 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002318 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002319 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002320 ASSERT_TRUE(
2321 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002322 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002323 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002324 WaitForSetRates(kLowerMaxBitrateKbps);
2325
2326 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2327 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2328 ASSERT_TRUE(
2329 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002330 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002331 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002332 // Expected target bitrate is the start bitrate set in the call to
2333 // call_->SetBitrateConfig.
2334 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002335 }
2336
pbos14fe7082016-04-20 06:35:56 -07002337 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002338 rtc::Event bitrate_changed_event_;
2339 rtc::CriticalSection crit_;
2340 uint32_t target_bitrate_ GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002341
pbos@webrtc.org00873182014-11-25 14:03:34 +00002342 int num_initializations_;
2343 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002344 webrtc::VideoSendStream* send_stream_;
2345 webrtc::VideoEncoderConfig encoder_config_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002346 } test;
2347
stefane74eef12016-01-08 06:47:13 -08002348 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002349}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002350
2351TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2352 static const size_t kNumStreams = 3;
2353 // Unusual resolutions to make sure that they are the ones being reported.
2354 static const struct {
2355 int width;
2356 int height;
2357 } kEncodedResolution[kNumStreams] = {
2358 {241, 181}, {300, 121}, {121, 221}};
2359 class ScreencastTargetBitrateTest : public test::SendTest,
2360 public test::FakeEncoder {
2361 public:
2362 ScreencastTargetBitrateTest()
2363 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002364 test::FakeEncoder(Clock::GetRealTimeClock()),
2365 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002366
2367 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002368 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002369 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002370 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002371 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002372 specifics.codecType = kVideoCodecGeneric;
2373
2374 uint8_t buffer[16] = {0};
2375 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2376 encoded._timeStamp = input_image.timestamp();
2377 encoded.capture_time_ms_ = input_image.render_time_ms();
2378
2379 for (size_t i = 0; i < kNumStreams; ++i) {
2380 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2381 encoded._frameType = (*frame_types)[i];
2382 encoded._encodedWidth = kEncodedResolution[i].width;
2383 encoded._encodedHeight = kEncodedResolution[i].height;
Peter Boström74f6e9e2016-04-04 17:56:10 +02002384 RTC_DCHECK(callback_);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00002385 if (callback_->Encoded(encoded, &specifics, nullptr) != 0)
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002386 return -1;
2387 }
2388
Peter Boström5811a392015-12-10 13:02:50 +01002389 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002390 return 0;
2391 }
stefanff483612015-12-21 03:14:00 -08002392 void ModifyVideoConfigs(
2393 VideoSendStream::Config* send_config,
2394 std::vector<VideoReceiveStream::Config>* receive_configs,
2395 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002396 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002397 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002398 }
2399
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002400 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002401
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002402 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002403 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002404 << "Timed out while waiting for the encoder to send one frame.";
2405 VideoSendStream::Stats stats = send_stream_->GetStats();
2406
2407 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002408 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002409 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002410 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002411 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002412 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002413 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002414 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2415 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002416 }
2417 }
2418
stefanff483612015-12-21 03:14:00 -08002419 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002420 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002421 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002422 send_stream_ = send_stream;
2423 }
2424
2425 VideoSendStream* send_stream_;
2426 } test;
2427
stefane74eef12016-01-08 06:47:13 -08002428 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002429}
philipel0f9af012015-09-01 07:01:51 -07002430
Peter Boström12996152016-05-14 02:03:18 +02002431#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002432class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002433 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002434 Vp9HeaderObserver()
2435 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002436 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002437 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2438 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002439 frames_sent_(0),
2440 expected_width_(0),
2441 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002442
stefanff483612015-12-21 03:14:00 -08002443 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002444 VideoSendStream::Config* send_config,
2445 std::vector<VideoReceiveStream::Config>* receive_configs,
2446 VideoEncoderConfig* encoder_config) {}
2447
Åsa Perssonff24c042015-12-04 10:58:08 +01002448 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002449
2450 private:
2451 const int kVp9PayloadType = 105;
2452
perkjfa10b552016-10-02 23:45:26 -07002453 class VideoStreamFactory
2454 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2455 public:
2456 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2457 : number_of_temporal_layers_(number_of_temporal_layers) {}
2458
2459 private:
2460 std::vector<VideoStream> CreateEncoderStreams(
2461 int width,
2462 int height,
2463 const VideoEncoderConfig& encoder_config) override {
2464 std::vector<VideoStream> streams =
2465 test::CreateVideoStreams(width, height, encoder_config);
2466 streams[0].temporal_layer_thresholds_bps.resize(
2467 number_of_temporal_layers_ - 1);
2468 return streams;
2469 }
2470
2471 const size_t number_of_temporal_layers_;
2472 };
2473
stefanff483612015-12-21 03:14:00 -08002474 void ModifyVideoConfigs(
2475 VideoSendStream::Config* send_config,
2476 std::vector<VideoReceiveStream::Config>* receive_configs,
2477 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002478 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002479 send_config->encoder_settings.payload_name = "VP9";
2480 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002481 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002482 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2483 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002484 EXPECT_EQ(1u, encoder_config->number_of_streams);
2485 encoder_config->video_stream_factory =
2486 new rtc::RefCountedObject<VideoStreamFactory>(
2487 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002488 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002489 }
2490
perkjfa10b552016-10-02 23:45:26 -07002491 void ModifyVideoCaptureStartResolution(int* width,
2492 int* height,
2493 int* frame_rate) override {
2494 expected_width_ = *width;
2495 expected_height_ = *height;
2496 }
2497
philipel0f9af012015-09-01 07:01:51 -07002498 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002499 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2500 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002501 }
2502
2503 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2504 RTPHeader header;
2505 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2506
Åsa Perssonff24c042015-12-04 10:58:08 +01002507 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2508 const uint8_t* payload = packet + header.headerLength;
2509 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002510
Åsa Perssonff24c042015-12-04 10:58:08 +01002511 bool new_packet = packets_sent_ == 0 ||
2512 IsNewerSequenceNumber(header.sequenceNumber,
2513 last_header_.sequenceNumber);
2514 if (payload_length > 0 && new_packet) {
2515 RtpDepacketizer::ParsedPayload parsed;
2516 RtpDepacketizerVp9 depacketizer;
2517 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2518 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2519 // Verify common fields for all configurations.
2520 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2521 CompareConsecutiveFrames(header, parsed.type.Video);
2522 // Verify configuration specific settings.
2523 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002524
Åsa Perssonff24c042015-12-04 10:58:08 +01002525 ++packets_sent_;
2526 if (header.markerBit) {
2527 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002528 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002529 last_header_ = header;
2530 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002531 }
philipel0f9af012015-09-01 07:01:51 -07002532 return SEND_PACKET;
2533 }
2534
philipel7fabd462015-09-03 04:42:32 -07002535 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01002536 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
2537 if (last_vp9_.picture_id > vp9.picture_id) {
2538 return vp9.picture_id == 0; // Wrap.
2539 } else {
2540 return vp9.picture_id == last_vp9_.picture_id + 1;
2541 }
2542 }
2543
2544 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01002545 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
2546 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
2547 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
2548 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
2549 vp9.spatial_idx);
2550 }
2551
2552 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
2553 uint8_t num_layers) const {
2554 switch (num_layers) {
2555 case 0:
2556 VerifyTemporalLayerStructure0(vp9);
2557 break;
2558 case 1:
2559 VerifyTemporalLayerStructure1(vp9);
2560 break;
2561 case 2:
2562 VerifyTemporalLayerStructure2(vp9);
2563 break;
2564 case 3:
2565 VerifyTemporalLayerStructure3(vp9);
2566 break;
2567 default:
2568 RTC_NOTREACHED();
2569 }
2570 }
2571
2572 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
2573 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
2574 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
2575 EXPECT_FALSE(vp9.temporal_up_switch);
2576 }
2577
2578 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
2579 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2580 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
2581 EXPECT_FALSE(vp9.temporal_up_switch);
2582 }
2583
2584 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
2585 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2586 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
2587 EXPECT_LE(vp9.temporal_idx, 1);
2588 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
2589 if (IsNewPictureId(vp9)) {
2590 uint8_t expected_tid =
2591 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
2592 EXPECT_EQ(expected_tid, vp9.temporal_idx);
2593 }
2594 }
2595
2596 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
2597 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2598 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
2599 EXPECT_LE(vp9.temporal_idx, 2);
2600 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
2601 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
2602 switch (vp9.temporal_idx) {
2603 case 0:
2604 EXPECT_EQ(2, last_vp9_.temporal_idx);
2605 EXPECT_FALSE(vp9.temporal_up_switch);
2606 break;
2607 case 1:
2608 EXPECT_EQ(2, last_vp9_.temporal_idx);
2609 EXPECT_TRUE(vp9.temporal_up_switch);
2610 break;
2611 case 2:
2612 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
2613 break;
2614 }
2615 }
2616 }
2617
2618 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
2619 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
2620 return;
2621
2622 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
2623 if (vp9.temporal_idx == 0)
2624 ++expected_tl0_idx;
2625 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
2626 }
2627
2628 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
2629 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
2630 }
2631
2632 // Flexible mode (F=1): Non-flexible mode (F=0):
2633 //
2634 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2635 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
2636 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2637 // I: |M| PICTURE ID | I: |M| PICTURE ID |
2638 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2639 // M: | EXTENDED PID | M: | EXTENDED PID |
2640 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2641 // L: | T |U| S |D| L: | T |U| S |D|
2642 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2643 // P,F: | P_DIFF |X|N| | TL0PICIDX |
2644 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2645 // X: |EXTENDED P_DIFF| V: | SS .. |
2646 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2647 // V: | SS .. |
2648 // +-+-+-+-+-+-+-+-+
2649 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
2650 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
2651 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
2652 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
2653 EXPECT_GE(vp9.spatial_idx, 0); // S
2654 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
2655 if (vp9.ss_data_available) // V
2656 VerifySsData(vp9);
2657
2658 if (frames_sent_ == 0)
2659 EXPECT_FALSE(vp9.inter_pic_predicted); // P
2660
2661 if (!vp9.inter_pic_predicted) {
2662 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
2663 EXPECT_FALSE(vp9.temporal_up_switch);
2664 }
2665 }
2666
2667 // Scalability structure (SS).
2668 //
2669 // +-+-+-+-+-+-+-+-+
2670 // V: | N_S |Y|G|-|-|-|
2671 // +-+-+-+-+-+-+-+-+
2672 // Y: | WIDTH | N_S + 1 times
2673 // +-+-+-+-+-+-+-+-+
2674 // | HEIGHT |
2675 // +-+-+-+-+-+-+-+-+
2676 // G: | N_G |
2677 // +-+-+-+-+-+-+-+-+
2678 // N_G: | T |U| R |-|-| N_G times
2679 // +-+-+-+-+-+-+-+-+
2680 // | P_DIFF | R times
2681 // +-+-+-+-+-+-+-+-+
2682 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
2683 EXPECT_TRUE(vp9.ss_data_available); // V
2684 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
2685 vp9.num_spatial_layers);
2686 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07002687 int expected_width = expected_width_;
2688 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02002689 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01002690 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
2691 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
2692 expected_width /= 2;
2693 expected_height /= 2;
2694 }
2695 }
2696
2697 void CompareConsecutiveFrames(const RTPHeader& header,
2698 const RTPVideoHeader& video) const {
2699 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
2700
2701 bool new_frame = packets_sent_ == 0 ||
2702 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
2703 EXPECT_EQ(new_frame, video.isFirstPacket);
2704 if (!new_frame) {
2705 EXPECT_FALSE(last_header_.markerBit);
2706 EXPECT_EQ(last_header_.timestamp, header.timestamp);
2707 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
2708 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
2709 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
2710 VerifySpatialIdxWithinFrame(vp9);
2711 return;
2712 }
2713 // New frame.
2714 EXPECT_TRUE(vp9.beginning_of_frame);
2715
2716 // Compare with last packet in previous frame.
2717 if (frames_sent_ == 0)
2718 return;
2719 EXPECT_TRUE(last_vp9_.end_of_frame);
2720 EXPECT_TRUE(last_header_.markerBit);
2721 EXPECT_TRUE(ContinuousPictureId(vp9));
2722 VerifyTl0Idx(vp9);
2723 }
2724
kwiberg27f982b2016-03-01 11:52:33 -08002725 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07002726 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01002727 webrtc::VideoEncoderConfig encoder_config_;
2728 RTPHeader last_header_;
2729 RTPVideoHeaderVP9 last_vp9_;
2730 size_t packets_sent_;
2731 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07002732 int expected_width_;
2733 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07002734};
2735
Åsa Perssonff24c042015-12-04 10:58:08 +01002736TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
2737 const uint8_t kNumTemporalLayers = 1;
2738 const uint8_t kNumSpatialLayers = 1;
2739 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2740}
2741
2742TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
2743 const uint8_t kNumTemporalLayers = 2;
2744 const uint8_t kNumSpatialLayers = 1;
2745 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2746}
2747
2748TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
2749 const uint8_t kNumTemporalLayers = 3;
2750 const uint8_t kNumSpatialLayers = 1;
2751 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2752}
2753
2754TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
2755 const uint8_t kNumTemporalLayers = 1;
2756 const uint8_t kNumSpatialLayers = 2;
2757 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2758}
2759
2760TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
2761 const uint8_t kNumTemporalLayers = 2;
2762 const uint8_t kNumSpatialLayers = 2;
2763 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2764}
2765
2766TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
2767 const uint8_t kNumTemporalLayers = 3;
2768 const uint8_t kNumSpatialLayers = 2;
2769 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2770}
2771
2772void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
2773 uint8_t num_spatial_layers) {
2774 static const size_t kNumFramesToSend = 100;
2775 // Set to < kNumFramesToSend and coprime to length of temporal layer
2776 // structures to verify temporal id reset on key frame.
2777 static const int kKeyFrameInterval = 31;
2778 class NonFlexibleMode : public Vp9HeaderObserver {
2779 public:
2780 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
2781 : num_temporal_layers_(num_temporal_layers),
2782 num_spatial_layers_(num_spatial_layers),
2783 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08002784 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002785 VideoSendStream::Config* send_config,
2786 std::vector<VideoReceiveStream::Config>* receive_configs,
2787 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01002788 vp9_settings_.flexibleMode = false;
2789 vp9_settings_.frameDroppingOn = false;
2790 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
2791 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
2792 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07002793 }
2794
Åsa Perssonff24c042015-12-04 10:58:08 +01002795 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
2796 bool ss_data_expected = !vp9.inter_pic_predicted &&
2797 vp9.beginning_of_frame && vp9.spatial_idx == 0;
2798 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
2799 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted); // D
asapersson38bb8ad2015-12-14 01:41:19 -08002800 EXPECT_EQ(!vp9.inter_pic_predicted,
2801 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01002802
2803 if (IsNewPictureId(vp9)) {
2804 EXPECT_EQ(0, vp9.spatial_idx);
2805 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
2806 }
2807
2808 VerifyFixedTemporalLayerStructure(vp9,
2809 l_field_ ? num_temporal_layers_ : 0);
2810
2811 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01002812 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07002813 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002814 const uint8_t num_temporal_layers_;
2815 const uint8_t num_spatial_layers_;
2816 const bool l_field_;
2817 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08002818
stefane74eef12016-01-08 06:47:13 -08002819 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08002820}
2821
asaperssond9f641e2016-01-21 01:11:35 -08002822TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
2823 static const size_t kNumFramesToSend = 50;
2824 static const int kWidth = 4;
2825 static const int kHeight = 4;
2826 class NonFlexibleModeResolution : public Vp9HeaderObserver {
2827 void ModifyVideoConfigsHook(
2828 VideoSendStream::Config* send_config,
2829 std::vector<VideoReceiveStream::Config>* receive_configs,
2830 VideoEncoderConfig* encoder_config) override {
2831 vp9_settings_.flexibleMode = false;
2832 vp9_settings_.numberOfTemporalLayers = 1;
2833 vp9_settings_.numberOfSpatialLayers = 1;
2834
perkjfa10b552016-10-02 23:45:26 -07002835 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08002836 }
2837
2838 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
2839 if (frames_sent_ > kNumFramesToSend)
2840 observation_complete_.Set();
2841 }
perkjfa10b552016-10-02 23:45:26 -07002842
2843 void ModifyVideoCaptureStartResolution(int* width,
2844 int* height,
2845 int* frame_rate) override {
2846 expected_width_ = kWidth;
2847 expected_height_ = kHeight;
2848 *width = kWidth;
2849 *height = kHeight;
2850 }
asaperssond9f641e2016-01-21 01:11:35 -08002851 } test;
2852
2853 RunBaseTest(&test);
2854}
2855
Åsa Perssonff24c042015-12-04 10:58:08 +01002856TEST_F(VideoSendStreamTest, Vp9FlexModeRefCount) {
2857 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08002858 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08002859 VideoSendStream::Config* send_config,
2860 std::vector<VideoReceiveStream::Config>* receive_configs,
2861 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01002862 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08002863 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01002864 vp9_settings_.numberOfTemporalLayers = 1;
2865 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08002866 }
2867
Åsa Perssonff24c042015-12-04 10:58:08 +01002868 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
2869 EXPECT_TRUE(vp9_header.flexible_mode);
2870 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
2871 if (vp9_header.inter_pic_predicted) {
2872 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01002873 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08002874 }
2875 }
2876 } test;
2877
stefane74eef12016-01-08 06:47:13 -08002878 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08002879}
Peter Boström12996152016-05-14 02:03:18 +02002880#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08002881
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00002882} // namespace webrtc