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/vie_encoder.cc

Issue 2255463002: Change OverUseFrameDetector to use a task queue (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@reland_taskq_in_encoder
Patch Set: Fix event.h include in unittest Created 4 years, 4 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) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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 10
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 options.low_encode_usage_threshold_percent = 150; 192 options.low_encode_usage_threshold_percent = 150;
193 options.high_encode_usage_threshold_percent = 200; 193 options.high_encode_usage_threshold_percent = 200;
194 } 194 }
195 return options; 195 return options;
196 } 196 }
197 197
198 } // namespace 198 } // namespace
199 199
200 class ViEEncoder::EncodeTask : public rtc::QueuedTask { 200 class ViEEncoder::EncodeTask : public rtc::QueuedTask {
201 public: 201 public:
202 EncodeTask(const VideoFrame& frame, ViEEncoder* vie_encoder) 202 EncodeTask(const VideoFrame& frame,
203 : vie_encoder_(vie_encoder) { 203 ViEEncoder* vie_encoder,
204 int64_t time_when_posted_in_ms)
205 : vie_encoder_(vie_encoder), time_when_posted_(time_when_posted_in_ms) {
204 frame_.ShallowCopy(frame); 206 frame_.ShallowCopy(frame);
205 ++vie_encoder_->posted_frames_waiting_for_encode_; 207 ++vie_encoder_->posted_frames_waiting_for_encode_;
206 } 208 }
207 209
208 private: 210 private:
209 bool Run() override { 211 bool Run() override {
210 RTC_DCHECK_GT(vie_encoder_->posted_frames_waiting_for_encode_.Value(), 0); 212 RTC_DCHECK_GT(vie_encoder_->posted_frames_waiting_for_encode_.Value(), 0);
211 if (--vie_encoder_->posted_frames_waiting_for_encode_ == 0) { 213 if (--vie_encoder_->posted_frames_waiting_for_encode_ == 0) {
212 vie_encoder_->EncodeVideoFrame(frame_); 214 vie_encoder_->EncodeVideoFrame(frame_, time_when_posted_);
213 } else { 215 } else {
214 // There is a newer frame in flight. Do not encode this frame. 216 // There is a newer frame in flight. Do not encode this frame.
215 LOG(LS_VERBOSE) 217 LOG(LS_VERBOSE)
216 << "Incoming frame dropped due to that the encoder is blocked."; 218 << "Incoming frame dropped due to that the encoder is blocked.";
217 } 219 }
218 return true; 220 return true;
219 } 221 }
220 VideoFrame frame_; 222 VideoFrame frame_;
221 ViEEncoder* vie_encoder_; 223 ViEEncoder* const vie_encoder_;
224 const int64_t time_when_posted_;
åsapersson 2016/08/24 08:59:05 time_when_posted_ms_
perkj_webrtc 2016/09/01 10:03:30 Done.
222 }; 225 };
223 226
224 ViEEncoder::ViEEncoder(uint32_t number_of_cores, 227 ViEEncoder::ViEEncoder(uint32_t number_of_cores,
225 SendStatisticsProxy* stats_proxy, 228 SendStatisticsProxy* stats_proxy,
226 const VideoSendStream::Config::EncoderSettings& settings, 229 const VideoSendStream::Config::EncoderSettings& settings,
227 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, 230 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
228 LoadObserver* overuse_callback, 231 LoadObserver* overuse_callback,
229 EncodedFrameObserver* encoder_timing) 232 EncodedFrameObserver* encoder_timing)
230 : shutdown_event_(true /* manual_reset */, false), 233 : shutdown_event_(true /* manual_reset */, false),
231 number_of_cores_(number_of_cores), 234 number_of_cores_(number_of_cores),
(...skipping 17 matching lines...) Expand all
249 picture_id_sli_(0), 252 picture_id_sli_(0),
250 has_received_rpsi_(false), 253 has_received_rpsi_(false),
251 picture_id_rpsi_(0), 254 picture_id_rpsi_(0),
252 clock_(Clock::GetRealTimeClock()), 255 clock_(Clock::GetRealTimeClock()),
253 last_captured_timestamp_(0), 256 last_captured_timestamp_(0),
254 delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() - 257 delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() -
255 clock_->TimeInMilliseconds()), 258 clock_->TimeInMilliseconds()),
256 encoder_queue_("EncoderQueue") { 259 encoder_queue_("EncoderQueue") {
257 vp_->EnableTemporalDecimation(false); 260 vp_->EnableTemporalDecimation(false);
258 261
259 encoder_queue_.PostTask([this] { 262 encoder_queue_.PostTask([this, encoder_timing] {
260 RTC_DCHECK_RUN_ON(&encoder_queue_); 263 RTC_DCHECK_RUN_ON(&encoder_queue_);
261 video_sender_.RegisterExternalEncoder( 264 video_sender_.RegisterExternalEncoder(
262 settings_.encoder, settings_.payload_type, settings_.internal_source); 265 settings_.encoder, settings_.payload_type, settings_.internal_source);
266 overuse_detector_.StartCheckForOveruse();
263 }); 267 });
264 } 268 }
265 269
266 ViEEncoder::~ViEEncoder() { 270 ViEEncoder::~ViEEncoder() {
267 RTC_DCHECK(shutdown_event_.Wait(0)) 271 RTC_DCHECK(shutdown_event_.Wait(0))
268 << "Must call ::Stop() before destruction."; 272 << "Must call ::Stop() before destruction.";
269 } 273 }
270 274
271 void ViEEncoder::Stop() { 275 void ViEEncoder::Stop() {
272 if (!encoder_queue_.IsCurrent()) { 276 if (!encoder_queue_.IsCurrent()) {
273 encoder_queue_.PostTask([this] { Stop(); }); 277 encoder_queue_.PostTask([this] { Stop(); });
274 shutdown_event_.Wait(rtc::Event::kForever); 278 shutdown_event_.Wait(rtc::Event::kForever);
275 return; 279 return;
276 } 280 }
277 RTC_DCHECK_RUN_ON(&encoder_queue_); 281 RTC_DCHECK_RUN_ON(&encoder_queue_);
278 video_sender_.RegisterExternalEncoder(nullptr, settings_.payload_type, false); 282 video_sender_.RegisterExternalEncoder(nullptr, settings_.payload_type, false);
283 overuse_detector_.StopCheckForOveruse();
279 shutdown_event_.Set(); 284 shutdown_event_.Set();
280 } 285 }
281 286
282 void ViEEncoder::RegisterProcessThread(ProcessThread* module_process_thread) { 287 void ViEEncoder::RegisterProcessThread(ProcessThread* module_process_thread) {
283 RTC_DCHECK(!module_process_thread_); 288 RTC_DCHECK(!module_process_thread_);
284 module_process_thread_ = module_process_thread; 289 module_process_thread_ = module_process_thread;
285 module_process_thread_->RegisterModule(&overuse_detector_);
286 module_process_thread_->RegisterModule(&video_sender_); 290 module_process_thread_->RegisterModule(&video_sender_);
287 module_process_thread_checker_.DetachFromThread(); 291 module_process_thread_checker_.DetachFromThread();
288 } 292 }
289 293
290 void ViEEncoder::DeRegisterProcessThread() { 294 void ViEEncoder::DeRegisterProcessThread() {
291 module_process_thread_->DeRegisterModule(&overuse_detector_);
292 module_process_thread_->DeRegisterModule(&video_sender_); 295 module_process_thread_->DeRegisterModule(&video_sender_);
293 } 296 }
294 297
295 void ViEEncoder::SetSink(EncodedImageCallback* sink) { 298 void ViEEncoder::SetSink(EncodedImageCallback* sink) {
296 encoder_queue_.PostTask([this, sink] { 299 encoder_queue_.PostTask([this, sink] {
297 RTC_DCHECK_RUN_ON(&encoder_queue_); 300 RTC_DCHECK_RUN_ON(&encoder_queue_);
298 sink_ = sink; 301 sink_ = sink;
299 }); 302 });
300 } 303 }
301 304
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 if (incoming_frame.ntp_time_ms() <= last_captured_timestamp_) { 393 if (incoming_frame.ntp_time_ms() <= last_captured_timestamp_) {
391 // We don't allow the same capture time for two frames, drop this one. 394 // We don't allow the same capture time for two frames, drop this one.
392 LOG(LS_WARNING) << "Same/old NTP timestamp (" 395 LOG(LS_WARNING) << "Same/old NTP timestamp ("
393 << incoming_frame.ntp_time_ms() 396 << incoming_frame.ntp_time_ms()
394 << " <= " << last_captured_timestamp_ 397 << " <= " << last_captured_timestamp_
395 << ") for incoming frame. Dropping."; 398 << ") for incoming frame. Dropping.";
396 return; 399 return;
397 } 400 }
398 401
399 last_captured_timestamp_ = incoming_frame.ntp_time_ms(); 402 last_captured_timestamp_ = incoming_frame.ntp_time_ms();
400 overuse_detector_.FrameCaptured(incoming_frame); 403 encoder_queue_.PostTask(std::unique_ptr<rtc::QueuedTask>(
401 encoder_queue_.PostTask( 404 new EncodeTask(incoming_frame, this, clock_->TimeInMilliseconds())));
402 std::unique_ptr<rtc::QueuedTask>(new EncodeTask(incoming_frame, this)));
403 } 405 }
404 406
405 bool ViEEncoder::EncoderPaused() const { 407 bool ViEEncoder::EncoderPaused() const {
406 RTC_DCHECK_RUN_ON(&encoder_queue_); 408 RTC_DCHECK_RUN_ON(&encoder_queue_);
407 // Pause video if paused by caller or as long as the network is down or the 409 // Pause video if paused by caller or as long as the network is down or the
408 // pacer queue has grown too large in buffered mode. 410 // pacer queue has grown too large in buffered mode.
409 // If the pacer queue has grown too large or the network is down, 411 // If the pacer queue has grown too large or the network is down,
410 // last_observed_bitrate_bps_ will be 0. 412 // last_observed_bitrate_bps_ will be 0.
411 return last_observed_bitrate_bps_ == 0; 413 return last_observed_bitrate_bps_ == 0;
412 } 414 }
(...skipping 10 matching lines...) Expand all
423 425
424 void ViEEncoder::TraceFrameDropEnd() { 426 void ViEEncoder::TraceFrameDropEnd() {
425 RTC_DCHECK_RUN_ON(&encoder_queue_); 427 RTC_DCHECK_RUN_ON(&encoder_queue_);
426 // End trace event on first frame after encoder resumes, if frame was dropped. 428 // End trace event on first frame after encoder resumes, if frame was dropped.
427 if (encoder_paused_and_dropped_frame_) { 429 if (encoder_paused_and_dropped_frame_) {
428 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); 430 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
429 } 431 }
430 encoder_paused_and_dropped_frame_ = false; 432 encoder_paused_and_dropped_frame_ = false;
431 } 433 }
432 434
433 void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame) { 435 void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
436 int64_t time_when_posted_in_ms) {
434 RTC_DCHECK_RUN_ON(&encoder_queue_); 437 RTC_DCHECK_RUN_ON(&encoder_queue_);
435 if (pre_encode_callback_) 438 if (pre_encode_callback_)
436 pre_encode_callback_->OnFrame(video_frame); 439 pre_encode_callback_->OnFrame(video_frame);
437 440
438 if (EncoderPaused()) { 441 if (EncoderPaused()) {
439 TraceFrameDropStart(); 442 TraceFrameDropStart();
440 return; 443 return;
441 } 444 }
442 TraceFrameDropEnd(); 445 TraceFrameDropEnd();
443 446
444 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(), 447 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(),
445 "Encode"); 448 "Encode");
446 const VideoFrame* frame_to_send = &video_frame; 449 const VideoFrame* frame_to_send = &video_frame;
447 // TODO(wuchengli): support texture frames. 450 // TODO(wuchengli): support texture frames.
448 if (!video_frame.video_frame_buffer()->native_handle()) { 451 if (!video_frame.video_frame_buffer()->native_handle()) {
449 // Pass frame via preprocessor. 452 // Pass frame via preprocessor.
450 frame_to_send = vp_->PreprocessFrame(video_frame); 453 frame_to_send = vp_->PreprocessFrame(video_frame);
451 if (!frame_to_send) { 454 if (!frame_to_send) {
452 // Drop this frame, or there was an error processing it. 455 // Drop this frame, or there was an error processing it.
453 return; 456 return;
454 } 457 }
455 } 458 }
456 459
460 overuse_detector_.FrameCaptured(video_frame, time_when_posted_in_ms);
461
457 if (encoder_config_.codecType == webrtc::kVideoCodecVP8) { 462 if (encoder_config_.codecType == webrtc::kVideoCodecVP8) {
458 webrtc::CodecSpecificInfo codec_specific_info; 463 webrtc::CodecSpecificInfo codec_specific_info;
459 codec_specific_info.codecType = webrtc::kVideoCodecVP8; 464 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
460 465
461 codec_specific_info.codecSpecific.VP8.hasReceivedRPSI = 466 codec_specific_info.codecSpecific.VP8.hasReceivedRPSI =
462 has_received_rpsi_; 467 has_received_rpsi_;
463 codec_specific_info.codecSpecific.VP8.hasReceivedSLI = 468 codec_specific_info.codecSpecific.VP8.hasReceivedSLI =
464 has_received_sli_; 469 has_received_sli_;
465 codec_specific_info.codecSpecific.VP8.pictureIdRPSI = 470 codec_specific_info.codecSpecific.VP8.pictureIdRPSI =
466 picture_id_rpsi_; 471 picture_id_rpsi_;
(...skipping 24 matching lines...) Expand all
491 // Encoded is called on whatever thread the real encoder implementation run 496 // Encoded is called on whatever thread the real encoder implementation run
492 // on. In the case of hardware encoders, there might be several encoders 497 // on. In the case of hardware encoders, there might be several encoders
493 // running in parallel on different threads. 498 // running in parallel on different threads.
494 if (stats_proxy_) { 499 if (stats_proxy_) {
495 stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info); 500 stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info);
496 } 501 }
497 502
498 EncodedImageCallback::Result result = 503 EncodedImageCallback::Result result =
499 sink_->OnEncodedImage(encoded_image, codec_specific_info, fragmentation); 504 sink_->OnEncodedImage(encoded_image, codec_specific_info, fragmentation);
500 505
501 overuse_detector_.FrameSent(encoded_image._timeStamp); 506 int64_t time_sent = clock_->TimeInMilliseconds();
507 uint32_t timestamp = encoded_image._timeStamp;
508 encoder_queue_.PostTask([this, timestamp, time_sent] {
509 RTC_DCHECK_RUN_ON(&encoder_queue_);
510 overuse_detector_.FrameSent(timestamp, time_sent);
511 });
502 return result; 512 return result;
503 } 513 }
504 514
505 void ViEEncoder::SendStatistics(uint32_t bit_rate, 515 void ViEEncoder::SendStatistics(uint32_t bit_rate,
506 uint32_t frame_rate, 516 uint32_t frame_rate,
507 const std::string& encoder_name) { 517 const std::string& encoder_name) {
508 RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread()); 518 RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread());
509 if (stats_proxy_) 519 if (stats_proxy_)
510 stats_proxy_->OnEncoderStatsUpdate(frame_rate, bit_rate, encoder_name); 520 stats_proxy_->OnEncoderStatsUpdate(frame_rate, bit_rate, encoder_name);
511 } 521 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 last_observed_bitrate_bps_ = bitrate_bps; 580 last_observed_bitrate_bps_ = bitrate_bps;
571 581
572 if (stats_proxy_ && video_suspension_changed) { 582 if (stats_proxy_ && video_suspension_changed) {
573 LOG(LS_INFO) << "Video suspend state changed to: " 583 LOG(LS_INFO) << "Video suspend state changed to: "
574 << (video_is_suspended ? "suspended" : "not suspended"); 584 << (video_is_suspended ? "suspended" : "not suspended");
575 stats_proxy_->OnSuspendChange(video_is_suspended); 585 stats_proxy_->OnSuspendChange(video_is_suspended);
576 } 586 }
577 } 587 }
578 588
579 void ViEEncoder::OveruseDetected() { 589 void ViEEncoder::OveruseDetected() {
580 RTC_DCHECK_RUN_ON(&module_process_thread_checker_); 590 RTC_DCHECK_RUN_ON(&encoder_queue_);
581 // TODO(perkj): When ViEEncoder inherit rtc::VideoSink instead of 591 // TODO(perkj): When ViEEncoder inherit rtc::VideoSink instead of
582 // VideoCaptureInput |load_observer_| should be removed and overuse be 592 // VideoCaptureInput |load_observer_| should be removed and overuse be
583 // expressed as rtc::VideoSinkWants instead. 593 // expressed as rtc::VideoSinkWants instead.
584 if (load_observer_) 594 if (load_observer_)
585 load_observer_->OnLoadUpdate(LoadObserver::kOveruse); 595 load_observer_->OnLoadUpdate(LoadObserver::kOveruse);
586 } 596 }
587 597
588 void ViEEncoder::NormalUsage() { 598 void ViEEncoder::NormalUsage() {
589 RTC_DCHECK_RUN_ON(&module_process_thread_checker_); 599 RTC_DCHECK_RUN_ON(&encoder_queue_);
590 if (load_observer_) 600 if (load_observer_)
591 load_observer_->OnLoadUpdate(LoadObserver::kUnderuse); 601 load_observer_->OnLoadUpdate(LoadObserver::kUnderuse);
592 } 602 }
593 603
594 } // namespace webrtc 604 } // namespace webrtc
OLDNEW
« webrtc/video/overuse_frame_detector_unittest.cc ('K') | « webrtc/video/vie_encoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698