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}
This commit is contained in:

committed by
Commit Bot

parent
d4f01c1e87
commit
ee92d626bd
@ -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 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory {
|
||||
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 {
|
||||
|
@ -25,11 +25,8 @@ namespace {
|
||||
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 @@ void GetForcedFallbackParamsFromFieldTrialGroup(int* param_min_pixels,
|
||||
} // 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 @@ VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
|
||||
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 @@ VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
|
||||
|
||||
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 VideoEncoderSoftwareFallbackWrapper::InitEncode(
|
||||
|
||||
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 @@ int32_t VideoEncoderSoftwareFallbackWrapper::RegisterEncodeCompleteCallback(
|
||||
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 @@ int32_t VideoEncoderSoftwareFallbackWrapper::SetChannelParameters(
|
||||
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 @@ int32_t VideoEncoderSoftwareFallbackWrapper::SetRateAllocation(
|
||||
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 @@ VideoEncoderSoftwareFallbackWrapper::GetScalingSettings() const {
|
||||
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 @@ void VideoEncoderSoftwareFallbackWrapper::ValidateSettingsForForcedFallback() {
|
||||
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
|
||||
|
@ -26,8 +26,8 @@ namespace webrtc {
|
||||
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 @@ class VideoEncoderSoftwareFallbackWrapper : public VideoEncoder {
|
||||
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_;
|
||||
|
@ -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 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
|
||||
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 {
|
||||
|
@ -382,7 +382,9 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
|
||||
|
||||
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>(
|
||||
|
Reference in New Issue
Block a user