blob: 3c43d7d1122fbdb73cf05128adb12457c614e717 [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 */
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020010#include "media/engine/internalencoderfactory.h"
11#include "media/engine/simulcast_encoder_adapter.h"
12#include "modules/rtp_rtcp/source/rtp_format.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020013#include "modules/video_coding/codecs/vp8/include/vp8.h"
Åsa Perssonad3c7a42017-11-29 10:24:27 +010014#include "modules/video_coding/codecs/vp9/include/vp9.h"
Oleh Prypina40f8242017-12-21 13:32:23 +010015#include "rtc_base/numerics/safe_conversions.h"
Bjorn Tereliusa194e582017-10-25 13:07:09 +020016#include "rtc_base/numerics/sequence_number_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "test/call_test.h"
Niels Möller4db138e2018-04-19 09:04:13 +020018#include "test/function_video_encoder_factory.h"
Sebastian Janssone92f93f2017-06-22 14:44:04 +020019
20namespace webrtc {
Åsa Persson4bece9a2017-10-06 10:04:04 +020021namespace {
Sebastian Janssone92f93f2017-06-22 14:44:04 +020022const int kFrameMaxWidth = 1280;
23const int kFrameMaxHeight = 720;
24const int kFrameRate = 30;
25const int kMaxSecondsLost = 5;
26const int kMaxFramesLost = kFrameRate * kMaxSecondsLost;
27const int kMinPacketsToObserve = 10;
Åsa Persson6a1b7ad2017-12-11 12:30:55 +010028const int kEncoderBitrateBps = 300000;
Sebastian Janssone92f93f2017-06-22 14:44:04 +020029const uint32_t kPictureIdWraparound = (1 << 15);
Åsa Persson71485ac2017-12-04 11:11:19 +010030const size_t kNumTemporalLayers[] = {1, 2, 3};
Sebastian Janssone92f93f2017-06-22 14:44:04 +020031
Åsa Persson4bece9a2017-10-06 10:04:04 +020032} // namespace
33
Sebastian Janssone92f93f2017-06-22 14:44:04 +020034class PictureIdObserver : public test::RtpRtcpObserver {
35 public:
Niels Möller520ca4e2018-06-04 11:14:38 +020036 explicit PictureIdObserver(VideoCodecType codec_type)
Sebastian Janssone92f93f2017-06-22 14:44:04 +020037 : test::RtpRtcpObserver(test::CallTest::kDefaultTimeoutMs),
Åsa Perssonad3c7a42017-11-29 10:24:27 +010038 codec_type_(codec_type),
Sebastian Janssone92f93f2017-06-22 14:44:04 +020039 max_expected_picture_id_gap_(0),
Åsa Persson71485ac2017-12-04 11:11:19 +010040 max_expected_tl0_idx_gap_(0),
Sebastian Janssone92f93f2017-06-22 14:44:04 +020041 num_ssrcs_to_observe_(1) {}
42
43 void SetExpectedSsrcs(size_t num_expected_ssrcs) {
44 rtc::CritScope lock(&crit_);
45 num_ssrcs_to_observe_ = num_expected_ssrcs;
46 }
47
48 void ResetObservedSsrcs() {
49 rtc::CritScope lock(&crit_);
50 // Do not clear the timestamp and picture_id, to ensure that we check
51 // consistency between reinits and recreations.
52 num_packets_sent_.clear();
53 observed_ssrcs_.clear();
54 }
55
56 void SetMaxExpectedPictureIdGap(int max_expected_picture_id_gap) {
57 rtc::CritScope lock(&crit_);
58 max_expected_picture_id_gap_ = max_expected_picture_id_gap;
Åsa Persson71485ac2017-12-04 11:11:19 +010059 // Expect smaller gap for |tl0_pic_idx| (running index for temporal_idx 0).
60 max_expected_tl0_idx_gap_ = max_expected_picture_id_gap_ / 2;
Sebastian Janssone92f93f2017-06-22 14:44:04 +020061 }
62
63 private:
Åsa Perssonad3c7a42017-11-29 10:24:27 +010064 struct ParsedPacket {
65 uint32_t timestamp;
66 uint32_t ssrc;
Åsa Persson71485ac2017-12-04 11:11:19 +010067 int16_t picture_id;
68 int16_t tl0_pic_idx;
69 uint8_t temporal_idx;
Åsa Perssonad3c7a42017-11-29 10:24:27 +010070 FrameType frame_type;
71 };
72
73 bool ParsePayload(const uint8_t* packet,
74 size_t length,
Åsa Persson71485ac2017-12-04 11:11:19 +010075 ParsedPacket* parsed) const {
Åsa Perssonad3c7a42017-11-29 10:24:27 +010076 RTPHeader header;
77 EXPECT_TRUE(parser_->Parse(packet, length, &header));
78 EXPECT_TRUE(header.ssrc == test::CallTest::kVideoSendSsrcs[0] ||
79 header.ssrc == test::CallTest::kVideoSendSsrcs[1] ||
80 header.ssrc == test::CallTest::kVideoSendSsrcs[2])
81 << "Unknown SSRC sent.";
82
83 EXPECT_GE(length, header.headerLength + header.paddingLength);
84 size_t payload_length = length - header.headerLength - header.paddingLength;
85 if (payload_length == 0) {
86 return false; // Padding packet.
87 }
88
Åsa Perssonad3c7a42017-11-29 10:24:27 +010089 parsed->timestamp = header.timestamp;
Åsa Persson71485ac2017-12-04 11:11:19 +010090 parsed->ssrc = header.ssrc;
Åsa Perssonad3c7a42017-11-29 10:24:27 +010091
92 std::unique_ptr<RtpDepacketizer> depacketizer(
93 RtpDepacketizer::Create(codec_type_));
94 RtpDepacketizer::ParsedPayload parsed_payload;
95 EXPECT_TRUE(depacketizer->Parse(
96 &parsed_payload, &packet[header.headerLength], payload_length));
97
98 switch (codec_type_) {
Niels Möller520ca4e2018-06-04 11:14:38 +020099 case kVideoCodecVP8:
philipel5ab67a52018-07-05 12:27:04 +0200100 parsed->picture_id = parsed_payload.video_header().vp8().pictureId;
101 parsed->tl0_pic_idx = parsed_payload.video_header().vp8().tl0PicIdx;
102 parsed->temporal_idx = parsed_payload.video_header().vp8().temporalIdx;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100103 break;
philipel29d88462018-08-08 14:26:00 +0200104 case kVideoCodecVP9: {
105 const auto& vp9_header = absl::get<RTPVideoHeaderVP9>(
106 parsed_payload.video_header().video_type_header);
107 parsed->picture_id = vp9_header.picture_id;
108 parsed->tl0_pic_idx = vp9_header.tl0_pic_idx;
109 parsed->temporal_idx = vp9_header.temporal_idx;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100110 break;
philipel29d88462018-08-08 14:26:00 +0200111 }
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100112 default:
113 RTC_NOTREACHED();
114 break;
115 }
116
117 parsed->frame_type = parsed_payload.frame_type;
118 return true;
119 }
120
Åsa Persson71485ac2017-12-04 11:11:19 +0100121 // Verify continuity and monotonicity of picture_id sequence.
122 void VerifyPictureId(const ParsedPacket& current,
123 const ParsedPacket& last) const
124 RTC_EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
125 if (current.timestamp == last.timestamp) {
126 EXPECT_EQ(last.picture_id, current.picture_id);
127 return; // Same frame.
128 }
129
130 // Packet belongs to a new frame.
131 // Picture id should be increasing.
132 EXPECT_TRUE((AheadOf<uint16_t, kPictureIdWraparound>(current.picture_id,
133 last.picture_id)));
134
135 // Expect continuously increasing picture id.
136 int diff = ForwardDiff<uint16_t, kPictureIdWraparound>(last.picture_id,
137 current.picture_id);
138 if (diff > 1) {
139 // If the VideoSendStream is destroyed, any frames still in queue is lost.
140 // Gaps only possible for first frame after a recreation, i.e. key frames.
141 EXPECT_EQ(kVideoFrameKey, current.frame_type);
142 EXPECT_LE(diff - 1, max_expected_picture_id_gap_);
143 }
144 }
145
146 void VerifyTl0Idx(const ParsedPacket& current, const ParsedPacket& last) const
147 RTC_EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
148 if (current.tl0_pic_idx == kNoTl0PicIdx ||
149 current.temporal_idx == kNoTemporalIdx) {
150 return; // No temporal layers.
151 }
152
153 if (current.timestamp == last.timestamp || current.temporal_idx != 0) {
154 EXPECT_EQ(last.tl0_pic_idx, current.tl0_pic_idx);
155 return;
156 }
157
158 // New frame with |temporal_idx| 0.
159 // |tl0_pic_idx| should be increasing.
160 EXPECT_TRUE(AheadOf<uint8_t>(current.tl0_pic_idx, last.tl0_pic_idx));
161
162 // Expect continuously increasing idx.
163 int diff = ForwardDiff<uint8_t>(last.tl0_pic_idx, current.tl0_pic_idx);
164 if (diff > 1) {
165 // If the VideoSendStream is destroyed, any frames still in queue is lost.
166 // Gaps only possible for first frame after a recreation, i.e. key frames.
167 EXPECT_EQ(kVideoFrameKey, current.frame_type);
168 EXPECT_LE(diff - 1, max_expected_tl0_idx_gap_);
169 }
170 }
171
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200172 Action OnSendRtp(const uint8_t* packet, size_t length) override {
173 rtc::CritScope lock(&crit_);
174
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100175 ParsedPacket parsed;
Åsa Persson71485ac2017-12-04 11:11:19 +0100176 if (!ParsePayload(packet, length, &parsed))
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200177 return SEND_PACKET;
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200178
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100179 uint32_t ssrc = parsed.ssrc;
180 if (last_observed_packet_.find(ssrc) != last_observed_packet_.end()) {
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100181 // Compare to last packet.
Åsa Persson71485ac2017-12-04 11:11:19 +0100182 VerifyPictureId(parsed, last_observed_packet_[ssrc]);
183 VerifyTl0Idx(parsed, last_observed_packet_[ssrc]);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200184 }
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200185
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100186 last_observed_packet_[ssrc] = parsed;
187
188 // Pass the test when enough media packets have been received on all
189 // streams.
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200190 if (++num_packets_sent_[ssrc] >= kMinPacketsToObserve &&
191 observed_ssrcs_.find(ssrc) == observed_ssrcs_.end()) {
192 observed_ssrcs_.insert(ssrc);
193 if (observed_ssrcs_.size() == num_ssrcs_to_observe_) {
194 observation_complete_.Set();
195 }
196 }
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200197 return SEND_PACKET;
198 }
199
200 rtc::CriticalSection crit_;
Niels Möller520ca4e2018-06-04 11:14:38 +0200201 const VideoCodecType codec_type_;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100202 std::map<uint32_t, ParsedPacket> last_observed_packet_ RTC_GUARDED_BY(crit_);
danilchapa37de392017-09-09 04:17:22 -0700203 std::map<uint32_t, size_t> num_packets_sent_ RTC_GUARDED_BY(crit_);
204 int max_expected_picture_id_gap_ RTC_GUARDED_BY(crit_);
Åsa Persson71485ac2017-12-04 11:11:19 +0100205 int max_expected_tl0_idx_gap_ RTC_GUARDED_BY(crit_);
danilchapa37de392017-09-09 04:17:22 -0700206 size_t num_ssrcs_to_observe_ RTC_GUARDED_BY(crit_);
207 std::set<uint32_t> observed_ssrcs_ RTC_GUARDED_BY(crit_);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200208};
209
Åsa Persson4bece9a2017-10-06 10:04:04 +0200210class PictureIdTest : public test::CallTest,
Åsa Persson677f42c2018-03-16 13:09:17 +0100211 public ::testing::WithParamInterface<size_t> {
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200212 public:
Åsa Persson677f42c2018-03-16 13:09:17 +0100213 PictureIdTest() : num_temporal_layers_(GetParam()) {}
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200214
215 virtual ~PictureIdTest() {
eladalon413ee9a2017-08-22 04:02:52 -0700216 task_queue_.SendTask([this]() {
eladalon413ee9a2017-08-22 04:02:52 -0700217 send_transport_.reset();
218 receive_transport_.reset();
219 DestroyCalls();
220 });
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200221 }
222
Niels Möller4db138e2018-04-19 09:04:13 +0200223 void SetupEncoder(VideoEncoderFactory* encoder_factory,
224 const std::string& payload_name);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200225 void TestPictureIdContinuousAfterReconfigure(
226 const std::vector<int>& ssrc_counts);
227 void TestPictureIdIncreaseAfterRecreateStreams(
228 const std::vector<int>& ssrc_counts);
229
230 private:
Åsa Persson71485ac2017-12-04 11:11:19 +0100231 const size_t num_temporal_layers_;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100232 std::unique_ptr<PictureIdObserver> observer_;
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200233};
234
Åsa Persson677f42c2018-03-16 13:09:17 +0100235INSTANTIATE_TEST_CASE_P(TemporalLayers,
236 PictureIdTest,
237 ::testing::ValuesIn(kNumTemporalLayers));
Åsa Persson4bece9a2017-10-06 10:04:04 +0200238
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200239// Use a special stream factory to ensure that all simulcast streams are being
240// sent.
241class VideoStreamFactory
242 : public VideoEncoderConfig::VideoStreamFactoryInterface {
243 public:
Åsa Persson71485ac2017-12-04 11:11:19 +0100244 explicit VideoStreamFactory(size_t num_temporal_layers)
245 : num_of_temporal_layers_(num_temporal_layers) {}
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200246
247 private:
248 std::vector<VideoStream> CreateEncoderStreams(
249 int width,
250 int height,
251 const VideoEncoderConfig& encoder_config) override {
252 std::vector<VideoStream> streams =
253 test::CreateVideoStreams(width, height, encoder_config);
254
Åsa Persson6a1b7ad2017-12-11 12:30:55 +0100255 // Use the same total bitrates when sending a single stream to avoid
256 // lowering the bitrate estimate and requiring a subsequent rampup.
Yves Gerey665174f2018-06-19 15:03:05 +0200257 const int encoder_stream_bps =
258 kEncoderBitrateBps /
259 rtc::checked_cast<int>(encoder_config.number_of_streams);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200260
Åsa Persson6a1b7ad2017-12-11 12:30:55 +0100261 for (size_t i = 0; i < encoder_config.number_of_streams; ++i) {
262 streams[i].min_bitrate_bps = encoder_stream_bps;
263 streams[i].target_bitrate_bps = encoder_stream_bps;
264 streams[i].max_bitrate_bps = encoder_stream_bps;
Sergey Silkina796a7e2018-03-01 15:11:29 +0100265 streams[i].num_temporal_layers = num_of_temporal_layers_;
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200266 // test::CreateVideoStreams does not return frame sizes for the lower
267 // streams that are accepted by VP8Impl::InitEncode.
268 // TODO(brandtr): Fix the problem in test::CreateVideoStreams, rather
269 // than overriding the values here.
Åsa Persson6a1b7ad2017-12-11 12:30:55 +0100270 streams[i].width =
271 width / (1 << (encoder_config.number_of_streams - 1 - i));
272 streams[i].height =
273 height / (1 << (encoder_config.number_of_streams - 1 - i));
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200274 }
275
276 return streams;
277 }
Åsa Persson71485ac2017-12-04 11:11:19 +0100278
279 const size_t num_of_temporal_layers_;
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200280};
281
Niels Möller4db138e2018-04-19 09:04:13 +0200282void PictureIdTest::SetupEncoder(VideoEncoderFactory* encoder_factory,
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100283 const std::string& payload_name) {
284 observer_.reset(
Niels Möller520ca4e2018-06-04 11:14:38 +0200285 new PictureIdObserver(PayloadStringToCodecType(payload_name)));
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100286
Niels Möller4db138e2018-04-19 09:04:13 +0200287 task_queue_.SendTask([this, encoder_factory, payload_name]() {
Sebastian Jansson8e6602f2018-07-13 10:43:20 +0200288 CreateCalls();
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200289
eladalon413ee9a2017-08-22 04:02:52 -0700290 send_transport_.reset(new test::PacketTransport(
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100291 &task_queue_, sender_call_.get(), observer_.get(),
eladalon413ee9a2017-08-22 04:02:52 -0700292 test::PacketTransport::kSender, payload_type_map_,
293 FakeNetworkPipe::Config()));
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200294
Ilya Nikolaevskiy255d1cd2017-12-21 18:02:59 +0100295 CreateSendConfig(kNumSimulcastStreams, 0, 0, send_transport_.get());
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200296 GetVideoSendConfig()->encoder_settings.encoder_factory = encoder_factory;
297 GetVideoSendConfig()->rtp.payload_name = payload_name;
298 GetVideoEncoderConfig()->codec_type =
299 PayloadStringToCodecType(payload_name);
300 GetVideoEncoderConfig()->video_stream_factory =
Åsa Persson71485ac2017-12-04 11:11:19 +0100301 new rtc::RefCountedObject<VideoStreamFactory>(num_temporal_layers_);
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200302 GetVideoEncoderConfig()->number_of_streams = 1;
eladalon413ee9a2017-08-22 04:02:52 -0700303 });
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200304}
305
306void PictureIdTest::TestPictureIdContinuousAfterReconfigure(
307 const std::vector<int>& ssrc_counts) {
eladalon413ee9a2017-08-22 04:02:52 -0700308 task_queue_.SendTask([this]() {
309 CreateVideoStreams();
310 CreateFrameGeneratorCapturer(kFrameRate, kFrameMaxWidth, kFrameMaxHeight);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200311
eladalon413ee9a2017-08-22 04:02:52 -0700312 // Initial test with a single stream.
313 Start();
314 });
315
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100316 EXPECT_TRUE(observer_->Wait()) << "Timed out waiting for packets.";
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200317
318 // Reconfigure VideoEncoder and test picture id increase.
Åsa Perssonae819752017-10-10 11:05:59 +0200319 // Expect continuously increasing picture id, equivalent to no gaps.
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100320 observer_->SetMaxExpectedPictureIdGap(0);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200321 for (int ssrc_count : ssrc_counts) {
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200322 GetVideoEncoderConfig()->number_of_streams = ssrc_count;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100323 observer_->SetExpectedSsrcs(ssrc_count);
324 observer_->ResetObservedSsrcs();
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200325 // Make sure the picture_id sequence is continuous on reinit and recreate.
eladalon413ee9a2017-08-22 04:02:52 -0700326 task_queue_.SendTask([this]() {
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200327 GetVideoSendStream()->ReconfigureVideoEncoder(
328 GetVideoEncoderConfig()->Copy());
eladalon413ee9a2017-08-22 04:02:52 -0700329 });
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100330 EXPECT_TRUE(observer_->Wait()) << "Timed out waiting for packets.";
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200331 }
332
eladalon413ee9a2017-08-22 04:02:52 -0700333 task_queue_.SendTask([this]() {
334 Stop();
335 DestroyStreams();
eladalon413ee9a2017-08-22 04:02:52 -0700336 });
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200337}
338
339void PictureIdTest::TestPictureIdIncreaseAfterRecreateStreams(
340 const std::vector<int>& ssrc_counts) {
eladalon413ee9a2017-08-22 04:02:52 -0700341 task_queue_.SendTask([this]() {
342 CreateVideoStreams();
343 CreateFrameGeneratorCapturer(kFrameRate, kFrameMaxWidth, kFrameMaxHeight);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200344
eladalon413ee9a2017-08-22 04:02:52 -0700345 // Initial test with a single stream.
346 Start();
347 });
348
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100349 EXPECT_TRUE(observer_->Wait()) << "Timed out waiting for packets.";
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200350
351 // Recreate VideoSendStream and test picture id increase.
352 // When the VideoSendStream is destroyed, any frames still in queue is lost
353 // with it, therefore it is expected that some frames might be lost.
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100354 observer_->SetMaxExpectedPictureIdGap(kMaxFramesLost);
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200355 for (int ssrc_count : ssrc_counts) {
eladalon413ee9a2017-08-22 04:02:52 -0700356 task_queue_.SendTask([this, &ssrc_count]() {
eladalon413ee9a2017-08-22 04:02:52 -0700357 frame_generator_capturer_->Stop();
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200358 DestroyVideoSendStreams();
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200359
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200360 GetVideoEncoderConfig()->number_of_streams = ssrc_count;
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100361 observer_->SetExpectedSsrcs(ssrc_count);
362 observer_->ResetObservedSsrcs();
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200363
Sebastian Janssonf33905d2018-07-13 09:49:00 +0200364 CreateVideoSendStreams();
365 GetVideoSendStream()->Start();
eladalon413ee9a2017-08-22 04:02:52 -0700366 CreateFrameGeneratorCapturer(kFrameRate, kFrameMaxWidth, kFrameMaxHeight);
367 frame_generator_capturer_->Start();
368 });
369
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100370 EXPECT_TRUE(observer_->Wait()) << "Timed out waiting for packets.";
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200371 }
372
eladalon413ee9a2017-08-22 04:02:52 -0700373 task_queue_.SendTask([this]() {
374 Stop();
375 DestroyStreams();
eladalon413ee9a2017-08-22 04:02:52 -0700376 });
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200377}
378
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100379TEST_P(PictureIdTest, ContinuousAfterReconfigureVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200380 test::FunctionVideoEncoderFactory encoder_factory(
381 []() { return VP8Encoder::Create(); });
382 SetupEncoder(&encoder_factory, "VP8");
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200383 TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1});
384}
385
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100386TEST_P(PictureIdTest, IncreasingAfterRecreateStreamVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200387 test::FunctionVideoEncoderFactory encoder_factory(
388 []() { return VP8Encoder::Create(); });
389 SetupEncoder(&encoder_factory, "VP8");
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200390 TestPictureIdIncreaseAfterRecreateStreams({1, 3, 3, 1, 1});
391}
392
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100393TEST_P(PictureIdTest, ContinuousAfterStreamCountChangeVp8) {
Niels Möller4db138e2018-04-19 09:04:13 +0200394 test::FunctionVideoEncoderFactory encoder_factory(
395 []() { return VP8Encoder::Create(); });
Åsa Persson71485ac2017-12-04 11:11:19 +0100396 // Make sure that the picture id is not reset if the stream count goes
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200397 // down and then up.
Niels Möller4db138e2018-04-19 09:04:13 +0200398 SetupEncoder(&encoder_factory, "VP8");
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100399 TestPictureIdContinuousAfterReconfigure({3, 1, 3});
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200400}
401
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100402TEST_P(PictureIdTest, ContinuousAfterReconfigureSimulcastEncoderAdapter) {
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100403 InternalEncoderFactory internal_encoder_factory;
Niels Möller4db138e2018-04-19 09:04:13 +0200404 test::FunctionVideoEncoderFactory encoder_factory(
405 [&internal_encoder_factory]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200406 return absl::make_unique<SimulcastEncoderAdapter>(
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200407 &internal_encoder_factory, SdpVideoFormat("VP8"));
Niels Möller4db138e2018-04-19 09:04:13 +0200408 });
409 SetupEncoder(&encoder_factory, "VP8");
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200410 TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1});
411}
412
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100413TEST_P(PictureIdTest, IncreasingAfterRecreateStreamSimulcastEncoderAdapter) {
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 TestPictureIdIncreaseAfterRecreateStreams({1, 3, 3, 1, 1});
422}
423
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100424TEST_P(PictureIdTest, ContinuousAfterStreamCountChangeSimulcastEncoderAdapter) {
Åsa Persson677f42c2018-03-16 13:09:17 +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 });
Åsa Persson677f42c2018-03-16 13:09:17 +0100431 // Make sure that the picture id is not reset if the stream count goes
432 // down and then up.
Niels Möller4db138e2018-04-19 09:04:13 +0200433 SetupEncoder(&encoder_factory, "VP8");
Åsa Persson677f42c2018-03-16 13:09:17 +0100434 TestPictureIdContinuousAfterReconfigure({3, 1, 3});
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200435}
436
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100437TEST_P(PictureIdTest, IncreasingAfterRecreateStreamVp9) {
Niels Möller4db138e2018-04-19 09:04:13 +0200438 test::FunctionVideoEncoderFactory encoder_factory(
439 []() { return VP9Encoder::Create(); });
440 SetupEncoder(&encoder_factory, "VP9");
Åsa Perssonad3c7a42017-11-29 10:24:27 +0100441 TestPictureIdIncreaseAfterRecreateStreams({1, 1});
442}
443
Sebastian Janssone92f93f2017-06-22 14:44:04 +0200444} // namespace webrtc