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:
@ -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));
|
||||
|
||||
@ -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) {}
|
||||
|
||||
@ -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.
|
||||
//
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user