| Index: webrtc/video/video_encoder.cc
|
| diff --git a/webrtc/video/video_encoder.cc b/webrtc/video/video_encoder.cc
|
| index 3e6ce634f8e9022442bab86e15250119e4639e35..d116a1ea6728c30391fceaaae931633c5eea0154 100644
|
| --- a/webrtc/video/video_encoder.cc
|
| +++ b/webrtc/video/video_encoder.cc
|
| @@ -50,34 +50,67 @@ VideoEncoder::EncoderType CodecToEncoderType(VideoCodecType codec_type) {
|
| VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
|
| VideoCodecType codec_type,
|
| webrtc::VideoEncoder* encoder)
|
| - : encoder_type_(CodecToEncoderType(codec_type)),
|
| + : rates_set_(false),
|
| + channel_parameters_set_(false),
|
| + encoder_type_(CodecToEncoderType(codec_type)),
|
| encoder_(encoder),
|
| - callback_(nullptr) {
|
| + callback_(nullptr) {}
|
| +
|
| +bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() {
|
| + RTC_CHECK(encoder_type_ != kUnsupportedCodec)
|
| + << "Encoder requesting fallback to codec not supported in software.";
|
| + fallback_encoder_.reset(VideoEncoder::Create(encoder_type_));
|
| + if (fallback_encoder_->InitEncode(&codec_settings_, number_of_cores_,
|
| + max_payload_size_) !=
|
| + WEBRTC_VIDEO_CODEC_OK) {
|
| + LOG(LS_ERROR) << "Failed to initialize software-encoder fallback.";
|
| + fallback_encoder_->Release();
|
| + fallback_encoder_.reset();
|
| + return false;
|
| + }
|
| + // Replay callback, rates, and channel parameters.
|
| + if (callback_)
|
| + fallback_encoder_->RegisterEncodeCompleteCallback(callback_);
|
| + if (rates_set_)
|
| + fallback_encoder_->SetRates(bitrate_, framerate_);
|
| + if (channel_parameters_set_)
|
| + fallback_encoder_->SetChannelParameters(packet_loss_, rtt_);
|
| +
|
| + // Since we're switching to the fallback encoder, Release the real encoder. It
|
| + // may be re-initialized via InitEncode later, and it will continue to get
|
| + // Set calls for rates and channel parameters in the meantime.
|
| + encoder_->Release();
|
| + return true;
|
| }
|
|
|
| int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
|
| const VideoCodec* codec_settings,
|
| int32_t number_of_cores,
|
| size_t max_payload_size) {
|
| + // Store settings, in case we need to dynamically switch to the fallback
|
| + // encoder after a failed Encode call.
|
| + codec_settings_ = *codec_settings;
|
| + number_of_cores_ = number_of_cores;
|
| + max_payload_size_ = max_payload_size;
|
| + // Clear stored rate/channel parameters.
|
| + rates_set_ = false;
|
| + channel_parameters_set_ = false;
|
| +
|
| int32_t ret =
|
| encoder_->InitEncode(codec_settings, number_of_cores, max_payload_size);
|
| if (ret == WEBRTC_VIDEO_CODEC_OK || encoder_type_ == kUnsupportedCodec) {
|
| + if (fallback_encoder_)
|
| + fallback_encoder_->Release();
|
| fallback_encoder_.reset();
|
| if (callback_)
|
| encoder_->RegisterEncodeCompleteCallback(callback_);
|
| return ret;
|
| }
|
| // Try to instantiate software codec.
|
| - fallback_encoder_.reset(VideoEncoder::Create(encoder_type_));
|
| - if (fallback_encoder_->InitEncode(codec_settings, number_of_cores,
|
| - max_payload_size) ==
|
| - WEBRTC_VIDEO_CODEC_OK) {
|
| - if (callback_)
|
| - fallback_encoder_->RegisterEncodeCompleteCallback(callback_);
|
| + if (InitFallbackEncoder()) {
|
| return WEBRTC_VIDEO_CODEC_OK;
|
| }
|
| - // Software encoder failed, reset and use original return code.
|
| - fallback_encoder_.reset();
|
| + // Software encoder failed, use original return code.
|
| return ret;
|
| }
|
|
|
| @@ -91,6 +124,9 @@ int32_t VideoEncoderSoftwareFallbackWrapper::RegisterEncodeCompleteCallback(
|
| }
|
|
|
| int32_t VideoEncoderSoftwareFallbackWrapper::Release() {
|
| + // If the fallback_encoder_ is non-null, it means it was created via
|
| + // InitFallbackEncoder which has Release()d encoder_, so we should only ever
|
| + // need to Release() whichever one is active.
|
| if (fallback_encoder_)
|
| return fallback_encoder_->Release();
|
| return encoder_->Release();
|
| @@ -102,12 +138,21 @@ int32_t VideoEncoderSoftwareFallbackWrapper::Encode(
|
| const std::vector<FrameType>* frame_types) {
|
| if (fallback_encoder_)
|
| return fallback_encoder_->Encode(frame, codec_specific_info, frame_types);
|
| - return encoder_->Encode(frame, codec_specific_info, frame_types);
|
| + int32_t ret = encoder_->Encode(frame, codec_specific_info, frame_types);
|
| + // If requested, try a software fallback.
|
| + if (ret == WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE && InitFallbackEncoder()) {
|
| + // Fallback was successful, so start using it with this frame.
|
| + return fallback_encoder_->Encode(frame, codec_specific_info, frame_types);
|
| + }
|
| + return ret;
|
| }
|
|
|
| int32_t VideoEncoderSoftwareFallbackWrapper::SetChannelParameters(
|
| uint32_t packet_loss,
|
| int64_t rtt) {
|
| + channel_parameters_set_ = true;
|
| + packet_loss_ = packet_loss;
|
| + rtt_ = rtt;
|
| int32_t ret = encoder_->SetChannelParameters(packet_loss, rtt);
|
| if (fallback_encoder_)
|
| return fallback_encoder_->SetChannelParameters(packet_loss, rtt);
|
| @@ -116,6 +161,9 @@ int32_t VideoEncoderSoftwareFallbackWrapper::SetChannelParameters(
|
|
|
| int32_t VideoEncoderSoftwareFallbackWrapper::SetRates(uint32_t bitrate,
|
| uint32_t framerate) {
|
| + rates_set_ = true;
|
| + bitrate_ = bitrate;
|
| + framerate_ = framerate;
|
| int32_t ret = encoder_->SetRates(bitrate, framerate);
|
| if (fallback_encoder_)
|
| return fallback_encoder_->SetRates(bitrate, framerate);
|
|
|