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}
This commit is contained in:
Erik Språng 2018-11-07 14:53:32 +01:00 committed by Commit Bot
parent e6a2d94eca
commit 75de46a966
3 changed files with 49 additions and 30 deletions

View File

@ -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 @@ SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory,
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 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
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 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
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 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
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 @@ void SimulcastEncoderAdapter::DestroyStoredEncoders() {
}
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

View File

@ -100,7 +100,7 @@ class SimulcastEncoderAdapter : public VideoEncoder {
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_;

View File

@ -56,7 +56,6 @@ std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
std::move(decoder_factory),
SdpVideoFormat(cricket::kVp8CodecName));
}
} // namespace
TEST(SimulcastEncoderAdapterSimulcastTest, TestKeyFrameRequestsOnAllStreams) {
@ -177,7 +176,9 @@ class MockVideoEncoderFactory : public VideoEncoderFactory {
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 @@ class MockVideoEncoder : public VideoEncoder {
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 @@ class MockVideoEncoder : public VideoEncoder {
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 @@ TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
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 @@ TEST_F(TestSimulcastEncoderAdapterFake,
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 @@ TEST_F(TestSimulcastEncoderAdapterFake,
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(