| OLD | NEW |
| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 ViEEncoder* const vie_encoder_; | 78 ViEEncoder* const vie_encoder_; |
| 79 VideoEncoderConfig config_; | 79 VideoEncoderConfig config_; |
| 80 size_t max_data_payload_length_; | 80 size_t max_data_payload_length_; |
| 81 bool nack_enabled_; | 81 bool nack_enabled_; |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 class ViEEncoder::EncodeTask : public rtc::QueuedTask { | 84 class ViEEncoder::EncodeTask : public rtc::QueuedTask { |
| 85 public: | 85 public: |
| 86 EncodeTask(const VideoFrame& frame, | 86 EncodeTask(const VideoFrame& frame, |
| 87 ViEEncoder* vie_encoder, | 87 ViEEncoder* vie_encoder, |
| 88 int64_t time_when_posted_in_ms, | 88 int64_t time_when_posted_us, |
| 89 bool log_stats) | 89 bool log_stats) |
| 90 : frame_(frame), | 90 : frame_(frame), |
| 91 vie_encoder_(vie_encoder), | 91 vie_encoder_(vie_encoder), |
| 92 time_when_posted_ms_(time_when_posted_in_ms), | 92 time_when_posted_us_(time_when_posted_us), |
| 93 log_stats_(log_stats) { | 93 log_stats_(log_stats) { |
| 94 ++vie_encoder_->posted_frames_waiting_for_encode_; | 94 ++vie_encoder_->posted_frames_waiting_for_encode_; |
| 95 } | 95 } |
| 96 | 96 |
| 97 private: | 97 private: |
| 98 bool Run() override { | 98 bool Run() override { |
| 99 RTC_DCHECK_RUN_ON(&vie_encoder_->encoder_queue_); | 99 RTC_DCHECK_RUN_ON(&vie_encoder_->encoder_queue_); |
| 100 RTC_DCHECK_GT(vie_encoder_->posted_frames_waiting_for_encode_.Value(), 0); | 100 RTC_DCHECK_GT(vie_encoder_->posted_frames_waiting_for_encode_.Value(), 0); |
| 101 vie_encoder_->stats_proxy_->OnIncomingFrame(frame_.width(), | 101 vie_encoder_->stats_proxy_->OnIncomingFrame(frame_.width(), |
| 102 frame_.height()); | 102 frame_.height()); |
| 103 ++vie_encoder_->captured_frame_count_; | 103 ++vie_encoder_->captured_frame_count_; |
| 104 if (--vie_encoder_->posted_frames_waiting_for_encode_ == 0) { | 104 if (--vie_encoder_->posted_frames_waiting_for_encode_ == 0) { |
| 105 vie_encoder_->EncodeVideoFrame(frame_, time_when_posted_ms_); | 105 vie_encoder_->EncodeVideoFrame(frame_, time_when_posted_us_); |
| 106 } else { | 106 } else { |
| 107 // There is a newer frame in flight. Do not encode this frame. | 107 // There is a newer frame in flight. Do not encode this frame. |
| 108 LOG(LS_VERBOSE) | 108 LOG(LS_VERBOSE) |
| 109 << "Incoming frame dropped due to that the encoder is blocked."; | 109 << "Incoming frame dropped due to that the encoder is blocked."; |
| 110 ++vie_encoder_->dropped_frame_count_; | 110 ++vie_encoder_->dropped_frame_count_; |
| 111 } | 111 } |
| 112 if (log_stats_) { | 112 if (log_stats_) { |
| 113 LOG(LS_INFO) << "Number of frames: captured " | 113 LOG(LS_INFO) << "Number of frames: captured " |
| 114 << vie_encoder_->captured_frame_count_ | 114 << vie_encoder_->captured_frame_count_ |
| 115 << ", dropped (due to encoder blocked) " | 115 << ", dropped (due to encoder blocked) " |
| 116 << vie_encoder_->dropped_frame_count_ << ", interval_ms " | 116 << vie_encoder_->dropped_frame_count_ << ", interval_ms " |
| 117 << kFrameLogIntervalMs; | 117 << kFrameLogIntervalMs; |
| 118 vie_encoder_->captured_frame_count_ = 0; | 118 vie_encoder_->captured_frame_count_ = 0; |
| 119 vie_encoder_->dropped_frame_count_ = 0; | 119 vie_encoder_->dropped_frame_count_ = 0; |
| 120 } | 120 } |
| 121 return true; | 121 return true; |
| 122 } | 122 } |
| 123 VideoFrame frame_; | 123 VideoFrame frame_; |
| 124 ViEEncoder* const vie_encoder_; | 124 ViEEncoder* const vie_encoder_; |
| 125 const int64_t time_when_posted_ms_; | 125 const int64_t time_when_posted_us_; |
| 126 const bool log_stats_; | 126 const bool log_stats_; |
| 127 }; | 127 }; |
| 128 | 128 |
| 129 // VideoSourceProxy is responsible ensuring thread safety between calls to | 129 // VideoSourceProxy is responsible ensuring thread safety between calls to |
| 130 // ViEEncoder::SetSource that will happen on libjingle's worker thread when a | 130 // ViEEncoder::SetSource that will happen on libjingle's worker thread when a |
| 131 // video capturer is connected to the encoder and the encoder task queue | 131 // video capturer is connected to the encoder and the encoder task queue |
| 132 // (encoder_queue_) where the encoder reports its VideoSinkWants. | 132 // (encoder_queue_) where the encoder reports its VideoSinkWants. |
| 133 class ViEEncoder::VideoSourceProxy { | 133 class ViEEncoder::VideoSourceProxy { |
| 134 public: | 134 public: |
| 135 explicit VideoSourceProxy(ViEEncoder* vie_encoder) | 135 explicit VideoSourceProxy(ViEEncoder* vie_encoder) |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, | 243 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, |
| 244 EncodedFrameObserver* encoder_timing) | 244 EncodedFrameObserver* encoder_timing) |
| 245 : shutdown_event_(true /* manual_reset */, false), | 245 : shutdown_event_(true /* manual_reset */, false), |
| 246 number_of_cores_(number_of_cores), | 246 number_of_cores_(number_of_cores), |
| 247 source_proxy_(new VideoSourceProxy(this)), | 247 source_proxy_(new VideoSourceProxy(this)), |
| 248 sink_(nullptr), | 248 sink_(nullptr), |
| 249 settings_(settings), | 249 settings_(settings), |
| 250 codec_type_(PayloadNameToCodecType(settings.payload_name) | 250 codec_type_(PayloadNameToCodecType(settings.payload_name) |
| 251 .value_or(VideoCodecType::kVideoCodecUnknown)), | 251 .value_or(VideoCodecType::kVideoCodecUnknown)), |
| 252 video_sender_(Clock::GetRealTimeClock(), this, this), | 252 video_sender_(Clock::GetRealTimeClock(), this, this), |
| 253 overuse_detector_(Clock::GetRealTimeClock(), | 253 overuse_detector_(GetCpuOveruseOptions(settings.full_overuse_time), |
| 254 GetCpuOveruseOptions(settings.full_overuse_time), | |
| 255 this, | 254 this, |
| 256 encoder_timing, | 255 encoder_timing, |
| 257 stats_proxy), | 256 stats_proxy), |
| 258 stats_proxy_(stats_proxy), | 257 stats_proxy_(stats_proxy), |
| 259 pre_encode_callback_(pre_encode_callback), | 258 pre_encode_callback_(pre_encode_callback), |
| 260 module_process_thread_(nullptr), | 259 module_process_thread_(nullptr), |
| 261 pending_encoder_reconfiguration_(false), | 260 pending_encoder_reconfiguration_(false), |
| 262 encoder_start_bitrate_bps_(0), | 261 encoder_start_bitrate_bps_(0), |
| 263 max_data_payload_length_(0), | 262 max_data_payload_length_(0), |
| 264 nack_enabled_(false), | 263 nack_enabled_(false), |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 } | 485 } |
| 487 | 486 |
| 488 bool log_stats = false; | 487 bool log_stats = false; |
| 489 if (current_time - last_frame_log_ms_ > kFrameLogIntervalMs) { | 488 if (current_time - last_frame_log_ms_ > kFrameLogIntervalMs) { |
| 490 last_frame_log_ms_ = current_time; | 489 last_frame_log_ms_ = current_time; |
| 491 log_stats = true; | 490 log_stats = true; |
| 492 } | 491 } |
| 493 | 492 |
| 494 last_captured_timestamp_ = incoming_frame.ntp_time_ms(); | 493 last_captured_timestamp_ = incoming_frame.ntp_time_ms(); |
| 495 encoder_queue_.PostTask(std::unique_ptr<rtc::QueuedTask>(new EncodeTask( | 494 encoder_queue_.PostTask(std::unique_ptr<rtc::QueuedTask>(new EncodeTask( |
| 496 incoming_frame, this, clock_->TimeInMilliseconds(), log_stats))); | 495 incoming_frame, this, rtc::TimeMicros(), log_stats))); |
| 497 } | 496 } |
| 498 | 497 |
| 499 bool ViEEncoder::EncoderPaused() const { | 498 bool ViEEncoder::EncoderPaused() const { |
| 500 RTC_DCHECK_RUN_ON(&encoder_queue_); | 499 RTC_DCHECK_RUN_ON(&encoder_queue_); |
| 501 // Pause video if paused by caller or as long as the network is down or the | 500 // Pause video if paused by caller or as long as the network is down or the |
| 502 // pacer queue has grown too large in buffered mode. | 501 // pacer queue has grown too large in buffered mode. |
| 503 // If the pacer queue has grown too large or the network is down, | 502 // If the pacer queue has grown too large or the network is down, |
| 504 // last_observed_bitrate_bps_ will be 0. | 503 // last_observed_bitrate_bps_ will be 0. |
| 505 return last_observed_bitrate_bps_ == 0; | 504 return last_observed_bitrate_bps_ == 0; |
| 506 } | 505 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 518 void ViEEncoder::TraceFrameDropEnd() { | 517 void ViEEncoder::TraceFrameDropEnd() { |
| 519 RTC_DCHECK_RUN_ON(&encoder_queue_); | 518 RTC_DCHECK_RUN_ON(&encoder_queue_); |
| 520 // End trace event on first frame after encoder resumes, if frame was dropped. | 519 // End trace event on first frame after encoder resumes, if frame was dropped. |
| 521 if (encoder_paused_and_dropped_frame_) { | 520 if (encoder_paused_and_dropped_frame_) { |
| 522 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); | 521 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); |
| 523 } | 522 } |
| 524 encoder_paused_and_dropped_frame_ = false; | 523 encoder_paused_and_dropped_frame_ = false; |
| 525 } | 524 } |
| 526 | 525 |
| 527 void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame, | 526 void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame, |
| 528 int64_t time_when_posted_in_ms) { | 527 int64_t time_when_posted_us) { |
| 529 RTC_DCHECK_RUN_ON(&encoder_queue_); | 528 RTC_DCHECK_RUN_ON(&encoder_queue_); |
| 530 | 529 |
| 531 if (pre_encode_callback_) | 530 if (pre_encode_callback_) |
| 532 pre_encode_callback_->OnFrame(video_frame); | 531 pre_encode_callback_->OnFrame(video_frame); |
| 533 | 532 |
| 534 if (!last_frame_info_ || video_frame.width() != last_frame_info_->width || | 533 if (!last_frame_info_ || video_frame.width() != last_frame_info_->width || |
| 535 video_frame.height() != last_frame_info_->height || | 534 video_frame.height() != last_frame_info_->height || |
| 536 video_frame.rotation() != last_frame_info_->rotation || | 535 video_frame.rotation() != last_frame_info_->rotation || |
| 537 video_frame.is_texture() != last_frame_info_->is_texture) { | 536 video_frame.is_texture() != last_frame_info_->is_texture) { |
| 538 pending_encoder_reconfiguration_ = true; | 537 pending_encoder_reconfiguration_ = true; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 558 | 557 |
| 559 if (EncoderPaused()) { | 558 if (EncoderPaused()) { |
| 560 TraceFrameDropStart(); | 559 TraceFrameDropStart(); |
| 561 return; | 560 return; |
| 562 } | 561 } |
| 563 TraceFrameDropEnd(); | 562 TraceFrameDropEnd(); |
| 564 | 563 |
| 565 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(), | 564 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(), |
| 566 "Encode"); | 565 "Encode"); |
| 567 | 566 |
| 568 overuse_detector_.FrameCaptured(video_frame, time_when_posted_in_ms); | 567 overuse_detector_.FrameCaptured(video_frame, time_when_posted_us); |
| 569 | 568 |
| 570 if (codec_type_ == webrtc::kVideoCodecVP8) { | 569 if (codec_type_ == webrtc::kVideoCodecVP8) { |
| 571 webrtc::CodecSpecificInfo codec_specific_info; | 570 webrtc::CodecSpecificInfo codec_specific_info; |
| 572 codec_specific_info.codecType = webrtc::kVideoCodecVP8; | 571 codec_specific_info.codecType = webrtc::kVideoCodecVP8; |
| 573 | 572 |
| 574 codec_specific_info.codecSpecific.VP8.hasReceivedRPSI = has_received_rpsi_; | 573 codec_specific_info.codecSpecific.VP8.hasReceivedRPSI = has_received_rpsi_; |
| 575 codec_specific_info.codecSpecific.VP8.hasReceivedSLI = has_received_sli_; | 574 codec_specific_info.codecSpecific.VP8.hasReceivedSLI = has_received_sli_; |
| 576 codec_specific_info.codecSpecific.VP8.pictureIdRPSI = picture_id_rpsi_; | 575 codec_specific_info.codecSpecific.VP8.pictureIdRPSI = picture_id_rpsi_; |
| 577 codec_specific_info.codecSpecific.VP8.pictureIdSLI = picture_id_sli_; | 576 codec_specific_info.codecSpecific.VP8.pictureIdSLI = picture_id_sli_; |
| 578 has_received_sli_ = false; | 577 has_received_sli_ = false; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 599 const RTPFragmentationHeader* fragmentation) { | 598 const RTPFragmentationHeader* fragmentation) { |
| 600 // Encoded is called on whatever thread the real encoder implementation run | 599 // Encoded is called on whatever thread the real encoder implementation run |
| 601 // on. In the case of hardware encoders, there might be several encoders | 600 // on. In the case of hardware encoders, there might be several encoders |
| 602 // running in parallel on different threads. | 601 // running in parallel on different threads. |
| 603 if (stats_proxy_) | 602 if (stats_proxy_) |
| 604 stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info); | 603 stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info); |
| 605 | 604 |
| 606 EncodedImageCallback::Result result = | 605 EncodedImageCallback::Result result = |
| 607 sink_->OnEncodedImage(encoded_image, codec_specific_info, fragmentation); | 606 sink_->OnEncodedImage(encoded_image, codec_specific_info, fragmentation); |
| 608 | 607 |
| 609 int64_t time_sent = clock_->TimeInMilliseconds(); | 608 int64_t time_sent_us = rtc::TimeMicros(); |
| 610 uint32_t timestamp = encoded_image._timeStamp; | 609 uint32_t timestamp = encoded_image._timeStamp; |
| 611 const int qp = encoded_image.qp_; | 610 const int qp = encoded_image.qp_; |
| 612 encoder_queue_.PostTask([this, timestamp, time_sent, qp] { | 611 encoder_queue_.PostTask([this, timestamp, time_sent_us, qp] { |
| 613 RTC_DCHECK_RUN_ON(&encoder_queue_); | 612 RTC_DCHECK_RUN_ON(&encoder_queue_); |
| 614 overuse_detector_.FrameSent(timestamp, time_sent); | 613 overuse_detector_.FrameSent(timestamp, time_sent_us); |
| 615 if (quality_scaler_) | 614 if (quality_scaler_) |
| 616 quality_scaler_->ReportQP(qp); | 615 quality_scaler_->ReportQP(qp); |
| 617 }); | 616 }); |
| 618 | 617 |
| 619 return result; | 618 return result; |
| 620 } | 619 } |
| 621 | 620 |
| 622 void ViEEncoder::OnDroppedFrame() { | 621 void ViEEncoder::OnDroppedFrame() { |
| 623 encoder_queue_.PostTask([this] { | 622 encoder_queue_.PostTask([this] { |
| 624 RTC_DCHECK_RUN_ON(&encoder_queue_); | 623 RTC_DCHECK_RUN_ON(&encoder_queue_); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 --scale_counter_[reason]; | 757 --scale_counter_[reason]; |
| 759 source_proxy_->RequestHigherResolutionThan(current_pixel_count); | 758 source_proxy_->RequestHigherResolutionThan(current_pixel_count); |
| 760 LOG(LS_INFO) << "Scaling up resolution."; | 759 LOG(LS_INFO) << "Scaling up resolution."; |
| 761 for (size_t i = 0; i < kScaleReasonSize; ++i) { | 760 for (size_t i = 0; i < kScaleReasonSize; ++i) { |
| 762 LOG(LS_INFO) << "Scaled " << scale_counter_[i] | 761 LOG(LS_INFO) << "Scaled " << scale_counter_[i] |
| 763 << " times for reason: " << (i ? "cpu" : "quality"); | 762 << " times for reason: " << (i ? "cpu" : "quality"); |
| 764 } | 763 } |
| 765 } | 764 } |
| 766 | 765 |
| 767 } // namespace webrtc | 766 } // namespace webrtc |
| OLD | NEW |