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

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

Issue 1896413002: Reland of Initialize/configure video encoders asychronously. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase2 Created 4 years, 8 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 | « webrtc/media/engine/webrtcvideoengine2_unittest.cc ('k') | webrtc/video/video_send_stream.h » ('j') | 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) 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 const std::string& graph_title, 57 const std::string& graph_title,
58 uint32_t ssrc_to_analyze) 58 uint32_t ssrc_to_analyze)
59 : input_(nullptr), 59 : input_(nullptr),
60 transport_(transport), 60 transport_(transport),
61 receiver_(nullptr), 61 receiver_(nullptr),
62 send_stream_(nullptr), 62 send_stream_(nullptr),
63 test_label_(test_label), 63 test_label_(test_label),
64 graph_data_output_file_(graph_data_output_file), 64 graph_data_output_file_(graph_data_output_file),
65 graph_title_(graph_title), 65 graph_title_(graph_title),
66 ssrc_to_analyze_(ssrc_to_analyze), 66 ssrc_to_analyze_(ssrc_to_analyze),
67 pre_encode_proxy_(this),
67 encode_timing_proxy_(this), 68 encode_timing_proxy_(this),
68 frames_to_process_(duration_frames), 69 frames_to_process_(duration_frames),
69 frames_recorded_(0), 70 frames_recorded_(0),
70 frames_processed_(0), 71 frames_processed_(0),
71 dropped_frames_(0), 72 dropped_frames_(0),
73 dropped_frames_before_first_encode_(0),
74 dropped_frames_before_rendering_(0),
72 last_render_time_(0), 75 last_render_time_(0),
73 rtp_timestamp_delta_(0), 76 rtp_timestamp_delta_(0),
74 avg_psnr_threshold_(avg_psnr_threshold), 77 avg_psnr_threshold_(avg_psnr_threshold),
75 avg_ssim_threshold_(avg_ssim_threshold), 78 avg_ssim_threshold_(avg_ssim_threshold),
76 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"), 79 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"),
77 comparison_available_event_(false, false), 80 comparison_available_event_(false, false),
78 done_(true, false) { 81 done_(true, false) {
79 // Create thread pool for CPU-expensive PSNR/SSIM calculations. 82 // Create thread pool for CPU-expensive PSNR/SSIM calculations.
80 83
81 // Try to use about as many threads as cores, but leave kMinCoresLeft alone, 84 // Try to use about as many threads as cores, but leave kMinCoresLeft alone,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 } 140 }
138 141
139 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) { 142 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) {
140 rtc::CritScope crit(&comparison_lock_); 143 rtc::CritScope crit(&comparison_lock_);
141 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; 144 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms;
142 } 145 }
143 146
144 void IncomingCapturedFrame(const VideoFrame& video_frame) override { 147 void IncomingCapturedFrame(const VideoFrame& video_frame) override {
145 VideoFrame copy = video_frame; 148 VideoFrame copy = video_frame;
146 copy.set_timestamp(copy.ntp_time_ms() * 90); 149 copy.set_timestamp(copy.ntp_time_ms() * 90);
147
148 { 150 {
149 rtc::CritScope lock(&crit_); 151 rtc::CritScope lock(&crit_);
150 if (!first_send_timestamp_ && rtp_timestamp_delta_ == 0)
151 first_send_timestamp_ = rtc::Optional<uint32_t>(copy.timestamp());
152
153 frames_.push_back(copy); 152 frames_.push_back(copy);
154 } 153 }
155 154
156 input_->IncomingCapturedFrame(video_frame); 155 input_->IncomingCapturedFrame(video_frame);
157 } 156 }
158 157
158 void PreEncodeOnFrame(const VideoFrame& video_frame) {
159 rtc::CritScope lock(&crit_);
160 if (!first_send_timestamp_ && rtp_timestamp_delta_ == 0) {
161 while (frames_.front().timestamp() != video_frame.timestamp()) {
162 ++dropped_frames_before_first_encode_;
163 frames_.pop_front();
164 RTC_CHECK(!frames_.empty());
165 }
166 first_send_timestamp_ = rtc::Optional<uint32_t>(video_frame.timestamp());
167 }
168 }
169
159 bool SendRtp(const uint8_t* packet, 170 bool SendRtp(const uint8_t* packet,
160 size_t length, 171 size_t length,
161 const PacketOptions& options) override { 172 const PacketOptions& options) override {
162 RtpUtility::RtpHeaderParser parser(packet, length); 173 RtpUtility::RtpHeaderParser parser(packet, length);
163 RTPHeader header; 174 RTPHeader header;
164 parser.Parse(&header); 175 parser.Parse(&header);
165 176
166 int64_t current_time = 177 int64_t current_time =
167 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 178 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
168 bool result = transport_->SendRtp(packet, length, options); 179 bool result = transport_->SendRtp(packet, length, options);
(...skipping 28 matching lines...) Expand all
197 208
198 void OnFrame(const VideoFrame& video_frame) override { 209 void OnFrame(const VideoFrame& video_frame) override {
199 int64_t render_time_ms = 210 int64_t render_time_ms =
200 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 211 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
201 212
202 rtc::CritScope lock(&crit_); 213 rtc::CritScope lock(&crit_);
203 int64_t send_timestamp = 214 int64_t send_timestamp =
204 wrap_handler_.Unwrap(video_frame.timestamp() - rtp_timestamp_delta_); 215 wrap_handler_.Unwrap(video_frame.timestamp() - rtp_timestamp_delta_);
205 216
206 while (wrap_handler_.Unwrap(frames_.front().timestamp()) < send_timestamp) { 217 while (wrap_handler_.Unwrap(frames_.front().timestamp()) < send_timestamp) {
218 if (last_rendered_frame_.IsZeroSize()) {
219 // No previous frame rendered, this one was dropped after sending but
220 // before rendering.
221 ++dropped_frames_before_rendering_;
222 frames_.pop_front();
223 RTC_CHECK(!frames_.empty());
224 continue;
225 }
207 AddFrameComparison(frames_.front(), last_rendered_frame_, true, 226 AddFrameComparison(frames_.front(), last_rendered_frame_, true,
208 render_time_ms); 227 render_time_ms);
209 frames_.pop_front(); 228 frames_.pop_front();
229 RTC_DCHECK(!frames_.empty());
210 } 230 }
211 231
212 VideoFrame reference_frame = frames_.front(); 232 VideoFrame reference_frame = frames_.front();
213 frames_.pop_front(); 233 frames_.pop_front();
214 assert(!reference_frame.IsZeroSize()); 234 assert(!reference_frame.IsZeroSize());
215 int64_t reference_timestamp = 235 int64_t reference_timestamp =
216 wrap_handler_.Unwrap(reference_frame.timestamp()); 236 wrap_handler_.Unwrap(reference_frame.timestamp());
217 if (send_timestamp == reference_timestamp - 1) { 237 if (send_timestamp == reference_timestamp - 1) {
218 // TODO(ivica): Make this work for > 2 streams. 238 // TODO(ivica): Make this work for > 2 streams.
219 // Look at RTPSender::BuildRTPHeader. 239 // Look at RTPSender::BuildRTPHeader.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 } 281 }
262 last_frames_processed = frames_processed; 282 last_frames_processed = frames_processed;
263 } 283 }
264 284
265 if (iteration > 0) 285 if (iteration > 0)
266 printf("- Farewell, sweet Concorde!\n"); 286 printf("- Farewell, sweet Concorde!\n");
267 287
268 stats_polling_thread_.Stop(); 288 stats_polling_thread_.Stop();
269 } 289 }
270 290
291 rtc::VideoSinkInterface<VideoFrame>* pre_encode_proxy() {
292 return &pre_encode_proxy_;
293 }
271 EncodedFrameObserver* encode_timing_proxy() { return &encode_timing_proxy_; } 294 EncodedFrameObserver* encode_timing_proxy() { return &encode_timing_proxy_; }
272 295
273 VideoCaptureInput* input_; 296 VideoCaptureInput* input_;
274 test::LayerFilteringTransport* const transport_; 297 test::LayerFilteringTransport* const transport_;
275 PacketReceiver* receiver_; 298 PacketReceiver* receiver_;
276 VideoSendStream* send_stream_; 299 VideoSendStream* send_stream_;
277 300
278 private: 301 private:
279 struct FrameComparison { 302 struct FrameComparison {
280 FrameComparison() 303 FrameComparison()
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 367
345 void OnEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) override { 368 void OnEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) override {
346 parent_->MeasuredEncodeTiming(ntp_time_ms, encode_time_ms); 369 parent_->MeasuredEncodeTiming(ntp_time_ms, encode_time_ms);
347 } 370 }
348 void EncodedFrameCallback(const EncodedFrame& frame) override {} 371 void EncodedFrameCallback(const EncodedFrame& frame) override {}
349 372
350 private: 373 private:
351 VideoAnalyzer* const parent_; 374 VideoAnalyzer* const parent_;
352 }; 375 };
353 376
377 // This class receives the send-side OnFrame callback and is provided to not
378 // conflict with the receiver-side renderer callback.
379 class PreEncodeProxy : public rtc::VideoSinkInterface<VideoFrame> {
380 public:
381 explicit PreEncodeProxy(VideoAnalyzer* parent) : parent_(parent) {}
382
383 void OnFrame(const VideoFrame& video_frame) override {
384 parent_->PreEncodeOnFrame(video_frame);
385 }
386
387 private:
388 VideoAnalyzer* const parent_;
389 };
390
354 void AddFrameComparison(const VideoFrame& reference, 391 void AddFrameComparison(const VideoFrame& reference,
355 const VideoFrame& render, 392 const VideoFrame& render,
356 bool dropped, 393 bool dropped,
357 int64_t render_time_ms) 394 int64_t render_time_ms)
358 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 395 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
396 RTC_DCHECK(!render.IsZeroSize());
359 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp()); 397 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp());
360 int64_t send_time_ms = send_times_[reference_timestamp]; 398 int64_t send_time_ms = send_times_[reference_timestamp];
361 send_times_.erase(reference_timestamp); 399 send_times_.erase(reference_timestamp);
362 int64_t recv_time_ms = recv_times_[reference_timestamp]; 400 int64_t recv_time_ms = recv_times_[reference_timestamp];
363 recv_times_.erase(reference_timestamp); 401 recv_times_.erase(reference_timestamp);
364 402
365 // TODO(ivica): Make this work for > 2 streams. 403 // TODO(ivica): Make this work for > 2 streams.
366 auto it = encoded_frame_sizes_.find(reference_timestamp); 404 auto it = encoded_frame_sizes_.find(reference_timestamp);
367 if (it == encoded_frame_sizes_.end()) 405 if (it == encoded_frame_sizes_.end())
368 it = encoded_frame_sizes_.find(reference_timestamp - 1); 406 it = encoded_frame_sizes_.find(reference_timestamp - 1);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 ++frames_processed_; 519 ++frames_processed_;
482 assert(frames_processed_ <= frames_to_process_); 520 assert(frames_processed_ <= frames_to_process_);
483 return frames_processed_ == frames_to_process_; 521 return frames_processed_ == frames_to_process_;
484 } 522 }
485 523
486 void PrintResults() { 524 void PrintResults() {
487 rtc::CritScope crit(&comparison_lock_); 525 rtc::CritScope crit(&comparison_lock_);
488 PrintResult("psnr", psnr_, " dB"); 526 PrintResult("psnr", psnr_, " dB");
489 PrintResult("ssim", ssim_, " score"); 527 PrintResult("ssim", ssim_, " score");
490 PrintResult("sender_time", sender_time_, " ms"); 528 PrintResult("sender_time", sender_time_, " ms");
491 printf("RESULT dropped_frames: %s = %d frames\n", test_label_.c_str(),
492 dropped_frames_);
493 PrintResult("receiver_time", receiver_time_, " ms"); 529 PrintResult("receiver_time", receiver_time_, " ms");
494 PrintResult("total_delay_incl_network", end_to_end_, " ms"); 530 PrintResult("total_delay_incl_network", end_to_end_, " ms");
495 PrintResult("time_between_rendered_frames", rendered_delta_, " ms"); 531 PrintResult("time_between_rendered_frames", rendered_delta_, " ms");
496 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes"); 532 PrintResult("encoded_frame_size", encoded_frame_size_, " bytes");
497 PrintResult("encode_frame_rate", encode_frame_rate_, " fps"); 533 PrintResult("encode_frame_rate", encode_frame_rate_, " fps");
498 PrintResult("encode_time", encode_time_ms, " ms"); 534 PrintResult("encode_time", encode_time_ms, " ms");
499 PrintResult("encode_usage_percent", encode_usage_percent, " percent"); 535 PrintResult("encode_usage_percent", encode_usage_percent, " percent");
500 PrintResult("media_bitrate", media_bitrate_bps, " bps"); 536 PrintResult("media_bitrate", media_bitrate_bps, " bps");
501 537
538 printf("RESULT dropped_frames: %s = %d frames\n", test_label_.c_str(),
539 dropped_frames_);
540 printf("RESULT dropped_frames_before_first_encode: %s = %d frames\n",
541 test_label_.c_str(), dropped_frames_before_first_encode_);
542 printf("RESULT dropped_frames_before_rendering: %s = %d frames\n",
543 test_label_.c_str(), dropped_frames_before_rendering_);
544
502 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_); 545 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_);
503 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_); 546 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_);
504 } 547 }
505 548
506 void PerformFrameComparison(const FrameComparison& comparison) { 549 void PerformFrameComparison(const FrameComparison& comparison) {
507 // Perform expensive psnr and ssim calculations while not holding lock. 550 // Perform expensive psnr and ssim calculations while not holding lock.
508 double psnr = I420PSNR(&comparison.reference, &comparison.render); 551 double psnr = I420PSNR(&comparison.reference, &comparison.render);
509 double ssim = I420SSIM(&comparison.reference, &comparison.render); 552 double ssim = I420SSIM(&comparison.reference, &comparison.render);
510 553
511 int64_t input_time_ms = comparison.reference.ntp_time_ms(); 554 int64_t input_time_ms = comparison.reference.ntp_time_ms();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 fprintf(stderr, 630 fprintf(stderr,
588 "Warning: Missing encode_time_ms samples for %d frame(s).\n", 631 "Warning: Missing encode_time_ms samples for %d frame(s).\n",
589 missing_encode_time_samples); 632 missing_encode_time_samples);
590 } 633 }
591 } 634 }
592 635
593 const std::string test_label_; 636 const std::string test_label_;
594 FILE* const graph_data_output_file_; 637 FILE* const graph_data_output_file_;
595 const std::string graph_title_; 638 const std::string graph_title_;
596 const uint32_t ssrc_to_analyze_; 639 const uint32_t ssrc_to_analyze_;
640 PreEncodeProxy pre_encode_proxy_;
597 OnEncodeTimingProxy encode_timing_proxy_; 641 OnEncodeTimingProxy encode_timing_proxy_;
598 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); 642 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_);
599 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); 643 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_);
600 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); 644 test::Statistics sender_time_ GUARDED_BY(comparison_lock_);
601 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); 645 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_);
602 test::Statistics psnr_ GUARDED_BY(comparison_lock_); 646 test::Statistics psnr_ GUARDED_BY(comparison_lock_);
603 test::Statistics ssim_ GUARDED_BY(comparison_lock_); 647 test::Statistics ssim_ GUARDED_BY(comparison_lock_);
604 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); 648 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_);
605 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); 649 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_);
606 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); 650 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_);
607 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); 651 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_);
608 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_); 652 test::Statistics encode_time_ms GUARDED_BY(comparison_lock_);
609 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_); 653 test::Statistics encode_usage_percent GUARDED_BY(comparison_lock_);
610 test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_); 654 test::Statistics media_bitrate_bps GUARDED_BY(comparison_lock_);
611 655
612 const int frames_to_process_; 656 const int frames_to_process_;
613 int frames_recorded_; 657 int frames_recorded_;
614 int frames_processed_; 658 int frames_processed_;
615 int dropped_frames_; 659 int dropped_frames_;
660 int dropped_frames_before_first_encode_;
661 int dropped_frames_before_rendering_;
616 int64_t last_render_time_; 662 int64_t last_render_time_;
617 uint32_t rtp_timestamp_delta_; 663 uint32_t rtp_timestamp_delta_;
618 664
619 rtc::CriticalSection crit_; 665 rtc::CriticalSection crit_;
620 std::deque<VideoFrame> frames_ GUARDED_BY(crit_); 666 std::deque<VideoFrame> frames_ GUARDED_BY(crit_);
621 VideoFrame last_rendered_frame_ GUARDED_BY(crit_); 667 VideoFrame last_rendered_frame_ GUARDED_BY(crit_);
622 rtc::TimestampWrapAroundHandler wrap_handler_ GUARDED_BY(crit_); 668 rtc::TimestampWrapAroundHandler wrap_handler_ GUARDED_BY(crit_);
623 std::map<int64_t, int64_t> send_times_ GUARDED_BY(crit_); 669 std::map<int64_t, int64_t> send_times_ GUARDED_BY(crit_);
624 std::map<int64_t, int64_t> recv_times_ GUARDED_BY(crit_); 670 std::map<int64_t, int64_t> recv_times_ GUARDED_BY(crit_);
625 std::map<int64_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_); 671 std::map<int64_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_);
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 params_.analyzer.test_durations_secs * params_.common.fps, 1045 params_.analyzer.test_durations_secs * params_.common.fps,
1000 graph_data_output_file, graph_title, 1046 graph_data_output_file, graph_title,
1001 kVideoSendSsrcs[params_.ss.selected_stream]); 1047 kVideoSendSsrcs[params_.ss.selected_stream]);
1002 1048
1003 analyzer.SetReceiver(receiver_call_->Receiver()); 1049 analyzer.SetReceiver(receiver_call_->Receiver());
1004 send_transport.SetReceiver(&analyzer); 1050 send_transport.SetReceiver(&analyzer);
1005 recv_transport.SetReceiver(sender_call_->Receiver()); 1051 recv_transport.SetReceiver(sender_call_->Receiver());
1006 1052
1007 SetupCommon(&analyzer, &recv_transport); 1053 SetupCommon(&analyzer, &recv_transport);
1008 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer; 1054 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer;
1055 video_send_config_.pre_encode_callback = analyzer.pre_encode_proxy();
1009 for (auto& config : video_receive_configs_) 1056 for (auto& config : video_receive_configs_)
1010 config.pre_decode_callback = &analyzer; 1057 config.pre_decode_callback = &analyzer;
1011 RTC_DCHECK(!video_send_config_.post_encode_callback); 1058 RTC_DCHECK(!video_send_config_.post_encode_callback);
1012 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy(); 1059 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy();
1013 1060
1014 if (params_.screenshare.enabled) 1061 if (params_.screenshare.enabled)
1015 SetupScreenshare(); 1062 SetupScreenshare();
1016 1063
1017 CreateVideoStreams(); 1064 CreateVideoStreams();
1018 analyzer.input_ = video_send_stream_->Input(); 1065 analyzer.input_ = video_send_stream_->Input();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 video_send_stream_->Stop(); 1146 video_send_stream_->Stop();
1100 receive_stream->Stop(); 1147 receive_stream->Stop();
1101 1148
1102 call->DestroyVideoReceiveStream(receive_stream); 1149 call->DestroyVideoReceiveStream(receive_stream);
1103 call->DestroyVideoSendStream(video_send_stream_); 1150 call->DestroyVideoSendStream(video_send_stream_);
1104 1151
1105 transport.StopSending(); 1152 transport.StopSending();
1106 } 1153 }
1107 1154
1108 } // namespace webrtc 1155 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/media/engine/webrtcvideoengine2_unittest.cc ('k') | webrtc/video/video_send_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698