Update SimulcastEncoderAdapter merging of EncoderInfo
Determining the EncoderInfo meta data is now done during InitEncode().
This implementation assums that no dynamic wrappers are wrapped in this
simulcast encoder adapter. Ie, if supports_native_handle changes,
InitEncode() must be called again for it to be reported properly.
Bug: webrtc:9722
Change-Id: I7901effe11e89ac011659a4ea862ab2a42577eb5
Reviewed-on: https://webrtc-review.googlesource.com/c/109620
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25549}
diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc
index f2717b3..e4d0b0b 100644
--- a/media/engine/simulcast_encoder_adapter.cc
+++ b/media/engine/simulcast_encoder_adapter.cc
@@ -19,6 +19,7 @@
#include "api/video_codecs/video_encoder_factory.h"
#include "modules/video_coding/utility/simulcast_rate_allocator.h"
#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/field_trial.h"
#include "third_party/libyuv/include/libyuv/scale.h"
@@ -126,9 +127,9 @@
factory_(factory),
video_format_(format),
encoded_complete_callback_(nullptr),
- implementation_name_("SimulcastEncoderAdapter"),
experimental_boosted_screenshare_qp_(GetScreenshareBoostedQpValue()) {
RTC_DCHECK(factory_);
+ encoder_info_.implementation_name = "SimulcastEncoderAdapter";
// The adapter is typically created on the worker thread, but operated on
// the encoder task queue.
@@ -202,7 +203,8 @@
start_bitrates.push_back(stream_bitrate);
}
- std::string implementation_name;
+ encoder_info_.supports_native_handle = true;
+ encoder_info_.scaling_settings.thresholds = absl::nullopt;
// Create |number_of_streams| of encoder instances and init them.
for (int i = 0; i < number_of_streams; ++i) {
VideoCodec stream_codec;
@@ -211,6 +213,7 @@
if (!doing_simulcast) {
stream_codec = codec_;
stream_codec.numberOfSimulcastStreams = 1;
+
} else {
// Cap start bitrate to the min bitrate in order to avoid strange codec
// behavior. Since sending will be false, this should not matter.
@@ -253,18 +256,39 @@
stream_codec.width, stream_codec.height,
send_stream);
- if (i != 0) {
- implementation_name += ", ";
+ if (!doing_simulcast) {
+ // Without simulcast, just pass through the encoder info from the one
+ // active encoder.
+ encoder_info_ = streaminfos_[0].encoder->GetEncoderInfo();
+ } else {
+ const EncoderInfo encoder_impl_info =
+ streaminfos_[i].encoder->GetEncoderInfo();
+
+ if (i == 0) {
+ // Quality scaling not enabled for simulcast.
+ encoder_info_.scaling_settings = VideoEncoder::ScalingSettings::kOff;
+
+ // Encoder name indicates names of all sub-encoders.
+ encoder_info_.implementation_name = "SimulcastEncoderAdapter (";
+ encoder_info_.implementation_name +=
+ encoder_impl_info.implementation_name;
+
+ encoder_info_.supports_native_handle =
+ encoder_impl_info.supports_native_handle;
+ } else {
+ encoder_info_.implementation_name += ", ";
+ encoder_info_.implementation_name +=
+ encoder_impl_info.implementation_name;
+
+ // Native handle supported only if all encoders supports it.
+ encoder_info_.supports_native_handle &=
+ encoder_impl_info.supports_native_handle;
+ }
}
- implementation_name +=
- streaminfos_[i].encoder->GetEncoderInfo().implementation_name;
}
if (doing_simulcast) {
- implementation_name_ =
- "SimulcastEncoderAdapter (" + implementation_name + ")";
- } else {
- implementation_name_ = implementation_name;
+ encoder_info_.implementation_name += ")";
}
// To save memory, don't store encoders that we don't use.
@@ -508,23 +532,7 @@
}
VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const {
- EncoderInfo info;
-
- if (Initialized() && NumberOfStreams(codec_) > 1) {
- info = streaminfos_[0].encoder->GetEncoderInfo();
- }
-
- info.supports_native_handle = true;
- for (const auto& streaminfo : streaminfos_) {
- if (!streaminfo.encoder->GetEncoderInfo().supports_native_handle) {
- info.supports_native_handle = false;
- break;
- }
- }
-
- info.implementation_name = implementation_name_;
-
- return info;
+ return encoder_info_;
}
} // namespace webrtc
diff --git a/media/engine/simulcast_encoder_adapter.h b/media/engine/simulcast_encoder_adapter.h
index 6cb47ef..783c342 100644
--- a/media/engine/simulcast_encoder_adapter.h
+++ b/media/engine/simulcast_encoder_adapter.h
@@ -100,7 +100,7 @@
VideoCodec codec_;
std::vector<StreamInfo> streaminfos_;
EncodedImageCallback* encoded_complete_callback_;
- std::string implementation_name_;
+ EncoderInfo encoder_info_;
// Used for checking the single-threaded access of the encoder interface.
rtc::SequencedTaskChecker encoder_queue_;
diff --git a/media/engine/simulcast_encoder_adapter_unittest.cc b/media/engine/simulcast_encoder_adapter_unittest.cc
index d99b414..4854725 100644
--- a/media/engine/simulcast_encoder_adapter_unittest.cc
+++ b/media/engine/simulcast_encoder_adapter_unittest.cc
@@ -56,7 +56,6 @@
std::move(decoder_factory),
SdpVideoFormat(cricket::kVp8CodecName));
}
-
} // namespace
TEST(SimulcastEncoderAdapterSimulcastTest, TestKeyFrameRequestsOnAllStreams) {
@@ -177,7 +176,9 @@
class MockVideoEncoder : public VideoEncoder {
public:
explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
- : factory_(factory), callback_(nullptr) {}
+ : factory_(factory),
+ scaling_settings_(VideoEncoder::ScalingSettings::kOff),
+ callback_(nullptr) {}
// TODO(nisse): Valid overrides commented out, because the gmock
// methods don't use any override declarations, and we want to avoid
@@ -214,6 +215,7 @@
EncoderInfo info;
info.supports_native_handle = supports_native_handle_;
info.implementation_name = implementation_name_;
+ info.scaling_settings = scaling_settings_;
return info;
}
@@ -244,12 +246,17 @@
init_encode_return_value_ = value;
}
+ void set_scaling_settings(const VideoEncoder::ScalingSettings& settings) {
+ scaling_settings_ = settings;
+ }
+
VideoBitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
private:
MockVideoEncoderFactory* const factory_;
bool supports_native_handle_ = false;
std::string implementation_name_ = "unknown";
+ VideoEncoder::ScalingSettings scaling_settings_;
int32_t init_encode_return_value_ = 0;
VideoBitrateAllocation last_set_bitrate_;
@@ -722,8 +729,10 @@
adapter_->RegisterEncodeCompleteCallback(this);
ASSERT_EQ(1u, helper_->factory()->encoders().size());
helper_->factory()->encoders()[0]->set_supports_native_handle(true);
+ EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
helper_->factory()->encoders()[0]->set_supports_native_handle(false);
+ EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
}
@@ -796,6 +805,7 @@
EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
// Once all do, then the adapter claims support.
helper_->factory()->encoders()[0]->set_supports_native_handle(true);
+ EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
}
@@ -832,6 +842,7 @@
ASSERT_EQ(3u, helper_->factory()->encoders().size());
for (MockVideoEncoder* encoder : helper_->factory()->encoders())
encoder->set_supports_native_handle(true);
+ EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
rtc::scoped_refptr<VideoFrameBuffer> buffer(