OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 | 11 |
12 #include <algorithm> | |
13 #include <deque> | 12 #include <deque> |
14 #include <map> | 13 #include <map> |
15 #include <vector> | |
16 | 14 |
17 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
18 | 16 |
19 #include "webrtc/base/checks.h" | |
20 #include "webrtc/base/format_macros.h" | 17 #include "webrtc/base/format_macros.h" |
21 #include "webrtc/base/scoped_ptr.h" | 18 #include "webrtc/base/scoped_ptr.h" |
| 19 #include "webrtc/base/thread_annotations.h" |
22 #include "webrtc/call.h" | 20 #include "webrtc/call.h" |
23 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 21 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
| 22 #include "webrtc/frame_callback.h" |
24 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" | 23 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" |
| 24 #include "webrtc/system_wrappers/interface/clock.h" |
25 #include "webrtc/system_wrappers/interface/cpu_info.h" | 25 #include "webrtc/system_wrappers/interface/cpu_info.h" |
26 #include "webrtc/test/layer_filtering_transport.h" | 26 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" |
27 #include "webrtc/test/run_loop.h" | 27 #include "webrtc/system_wrappers/interface/event_wrapper.h" |
| 28 #include "webrtc/system_wrappers/interface/sleep.h" |
| 29 #include "webrtc/test/call_test.h" |
| 30 #include "webrtc/test/direct_transport.h" |
| 31 #include "webrtc/test/encoder_settings.h" |
| 32 #include "webrtc/test/fake_encoder.h" |
| 33 #include "webrtc/test/frame_generator.h" |
| 34 #include "webrtc/test/frame_generator_capturer.h" |
28 #include "webrtc/test/statistics.h" | 35 #include "webrtc/test/statistics.h" |
29 #include "webrtc/test/testsupport/fileutils.h" | 36 #include "webrtc/test/testsupport/fileutils.h" |
30 #include "webrtc/test/video_renderer.h" | 37 #include "webrtc/typedefs.h" |
31 #include "webrtc/video/video_quality_test.h" | |
32 | 38 |
33 namespace webrtc { | 39 namespace webrtc { |
34 | 40 |
35 static const int kTransportSeqExtensionId = | 41 enum class ContentMode { |
36 VideoQualityTest::kAbsSendTimeExtensionId + 1; | 42 kRealTimeVideo, |
| 43 kScreensharingStaticImage, |
| 44 kScreensharingScrollingImage, |
| 45 }; |
| 46 |
| 47 struct FullStackTestBeforeParams { |
| 48 const char* test_label; |
| 49 struct { |
| 50 const char* name; |
| 51 size_t width, height; |
| 52 int fps; |
| 53 } clip; |
| 54 ContentMode mode; |
| 55 int min_bitrate_bps; |
| 56 int target_bitrate_bps; |
| 57 int max_bitrate_bps; |
| 58 double avg_psnr_threshold; |
| 59 double avg_ssim_threshold; |
| 60 int test_durations_secs; |
| 61 std::string codec; |
| 62 FakeNetworkPipe::Config link; |
| 63 std::string graph_data_output_filename; |
| 64 }; |
| 65 |
| 66 class FullStackTestBefore : public test::CallTest { |
| 67 protected: |
| 68 void RunTest(const FullStackTestBeforeParams& params); |
| 69 }; |
| 70 |
| 71 static const int kFullStackTestBeforeDurationSecs = 60; |
37 static const int kSendStatsPollingIntervalMs = 1000; | 72 static const int kSendStatsPollingIntervalMs = 1000; |
38 static const int kPayloadTypeVP8 = 123; | |
39 static const int kPayloadTypeVP9 = 124; | |
40 | 73 |
41 class VideoAnalyzer : public PacketReceiver, | 74 class VideoAnalyzerBefore : public PacketReceiver, |
42 public Transport, | 75 public Transport, |
43 public VideoRenderer, | 76 public VideoRenderer, |
44 public VideoCaptureInput, | 77 public VideoCaptureInput, |
45 public EncodedFrameObserver { | 78 public EncodedFrameObserver { |
46 public: | 79 public: |
47 VideoAnalyzer(VideoCaptureInput* input, | 80 VideoAnalyzerBefore(VideoCaptureInput* input, |
48 Transport* transport, | 81 Transport* transport, |
49 const std::string& test_label, | 82 const char* test_label, |
50 double avg_psnr_threshold, | 83 double avg_psnr_threshold, |
51 double avg_ssim_threshold, | 84 double avg_ssim_threshold, |
52 int duration_frames, | 85 int duration_frames, |
53 FILE* graph_data_output_file) | 86 const std::string& graph_data_output_filename) |
54 : input_(input), | 87 : input_(input), |
55 transport_(transport), | 88 transport_(transport), |
56 receiver_(nullptr), | 89 receiver_(nullptr), |
57 send_stream_(nullptr), | 90 send_stream_(nullptr), |
58 test_label_(test_label), | 91 test_label_(test_label), |
59 graph_data_output_file_(graph_data_output_file), | 92 graph_data_output_filename_(graph_data_output_filename), |
60 frames_to_process_(duration_frames), | 93 frames_to_process_(duration_frames), |
61 frames_recorded_(0), | 94 frames_recorded_(0), |
62 frames_processed_(0), | 95 frames_processed_(0), |
63 dropped_frames_(0), | 96 dropped_frames_(0), |
64 last_render_time_(0), | 97 last_render_time_(0), |
65 rtp_timestamp_delta_(0), | 98 rtp_timestamp_delta_(0), |
66 avg_psnr_threshold_(avg_psnr_threshold), | 99 avg_psnr_threshold_(avg_psnr_threshold), |
67 avg_ssim_threshold_(avg_ssim_threshold), | 100 avg_ssim_threshold_(avg_ssim_threshold), |
68 comparison_available_event_(EventWrapper::Create()), | 101 comparison_available_event_(EventWrapper::Create()), |
69 done_(EventWrapper::Create()) { | 102 done_(EventWrapper::Create()) { |
(...skipping 21 matching lines...) Expand all Loading... |
91 ThreadWrapper::CreateThread(&FrameComparisonThread, this, "Analyzer"); | 124 ThreadWrapper::CreateThread(&FrameComparisonThread, this, "Analyzer"); |
92 EXPECT_TRUE(thread->Start()); | 125 EXPECT_TRUE(thread->Start()); |
93 comparison_thread_pool_.push_back(thread.release()); | 126 comparison_thread_pool_.push_back(thread.release()); |
94 } | 127 } |
95 | 128 |
96 stats_polling_thread_ = | 129 stats_polling_thread_ = |
97 ThreadWrapper::CreateThread(&PollStatsThread, this, "StatsPoller"); | 130 ThreadWrapper::CreateThread(&PollStatsThread, this, "StatsPoller"); |
98 EXPECT_TRUE(stats_polling_thread_->Start()); | 131 EXPECT_TRUE(stats_polling_thread_->Start()); |
99 } | 132 } |
100 | 133 |
101 ~VideoAnalyzer() { | 134 ~VideoAnalyzerBefore() { |
102 for (ThreadWrapper* thread : comparison_thread_pool_) { | 135 for (ThreadWrapper* thread : comparison_thread_pool_) { |
103 EXPECT_TRUE(thread->Stop()); | 136 EXPECT_TRUE(thread->Stop()); |
104 delete thread; | 137 delete thread; |
105 } | 138 } |
106 } | 139 } |
107 | 140 |
108 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; } | 141 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; } |
109 | 142 |
110 DeliveryStatus DeliverPacket(MediaType media_type, | 143 DeliveryStatus DeliverPacket(MediaType media_type, |
111 const uint8_t* packet, | 144 const uint8_t* packet, |
(...skipping 29 matching lines...) Expand all Loading... |
141 bool SendRtp(const uint8_t* packet, | 174 bool SendRtp(const uint8_t* packet, |
142 size_t length, | 175 size_t length, |
143 const PacketOptions& options) override { | 176 const PacketOptions& options) override { |
144 rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); | 177 rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); |
145 RTPHeader header; | 178 RTPHeader header; |
146 parser->Parse(packet, length, &header); | 179 parser->Parse(packet, length, &header); |
147 | 180 |
148 { | 181 { |
149 rtc::CritScope lock(&crit_); | 182 rtc::CritScope lock(&crit_); |
150 if (rtp_timestamp_delta_ == 0) { | 183 if (rtp_timestamp_delta_ == 0) { |
151 rtp_timestamp_delta_ = header.timestamp - first_send_frame_.timestamp(); | 184 rtp_timestamp_delta_ = |
| 185 header.timestamp - first_send_frame_.timestamp(); |
152 first_send_frame_.Reset(); | 186 first_send_frame_.Reset(); |
153 } | 187 } |
154 uint32_t timestamp = header.timestamp - rtp_timestamp_delta_; | 188 uint32_t timestamp = header.timestamp - rtp_timestamp_delta_; |
155 send_times_[timestamp] = | 189 send_times_[timestamp] = |
156 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); | 190 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); |
157 encoded_frame_sizes_[timestamp] += | 191 encoded_frame_sizes_[timestamp] += |
158 length - (header.headerLength + header.paddingLength); | 192 length - (header.headerLength + header.paddingLength); |
159 } | 193 } |
160 | 194 |
161 return transport_->SendRtp(packet, length, options); | 195 return transport_->SendRtp(packet, length, options); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 bool IsTextureSupported() const override { return false; } | 233 bool IsTextureSupported() const override { return false; } |
200 | 234 |
201 void Wait() { | 235 void Wait() { |
202 // Frame comparisons can be very expensive. Wait for test to be done, but | 236 // Frame comparisons can be very expensive. Wait for test to be done, but |
203 // at time-out check if frames_processed is going up. If so, give it more | 237 // at time-out check if frames_processed is going up. If so, give it more |
204 // time, otherwise fail. Hopefully this will reduce test flakiness. | 238 // time, otherwise fail. Hopefully this will reduce test flakiness. |
205 | 239 |
206 int last_frames_processed = -1; | 240 int last_frames_processed = -1; |
207 EventTypeWrapper eventType; | 241 EventTypeWrapper eventType; |
208 int iteration = 0; | 242 int iteration = 0; |
209 while ((eventType = done_->Wait(VideoQualityTest::kDefaultTimeoutMs)) != | 243 while ((eventType = done_->Wait(FullStackTestBefore::kDefaultTimeoutMs)) != |
210 kEventSignaled) { | 244 kEventSignaled) { |
211 int frames_processed; | 245 int frames_processed; |
212 { | 246 { |
213 rtc::CritScope crit(&comparison_lock_); | 247 rtc::CritScope crit(&comparison_lock_); |
214 frames_processed = frames_processed_; | 248 frames_processed = frames_processed_; |
215 } | 249 } |
216 | 250 |
217 // Print some output so test infrastructure won't think we've crashed. | 251 // Print some output so test infrastructure won't think we've crashed. |
218 const char* kKeepAliveMessages[3] = { | 252 const char* kKeepAliveMessages[3] = { |
219 "Uh, I'm-I'm not quite dead, sir.", | 253 "Uh, I'm-I'm not quite dead, sir.", |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 render_copy.CopyFrame(render); | 359 render_copy.CopyFrame(render); |
326 | 360 |
327 rtc::CritScope crit(&comparison_lock_); | 361 rtc::CritScope crit(&comparison_lock_); |
328 comparisons_.push_back(FrameComparison(reference_copy, render_copy, dropped, | 362 comparisons_.push_back(FrameComparison(reference_copy, render_copy, dropped, |
329 send_time_ms, recv_time_ms, | 363 send_time_ms, recv_time_ms, |
330 render_time_ms, encoded_size)); | 364 render_time_ms, encoded_size)); |
331 comparison_available_event_->Set(); | 365 comparison_available_event_->Set(); |
332 } | 366 } |
333 | 367 |
334 static bool PollStatsThread(void* obj) { | 368 static bool PollStatsThread(void* obj) { |
335 return static_cast<VideoAnalyzer*>(obj)->PollStats(); | 369 return static_cast<VideoAnalyzerBefore*>(obj)->PollStats(); |
336 } | 370 } |
337 | 371 |
338 bool PollStats() { | 372 bool PollStats() { |
339 switch (done_->Wait(kSendStatsPollingIntervalMs)) { | 373 switch (done_->Wait(kSendStatsPollingIntervalMs)) { |
340 case kEventSignaled: | 374 case kEventSignaled: |
341 case kEventError: | 375 case kEventError: |
342 done_->Set(); // Make sure main thread is also signaled. | 376 done_->Set(); // Make sure main thread is also signaled. |
343 return false; | 377 return false; |
344 case kEventTimeout: | 378 case kEventTimeout: |
345 break; | 379 break; |
346 default: | 380 default: |
347 RTC_NOTREACHED(); | 381 RTC_NOTREACHED(); |
348 } | 382 } |
349 | 383 |
350 VideoSendStream::Stats stats = send_stream_->GetStats(); | 384 VideoSendStream::Stats stats = send_stream_->GetStats(); |
351 | 385 |
352 rtc::CritScope crit(&comparison_lock_); | 386 rtc::CritScope crit(&comparison_lock_); |
353 encode_frame_rate_.AddSample(stats.encode_frame_rate); | 387 encode_frame_rate_.AddSample(stats.encode_frame_rate); |
354 encode_time_ms.AddSample(stats.avg_encode_time_ms); | 388 encode_time_ms.AddSample(stats.avg_encode_time_ms); |
355 encode_usage_percent.AddSample(stats.encode_usage_percent); | 389 encode_usage_percent.AddSample(stats.encode_usage_percent); |
356 media_bitrate_bps.AddSample(stats.media_bitrate_bps); | 390 media_bitrate_bps.AddSample(stats.media_bitrate_bps); |
357 | 391 |
358 return true; | 392 return true; |
359 } | 393 } |
360 | 394 |
361 static bool FrameComparisonThread(void* obj) { | 395 static bool FrameComparisonThread(void* obj) { |
362 return static_cast<VideoAnalyzer*>(obj)->CompareFrames(); | 396 return static_cast<VideoAnalyzerBefore*>(obj)->CompareFrames(); |
363 } | 397 } |
364 | 398 |
365 bool CompareFrames() { | 399 bool CompareFrames() { |
366 if (AllFramesRecorded()) | 400 if (AllFramesRecorded()) |
367 return false; | 401 return false; |
368 | 402 |
369 VideoFrame reference; | 403 VideoFrame reference; |
370 VideoFrame render; | 404 VideoFrame render; |
371 FrameComparison comparison; | 405 FrameComparison comparison; |
372 | 406 |
373 if (!PopComparison(&comparison)) { | 407 if (!PopComparison(&comparison)) { |
374 // Wait until new comparison task is available, or test is done. | 408 // Wait until new comparison task is available, or test is done. |
375 // If done, wake up remaining threads waiting. | 409 // If done, wake up remaining threads waiting. |
376 comparison_available_event_->Wait(1000); | 410 comparison_available_event_->Wait(1000); |
377 if (AllFramesRecorded()) { | 411 if (AllFramesRecorded()) { |
378 comparison_available_event_->Set(); | 412 comparison_available_event_->Set(); |
379 return false; | 413 return false; |
380 } | 414 } |
381 return true; // Try again. | 415 return true; // Try again. |
382 } | 416 } |
383 | 417 |
384 PerformFrameComparison(comparison); | 418 PerformFrameComparison(comparison); |
385 | 419 |
386 if (FrameProcessed()) { | 420 if (FrameProcessed()) { |
387 PrintResults(); | 421 PrintResults(); |
388 if (graph_data_output_file_) | 422 if (!graph_data_output_filename_.empty()) |
389 PrintSamplesToFile(); | 423 PrintSamplesToFile(); |
390 done_->Set(); | 424 done_->Set(); |
391 comparison_available_event_->Set(); | 425 comparison_available_event_->Set(); |
392 return false; | 426 return false; |
393 } | 427 } |
394 | 428 |
395 return true; | 429 return true; |
396 } | 430 } |
397 | 431 |
398 bool PopComparison(FrameComparison* comparison) { | 432 bool PopComparison(FrameComparison* comparison) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 ++frames_processed_; | 466 ++frames_processed_; |
433 assert(frames_processed_ <= frames_to_process_); | 467 assert(frames_processed_ <= frames_to_process_); |
434 return frames_processed_ == frames_to_process_; | 468 return frames_processed_ == frames_to_process_; |
435 } | 469 } |
436 | 470 |
437 void PrintResults() { | 471 void PrintResults() { |
438 rtc::CritScope crit(&comparison_lock_); | 472 rtc::CritScope crit(&comparison_lock_); |
439 PrintResult("psnr", psnr_, " dB"); | 473 PrintResult("psnr", psnr_, " dB"); |
440 PrintResult("ssim", ssim_, ""); | 474 PrintResult("ssim", ssim_, ""); |
441 PrintResult("sender_time", sender_time_, " ms"); | 475 PrintResult("sender_time", sender_time_, " ms"); |
442 printf("RESULT dropped_frames: %s = %d frames\n", test_label_.c_str(), | 476 printf("RESULT dropped_frames: %s = %d frames\n", test_label_, |
443 dropped_frames_); | 477 dropped_frames_); |
444 PrintResult("receiver_time", receiver_time_, " ms"); | 478 PrintResult("receiver_time", receiver_time_, " ms"); |
445 PrintResult("total_delay_incl_network", end_to_end_, " ms"); | 479 PrintResult("total_delay_incl_network", end_to_end_, " ms"); |
446 PrintResult("time_between_rendered_frames", rendered_delta_, " ms"); | 480 PrintResult("time_between_rendered_frames", rendered_delta_, " ms"); |
447 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes"); | 481 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes"); |
448 PrintResult("encode_frame_rate", encode_frame_rate_, " fps"); | 482 PrintResult("encode_frame_rate", encode_frame_rate_, " fps"); |
449 PrintResult("encode_time", encode_time_ms, " ms"); | 483 PrintResult("encode_time", encode_time_ms, " ms"); |
450 PrintResult("encode_usage_percent", encode_usage_percent, " percent"); | 484 PrintResult("encode_usage_percent", encode_usage_percent, " percent"); |
451 PrintResult("media_bitrate", media_bitrate_bps, " bps"); | 485 PrintResult("media_bitrate", media_bitrate_bps, " bps"); |
452 | 486 |
453 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_); | 487 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_); |
454 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_); | 488 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_); |
455 } | 489 } |
456 | 490 |
457 void PerformFrameComparison(const FrameComparison& comparison) { | 491 void PerformFrameComparison(const FrameComparison& comparison) { |
458 // Perform expensive psnr and ssim calculations while not holding lock. | 492 // Perform expensive psnr and ssim calculations while not holding lock. |
459 double psnr = I420PSNR(&comparison.reference, &comparison.render); | 493 double psnr = I420PSNR(&comparison.reference, &comparison.render); |
460 double ssim = I420SSIM(&comparison.reference, &comparison.render); | 494 double ssim = I420SSIM(&comparison.reference, &comparison.render); |
461 | 495 |
462 int64_t input_time_ms = comparison.reference.ntp_time_ms(); | 496 int64_t input_time_ms = comparison.reference.ntp_time_ms(); |
463 | 497 |
464 rtc::CritScope crit(&comparison_lock_); | 498 rtc::CritScope crit(&comparison_lock_); |
465 if (graph_data_output_file_) { | 499 if (!graph_data_output_filename_.empty()) { |
466 samples_.push_back( | 500 samples_.push_back(Sample( |
467 Sample(comparison.dropped, input_time_ms, comparison.send_time_ms, | 501 comparison.dropped, input_time_ms, comparison.send_time_ms, |
468 comparison.recv_time_ms, comparison.encoded_frame_size, psnr, | 502 comparison.recv_time_ms, comparison.encoded_frame_size, psnr, ssim, |
469 ssim, comparison.render_time_ms)); | 503 comparison.render_time_ms)); |
470 } | 504 } |
471 psnr_.AddSample(psnr); | 505 psnr_.AddSample(psnr); |
472 ssim_.AddSample(ssim); | 506 ssim_.AddSample(ssim); |
473 | 507 |
474 if (comparison.dropped) { | 508 if (comparison.dropped) { |
475 ++dropped_frames_; | 509 ++dropped_frames_; |
476 return; | 510 return; |
477 } | 511 } |
478 if (last_render_time_ != 0) | 512 if (last_render_time_ != 0) |
479 rendered_delta_.AddSample(comparison.render_time_ms - last_render_time_); | 513 rendered_delta_.AddSample(comparison.render_time_ms - last_render_time_); |
480 last_render_time_ = comparison.render_time_ms; | 514 last_render_time_ = comparison.render_time_ms; |
481 | 515 |
482 sender_time_.AddSample(comparison.send_time_ms - input_time_ms); | 516 sender_time_.AddSample(comparison.send_time_ms - input_time_ms); |
483 receiver_time_.AddSample(comparison.render_time_ms - | 517 receiver_time_.AddSample(comparison.render_time_ms - |
484 comparison.recv_time_ms); | 518 comparison.recv_time_ms); |
485 end_to_end_.AddSample(comparison.render_time_ms - input_time_ms); | 519 end_to_end_.AddSample(comparison.render_time_ms - input_time_ms); |
486 encoded_frame_size_.AddSample(comparison.encoded_frame_size); | 520 encoded_frame_size_.AddSample(comparison.encoded_frame_size); |
487 } | 521 } |
488 | 522 |
489 void PrintResult(const char* result_type, | 523 void PrintResult(const char* result_type, |
490 test::Statistics stats, | 524 test::Statistics stats, |
491 const char* unit) { | 525 const char* unit) { |
492 printf("RESULT %s: %s = {%f, %f}%s\n", | 526 printf("RESULT %s: %s = {%f, %f}%s\n", |
493 result_type, | 527 result_type, |
494 test_label_.c_str(), | 528 test_label_, |
495 stats.Mean(), | 529 stats.Mean(), |
496 stats.StandardDeviation(), | 530 stats.StandardDeviation(), |
497 unit); | 531 unit); |
498 } | 532 } |
499 | 533 |
500 void PrintSamplesToFile(void) { | 534 void PrintSamplesToFile(void) { |
501 FILE* out = graph_data_output_file_; | 535 FILE* out = fopen(graph_data_output_filename_.c_str(), "w"); |
| 536 RTC_CHECK(out != nullptr) << "Couldn't open file: " |
| 537 << graph_data_output_filename_; |
| 538 |
502 rtc::CritScope crit(&comparison_lock_); | 539 rtc::CritScope crit(&comparison_lock_); |
503 std::sort(samples_.begin(), samples_.end(), | 540 std::sort(samples_.begin(), samples_.end(), |
504 [](const Sample& A, const Sample& B) -> bool { | 541 [](const Sample& A, const Sample& B) |
505 return A.input_time_ms < B.input_time_ms; | 542 -> bool { return A.input_time_ms < B.input_time_ms; }); |
506 }); | |
507 | 543 |
508 fprintf(out, "%s\n", test_label_.c_str()); | 544 fprintf(out, "%s\n", test_label_); |
509 fprintf(out, "%" PRIuS "\n", samples_.size()); | 545 fprintf(out, "%" PRIuS "\n", samples_.size()); |
510 fprintf(out, | 546 fprintf(out, |
511 "dropped " | 547 "dropped " |
512 "input_time_ms " | 548 "input_time_ms " |
513 "send_time_ms " | 549 "send_time_ms " |
514 "recv_time_ms " | 550 "recv_time_ms " |
515 "encoded_frame_size " | 551 "encoded_frame_size " |
516 "psnr " | 552 "psnr " |
517 "ssim " | 553 "ssim " |
518 "render_time_ms\n"); | 554 "render_time_ms\n"); |
519 for (const Sample& sample : samples_) { | 555 for (const Sample& sample : samples_) { |
520 fprintf(out, "%lf %lf %lf %lf %lf %lf %lf %lf\n", sample.dropped, | 556 fprintf(out, "%lf %lf %lf %lf %lf %lf %lf %lf\n", sample.dropped, |
521 sample.input_time_ms, sample.send_time_ms, sample.recv_time_ms, | 557 sample.input_time_ms, sample.send_time_ms, sample.recv_time_ms, |
522 sample.encoded_frame_size, sample.psnr, sample.ssim, | 558 sample.encoded_frame_size, sample.psnr, sample.ssim, |
523 sample.render_time_ms); | 559 sample.render_time_ms); |
524 } | 560 } |
| 561 fclose(out); |
525 } | 562 } |
526 | 563 |
527 const std::string test_label_; | 564 const char* const test_label_; |
528 FILE* const graph_data_output_file_; | 565 std::string graph_data_output_filename_; |
529 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); | 566 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); |
530 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); | 567 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); |
531 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); | 568 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); |
532 test::Statistics psnr_ GUARDED_BY(comparison_lock_); | 569 test::Statistics psnr_ GUARDED_BY(comparison_lock_); |
533 test::Statistics ssim_ GUARDED_BY(comparison_lock_); | 570 test::Statistics ssim_ GUARDED_BY(comparison_lock_); |
534 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); | 571 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); |
535 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); | 572 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); |
536 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); | 573 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); |
537 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); | 574 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); |
538 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_); | 575 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_); |
539 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_); | 576 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_); |
540 test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_); | 577 test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_); |
541 | 578 |
542 const int frames_to_process_; | 579 const int frames_to_process_; |
543 int frames_recorded_; | 580 int frames_recorded_; |
544 int frames_processed_; | 581 int frames_processed_; |
545 int dropped_frames_; | 582 int dropped_frames_; |
546 int64_t last_render_time_; | 583 int64_t last_render_time_; |
547 uint32_t rtp_timestamp_delta_; | 584 uint32_t rtp_timestamp_delta_; |
548 | 585 |
549 rtc::CriticalSection crit_; | 586 rtc::CriticalSection crit_; |
550 std::deque<VideoFrame> frames_ GUARDED_BY(crit_); | 587 std::deque<VideoFrame> frames_ GUARDED_BY(crit_); |
| 588 std::deque<VideoSendStream::Stats> send_stats_ GUARDED_BY(crit_); |
551 VideoFrame last_rendered_frame_ GUARDED_BY(crit_); | 589 VideoFrame last_rendered_frame_ GUARDED_BY(crit_); |
552 std::map<uint32_t, int64_t> send_times_ GUARDED_BY(crit_); | 590 std::map<uint32_t, int64_t> send_times_ GUARDED_BY(crit_); |
553 std::map<uint32_t, int64_t> recv_times_ GUARDED_BY(crit_); | 591 std::map<uint32_t, int64_t> recv_times_ GUARDED_BY(crit_); |
554 std::map<uint32_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_); | 592 std::map<uint32_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_); |
555 VideoFrame first_send_frame_ GUARDED_BY(crit_); | 593 VideoFrame first_send_frame_ GUARDED_BY(crit_); |
556 const double avg_psnr_threshold_; | 594 const double avg_psnr_threshold_; |
557 const double avg_ssim_threshold_; | 595 const double avg_ssim_threshold_; |
558 | 596 |
559 rtc::CriticalSection comparison_lock_; | 597 rtc::CriticalSection comparison_lock_; |
560 std::vector<ThreadWrapper*> comparison_thread_pool_; | 598 std::vector<ThreadWrapper*> comparison_thread_pool_; |
561 rtc::scoped_ptr<ThreadWrapper> stats_polling_thread_; | 599 rtc::scoped_ptr<ThreadWrapper> stats_polling_thread_; |
562 const rtc::scoped_ptr<EventWrapper> comparison_available_event_; | 600 const rtc::scoped_ptr<EventWrapper> comparison_available_event_; |
563 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_); | 601 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_); |
564 const rtc::scoped_ptr<EventWrapper> done_; | 602 const rtc::scoped_ptr<EventWrapper> done_; |
565 }; | 603 }; |
566 | 604 |
567 VideoQualityTest::VideoQualityTest() : clock_(Clock::GetRealTimeClock()) {} | 605 void FullStackTestBefore::RunTest(const FullStackTestBeforeParams& params) { |
568 | 606 // TODO(ivica): Add num_temporal_layers as a param. |
569 void VideoQualityTest::ValidateParams(const Params& params) { | 607 unsigned char num_temporal_layers = |
570 RTC_CHECK_GE(params.common.max_bitrate_bps, params.common.target_bitrate_bps); | 608 params.graph_data_output_filename.empty() ? 2 : 1; |
571 RTC_CHECK_GE(params.common.target_bitrate_bps, params.common.min_bitrate_bps); | 609 |
572 RTC_CHECK_LT(params.common.tl_discard_threshold, | 610 test::DirectTransport send_transport(params.link); |
573 params.common.num_temporal_layers); | 611 test::DirectTransport recv_transport(params.link); |
574 } | 612 VideoAnalyzerBefore analyzer(nullptr, &send_transport, params.test_label, |
575 | 613 params.avg_psnr_threshold, params.avg_ssim_threshold, |
576 void VideoQualityTest::TestBody() {} | 614 params.test_durations_secs * params.clip.fps, |
577 | 615 params.graph_data_output_filename); |
578 void VideoQualityTest::SetupFullStack(const Params& params, | 616 |
579 Transport* send_transport, | 617 CreateCalls(Call::Config(), Call::Config()); |
580 Transport* recv_transport) { | 618 |
581 if (params.logs) | 619 analyzer.SetReceiver(receiver_call_->Receiver()); |
582 trace_to_stderr_.reset(new test::TraceToStderr); | 620 send_transport.SetReceiver(&analyzer); |
583 | 621 recv_transport.SetReceiver(sender_call_->Receiver()); |
584 CreateSendConfig(1, send_transport); | 622 |
585 | 623 CreateSendConfig(1, &analyzer); |
586 int payload_type; | 624 |
587 if (params.common.codec == "VP8") { | 625 rtc::scoped_ptr<VideoEncoder> encoder; |
588 encoder_.reset(VideoEncoder::Create(VideoEncoder::kVp8)); | 626 if (params.codec == "VP8") { |
589 payload_type = kPayloadTypeVP8; | 627 encoder = |
590 } else if (params.common.codec == "VP9") { | 628 rtc::scoped_ptr<VideoEncoder>(VideoEncoder::Create(VideoEncoder::kVp8)); |
591 encoder_.reset(VideoEncoder::Create(VideoEncoder::kVp9)); | 629 send_config_.encoder_settings.encoder = encoder.get(); |
592 payload_type = kPayloadTypeVP9; | 630 send_config_.encoder_settings.payload_name = "VP8"; |
| 631 } else if (params.codec == "VP9") { |
| 632 encoder = |
| 633 rtc::scoped_ptr<VideoEncoder>(VideoEncoder::Create(VideoEncoder::kVp9)); |
| 634 send_config_.encoder_settings.encoder = encoder.get(); |
| 635 send_config_.encoder_settings.payload_name = "VP9"; |
593 } else { | 636 } else { |
594 RTC_NOTREACHED() << "Codec not supported!"; | 637 RTC_NOTREACHED() << "Codec not supported!"; |
595 return; | 638 return; |
596 } | 639 } |
597 send_config_.encoder_settings.encoder = encoder_.get(); | 640 send_config_.encoder_settings.payload_type = 124; |
598 send_config_.encoder_settings.payload_name = params.common.codec; | |
599 send_config_.encoder_settings.payload_type = payload_type; | |
600 | 641 |
601 send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; | 642 send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
602 send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); | 643 send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); |
603 send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; | 644 send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; |
604 | 645 |
605 send_config_.rtp.extensions.clear(); | 646 VideoStream* stream = &encoder_config_.streams[0]; |
606 if (params.common.send_side_bwe) { | 647 stream->width = params.clip.width; |
607 send_config_.rtp.extensions.push_back(RtpExtension( | 648 stream->height = params.clip.height; |
608 RtpExtension::kTransportSequenceNumber, kTransportSeqExtensionId)); | 649 stream->min_bitrate_bps = params.min_bitrate_bps; |
609 } else { | 650 stream->target_bitrate_bps = params.target_bitrate_bps; |
610 send_config_.rtp.extensions.push_back( | 651 stream->max_bitrate_bps = params.max_bitrate_bps; |
611 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); | 652 stream->max_framerate = params.clip.fps; |
| 653 |
| 654 VideoCodecVP8 vp8_settings; |
| 655 VideoCodecVP9 vp9_settings; |
| 656 if (params.mode == ContentMode::kScreensharingStaticImage || |
| 657 params.mode == ContentMode::kScreensharingScrollingImage) { |
| 658 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen; |
| 659 encoder_config_.min_transmit_bitrate_bps = 400 * 1000; |
| 660 if (params.codec == "VP8") { |
| 661 vp8_settings = VideoEncoder::GetDefaultVp8Settings(); |
| 662 vp8_settings.denoisingOn = false; |
| 663 vp8_settings.frameDroppingOn = false; |
| 664 vp8_settings.numberOfTemporalLayers = num_temporal_layers; |
| 665 encoder_config_.encoder_specific_settings = &vp8_settings; |
| 666 } else if (params.codec == "VP9") { |
| 667 vp9_settings = VideoEncoder::GetDefaultVp9Settings(); |
| 668 vp9_settings.denoisingOn = false; |
| 669 vp9_settings.frameDroppingOn = false; |
| 670 vp9_settings.numberOfTemporalLayers = num_temporal_layers; |
| 671 encoder_config_.encoder_specific_settings = &vp9_settings; |
| 672 } |
| 673 |
| 674 stream->temporal_layer_thresholds_bps.clear(); |
| 675 if (num_temporal_layers > 1) { |
| 676 stream->temporal_layer_thresholds_bps.push_back( |
| 677 stream->target_bitrate_bps); |
| 678 } |
612 } | 679 } |
613 | 680 |
614 // Automatically fill out streams[0] with params. | 681 CreateMatchingReceiveConfigs(&recv_transport); |
615 VideoStream* stream = &encoder_config_.streams[0]; | 682 receive_configs_[0].renderer = &analyzer; |
616 stream->width = params.common.width; | |
617 stream->height = params.common.height; | |
618 stream->min_bitrate_bps = params.common.min_bitrate_bps; | |
619 stream->target_bitrate_bps = params.common.target_bitrate_bps; | |
620 stream->max_bitrate_bps = params.common.max_bitrate_bps; | |
621 stream->max_framerate = static_cast<int>(params.common.fps); | |
622 | |
623 stream->temporal_layer_thresholds_bps.clear(); | |
624 if (params.common.num_temporal_layers > 1) { | |
625 stream->temporal_layer_thresholds_bps.push_back(stream->target_bitrate_bps); | |
626 } | |
627 | |
628 CreateMatchingReceiveConfigs(recv_transport); | |
629 | |
630 receive_configs_[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; | 683 receive_configs_[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
631 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].ssrc = kSendRtxSsrcs[0]; | 684 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].ssrc = kSendRtxSsrcs[0]; |
632 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].payload_type = | 685 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].payload_type = |
633 kSendRtxPayloadType; | 686 kSendRtxPayloadType; |
634 | 687 |
635 encoder_config_.min_transmit_bitrate_bps = params.common.min_transmit_bps; | 688 for (auto& config : receive_configs_) |
636 } | 689 config.pre_decode_callback = &analyzer; |
637 | 690 CreateStreams(); |
638 void VideoQualityTest::SetupScreenshare(const Params& params) { | 691 analyzer.input_ = send_stream_->Input(); |
639 RTC_CHECK(params.screenshare.enabled); | 692 analyzer.send_stream_ = send_stream_; |
640 | 693 |
641 // Fill out codec settings. | |
642 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen; | |
643 if (params.common.codec == "VP8") { | |
644 codec_settings_.VP8 = VideoEncoder::GetDefaultVp8Settings(); | |
645 codec_settings_.VP8.denoisingOn = false; | |
646 codec_settings_.VP8.frameDroppingOn = false; | |
647 codec_settings_.VP8.numberOfTemporalLayers = | |
648 static_cast<unsigned char>(params.common.num_temporal_layers); | |
649 encoder_config_.encoder_specific_settings = &codec_settings_.VP8; | |
650 } else if (params.common.codec == "VP9") { | |
651 codec_settings_.VP9 = VideoEncoder::GetDefaultVp9Settings(); | |
652 codec_settings_.VP9.denoisingOn = false; | |
653 codec_settings_.VP9.frameDroppingOn = false; | |
654 codec_settings_.VP9.numberOfTemporalLayers = | |
655 static_cast<unsigned char>(params.common.num_temporal_layers); | |
656 encoder_config_.encoder_specific_settings = &codec_settings_.VP9; | |
657 } | |
658 | |
659 // Setup frame generator. | |
660 const size_t kWidth = 1850; | |
661 const size_t kHeight = 1110; | |
662 std::vector<std::string> slides; | 694 std::vector<std::string> slides; |
663 slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv")); | 695 slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv")); |
664 slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv")); | 696 slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv")); |
665 slides.push_back(test::ResourcePath("photo_1850_1110", "yuv")); | 697 slides.push_back(test::ResourcePath("photo_1850_1110", "yuv")); |
666 slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv")); | 698 slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv")); |
667 | 699 size_t kSlidesWidth = 1850; |
668 if (params.screenshare.scroll_duration == 0) { | 700 size_t kSlidesHeight = 1110; |
669 // Cycle image every slide_change_interval seconds. | 701 |
670 frame_generator_.reset(test::FrameGenerator::CreateFromYuvFile( | 702 Clock* clock = Clock::GetRealTimeClock(); |
671 slides, kWidth, kHeight, | 703 rtc::scoped_ptr<test::FrameGenerator> frame_generator; |
672 params.screenshare.slide_change_interval * params.common.fps)); | 704 |
673 } else { | 705 switch (params.mode) { |
674 RTC_CHECK_LE(params.common.width, kWidth); | 706 case ContentMode::kRealTimeVideo: |
675 RTC_CHECK_LE(params.common.height, kHeight); | 707 frame_generator.reset(test::FrameGenerator::CreateFromYuvFile( |
676 RTC_CHECK_GT(params.screenshare.slide_change_interval, 0); | 708 std::vector<std::string>(1, |
677 const int kPauseDurationMs = (params.screenshare.slide_change_interval - | 709 test::ResourcePath(params.clip.name, "yuv")), |
678 params.screenshare.scroll_duration) * 1000; | 710 params.clip.width, params.clip.height, 1)); |
679 RTC_CHECK_LE(params.screenshare.scroll_duration, | 711 break; |
680 params.screenshare.slide_change_interval); | 712 case ContentMode::kScreensharingScrollingImage: |
681 | 713 frame_generator.reset( |
682 if (params.screenshare.scroll_duration) { | |
683 frame_generator_.reset( | |
684 test::FrameGenerator::CreateScrollingInputFromYuvFiles( | 714 test::FrameGenerator::CreateScrollingInputFromYuvFiles( |
685 clock_, slides, kWidth, kHeight, params.common.width, | 715 clock, slides, kSlidesWidth, kSlidesHeight, params.clip.width, |
686 params.common.height, params.screenshare.scroll_duration * 1000, | 716 params.clip.height, 2000, |
687 kPauseDurationMs)); | 717 8000)); // Scroll for 2 seconds, then pause for 8. |
688 } else { | 718 break; |
689 frame_generator_.reset(test::FrameGenerator::CreateFromYuvFile( | 719 case ContentMode::kScreensharingStaticImage: |
690 slides, kWidth, kHeight, | 720 frame_generator.reset(test::FrameGenerator::CreateFromYuvFile( |
691 params.screenshare.slide_change_interval * params.common.fps)); | 721 slides, kSlidesWidth, kSlidesHeight, |
692 } | 722 10 * params.clip.fps)); // Cycle image every 10 seconds. |
| 723 break; |
693 } | 724 } |
694 } | 725 |
695 | 726 ASSERT_TRUE(frame_generator.get() != nullptr); |
696 void VideoQualityTest::CreateCapturer(const Params& params, | 727 frame_generator_capturer_.reset(new test::FrameGeneratorCapturer( |
697 VideoCaptureInput* input) { | 728 clock, &analyzer, frame_generator.release(), params.clip.fps)); |
698 if (params.screenshare.enabled) { | 729 ASSERT_TRUE(frame_generator_capturer_->Init()); |
699 test::FrameGeneratorCapturer *frame_generator_capturer = | 730 |
700 new test::FrameGeneratorCapturer( | 731 Start(); |
701 clock_, input, frame_generator_.release(), params.common.fps); | |
702 EXPECT_TRUE(frame_generator_capturer->Init()); | |
703 capturer_.reset(frame_generator_capturer); | |
704 } else { | |
705 if (params.video.clip_name.empty()) { | |
706 capturer_.reset(test::VideoCapturer::Create( | |
707 input, params.common.width, params.common.height, params.common.fps, | |
708 clock_)); | |
709 } else { | |
710 capturer_.reset(test::FrameGeneratorCapturer::CreateFromYuvFile( | |
711 input, test::ResourcePath(params.video.clip_name, "yuv"), | |
712 params.common.width, params.common.height, params.common.fps, | |
713 clock_)); | |
714 ASSERT_TRUE(capturer_.get() != nullptr) | |
715 << "Could not create capturer for " << params.video.clip_name | |
716 << ".yuv. Is this resource file present?"; | |
717 } | |
718 } | |
719 } | |
720 | |
721 void VideoQualityTest::RunWithAnalyzer(const Params& params) { | |
722 // TODO(ivica): Merge with RunWithRenderer and use a flag / argument to | |
723 // differentiate between the analyzer and the renderer case. | |
724 ValidateParams(params); | |
725 | |
726 FILE* graph_data_output_file = nullptr; | |
727 if (!params.analyzer.graph_data_output_filename.empty()) { | |
728 graph_data_output_file = | |
729 fopen(params.analyzer.graph_data_output_filename.c_str(), "w"); | |
730 RTC_CHECK(graph_data_output_file != nullptr) | |
731 << "Can't open the file " | |
732 << params.analyzer.graph_data_output_filename << "!"; | |
733 } | |
734 | |
735 test::LayerFilteringTransport send_transport( | |
736 params.pipe, kPayloadTypeVP8, kPayloadTypeVP9, | |
737 static_cast<uint8_t>(params.common.tl_discard_threshold), 0); | |
738 test::DirectTransport recv_transport(params.pipe); | |
739 VideoAnalyzer analyzer( | |
740 nullptr, &send_transport, params.analyzer.test_label, | |
741 params.analyzer.avg_psnr_threshold, params.analyzer.avg_ssim_threshold, | |
742 params.analyzer.test_durations_secs * params.common.fps, | |
743 graph_data_output_file); | |
744 | |
745 Call::Config call_config; | |
746 call_config.bitrate_config = params.common.call_bitrate_config; | |
747 CreateCalls(call_config, call_config); | |
748 | |
749 analyzer.SetReceiver(receiver_call_->Receiver()); | |
750 send_transport.SetReceiver(&analyzer); | |
751 recv_transport.SetReceiver(sender_call_->Receiver()); | |
752 | |
753 SetupFullStack(params, &analyzer, &recv_transport); | |
754 receive_configs_[0].renderer = &analyzer; | |
755 for (auto& config : receive_configs_) | |
756 config.pre_decode_callback = &analyzer; | |
757 | |
758 if (params.screenshare.enabled) | |
759 SetupScreenshare(params); | |
760 | |
761 CreateCapturer(params, &analyzer); | |
762 | |
763 CreateStreams(); | |
764 analyzer.input_ = send_stream_->Input(); | |
765 analyzer.send_stream_ = send_stream_; | |
766 | |
767 send_stream_->Start(); | |
768 for (size_t i = 0; i < receive_streams_.size(); ++i) | |
769 receive_streams_[i]->Start(); | |
770 capturer_->Start(); | |
771 | 732 |
772 analyzer.Wait(); | 733 analyzer.Wait(); |
773 | 734 |
774 send_transport.StopSending(); | 735 send_transport.StopSending(); |
775 recv_transport.StopSending(); | 736 recv_transport.StopSending(); |
776 | 737 |
777 capturer_->Stop(); | 738 Stop(); |
778 for (size_t i = 0; i < receive_streams_.size(); ++i) | |
779 receive_streams_[i]->Stop(); | |
780 send_stream_->Stop(); | |
781 | 739 |
782 DestroyStreams(); | 740 DestroyStreams(); |
783 | |
784 if (graph_data_output_file) | |
785 fclose(graph_data_output_file); | |
786 } | 741 } |
787 | 742 |
788 void VideoQualityTest::RunWithVideoRenderer(const Params& params) { | 743 // TEST_F(FullStackTestBefore, ParisQcifWithoutPacketLoss) { |
789 ValidateParams(params); | 744 // FullStackTestBeforeParams paris_qcif = {"net_delay_0_0_plr_0", |
790 | 745 // {"paris_qcif", 176, 144, 30}, |
791 rtc::scoped_ptr<test::VideoRenderer> local_preview( | 746 // ContentMode::kRealTimeVideo, |
792 test::VideoRenderer::Create("Local Preview", params.common.width, | 747 // 300000, |
793 params.common.height)); | 748 // 300000, |
794 rtc::scoped_ptr<test::VideoRenderer> loopback_video( | 749 // 300000, |
795 test::VideoRenderer::Create("Loopback Video", params.common.width, | 750 // 36.0, |
796 params.common.height)); | 751 // 0.96, |
797 | 752 // kFullStackTestBeforeDurationSecs, |
798 // TODO(ivica): Remove bitrate_config and use the default Call::Config(), to | 753 // "VP8"}; |
799 // match the full stack tests. | 754 // RunTest(paris_qcif); |
800 Call::Config call_config; | 755 // } |
801 call_config.bitrate_config = params.common.call_bitrate_config; | 756 // |
802 rtc::scoped_ptr<Call> call(Call::Create(call_config)); | 757 // TEST_F(FullStackTestBefore, ForemanCifWithoutPacketLoss) { |
803 | 758 // // TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif. |
804 test::LayerFilteringTransport transport( | 759 // FullStackTestBeforeParams foreman_cif = {"foreman_cif_net_delay_0_0_plr_0", |
805 params.pipe, kPayloadTypeVP8, kPayloadTypeVP9, | 760 // {"foreman_cif", 352, 288, 30}, |
806 static_cast<uint8_t>(params.common.tl_discard_threshold), 0); | 761 // ContentMode::kRealTimeVideo, |
807 // TODO(ivica): Use two calls to be able to merge with RunWithAnalyzer or at | 762 // 700000, |
808 // least share as much code as possible. That way this test would also match | 763 // 700000, |
809 // the full stack tests better. | 764 // 700000, |
810 transport.SetReceiver(call->Receiver()); | 765 // 0.0, |
811 | 766 // 0.0, |
812 SetupFullStack(params, &transport, &transport); | 767 // kFullStackTestBeforeDurationSecs, |
813 send_config_.local_renderer = local_preview.get(); | 768 // "VP8"}; |
814 receive_configs_[0].renderer = loopback_video.get(); | 769 // RunTest(foreman_cif); |
815 | 770 // } |
816 if (params.screenshare.enabled) | 771 // |
817 SetupScreenshare(params); | 772 // TEST_F(FullStackTestBefore, ForemanCifPlr5) { |
818 | 773 // FullStackTestBeforeParams foreman_cif = {"foreman_cif_delay_50_0_plr_5", |
819 send_stream_ = call->CreateVideoSendStream(send_config_, encoder_config_); | 774 // {"foreman_cif", 352, 288, 30}, |
820 CreateCapturer(params, send_stream_->Input()); | 775 // ContentMode::kRealTimeVideo, |
821 | 776 // 30000, |
822 VideoReceiveStream* receive_stream = | 777 // 500000, |
823 call->CreateVideoReceiveStream(receive_configs_[0]); | 778 // 2000000, |
824 | 779 // 0.0, |
825 receive_stream->Start(); | 780 // 0.0, |
826 send_stream_->Start(); | 781 // kFullStackTestBeforeDurationSecs, |
827 capturer_->Start(); | 782 // "VP8"}; |
828 | 783 // foreman_cif.link.loss_percent = 5; |
829 test::PressEnterToContinue(); | 784 // foreman_cif.link.queue_delay_ms = 50; |
830 | 785 // RunTest(foreman_cif); |
831 capturer_->Stop(); | 786 // } |
832 send_stream_->Stop(); | 787 // |
833 receive_stream->Stop(); | 788 // TEST_F(FullStackTestBefore, ForemanCif500kbps) { |
834 | 789 // FullStackTestBeforeParams foreman_cif = {"foreman_cif_500kbps", |
835 call->DestroyVideoReceiveStream(receive_stream); | 790 // {"foreman_cif", 352, 288, 30}, |
836 call->DestroyVideoSendStream(send_stream_); | 791 // ContentMode::kRealTimeVideo, |
837 | 792 // 30000, |
838 transport.StopSending(); | 793 // 500000, |
| 794 // 2000000, |
| 795 // 0.0, |
| 796 // 0.0, |
| 797 // kFullStackTestBeforeDurationSecs, |
| 798 // "VP8"}; |
| 799 // foreman_cif.link.queue_length_packets = 0; |
| 800 // foreman_cif.link.queue_delay_ms = 0; |
| 801 // foreman_cif.link.link_capacity_kbps = 500; |
| 802 // RunTest(foreman_cif); |
| 803 // } |
| 804 // |
| 805 // TEST_F(FullStackTestBefore, ForemanCif500kbpsLimitedQueue) { |
| 806 // FullStackTestBeforeParams foreman_cif = {"foreman_cif_500kbps_32pkts_queue"
, |
| 807 // {"foreman_cif", 352, 288, 30}, |
| 808 // ContentMode::kRealTimeVideo, |
| 809 // 30000, |
| 810 // 500000, |
| 811 // 2000000, |
| 812 // 0.0, |
| 813 // 0.0, |
| 814 // kFullStackTestBeforeDurationSecs, |
| 815 // "VP8"}; |
| 816 // foreman_cif.link.queue_length_packets = 32; |
| 817 // foreman_cif.link.queue_delay_ms = 0; |
| 818 // foreman_cif.link.link_capacity_kbps = 500; |
| 819 // RunTest(foreman_cif); |
| 820 // } |
| 821 // |
| 822 // TEST_F(FullStackTestBefore, ForemanCif500kbps100ms) { |
| 823 // FullStackTestBeforeParams foreman_cif = {"foreman_cif_500kbps_100ms", |
| 824 // {"foreman_cif", 352, 288, 30}, |
| 825 // ContentMode::kRealTimeVideo, |
| 826 // 30000, |
| 827 // 500000, |
| 828 // 2000000, |
| 829 // 0.0, |
| 830 // 0.0, |
| 831 // kFullStackTestBeforeDurationSecs, |
| 832 // "VP8"}; |
| 833 // foreman_cif.link.queue_length_packets = 0; |
| 834 // foreman_cif.link.queue_delay_ms = 100; |
| 835 // foreman_cif.link.link_capacity_kbps = 500; |
| 836 // RunTest(foreman_cif); |
| 837 // } |
| 838 // |
| 839 // TEST_F(FullStackTestBefore, ForemanCif500kbps100msLimitedQueue) { |
| 840 // FullStackTestBeforeParams foreman_cif = {"foreman_cif_500kbps_100ms_32pkts_
queue", |
| 841 // {"foreman_cif", 352, 288, 30}, |
| 842 // ContentMode::kRealTimeVideo, |
| 843 // 30000, |
| 844 // 500000, |
| 845 // 2000000, |
| 846 // 0.0, |
| 847 // 0.0, |
| 848 // kFullStackTestBeforeDurationSecs, |
| 849 // "VP8"}; |
| 850 // foreman_cif.link.queue_length_packets = 32; |
| 851 // foreman_cif.link.queue_delay_ms = 100; |
| 852 // foreman_cif.link.link_capacity_kbps = 500; |
| 853 // RunTest(foreman_cif); |
| 854 // } |
| 855 // |
| 856 // TEST_F(FullStackTestBefore, ForemanCif1000kbps100msLimitedQueue) { |
| 857 // FullStackTestBeforeParams foreman_cif = {"foreman_cif_1000kbps_100ms_32pkts
_queue", |
| 858 // {"foreman_cif", 352, 288, 30}, |
| 859 // ContentMode::kRealTimeVideo, |
| 860 // 30000, |
| 861 // 2000000, |
| 862 // 2000000, |
| 863 // 0.0, |
| 864 // 0.0, |
| 865 // kFullStackTestBeforeDurationSecs, |
| 866 // "VP8"}; |
| 867 // foreman_cif.link.queue_length_packets = 32; |
| 868 // foreman_cif.link.queue_delay_ms = 100; |
| 869 // foreman_cif.link.link_capacity_kbps = 1000; |
| 870 // RunTest(foreman_cif); |
| 871 // } |
| 872 // |
| 873 // // Temporarily disabled on Android due to low test timeouts. |
| 874 // // https://code.google.com/p/chromium/issues/detail?id=513170 |
| 875 // #include "webrtc/test/testsupport/gtest_disable.h" |
| 876 // TEST_F(FullStackTestBefore, DISABLED_ON_ANDROID(ScreenshareSlidesVP8_2TL)) { |
| 877 // FullStackTestBeforeParams screenshare_params = { |
| 878 // "screenshare_slides", |
| 879 // {"screenshare_slides", 1850, 1110, 5}, |
| 880 // ContentMode::kScreensharingStaticImage, |
| 881 // 50000, |
| 882 // 200000, |
| 883 // 2000000, |
| 884 // 0.0, |
| 885 // 0.0, |
| 886 // kFullStackTestBeforeDurationSecs, |
| 887 // "VP8"}; |
| 888 // RunTest(screenshare_params); |
| 889 // } |
| 890 // |
| 891 // TEST_F(FullStackTestBefore, DISABLED_ON_ANDROID(ScreenshareSlidesVP8_2TL_Scro
ll)) { |
| 892 // FullStackTestBeforeParams screenshare_params = { |
| 893 // "screenshare_slides_scrolling", |
| 894 // // Crop height by two, scrolling vertically only. |
| 895 // {"screenshare_slides_scrolling", 1850, 1110 / 2, 5}, |
| 896 // ContentMode::kScreensharingScrollingImage, |
| 897 // 50000, |
| 898 // 200000, |
| 899 // 2000000, |
| 900 // 0.0, |
| 901 // 0.0, |
| 902 // kFullStackTestBeforeDurationSecs, |
| 903 // "VP8"}; |
| 904 // RunTest(screenshare_params); |
| 905 // } |
| 906 |
| 907 #define SCREENSHARE_VP8_2TL { \ |
| 908 FullStackTestBeforeParams screenshare_params = { \ |
| 909 "screenshare_slides", \ |
| 910 {"screenshare_slides", 1850, 1110, 5}, \ |
| 911 ContentMode::kScreensharingStaticImage, \ |
| 912 50000, \ |
| 913 200000, \ |
| 914 2000000, \ |
| 915 0.0, \ |
| 916 0.0, \ |
| 917 kFullStackTestBeforeDurationSecs, \ |
| 918 "VP8"}; \ |
| 919 RunTest(screenshare_params); \ |
839 } | 920 } |
840 | 921 |
| 922 #define SCREENSHARE_VP9_2TL { \ |
| 923 FullStackTestBeforeParams screenshare_params = { \ |
| 924 "screenshare_slides_vp9_2tl", \ |
| 925 {"screenshare_slides", 1850, 1110, 5}, \ |
| 926 ContentMode::kScreensharingStaticImage, \ |
| 927 50000, \ |
| 928 200000, \ |
| 929 2000000, \ |
| 930 0.0, \ |
| 931 0.0, \ |
| 932 kFullStackTestBeforeDurationSecs, \ |
| 933 "VP9"}; \ |
| 934 RunTest(screenshare_params); \ |
| 935 } |
| 936 |
| 937 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_0) SCREENSHARE_VP8_2
TL; |
| 938 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_1) SCREENSHARE_VP8_2
TL; |
| 939 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_2) SCREENSHARE_VP8_2
TL; |
| 940 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_3) SCREENSHARE_VP8_2
TL; |
| 941 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_4) SCREENSHARE_VP8_2
TL; |
| 942 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_5) SCREENSHARE_VP8_2
TL; |
| 943 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_6) SCREENSHARE_VP8_2
TL; |
| 944 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_7) SCREENSHARE_VP8_2
TL; |
| 945 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_8) SCREENSHARE_VP8_2
TL; |
| 946 TEST_F(FullStackTestBefore, ScreenshareSlidesVP8_2TL_Before_9) SCREENSHARE_VP8_2
TL; |
841 } // namespace webrtc | 947 } // namespace webrtc |
OLD | NEW |