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 |