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

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: 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 } 132 }
130 133
131 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) { 134 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) {
132 rtc::CritScope crit(&comparison_lock_); 135 rtc::CritScope crit(&comparison_lock_);
133 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; 136 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms;
134 } 137 }
135 138
136 void IncomingCapturedFrame(const VideoFrame& video_frame) override { 139 void IncomingCapturedFrame(const VideoFrame& video_frame) override {
137 VideoFrame copy = video_frame; 140 VideoFrame copy = video_frame;
138 copy.set_timestamp(copy.ntp_time_ms() * 90); 141 copy.set_timestamp(copy.ntp_time_ms() * 90);
139
140 { 142 {
141 rtc::CritScope lock(&crit_); 143 rtc::CritScope lock(&crit_);
142 if (first_send_frame_.IsZeroSize() && rtp_timestamp_delta_ == 0)
143 first_send_frame_ = copy;
144
145 frames_.push_back(copy); 144 frames_.push_back(copy);
146 } 145 }
147 146
148 input_->IncomingCapturedFrame(video_frame); 147 input_->IncomingCapturedFrame(video_frame);
149 } 148 }
150 149
150 void FrameCallback(VideoFrame* video_frame) {
151 rtc::CritScope lock(&crit_);
152 if (first_send_frame_.IsZeroSize() && rtp_timestamp_delta_ == 0) {
153 while (frames_.front().timestamp() != video_frame->timestamp()) {
154 ++dropped_frames_before_first_encode_;
155 frames_.pop_front();
156 RTC_CHECK(!frames_.empty());
157 }
158 first_send_frame_ = *video_frame;
159 }
160 }
161
151 bool SendRtp(const uint8_t* packet, 162 bool SendRtp(const uint8_t* packet,
152 size_t length, 163 size_t length,
153 const PacketOptions& options) override { 164 const PacketOptions& options) override {
154 RtpUtility::RtpHeaderParser parser(packet, length); 165 RtpUtility::RtpHeaderParser parser(packet, length);
155 RTPHeader header; 166 RTPHeader header;
156 parser.Parse(&header); 167 parser.Parse(&header);
157 168
158 int64_t current_time = 169 int64_t current_time =
159 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 170 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
160 bool result = transport_->SendRtp(packet, length, options); 171 bool result = transport_->SendRtp(packet, length, options);
161 { 172 {
162 rtc::CritScope lock(&crit_); 173 rtc::CritScope lock(&crit_);
163 int64_t timestamp = wrap_handler_.Unwrap(header.timestamp); 174 int64_t timestamp = wrap_handler_.Unwrap(header.timestamp);
164 175
165 if (rtp_timestamp_delta_ == 0) { 176 if (!first_send_frame_.IsZeroSize()) {
166 rtp_timestamp_delta_ = timestamp - first_send_frame_.timestamp(); 177 rtp_timestamp_delta_ = timestamp - first_send_frame_.timestamp();
167 first_send_frame_.Reset(); 178 first_send_frame_.Reset();
168 } 179 }
169 timestamp -= rtp_timestamp_delta_; 180 timestamp -= rtp_timestamp_delta_;
170 send_times_[timestamp] = current_time; 181 send_times_[timestamp] = current_time;
171 if (!transport_->DiscardedLastPacket() && 182 if (!transport_->DiscardedLastPacket() &&
172 header.ssrc == ssrc_to_analyze_) { 183 header.ssrc == ssrc_to_analyze_) {
173 encoded_frame_sizes_[timestamp] += 184 encoded_frame_sizes_[timestamp] +=
174 length - (header.headerLength + header.paddingLength); 185 length - (header.headerLength + header.paddingLength);
175 } 186 }
(...skipping 12 matching lines...) Expand all
188 } 199 }
189 200
190 void RenderFrame(const VideoFrame& video_frame, 201 void RenderFrame(const VideoFrame& video_frame,
191 int time_to_render_ms) override { 202 int time_to_render_ms) override {
192 int64_t render_time_ms = 203 int64_t render_time_ms =
193 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 204 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
194 uint32_t send_timestamp = video_frame.timestamp() - rtp_timestamp_delta_; 205 uint32_t send_timestamp = video_frame.timestamp() - rtp_timestamp_delta_;
195 206
196 rtc::CritScope lock(&crit_); 207 rtc::CritScope lock(&crit_);
197 208
198 while (frames_.front().timestamp() < send_timestamp) { 209 while (frames_.front().timestamp() != send_timestamp) {
210 if (last_rendered_frame_.IsZeroSize()) {
211 // No previous frame rendered, this one was dropped after sending but
212 // before rendering.
213 ++dropped_frames_before_rendering_;
214 frames_.pop_front();
215 RTC_CHECK(!frames_.empty());
216 continue;
217 }
199 AddFrameComparison(frames_.front(), last_rendered_frame_, true, 218 AddFrameComparison(frames_.front(), last_rendered_frame_, true,
200 render_time_ms); 219 render_time_ms);
201 frames_.pop_front(); 220 frames_.pop_front();
221 RTC_DCHECK(!frames_.empty());
202 } 222 }
203 223
204 VideoFrame reference_frame = frames_.front(); 224 VideoFrame reference_frame = frames_.front();
205 frames_.pop_front(); 225 frames_.pop_front();
206 assert(!reference_frame.IsZeroSize()); 226 assert(!reference_frame.IsZeroSize());
207 if (send_timestamp == reference_frame.timestamp() - 1) { 227 if (send_timestamp == reference_frame.timestamp() - 1) {
208 // TODO(ivica): Make this work for > 2 streams. 228 // TODO(ivica): Make this work for > 2 streams.
209 // Look at RTPSender::BuildRTPHeader. 229 // Look at RTPSender::BuildRTPHeader.
210 ++send_timestamp; 230 ++send_timestamp;
211 } 231 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 362
343 private: 363 private:
344 VideoAnalyzer* const parent_; 364 VideoAnalyzer* const parent_;
345 }; 365 };
346 366
347 void AddFrameComparison(const VideoFrame& reference, 367 void AddFrameComparison(const VideoFrame& reference,
348 const VideoFrame& render, 368 const VideoFrame& render,
349 bool dropped, 369 bool dropped,
350 int64_t render_time_ms) 370 int64_t render_time_ms)
351 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 371 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
372 RTC_DCHECK(!render.IsZeroSize());
352 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp()); 373 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp());
353 int64_t send_time_ms = send_times_[reference_timestamp]; 374 int64_t send_time_ms = send_times_[reference_timestamp];
354 send_times_.erase(reference_timestamp); 375 send_times_.erase(reference_timestamp);
355 int64_t recv_time_ms = recv_times_[reference_timestamp]; 376 int64_t recv_time_ms = recv_times_[reference_timestamp];
356 recv_times_.erase(reference_timestamp); 377 recv_times_.erase(reference_timestamp);
357 378
358 // TODO(ivica): Make this work for > 2 streams. 379 // TODO(ivica): Make this work for > 2 streams.
359 auto it = encoded_frame_sizes_.find(reference_timestamp); 380 auto it = encoded_frame_sizes_.find(reference_timestamp);
360 if (it == encoded_frame_sizes_.end()) 381 if (it == encoded_frame_sizes_.end())
361 it = encoded_frame_sizes_.find(reference_timestamp - 1); 382 it = encoded_frame_sizes_.find(reference_timestamp - 1);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 return frames_processed_ == frames_to_process_; 497 return frames_processed_ == frames_to_process_;
477 } 498 }
478 499
479 void PrintResults() { 500 void PrintResults() {
480 rtc::CritScope crit(&comparison_lock_); 501 rtc::CritScope crit(&comparison_lock_);
481 PrintResult("psnr", psnr_, " dB"); 502 PrintResult("psnr", psnr_, " dB");
482 PrintResult("ssim", ssim_, " score"); 503 PrintResult("ssim", ssim_, " score");
483 PrintResult("sender_time", sender_time_, " ms"); 504 PrintResult("sender_time", sender_time_, " ms");
484 printf("RESULT dropped_frames: %s = %d frames\n", test_label_.c_str(), 505 printf("RESULT dropped_frames: %s = %d frames\n", test_label_.c_str(),
485 dropped_frames_); 506 dropped_frames_);
507 printf("RESULT dropped_frames_before_first_encode: %s = %d frames\n",
508 test_label_.c_str(), dropped_frames_before_first_encode_);
509 printf("RESULT dropped_frames_before_rendering: %s = %d frames\n",
510 test_label_.c_str(), dropped_frames_before_rendering_);
stefan-webrtc 2016/03/14 13:14:03 It's a bit weird that we mix PrintResult with prin
pbos-webrtc 2016/03/14 15:12:58 Done.
486 PrintResult("receiver_time", receiver_time_, " ms"); 511 PrintResult("receiver_time", receiver_time_, " ms");
487 PrintResult("total_delay_incl_network", end_to_end_, " ms"); 512 PrintResult("total_delay_incl_network", end_to_end_, " ms");
488 PrintResult("time_between_rendered_frames", rendered_delta_, " ms"); 513 PrintResult("time_between_rendered_frames", rendered_delta_, " ms");
489 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes"); 514 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes");
490 PrintResult("encode_frame_rate", encode_frame_rate_, " fps"); 515 PrintResult("encode_frame_rate", encode_frame_rate_, " fps");
491 PrintResult("encode_time", encode_time_ms, " ms"); 516 PrintResult("encode_time", encode_time_ms, " ms");
492 PrintResult("encode_usage_percent", encode_usage_percent, " percent"); 517 PrintResult("encode_usage_percent", encode_usage_percent, " percent");
493 PrintResult("media_bitrate", media_bitrate_bps, " bps"); 518 PrintResult("media_bitrate", media_bitrate_bps, " bps");
494 519
495 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_); 520 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); 624 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_);
600 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); 625 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_);
601 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_); 626 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_);
602 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_); 627 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_);
603 test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_); 628 test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_);
604 629
605 const int frames_to_process_; 630 const int frames_to_process_;
606 int frames_recorded_; 631 int frames_recorded_;
607 int frames_processed_; 632 int frames_processed_;
608 int dropped_frames_; 633 int dropped_frames_;
634 int dropped_frames_before_first_encode_;
635 int dropped_frames_before_rendering_;
609 int64_t last_render_time_; 636 int64_t last_render_time_;
610 uint32_t rtp_timestamp_delta_; 637 uint32_t rtp_timestamp_delta_;
611 638
612 rtc::CriticalSection crit_; 639 rtc::CriticalSection crit_;
613 std::deque<VideoFrame> frames_ GUARDED_BY(crit_); 640 std::deque<VideoFrame> frames_ GUARDED_BY(crit_);
614 VideoFrame last_rendered_frame_ GUARDED_BY(crit_); 641 VideoFrame last_rendered_frame_ GUARDED_BY(crit_);
615 rtc::TimestampWrapAroundHandler wrap_handler_ GUARDED_BY(crit_); 642 rtc::TimestampWrapAroundHandler wrap_handler_ GUARDED_BY(crit_);
616 std::map<int64_t, int64_t> send_times_ GUARDED_BY(crit_); 643 std::map<int64_t, int64_t> send_times_ GUARDED_BY(crit_);
617 std::map<int64_t, int64_t> recv_times_ GUARDED_BY(crit_); 644 std::map<int64_t, int64_t> recv_times_ GUARDED_BY(crit_);
618 std::map<int64_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_); 645 std::map<int64_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_);
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 params_.analyzer.test_durations_secs * params_.common.fps, 1019 params_.analyzer.test_durations_secs * params_.common.fps,
993 graph_data_output_file, graph_title, 1020 graph_data_output_file, graph_title,
994 kVideoSendSsrcs[params_.ss.selected_stream]); 1021 kVideoSendSsrcs[params_.ss.selected_stream]);
995 1022
996 analyzer.SetReceiver(receiver_call_->Receiver()); 1023 analyzer.SetReceiver(receiver_call_->Receiver());
997 send_transport.SetReceiver(&analyzer); 1024 send_transport.SetReceiver(&analyzer);
998 recv_transport.SetReceiver(sender_call_->Receiver()); 1025 recv_transport.SetReceiver(sender_call_->Receiver());
999 1026
1000 SetupCommon(&analyzer, &recv_transport); 1027 SetupCommon(&analyzer, &recv_transport);
1001 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer; 1028 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer;
1029 video_send_config_.pre_encode_callback = &analyzer;
1002 for (auto& config : video_receive_configs_) 1030 for (auto& config : video_receive_configs_)
1003 config.pre_decode_callback = &analyzer; 1031 config.pre_decode_callback = &analyzer;
1004 RTC_DCHECK(!video_send_config_.post_encode_callback); 1032 RTC_DCHECK(!video_send_config_.post_encode_callback);
1005 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy(); 1033 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy();
1006 1034
1007 if (params_.screenshare.enabled) 1035 if (params_.screenshare.enabled)
1008 SetupScreenshare(); 1036 SetupScreenshare();
1009 1037
1010 CreateVideoStreams(); 1038 CreateVideoStreams();
1011 analyzer.input_ = video_send_stream_->Input(); 1039 analyzer.input_ = video_send_stream_->Input();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 video_send_stream_->Stop(); 1120 video_send_stream_->Stop();
1093 receive_stream->Stop(); 1121 receive_stream->Stop();
1094 1122
1095 call->DestroyVideoReceiveStream(receive_stream); 1123 call->DestroyVideoReceiveStream(receive_stream);
1096 call->DestroyVideoSendStream(video_send_stream_); 1124 call->DestroyVideoSendStream(video_send_stream_);
1097 1125
1098 transport.StopSending(); 1126 transport.StopSending();
1099 } 1127 }
1100 1128
1101 } // namespace webrtc 1129 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698