Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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> |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 static const int kTransportSeqExtensionId = | 35 static const int kTransportSeqExtensionId = |
| 36 VideoQualityTest::kAbsSendTimeExtensionId + 1; | 36 VideoQualityTest::kAbsSendTimeExtensionId + 1; |
| 37 static const int kSendStatsPollingIntervalMs = 1000; | 37 static const int kSendStatsPollingIntervalMs = 1000; |
| 38 static const int kPayloadTypeVP8 = 123; | 38 static const int kPayloadTypeVP8 = 123; |
| 39 static const int kPayloadTypeVP9 = 124; | 39 static const int kPayloadTypeVP9 = 124; |
| 40 | 40 |
| 41 class VideoAnalyzer : public PacketReceiver, | 41 class VideoAnalyzer : public PacketReceiver, |
| 42 public Transport, | 42 public Transport, |
| 43 public VideoRenderer, | 43 public VideoRenderer, |
| 44 public VideoCaptureInput, | 44 public VideoCaptureInput, |
| 45 public EncodedFrameObserver { | 45 public EncodedFrameObserver, |
| 46 public EncodingTimeObserver { | |
| 46 public: | 47 public: |
| 47 VideoAnalyzer(VideoCaptureInput* input, | 48 VideoAnalyzer(Transport* transport, |
| 48 Transport* transport, | |
| 49 const std::string& test_label, | 49 const std::string& test_label, |
| 50 double avg_psnr_threshold, | 50 double avg_psnr_threshold, |
| 51 double avg_ssim_threshold, | 51 double avg_ssim_threshold, |
| 52 int duration_frames, | 52 int duration_frames, |
| 53 FILE* graph_data_output_file) | 53 FILE* graph_data_output_file) |
| 54 : input_(input), | 54 : input_(nullptr), |
| 55 transport_(transport), | 55 transport_(transport), |
| 56 receiver_(nullptr), | 56 receiver_(nullptr), |
| 57 send_stream_(nullptr), | 57 send_stream_(nullptr), |
| 58 test_label_(test_label), | 58 test_label_(test_label), |
| 59 graph_data_output_file_(graph_data_output_file), | 59 graph_data_output_file_(graph_data_output_file), |
| 60 frames_to_process_(duration_frames), | 60 frames_to_process_(duration_frames), |
| 61 frames_recorded_(0), | 61 frames_recorded_(0), |
| 62 frames_processed_(0), | 62 frames_processed_(0), |
| 63 dropped_frames_(0), | 63 dropped_frames_(0), |
| 64 last_render_time_(0), | 64 last_render_time_(0), |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 parser->Parse(packet, length, &header); | 116 parser->Parse(packet, length, &header); |
| 117 { | 117 { |
| 118 rtc::CritScope lock(&crit_); | 118 rtc::CritScope lock(&crit_); |
| 119 recv_times_[header.timestamp - rtp_timestamp_delta_] = | 119 recv_times_[header.timestamp - rtp_timestamp_delta_] = |
| 120 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); | 120 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); |
| 121 } | 121 } |
| 122 | 122 |
| 123 return receiver_->DeliverPacket(media_type, packet, length, packet_time); | 123 return receiver_->DeliverPacket(media_type, packet, length, packet_time); |
| 124 } | 124 } |
| 125 | 125 |
| 126 // EncodingTimeObserver. | |
| 127 void OnEncodedFrame(const VideoFrame& frame, int encode_time_ms) override { | |
| 128 rtc::CritScope crit(&comparison_lock_); | |
| 129 samples_encode_time_ms_[frame.ntp_time_ms()] = encode_time_ms; | |
| 130 } | |
|
mflodman
2015/10/06 11:11:26
override
ivica
2015/10/06 12:04:32
Hmm, it already has override.
mflodman
2015/10/06 12:10:00
Doh, the window was too small and I missed that. *
ivica
2015/10/06 12:12:34
Haha :)
| |
| 131 | |
| 126 void IncomingCapturedFrame(const VideoFrame& video_frame) override { | 132 void IncomingCapturedFrame(const VideoFrame& video_frame) override { |
| 127 VideoFrame copy = video_frame; | 133 VideoFrame copy = video_frame; |
| 128 copy.set_timestamp(copy.ntp_time_ms() * 90); | 134 copy.set_timestamp(copy.ntp_time_ms() * 90); |
| 129 | 135 |
| 130 { | 136 { |
| 131 rtc::CritScope lock(&crit_); | 137 rtc::CritScope lock(&crit_); |
| 132 if (first_send_frame_.IsZeroSize() && rtp_timestamp_delta_ == 0) | 138 if (first_send_frame_.IsZeroSize() && rtp_timestamp_delta_ == 0) |
| 133 first_send_frame_ = copy; | 139 first_send_frame_ = copy; |
| 134 | 140 |
| 135 frames_.push_back(copy); | 141 frames_.push_back(copy); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 VideoFrame reference; | 276 VideoFrame reference; |
| 271 VideoFrame render; | 277 VideoFrame render; |
| 272 bool dropped; | 278 bool dropped; |
| 273 int64_t send_time_ms; | 279 int64_t send_time_ms; |
| 274 int64_t recv_time_ms; | 280 int64_t recv_time_ms; |
| 275 int64_t render_time_ms; | 281 int64_t render_time_ms; |
| 276 size_t encoded_frame_size; | 282 size_t encoded_frame_size; |
| 277 }; | 283 }; |
| 278 | 284 |
| 279 struct Sample { | 285 struct Sample { |
| 280 Sample(double dropped, | 286 Sample(int dropped, |
| 281 double input_time_ms, | 287 int64_t input_time_ms, |
| 282 double send_time_ms, | 288 int64_t send_time_ms, |
| 283 double recv_time_ms, | 289 int64_t recv_time_ms, |
| 284 double encoded_frame_size, | 290 int64_t render_time_ms, |
| 291 size_t encoded_frame_size, | |
| 285 double psnr, | 292 double psnr, |
| 286 double ssim, | 293 double ssim) |
| 287 double render_time_ms) | |
| 288 : dropped(dropped), | 294 : dropped(dropped), |
| 289 input_time_ms(input_time_ms), | 295 input_time_ms(input_time_ms), |
| 290 send_time_ms(send_time_ms), | 296 send_time_ms(send_time_ms), |
| 291 recv_time_ms(recv_time_ms), | 297 recv_time_ms(recv_time_ms), |
| 298 render_time_ms(render_time_ms), | |
| 292 encoded_frame_size(encoded_frame_size), | 299 encoded_frame_size(encoded_frame_size), |
| 293 psnr(psnr), | 300 psnr(psnr), |
| 294 ssim(ssim), | 301 ssim(ssim) {} |
| 295 render_time_ms(render_time_ms) {} | |
| 296 | 302 |
| 297 double dropped; | 303 int dropped; |
| 298 double input_time_ms; | 304 int64_t input_time_ms; |
| 299 double send_time_ms; | 305 int64_t send_time_ms; |
| 300 double recv_time_ms; | 306 int64_t recv_time_ms; |
| 301 double encoded_frame_size; | 307 int64_t render_time_ms; |
| 308 size_t encoded_frame_size; | |
| 302 double psnr; | 309 double psnr; |
| 303 double ssim; | 310 double ssim; |
| 304 double render_time_ms; | |
| 305 }; | 311 }; |
| 306 | 312 |
| 307 void AddFrameComparison(const VideoFrame& reference, | 313 void AddFrameComparison(const VideoFrame& reference, |
| 308 const VideoFrame& render, | 314 const VideoFrame& render, |
| 309 bool dropped, | 315 bool dropped, |
| 310 int64_t render_time_ms) | 316 int64_t render_time_ms) |
| 311 EXCLUSIVE_LOCKS_REQUIRED(crit_) { | 317 EXCLUSIVE_LOCKS_REQUIRED(crit_) { |
| 312 int64_t send_time_ms = send_times_[reference.timestamp()]; | 318 int64_t send_time_ms = send_times_[reference.timestamp()]; |
| 313 send_times_.erase(reference.timestamp()); | 319 send_times_.erase(reference.timestamp()); |
| 314 int64_t recv_time_ms = recv_times_[reference.timestamp()]; | 320 int64_t recv_time_ms = recv_times_[reference.timestamp()]; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 // Perform expensive psnr and ssim calculations while not holding lock. | 462 // Perform expensive psnr and ssim calculations while not holding lock. |
| 457 double psnr = I420PSNR(&comparison.reference, &comparison.render); | 463 double psnr = I420PSNR(&comparison.reference, &comparison.render); |
| 458 double ssim = I420SSIM(&comparison.reference, &comparison.render); | 464 double ssim = I420SSIM(&comparison.reference, &comparison.render); |
| 459 | 465 |
| 460 int64_t input_time_ms = comparison.reference.ntp_time_ms(); | 466 int64_t input_time_ms = comparison.reference.ntp_time_ms(); |
| 461 | 467 |
| 462 rtc::CritScope crit(&comparison_lock_); | 468 rtc::CritScope crit(&comparison_lock_); |
| 463 if (graph_data_output_file_) { | 469 if (graph_data_output_file_) { |
| 464 samples_.push_back( | 470 samples_.push_back( |
| 465 Sample(comparison.dropped, input_time_ms, comparison.send_time_ms, | 471 Sample(comparison.dropped, input_time_ms, comparison.send_time_ms, |
| 466 comparison.recv_time_ms, comparison.encoded_frame_size, psnr, | 472 comparison.recv_time_ms, comparison.render_time_ms, |
| 467 ssim, comparison.render_time_ms)); | 473 comparison.encoded_frame_size, psnr, ssim)); |
| 468 } | 474 } |
| 469 psnr_.AddSample(psnr); | 475 psnr_.AddSample(psnr); |
| 470 ssim_.AddSample(ssim); | 476 ssim_.AddSample(ssim); |
| 471 | 477 |
| 472 if (comparison.dropped) { | 478 if (comparison.dropped) { |
| 473 ++dropped_frames_; | 479 ++dropped_frames_; |
| 474 return; | 480 return; |
| 475 } | 481 } |
| 476 if (last_render_time_ != 0) | 482 if (last_render_time_ != 0) |
| 477 rendered_delta_.AddSample(comparison.render_time_ms - last_render_time_); | 483 rendered_delta_.AddSample(comparison.render_time_ms - last_render_time_); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 503 return A.input_time_ms < B.input_time_ms; | 509 return A.input_time_ms < B.input_time_ms; |
| 504 }); | 510 }); |
| 505 | 511 |
| 506 fprintf(out, "%s\n", test_label_.c_str()); | 512 fprintf(out, "%s\n", test_label_.c_str()); |
| 507 fprintf(out, "%" PRIuS "\n", samples_.size()); | 513 fprintf(out, "%" PRIuS "\n", samples_.size()); |
| 508 fprintf(out, | 514 fprintf(out, |
| 509 "dropped " | 515 "dropped " |
| 510 "input_time_ms " | 516 "input_time_ms " |
| 511 "send_time_ms " | 517 "send_time_ms " |
| 512 "recv_time_ms " | 518 "recv_time_ms " |
| 519 "render_time_ms " | |
| 513 "encoded_frame_size " | 520 "encoded_frame_size " |
| 514 "psnr " | 521 "psnr " |
| 515 "ssim " | 522 "ssim " |
| 516 "render_time_ms\n"); | 523 "encode_time_ms\n"); |
| 524 int missing_encode_time_samples = 0; | |
| 517 for (const Sample& sample : samples_) { | 525 for (const Sample& sample : samples_) { |
| 518 fprintf(out, "%lf %lf %lf %lf %lf %lf %lf %lf\n", sample.dropped, | 526 auto it = samples_encode_time_ms_.find(sample.input_time_ms); |
| 519 sample.input_time_ms, sample.send_time_ms, sample.recv_time_ms, | 527 int encode_time_ms; |
| 528 if (it != samples_encode_time_ms_.end()) { | |
| 529 encode_time_ms = it->second; | |
| 530 } else { | |
| 531 ++missing_encode_time_samples; | |
| 532 encode_time_ms = -1; | |
| 533 } | |
| 534 fprintf(out, "%d %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRIuS | |
| 535 " %lf %lf %d\n", | |
| 536 sample.dropped, sample.input_time_ms, sample.send_time_ms, | |
| 537 sample.recv_time_ms, sample.render_time_ms, | |
| 520 sample.encoded_frame_size, sample.psnr, sample.ssim, | 538 sample.encoded_frame_size, sample.psnr, sample.ssim, |
| 521 sample.render_time_ms); | 539 encode_time_ms); |
| 540 } | |
| 541 if (missing_encode_time_samples) { | |
| 542 fprintf(stderr, | |
| 543 "Warning: Missing encode_time_ms samples for %d frame(s).\n", | |
| 544 missing_encode_time_samples); | |
| 522 } | 545 } |
| 523 } | 546 } |
| 524 | 547 |
| 525 const std::string test_label_; | 548 const std::string test_label_; |
| 526 FILE* const graph_data_output_file_; | 549 FILE* const graph_data_output_file_; |
| 527 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); | 550 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); |
| 551 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); | |
| 528 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); | 552 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); |
| 529 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); | 553 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); |
| 530 test::Statistics psnr_ GUARDED_BY(comparison_lock_); | 554 test::Statistics psnr_ GUARDED_BY(comparison_lock_); |
| 531 test::Statistics ssim_ GUARDED_BY(comparison_lock_); | 555 test::Statistics ssim_ GUARDED_BY(comparison_lock_); |
| 532 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); | 556 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); |
| 533 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); | 557 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); |
| 534 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); | 558 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); |
| 535 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); | 559 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); |
| 536 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_); | 560 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_); |
| 537 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_); | 561 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_); |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 728 RTC_CHECK(graph_data_output_file != nullptr) | 752 RTC_CHECK(graph_data_output_file != nullptr) |
| 729 << "Can't open the file " | 753 << "Can't open the file " |
| 730 << params.analyzer.graph_data_output_filename << "!"; | 754 << params.analyzer.graph_data_output_filename << "!"; |
| 731 } | 755 } |
| 732 | 756 |
| 733 test::LayerFilteringTransport send_transport( | 757 test::LayerFilteringTransport send_transport( |
| 734 params.pipe, kPayloadTypeVP8, kPayloadTypeVP9, | 758 params.pipe, kPayloadTypeVP8, kPayloadTypeVP9, |
| 735 static_cast<uint8_t>(params.common.tl_discard_threshold), 0); | 759 static_cast<uint8_t>(params.common.tl_discard_threshold), 0); |
| 736 test::DirectTransport recv_transport(params.pipe); | 760 test::DirectTransport recv_transport(params.pipe); |
| 737 VideoAnalyzer analyzer( | 761 VideoAnalyzer analyzer( |
| 738 nullptr, &send_transport, params.analyzer.test_label, | 762 &send_transport, params.analyzer.test_label, |
| 739 params.analyzer.avg_psnr_threshold, params.analyzer.avg_ssim_threshold, | 763 params.analyzer.avg_psnr_threshold, params.analyzer.avg_ssim_threshold, |
| 740 params.analyzer.test_durations_secs * params.common.fps, | 764 params.analyzer.test_durations_secs * params.common.fps, |
| 741 graph_data_output_file); | 765 graph_data_output_file); |
| 742 | 766 |
| 743 Call::Config call_config; | 767 Call::Config call_config; |
| 744 call_config.bitrate_config = params.common.call_bitrate_config; | 768 call_config.bitrate_config = params.common.call_bitrate_config; |
| 745 CreateCalls(call_config, call_config); | 769 CreateCalls(call_config, call_config); |
| 746 | 770 |
| 747 analyzer.SetReceiver(receiver_call_->Receiver()); | 771 analyzer.SetReceiver(receiver_call_->Receiver()); |
| 748 send_transport.SetReceiver(&analyzer); | 772 send_transport.SetReceiver(&analyzer); |
| 749 recv_transport.SetReceiver(sender_call_->Receiver()); | 773 recv_transport.SetReceiver(sender_call_->Receiver()); |
| 750 | 774 |
| 751 SetupFullStack(params, &analyzer, &recv_transport); | 775 SetupFullStack(params, &analyzer, &recv_transport); |
| 776 send_config_.encoding_time_observer = &analyzer; | |
| 752 receive_configs_[0].renderer = &analyzer; | 777 receive_configs_[0].renderer = &analyzer; |
| 753 for (auto& config : receive_configs_) | 778 for (auto& config : receive_configs_) |
| 754 config.pre_decode_callback = &analyzer; | 779 config.pre_decode_callback = &analyzer; |
| 755 | 780 |
| 756 if (params.screenshare.enabled) | 781 if (params.screenshare.enabled) |
| 757 SetupScreenshare(params); | 782 SetupScreenshare(params); |
| 758 | 783 |
| 759 CreateCapturer(params, &analyzer); | 784 CreateCapturer(params, &analyzer); |
| 760 | 785 |
| 761 CreateStreams(); | 786 CreateStreams(); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 send_stream_->Stop(); | 855 send_stream_->Stop(); |
| 831 receive_stream->Stop(); | 856 receive_stream->Stop(); |
| 832 | 857 |
| 833 call->DestroyVideoReceiveStream(receive_stream); | 858 call->DestroyVideoReceiveStream(receive_stream); |
| 834 call->DestroyVideoSendStream(send_stream_); | 859 call->DestroyVideoSendStream(send_stream_); |
| 835 | 860 |
| 836 transport.StopSending(); | 861 transport.StopSending(); |
| 837 } | 862 } |
| 838 | 863 |
| 839 } // namespace webrtc | 864 } // namespace webrtc |
| OLD | NEW |