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