Inform VideoEncoder of negotiated capabilities

After this CL lands, an announcement will be made to
discuss-webrtc about the deprecation of one version
of InitEncode().

Bug: webrtc:10720
Change-Id: Ib992af0272bbb16ae16ef7e69491f365702d179e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/140884
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Elad Alon <eladalon@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28224}
This commit is contained in:
Elad Alon
2019-06-10 19:10:29 +02:00
committed by Commit Bot
parent a7d70ab0fe
commit 11dfff0878
59 changed files with 601 additions and 226 deletions

View File

@ -50,6 +50,11 @@ const int kDefaultMinPixelsPerFrame = 320 * 180;
const int kLowThreshold = 10;
const int kHighThreshold = 20;
const VideoEncoder::Capabilities kCapabilities(false);
const VideoEncoder::Settings kSettings(kCapabilities,
kNumCores,
kMaxPayloadSize);
VideoEncoder::EncoderInfo GetEncoderInfoWithTrustedRateController(
bool trusted_rate_controller) {
VideoEncoder::EncoderInfo info;
@ -89,9 +94,16 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
int32_t InitEncode(const VideoCodec* codec_settings,
int32_t number_of_cores,
size_t max_payload_size) override {
RTC_NOTREACHED();
return WEBRTC_VIDEO_CODEC_ERROR;
}
int32_t InitEncode(const VideoCodec* codec_settings,
const VideoEncoder::Settings& settings) override {
++init_encode_count_;
return init_encode_return_code_;
}
int32_t Encode(const VideoFrame& frame,
const std::vector<VideoFrameType>* frame_types) override {
++encode_count_;
@ -202,7 +214,7 @@ void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() {
fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize));
fallback_wrapper_->InitEncode(&codec_, kSettings));
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
@ -221,7 +233,7 @@ void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() {
codec_.height = kHeight;
codec_.VP8()->numberOfTemporalLayers = 1;
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
fallback_wrapper_->InitEncode(&codec_, 2, kMaxPayloadSize);
fallback_wrapper_->InitEncode(&codec_, kSettings);
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
EXPECT_EQ(1, fake_encoder_->init_encode_count_);
@ -238,7 +250,7 @@ void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() {
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) {
VideoCodec codec = {};
fallback_wrapper_->InitEncode(&codec, 2, kMaxPayloadSize);
fallback_wrapper_->InitEncode(&codec, kSettings);
EXPECT_EQ(1, fake_encoder_->init_encode_count_);
}
@ -324,7 +336,7 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) {
codec_.width = kWidth;
codec_.height = kHeight;
fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize);
fallback_wrapper_->InitEncode(&codec_, kSettings);
EncodeFrame();
CheckLastEncoderName("fake-encoder");
}
@ -375,8 +387,8 @@ class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest {
void InitEncode(int width, int height) {
codec_.width = width;
codec_.height = height;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->InitEncode(
&codec_, kNumCores, kMaxPayloadSize));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_->InitEncode(&codec_, kSettings));
SetRateAllocation(kBitrateKbps);
}
@ -590,6 +602,9 @@ TEST(SoftwareFallbackEncoderTest, HwRateControllerTrusted) {
std::unique_ptr<VideoEncoder>(hw_encoder));
EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
VideoCodec codec_ = {};
wrapper->InitEncode(&codec_, kSettings);
// Trigger fallback to software.
EXPECT_CALL(*hw_encoder, Encode)
.WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
@ -630,6 +645,9 @@ TEST(SoftwareFallbackEncoderTest, ReportsHardwareAccelerated) {
std::unique_ptr<VideoEncoder>(hw_encoder));
EXPECT_TRUE(wrapper->GetEncoderInfo().is_hardware_accelerated);
VideoCodec codec_ = {};
wrapper->InitEncode(&codec_, kSettings);
// Trigger fallback to software.
EXPECT_CALL(*hw_encoder, Encode)
.WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
@ -654,6 +672,9 @@ TEST(SoftwareFallbackEncoderTest, ReportsInternalSource) {
std::unique_ptr<VideoEncoder>(hw_encoder));
EXPECT_TRUE(wrapper->GetEncoderInfo().has_internal_source);
VideoCodec codec_ = {};
wrapper->InitEncode(&codec_, kSettings);
// Trigger fallback to software.
EXPECT_CALL(*hw_encoder, Encode)
.WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));

View File

@ -118,6 +118,14 @@ VideoEncoder::RateControlParameters::RateControlParameters(
VideoEncoder::RateControlParameters::~RateControlParameters() = default;
int VideoEncoder::InitEncode(const VideoCodec* codec_settings,
const VideoEncoder::Settings& settings) {
// TODO(bugs.webrtc.org/10720): After updating downstream projects and posting
// an announcement to discuss-webrtc, remove this.
return InitEncode(codec_settings, settings.number_of_cores,
settings.max_payload_size);
}
void VideoEncoder::OnPacketLossRateUpdate(float packet_loss_rate) {}
void VideoEncoder::OnRttUpdate(int64_t rtt_ms) {}

View File

@ -86,6 +86,7 @@ class RTC_EXPORT VideoEncoder {
int low;
int high;
};
// Quality scaling is enabled if thresholds are provided.
struct ScalingSettings {
private:
@ -237,6 +238,27 @@ class RTC_EXPORT VideoEncoder {
absl::optional<bool> last_received_decodable;
};
// Negotiated capabilities which the VideoEncoder may expect the other
// side to use.
struct Capabilities {
explicit Capabilities(bool loss_notification)
: loss_notification(loss_notification) {}
bool loss_notification;
};
struct Settings {
Settings(const Capabilities& capabilities,
int number_of_cores,
size_t max_payload_size)
: capabilities(capabilities),
number_of_cores(number_of_cores),
max_payload_size(max_payload_size) {}
Capabilities capabilities;
int number_of_cores;
size_t max_payload_size;
};
static VideoCodecVP8 GetDefaultVp8Settings();
static VideoCodecVP9 GetDefaultVp9Settings();
static VideoCodecH264 GetDefaultH264Settings();
@ -247,6 +269,8 @@ class RTC_EXPORT VideoEncoder {
//
// Input:
// - codec_settings : Codec settings
// - settings : Settings affecting the encoding itself.
// Input for deprecated version:
// - number_of_cores : Number of cores available for the encoder
// - max_payload_size : The maximum size each payload is allowed
// to have. Usually MTU - overhead.
@ -257,9 +281,15 @@ class RTC_EXPORT VideoEncoder {
// WEBRTC_VIDEO_CODEC_ERR_SIZE
// WEBRTC_VIDEO_CODEC_MEMORY
// WEBRTC_VIDEO_CODEC_ERROR
virtual int32_t InitEncode(const VideoCodec* codec_settings,
int32_t number_of_cores,
size_t max_payload_size) = 0;
// TODO(bugs.webrtc.org/10720): After updating downstream projects and posting
// an announcement to discuss-webrtc, remove the three-parameters variant
// and make the two-parameters variant pure-virtual.
/* RTC_DEPRECATED */ virtual int32_t InitEncode(
const VideoCodec* codec_settings,
int32_t number_of_cores,
size_t max_payload_size) = 0;
virtual int InitEncode(const VideoCodec* codec_settings,
const VideoEncoder::Settings& settings);
// Register an encode complete callback object.
//

View File

@ -21,6 +21,7 @@
#include "api/video/video_bitrate_allocation.h"
#include "api/video/video_frame.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
@ -81,6 +82,8 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
int32_t InitEncode(const VideoCodec* codec_settings,
int32_t number_of_cores,
size_t max_payload_size) override;
int32_t InitEncode(const VideoCodec* codec_settings,
const VideoEncoder::Settings& settings) override;
int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override;
@ -118,8 +121,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
// Settings used in the last InitEncode call and used if a dynamic fallback to
// software is required.
VideoCodec codec_settings_;
int32_t number_of_cores_;
size_t max_payload_size_;
absl::optional<VideoEncoder::Settings> encoder_settings_;
// The last rate control settings, if set.
absl::optional<RateControlParameters> rate_control_parameters_;
@ -142,9 +144,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
std::unique_ptr<webrtc::VideoEncoder> hw_encoder)
: number_of_cores_(0),
max_payload_size_(0),
channel_parameters_set_(false),
: channel_parameters_set_(false),
packet_loss_(0),
rtt_(0),
use_fallback_encoder_(false),
@ -165,8 +165,9 @@ VideoEncoderSoftwareFallbackWrapper::~VideoEncoderSoftwareFallbackWrapper() =
bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() {
RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding.";
const int ret = fallback_encoder_->InitEncode(
&codec_settings_, number_of_cores_, max_payload_size_);
RTC_DCHECK(encoder_settings_.has_value());
const int ret = fallback_encoder_->InitEncode(&codec_settings_,
encoder_settings_.value());
use_fallback_encoder_ = (ret == WEBRTC_VIDEO_CODEC_OK);
if (!use_fallback_encoder_) {
RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback.";
@ -190,11 +191,17 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
const VideoCodec* codec_settings,
int32_t number_of_cores,
size_t max_payload_size) {
RTC_NOTREACHED();
return WEBRTC_VIDEO_CODEC_ERROR;
}
int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
const VideoCodec* codec_settings,
const VideoEncoder::Settings& settings) {
// 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;
encoder_settings_ = settings;
// Clear stored rate/channel parameters.
rate_control_parameters_ = absl::nullopt;
ValidateSettingsForForcedFallback();
@ -209,8 +216,7 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
}
forced_fallback_.active_ = false;
int32_t ret =
encoder_->InitEncode(codec_settings, number_of_cores, max_payload_size);
int32_t ret = encoder_->InitEncode(codec_settings, settings);
if (ret == WEBRTC_VIDEO_CODEC_OK) {
if (use_fallback_encoder_) {
RTC_LOG(LS_WARNING)
@ -319,14 +325,17 @@ bool VideoEncoderSoftwareFallbackWrapper::TryReInitForcedFallbackEncoder() {
if (!IsForcedFallbackActive()) {
return false;
}
// Forced fallback active.
if (!forced_fallback_.IsValid(codec_settings_)) {
RTC_LOG(LS_INFO) << "Stop forced SW encoder fallback, max pixels exceeded.";
return false;
}
// Settings valid, reinitialize the forced fallback encoder.
if (fallback_encoder_->InitEncode(&codec_settings_, number_of_cores_,
max_payload_size_) !=
RTC_DCHECK(encoder_settings_.has_value());
if (fallback_encoder_->InitEncode(&codec_settings_,
encoder_settings_.value()) !=
WEBRTC_VIDEO_CODEC_OK) {
RTC_LOG(LS_ERROR) << "Failed to init forced SW encoder fallback.";
return false;