blob: c241c63245012eeda0eccb6f135b2b694dc14362 [file] [log] [blame]
Sebastian Janssone92f93f2017-06-22 14:44:04 +02001/*
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 */
Artem Titov46c4e602018-08-17 14:26:54 +020010
Steve Anton40d55332019-01-07 10:21:47 -080011#include "absl/memory/memory.h"
Artem Titov46c4e602018-08-17 14:26:54 +020012#include "api/test/simulated_network.h"
Danil Chapovalov99b71df2018-10-26 15:57:48 +020013#include "api/test/video/function_video_encoder_factory.h"
Artem Titov4e199e92018-08-20 13:30:39 +020014#include "call/fake_network_pipe.h"
15#include "call/simulated_network.h"
Steve Anton10542f22019-01-11 09:11:00 -080016#include "media/engine/internal_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "media/engine/simulcast_encoder_adapter.h"
18#include "modules/rtp_rtcp/source/rtp_format.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020019#include "modules/video_coding/codecs/vp8/include/vp8.h"
Åsa Perssonad3c7a42017-11-29 10:24:27 +010020#include "modules/video_coding/codecs/vp9/include/vp9.h"
Oleh Prypina40f8242017-12-21 13:32:23 +010021#include "rtc_base/numerics/safe_conversions.h"
Bjorn Tereliusa194e582017-10-25 13:07:09 +020022#include "rtc_base/numerics/sequence_number_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "test/call_test.h"
Sebastian Janssone92f93f2017-06-22 14:44:04 +020024
25namespace webrtc {
Åsa Persson4bece9a2017-10-06 10:04:04 +020026namespace {
Sebastian Janssone92f93f2017-06-22 14:44:04 +020027const int kFrameMaxWidth = 1280;
28const int kFrameMaxHeight = 720;
29const int kFrameRate = 30;
30const int kMaxSecondsLost = 5;
31const int kMaxFramesLost = kFrameRate * kMaxSecondsLost;
32const int kMinPacketsToObserve = 10;
Åsa Persson6a1b7ad2017-12-11 12:30:55 +010033const int kEncoderBitrateBps = 300000;
Sebastian Janssone92f93f2017-06-22 14:44:04 +020034const uint32_t kPictureIdWraparound = (1 << 15);
Åsa Persson71485ac2017-12-04 11:11:19 +010035const size_t kNumTemporalLayers[] = {1, 2, 3};
Sebastian Janssone92f93f2017-06-22 14:44:04 +020036
Åsa Persson4bece9a2017-10-06 10:04:04 +020037} // namespace
38
Sebastian Janssone92f93f2017-06-22 14:44:04 +020039class PictureIdObserver : public test::RtpRtcpObserver {
40 public:
Niels Möller520ca4e2018-06-04 11:14:38 +020041 explicit PictureIdObserver(VideoCodecType codec_type)
Sebastian Janssone92f93f2017-06-22 14:44:04 +020042 : test::RtpRtcpObserver(test::CallTest::kDefaultTimeoutMs),
Åsa Perssonad3c7a42017-11-29 10:24:27 +010043 codec_type_(codec_type),
Sebastian Janssone92f93f2017-06-22 14:44:04 +020044 max_expected_picture_id_gap_(0),
Åsa Persson71485ac2017-12-04 11:11:19 +010045 max_expected_tl0_idx_gap_(0),
Sebastian Janssone92f93f2017-06-22 14:44:04 +020046 num_ssrcs_to_observe_(1) {}
47
48 void SetExpectedSsrcs(size_t num_expected_ssrcs) {
49 rtc::CritScope lock(&crit_);
50 num_ssrcs_to_observe_ = num_expected_ssrcs;
51 }
52
53 void ResetObservedSsrcs() {
54 rtc::CritScope lock(&crit_);
55 // Do not clear the timestamp and picture_id, to ensure that we check
56 // consistency between reinits and recreations.
57 num_packets_sent_.clear();
58 observed_ssrcs_.clear();
59 }
60
61 void SetMaxExpectedPictureIdGap(int max_expected_picture_id_gap) {
62 rtc::CritScope lock(&crit_);
63 max_expected_picture_id_gap_ = max_expected_picture_id_gap;
Åsa Persson71485ac2017-12-04 11:11:19 +010064 // Expect smaller gap for |tl0_pic_idx| (running index for temporal_idx 0).
65 max_expected_tl0_idx_gap_ = max_expected_picture_id_gap_ / 2;
Sebastian Janssone92f93f2017-06-22 14:44:04 +020066 }
67
68 private:
Åsa Perssonad3c7a42017-11-29 10:24:27 +010069 struct ParsedPacket {
70 uint32_t timestamp;
71 uint32_t ssrc;
Åsa Persson71485ac2017-12-04 11:11:19 +010072 int16_t picture_id;
73 int16_t tl0_pic_idx;
74 uint8_t temporal_idx;
Niels Möller87e2d782019-03-07 10:18:23 +010075 VideoFrameType frame_type;
Åsa Perssonad3c7a42017-11-29 10:24:27 +010076 };
77
78 bool ParsePayload(const uint8_t* packet,
79 size_t length,
Åsa Persson71485ac2017-12-04 11:11:19 +010080 ParsedPacket* parsed) const {
Åsa Perssonad3c7a42017-11-29 10:24:27 +010081 RTPHeader header;
82 EXPECT_TRUE(parser_->Parse(packet, length, &header));
83 EXPECT_TRUE(header.ssrc == test::CallTest::kVideoSendSsrcs[0] ||
84 header.ssrc == test::CallTest::kVideoSendSsrcs[1] ||
85 header.ssrc == test::CallTest::kVideoSendSsrcs[2])
86 << "Unknown SSRC sent.";
87
88 EXPECT_GE(length, header.headerLength + header.paddingLength);
89 size_t payload_length = length - header.headerLength - header.paddingLength;
90 if (payload_length == 0) {
91 return false; // Padding packet.
92 }
93
Åsa Perssonad3c7a42017-11-29 10:24:27 +010094 parsed->timestamp = header.timestamp;
Åsa Persson71485ac2017-12-04 11:11:19 +010095 parsed->ssrc = header.ssrc;
Åsa Perssonad3c7a42017-11-29 10:24:27 +010096
97 std::unique_ptr<RtpDepacketizer> depacketizer(
98 RtpDepacketizer::Create(codec_type_));
99 RtpDepacketizer::ParsedPayload parsed_payload;
100 EXPECT_TRUE(depacketizer->Parse(
101 &parsed_payload, &packet[header.headerLength], payload_length));
102
103 switch (codec_type_) {
Philip Eliassond52a1a62018-09-07 13:03:55 +0000104 case kVideoCodecVP8: {
105 const auto& vp8_header = absl::get<RTPVideoHeaderVP8>(
106 parsed_payload.video_header().video_type_header);
107 parsed->picture_id = vp8_header.pictureId;
108 parsed->tl0_pic_idx = vp8_header.tl0PicIdx;
109 parsed->temporal_idx = vp8_header.temporalIdx;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100110 break;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000111 }
philipel29d88462018-08-08 14:26:00 +0200112 case kVideoCodecVP9: {
113 const auto& vp9_header = absl::get<RTPVideoHeaderVP9>(
114 parsed_payload.video_header().video_type_header);
115 parsed->picture_id = vp9_header.picture_id;
116 parsed->tl0_pic_idx = vp9_header.tl0_pic_idx;
117 parsed->temporal_idx = vp9_header.temporal_idx;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100118 break;
philipel29d88462018-08-08 14:26:00 +0200119 }
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100120 default:
121 RTC_NOTREACHED();
122 break;
123 }
124
125 parsed->frame_type = parsed_payload.frame_type;
126 return true;
127 }
128
Åsa Persson71485ac2017-12-04 11:11:19 +0100129 // Verify continuity and monotonicity of picture_id sequence.
130 void VerifyPictureId(const ParsedPacket& current,
131 const ParsedPacket& last) const
132 RTC_EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
133 if (current.timestamp == last.timestamp) {
134 EXPECT_EQ(last.picture_id, current.picture_id);
135 return; // Same frame.
136 }
137
138 // Packet belongs to a new frame.
139 // Picture id should be increasing.
140 EXPECT_TRUE((AheadOf<uint16_t, kPictureIdWraparound>(current.picture_id,
141 last.picture_id)));
142
143 // Expect continuously increasing picture id.
144 int diff = ForwardDiff<uint16_t, kPictureIdWraparound>(last.picture_id,
145 current.picture_id);
146 if (diff > 1) {
147 // If the VideoSendStream is destroyed, any frames still in queue is lost.
148 // Gaps only possible for first frame after a recreation, i.e. key frames.
Niels Möller8f7ce222019-03-21 15:43:58 +0100149 EXPECT_EQ(VideoFrameType::kVideoFrameKey, current.frame_type);
Åsa Persson71485ac2017-12-04 11:11:19 +0100150 EXPECT_LE(diff - 1, max_expected_picture_id_gap_);
151 }
152 }
153
154 void VerifyTl0Idx(const ParsedPacket& current, const ParsedPacket& last) const
155 RTC_EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
156 if (current.tl0_pic_idx == kNoTl0PicIdx ||
157 current.temporal_idx == kNoTemporalIdx) {
158 return; // No temporal layers.
159 }
160
161 if (current.timestamp == last.timestamp || current.temporal_idx != 0) {
162 EXPECT_EQ(last.tl0_pic_idx, current.tl0_pic_idx);
163 return;
164 }
165
166 // New frame with |temporal_idx| 0.
167 // |tl0_pic_idx| should be increasing.
168 EXPECT_TRUE(AheadOf<uint8_t>(current.tl0_pic_idx, last.tl0_pic_idx));
169
170 // Expect continuously increasing idx.
171 int diff = ForwardDiff<uint8_t>(last.tl0_pic_idx, current.tl0_pic_idx);
172 if (diff > 1) {
173 // If the VideoSendStream is destroyed, any frames still in queue is lost.
174 // Gaps only possible for first frame after a recreation, i.e. key frames.
Niels Möller8f7ce222019-03-21 15:43:58 +0100175 EXPECT_EQ(VideoFrameType::kVideoFrameKey, current.frame_type);
Åsa Persson71485ac2017-12-04 11:11:19 +0100176 EXPECT_LE(diff - 1, max_expected_tl0_idx_gap_);
177 }
178 }
179
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200180 Action OnSendRtp(const uint8_t* packet, size_t length) override {
181 rtc::CritScope lock(&crit_);
182
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100183 ParsedPacket parsed;
Åsa Persson71485ac2017-12-04 11:11:19 +0100184 if (!ParsePayload(packet, length, &parsed))
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200185 return SEND_PACKET;
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200186
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100187 uint32_t ssrc = parsed.ssrc;
188 if (last_observed_packet_.find(ssrc) != last_observed_packet_.end()) {
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100189 // Compare to last packet.
Åsa Persson71485ac2017-12-04 11:11:19 +0100190 VerifyPictureId(parsed, last_observed_packet_[ssrc]);
191 VerifyTl0Idx(parsed, last_observed_packet_[ssrc]);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200192 }
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200193
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100194 last_observed_packet_[ssrc] = parsed;
195
196 // Pass the test when enough media packets have been received on all
197 // streams.
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200198 if (++num_packets_sent_[ssrc] >= kMinPacketsToObserve &&
199 observed_ssrcs_.find(ssrc) == observed_ssrcs_.end()) {
200 observed_ssrcs_.insert(ssrc);
201 if (observed_ssrcs_.size() == num_ssrcs_to_observe_) {
202 observation_complete_.Set();
203 }
204 }
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200205 return SEND_PACKET;
206 }
207
208 rtc::CriticalSection crit_;
Niels Möller520ca4e2018-06-04 11:14:38 +0200209 const VideoCodecType codec_type_;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100210 std::map<uint32_t, ParsedPacket> last_observed_packet_ RTC_GUARDED_BY(crit_);
danilchapa37de392017-09-09 04:17:22 -0700211 std::map<uint32_t, size_t> num_packets_sent_ RTC_GUARDED_BY(crit_);
212 int max_expected_picture_id_gap_ RTC_GUARDED_BY(crit_);
Åsa Persson71485ac2017-12-04 11:11:19 +0100213 int max_expected_tl0_idx_gap_ RTC_GUARDED_BY(crit_);
danilchapa37de392017-09-09 04:17:22 -0700214 size_t num_ssrcs_to_observe_ RTC_GUARDED_BY(crit_);
215 std::set<uint32_t> observed_ssrcs_ RTC_GUARDED_BY(crit_);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200216};
217
Åsa Persson4bece9a2017-10-06 10:04:04 +0200218class PictureIdTest : public test::CallTest,
Åsa Persson677f42c2018-03-16 13:09:17 +0100219 public ::testing::WithParamInterface<size_t> {
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200220 public:
Åsa Persson677f42c2018-03-16 13:09:17 +0100221 PictureIdTest() : num_temporal_layers_(GetParam()) {}
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200222
223 virtual ~PictureIdTest() {
eladalon413ee9a2017-08-22 04:02:52 -0700224 task_queue_.SendTask([this]() {
eladalon413ee9a2017-08-22 04:02:52 -0700225 send_transport_.reset();
226 receive_transport_.reset();
227 DestroyCalls();
228 });
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200229 }
230
Niels Möller4db138e2018-04-19 09:04:13 +0200231 void SetupEncoder(VideoEncoderFactory* encoder_factory,
232 const std::string& payload_name);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200233 void TestPictureIdContinuousAfterReconfigure(
234 const std::vector<int>& ssrc_counts);
235 void TestPictureIdIncreaseAfterRecreateStreams(
236 const std::vector<int>& ssrc_counts);
237
238 private:
Åsa Persson71485ac2017-12-04 11:11:19 +0100239 const size_t num_temporal_layers_;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100240 std::unique_ptr<PictureIdObserver> observer_;
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200241};
242
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100243INSTANTIATE_TEST_SUITE_P(TemporalLayers,
244 PictureIdTest,
245 ::testing::ValuesIn(kNumTemporalLayers));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200246
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200247// Use a special stream factory to ensure that all simulcast streams are being
248// sent.
249class VideoStreamFactory
250 : public VideoEncoderConfig::VideoStreamFactoryInterface {
251 public:
Åsa Persson71485ac2017-12-04 11:11:19 +0100252 explicit VideoStreamFactory(size_t num_temporal_layers)
253 : num_of_temporal_layers_(num_temporal_layers) {}
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200254
255 private:
256 std::vector<VideoStream> CreateEncoderStreams(
257 int width,
258 int height,
259 const VideoEncoderConfig& encoder_config) override {
260 std::vector<VideoStream> streams =
261 test::CreateVideoStreams(width, height, encoder_config);
262
Erik Språng482b3ef2019-01-08 16:19:11 +0100263 // Always divide the same total bitrate across all streams so that sending a
264 // single stream avoids lowering the bitrate estimate and requiring a
Erik Språngc12d41b2019-01-09 09:55:31 +0100265 // subsequent rampup.
266 const int encoder_stream_bps =
267 kEncoderBitrateBps /
268 rtc::checked_cast<int>(encoder_config.number_of_streams);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200269
Åsa Persson6a1b7ad2017-12-11 12:30:55 +0100270 for (size_t i = 0; i < encoder_config.number_of_streams; ++i) {
Erik Språngc12d41b2019-01-09 09:55:31 +0100271 // Reduce the min bitrate by 10% to account for overhead that might
272 // otherwise cause streams to not be enabled.
273 streams[i].min_bitrate_bps = static_cast<int>(encoder_stream_bps * 0.9);
Åsa Persson6a1b7ad2017-12-11 12:30:55 +0100274 streams[i].target_bitrate_bps = encoder_stream_bps;
275 streams[i].max_bitrate_bps = encoder_stream_bps;
Sergey Silkina796a7e2018-03-01 15:11:29 +0100276 streams[i].num_temporal_layers = num_of_temporal_layers_;
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200277 // test::CreateVideoStreams does not return frame sizes for the lower
278 // streams that are accepted by VP8Impl::InitEncode.
279 // TODO(brandtr): Fix the problem in test::CreateVideoStreams, rather
280 // than overriding the values here.
Åsa Persson6a1b7ad2017-12-11 12:30:55 +0100281 streams[i].width =
282 width / (1 << (encoder_config.number_of_streams - 1 - i));
283 streams[i].height =
284 height / (1 << (encoder_config.number_of_streams - 1 - i));
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200285 }
286
287 return streams;
288 }
Åsa Persson71485ac2017-12-04 11:11:19 +0100289
290 const size_t num_of_temporal_layers_;
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200291};
292
Niels Möller4db138e2018-04-19 09:04:13 +0200293void PictureIdTest::SetupEncoder(VideoEncoderFactory* encoder_factory,
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100294 const std::string& payload_name) {
295 observer_.reset(
Niels Möller520ca4e2018-06-04 11:14:38 +0200296 new PictureIdObserver(PayloadStringToCodecType(payload_name)));
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100297
Niels Möller4db138e2018-04-19 09:04:13 +0200298 task_queue_.SendTask([this, encoder_factory, payload_name]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200299 CreateCalls();
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200300
eladalon413ee9a2017-08-22 04:02:52 -0700301 send_transport_.reset(new test::PacketTransport(
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100302 &task_queue_, sender_call_.get(), observer_.get(),
eladalon413ee9a2017-08-22 04:02:52 -0700303 test::PacketTransport::kSender, payload_type_map_,
Artem Titov4e199e92018-08-20 13:30:39 +0200304 absl::make_unique<FakeNetworkPipe>(
305 Clock::GetRealTimeClock(), absl::make_unique<SimulatedNetwork>(
Artem Titov75e36472018-10-08 12:28:56 +0200306 BuiltInNetworkBehaviorConfig()))));
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200307
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100308 CreateSendConfig(kNumSimulcastStreams, 0, 0, send_transport_.get());
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200309 GetVideoSendConfig()->encoder_settings.encoder_factory = encoder_factory;
310 GetVideoSendConfig()->rtp.payload_name = payload_name;
311 GetVideoEncoderConfig()->codec_type =
312 PayloadStringToCodecType(payload_name);
313 GetVideoEncoderConfig()->video_stream_factory =
Åsa Persson71485ac2017-12-04 11:11:19 +0100314 new rtc::RefCountedObject<VideoStreamFactory>(num_temporal_layers_);
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200315 GetVideoEncoderConfig()->number_of_streams = 1;
eladalon413ee9a2017-08-22 04:02:52 -0700316 });
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200317}
318
319void PictureIdTest::TestPictureIdContinuousAfterReconfigure(
320 const std::vector<int>& ssrc_counts) {
eladalon413ee9a2017-08-22 04:02:52 -0700321 task_queue_.SendTask([this]() {
322 CreateVideoStreams();
323 CreateFrameGeneratorCapturer(kFrameRate, kFrameMaxWidth, kFrameMaxHeight);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200324
eladalon413ee9a2017-08-22 04:02:52 -0700325 // Initial test with a single stream.
326 Start();
327 });
328
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100329 EXPECT_TRUE(observer_->Wait()) << "Timed out waiting for packets.";
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200330
331 // Reconfigure VideoEncoder and test picture id increase.
Åsa Perssonae819752017-10-10 11:05:59 +0200332 // Expect continuously increasing picture id, equivalent to no gaps.
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100333 observer_->SetMaxExpectedPictureIdGap(0);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200334 for (int ssrc_count : ssrc_counts) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200335 GetVideoEncoderConfig()->number_of_streams = ssrc_count;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100336 observer_->SetExpectedSsrcs(ssrc_count);
337 observer_->ResetObservedSsrcs();
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200338 // Make sure the picture_id sequence is continuous on reinit and recreate.
eladalon413ee9a2017-08-22 04:02:52 -0700339 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200340 GetVideoSendStream()->ReconfigureVideoEncoder(
341 GetVideoEncoderConfig()->Copy());
eladalon413ee9a2017-08-22 04:02:52 -0700342 });
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100343 EXPECT_TRUE(observer_->Wait()) << "Timed out waiting for packets.";
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200344 }
345
eladalon413ee9a2017-08-22 04:02:52 -0700346 task_queue_.SendTask([this]() {
347 Stop();
348 DestroyStreams();
eladalon413ee9a2017-08-22 04:02:52 -0700349 });
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200350}
351
352void PictureIdTest::TestPictureIdIncreaseAfterRecreateStreams(
353 const std::vector<int>& ssrc_counts) {
eladalon413ee9a2017-08-22 04:02:52 -0700354 task_queue_.SendTask([this]() {
355 CreateVideoStreams();
356 CreateFrameGeneratorCapturer(kFrameRate, kFrameMaxWidth, kFrameMaxHeight);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200357
eladalon413ee9a2017-08-22 04:02:52 -0700358 // Initial test with a single stream.
359 Start();
360 });
361
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100362 EXPECT_TRUE(observer_->Wait()) << "Timed out waiting for packets.";
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200363
364 // Recreate VideoSendStream and test picture id increase.
365 // When the VideoSendStream is destroyed, any frames still in queue is lost
366 // with it, therefore it is expected that some frames might be lost.
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100367 observer_->SetMaxExpectedPictureIdGap(kMaxFramesLost);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200368 for (int ssrc_count : ssrc_counts) {
eladalon413ee9a2017-08-22 04:02:52 -0700369 task_queue_.SendTask([this, &ssrc_count]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200370 DestroyVideoSendStreams();
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200371
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200372 GetVideoEncoderConfig()->number_of_streams = ssrc_count;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100373 observer_->SetExpectedSsrcs(ssrc_count);
374 observer_->ResetObservedSsrcs();
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200375
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200376 CreateVideoSendStreams();
377 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700378 CreateFrameGeneratorCapturer(kFrameRate, kFrameMaxWidth, kFrameMaxHeight);
eladalon413ee9a2017-08-22 04:02:52 -0700379 });
380
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100381 EXPECT_TRUE(observer_->Wait()) << "Timed out waiting for packets.";
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200382 }
383
eladalon413ee9a2017-08-22 04:02:52 -0700384 task_queue_.SendTask([this]() {
385 Stop();
386 DestroyStreams();
eladalon413ee9a2017-08-22 04:02:52 -0700387 });
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200388}
389
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100390TEST_P(PictureIdTest, ContinuousAfterReconfigureVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200391 test::FunctionVideoEncoderFactory encoder_factory(
392 []() { return VP8Encoder::Create(); });
393 SetupEncoder(&encoder_factory, "VP8");
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200394 TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1});
395}
396
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100397TEST_P(PictureIdTest, IncreasingAfterRecreateStreamVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200398 test::FunctionVideoEncoderFactory encoder_factory(
399 []() { return VP8Encoder::Create(); });
400 SetupEncoder(&encoder_factory, "VP8");
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200401 TestPictureIdIncreaseAfterRecreateStreams({1, 3, 3, 1, 1});
402}
403
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100404TEST_P(PictureIdTest, ContinuousAfterStreamCountChangeVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200405 test::FunctionVideoEncoderFactory encoder_factory(
406 []() { return VP8Encoder::Create(); });
Åsa Persson71485ac2017-12-04 11:11:19 +0100407 // Make sure that the picture id is not reset if the stream count goes
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200408 // down and then up.
Niels Möller4db138e2018-04-19 09:04:13 +0200409 SetupEncoder(&encoder_factory, "VP8");
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100410 TestPictureIdContinuousAfterReconfigure({3, 1, 3});
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200411}
412
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100413TEST_P(PictureIdTest, ContinuousAfterReconfigureSimulcastEncoderAdapter) {
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100414 InternalEncoderFactory internal_encoder_factory;
Niels Möller4db138e2018-04-19 09:04:13 +0200415 test::FunctionVideoEncoderFactory encoder_factory(
416 [&internal_encoder_factory]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200417 return absl::make_unique<SimulcastEncoderAdapter>(
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200418 &internal_encoder_factory, SdpVideoFormat("VP8"));
Niels Möller4db138e2018-04-19 09:04:13 +0200419 });
420 SetupEncoder(&encoder_factory, "VP8");
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200421 TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1});
422}
423
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100424TEST_P(PictureIdTest, IncreasingAfterRecreateStreamSimulcastEncoderAdapter) {
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100425 InternalEncoderFactory internal_encoder_factory;
Niels Möller4db138e2018-04-19 09:04:13 +0200426 test::FunctionVideoEncoderFactory encoder_factory(
427 [&internal_encoder_factory]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200428 return absl::make_unique<SimulcastEncoderAdapter>(
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200429 &internal_encoder_factory, SdpVideoFormat("VP8"));
Niels Möller4db138e2018-04-19 09:04:13 +0200430 });
431 SetupEncoder(&encoder_factory, "VP8");
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200432 TestPictureIdIncreaseAfterRecreateStreams({1, 3, 3, 1, 1});
433}
434
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100435TEST_P(PictureIdTest, ContinuousAfterStreamCountChangeSimulcastEncoderAdapter) {
Åsa Persson677f42c2018-03-16 13:09:17 +0100436 InternalEncoderFactory internal_encoder_factory;
Niels Möller4db138e2018-04-19 09:04:13 +0200437 test::FunctionVideoEncoderFactory encoder_factory(
438 [&internal_encoder_factory]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200439 return absl::make_unique<SimulcastEncoderAdapter>(
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200440 &internal_encoder_factory, SdpVideoFormat("VP8"));
Niels Möller4db138e2018-04-19 09:04:13 +0200441 });
Åsa Persson677f42c2018-03-16 13:09:17 +0100442 // Make sure that the picture id is not reset if the stream count goes
443 // down and then up.
Niels Möller4db138e2018-04-19 09:04:13 +0200444 SetupEncoder(&encoder_factory, "VP8");
Åsa Persson677f42c2018-03-16 13:09:17 +0100445 TestPictureIdContinuousAfterReconfigure({3, 1, 3});
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200446}
447
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100448TEST_P(PictureIdTest, IncreasingAfterRecreateStreamVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200449 test::FunctionVideoEncoderFactory encoder_factory(
450 []() { return VP9Encoder::Create(); });
451 SetupEncoder(&encoder_factory, "VP9");
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100452 TestPictureIdIncreaseAfterRecreateStreams({1, 1});
453}
454
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200455} // namespace webrtc