Update VideoEncoderSoftwareFallbackWrapper to take VideoEncoder as arg
VideoEncoderSoftwareFallbackWrapper is updated to take a VideoEncoder as
argument instead relying on built-in SW codecs. The purpose is to make
VideoEncoderSoftwareFallbackWrapper more modular and not depend on
built-in SW encoders.
Bug: webrtc:7925
Change-Id: I99896f0751cfb77e01efd29c97d3bd07bdb2c7c0
Reviewed-on: https://webrtc-review.googlesource.com/22320
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20671}
diff --git a/media/engine/convert_legacy_video_factory.cc b/media/engine/convert_legacy_video_factory.cc
index d40f869..f3638ee 100644
--- a/media/engine/convert_legacy_video_factory.cc
+++ b/media/engine/convert_legacy_video_factory.cc
@@ -27,6 +27,7 @@
#include "media/engine/webrtcvideodecoderfactory.h"
#include "media/engine/webrtcvideoencoderfactory.h"
#include "rtc_base/checks.h"
+#include "rtc_base/ptr_util.h"
namespace cricket {
@@ -95,44 +96,39 @@
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) {
const VideoCodec codec(format);
+
+ // Try creating internal encoder.
+ std::unique_ptr<webrtc::VideoEncoder> internal_encoder;
+ if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(),
+ codec)) {
+ internal_encoder =
+ CodecNamesEq(format.name.c_str(), kVp8CodecName)
+ ? rtc::MakeUnique<webrtc::VP8EncoderSimulcastProxy>(
+ internal_encoder_factory_.get())
+ : std::unique_ptr<webrtc::VideoEncoder>(
+ internal_encoder_factory_->CreateVideoEncoder(codec));
+ }
+
// Try creating external encoder.
+ std::unique_ptr<webrtc::VideoEncoder> external_encoder;
if (external_encoder_factory_ != nullptr &&
FindMatchingCodec(external_encoder_factory_->supported_codecs(),
codec)) {
- std::unique_ptr<webrtc::VideoEncoder> external_encoder;
- if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) {
- // If it's a codec type we can simulcast, create a wrapped encoder.
- external_encoder = std::unique_ptr<webrtc::VideoEncoder>(
- new webrtc::SimulcastEncoderAdapter(
- external_encoder_factory_.get()));
- } else {
- external_encoder =
- CreateScopedVideoEncoder(external_encoder_factory_.get(), codec);
- }
- if (external_encoder) {
- return std::unique_ptr<webrtc::VideoEncoder>(
- new webrtc::VideoEncoderSoftwareFallbackWrapper(
- codec, std::move(external_encoder)));
- }
+ external_encoder = CodecNamesEq(format.name.c_str(), kVp8CodecName)
+ ? rtc::MakeUnique<webrtc::SimulcastEncoderAdapter>(
+ external_encoder_factory_.get())
+ : CreateScopedVideoEncoder(
+ external_encoder_factory_.get(), codec);
}
- // Try creating internal encoder.
- if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(),
- codec)) {
- if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) {
- return std::unique_ptr<webrtc::VideoEncoder>(
- new webrtc::VP8EncoderSimulcastProxy(
- internal_encoder_factory_.get()));
- } else {
- return std::unique_ptr<webrtc::VideoEncoder>(
- internal_encoder_factory_->CreateVideoEncoder(codec));
- }
+ if (internal_encoder && external_encoder) {
+ // Both internal SW encoder and external HW encoder available - create
+ // fallback encoder.
+ return rtc::MakeUnique<webrtc::VideoEncoderSoftwareFallbackWrapper>(
+ std::move(internal_encoder), std::move(external_encoder));
}
-
- // This shouldn't happen, we should not be trying to create something we
- // don't support.
- RTC_NOTREACHED();
- return nullptr;
+ return external_encoder ? std::move(external_encoder)
+ : std::move(internal_encoder);
}
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const {
diff --git a/media/engine/videoencodersoftwarefallbackwrapper.cc b/media/engine/videoencodersoftwarefallbackwrapper.cc
index 5e57c55..69254f5 100644
--- a/media/engine/videoencodersoftwarefallbackwrapper.cc
+++ b/media/engine/videoencodersoftwarefallbackwrapper.cc
@@ -25,11 +25,8 @@
const char kVp8ForceFallbackEncoderFieldTrial[] =
"WebRTC-VP8-Forced-Fallback-Encoder-v2";
-bool EnableForcedFallback(const cricket::VideoCodec& codec) {
- if (!webrtc::field_trial::IsEnabled(kVp8ForceFallbackEncoderFieldTrial))
- return false;
-
- return (PayloadStringToCodecType(codec.name) == kVideoCodecVP8);
+bool EnableForcedFallback() {
+ return field_trial::IsEnabled(kVp8ForceFallbackEncoderFieldTrial);
}
bool IsForcedFallbackPossible(const VideoCodec& codec_settings) {
@@ -68,8 +65,8 @@
} // namespace
VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
- const cricket::VideoCodec& codec,
- std::unique_ptr<webrtc::VideoEncoder> encoder)
+ std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
+ std::unique_ptr<webrtc::VideoEncoder> hw_encoder)
: number_of_cores_(0),
max_payload_size_(0),
rates_set_(false),
@@ -77,10 +74,11 @@
channel_parameters_set_(false),
packet_loss_(0),
rtt_(0),
- codec_(codec),
- encoder_(std::move(encoder)),
+ use_fallback_encoder_(false),
+ encoder_(std::move(hw_encoder)),
+ fallback_encoder_(std::move(sw_encoder)),
callback_(nullptr),
- forced_fallback_possible_(EnableForcedFallback(codec)) {
+ forced_fallback_possible_(EnableForcedFallback()) {
if (forced_fallback_possible_) {
GetForcedFallbackParamsFromFieldTrialGroup(
&forced_fallback_.min_pixels_, &forced_fallback_.max_pixels_,
@@ -91,20 +89,13 @@
bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() {
RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding.";
- MaybeModifyCodecForFallback();
- cricket::InternalEncoderFactory internal_factory;
- if (!FindMatchingCodec(internal_factory.supported_codecs(), codec_)) {
- RTC_LOG(LS_WARNING)
- << "Encoder requesting fallback to codec not supported in software.";
- return false;
- }
- fallback_encoder_.reset(internal_factory.CreateVideoEncoder(codec_));
- if (fallback_encoder_->InitEncode(&codec_settings_, number_of_cores_,
- max_payload_size_) !=
- WEBRTC_VIDEO_CODEC_OK) {
+
+ const int ret = fallback_encoder_->InitEncode(
+ &codec_settings_, number_of_cores_, max_payload_size_);
+ use_fallback_encoder_ = (ret == WEBRTC_VIDEO_CODEC_OK);
+ if (!use_fallback_encoder_) {
RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback.";
fallback_encoder_->Release();
- fallback_encoder_.reset();
return false;
}
// Replay callback, rates, and channel parameters.
@@ -148,13 +139,13 @@
int32_t ret =
encoder_->InitEncode(codec_settings, number_of_cores, max_payload_size);
- if (ret == WEBRTC_VIDEO_CODEC_OK || codec_.name.empty()) {
- if (fallback_encoder_) {
+ if (ret == WEBRTC_VIDEO_CODEC_OK) {
+ if (use_fallback_encoder_) {
RTC_LOG(LS_WARNING)
<< "InitEncode OK, no longer using the software fallback encoder.";
fallback_encoder_->Release();
+ use_fallback_encoder_ = false;
}
- fallback_encoder_.reset();
if (callback_)
encoder_->RegisterEncodeCompleteCallback(callback_);
return ret;
@@ -171,25 +162,21 @@
EncodedImageCallback* callback) {
callback_ = callback;
int32_t ret = encoder_->RegisterEncodeCompleteCallback(callback);
- if (fallback_encoder_)
+ if (use_fallback_encoder_)
return fallback_encoder_->RegisterEncodeCompleteCallback(callback);
return ret;
}
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();
+ return use_fallback_encoder_ ? fallback_encoder_->Release()
+ : encoder_->Release();
}
int32_t VideoEncoderSoftwareFallbackWrapper::Encode(
const VideoFrame& frame,
const CodecSpecificInfo* codec_specific_info,
const std::vector<FrameType>* frame_types) {
- if (fallback_encoder_)
+ if (use_fallback_encoder_)
return fallback_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.
@@ -215,7 +202,7 @@
packet_loss_ = packet_loss;
rtt_ = rtt;
int32_t ret = encoder_->SetChannelParameters(packet_loss, rtt);
- if (fallback_encoder_)
+ if (use_fallback_encoder_)
return fallback_encoder_->SetChannelParameters(packet_loss, rtt);
return ret;
}
@@ -227,15 +214,14 @@
bitrate_allocation_ = bitrate_allocation;
framerate_ = framerate;
int32_t ret = encoder_->SetRateAllocation(bitrate_allocation_, framerate);
- if (fallback_encoder_)
+ if (use_fallback_encoder_)
return fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate);
return ret;
}
bool VideoEncoderSoftwareFallbackWrapper::SupportsNativeHandle() const {
- if (fallback_encoder_)
- return fallback_encoder_->SupportsNativeHandle();
- return encoder_->SupportsNativeHandle();
+ return use_fallback_encoder_ ? fallback_encoder_->SupportsNativeHandle()
+ : encoder_->SupportsNativeHandle();
}
VideoEncoder::ScalingSettings
@@ -258,19 +244,18 @@
return encoder_->GetScalingSettings();
}
-const char *VideoEncoderSoftwareFallbackWrapper::ImplementationName() const {
- if (fallback_encoder_)
- return fallback_encoder_->ImplementationName();
- return encoder_->ImplementationName();
+const char* VideoEncoderSoftwareFallbackWrapper::ImplementationName() const {
+ return use_fallback_encoder_ ? fallback_encoder_->ImplementationName()
+ : encoder_->ImplementationName();
}
bool VideoEncoderSoftwareFallbackWrapper::IsForcedFallbackActive() const {
- return (forced_fallback_possible_ && fallback_encoder_ &&
+ return (forced_fallback_possible_ && use_fallback_encoder_ &&
forced_fallback_.active_);
}
bool VideoEncoderSoftwareFallbackWrapper::TryInitForcedFallbackEncoder() {
- if (!forced_fallback_possible_ || fallback_encoder_) {
+ if (!forced_fallback_possible_ || use_fallback_encoder_) {
return false;
}
// Fallback not active.
@@ -313,20 +298,11 @@
if (!IsForcedFallbackPossible(codec_settings_)) {
if (IsForcedFallbackActive()) {
fallback_encoder_->Release();
- fallback_encoder_.reset();
+ use_fallback_encoder_ = false;
}
RTC_LOG(LS_INFO) << "Disable forced_fallback_possible_ due to settings.";
forced_fallback_possible_ = false;
}
}
-void VideoEncoderSoftwareFallbackWrapper::MaybeModifyCodecForFallback() {
- // We have a specific case for H264 ConstrainedBaseline because that is the
- // only supported profile in Sw fallback.
- if (!cricket::CodecNamesEq(codec_.name.c_str(), cricket::kH264CodecName))
- return;
- codec_.SetParam(cricket::kH264FmtpProfileLevelId,
- cricket::kH264ProfileLevelConstrainedBaseline);
-}
-
} // namespace webrtc
diff --git a/media/engine/videoencodersoftwarefallbackwrapper.h b/media/engine/videoencodersoftwarefallbackwrapper.h
index 6322982..a9a349c 100644
--- a/media/engine/videoencodersoftwarefallbackwrapper.h
+++ b/media/engine/videoencodersoftwarefallbackwrapper.h
@@ -26,8 +26,8 @@
class VideoEncoderSoftwareFallbackWrapper : public VideoEncoder {
public:
VideoEncoderSoftwareFallbackWrapper(
- const cricket::VideoCodec& codec,
- std::unique_ptr<webrtc::VideoEncoder> encoder);
+ std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
+ std::unique_ptr<webrtc::VideoEncoder> hw_encoder);
int32_t InitEncode(const VideoCodec* codec_settings,
int32_t number_of_cores,
@@ -87,10 +87,10 @@
uint32_t packet_loss_;
int64_t rtt_;
- cricket::VideoCodec codec_;
- std::unique_ptr<webrtc::VideoEncoder> encoder_;
+ bool use_fallback_encoder_;
+ const std::unique_ptr<webrtc::VideoEncoder> encoder_;
- std::unique_ptr<webrtc::VideoEncoder> fallback_encoder_;
+ const std::unique_ptr<webrtc::VideoEncoder> fallback_encoder_;
EncodedImageCallback* callback_;
bool forced_fallback_possible_;
diff --git a/media/engine/videoencodersoftwarefallbackwrapper_unittest.cc b/media/engine/videoencodersoftwarefallbackwrapper_unittest.cc
index 1ec325d..e39b02f 100644
--- a/media/engine/videoencodersoftwarefallbackwrapper_unittest.cc
+++ b/media/engine/videoencodersoftwarefallbackwrapper_unittest.cc
@@ -13,6 +13,7 @@
#include <utility>
#include "api/video/i420_buffer.h"
+#include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/codecs/vp8/simulcast_rate_allocator.h"
#include "modules/video_coding/codecs/vp8/temporal_layers.h"
#include "modules/video_coding/include/video_codec_interface.h"
@@ -42,7 +43,7 @@
const std::string& field_trials)
: override_field_trials_(field_trials),
fake_encoder_(new CountingFakeEncoder()),
- fallback_wrapper_(cricket::VideoCodec("VP8"),
+ fallback_wrapper_(std::unique_ptr<VideoEncoder>(VP8Encoder::Create()),
std::unique_ptr<VideoEncoder>(fake_encoder_)) {}
class CountingFakeEncoder : public VideoEncoder {
diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc
index 34ec2a1..dc77605 100644
--- a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc
+++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc
@@ -382,7 +382,9 @@
if (config_.sw_fallback_encoder) {
encoder_ = rtc::MakeUnique<VideoEncoderSoftwareFallbackWrapper>(
- codec, std::move(encoder_));
+ std::unique_ptr<VideoEncoder>(
+ cricket::InternalEncoderFactory().CreateVideoEncoder(codec)),
+ std::move(encoder_));
}
if (config_.sw_fallback_decoder) {
decoder_ = rtc::MakeUnique<VideoDecoderSoftwareFallbackWrapper>(