Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: webrtc/video/video_quality_test.cc

Issue 1757313002: Initialize/configure video encoders asychronously. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: feedback Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 25 matching lines...) Expand all
36 36
37 namespace webrtc { 37 namespace webrtc {
38 38
39 static const int kSendStatsPollingIntervalMs = 1000; 39 static const int kSendStatsPollingIntervalMs = 1000;
40 static const int kPayloadTypeH264 = 122; 40 static const int kPayloadTypeH264 = 122;
41 static const int kPayloadTypeVP8 = 123; 41 static const int kPayloadTypeVP8 = 123;
42 static const int kPayloadTypeVP9 = 124; 42 static const int kPayloadTypeVP9 = 124;
43 43
44 class VideoAnalyzer : public PacketReceiver, 44 class VideoAnalyzer : public PacketReceiver,
45 public Transport, 45 public Transport,
46 public I420FrameCallback,
46 public VideoRenderer, 47 public VideoRenderer,
47 public VideoCaptureInput, 48 public VideoCaptureInput,
48 public EncodedFrameObserver { 49 public EncodedFrameObserver {
49 public: 50 public:
50 VideoAnalyzer(test::LayerFilteringTransport* transport, 51 VideoAnalyzer(test::LayerFilteringTransport* transport,
51 const std::string& test_label, 52 const std::string& test_label,
52 double avg_psnr_threshold, 53 double avg_psnr_threshold,
53 double avg_ssim_threshold, 54 double avg_ssim_threshold,
54 int duration_frames, 55 int duration_frames,
55 FILE* graph_data_output_file, 56 FILE* graph_data_output_file,
56 const std::string& graph_title, 57 const std::string& graph_title,
57 uint32_t ssrc_to_analyze) 58 uint32_t ssrc_to_analyze)
58 : input_(nullptr), 59 : input_(nullptr),
59 transport_(transport), 60 transport_(transport),
60 receiver_(nullptr), 61 receiver_(nullptr),
61 send_stream_(nullptr), 62 send_stream_(nullptr),
62 test_label_(test_label), 63 test_label_(test_label),
63 graph_data_output_file_(graph_data_output_file), 64 graph_data_output_file_(graph_data_output_file),
64 graph_title_(graph_title), 65 graph_title_(graph_title),
65 ssrc_to_analyze_(ssrc_to_analyze), 66 ssrc_to_analyze_(ssrc_to_analyze),
66 encode_timing_proxy_(this), 67 encode_timing_proxy_(this),
67 frames_to_process_(duration_frames), 68 frames_to_process_(duration_frames),
68 frames_recorded_(0), 69 frames_recorded_(0),
69 frames_processed_(0), 70 frames_processed_(0),
70 dropped_frames_(0), 71 dropped_frames_(0),
72 dropped_frames_before_first_encode_(0),
73 dropped_frames_before_rendering_(0),
71 last_render_time_(0), 74 last_render_time_(0),
72 rtp_timestamp_delta_(0), 75 rtp_timestamp_delta_(0),
73 avg_psnr_threshold_(avg_psnr_threshold), 76 avg_psnr_threshold_(avg_psnr_threshold),
74 avg_ssim_threshold_(avg_ssim_threshold), 77 avg_ssim_threshold_(avg_ssim_threshold),
75 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"), 78 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"),
76 comparison_available_event_(false, false), 79 comparison_available_event_(false, false),
77 done_(true, false) { 80 done_(true, false) {
78 // Create thread pool for CPU-expensive PSNR/SSIM calculations. 81 // Create thread pool for CPU-expensive PSNR/SSIM calculations.
79 82
80 // Try to use about as many threads as cores, but leave kMinCoresLeft alone, 83 // Try to use about as many threads as cores, but leave kMinCoresLeft alone,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 } 133 }
131 134
132 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) { 135 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) {
133 rtc::CritScope crit(&comparison_lock_); 136 rtc::CritScope crit(&comparison_lock_);
134 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; 137 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms;
135 } 138 }
136 139
137 void IncomingCapturedFrame(const VideoFrame& video_frame) override { 140 void IncomingCapturedFrame(const VideoFrame& video_frame) override {
138 VideoFrame copy = video_frame; 141 VideoFrame copy = video_frame;
139 copy.set_timestamp(copy.ntp_time_ms() * 90); 142 copy.set_timestamp(copy.ntp_time_ms() * 90);
140
141 { 143 {
142 rtc::CritScope lock(&crit_); 144 rtc::CritScope lock(&crit_);
143 if (first_send_frame_.IsZeroSize() && rtp_timestamp_delta_ == 0)
144 first_send_frame_ = copy;
145
146 frames_.push_back(copy); 145 frames_.push_back(copy);
147 } 146 }
148 147
149 input_->IncomingCapturedFrame(video_frame); 148 input_->IncomingCapturedFrame(video_frame);
150 } 149 }
151 150
151 void FrameCallback(VideoFrame* video_frame) {
152 rtc::CritScope lock(&crit_);
153 if (first_send_frame_.IsZeroSize() && rtp_timestamp_delta_ == 0) {
154 while (frames_.front().timestamp() != video_frame->timestamp()) {
155 ++dropped_frames_before_first_encode_;
156 frames_.pop_front();
157 RTC_CHECK(!frames_.empty());
158 }
159 first_send_frame_ = *video_frame;
160 }
161 }
162
152 bool SendRtp(const uint8_t* packet, 163 bool SendRtp(const uint8_t* packet,
153 size_t length, 164 size_t length,
154 const PacketOptions& options) override { 165 const PacketOptions& options) override {
155 RtpUtility::RtpHeaderParser parser(packet, length); 166 RtpUtility::RtpHeaderParser parser(packet, length);
156 RTPHeader header; 167 RTPHeader header;
157 parser.Parse(&header); 168 parser.Parse(&header);
158 169
159 int64_t current_time = 170 int64_t current_time =
160 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 171 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
161 bool result = transport_->SendRtp(packet, length, options); 172 bool result = transport_->SendRtp(packet, length, options);
162 { 173 {
163 rtc::CritScope lock(&crit_); 174 rtc::CritScope lock(&crit_);
164 175
165 if (rtp_timestamp_delta_ == 0) { 176 if (!first_send_frame_.IsZeroSize()) {
166 rtp_timestamp_delta_ = header.timestamp - first_send_frame_.timestamp(); 177 rtp_timestamp_delta_ = header.timestamp - first_send_frame_.timestamp();
167 first_send_frame_.Reset(); 178 first_send_frame_.Reset();
168 } 179 }
169 int64_t timestamp = 180 int64_t timestamp =
170 wrap_handler_.Unwrap(header.timestamp - rtp_timestamp_delta_); 181 wrap_handler_.Unwrap(header.timestamp - rtp_timestamp_delta_);
171 send_times_[timestamp] = current_time; 182 send_times_[timestamp] = current_time;
172 if (!transport_->DiscardedLastPacket() && 183 if (!transport_->DiscardedLastPacket() &&
173 header.ssrc == ssrc_to_analyze_) { 184 header.ssrc == ssrc_to_analyze_) {
174 encoded_frame_sizes_[timestamp] += 185 encoded_frame_sizes_[timestamp] +=
175 length - (header.headerLength + header.paddingLength); 186 length - (header.headerLength + header.paddingLength);
(...skipping 15 matching lines...) Expand all
191 void RenderFrame(const VideoFrame& video_frame, 202 void RenderFrame(const VideoFrame& video_frame,
192 int time_to_render_ms) override { 203 int time_to_render_ms) override {
193 int64_t render_time_ms = 204 int64_t render_time_ms =
194 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 205 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
195 206
196 rtc::CritScope lock(&crit_); 207 rtc::CritScope lock(&crit_);
197 uint32_t send_timestamp = 208 uint32_t send_timestamp =
198 wrap_handler_.Unwrap(video_frame.timestamp() - rtp_timestamp_delta_); 209 wrap_handler_.Unwrap(video_frame.timestamp() - rtp_timestamp_delta_);
199 210
200 while (wrap_handler_.Unwrap(frames_.front().timestamp()) < send_timestamp) { 211 while (wrap_handler_.Unwrap(frames_.front().timestamp()) < send_timestamp) {
212 if (last_rendered_frame_.IsZeroSize()) {
213 // No previous frame rendered, this one was dropped after sending but
214 // before rendering.
215 ++dropped_frames_before_rendering_;
216 frames_.pop_front();
217 RTC_CHECK(!frames_.empty());
218 continue;
219 }
201 AddFrameComparison(frames_.front(), last_rendered_frame_, true, 220 AddFrameComparison(frames_.front(), last_rendered_frame_, true,
202 render_time_ms); 221 render_time_ms);
203 frames_.pop_front(); 222 frames_.pop_front();
223 RTC_DCHECK(!frames_.empty());
204 } 224 }
205 225
206 VideoFrame reference_frame = frames_.front(); 226 VideoFrame reference_frame = frames_.front();
207 frames_.pop_front(); 227 frames_.pop_front();
208 assert(!reference_frame.IsZeroSize()); 228 assert(!reference_frame.IsZeroSize());
209 int64_t reference_timestamp = 229 int64_t reference_timestamp =
210 wrap_handler_.Unwrap(reference_frame.timestamp()); 230 wrap_handler_.Unwrap(reference_frame.timestamp());
211 if (send_timestamp == reference_timestamp - 1) { 231 if (send_timestamp == reference_timestamp - 1) {
212 // TODO(ivica): Make this work for > 2 streams. 232 // TODO(ivica): Make this work for > 2 streams.
213 // Look at RTPSender::BuildRTPHeader. 233 // Look at RTPSender::BuildRTPHeader.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 365
346 private: 366 private:
347 VideoAnalyzer* const parent_; 367 VideoAnalyzer* const parent_;
348 }; 368 };
349 369
350 void AddFrameComparison(const VideoFrame& reference, 370 void AddFrameComparison(const VideoFrame& reference,
351 const VideoFrame& render, 371 const VideoFrame& render,
352 bool dropped, 372 bool dropped,
353 int64_t render_time_ms) 373 int64_t render_time_ms)
354 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 374 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
375 RTC_DCHECK(!render.IsZeroSize());
355 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp()); 376 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp());
356 int64_t send_time_ms = send_times_[reference_timestamp]; 377 int64_t send_time_ms = send_times_[reference_timestamp];
357 send_times_.erase(reference_timestamp); 378 send_times_.erase(reference_timestamp);
358 int64_t recv_time_ms = recv_times_[reference_timestamp]; 379 int64_t recv_time_ms = recv_times_[reference_timestamp];
359 recv_times_.erase(reference_timestamp); 380 recv_times_.erase(reference_timestamp);
360 381
361 // TODO(ivica): Make this work for > 2 streams. 382 // TODO(ivica): Make this work for > 2 streams.
362 auto it = encoded_frame_sizes_.find(reference_timestamp); 383 auto it = encoded_frame_sizes_.find(reference_timestamp);
363 if (it == encoded_frame_sizes_.end()) 384 if (it == encoded_frame_sizes_.end())
364 it = encoded_frame_sizes_.find(reference_timestamp - 1); 385 it = encoded_frame_sizes_.find(reference_timestamp - 1);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 ++frames_processed_; 498 ++frames_processed_;
478 assert(frames_processed_ <= frames_to_process_); 499 assert(frames_processed_ <= frames_to_process_);
479 return frames_processed_ == frames_to_process_; 500 return frames_processed_ == frames_to_process_;
480 } 501 }
481 502
482 void PrintResults() { 503 void PrintResults() {
483 rtc::CritScope crit(&comparison_lock_); 504 rtc::CritScope crit(&comparison_lock_);
484 PrintResult("psnr", psnr_, " dB"); 505 PrintResult("psnr", psnr_, " dB");
485 PrintResult("ssim", ssim_, " score"); 506 PrintResult("ssim", ssim_, " score");
486 PrintResult("sender_time", sender_time_, " ms"); 507 PrintResult("sender_time", sender_time_, " ms");
487 printf("RESULT dropped_frames: %s = %d frames\n", test_label_.c_str(),
488 dropped_frames_);
489 PrintResult("receiver_time", receiver_time_, " ms"); 508 PrintResult("receiver_time", receiver_time_, " ms");
490 PrintResult("total_delay_incl_network", end_to_end_, " ms"); 509 PrintResult("total_delay_incl_network", end_to_end_, " ms");
491 PrintResult("time_between_rendered_frames", rendered_delta_, " ms"); 510 PrintResult("time_between_rendered_frames", rendered_delta_, " ms");
492 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes"); 511 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes");
493 PrintResult("encode_frame_rate", encode_frame_rate_, " fps"); 512 PrintResult("encode_frame_rate", encode_frame_rate_, " fps");
494 PrintResult("encode_time", encode_time_ms, " ms"); 513 PrintResult("encode_time", encode_time_ms, " ms");
495 PrintResult("encode_usage_percent", encode_usage_percent, " percent"); 514 PrintResult("encode_usage_percent", encode_usage_percent, " percent");
496 PrintResult("media_bitrate", media_bitrate_bps, " bps"); 515 PrintResult("media_bitrate", media_bitrate_bps, " bps");
497 516
517 printf("RESULT dropped_frames: %s = %d frames\n", test_label_.c_str(),
518 dropped_frames_);
519 printf("RESULT dropped_frames_before_first_encode: %s = %d frames\n",
520 test_label_.c_str(), dropped_frames_before_first_encode_);
521 printf("RESULT dropped_frames_before_rendering: %s = %d frames\n",
522 test_label_.c_str(), dropped_frames_before_rendering_);
523
498 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_); 524 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_);
499 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_); 525 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_);
500 } 526 }
501 527
502 void PerformFrameComparison(const FrameComparison& comparison) { 528 void PerformFrameComparison(const FrameComparison& comparison) {
503 // Perform expensive psnr and ssim calculations while not holding lock. 529 // Perform expensive psnr and ssim calculations while not holding lock.
504 double psnr = I420PSNR(&comparison.reference, &comparison.render); 530 double psnr = I420PSNR(&comparison.reference, &comparison.render);
505 double ssim = I420SSIM(&comparison.reference, &comparison.render); 531 double ssim = I420SSIM(&comparison.reference, &comparison.render);
506 532
507 int64_t input_time_ms = comparison.reference.ntp_time_ms(); 533 int64_t input_time_ms = comparison.reference.ntp_time_ms();
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); 628 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_);
603 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); 629 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_);
604 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_); 630 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_);
605 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_); 631 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_);
606 test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_); 632 test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_);
607 633
608 const int frames_to_process_; 634 const int frames_to_process_;
609 int frames_recorded_; 635 int frames_recorded_;
610 int frames_processed_; 636 int frames_processed_;
611 int dropped_frames_; 637 int dropped_frames_;
638 int dropped_frames_before_first_encode_;
639 int dropped_frames_before_rendering_;
612 int64_t last_render_time_; 640 int64_t last_render_time_;
613 uint32_t rtp_timestamp_delta_; 641 uint32_t rtp_timestamp_delta_;
614 642
615 rtc::CriticalSection crit_; 643 rtc::CriticalSection crit_;
616 std::deque<VideoFrame> frames_ GUARDED_BY(crit_); 644 std::deque<VideoFrame> frames_ GUARDED_BY(crit_);
617 VideoFrame last_rendered_frame_ GUARDED_BY(crit_); 645 VideoFrame last_rendered_frame_ GUARDED_BY(crit_);
618 rtc::TimestampWrapAroundHandler wrap_handler_ GUARDED_BY(crit_); 646 rtc::TimestampWrapAroundHandler wrap_handler_ GUARDED_BY(crit_);
619 std::map<int64_t, int64_t> send_times_ GUARDED_BY(crit_); 647 std::map<int64_t, int64_t> send_times_ GUARDED_BY(crit_);
620 std::map<int64_t, int64_t> recv_times_ GUARDED_BY(crit_); 648 std::map<int64_t, int64_t> recv_times_ GUARDED_BY(crit_);
621 std::map<int64_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_); 649 std::map<int64_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_);
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 params_.analyzer.test_durations_secs * params_.common.fps, 1023 params_.analyzer.test_durations_secs * params_.common.fps,
996 graph_data_output_file, graph_title, 1024 graph_data_output_file, graph_title,
997 kVideoSendSsrcs[params_.ss.selected_stream]); 1025 kVideoSendSsrcs[params_.ss.selected_stream]);
998 1026
999 analyzer.SetReceiver(receiver_call_->Receiver()); 1027 analyzer.SetReceiver(receiver_call_->Receiver());
1000 send_transport.SetReceiver(&analyzer); 1028 send_transport.SetReceiver(&analyzer);
1001 recv_transport.SetReceiver(sender_call_->Receiver()); 1029 recv_transport.SetReceiver(sender_call_->Receiver());
1002 1030
1003 SetupCommon(&analyzer, &recv_transport); 1031 SetupCommon(&analyzer, &recv_transport);
1004 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer; 1032 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer;
1033 video_send_config_.pre_encode_callback = &analyzer;
1005 for (auto& config : video_receive_configs_) 1034 for (auto& config : video_receive_configs_)
1006 config.pre_decode_callback = &analyzer; 1035 config.pre_decode_callback = &analyzer;
1007 RTC_DCHECK(!video_send_config_.post_encode_callback); 1036 RTC_DCHECK(!video_send_config_.post_encode_callback);
1008 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy(); 1037 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy();
1009 1038
1010 if (params_.screenshare.enabled) 1039 if (params_.screenshare.enabled)
1011 SetupScreenshare(); 1040 SetupScreenshare();
1012 1041
1013 CreateVideoStreams(); 1042 CreateVideoStreams();
1014 analyzer.input_ = video_send_stream_->Input(); 1043 analyzer.input_ = video_send_stream_->Input();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 video_send_stream_->Stop(); 1124 video_send_stream_->Stop();
1096 receive_stream->Stop(); 1125 receive_stream->Stop();
1097 1126
1098 call->DestroyVideoReceiveStream(receive_stream); 1127 call->DestroyVideoReceiveStream(receive_stream);
1099 call->DestroyVideoSendStream(video_send_stream_); 1128 call->DestroyVideoSendStream(video_send_stream_);
1100 1129
1101 transport.StopSending(); 1130 transport.StopSending();
1102 } 1131 }
1103 1132
1104 } // namespace webrtc 1133 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698