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

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

Powered by Google App Engine
This is Rietveld 408576698