| 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 10 matching lines...) Expand all Loading... |
| 21 #include "webrtc/modules/pacing/paced_sender.h" | 21 #include "webrtc/modules/pacing/paced_sender.h" |
| 22 #include "webrtc/modules/video_coding/include/video_coding.h" | 22 #include "webrtc/modules/video_coding/include/video_coding.h" |
| 23 #include "webrtc/modules/video_coding/include/video_coding_defines.h" | 23 #include "webrtc/modules/video_coding/include/video_coding_defines.h" |
| 24 #include "webrtc/system_wrappers/include/metrics.h" | 24 #include "webrtc/system_wrappers/include/metrics.h" |
| 25 #include "webrtc/video/overuse_frame_detector.h" | 25 #include "webrtc/video/overuse_frame_detector.h" |
| 26 #include "webrtc/video/send_statistics_proxy.h" | 26 #include "webrtc/video/send_statistics_proxy.h" |
| 27 #include "webrtc/video_frame.h" | 27 #include "webrtc/video_frame.h" |
| 28 | 28 |
| 29 namespace webrtc { | 29 namespace webrtc { |
| 30 | 30 |
| 31 static const float kStopPaddingThresholdMs = 2000; | |
| 32 | |
| 33 ViEEncoder::ViEEncoder(uint32_t number_of_cores, | 31 ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
| 34 ProcessThread* module_process_thread, | 32 ProcessThread* module_process_thread, |
| 35 SendStatisticsProxy* stats_proxy, | 33 SendStatisticsProxy* stats_proxy, |
| 36 OveruseFrameDetector* overuse_detector, | 34 OveruseFrameDetector* overuse_detector, |
| 37 EncodedImageCallback* sink) | 35 EncodedImageCallback* sink) |
| 38 : number_of_cores_(number_of_cores), | 36 : number_of_cores_(number_of_cores), |
| 39 sink_(sink), | 37 sink_(sink), |
| 40 vp_(VideoProcessing::Create()), | 38 vp_(VideoProcessing::Create()), |
| 41 video_sender_(Clock::GetRealTimeClock(), this, this, this), | 39 video_sender_(Clock::GetRealTimeClock(), this, this, this), |
| 42 stats_proxy_(stats_proxy), | 40 stats_proxy_(stats_proxy), |
| 43 overuse_detector_(overuse_detector), | 41 overuse_detector_(overuse_detector), |
| 44 time_of_last_frame_activity_ms_(0), | 42 time_of_last_frame_activity_ms_(0), |
| 45 encoder_config_(), | 43 encoder_config_(), |
| 46 min_transmit_bitrate_bps_(0), | |
| 47 last_observed_bitrate_bps_(0), | 44 last_observed_bitrate_bps_(0), |
| 48 encoder_paused_(true), | 45 encoder_paused_(true), |
| 49 encoder_paused_and_dropped_frame_(false), | 46 encoder_paused_and_dropped_frame_(false), |
| 50 module_process_thread_(module_process_thread), | 47 module_process_thread_(module_process_thread), |
| 51 has_received_sli_(false), | 48 has_received_sli_(false), |
| 52 picture_id_sli_(0), | 49 picture_id_sli_(0), |
| 53 has_received_rpsi_(false), | 50 has_received_rpsi_(false), |
| 54 picture_id_rpsi_(0), | 51 picture_id_rpsi_(0), |
| 55 video_suspended_(false) { | 52 video_suspended_(false) { |
| 56 module_process_thread_->RegisterModule(&video_sender_); | 53 module_process_thread_->RegisterModule(&video_sender_); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 81 video_sender_.RegisterExternalEncoder(encoder, pl_type, internal_source); | 78 video_sender_.RegisterExternalEncoder(encoder, pl_type, internal_source); |
| 82 return 0; | 79 return 0; |
| 83 } | 80 } |
| 84 | 81 |
| 85 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { | 82 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { |
| 86 video_sender_.RegisterExternalEncoder(nullptr, pl_type, false); | 83 video_sender_.RegisterExternalEncoder(nullptr, pl_type, false); |
| 87 return 0; | 84 return 0; |
| 88 } | 85 } |
| 89 | 86 |
| 90 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec, | 87 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec, |
| 91 int min_transmit_bitrate_bps, | |
| 92 size_t max_data_payload_length) { | 88 size_t max_data_payload_length) { |
| 93 // Setting target width and height for VPM. | 89 // Setting target width and height for VPM. |
| 94 RTC_CHECK_EQ(VPM_OK, | 90 RTC_CHECK_EQ(VPM_OK, |
| 95 vp_->SetTargetResolution(video_codec.width, video_codec.height, | 91 vp_->SetTargetResolution(video_codec.width, video_codec.height, |
| 96 video_codec.maxFramerate)); | 92 video_codec.maxFramerate)); |
| 97 | 93 |
| 98 // Cache codec before calling AddBitrateObserver (which calls OnBitrateUpdated | 94 // Cache codec before calling AddBitrateObserver (which calls OnBitrateUpdated |
| 99 // that makes use of the number of simulcast streams configured). | 95 // that makes use of the number of simulcast streams configured). |
| 100 { | 96 { |
| 101 rtc::CritScope lock(&data_cs_); | 97 rtc::CritScope lock(&data_cs_); |
| 102 encoder_config_ = video_codec; | 98 encoder_config_ = video_codec; |
| 103 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps; | |
| 104 } | 99 } |
| 105 | 100 |
| 106 bool success = video_sender_.RegisterSendCodec( | 101 bool success = video_sender_.RegisterSendCodec( |
| 107 &video_codec, number_of_cores_, | 102 &video_codec, number_of_cores_, |
| 108 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK; | 103 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK; |
| 109 if (!success) { | 104 if (!success) { |
| 110 LOG(LS_ERROR) << "Failed to configure encoder."; | 105 LOG(LS_ERROR) << "Failed to configure encoder."; |
| 111 RTC_DCHECK(success); | 106 RTC_DCHECK(success); |
| 112 } | 107 } |
| 113 | 108 |
| 114 if (stats_proxy_) { | 109 if (stats_proxy_) { |
| 115 VideoEncoderConfig::ContentType content_type = | 110 VideoEncoderConfig::ContentType content_type = |
| 116 VideoEncoderConfig::ContentType::kRealtimeVideo; | 111 VideoEncoderConfig::ContentType::kRealtimeVideo; |
| 117 switch (video_codec.mode) { | 112 switch (video_codec.mode) { |
| 118 case kRealtimeVideo: | 113 case kRealtimeVideo: |
| 119 content_type = VideoEncoderConfig::ContentType::kRealtimeVideo; | 114 content_type = VideoEncoderConfig::ContentType::kRealtimeVideo; |
| 120 break; | 115 break; |
| 121 case kScreensharing: | 116 case kScreensharing: |
| 122 content_type = VideoEncoderConfig::ContentType::kScreen; | 117 content_type = VideoEncoderConfig::ContentType::kScreen; |
| 123 break; | 118 break; |
| 124 default: | 119 default: |
| 125 RTC_NOTREACHED(); | 120 RTC_NOTREACHED(); |
| 126 break; | 121 break; |
| 127 } | 122 } |
| 128 stats_proxy_->SetContentType(content_type); | 123 stats_proxy_->SetContentType(content_type); |
| 129 } | 124 } |
| 130 } | 125 } |
| 131 | 126 |
| 132 int ViEEncoder::GetPaddingNeededBps() const { | |
| 133 int64_t time_of_last_frame_activity_ms; | |
| 134 int min_transmit_bitrate_bps; | |
| 135 VideoCodec send_codec; | |
| 136 bool video_is_suspended; | |
| 137 { | |
| 138 rtc::CritScope lock(&data_cs_); | |
| 139 bool send_padding = encoder_config_.numberOfSimulcastStreams > 1 || | |
| 140 video_suspended_ || min_transmit_bitrate_bps_ > 0; | |
| 141 if (!send_padding) | |
| 142 return 0; | |
| 143 time_of_last_frame_activity_ms = time_of_last_frame_activity_ms_; | |
| 144 min_transmit_bitrate_bps = min_transmit_bitrate_bps_; | |
| 145 send_codec = encoder_config_; | |
| 146 video_is_suspended = video_suspended_; | |
| 147 } | |
| 148 | |
| 149 // Find the max amount of padding we can allow ourselves to send at this | |
| 150 // point, based on which streams are currently active and what our current | |
| 151 // available bandwidth is. | |
| 152 int pad_up_to_bitrate_bps = 0; | |
| 153 if (send_codec.numberOfSimulcastStreams == 0) { | |
| 154 pad_up_to_bitrate_bps = send_codec.minBitrate * 1000; | |
| 155 } else { | |
| 156 SimulcastStream* stream_configs = send_codec.simulcastStream; | |
| 157 pad_up_to_bitrate_bps = | |
| 158 stream_configs[send_codec.numberOfSimulcastStreams - 1].minBitrate * | |
| 159 1000; | |
| 160 for (int i = 0; i < send_codec.numberOfSimulcastStreams - 1; ++i) { | |
| 161 pad_up_to_bitrate_bps += stream_configs[i].targetBitrate * 1000; | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 // Disable padding if only sending one stream and video isn't suspended and | |
| 166 // min-transmit bitrate isn't used (applied later). | |
| 167 if (!video_is_suspended && send_codec.numberOfSimulcastStreams <= 1) | |
| 168 pad_up_to_bitrate_bps = 0; | |
| 169 | |
| 170 // The amount of padding should decay to zero if no frames are being | |
| 171 // captured/encoded unless a min-transmit bitrate is used. | |
| 172 int64_t now_ms = rtc::TimeMillis(); | |
| 173 if (now_ms - time_of_last_frame_activity_ms > kStopPaddingThresholdMs) | |
| 174 pad_up_to_bitrate_bps = 0; | |
| 175 | |
| 176 // Pad up to min bitrate. | |
| 177 if (pad_up_to_bitrate_bps < min_transmit_bitrate_bps) | |
| 178 pad_up_to_bitrate_bps = min_transmit_bitrate_bps; | |
| 179 | |
| 180 return pad_up_to_bitrate_bps; | |
| 181 } | |
| 182 | |
| 183 bool ViEEncoder::EncoderPaused() const { | 127 bool ViEEncoder::EncoderPaused() const { |
| 184 // Pause video if paused by caller or as long as the network is down or the | 128 // Pause video if paused by caller or as long as the network is down or the |
| 185 // pacer queue has grown too large in buffered mode. | 129 // pacer queue has grown too large in buffered mode. |
| 186 // If the pacer queue has grown to large or the network is down, | 130 // If the pacer queue has grown to large or the network is down, |
| 187 // last_observed_bitrate_bps_ will be 0. | 131 // last_observed_bitrate_bps_ will be 0. |
| 188 return encoder_paused_ || video_suspended_ || last_observed_bitrate_bps_ == 0; | 132 return encoder_paused_ || video_suspended_ || last_observed_bitrate_bps_ == 0; |
| 189 } | 133 } |
| 190 | 134 |
| 191 void ViEEncoder::TraceFrameDropStart() { | 135 void ViEEncoder::TraceFrameDropStart() { |
| 192 // Start trace event only on the first frame after encoder is paused. | 136 // Start trace event only on the first frame after encoder is paused. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 video_sender_.AddVideoFrame(*frame_to_send, &codec_specific_info); | 195 video_sender_.AddVideoFrame(*frame_to_send, &codec_specific_info); |
| 252 return; | 196 return; |
| 253 } | 197 } |
| 254 video_sender_.AddVideoFrame(*frame_to_send, nullptr); | 198 video_sender_.AddVideoFrame(*frame_to_send, nullptr); |
| 255 } | 199 } |
| 256 | 200 |
| 257 void ViEEncoder::SendKeyFrame() { | 201 void ViEEncoder::SendKeyFrame() { |
| 258 video_sender_.IntraFrameRequest(0); | 202 video_sender_.IntraFrameRequest(0); |
| 259 } | 203 } |
| 260 | 204 |
| 205 int64_t ViEEncoder::time_of_last_frame_activity_ms() { |
| 206 rtc::CritScope lock(&data_cs_); |
| 207 return time_of_last_frame_activity_ms_; |
| 208 } |
| 209 |
| 261 void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) { | 210 void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) { |
| 262 if (stats_proxy_) | 211 if (stats_proxy_) |
| 263 stats_proxy_->OnSetRates(bitrate_bps, framerate); | 212 stats_proxy_->OnSetRates(bitrate_bps, framerate); |
| 264 } | 213 } |
| 265 | 214 |
| 266 int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image, | 215 int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image, |
| 267 const CodecSpecificInfo* codec_specific_info, | 216 const CodecSpecificInfo* codec_specific_info, |
| 268 const RTPFragmentationHeader* fragmentation) { | 217 const RTPFragmentationHeader* fragmentation) { |
| 269 { | 218 { |
| 270 rtc::CritScope lock(&data_cs_); | 219 rtc::CritScope lock(&data_cs_); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 video_suspended_ = video_is_suspended; | 272 video_suspended_ = video_is_suspended; |
| 324 } | 273 } |
| 325 | 274 |
| 326 if (stats_proxy_ && video_suspension_changed) { | 275 if (stats_proxy_ && video_suspension_changed) { |
| 327 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended; | 276 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended; |
| 328 stats_proxy_->OnSuspendChange(video_is_suspended); | 277 stats_proxy_->OnSuspendChange(video_is_suspended); |
| 329 } | 278 } |
| 330 } | 279 } |
| 331 | 280 |
| 332 } // namespace webrtc | 281 } // namespace webrtc |
| OLD | NEW |