blob: 2a848cc3f78689d55546018066f3ff288b512cf6 [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
pbos@webrtc.org38344ed2014-09-24 06:05:00 +000017#include "webrtc/base/thread_annotations.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000018#include "webrtc/call.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000019#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
20#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
21#include "webrtc/system_wrappers/interface/clock.h"
22#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
23#include "webrtc/system_wrappers/interface/event_wrapper.h"
24#include "webrtc/system_wrappers/interface/scoped_ptr.h"
pbos@webrtc.org94015242013-10-16 11:05:37 +000025#include "webrtc/system_wrappers/interface/sleep.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000026#include "webrtc/test/call_test.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000027#include "webrtc/test/direct_transport.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000028#include "webrtc/test/encoder_settings.h"
29#include "webrtc/test/fake_encoder.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000030#include "webrtc/test/frame_generator_capturer.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000031#include "webrtc/test/statistics.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000032#include "webrtc/test/testsupport/fileutils.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000033#include "webrtc/typedefs.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000034
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000035namespace webrtc {
36
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +000037static const int kFullStackTestDurationSecs = 60;
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000038
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000039struct FullStackTestParams {
40 const char* test_label;
41 struct {
42 const char* name;
pbos@webrtc.orgf3f13582013-07-09 14:04:46 +000043 size_t width, height;
44 int fps;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000045 } clip;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +000046 int min_bitrate_bps;
47 int target_bitrate_bps;
48 int max_bitrate_bps;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000049 double avg_psnr_threshold;
50 double avg_ssim_threshold;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +000051 FakeNetworkPipe::Config link;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000052};
53
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000054class FullStackTest : public test::CallTest {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000055 protected:
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +000056 void RunTest(const FullStackTestParams& params);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000057};
58
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000059class VideoAnalyzer : public PacketReceiver,
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000060 public newapi::Transport,
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000061 public VideoRenderer,
62 public VideoSendStreamInput {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000063 public:
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000064 VideoAnalyzer(VideoSendStreamInput* input,
65 Transport* transport,
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000066 const char* test_label,
67 double avg_psnr_threshold,
68 double avg_ssim_threshold,
pbos@webrtc.org94015242013-10-16 11:05:37 +000069 int duration_frames)
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000070 : input_(input),
71 transport_(transport),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000072 receiver_(NULL),
73 test_label_(test_label),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000074 frames_left_(duration_frames),
pbos@webrtc.org94015242013-10-16 11:05:37 +000075 dropped_frames_(0),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000076 last_render_time_(0),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000077 rtp_timestamp_delta_(0),
78 crit_(CriticalSectionWrapper::CreateCriticalSection()),
79 first_send_frame_(NULL),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000080 avg_psnr_threshold_(avg_psnr_threshold),
81 avg_ssim_threshold_(avg_ssim_threshold),
pbos@webrtc.org94015242013-10-16 11:05:37 +000082 comparison_lock_(CriticalSectionWrapper::CreateCriticalSection()),
83 comparison_thread_(ThreadWrapper::CreateThread(&FrameComparisonThread,
84 this)),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000085 done_(EventWrapper::Create()) {
pbos@webrtc.org94015242013-10-16 11:05:37 +000086 unsigned int id;
87 EXPECT_TRUE(comparison_thread_->Start(id));
88 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000089
90 ~VideoAnalyzer() {
pbos@webrtc.org94015242013-10-16 11:05:37 +000091 EXPECT_TRUE(comparison_thread_->Stop());
92
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000093 while (!frames_.empty()) {
94 delete frames_.back();
95 frames_.pop_back();
96 }
97 while (!frame_pool_.empty()) {
98 delete frame_pool_.back();
99 frame_pool_.pop_back();
100 }
101 }
102
pbos@webrtc.org94015242013-10-16 11:05:37 +0000103 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; }
104
pbos@webrtc.orgcaba2d22014-05-14 13:57:12 +0000105 virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
106 size_t length) OVERRIDE {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000107 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
108 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000109 parser->Parse(packet, length, &header);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000110 {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000111 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000112 recv_times_[header.timestamp - rtp_timestamp_delta_] =
113 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
114 }
115
116 return receiver_->DeliverPacket(packet, length);
117 }
118
pbos@webrtc.org724947b2013-12-11 16:26:16 +0000119 virtual void SwapFrame(I420VideoFrame* video_frame) OVERRIDE {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000120 I420VideoFrame* copy = NULL;
121 {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000122 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000123 if (frame_pool_.size() > 0) {
124 copy = frame_pool_.front();
125 frame_pool_.pop_front();
126 }
127 }
128 if (copy == NULL)
129 copy = new I420VideoFrame();
130
pbos@webrtc.org724947b2013-12-11 16:26:16 +0000131 copy->CopyFrame(*video_frame);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000132 copy->set_timestamp(copy->render_time_ms() * 90);
133
134 {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000135 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000136 if (first_send_frame_ == NULL && rtp_timestamp_delta_ == 0)
137 first_send_frame_ = copy;
138
139 frames_.push_back(copy);
140 }
141
pbos@webrtc.org724947b2013-12-11 16:26:16 +0000142 input_->SwapFrame(video_frame);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000143 }
144
pbos@webrtc.org27326b62013-11-20 12:17:04 +0000145 virtual bool SendRtp(const uint8_t* packet, size_t length) OVERRIDE {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000146 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
147 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000148 parser->Parse(packet, length, &header);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000149
150 {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000151 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000152 if (rtp_timestamp_delta_ == 0) {
153 rtp_timestamp_delta_ =
154 header.timestamp - first_send_frame_->timestamp();
155 first_send_frame_ = NULL;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000156 }
pbos@webrtc.org7fb9ce02013-08-05 09:29:50 +0000157 send_times_[header.timestamp - rtp_timestamp_delta_] =
158 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000159 }
160
pbos@webrtc.org27326b62013-11-20 12:17:04 +0000161 return transport_->SendRtp(packet, length);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000162 }
163
pbos@webrtc.org27326b62013-11-20 12:17:04 +0000164 virtual bool SendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
165 return transport_->SendRtcp(packet, length);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000166 }
167
168 virtual void RenderFrame(const I420VideoFrame& video_frame,
169 int time_to_render_ms) OVERRIDE {
pbos@webrtc.org94015242013-10-16 11:05:37 +0000170 int64_t render_time_ms =
171 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000172 uint32_t send_timestamp = video_frame.timestamp() - rtp_timestamp_delta_;
173
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000174 CriticalSectionScoped lock(crit_.get());
175 while (frames_.front()->timestamp() < send_timestamp) {
176 AddFrameComparison(
177 frames_.front(), &last_rendered_frame_, true, render_time_ms);
178 frame_pool_.push_back(frames_.front());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000179 frames_.pop_front();
pbos@webrtc.org94015242013-10-16 11:05:37 +0000180 }
181
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000182 I420VideoFrame* reference_frame = frames_.front();
183 frames_.pop_front();
184 assert(reference_frame != NULL);
185 EXPECT_EQ(reference_frame->timestamp(), send_timestamp);
186 assert(reference_frame->timestamp() == send_timestamp);
187
188 AddFrameComparison(reference_frame, &video_frame, false, render_time_ms);
189 frame_pool_.push_back(reference_frame);
190
pbos@webrtc.org94015242013-10-16 11:05:37 +0000191 last_rendered_frame_.CopyFrame(video_frame);
192 }
193
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000194 virtual bool IsTextureSupported() const override { return false; }
195
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000196 void Wait() {
197 EXPECT_EQ(kEventSignaled, done_->Wait(FullStackTest::kLongTimeoutMs));
198 }
pbos@webrtc.org94015242013-10-16 11:05:37 +0000199
200 VideoSendStreamInput* input_;
201 Transport* transport_;
202 PacketReceiver* receiver_;
203
204 private:
205 struct FrameComparison {
206 FrameComparison(const I420VideoFrame* reference,
207 const I420VideoFrame* render,
208 bool dropped,
209 int64_t send_time_ms,
210 int64_t recv_time_ms,
211 int64_t render_time_ms)
212 : dropped(dropped),
213 send_time_ms(send_time_ms),
214 recv_time_ms(recv_time_ms),
215 render_time_ms(render_time_ms) {
216 this->reference.CopyFrame(*reference);
217 this->render.CopyFrame(*render);
218 }
219
220 FrameComparison(const FrameComparison& compare)
221 : dropped(compare.dropped),
222 send_time_ms(compare.send_time_ms),
223 recv_time_ms(compare.recv_time_ms),
224 render_time_ms(compare.render_time_ms) {
225 this->reference.CopyFrame(compare.reference);
226 this->render.CopyFrame(compare.render);
227 }
228
229 ~FrameComparison() {}
230
231 I420VideoFrame reference;
232 I420VideoFrame render;
233 bool dropped;
234 int64_t send_time_ms;
235 int64_t recv_time_ms;
236 int64_t render_time_ms;
237 };
238
239 void AddFrameComparison(const I420VideoFrame* reference,
240 const I420VideoFrame* render,
241 bool dropped,
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000242 int64_t render_time_ms)
243 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
pbos@webrtc.org94015242013-10-16 11:05:37 +0000244 int64_t send_time_ms = send_times_[reference->timestamp()];
245 send_times_.erase(reference->timestamp());
246 int64_t recv_time_ms = recv_times_[reference->timestamp()];
247 recv_times_.erase(reference->timestamp());
248
249 CriticalSectionScoped crit(comparison_lock_.get());
250 comparisons_.push_back(FrameComparison(reference,
251 render,
252 dropped,
253 send_time_ms,
254 recv_time_ms,
255 render_time_ms));
256 }
257
258 static bool FrameComparisonThread(void* obj) {
259 return static_cast<VideoAnalyzer*>(obj)->CompareFrames();
260 }
261
262 bool CompareFrames() {
263 assert(frames_left_ > 0);
264
265 I420VideoFrame reference;
266 I420VideoFrame render;
267 bool dropped;
268 int64_t send_time_ms;
269 int64_t recv_time_ms;
270 int64_t render_time_ms;
271
272 SleepMs(10);
273
274 while (true) {
275 {
276 CriticalSectionScoped crit(comparison_lock_.get());
277 if (comparisons_.empty())
278 return true;
279 reference.SwapFrame(&comparisons_.front().reference);
280 render.SwapFrame(&comparisons_.front().render);
281 dropped = comparisons_.front().dropped;
282 send_time_ms = comparisons_.front().send_time_ms;
283 recv_time_ms = comparisons_.front().recv_time_ms;
284 render_time_ms = comparisons_.front().render_time_ms;
285 comparisons_.pop_front();
286 }
287
288 PerformFrameComparison(&reference,
289 &render,
290 dropped,
291 send_time_ms,
292 recv_time_ms,
293 render_time_ms);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000294
295 if (--frames_left_ == 0) {
296 PrintResult("psnr", psnr_, " dB");
297 PrintResult("ssim", ssim_, "");
298 PrintResult("sender_time", sender_time_, " ms");
pbos@webrtc.orga5d29fc2014-11-10 09:54:19 +0000299 printf("RESULT dropped_frames: %s = %d frames\n", test_label_,
300 dropped_frames_);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000301 PrintResult("receiver_time", receiver_time_, " ms");
302 PrintResult("total_delay_incl_network", end_to_end_, " ms");
303 PrintResult("time_between_rendered_frames", rendered_delta_, " ms");
304 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_);
305 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000306 done_->Set();
pbos@webrtc.org94015242013-10-16 11:05:37 +0000307
308 return false;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000309 }
310 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000311 }
312
pbos@webrtc.org94015242013-10-16 11:05:37 +0000313 void PerformFrameComparison(const I420VideoFrame* reference,
314 const I420VideoFrame* render,
315 bool dropped,
316 int64_t send_time_ms,
317 int64_t recv_time_ms,
318 int64_t render_time_ms) {
319 psnr_.AddSample(I420PSNR(reference, render));
320 ssim_.AddSample(I420SSIM(reference, render));
321 if (dropped) {
322 ++dropped_frames_;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000323 return;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000324 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000325 if (last_render_time_ != 0)
pbos@webrtc.org94015242013-10-16 11:05:37 +0000326 rendered_delta_.AddSample(render_time_ms - last_render_time_);
327 last_render_time_ = render_time_ms;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000328
pbos@webrtc.org94015242013-10-16 11:05:37 +0000329 int64_t input_time_ms = reference->render_time_ms();
330 sender_time_.AddSample(send_time_ms - input_time_ms);
331 receiver_time_.AddSample(render_time_ms - recv_time_ms);
332 end_to_end_.AddSample(render_time_ms - input_time_ms);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000333 }
334
335 void PrintResult(const char* result_type,
336 test::Statistics stats,
337 const char* unit) {
338 printf("RESULT %s: %s = {%f, %f}%s\n",
339 result_type,
340 test_label_,
341 stats.Mean(),
342 stats.StandardDeviation(),
343 unit);
344 }
345
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000346 const char* const test_label_;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000347 test::Statistics sender_time_;
348 test::Statistics receiver_time_;
349 test::Statistics psnr_;
350 test::Statistics ssim_;
351 test::Statistics end_to_end_;
352 test::Statistics rendered_delta_;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000353 int frames_left_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000354 int dropped_frames_;
355 int64_t last_render_time_;
356 uint32_t rtp_timestamp_delta_;
357
358 const scoped_ptr<CriticalSectionWrapper> crit_;
359 std::deque<I420VideoFrame*> frames_ GUARDED_BY(crit_);
360 std::deque<I420VideoFrame*> frame_pool_ GUARDED_BY(crit_);
361 I420VideoFrame last_rendered_frame_ GUARDED_BY(crit_);
362 std::map<uint32_t, int64_t> send_times_ GUARDED_BY(crit_);
363 std::map<uint32_t, int64_t> recv_times_ GUARDED_BY(crit_);
364 I420VideoFrame* first_send_frame_ GUARDED_BY(crit_);
pbos@webrtc.orgb35b1362014-10-20 09:14:38 +0000365 const double avg_psnr_threshold_;
366 const double avg_ssim_threshold_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000367
368 const scoped_ptr<CriticalSectionWrapper> comparison_lock_;
369 const scoped_ptr<ThreadWrapper> comparison_thread_;
370 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_);
371 const scoped_ptr<EventWrapper> done_;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000372};
373
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000374void FullStackTest::RunTest(const FullStackTestParams& params) {
375 test::DirectTransport send_transport(params.link);
376 test::DirectTransport recv_transport(params.link);
pbos@webrtc.org94015242013-10-16 11:05:37 +0000377 VideoAnalyzer analyzer(NULL,
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000378 &send_transport,
pbos@webrtc.org94015242013-10-16 11:05:37 +0000379 params.test_label,
380 params.avg_psnr_threshold,
381 params.avg_ssim_threshold,
pbos@webrtc.org023b1012014-05-13 11:26:40 +0000382 kFullStackTestDurationSecs * params.clip.fps);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000383
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000384 CreateCalls(Call::Config(&analyzer), Call::Config(&recv_transport));
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +0000385
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000386 analyzer.SetReceiver(receiver_call_->Receiver());
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000387 send_transport.SetReceiver(&analyzer);
388 recv_transport.SetReceiver(sender_call_->Receiver());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000389
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000390 CreateSendConfig(1);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000391
pbos@webrtc.orgab990ae2014-09-17 09:02:25 +0000392 scoped_ptr<VideoEncoder> encoder(
393 VideoEncoder::Create(VideoEncoder::kVp8));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000394 send_config_.encoder_settings.encoder = encoder.get();
395 send_config_.encoder_settings.payload_name = "VP8";
396 send_config_.encoder_settings.payload_type = 124;
stefan@webrtc.orgc216b9a2014-10-14 10:38:49 +0000397 send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000398
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000399 VideoStream* stream = &encoder_config_.streams[0];
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +0000400 stream->width = params.clip.width;
401 stream->height = params.clip.height;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000402 stream->min_bitrate_bps = params.min_bitrate_bps;
403 stream->target_bitrate_bps = params.target_bitrate_bps;
404 stream->max_bitrate_bps = params.max_bitrate_bps;
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +0000405 stream->max_framerate = params.clip.fps;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000406
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000407 CreateMatchingReceiveConfigs();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000408 receive_configs_[0].renderer = &analyzer;
stefan@webrtc.orgc216b9a2014-10-14 10:38:49 +0000409 receive_configs_[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000410
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000411 CreateStreams();
412 analyzer.input_ = send_stream_->Input();
413
414 frame_generator_capturer_.reset(
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000415 test::FrameGeneratorCapturer::CreateFromYuvFile(
pbos@webrtc.org4c966012013-08-21 12:07:37 +0000416 &analyzer,
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000417 test::ResourcePath(params.clip.name, "yuv").c_str(),
418 params.clip.width,
419 params.clip.height,
420 params.clip.fps,
421 Clock::GetRealTimeClock()));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000422
423 ASSERT_TRUE(frame_generator_capturer_.get() != NULL)
pbos@webrtc.org94015242013-10-16 11:05:37 +0000424 << "Could not create capturer for " << params.clip.name
425 << ".yuv. Is this resource file present?";
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000426
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000427 Start();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000428
429 analyzer.Wait();
430
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000431 send_transport.StopSending();
432 recv_transport.StopSending();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000433
434 Stop();
435
436 DestroyStreams();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000437}
438
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000439TEST_F(FullStackTest, ParisQcifWithoutPacketLoss) {
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000440 FullStackTestParams paris_qcif = {"net_delay_0_0_plr_0",
441 {"paris_qcif", 176, 144, 30},
442 300000,
443 300000,
444 300000,
445 36.0,
446 0.96
447 };
448 RunTest(paris_qcif);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000449}
450
451TEST_F(FullStackTest, ForemanCifWithoutPacketLoss) {
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000452 // TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif.
453 FullStackTestParams foreman_cif = {"foreman_cif_net_delay_0_0_plr_0",
454 {"foreman_cif", 352, 288, 30},
455 700000,
456 700000,
457 700000,
458 0.0,
459 0.0
460 };
461 RunTest(foreman_cif);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000462}
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000463
stefan@webrtc.orgc216b9a2014-10-14 10:38:49 +0000464TEST_F(FullStackTest, ForemanCifPlr5) {
465 FullStackTestParams foreman_cif = {"foreman_cif_delay_50_0_plr_5",
466 {"foreman_cif", 352, 288, 30},
467 30000,
468 500000,
469 2000000,
470 0.0,
471 0.0
472 };
473 foreman_cif.link.loss_percent = 5;
474 foreman_cif.link.queue_delay_ms = 50;
475 RunTest(foreman_cif);
476}
477
stefan@webrtc.orgb8e9e442014-07-09 11:29:06 +0000478TEST_F(FullStackTest, ForemanCif500kbps) {
479 FullStackTestParams foreman_cif = {"foreman_cif_500kbps",
480 {"foreman_cif", 352, 288, 30},
481 30000,
482 500000,
483 2000000,
484 0.0,
485 0.0
486 };
487 foreman_cif.link.queue_length_packets = 0;
488 foreman_cif.link.queue_delay_ms = 0;
489 foreman_cif.link.link_capacity_kbps = 500;
490 RunTest(foreman_cif);
491}
492
493TEST_F(FullStackTest, ForemanCif500kbpsLimitedQueue) {
494 FullStackTestParams foreman_cif = {"foreman_cif_500kbps_32pkts_queue",
495 {"foreman_cif", 352, 288, 30},
496 30000,
497 500000,
498 2000000,
499 0.0,
500 0.0
501 };
502 foreman_cif.link.queue_length_packets = 32;
503 foreman_cif.link.queue_delay_ms = 0;
504 foreman_cif.link.link_capacity_kbps = 500;
505 RunTest(foreman_cif);
506}
507
508TEST_F(FullStackTest, ForemanCif500kbps100ms) {
509 FullStackTestParams foreman_cif = {"foreman_cif_500kbps_100ms",
510 {"foreman_cif", 352, 288, 30},
511 30000,
512 500000,
513 2000000,
514 0.0,
515 0.0
516 };
517 foreman_cif.link.queue_length_packets = 0;
518 foreman_cif.link.queue_delay_ms = 100;
519 foreman_cif.link.link_capacity_kbps = 500;
520 RunTest(foreman_cif);
521}
522
523TEST_F(FullStackTest, ForemanCif500kbps100msLimitedQueue) {
524 FullStackTestParams foreman_cif = {"foreman_cif_500kbps_100ms_32pkts_queue",
525 {"foreman_cif", 352, 288, 30},
526 30000,
527 500000,
528 2000000,
529 0.0,
530 0.0
531 };
532 foreman_cif.link.queue_length_packets = 32;
533 foreman_cif.link.queue_delay_ms = 100;
534 foreman_cif.link.link_capacity_kbps = 500;
535 RunTest(foreman_cif);
536}
537
538TEST_F(FullStackTest, ForemanCif1000kbps100msLimitedQueue) {
539 FullStackTestParams foreman_cif = {"foreman_cif_1000kbps_100ms_32pkts_queue",
540 {"foreman_cif", 352, 288, 30},
541 30000,
542 2000000,
543 2000000,
544 0.0,
545 0.0
546 };
547 foreman_cif.link.queue_length_packets = 32;
548 foreman_cif.link.queue_delay_ms = 100;
549 foreman_cif.link.link_capacity_kbps = 1000;
550 RunTest(foreman_cif);
551}
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000552} // namespace webrtc