blob: a03344e635516444ac2aaf40b09fb27f1bf58a6a [file] [log] [blame]
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +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 */
10#include <stdio.h>
11
12#include <deque>
13#include <map>
14
pbos@webrtc.org69215d82013-07-10 15:02:02 +000015#include "testing/gtest/include/gtest/gtest.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000016
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000017#include "webrtc/base/scoped_ptr.h"
pbos@webrtc.org38344ed2014-09-24 06:05:00 +000018#include "webrtc/base/thread_annotations.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000019#include "webrtc/call.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000020#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
Erik Språng085856c2015-07-22 17:17:58 +020021#include "webrtc/frame_callback.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000022#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
23#include "webrtc/system_wrappers/interface/clock.h"
sprang@webrtc.org131bea82015-02-18 12:46:06 +000024#include "webrtc/system_wrappers/interface/cpu_info.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000025#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
26#include "webrtc/system_wrappers/interface/event_wrapper.h"
pbos@webrtc.org94015242013-10-16 11:05:37 +000027#include "webrtc/system_wrappers/interface/sleep.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000028#include "webrtc/test/call_test.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000029#include "webrtc/test/direct_transport.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000030#include "webrtc/test/encoder_settings.h"
31#include "webrtc/test/fake_encoder.h"
sprang@webrtc.org131bea82015-02-18 12:46:06 +000032#include "webrtc/test/frame_generator.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000033#include "webrtc/test/frame_generator_capturer.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000034#include "webrtc/test/statistics.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000035#include "webrtc/test/testsupport/fileutils.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000036#include "webrtc/typedefs.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000037
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000038namespace webrtc {
39
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +000040static const int kFullStackTestDurationSecs = 60;
Erik Språng085856c2015-07-22 17:17:58 +020041static const int kSendStatsPollingIntervalMs = 1000;
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000042
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000043struct FullStackTestParams {
44 const char* test_label;
45 struct {
46 const char* name;
pbos@webrtc.orgf3f13582013-07-09 14:04:46 +000047 size_t width, height;
48 int fps;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000049 } clip;
sprang@webrtc.org131bea82015-02-18 12:46:06 +000050 bool screenshare;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +000051 int min_bitrate_bps;
52 int target_bitrate_bps;
53 int max_bitrate_bps;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000054 double avg_psnr_threshold;
55 double avg_ssim_threshold;
sprang@webrtc.org131bea82015-02-18 12:46:06 +000056 int test_durations_secs;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +000057 FakeNetworkPipe::Config link;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000058};
59
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000060class FullStackTest : public test::CallTest {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000061 protected:
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +000062 void RunTest(const FullStackTestParams& params);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000063};
64
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000065class VideoAnalyzer : public PacketReceiver,
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000066 public newapi::Transport,
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000067 public VideoRenderer,
Erik Språng085856c2015-07-22 17:17:58 +020068 public VideoCaptureInput,
69 public EncodedFrameObserver {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000070 public:
Peter Boström4b91bd02015-06-26 06:58:16 +020071 VideoAnalyzer(VideoCaptureInput* input,
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000072 Transport* transport,
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000073 const char* test_label,
74 double avg_psnr_threshold,
75 double avg_ssim_threshold,
pbos@webrtc.org94015242013-10-16 11:05:37 +000076 int duration_frames)
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000077 : input_(input),
78 transport_(transport),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +000079 receiver_(nullptr),
Erik Språng085856c2015-07-22 17:17:58 +020080 send_stream_(nullptr),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000081 test_label_(test_label),
sprang@webrtc.org131bea82015-02-18 12:46:06 +000082 frames_to_process_(duration_frames),
83 frames_recorded_(0),
84 frames_processed_(0),
pbos@webrtc.org94015242013-10-16 11:05:37 +000085 dropped_frames_(0),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000086 last_render_time_(0),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000087 rtp_timestamp_delta_(0),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000088 avg_psnr_threshold_(avg_psnr_threshold),
89 avg_ssim_threshold_(avg_ssim_threshold),
sprang@webrtc.org131bea82015-02-18 12:46:06 +000090 comparison_available_event_(EventWrapper::Create()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000091 done_(EventWrapper::Create()) {
sprang@webrtc.org131bea82015-02-18 12:46:06 +000092 // Create thread pool for CPU-expensive PSNR/SSIM calculations.
93
94 // Try to use about as many threads as cores, but leave kMinCoresLeft alone,
95 // so that we don't accidentally starve "real" worker threads (codec etc).
96 // Also, don't allocate more than kMaxComparisonThreads, even if there are
97 // spare cores.
98
99 uint32_t num_cores = CpuInfo::DetectNumberOfCores();
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000100 DCHECK_GE(num_cores, 1u);
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000101 static const uint32_t kMinCoresLeft = 4;
sprang@webrtc.org343096a2015-02-23 08:34:17 +0000102 static const uint32_t kMaxComparisonThreads = 8;
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000103
104 if (num_cores <= kMinCoresLeft) {
105 num_cores = 1;
106 } else {
107 num_cores -= kMinCoresLeft;
108 num_cores = std::min(num_cores, kMaxComparisonThreads);
109 }
110
111 for (uint32_t i = 0; i < num_cores; ++i) {
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000112 rtc::scoped_ptr<ThreadWrapper> thread =
tommi@webrtc.org38492c52015-03-22 14:41:46 +0000113 ThreadWrapper::CreateThread(&FrameComparisonThread, this, "Analyzer");
pbos@webrtc.org86639732015-03-13 00:06:21 +0000114 EXPECT_TRUE(thread->Start());
tommi@webrtc.org361981f2015-03-19 14:44:18 +0000115 comparison_thread_pool_.push_back(thread.release());
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000116 }
Erik Språng085856c2015-07-22 17:17:58 +0200117
118 stats_polling_thread_ =
119 ThreadWrapper::CreateThread(&PollStatsThread, this, "StatsPoller");
120 EXPECT_TRUE(stats_polling_thread_->Start());
pbos@webrtc.org94015242013-10-16 11:05:37 +0000121 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000122
123 ~VideoAnalyzer() {
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000124 for (ThreadWrapper* thread : comparison_thread_pool_) {
125 EXPECT_TRUE(thread->Stop());
126 delete thread;
127 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000128 }
129
pbos@webrtc.org94015242013-10-16 11:05:37 +0000130 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; }
131
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200132 DeliveryStatus DeliverPacket(MediaType media_type, const uint8_t* packet,
133 size_t length) override {
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000134 rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000135 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000136 parser->Parse(packet, length, &header);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000137 {
Peter Boströmf2f82832015-05-01 13:00:41 +0200138 rtc::CritScope lock(&crit_);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000139 recv_times_[header.timestamp - rtp_timestamp_delta_] =
140 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
141 }
142
Fredrik Solenberg23fba1f2015-04-29 15:24:01 +0200143 return receiver_->DeliverPacket(media_type, packet, length);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000144 }
145
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700146 void IncomingCapturedFrame(const VideoFrame& video_frame) override {
147 VideoFrame copy = video_frame;
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000148 copy.set_timestamp(copy.ntp_time_ms() * 90);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000149
150 {
Peter Boströmf2f82832015-05-01 13:00:41 +0200151 rtc::CritScope lock(&crit_);
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000152 if (first_send_frame_.IsZeroSize() && rtp_timestamp_delta_ == 0)
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000153 first_send_frame_ = copy;
154
155 frames_.push_back(copy);
156 }
157
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000158 input_->IncomingCapturedFrame(video_frame);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000159 }
160
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000161 bool SendRtp(const uint8_t* packet, size_t length) override {
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000162 rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000163 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000164 parser->Parse(packet, length, &header);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000165
166 {
Peter Boströmf2f82832015-05-01 13:00:41 +0200167 rtc::CritScope lock(&crit_);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000168 if (rtp_timestamp_delta_ == 0) {
169 rtp_timestamp_delta_ =
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000170 header.timestamp - first_send_frame_.timestamp();
171 first_send_frame_.Reset();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000172 }
pbos@webrtc.org7fb9ce02013-08-05 09:29:50 +0000173 send_times_[header.timestamp - rtp_timestamp_delta_] =
174 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000175 }
176
pbos@webrtc.org27326b62013-11-20 12:17:04 +0000177 return transport_->SendRtp(packet, length);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000178 }
179
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000180 bool SendRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org27326b62013-11-20 12:17:04 +0000181 return transport_->SendRtcp(packet, length);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000182 }
183
Erik Språng085856c2015-07-22 17:17:58 +0200184 void EncodedFrameCallback(const EncodedFrame& frame) override {
185 rtc::CritScope lock(&comparison_lock_);
186 if (frames_recorded_ < frames_to_process_)
187 encoded_frame_size_.AddSample(frame.length_);
188 }
189
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700190 void RenderFrame(const VideoFrame& video_frame,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000191 int time_to_render_ms) override {
pbos@webrtc.org94015242013-10-16 11:05:37 +0000192 int64_t render_time_ms =
193 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000194 uint32_t send_timestamp = video_frame.timestamp() - rtp_timestamp_delta_;
195
Peter Boströmf2f82832015-05-01 13:00:41 +0200196 rtc::CritScope lock(&crit_);
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000197
198 while (frames_.front().timestamp() < send_timestamp) {
199 AddFrameComparison(frames_.front(), last_rendered_frame_, true,
200 render_time_ms);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000201 frames_.pop_front();
pbos@webrtc.org94015242013-10-16 11:05:37 +0000202 }
203
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700204 VideoFrame reference_frame = frames_.front();
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000205 frames_.pop_front();
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000206 assert(!reference_frame.IsZeroSize());
207 EXPECT_EQ(reference_frame.timestamp(), send_timestamp);
208 assert(reference_frame.timestamp() == send_timestamp);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000209
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000210 AddFrameComparison(reference_frame, video_frame, false, render_time_ms);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000211
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000212 last_rendered_frame_ = video_frame;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000213 }
214
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000215 bool IsTextureSupported() const override { return false; }
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000216
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000217 void Wait() {
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000218 // Frame comparisons can be very expensive. Wait for test to be done, but
219 // at time-out check if frames_processed is going up. If so, give it more
220 // time, otherwise fail. Hopefully this will reduce test flakiness.
221
222 int last_frames_processed = -1;
223 EventTypeWrapper eventType;
224 while ((eventType = done_->Wait(FullStackTest::kDefaultTimeoutMs)) !=
225 kEventSignaled) {
226 int frames_processed;
227 {
Peter Boströmf2f82832015-05-01 13:00:41 +0200228 rtc::CritScope crit(&comparison_lock_);
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000229 frames_processed = frames_processed_;
230 }
231 if (last_frames_processed == -1) {
232 last_frames_processed = frames_processed;
233 continue;
234 }
235 ASSERT_GT(frames_processed, last_frames_processed)
236 << "Analyzer stalled while waiting for test to finish.";
237 last_frames_processed = frames_processed;
238 }
Erik Språng085856c2015-07-22 17:17:58 +0200239
240 // Signal stats polling thread if that is still waiting and stop it now,
241 // since it uses the send_stream_ reference that might be reclaimed after
242 // returning from this method.
243 done_->Set();
244 EXPECT_TRUE(stats_polling_thread_->Stop());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000245 }
pbos@webrtc.org94015242013-10-16 11:05:37 +0000246
Peter Boström4b91bd02015-06-26 06:58:16 +0200247 VideoCaptureInput* input_;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000248 Transport* transport_;
249 PacketReceiver* receiver_;
Erik Språng085856c2015-07-22 17:17:58 +0200250 VideoSendStream* send_stream_;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000251
252 private:
253 struct FrameComparison {
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000254 FrameComparison()
255 : dropped(false), send_time_ms(0), recv_time_ms(0), render_time_ms(0) {}
256
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700257 FrameComparison(const VideoFrame& reference,
258 const VideoFrame& render,
pbos@webrtc.org94015242013-10-16 11:05:37 +0000259 bool dropped,
260 int64_t send_time_ms,
261 int64_t recv_time_ms,
262 int64_t render_time_ms)
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000263 : reference(reference),
264 render(render),
265 dropped(dropped),
pbos@webrtc.org94015242013-10-16 11:05:37 +0000266 send_time_ms(send_time_ms),
267 recv_time_ms(recv_time_ms),
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000268 render_time_ms(render_time_ms) {}
pbos@webrtc.org94015242013-10-16 11:05:37 +0000269
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700270 VideoFrame reference;
271 VideoFrame render;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000272 bool dropped;
273 int64_t send_time_ms;
274 int64_t recv_time_ms;
275 int64_t render_time_ms;
276 };
277
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700278 void AddFrameComparison(const VideoFrame& reference,
279 const VideoFrame& render,
pbos@webrtc.org94015242013-10-16 11:05:37 +0000280 bool dropped,
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000281 int64_t render_time_ms)
282 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000283 int64_t send_time_ms = send_times_[reference.timestamp()];
284 send_times_.erase(reference.timestamp());
285 int64_t recv_time_ms = recv_times_[reference.timestamp()];
286 recv_times_.erase(reference.timestamp());
pbos@webrtc.org94015242013-10-16 11:05:37 +0000287
Peter Boströmf2f82832015-05-01 13:00:41 +0200288 rtc::CritScope crit(&comparison_lock_);
Erik Språng085856c2015-07-22 17:17:58 +0200289 comparisons_.push_back(FrameComparison(reference, render, dropped,
290 send_time_ms, recv_time_ms,
pbos@webrtc.org94015242013-10-16 11:05:37 +0000291 render_time_ms));
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000292 comparison_available_event_->Set();
pbos@webrtc.org94015242013-10-16 11:05:37 +0000293 }
294
Erik Språng085856c2015-07-22 17:17:58 +0200295 static bool PollStatsThread(void* obj) {
296 return static_cast<VideoAnalyzer*>(obj)->PollStats();
297 }
298
299 bool PollStats() {
300 switch (done_->Wait(kSendStatsPollingIntervalMs)) {
301 case kEventSignaled:
302 case kEventError:
303 done_->Set(); // Make sure main thread is also signaled.
304 return false;
305 case kEventTimeout:
306 break;
307 default:
308 RTC_NOTREACHED();
309 }
310
311 VideoSendStream::Stats stats = send_stream_->GetStats();
312
313 rtc::CritScope crit(&comparison_lock_);
314 encode_frame_rate_.AddSample(stats.encode_frame_rate);
315 encode_time_ms.AddSample(stats.avg_encode_time_ms);
316 encode_usage_percent.AddSample(stats.encode_usage_percent);
317 media_bitrate_bps.AddSample(stats.media_bitrate_bps);
318
319 return true;
320 }
321
pbos@webrtc.org94015242013-10-16 11:05:37 +0000322 static bool FrameComparisonThread(void* obj) {
323 return static_cast<VideoAnalyzer*>(obj)->CompareFrames();
324 }
325
326 bool CompareFrames() {
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000327 if (AllFramesRecorded())
328 return false;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000329
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700330 VideoFrame reference;
331 VideoFrame render;
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000332 FrameComparison comparison;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000333
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000334 if (!PopComparison(&comparison)) {
335 // Wait until new comparison task is available, or test is done.
336 // If done, wake up remaining threads waiting.
337 comparison_available_event_->Wait(1000);
338 if (AllFramesRecorded()) {
339 comparison_available_event_->Set();
pbos@webrtc.org94015242013-10-16 11:05:37 +0000340 return false;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000341 }
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000342 return true; // Try again.
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000343 }
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000344
345 PerformFrameComparison(comparison);
346
347 if (FrameProcessed()) {
348 PrintResults();
349 done_->Set();
350 comparison_available_event_->Set();
351 return false;
352 }
353
354 return true;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000355 }
356
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000357 bool PopComparison(FrameComparison* comparison) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200358 rtc::CritScope crit(&comparison_lock_);
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000359 // If AllFramesRecorded() is true, it means we have already popped
360 // frames_to_process_ frames from comparisons_, so there is no more work
361 // for this thread to be done. frames_processed_ might still be lower if
362 // all comparisons are not done, but those frames are currently being
363 // worked on by other threads.
364 if (comparisons_.empty() || AllFramesRecorded())
365 return false;
366
pbos@webrtc.org443ad402015-03-20 07:34:28 +0000367 *comparison = comparisons_.front();
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000368 comparisons_.pop_front();
369
370 FrameRecorded();
371 return true;
372 }
373
374 // Increment counter for number of frames received for comparison.
375 void FrameRecorded() {
Peter Boströmf2f82832015-05-01 13:00:41 +0200376 rtc::CritScope crit(&comparison_lock_);
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000377 ++frames_recorded_;
378 }
379
380 // Returns true if all frames to be compared have been taken from the queue.
381 bool AllFramesRecorded() {
Peter Boströmf2f82832015-05-01 13:00:41 +0200382 rtc::CritScope crit(&comparison_lock_);
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000383 assert(frames_recorded_ <= frames_to_process_);
384 return frames_recorded_ == frames_to_process_;
385 }
386
387 // Increase count of number of frames processed. Returns true if this was the
388 // last frame to be processed.
389 bool FrameProcessed() {
Peter Boströmf2f82832015-05-01 13:00:41 +0200390 rtc::CritScope crit(&comparison_lock_);
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000391 ++frames_processed_;
392 assert(frames_processed_ <= frames_to_process_);
393 return frames_processed_ == frames_to_process_;
394 }
395
396 void PrintResults() {
Peter Boströmf2f82832015-05-01 13:00:41 +0200397 rtc::CritScope crit(&comparison_lock_);
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000398 PrintResult("psnr", psnr_, " dB");
399 PrintResult("ssim", ssim_, "");
400 PrintResult("sender_time", sender_time_, " ms");
401 printf("RESULT dropped_frames: %s = %d frames\n", test_label_,
402 dropped_frames_);
403 PrintResult("receiver_time", receiver_time_, " ms");
404 PrintResult("total_delay_incl_network", end_to_end_, " ms");
405 PrintResult("time_between_rendered_frames", rendered_delta_, " ms");
Erik Språng085856c2015-07-22 17:17:58 +0200406 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes");
407 PrintResult("encode_frame_rate", encode_frame_rate_, " fps");
408 PrintResult("encode_time", encode_time_ms, " ms");
409 PrintResult("encode_usage_percent", encode_usage_percent, " percent");
410 PrintResult("media_bitrate", media_bitrate_bps, " bps");
411
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000412 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_);
413 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_);
414 }
415
416 void PerformFrameComparison(const FrameComparison& comparison) {
417 // Perform expensive psnr and ssim calculations while not holding lock.
magjed@webrtc.org2056ee32015-03-16 13:46:52 +0000418 double psnr = I420PSNR(&comparison.reference, &comparison.render);
419 double ssim = I420SSIM(&comparison.reference, &comparison.render);
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000420
Peter Boströmf2f82832015-05-01 13:00:41 +0200421 rtc::CritScope crit(&comparison_lock_);
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000422 psnr_.AddSample(psnr);
423 ssim_.AddSample(ssim);
424 if (comparison.dropped) {
pbos@webrtc.org94015242013-10-16 11:05:37 +0000425 ++dropped_frames_;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000426 return;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000427 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000428 if (last_render_time_ != 0)
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000429 rendered_delta_.AddSample(comparison.render_time_ms - last_render_time_);
430 last_render_time_ = comparison.render_time_ms;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000431
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000432 int64_t input_time_ms = comparison.reference.ntp_time_ms();
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000433 sender_time_.AddSample(comparison.send_time_ms - input_time_ms);
434 receiver_time_.AddSample(comparison.render_time_ms -
435 comparison.recv_time_ms);
436 end_to_end_.AddSample(comparison.render_time_ms - input_time_ms);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000437 }
438
439 void PrintResult(const char* result_type,
440 test::Statistics stats,
441 const char* unit) {
442 printf("RESULT %s: %s = {%f, %f}%s\n",
443 result_type,
444 test_label_,
445 stats.Mean(),
446 stats.StandardDeviation(),
447 unit);
448 }
449
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000450 const char* const test_label_;
Erik Språng085856c2015-07-22 17:17:58 +0200451 test::Statistics sender_time_ GUARDED_BY(comparison_lock_);
452 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_);
453 test::Statistics psnr_ GUARDED_BY(comparison_lock_);
454 test::Statistics ssim_ GUARDED_BY(comparison_lock_);
455 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_);
456 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_);
457 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_);
458 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_);
459 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_);
460 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_);
461 test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_);
462
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000463 const int frames_to_process_;
464 int frames_recorded_;
465 int frames_processed_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000466 int dropped_frames_;
467 int64_t last_render_time_;
468 uint32_t rtp_timestamp_delta_;
469
Peter Boströmf2f82832015-05-01 13:00:41 +0200470 rtc::CriticalSection crit_;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700471 std::deque<VideoFrame> frames_ GUARDED_BY(crit_);
472 VideoFrame last_rendered_frame_ GUARDED_BY(crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000473 std::map<uint32_t, int64_t> send_times_ GUARDED_BY(crit_);
474 std::map<uint32_t, int64_t> recv_times_ GUARDED_BY(crit_);
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700475 VideoFrame first_send_frame_ GUARDED_BY(crit_);
pbos@webrtc.orgb35b1362014-10-20 09:14:38 +0000476 const double avg_psnr_threshold_;
477 const double avg_ssim_threshold_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000478
Peter Boströmf2f82832015-05-01 13:00:41 +0200479 rtc::CriticalSection comparison_lock_;
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000480 std::vector<ThreadWrapper*> comparison_thread_pool_;
Erik Språng085856c2015-07-22 17:17:58 +0200481 rtc::scoped_ptr<ThreadWrapper> stats_polling_thread_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000482 const rtc::scoped_ptr<EventWrapper> comparison_available_event_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000483 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_);
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000484 const rtc::scoped_ptr<EventWrapper> done_;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000485};
486
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000487void FullStackTest::RunTest(const FullStackTestParams& params) {
488 test::DirectTransport send_transport(params.link);
489 test::DirectTransport recv_transport(params.link);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000490 VideoAnalyzer analyzer(nullptr, &send_transport, params.test_label,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000491 params.avg_psnr_threshold, params.avg_ssim_threshold,
492 params.test_durations_secs * params.clip.fps);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000493
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000494 CreateCalls(Call::Config(&analyzer), Call::Config(&recv_transport));
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +0000495
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000496 analyzer.SetReceiver(receiver_call_->Receiver());
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000497 send_transport.SetReceiver(&analyzer);
498 recv_transport.SetReceiver(sender_call_->Receiver());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000499
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000500 CreateSendConfig(1);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000501
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000502 rtc::scoped_ptr<VideoEncoder> encoder(
pbos@webrtc.orgab990ae2014-09-17 09:02:25 +0000503 VideoEncoder::Create(VideoEncoder::kVp8));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000504 send_config_.encoder_settings.encoder = encoder.get();
505 send_config_.encoder_settings.payload_name = "VP8";
506 send_config_.encoder_settings.payload_type = 124;
stefan@webrtc.orgc216b9a2014-10-14 10:38:49 +0000507 send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000508 send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]);
509 send_config_.rtp.rtx.payload_type = kSendRtxPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000510
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000511 VideoStream* stream = &encoder_config_.streams[0];
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +0000512 stream->width = params.clip.width;
513 stream->height = params.clip.height;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000514 stream->min_bitrate_bps = params.min_bitrate_bps;
515 stream->target_bitrate_bps = params.target_bitrate_bps;
516 stream->max_bitrate_bps = params.max_bitrate_bps;
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +0000517 stream->max_framerate = params.clip.fps;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000518
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000519 if (params.screenshare) {
Erik Språng143cec12015-04-28 10:01:41 +0200520 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000521 encoder_config_.min_transmit_bitrate_bps = 400 * 1000;
522 VideoCodecVP8 vp8_settings = VideoEncoder::GetDefaultVp8Settings();
523 vp8_settings.denoisingOn = false;
524 vp8_settings.frameDroppingOn = false;
525 vp8_settings.numberOfTemporalLayers = 2;
526 encoder_config_.encoder_specific_settings = &vp8_settings;
527
528 stream->temporal_layer_thresholds_bps.clear();
529 stream->temporal_layer_thresholds_bps.push_back(stream->target_bitrate_bps);
530 }
531
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000532 CreateMatchingReceiveConfigs();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000533 receive_configs_[0].renderer = &analyzer;
stefan@webrtc.orgc216b9a2014-10-14 10:38:49 +0000534 receive_configs_[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000535 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].ssrc = kSendRtxSsrcs[0];
536 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].payload_type =
sprang@webrtc.org343096a2015-02-23 08:34:17 +0000537 kSendRtxPayloadType;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000538
Erik Språng085856c2015-07-22 17:17:58 +0200539 for (auto& config : receive_configs_)
540 config.pre_decode_callback = &analyzer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000541 CreateStreams();
542 analyzer.input_ = send_stream_->Input();
Erik Språng085856c2015-07-22 17:17:58 +0200543 analyzer.send_stream_ = send_stream_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000544
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000545 if (params.screenshare) {
546 std::vector<std::string> slides;
547 slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv"));
548 slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv"));
549 slides.push_back(test::ResourcePath("photo_1850_1110", "yuv"));
550 slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv"));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000551
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000552 rtc::scoped_ptr<test::FrameGenerator> frame_generator(
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000553 test::FrameGenerator::CreateFromYuvFile(
554 slides, 1850, 1110,
555 10 * params.clip.fps) // Cycle image every 10 seconds.
556 );
557 frame_generator_capturer_.reset(new test::FrameGeneratorCapturer(
558 Clock::GetRealTimeClock(), &analyzer, frame_generator.release(),
559 params.clip.fps));
560 ASSERT_TRUE(frame_generator_capturer_->Init());
561 } else {
562 frame_generator_capturer_.reset(
563 test::FrameGeneratorCapturer::CreateFromYuvFile(
564 &analyzer, test::ResourcePath(params.clip.name, "yuv"),
565 params.clip.width, params.clip.height, params.clip.fps,
566 Clock::GetRealTimeClock()));
567
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000568 ASSERT_TRUE(frame_generator_capturer_.get() != nullptr)
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000569 << "Could not create capturer for " << params.clip.name
570 << ".yuv. Is this resource file present?";
571 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000572
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000573 Start();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000574
575 analyzer.Wait();
576
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000577 send_transport.StopSending();
578 recv_transport.StopSending();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000579
580 Stop();
581
582 DestroyStreams();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000583}
584
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000585TEST_F(FullStackTest, ParisQcifWithoutPacketLoss) {
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000586 FullStackTestParams paris_qcif = {"net_delay_0_0_plr_0",
587 {"paris_qcif", 176, 144, 30},
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000588 false,
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000589 300000,
590 300000,
591 300000,
592 36.0,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000593 0.96,
594 kFullStackTestDurationSecs};
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000595 RunTest(paris_qcif);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000596}
597
598TEST_F(FullStackTest, ForemanCifWithoutPacketLoss) {
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000599 // TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif.
600 FullStackTestParams foreman_cif = {"foreman_cif_net_delay_0_0_plr_0",
601 {"foreman_cif", 352, 288, 30},
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000602 false,
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000603 700000,
604 700000,
605 700000,
606 0.0,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000607 0.0,
608 kFullStackTestDurationSecs};
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000609 RunTest(foreman_cif);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000610}
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000611
sprang@webrtc.org343096a2015-02-23 08:34:17 +0000612TEST_F(FullStackTest, ForemanCifPlr5) {
stefan@webrtc.orgc216b9a2014-10-14 10:38:49 +0000613 FullStackTestParams foreman_cif = {"foreman_cif_delay_50_0_plr_5",
614 {"foreman_cif", 352, 288, 30},
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000615 false,
stefan@webrtc.orgc216b9a2014-10-14 10:38:49 +0000616 30000,
617 500000,
618 2000000,
619 0.0,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000620 0.0,
621 kFullStackTestDurationSecs};
stefan@webrtc.orgc216b9a2014-10-14 10:38:49 +0000622 foreman_cif.link.loss_percent = 5;
623 foreman_cif.link.queue_delay_ms = 50;
624 RunTest(foreman_cif);
625}
626
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000627TEST_F(FullStackTest, ForemanCif500kbps) {
628 FullStackTestParams foreman_cif = {"foreman_cif_500kbps",
629 {"foreman_cif", 352, 288, 30},
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000630 false,
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000631 30000,
632 500000,
633 2000000,
634 0.0,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000635 0.0,
636 kFullStackTestDurationSecs};
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000637 foreman_cif.link.queue_length_packets = 0;
638 foreman_cif.link.queue_delay_ms = 0;
639 foreman_cif.link.link_capacity_kbps = 500;
640 RunTest(foreman_cif);
641}
642
643TEST_F(FullStackTest, ForemanCif500kbpsLimitedQueue) {
644 FullStackTestParams foreman_cif = {"foreman_cif_500kbps_32pkts_queue",
645 {"foreman_cif", 352, 288, 30},
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000646 false,
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000647 30000,
648 500000,
649 2000000,
650 0.0,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000651 0.0,
652 kFullStackTestDurationSecs};
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000653 foreman_cif.link.queue_length_packets = 32;
654 foreman_cif.link.queue_delay_ms = 0;
655 foreman_cif.link.link_capacity_kbps = 500;
656 RunTest(foreman_cif);
657}
658
659TEST_F(FullStackTest, ForemanCif500kbps100ms) {
660 FullStackTestParams foreman_cif = {"foreman_cif_500kbps_100ms",
661 {"foreman_cif", 352, 288, 30},
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000662 false,
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000663 30000,
664 500000,
665 2000000,
666 0.0,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000667 0.0,
668 kFullStackTestDurationSecs};
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000669 foreman_cif.link.queue_length_packets = 0;
670 foreman_cif.link.queue_delay_ms = 100;
671 foreman_cif.link.link_capacity_kbps = 500;
672 RunTest(foreman_cif);
673}
674
675TEST_F(FullStackTest, ForemanCif500kbps100msLimitedQueue) {
676 FullStackTestParams foreman_cif = {"foreman_cif_500kbps_100ms_32pkts_queue",
677 {"foreman_cif", 352, 288, 30},
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000678 false,
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000679 30000,
680 500000,
681 2000000,
682 0.0,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000683 0.0,
684 kFullStackTestDurationSecs};
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000685 foreman_cif.link.queue_length_packets = 32;
686 foreman_cif.link.queue_delay_ms = 100;
687 foreman_cif.link.link_capacity_kbps = 500;
688 RunTest(foreman_cif);
689}
690
691TEST_F(FullStackTest, ForemanCif1000kbps100msLimitedQueue) {
692 FullStackTestParams foreman_cif = {"foreman_cif_1000kbps_100ms_32pkts_queue",
693 {"foreman_cif", 352, 288, 30},
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000694 false,
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000695 30000,
696 2000000,
697 2000000,
698 0.0,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000699 0.0,
700 kFullStackTestDurationSecs};
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000701 foreman_cif.link.queue_length_packets = 32;
702 foreman_cif.link.queue_delay_ms = 100;
703 foreman_cif.link.link_capacity_kbps = 1000;
704 RunTest(foreman_cif);
705}
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000706
707TEST_F(FullStackTest, ScreenshareSlides) {
708 FullStackTestParams screenshare_params = {
709 "screenshare_slides",
710 {"screenshare_slides", 1850, 1110, 5},
711 true,
712 50000,
Erik Språng2c4c9142015-06-24 11:24:44 +0200713 200000,
714 2000000,
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000715 0.0,
716 0.0,
717 kFullStackTestDurationSecs};
718 RunTest(screenshare_params);
719}
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000720} // namespace webrtc