mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00
Use fallback encoder if primary can't be created
In case if primary encoder can't be instantiated (max number of instances has reached, for example), use fallback encoder. Bug: none Change-Id: I477bdeb7af4dcce50e36b1804ffc6ad2ab004dfd Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/234500 Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Xavier Lepaul <xalep@webrtc.org> Cr-Commit-Position: refs/heads/main@{#35161}
This commit is contained in:
parent
bcef6e1859
commit
9b2a7461f0
2 changed files with 83 additions and 8 deletions
|
@ -709,17 +709,40 @@ SimulcastEncoderAdapter::FetchOrCreateEncoderContext(
|
|||
encoder_context = std::move(*encoder_context_iter);
|
||||
cached_encoder_contexts_.erase(encoder_context_iter);
|
||||
} else {
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
std::unique_ptr<VideoEncoder> primary_encoder =
|
||||
primary_encoder_factory_->CreateVideoEncoder(video_format_);
|
||||
VideoEncoder::EncoderInfo primary_info = encoder->GetEncoderInfo();
|
||||
VideoEncoder::EncoderInfo fallback_info = primary_info;
|
||||
|
||||
std::unique_ptr<VideoEncoder> fallback_encoder;
|
||||
if (fallback_encoder_factory_ != nullptr) {
|
||||
std::unique_ptr<VideoEncoder> fallback_encoder =
|
||||
fallback_encoder =
|
||||
fallback_encoder_factory_->CreateVideoEncoder(video_format_);
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoEncoder> encoder;
|
||||
VideoEncoder::EncoderInfo primary_info;
|
||||
VideoEncoder::EncoderInfo fallback_info;
|
||||
|
||||
if (primary_encoder != nullptr) {
|
||||
primary_info = primary_encoder->GetEncoderInfo();
|
||||
fallback_info = primary_info;
|
||||
|
||||
if (fallback_encoder == nullptr) {
|
||||
encoder = std::move(primary_encoder);
|
||||
} else {
|
||||
encoder = CreateVideoEncoderSoftwareFallbackWrapper(
|
||||
std::move(fallback_encoder), std::move(primary_encoder),
|
||||
prefer_temporal_support);
|
||||
}
|
||||
} else if (fallback_encoder != nullptr) {
|
||||
RTC_LOG(LS_WARNING) << "Failed to create primary " << video_format_.name
|
||||
<< " encoder. Use fallback encoder.";
|
||||
fallback_info = fallback_encoder->GetEncoderInfo();
|
||||
encoder = CreateVideoEncoderSoftwareFallbackWrapper(
|
||||
std::move(fallback_encoder), std::move(encoder),
|
||||
prefer_temporal_support);
|
||||
primary_info = fallback_info;
|
||||
encoder = std::move(fallback_encoder);
|
||||
} else {
|
||||
RTC_LOG(LS_ERROR) << "Failed to create primary and fallback "
|
||||
<< video_format_.name << " encoders.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
encoder_context = std::make_unique<SimulcastEncoderAdapter::EncoderContext>(
|
||||
|
@ -829,7 +852,10 @@ VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const {
|
|||
// Create one encoder and query it.
|
||||
|
||||
std::unique_ptr<SimulcastEncoderAdapter::EncoderContext> encoder_context =
|
||||
FetchOrCreateEncoderContext(true);
|
||||
FetchOrCreateEncoderContext(/*is_lowest_quality_stream=*/true);
|
||||
if (encoder_context == nullptr) {
|
||||
return encoder_info;
|
||||
}
|
||||
|
||||
const VideoEncoder::EncoderInfo& primary_info =
|
||||
encoder_context->PrimaryInfo();
|
||||
|
|
|
@ -171,6 +171,9 @@ class MockVideoEncoderFactory : public VideoEncoderFactory {
|
|||
|
||||
const std::vector<MockVideoEncoder*>& encoders() const;
|
||||
void SetEncoderNames(const std::vector<const char*>& encoder_names);
|
||||
void set_create_video_encode_return_nullptr(bool return_nullptr) {
|
||||
create_video_encoder_return_nullptr_ = return_nullptr;
|
||||
}
|
||||
void set_init_encode_return_value(int32_t value);
|
||||
void set_requested_resolution_alignments(
|
||||
std::vector<int> requested_resolution_alignments) {
|
||||
|
@ -183,6 +186,7 @@ class MockVideoEncoderFactory : public VideoEncoderFactory {
|
|||
void DestroyVideoEncoder(VideoEncoder* encoder);
|
||||
|
||||
private:
|
||||
bool create_video_encoder_return_nullptr_ = false;
|
||||
int32_t init_encode_return_value_ = 0;
|
||||
std::vector<MockVideoEncoder*> encoders_;
|
||||
std::vector<const char*> encoder_names_;
|
||||
|
@ -346,6 +350,10 @@ std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
|
|||
|
||||
std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
|
||||
const SdpVideoFormat& format) {
|
||||
if (create_video_encoder_return_nullptr_) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto encoder = std::make_unique<::testing::NiceMock<MockVideoEncoder>>(this);
|
||||
encoder->set_init_encode_return_value(init_encode_return_value_);
|
||||
const char* encoder_name = encoder_names_.empty()
|
||||
|
@ -1711,5 +1719,46 @@ TEST_F(TestSimulcastEncoderAdapterFake,
|
|||
EXPECT_NE(helper_->factory()->encoders()[0], prev_encoder);
|
||||
}
|
||||
|
||||
TEST_F(TestSimulcastEncoderAdapterFake,
|
||||
UseFallbackEncoderIfCreatePrimaryEncoderFailed) {
|
||||
// Enable support for fallback encoder factory and re-setup.
|
||||
use_fallback_factory_ = true;
|
||||
SetUp();
|
||||
SimulcastTestFixtureImpl::DefaultSettings(
|
||||
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
||||
kVideoCodecVP8);
|
||||
codec_.numberOfSimulcastStreams = 1;
|
||||
helper_->factory()->SetEncoderNames({"primary"});
|
||||
helper_->fallback_factory()->SetEncoderNames({"fallback"});
|
||||
|
||||
// Emulate failure at creating of primary encoder and verify that SEA switches
|
||||
// to fallback encoder.
|
||||
helper_->factory()->set_create_video_encode_return_nullptr(true);
|
||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||
ASSERT_EQ(0u, helper_->factory()->encoders().size());
|
||||
ASSERT_EQ(1u, helper_->fallback_factory()->encoders().size());
|
||||
EXPECT_EQ("fallback", adapter_->GetEncoderInfo().implementation_name);
|
||||
}
|
||||
|
||||
TEST_F(TestSimulcastEncoderAdapterFake,
|
||||
InitEncodeReturnsErrorIfEncoderCannotBeCreated) {
|
||||
// Enable support for fallback encoder factory and re-setup.
|
||||
use_fallback_factory_ = true;
|
||||
SetUp();
|
||||
SimulcastTestFixtureImpl::DefaultSettings(
|
||||
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
||||
kVideoCodecVP8);
|
||||
codec_.numberOfSimulcastStreams = 1;
|
||||
helper_->factory()->SetEncoderNames({"primary"});
|
||||
helper_->fallback_factory()->SetEncoderNames({"fallback"});
|
||||
|
||||
// Emulate failure at creating of primary and fallback encoders and verify
|
||||
// that `InitEncode` returns an error.
|
||||
helper_->factory()->set_create_video_encode_return_nullptr(true);
|
||||
helper_->fallback_factory()->set_create_video_encode_return_nullptr(true);
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_MEMORY,
|
||||
adapter_->InitEncode(&codec_, kSettings));
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
|
Loading…
Reference in a new issue