| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 } | 77 } |
| 78 | 78 |
| 79 int64_t VideoSender::TimeUntilNextProcess() { | 79 int64_t VideoSender::TimeUntilNextProcess() { |
| 80 return _sendStatsTimer.TimeUntilProcess(); | 80 return _sendStatsTimer.TimeUntilProcess(); |
| 81 } | 81 } |
| 82 | 82 |
| 83 // Register the send codec to be used. | 83 // Register the send codec to be used. |
| 84 int32_t VideoSender::RegisterSendCodec(const VideoCodec* sendCodec, | 84 int32_t VideoSender::RegisterSendCodec(const VideoCodec* sendCodec, |
| 85 uint32_t numberOfCores, | 85 uint32_t numberOfCores, |
| 86 uint32_t maxPayloadSize) { | 86 uint32_t maxPayloadSize) { |
| 87 DCHECK(main_thread_.CalledOnValidThread()); | 87 RTC_DCHECK(main_thread_.CalledOnValidThread()); |
| 88 rtc::CritScope lock(&send_crit_); | 88 rtc::CritScope lock(&send_crit_); |
| 89 if (sendCodec == nullptr) { | 89 if (sendCodec == nullptr) { |
| 90 return VCM_PARAMETER_ERROR; | 90 return VCM_PARAMETER_ERROR; |
| 91 } | 91 } |
| 92 | 92 |
| 93 bool ret = _codecDataBase.SetSendCodec( | 93 bool ret = _codecDataBase.SetSendCodec( |
| 94 sendCodec, numberOfCores, maxPayloadSize, &_encodedFrameCallback); | 94 sendCodec, numberOfCores, maxPayloadSize, &_encodedFrameCallback); |
| 95 | 95 |
| 96 // Update encoder regardless of result to make sure that we're not holding on | 96 // Update encoder regardless of result to make sure that we're not holding on |
| 97 // to a deleted instance. | 97 // to a deleted instance. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 126 sendCodec->startBitrate * 1000, | 126 sendCodec->startBitrate * 1000, |
| 127 sendCodec->width, | 127 sendCodec->width, |
| 128 sendCodec->height, | 128 sendCodec->height, |
| 129 sendCodec->maxFramerate, | 129 sendCodec->maxFramerate, |
| 130 numLayers, | 130 numLayers, |
| 131 maxPayloadSize); | 131 maxPayloadSize); |
| 132 return VCM_OK; | 132 return VCM_OK; |
| 133 } | 133 } |
| 134 | 134 |
| 135 const VideoCodec& VideoSender::GetSendCodec() const { | 135 const VideoCodec& VideoSender::GetSendCodec() const { |
| 136 DCHECK(main_thread_.CalledOnValidThread()); | 136 RTC_DCHECK(main_thread_.CalledOnValidThread()); |
| 137 return current_codec_; | 137 return current_codec_; |
| 138 } | 138 } |
| 139 | 139 |
| 140 int32_t VideoSender::SendCodecBlocking(VideoCodec* currentSendCodec) const { | 140 int32_t VideoSender::SendCodecBlocking(VideoCodec* currentSendCodec) const { |
| 141 rtc::CritScope lock(&send_crit_); | 141 rtc::CritScope lock(&send_crit_); |
| 142 if (currentSendCodec == nullptr) { | 142 if (currentSendCodec == nullptr) { |
| 143 return VCM_PARAMETER_ERROR; | 143 return VCM_PARAMETER_ERROR; |
| 144 } | 144 } |
| 145 return _codecDataBase.SendCodec(currentSendCodec) ? 0 : -1; | 145 return _codecDataBase.SendCodec(currentSendCodec) ? 0 : -1; |
| 146 } | 146 } |
| 147 | 147 |
| 148 VideoCodecType VideoSender::SendCodecBlocking() const { | 148 VideoCodecType VideoSender::SendCodecBlocking() const { |
| 149 rtc::CritScope lock(&send_crit_); | 149 rtc::CritScope lock(&send_crit_); |
| 150 return _codecDataBase.SendCodec(); | 150 return _codecDataBase.SendCodec(); |
| 151 } | 151 } |
| 152 | 152 |
| 153 // Register an external decoder object. | 153 // Register an external decoder object. |
| 154 // This can not be used together with external decoder callbacks. | 154 // This can not be used together with external decoder callbacks. |
| 155 int32_t VideoSender::RegisterExternalEncoder(VideoEncoder* externalEncoder, | 155 int32_t VideoSender::RegisterExternalEncoder(VideoEncoder* externalEncoder, |
| 156 uint8_t payloadType, | 156 uint8_t payloadType, |
| 157 bool internalSource /*= false*/) { | 157 bool internalSource /*= false*/) { |
| 158 DCHECK(main_thread_.CalledOnValidThread()); | 158 RTC_DCHECK(main_thread_.CalledOnValidThread()); |
| 159 | 159 |
| 160 rtc::CritScope lock(&send_crit_); | 160 rtc::CritScope lock(&send_crit_); |
| 161 | 161 |
| 162 if (externalEncoder == nullptr) { | 162 if (externalEncoder == nullptr) { |
| 163 bool wasSendCodec = false; | 163 bool wasSendCodec = false; |
| 164 const bool ret = | 164 const bool ret = |
| 165 _codecDataBase.DeregisterExternalEncoder(payloadType, &wasSendCodec); | 165 _codecDataBase.DeregisterExternalEncoder(payloadType, &wasSendCodec); |
| 166 if (wasSendCodec) { | 166 if (wasSendCodec) { |
| 167 // Make sure the VCM doesn't use the de-registered codec | 167 // Make sure the VCM doesn't use the de-registered codec |
| 168 _encoder = nullptr; | 168 _encoder = nullptr; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 186 | 186 |
| 187 // TODO(andresp): Make const once media_opt is thread-safe and this has a | 187 // TODO(andresp): Make const once media_opt is thread-safe and this has a |
| 188 // pointer to it. | 188 // pointer to it. |
| 189 int32_t VideoSender::SentFrameCount(VCMFrameCount* frameCount) { | 189 int32_t VideoSender::SentFrameCount(VCMFrameCount* frameCount) { |
| 190 *frameCount = _mediaOpt.SentFrameCount(); | 190 *frameCount = _mediaOpt.SentFrameCount(); |
| 191 return VCM_OK; | 191 return VCM_OK; |
| 192 } | 192 } |
| 193 | 193 |
| 194 // Get encode bitrate | 194 // Get encode bitrate |
| 195 int VideoSender::Bitrate(unsigned int* bitrate) const { | 195 int VideoSender::Bitrate(unsigned int* bitrate) const { |
| 196 DCHECK(main_thread_.CalledOnValidThread()); | 196 RTC_DCHECK(main_thread_.CalledOnValidThread()); |
| 197 // Since we're running on the thread that's the only thread known to modify | 197 // Since we're running on the thread that's the only thread known to modify |
| 198 // the value of _encoder, we don't need to grab the lock here. | 198 // the value of _encoder, we don't need to grab the lock here. |
| 199 | 199 |
| 200 // return the bit rate which the encoder is set to | 200 // return the bit rate which the encoder is set to |
| 201 if (!_encoder) { | 201 if (!_encoder) { |
| 202 return VCM_UNINITIALIZED; | 202 return VCM_UNINITIALIZED; |
| 203 } | 203 } |
| 204 *bitrate = _encoder->BitRate(); | 204 *bitrate = _encoder->BitRate(); |
| 205 return 0; | 205 return 0; |
| 206 } | 206 } |
| 207 | 207 |
| 208 // Get encode frame rate | 208 // Get encode frame rate |
| 209 int VideoSender::FrameRate(unsigned int* framerate) const { | 209 int VideoSender::FrameRate(unsigned int* framerate) const { |
| 210 DCHECK(main_thread_.CalledOnValidThread()); | 210 RTC_DCHECK(main_thread_.CalledOnValidThread()); |
| 211 // Since we're running on the thread that's the only thread known to modify | 211 // Since we're running on the thread that's the only thread known to modify |
| 212 // the value of _encoder, we don't need to grab the lock here. | 212 // the value of _encoder, we don't need to grab the lock here. |
| 213 | 213 |
| 214 // input frame rate, not compensated | 214 // input frame rate, not compensated |
| 215 if (!_encoder) { | 215 if (!_encoder) { |
| 216 return VCM_UNINITIALIZED; | 216 return VCM_UNINITIALIZED; |
| 217 } | 217 } |
| 218 *framerate = _encoder->FrameRate(); | 218 *framerate = _encoder->FrameRate(); |
| 219 return 0; | 219 return 0; |
| 220 } | 220 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 _sendStatsCallback = sendStats; | 267 _sendStatsCallback = sendStats; |
| 268 return VCM_OK; | 268 return VCM_OK; |
| 269 } | 269 } |
| 270 | 270 |
| 271 // Register a video protection callback which will be called to deliver the | 271 // Register a video protection callback which will be called to deliver the |
| 272 // requested FEC rate and NACK status (on/off). | 272 // requested FEC rate and NACK status (on/off). |
| 273 // Note: this callback is assumed to only be registered once and before it is | 273 // Note: this callback is assumed to only be registered once and before it is |
| 274 // used in this class. | 274 // used in this class. |
| 275 int32_t VideoSender::RegisterProtectionCallback( | 275 int32_t VideoSender::RegisterProtectionCallback( |
| 276 VCMProtectionCallback* protection_callback) { | 276 VCMProtectionCallback* protection_callback) { |
| 277 DCHECK(protection_callback == nullptr || protection_callback_ == nullptr); | 277 RTC_DCHECK(protection_callback == nullptr || protection_callback_ == nullptr); |
| 278 protection_callback_ = protection_callback; | 278 protection_callback_ = protection_callback; |
| 279 return VCM_OK; | 279 return VCM_OK; |
| 280 } | 280 } |
| 281 | 281 |
| 282 // Enable or disable a video protection method. | 282 // Enable or disable a video protection method. |
| 283 void VideoSender::SetVideoProtection(VCMVideoProtection videoProtection) { | 283 void VideoSender::SetVideoProtection(VCMVideoProtection videoProtection) { |
| 284 rtc::CritScope lock(&send_crit_); | 284 rtc::CritScope lock(&send_crit_); |
| 285 switch (videoProtection) { | 285 switch (videoProtection) { |
| 286 case kProtectionNone: | 286 case kProtectionNone: |
| 287 _mediaOpt.SetProtectionMethod(media_optimization::kNone); | 287 _mediaOpt.SetProtectionMethod(media_optimization::kNone); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 if (!_codecDataBase.MatchesCurrentResolution(videoFrame.width(), | 327 if (!_codecDataBase.MatchesCurrentResolution(videoFrame.width(), |
| 328 videoFrame.height())) { | 328 videoFrame.height())) { |
| 329 LOG(LS_ERROR) << "Incoming frame doesn't match set resolution. Dropping."; | 329 LOG(LS_ERROR) << "Incoming frame doesn't match set resolution. Dropping."; |
| 330 return VCM_PARAMETER_ERROR; | 330 return VCM_PARAMETER_ERROR; |
| 331 } | 331 } |
| 332 VideoFrame converted_frame = videoFrame; | 332 VideoFrame converted_frame = videoFrame; |
| 333 if (converted_frame.native_handle() && !_encoder->SupportsNativeHandle()) { | 333 if (converted_frame.native_handle() && !_encoder->SupportsNativeHandle()) { |
| 334 // This module only supports software encoding. | 334 // This module only supports software encoding. |
| 335 // TODO(pbos): Offload conversion from the encoder thread. | 335 // TODO(pbos): Offload conversion from the encoder thread. |
| 336 converted_frame = converted_frame.ConvertNativeToI420Frame(); | 336 converted_frame = converted_frame.ConvertNativeToI420Frame(); |
| 337 CHECK(!converted_frame.IsZeroSize()) | 337 RTC_CHECK(!converted_frame.IsZeroSize()) |
| 338 << "Frame conversion failed, won't be able to encode frame."; | 338 << "Frame conversion failed, won't be able to encode frame."; |
| 339 } | 339 } |
| 340 int32_t ret = | 340 int32_t ret = |
| 341 _encoder->Encode(converted_frame, codecSpecificInfo, _nextFrameTypes); | 341 _encoder->Encode(converted_frame, codecSpecificInfo, _nextFrameTypes); |
| 342 if (ret < 0) { | 342 if (ret < 0) { |
| 343 LOG(LS_ERROR) << "Failed to encode frame. Error code: " << ret; | 343 LOG(LS_ERROR) << "Failed to encode frame. Error code: " << ret; |
| 344 return ret; | 344 return ret; |
| 345 } | 345 } |
| 346 for (size_t i = 0; i < _nextFrameTypes.size(); ++i) { | 346 for (size_t i = 0; i < _nextFrameTypes.size(); ++i) { |
| 347 _nextFrameTypes[i] = kVideoFrameDelta; // Default frame type. | 347 _nextFrameTypes[i] = kVideoFrameDelta; // Default frame type. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 369 } | 369 } |
| 370 | 370 |
| 371 int32_t VideoSender::EnableFrameDropper(bool enable) { | 371 int32_t VideoSender::EnableFrameDropper(bool enable) { |
| 372 rtc::CritScope lock(&send_crit_); | 372 rtc::CritScope lock(&send_crit_); |
| 373 frame_dropper_enabled_ = enable; | 373 frame_dropper_enabled_ = enable; |
| 374 _mediaOpt.EnableFrameDropper(enable); | 374 _mediaOpt.EnableFrameDropper(enable); |
| 375 return VCM_OK; | 375 return VCM_OK; |
| 376 } | 376 } |
| 377 | 377 |
| 378 void VideoSender::SuspendBelowMinBitrate() { | 378 void VideoSender::SuspendBelowMinBitrate() { |
| 379 DCHECK(main_thread_.CalledOnValidThread()); | 379 RTC_DCHECK(main_thread_.CalledOnValidThread()); |
| 380 int threshold_bps; | 380 int threshold_bps; |
| 381 if (current_codec_.numberOfSimulcastStreams == 0) { | 381 if (current_codec_.numberOfSimulcastStreams == 0) { |
| 382 threshold_bps = current_codec_.minBitrate * 1000; | 382 threshold_bps = current_codec_.minBitrate * 1000; |
| 383 } else { | 383 } else { |
| 384 threshold_bps = current_codec_.simulcastStream[0].minBitrate * 1000; | 384 threshold_bps = current_codec_.simulcastStream[0].minBitrate * 1000; |
| 385 } | 385 } |
| 386 // Set the hysteresis window to be at 10% of the threshold, but at least | 386 // Set the hysteresis window to be at 10% of the threshold, but at least |
| 387 // 10 kbps. | 387 // 10 kbps. |
| 388 int window_bps = std::max(threshold_bps / 10, 10000); | 388 int window_bps = std::max(threshold_bps / 10, 10000); |
| 389 _mediaOpt.SuspendBelowMinBitrate(threshold_bps, window_bps); | 389 _mediaOpt.SuspendBelowMinBitrate(threshold_bps, window_bps); |
| 390 } | 390 } |
| 391 | 391 |
| 392 bool VideoSender::VideoSuspended() const { | 392 bool VideoSender::VideoSuspended() const { |
| 393 rtc::CritScope lock(&send_crit_); | 393 rtc::CritScope lock(&send_crit_); |
| 394 return _mediaOpt.IsVideoSuspended(); | 394 return _mediaOpt.IsVideoSuspended(); |
| 395 } | 395 } |
| 396 } // namespace vcm | 396 } // namespace vcm |
| 397 } // namespace webrtc | 397 } // namespace webrtc |
| OLD | NEW |