| 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 OnReportEncodedTime(int64_t ntp_time_ms, int encode_time_ms) override { | 
|  | 128     rtc::CritScope crit(&comparison_lock_); | 
|  | 129     samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; | 
|  | 130   } | 
|  | 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 272     VideoFrame reference; | 278     VideoFrame reference; | 
| 273     VideoFrame render; | 279     VideoFrame render; | 
| 274     bool dropped; | 280     bool dropped; | 
| 275     int64_t send_time_ms; | 281     int64_t send_time_ms; | 
| 276     int64_t recv_time_ms; | 282     int64_t recv_time_ms; | 
| 277     int64_t render_time_ms; | 283     int64_t render_time_ms; | 
| 278     size_t encoded_frame_size; | 284     size_t encoded_frame_size; | 
| 279   }; | 285   }; | 
| 280 | 286 | 
| 281   struct Sample { | 287   struct Sample { | 
| 282     Sample(double dropped, | 288     Sample(int dropped, | 
| 283            double input_time_ms, | 289            int64_t input_time_ms, | 
| 284            double send_time_ms, | 290            int64_t send_time_ms, | 
| 285            double recv_time_ms, | 291            int64_t recv_time_ms, | 
| 286            double encoded_frame_size, | 292            int64_t render_time_ms, | 
|  | 293            size_t encoded_frame_size, | 
| 287            double psnr, | 294            double psnr, | 
| 288            double ssim, | 295            double ssim) | 
| 289            double render_time_ms) |  | 
| 290         : dropped(dropped), | 296         : dropped(dropped), | 
| 291           input_time_ms(input_time_ms), | 297           input_time_ms(input_time_ms), | 
| 292           send_time_ms(send_time_ms), | 298           send_time_ms(send_time_ms), | 
| 293           recv_time_ms(recv_time_ms), | 299           recv_time_ms(recv_time_ms), | 
|  | 300           render_time_ms(render_time_ms), | 
| 294           encoded_frame_size(encoded_frame_size), | 301           encoded_frame_size(encoded_frame_size), | 
| 295           psnr(psnr), | 302           psnr(psnr), | 
| 296           ssim(ssim), | 303           ssim(ssim) {} | 
| 297           render_time_ms(render_time_ms) {} |  | 
| 298 | 304 | 
| 299     double dropped; | 305     int dropped; | 
| 300     double input_time_ms; | 306     int64_t input_time_ms; | 
| 301     double send_time_ms; | 307     int64_t send_time_ms; | 
| 302     double recv_time_ms; | 308     int64_t recv_time_ms; | 
| 303     double encoded_frame_size; | 309     int64_t render_time_ms; | 
|  | 310     size_t encoded_frame_size; | 
| 304     double psnr; | 311     double psnr; | 
| 305     double ssim; | 312     double ssim; | 
| 306     double render_time_ms; |  | 
| 307   }; | 313   }; | 
| 308 | 314 | 
| 309   void AddFrameComparison(const VideoFrame& reference, | 315   void AddFrameComparison(const VideoFrame& reference, | 
| 310                           const VideoFrame& render, | 316                           const VideoFrame& render, | 
| 311                           bool dropped, | 317                           bool dropped, | 
| 312                           int64_t render_time_ms) | 318                           int64_t render_time_ms) | 
| 313       EXCLUSIVE_LOCKS_REQUIRED(crit_) { | 319       EXCLUSIVE_LOCKS_REQUIRED(crit_) { | 
| 314     int64_t send_time_ms = send_times_[reference.timestamp()]; | 320     int64_t send_time_ms = send_times_[reference.timestamp()]; | 
| 315     send_times_.erase(reference.timestamp()); | 321     send_times_.erase(reference.timestamp()); | 
| 316     int64_t recv_time_ms = recv_times_[reference.timestamp()]; | 322     int64_t recv_time_ms = recv_times_[reference.timestamp()]; | 
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 458     // Perform expensive psnr and ssim calculations while not holding lock. | 464     // Perform expensive psnr and ssim calculations while not holding lock. | 
| 459     double psnr = I420PSNR(&comparison.reference, &comparison.render); | 465     double psnr = I420PSNR(&comparison.reference, &comparison.render); | 
| 460     double ssim = I420SSIM(&comparison.reference, &comparison.render); | 466     double ssim = I420SSIM(&comparison.reference, &comparison.render); | 
| 461 | 467 | 
| 462     int64_t input_time_ms = comparison.reference.ntp_time_ms(); | 468     int64_t input_time_ms = comparison.reference.ntp_time_ms(); | 
| 463 | 469 | 
| 464     rtc::CritScope crit(&comparison_lock_); | 470     rtc::CritScope crit(&comparison_lock_); | 
| 465     if (graph_data_output_file_) { | 471     if (graph_data_output_file_) { | 
| 466       samples_.push_back( | 472       samples_.push_back( | 
| 467           Sample(comparison.dropped, input_time_ms, comparison.send_time_ms, | 473           Sample(comparison.dropped, input_time_ms, comparison.send_time_ms, | 
| 468                  comparison.recv_time_ms, comparison.encoded_frame_size, psnr, | 474                  comparison.recv_time_ms, comparison.render_time_ms, | 
| 469                  ssim, comparison.render_time_ms)); | 475                  comparison.encoded_frame_size, psnr, ssim)); | 
| 470     } | 476     } | 
| 471     psnr_.AddSample(psnr); | 477     psnr_.AddSample(psnr); | 
| 472     ssim_.AddSample(ssim); | 478     ssim_.AddSample(ssim); | 
| 473 | 479 | 
| 474     if (comparison.dropped) { | 480     if (comparison.dropped) { | 
| 475       ++dropped_frames_; | 481       ++dropped_frames_; | 
| 476       return; | 482       return; | 
| 477     } | 483     } | 
| 478     if (last_render_time_ != 0) | 484     if (last_render_time_ != 0) | 
| 479       rendered_delta_.AddSample(comparison.render_time_ms - last_render_time_); | 485       rendered_delta_.AddSample(comparison.render_time_ms - last_render_time_); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 505                 return A.input_time_ms < B.input_time_ms; | 511                 return A.input_time_ms < B.input_time_ms; | 
| 506               }); | 512               }); | 
| 507 | 513 | 
| 508     fprintf(out, "%s\n", test_label_.c_str()); | 514     fprintf(out, "%s\n", test_label_.c_str()); | 
| 509     fprintf(out, "%" PRIuS "\n", samples_.size()); | 515     fprintf(out, "%" PRIuS "\n", samples_.size()); | 
| 510     fprintf(out, | 516     fprintf(out, | 
| 511             "dropped " | 517             "dropped " | 
| 512             "input_time_ms " | 518             "input_time_ms " | 
| 513             "send_time_ms " | 519             "send_time_ms " | 
| 514             "recv_time_ms " | 520             "recv_time_ms " | 
|  | 521             "render_time_ms " | 
| 515             "encoded_frame_size " | 522             "encoded_frame_size " | 
| 516             "psnr " | 523             "psnr " | 
| 517             "ssim " | 524             "ssim " | 
| 518             "render_time_ms\n"); | 525             "encode_time_ms\n"); | 
|  | 526     int missing_encode_time_samples = 0; | 
| 519     for (const Sample& sample : samples_) { | 527     for (const Sample& sample : samples_) { | 
| 520       fprintf(out, "%lf %lf %lf %lf %lf %lf %lf %lf\n", sample.dropped, | 528       auto it = samples_encode_time_ms_.find(sample.input_time_ms); | 
| 521               sample.input_time_ms, sample.send_time_ms, sample.recv_time_ms, | 529       int encode_time_ms; | 
|  | 530       if (it != samples_encode_time_ms_.end()) { | 
|  | 531         encode_time_ms = it->second; | 
|  | 532       } else { | 
|  | 533         ++missing_encode_time_samples; | 
|  | 534         encode_time_ms = -1; | 
|  | 535       } | 
|  | 536       fprintf(out, "%d %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRIuS | 
|  | 537                    " %lf %lf %d\n", | 
|  | 538               sample.dropped, sample.input_time_ms, sample.send_time_ms, | 
|  | 539               sample.recv_time_ms, sample.render_time_ms, | 
| 522               sample.encoded_frame_size, sample.psnr, sample.ssim, | 540               sample.encoded_frame_size, sample.psnr, sample.ssim, | 
| 523               sample.render_time_ms); | 541               encode_time_ms); | 
|  | 542     } | 
|  | 543     if (missing_encode_time_samples) { | 
|  | 544       fprintf(stderr, | 
|  | 545               "Warning: Missing encode_time_ms samples for %d frame(s).\n", | 
|  | 546               missing_encode_time_samples); | 
| 524     } | 547     } | 
| 525   } | 548   } | 
| 526 | 549 | 
| 527   const std::string test_label_; | 550   const std::string test_label_; | 
| 528   FILE* const graph_data_output_file_; | 551   FILE* const graph_data_output_file_; | 
| 529   std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); | 552   std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); | 
|  | 553   std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); | 
| 530   test::Statistics sender_time_ GUARDED_BY(comparison_lock_); | 554   test::Statistics sender_time_ GUARDED_BY(comparison_lock_); | 
| 531   test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); | 555   test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); | 
| 532   test::Statistics psnr_ GUARDED_BY(comparison_lock_); | 556   test::Statistics psnr_ GUARDED_BY(comparison_lock_); | 
| 533   test::Statistics ssim_ GUARDED_BY(comparison_lock_); | 557   test::Statistics ssim_ GUARDED_BY(comparison_lock_); | 
| 534   test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); | 558   test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); | 
| 535   test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); | 559   test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); | 
| 536   test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); | 560   test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); | 
| 537   test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); | 561   test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); | 
| 538   test::Statistics encode_time_ms GUARDED_BY(comparison_lock_); | 562   test::Statistics encode_time_ms GUARDED_BY(comparison_lock_); | 
| 539   test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_); | 563   test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_); | 
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 730     RTC_CHECK(graph_data_output_file != nullptr) | 754     RTC_CHECK(graph_data_output_file != nullptr) | 
| 731         << "Can't open the file " | 755         << "Can't open the file " | 
| 732         << params.analyzer.graph_data_output_filename << "!"; | 756         << params.analyzer.graph_data_output_filename << "!"; | 
| 733   } | 757   } | 
| 734 | 758 | 
| 735   test::LayerFilteringTransport send_transport( | 759   test::LayerFilteringTransport send_transport( | 
| 736       params.pipe, kPayloadTypeVP8, kPayloadTypeVP9, | 760       params.pipe, kPayloadTypeVP8, kPayloadTypeVP9, | 
| 737       static_cast<uint8_t>(params.common.tl_discard_threshold), 0); | 761       static_cast<uint8_t>(params.common.tl_discard_threshold), 0); | 
| 738   test::DirectTransport recv_transport(params.pipe); | 762   test::DirectTransport recv_transport(params.pipe); | 
| 739   VideoAnalyzer analyzer( | 763   VideoAnalyzer analyzer( | 
| 740       nullptr, &send_transport, params.analyzer.test_label, | 764       &send_transport, params.analyzer.test_label, | 
| 741       params.analyzer.avg_psnr_threshold, params.analyzer.avg_ssim_threshold, | 765       params.analyzer.avg_psnr_threshold, params.analyzer.avg_ssim_threshold, | 
| 742       params.analyzer.test_durations_secs * params.common.fps, | 766       params.analyzer.test_durations_secs * params.common.fps, | 
| 743       graph_data_output_file); | 767       graph_data_output_file); | 
| 744 | 768 | 
| 745   Call::Config call_config; | 769   Call::Config call_config; | 
| 746   call_config.bitrate_config = params.common.call_bitrate_config; | 770   call_config.bitrate_config = params.common.call_bitrate_config; | 
| 747   CreateCalls(call_config, call_config); | 771   CreateCalls(call_config, call_config); | 
| 748 | 772 | 
| 749   analyzer.SetReceiver(receiver_call_->Receiver()); | 773   analyzer.SetReceiver(receiver_call_->Receiver()); | 
| 750   send_transport.SetReceiver(&analyzer); | 774   send_transport.SetReceiver(&analyzer); | 
| 751   recv_transport.SetReceiver(sender_call_->Receiver()); | 775   recv_transport.SetReceiver(sender_call_->Receiver()); | 
| 752 | 776 | 
| 753   SetupFullStack(params, &analyzer, &recv_transport); | 777   SetupFullStack(params, &analyzer, &recv_transport); | 
|  | 778   send_config_.encoding_time_observer = &analyzer; | 
| 754   receive_configs_[0].renderer = &analyzer; | 779   receive_configs_[0].renderer = &analyzer; | 
| 755   for (auto& config : receive_configs_) | 780   for (auto& config : receive_configs_) | 
| 756     config.pre_decode_callback = &analyzer; | 781     config.pre_decode_callback = &analyzer; | 
| 757 | 782 | 
| 758   if (params.screenshare.enabled) | 783   if (params.screenshare.enabled) | 
| 759     SetupScreenshare(params); | 784     SetupScreenshare(params); | 
| 760 | 785 | 
| 761   CreateCapturer(params, &analyzer); | 786   CreateCapturer(params, &analyzer); | 
| 762 | 787 | 
| 763   CreateStreams(); | 788   CreateStreams(); | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 832   send_stream_->Stop(); | 857   send_stream_->Stop(); | 
| 833   receive_stream->Stop(); | 858   receive_stream->Stop(); | 
| 834 | 859 | 
| 835   call->DestroyVideoReceiveStream(receive_stream); | 860   call->DestroyVideoReceiveStream(receive_stream); | 
| 836   call->DestroyVideoSendStream(send_stream_); | 861   call->DestroyVideoSendStream(send_stream_); | 
| 837 | 862 | 
| 838   transport.StopSending(); | 863   transport.StopSending(); | 
| 839 } | 864 } | 
| 840 | 865 | 
| 841 }  // namespace webrtc | 866 }  // namespace webrtc | 
| OLD | NEW | 
|---|