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

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

Issue 1216613002: Extend full stack tests with more stats (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Formatting Created 5 years, 5 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 132 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
133 } 133 }
134 134
135 return receiver_->DeliverPacket(media_type, packet, length); 135 return receiver_->DeliverPacket(media_type, packet, length);
136 } 136 }
137 137
138 void IncomingCapturedFrame(const VideoFrame& video_frame) override { 138 void IncomingCapturedFrame(const VideoFrame& video_frame) override {
139 VideoFrame copy = video_frame; 139 VideoFrame copy = video_frame;
140 copy.set_timestamp(copy.ntp_time_ms() * 90); 140 copy.set_timestamp(copy.ntp_time_ms() * 90);
141 141
142 VideoSendStream::Stats stats = send_stream_->GetStats();
142 { 143 {
143 rtc::CritScope lock(&crit_); 144 rtc::CritScope lock(&crit_);
144 if (first_send_frame_.IsZeroSize() && rtp_timestamp_delta_ == 0) 145 if (first_send_frame_.IsZeroSize() && rtp_timestamp_delta_ == 0)
145 first_send_frame_ = copy; 146 first_send_frame_ = copy;
146 147
147 frames_.push_back(copy); 148 frames_.push_back(copy);
149 send_stats_.push_back(stats);
148 } 150 }
149 151
150 input_->IncomingCapturedFrame(video_frame); 152 input_->IncomingCapturedFrame(video_frame);
151 } 153 }
152 154
153 bool SendRtp(const uint8_t* packet, size_t length) override { 155 bool SendRtp(const uint8_t* packet, size_t length) override {
154 rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); 156 rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
155 RTPHeader header; 157 RTPHeader header;
156 parser->Parse(packet, length, &header); 158 parser->Parse(packet, length, &header);
157 159
158 { 160 {
159 rtc::CritScope lock(&crit_); 161 rtc::CritScope lock(&crit_);
160 if (rtp_timestamp_delta_ == 0) { 162 if (rtp_timestamp_delta_ == 0) {
161 rtp_timestamp_delta_ = 163 rtp_timestamp_delta_ =
162 header.timestamp - first_send_frame_.timestamp(); 164 header.timestamp - first_send_frame_.timestamp();
163 first_send_frame_.Reset(); 165 first_send_frame_.Reset();
164 } 166 }
165 send_times_[header.timestamp - rtp_timestamp_delta_] = 167 uint32_t timestamp = header.timestamp - rtp_timestamp_delta_;
168 send_times_[timestamp] =
166 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 169 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
170 encoded_frame_sizes_[timestamp] +=
pbos-webrtc 2015/06/28 18:35:31 Why do you need a += here if you remove the stats
sprang_webrtc 2015/07/06 11:19:00 Is simulcast used in the full stack tests? Then ho
pbos-webrtc 2015/07/06 11:36:00 It won't be popped unless it's rendered, right? Th
sprang_webrtc 2015/07/17 11:42:07 True, what I'm saying is that send_times is racy a
171 length - (header.headerLength + header.paddingLength);
167 } 172 }
168 173
169 return transport_->SendRtp(packet, length); 174 return transport_->SendRtp(packet, length);
170 } 175 }
171 176
172 bool SendRtcp(const uint8_t* packet, size_t length) override { 177 bool SendRtcp(const uint8_t* packet, size_t length) override {
173 return transport_->SendRtcp(packet, length); 178 return transport_->SendRtcp(packet, length);
174 } 179 }
175 180
176 void RenderFrame(const VideoFrame& video_frame, 181 void RenderFrame(const VideoFrame& video_frame,
177 int time_to_render_ms) override { 182 int time_to_render_ms) override {
178 int64_t render_time_ms = 183 int64_t render_time_ms =
179 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 184 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
180 uint32_t send_timestamp = video_frame.timestamp() - rtp_timestamp_delta_; 185 uint32_t send_timestamp = video_frame.timestamp() - rtp_timestamp_delta_;
181 186
182 rtc::CritScope lock(&crit_); 187 rtc::CritScope lock(&crit_);
183 188
184 while (frames_.front().timestamp() < send_timestamp) { 189 while (frames_.front().timestamp() < send_timestamp) {
185 AddFrameComparison(frames_.front(), last_rendered_frame_, true, 190 AddFrameComparison(frames_.front(), last_rendered_frame_, true,
186 render_time_ms); 191 render_time_ms, send_stats_.front());
187 frames_.pop_front(); 192 frames_.pop_front();
193 send_stats_.pop_front();
188 } 194 }
189 195
190 VideoFrame reference_frame = frames_.front(); 196 VideoFrame reference_frame = frames_.front();
197 VideoSendStream::Stats send_stats = send_stats_.front();
pbos-webrtc 2015/06/28 18:35:32 You can pop this one after AddFrameComparison so y
sprang_webrtc 2015/07/06 11:19:00 Done.
191 frames_.pop_front(); 198 frames_.pop_front();
199 send_stats_.pop_front();
192 assert(!reference_frame.IsZeroSize()); 200 assert(!reference_frame.IsZeroSize());
193 EXPECT_EQ(reference_frame.timestamp(), send_timestamp); 201 EXPECT_EQ(reference_frame.timestamp(), send_timestamp);
194 assert(reference_frame.timestamp() == send_timestamp); 202 assert(reference_frame.timestamp() == send_timestamp);
195 203
196 AddFrameComparison(reference_frame, video_frame, false, render_time_ms); 204 AddFrameComparison(reference_frame, video_frame, false, render_time_ms,
205 send_stats);
197 206
198 last_rendered_frame_ = video_frame; 207 last_rendered_frame_ = video_frame;
199 } 208 }
200 209
201 bool IsTextureSupported() const override { return false; } 210 bool IsTextureSupported() const override { return false; }
202 211
203 void Wait() { 212 void Wait() {
204 // Frame comparisons can be very expensive. Wait for test to be done, but 213 // Frame comparisons can be very expensive. Wait for test to be done, but
205 // at time-out check if frames_processed is going up. If so, give it more 214 // at time-out check if frames_processed is going up. If so, give it more
206 // time, otherwise fail. Hopefully this will reduce test flakiness. 215 // time, otherwise fail. Hopefully this will reduce test flakiness.
(...skipping 13 matching lines...) Expand all
220 } 229 }
221 ASSERT_GT(frames_processed, last_frames_processed) 230 ASSERT_GT(frames_processed, last_frames_processed)
222 << "Analyzer stalled while waiting for test to finish."; 231 << "Analyzer stalled while waiting for test to finish.";
223 last_frames_processed = frames_processed; 232 last_frames_processed = frames_processed;
224 } 233 }
225 } 234 }
226 235
227 VideoCaptureInput* input_; 236 VideoCaptureInput* input_;
228 Transport* transport_; 237 Transport* transport_;
229 PacketReceiver* receiver_; 238 PacketReceiver* receiver_;
239 VideoSendStream* send_stream_;
230 240
231 private: 241 private:
232 struct FrameComparison { 242 struct FrameComparison {
233 FrameComparison() 243 FrameComparison()
234 : dropped(false), send_time_ms(0), recv_time_ms(0), render_time_ms(0) {} 244 : dropped(false),
245 send_time_ms(0),
246 recv_time_ms(0),
247 render_time_ms(0),
248 encoded_frame_size(0) {}
235 249
236 FrameComparison(const VideoFrame& reference, 250 FrameComparison(const VideoFrame& reference,
237 const VideoFrame& render, 251 const VideoFrame& render,
238 bool dropped, 252 bool dropped,
239 int64_t send_time_ms, 253 int64_t send_time_ms,
240 int64_t recv_time_ms, 254 int64_t recv_time_ms,
241 int64_t render_time_ms) 255 int64_t render_time_ms,
256 size_t encoded_frame_size,
257 const VideoSendStream::Stats& send_stats)
242 : reference(reference), 258 : reference(reference),
243 render(render), 259 render(render),
244 dropped(dropped), 260 dropped(dropped),
245 send_time_ms(send_time_ms), 261 send_time_ms(send_time_ms),
246 recv_time_ms(recv_time_ms), 262 recv_time_ms(recv_time_ms),
247 render_time_ms(render_time_ms) {} 263 render_time_ms(render_time_ms),
264 encoded_frame_size(encoded_frame_size),
265 send_stats(send_stats) {}
248 266
249 VideoFrame reference; 267 VideoFrame reference;
250 VideoFrame render; 268 VideoFrame render;
251 bool dropped; 269 bool dropped;
252 int64_t send_time_ms; 270 int64_t send_time_ms;
253 int64_t recv_time_ms; 271 int64_t recv_time_ms;
254 int64_t render_time_ms; 272 int64_t render_time_ms;
273 size_t encoded_frame_size;
274 VideoSendStream::Stats send_stats;
255 }; 275 };
256 276
257 void AddFrameComparison(const VideoFrame& reference, 277 void AddFrameComparison(const VideoFrame& reference,
258 const VideoFrame& render, 278 const VideoFrame& render,
259 bool dropped, 279 bool dropped,
260 int64_t render_time_ms) 280 int64_t render_time_ms,
281 const VideoSendStream::Stats& send_stats)
261 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 282 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
262 int64_t send_time_ms = send_times_[reference.timestamp()]; 283 int64_t send_time_ms = send_times_[reference.timestamp()];
263 send_times_.erase(reference.timestamp()); 284 send_times_.erase(reference.timestamp());
264 int64_t recv_time_ms = recv_times_[reference.timestamp()]; 285 int64_t recv_time_ms = recv_times_[reference.timestamp()];
265 recv_times_.erase(reference.timestamp()); 286 recv_times_.erase(reference.timestamp());
287 size_t encoded_size = encoded_frame_sizes_[reference.timestamp()];
288 encoded_frame_sizes_.erase(reference.timestamp());
266 289
267 rtc::CritScope crit(&comparison_lock_); 290 rtc::CritScope crit(&comparison_lock_);
268 comparisons_.push_back(FrameComparison(reference, 291 comparisons_.push_back(
269 render, 292 FrameComparison(reference, render, dropped, send_time_ms, recv_time_ms,
270 dropped, 293 render_time_ms, encoded_size, send_stats));
271 send_time_ms,
272 recv_time_ms,
273 render_time_ms));
274 comparison_available_event_->Set(); 294 comparison_available_event_->Set();
275 } 295 }
276 296
277 static bool FrameComparisonThread(void* obj) { 297 static bool FrameComparisonThread(void* obj) {
278 return static_cast<VideoAnalyzer*>(obj)->CompareFrames(); 298 return static_cast<VideoAnalyzer*>(obj)->CompareFrames();
279 } 299 }
280 300
281 bool CompareFrames() { 301 bool CompareFrames() {
282 if (AllFramesRecorded()) 302 if (AllFramesRecorded())
283 return false; 303 return false;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 void PrintResults() { 371 void PrintResults() {
352 rtc::CritScope crit(&comparison_lock_); 372 rtc::CritScope crit(&comparison_lock_);
353 PrintResult("psnr", psnr_, " dB"); 373 PrintResult("psnr", psnr_, " dB");
354 PrintResult("ssim", ssim_, ""); 374 PrintResult("ssim", ssim_, "");
355 PrintResult("sender_time", sender_time_, " ms"); 375 PrintResult("sender_time", sender_time_, " ms");
356 printf("RESULT dropped_frames: %s = %d frames\n", test_label_, 376 printf("RESULT dropped_frames: %s = %d frames\n", test_label_,
357 dropped_frames_); 377 dropped_frames_);
358 PrintResult("receiver_time", receiver_time_, " ms"); 378 PrintResult("receiver_time", receiver_time_, " ms");
359 PrintResult("total_delay_incl_network", end_to_end_, " ms"); 379 PrintResult("total_delay_incl_network", end_to_end_, " ms");
360 PrintResult("time_between_rendered_frames", rendered_delta_, " ms"); 380 PrintResult("time_between_rendered_frames", rendered_delta_, " ms");
381 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes");
382 PrintResult("encode_frame_rate_", encode_frame_rate_, " fps");
383 PrintResult("avg_encode_time", avg_encode_time_ms, " ms");
384 PrintResult("encode_usage_percent", encode_usage_percent, " percent");
385 PrintResult("media_bitrate", media_bitrate_bps, " bps");
386
361 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_); 387 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_);
362 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_); 388 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_);
363 } 389 }
364 390
365 void PerformFrameComparison(const FrameComparison& comparison) { 391 void PerformFrameComparison(const FrameComparison& comparison) {
366 // Perform expensive psnr and ssim calculations while not holding lock. 392 // Perform expensive psnr and ssim calculations while not holding lock.
367 double psnr = I420PSNR(&comparison.reference, &comparison.render); 393 double psnr = I420PSNR(&comparison.reference, &comparison.render);
368 double ssim = I420SSIM(&comparison.reference, &comparison.render); 394 double ssim = I420SSIM(&comparison.reference, &comparison.render);
369 395
370 rtc::CritScope crit(&comparison_lock_); 396 rtc::CritScope crit(&comparison_lock_);
371 psnr_.AddSample(psnr); 397 psnr_.AddSample(psnr);
372 ssim_.AddSample(ssim); 398 ssim_.AddSample(ssim);
373 if (comparison.dropped) { 399 if (comparison.dropped) {
374 ++dropped_frames_; 400 ++dropped_frames_;
375 return; 401 return;
376 } 402 }
377 if (last_render_time_ != 0) 403 if (last_render_time_ != 0)
378 rendered_delta_.AddSample(comparison.render_time_ms - last_render_time_); 404 rendered_delta_.AddSample(comparison.render_time_ms - last_render_time_);
379 last_render_time_ = comparison.render_time_ms; 405 last_render_time_ = comparison.render_time_ms;
380 406
381 int64_t input_time_ms = comparison.reference.ntp_time_ms(); 407 int64_t input_time_ms = comparison.reference.ntp_time_ms();
382 sender_time_.AddSample(comparison.send_time_ms - input_time_ms); 408 sender_time_.AddSample(comparison.send_time_ms - input_time_ms);
383 receiver_time_.AddSample(comparison.render_time_ms - 409 receiver_time_.AddSample(comparison.render_time_ms -
384 comparison.recv_time_ms); 410 comparison.recv_time_ms);
385 end_to_end_.AddSample(comparison.render_time_ms - input_time_ms); 411 end_to_end_.AddSample(comparison.render_time_ms - input_time_ms);
412 encoded_frame_size_.AddSample(comparison.encoded_frame_size);
413 encode_frame_rate_.AddSample(comparison.send_stats.encode_frame_rate);
pbos-webrtc 2015/06/28 18:35:31 Does this send_stats even necessarily correspond t
sprang_webrtc 2015/07/06 11:19:00 The reason I did this was that I wanted samples fr
pbos-webrtc 2015/07/06 11:36:00 Ok, so this essentially replaces a separate thread
sprang_webrtc 2015/07/17 11:42:07 Sure. I added a check for frames_captured_ instead
414 avg_encode_time_ms.AddSample(comparison.send_stats.avg_encode_time_ms);
415 encode_usage_percent.AddSample(comparison.send_stats.encode_usage_percent);
416 media_bitrate_bps.AddSample(comparison.send_stats.media_bitrate_bps);
386 } 417 }
387 418
388 void PrintResult(const char* result_type, 419 void PrintResult(const char* result_type,
389 test::Statistics stats, 420 test::Statistics stats,
390 const char* unit) { 421 const char* unit) {
391 printf("RESULT %s: %s = {%f, %f}%s\n", 422 printf("RESULT %s: %s = {%f, %f}%s\n",
392 result_type, 423 result_type,
393 test_label_, 424 test_label_,
394 stats.Mean(), 425 stats.Mean(),
395 stats.StandardDeviation(), 426 stats.StandardDeviation(),
396 unit); 427 unit);
397 } 428 }
398 429
399 const char* const test_label_; 430 const char* const test_label_;
400 test::Statistics sender_time_; 431 test::Statistics sender_time_;
401 test::Statistics receiver_time_; 432 test::Statistics receiver_time_;
402 test::Statistics psnr_; 433 test::Statistics psnr_;
403 test::Statistics ssim_; 434 test::Statistics ssim_;
404 test::Statistics end_to_end_; 435 test::Statistics end_to_end_;
405 test::Statistics rendered_delta_; 436 test::Statistics rendered_delta_;
437 test::Statistics encoded_frame_size_;
438 test::Statistics encode_frame_rate_;
439 test::Statistics avg_encode_time_ms;
440 test::Statistics encode_usage_percent;
441 test::Statistics media_bitrate_bps;
442
406 const int frames_to_process_; 443 const int frames_to_process_;
407 int frames_recorded_; 444 int frames_recorded_;
408 int frames_processed_; 445 int frames_processed_;
409 int dropped_frames_; 446 int dropped_frames_;
410 int64_t last_render_time_; 447 int64_t last_render_time_;
411 uint32_t rtp_timestamp_delta_; 448 uint32_t rtp_timestamp_delta_;
412 449
413 rtc::CriticalSection crit_; 450 rtc::CriticalSection crit_;
414 std::deque<VideoFrame> frames_ GUARDED_BY(crit_); 451 std::deque<VideoFrame> frames_ GUARDED_BY(crit_);
452 std::deque<VideoSendStream::Stats> send_stats_ GUARDED_BY(crit_);
415 VideoFrame last_rendered_frame_ GUARDED_BY(crit_); 453 VideoFrame last_rendered_frame_ GUARDED_BY(crit_);
416 std::map<uint32_t, int64_t> send_times_ GUARDED_BY(crit_); 454 std::map<uint32_t, int64_t> send_times_ GUARDED_BY(crit_);
417 std::map<uint32_t, int64_t> recv_times_ GUARDED_BY(crit_); 455 std::map<uint32_t, int64_t> recv_times_ GUARDED_BY(crit_);
456 std::map<uint32_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_);
418 VideoFrame first_send_frame_ GUARDED_BY(crit_); 457 VideoFrame first_send_frame_ GUARDED_BY(crit_);
419 const double avg_psnr_threshold_; 458 const double avg_psnr_threshold_;
420 const double avg_ssim_threshold_; 459 const double avg_ssim_threshold_;
421 460
422 rtc::CriticalSection comparison_lock_; 461 rtc::CriticalSection comparison_lock_;
423 std::vector<ThreadWrapper*> comparison_thread_pool_; 462 std::vector<ThreadWrapper*> comparison_thread_pool_;
424 const rtc::scoped_ptr<EventWrapper> comparison_available_event_; 463 const rtc::scoped_ptr<EventWrapper> comparison_available_event_;
425 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_); 464 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_);
426 const rtc::scoped_ptr<EventWrapper> done_; 465 const rtc::scoped_ptr<EventWrapper> done_;
427 }; 466 };
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 512
474 CreateMatchingReceiveConfigs(); 513 CreateMatchingReceiveConfigs();
475 receive_configs_[0].renderer = &analyzer; 514 receive_configs_[0].renderer = &analyzer;
476 receive_configs_[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 515 receive_configs_[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
477 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].ssrc = kSendRtxSsrcs[0]; 516 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].ssrc = kSendRtxSsrcs[0];
478 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].payload_type = 517 receive_configs_[0].rtp.rtx[kSendRtxPayloadType].payload_type =
479 kSendRtxPayloadType; 518 kSendRtxPayloadType;
480 519
481 CreateStreams(); 520 CreateStreams();
482 analyzer.input_ = send_stream_->Input(); 521 analyzer.input_ = send_stream_->Input();
522 analyzer.send_stream_ = send_stream_;
483 523
484 if (params.screenshare) { 524 if (params.screenshare) {
485 std::vector<std::string> slides; 525 std::vector<std::string> slides;
486 slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv")); 526 slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv"));
487 slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv")); 527 slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv"));
488 slides.push_back(test::ResourcePath("photo_1850_1110", "yuv")); 528 slides.push_back(test::ResourcePath("photo_1850_1110", "yuv"));
489 slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv")); 529 slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv"));
490 530
491 rtc::scoped_ptr<test::FrameGenerator> frame_generator( 531 rtc::scoped_ptr<test::FrameGenerator> frame_generator(
492 test::FrameGenerator::CreateFromYuvFile( 532 test::FrameGenerator::CreateFromYuvFile(
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 true, 690 true,
651 50000, 691 50000,
652 200000, 692 200000,
653 2000000, 693 2000000,
654 0.0, 694 0.0,
655 0.0, 695 0.0,
656 kFullStackTestDurationSecs}; 696 kFullStackTestDurationSecs};
657 RunTest(screenshare_params); 697 RunTest(screenshare_params);
658 } 698 }
659 } // namespace webrtc 699 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698