Revert "Replace VideoEncoderFactory::QueryVideoEncoder with VideoEncoder::GetEncoderInfo"

This reverts commit cdc5eb0de179dcc866ef770ea303879c64466879.

Reason for revert: Causes wrong CPU adaptation to be used for some HW codecs since GetEncoderInfo() is polled before InitEncode().

Original change's description:
> Replace VideoEncoderFactory::QueryVideoEncoder with VideoEncoder::GetEncoderInfo
> 
> Make implementation of VideoEncoderFactory::QueryVideoEncoder optional
> until it is removed downstream and remove all implementations of it.
> 
> Bug: webrtc:10065
> Change-Id: Ibb1f9612234e536651ce53f05ee048a5d172a41f
> Reviewed-on: https://webrtc-review.googlesource.com/c/113065
> Commit-Queue: Mirta Dvornicic <mirtad@webrtc.org>
> Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> Reviewed-by: Per Kjellander <perkj@webrtc.org>
> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
> Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
> Reviewed-by: Erik Språng <sprang@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#25924}

TBR=brandtr@webrtc.org,sakal@webrtc.org,kthelgason@webrtc.org,sprang@webrtc.org,srte@webrtc.org,perkj@webrtc.org,mirtad@webrtc.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: webrtc:10065
Change-Id: Idaa452e1d8c1c58cdb4ec69b88fce9042589cc3c
Reviewed-on: https://webrtc-review.googlesource.com/c/113800
Reviewed-by: Mirta Dvornicic <mirtad@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Commit-Queue: Mirta Dvornicic <mirtad@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25943}
This commit is contained in:
Mirta Dvornicic 2018-12-10 09:47:34 +00:00 committed by Commit Bot
parent 6a8727bd2a
commit 1ec2a16121
26 changed files with 179 additions and 91 deletions

View File

@ -24,6 +24,8 @@ class MockVideoEncoderFactory : public webrtc::VideoEncoderFactory {
public:
MOCK_CONST_METHOD0(GetSupportedFormats,
std::vector<webrtc::SdpVideoFormat>());
MOCK_CONST_METHOD1(QueryVideoEncoder,
CodecInfo(const webrtc::SdpVideoFormat&));
// We need to proxy to a return type that is copyable.
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(

View File

@ -41,6 +41,14 @@ class FunctionVideoEncoderFactory final : public VideoEncoderFactory {
return {};
}
CodecInfo QueryVideoEncoder(
const SdpVideoFormat& /* format */) const override {
CodecInfo codec_info;
codec_info.is_hardware_accelerated = false;
codec_info.has_internal_source = false;
return codec_info;
}
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) override {
return create_(format);

View File

@ -27,7 +27,6 @@ rtc_source_set("video_codecs_api") {
"video_encoder.h",
"video_encoder_config.cc",
"video_encoder_config.h",
"video_encoder_factory.cc",
"video_encoder_factory.h",
"vp8_temporal_layers.h",
]

View File

@ -44,6 +44,17 @@ class BuiltinVideoEncoderFactory : public VideoEncoderFactory {
BuiltinVideoEncoderFactory()
: internal_encoder_factory_(new InternalEncoderFactory()) {}
VideoEncoderFactory::CodecInfo QueryVideoEncoder(
const SdpVideoFormat& format) const override {
// Format must be one of the internal formats.
RTC_DCHECK(IsFormatSupported(
internal_encoder_factory_->GetSupportedFormats(), format));
VideoEncoderFactory::CodecInfo info;
info.has_internal_source = false;
info.is_hardware_accelerated = false;
return info;
}
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) override {
// Try creating internal encoder.

View File

@ -1,26 +0,0 @@
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "api/video_codecs/video_encoder_factory.h"
// TODO(webrtc:10065) Remove once downstream projects have been updated.
namespace webrtc {
VideoEncoderFactory::CodecInfo::CodecInfo()
: is_hardware_accelerated(false), has_internal_source(false) {}
VideoEncoderFactory::CodecInfo::~CodecInfo() = default;
VideoEncoderFactory::CodecInfo VideoEncoderFactory::QueryVideoEncoder(
const SdpVideoFormat& format) const {
return CodecInfo();
}
} // namespace webrtc

View File

@ -25,9 +25,6 @@ class VideoEncoderFactory {
public:
// TODO(magjed): Try to get rid of this struct.
struct CodecInfo {
CodecInfo();
~CodecInfo();
// |is_hardware_accelerated| is true if the encoders created by this factory
// of the given codec will use hardware support.
bool is_hardware_accelerated;
@ -46,7 +43,7 @@ class VideoEncoderFactory {
// Returns information about how this format will be encoded. The specified
// format must be one of the supported formats by this factory.
// TODO(magjed): Try to get rid of this method.
virtual CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const;
virtual CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const = 0;
// Creates a VideoEncoder for the specified format.
virtual std::unique_ptr<VideoEncoder> CreateVideoEncoder(

View File

@ -60,6 +60,21 @@ class CricketToWebRtcEncoderFactory : public webrtc::VideoEncoderFactory {
std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory)
: external_encoder_factory_(std::move(external_encoder_factory)) {}
webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
const webrtc::SdpVideoFormat& format) const override {
CodecInfo info;
info.has_internal_source = false;
info.is_hardware_accelerated = false;
if (!external_encoder_factory_)
return info;
info.has_internal_source =
external_encoder_factory_->EncoderTypeHasInternalSource(
webrtc::PayloadStringToCodecType(format.name));
info.is_hardware_accelerated = true;
return info;
}
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
if (!external_encoder_factory_)
return std::vector<webrtc::SdpVideoFormat>();
@ -98,6 +113,22 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory {
: internal_encoder_factory_(new webrtc::InternalEncoderFactory()),
external_encoder_factory_(std::move(external_encoder_factory)) {}
webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
const webrtc::SdpVideoFormat& format) const override {
if (IsFormatSupported(external_encoder_factory_->GetSupportedFormats(),
format)) {
return external_encoder_factory_->QueryVideoEncoder(format);
}
// Format must be one of the internal formats.
RTC_DCHECK(IsFormatSupported(
internal_encoder_factory_->GetSupportedFormats(), format));
webrtc::VideoEncoderFactory::CodecInfo info;
info.has_internal_source = false;
info.is_hardware_accelerated = false;
return info;
}
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) override {
// Try creating internal encoder.

View File

@ -187,17 +187,10 @@ int FakeWebRtcVideoEncoder::GetNumEncodedFrames() {
return num_frames_encoded_;
}
webrtc::VideoEncoder::EncoderInfo FakeWebRtcVideoEncoder::GetEncoderInfo()
const {
EncoderInfo info;
info.is_hardware_accelerated = true;
info.has_internal_source = false;
return info;
}
// Video encoder factory.
FakeWebRtcVideoEncoderFactory::FakeWebRtcVideoEncoderFactory()
: num_created_encoders_(0),
encoders_have_internal_sources_(false),
vp8_factory_mode_(false) {}
std::vector<webrtc::SdpVideoFormat>
@ -237,6 +230,15 @@ FakeWebRtcVideoEncoderFactory::CreateVideoEncoder(
return encoder;
}
webrtc::VideoEncoderFactory::CodecInfo
FakeWebRtcVideoEncoderFactory::QueryVideoEncoder(
const webrtc::SdpVideoFormat& format) const {
webrtc::VideoEncoderFactory::CodecInfo info;
info.has_internal_source = encoders_have_internal_sources_;
info.is_hardware_accelerated = true;
return info;
}
bool FakeWebRtcVideoEncoderFactory::WaitForCreatedVideoEncoders(
int num_encoders) {
int64_t start_offset_ms = rtc::TimeMillis();
@ -256,6 +258,11 @@ void FakeWebRtcVideoEncoderFactory::EncoderDestroyed(
encoders_.end());
}
void FakeWebRtcVideoEncoderFactory::set_encoders_have_internal_sources(
bool internal_source) {
encoders_have_internal_sources_ = internal_source;
}
void FakeWebRtcVideoEncoderFactory::AddSupportedVideoCodec(
const webrtc::SdpVideoFormat& format) {
formats_.push_back(format);

View File

@ -96,7 +96,6 @@ class FakeWebRtcVideoEncoder : public webrtc::VideoEncoder {
int32_t Release() override;
int32_t SetRateAllocation(const webrtc::VideoBitrateAllocation& allocation,
uint32_t framerate) override;
webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const override;
bool WaitForInitEncode();
webrtc::VideoCodec GetCodecSettings();
@ -118,6 +117,8 @@ class FakeWebRtcVideoEncoderFactory : public webrtc::VideoEncoderFactory {
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override;
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) override;
CodecInfo QueryVideoEncoder(
const webrtc::SdpVideoFormat& format) const override;
bool WaitForCreatedVideoEncoders(int num_encoders);
void EncoderDestroyed(FakeWebRtcVideoEncoder* encoder);

View File

@ -34,6 +34,14 @@ std::vector<SdpVideoFormat> InternalEncoderFactory::GetSupportedFormats()
return supported_codecs;
}
VideoEncoderFactory::CodecInfo InternalEncoderFactory::QueryVideoEncoder(
const SdpVideoFormat& format) const {
CodecInfo info;
info.is_hardware_accelerated = false;
info.has_internal_source = false;
return info;
}
std::unique_ptr<VideoEncoder> InternalEncoderFactory::CreateVideoEncoder(
const SdpVideoFormat& format) {
if (absl::EqualsIgnoreCase(format.name, cricket::kVp8CodecName))

View File

@ -24,6 +24,8 @@ class InternalEncoderFactory : public VideoEncoderFactory {
public:
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) override;
};

View File

@ -57,6 +57,14 @@ std::vector<SdpVideoFormat> MultiplexEncoderFactory::GetSupportedFormats()
return formats;
}
VideoEncoderFactory::CodecInfo MultiplexEncoderFactory::QueryVideoEncoder(
const SdpVideoFormat& format) const {
if (!IsMultiplexCodec(cricket::VideoCodec(format)))
return factory_->QueryVideoEncoder(format);
return factory_->QueryVideoEncoder(
SdpVideoFormat(kMultiplexAssociatedCodecName));
}
std::unique_ptr<VideoEncoder> MultiplexEncoderFactory::CreateVideoEncoder(
const SdpVideoFormat& format) {
if (!IsMultiplexCodec(cricket::VideoCodec(format)))

View File

@ -49,6 +49,7 @@ class RTC_EXPORT MultiplexEncoderFactory : public VideoEncoderFactory {
bool supports_augmenting_data = false);
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) override;

View File

@ -159,6 +159,8 @@ class MockVideoEncoderFactory : public VideoEncoderFactory {
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) override;
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
const std::vector<MockVideoEncoder*>& encoders() const;
void SetEncoderNames(const std::vector<const char*>& encoder_names);
void set_init_encode_return_value(int32_t value);
@ -308,6 +310,11 @@ void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
}
}
VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
const SdpVideoFormat& format) const {
return CodecInfo();
}
const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
const {
return encoders_;

View File

@ -1090,7 +1090,12 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0));
// Mock encoder creation. |engine| take ownership of the encoder.
webrtc::VideoEncoderFactory::CodecInfo codec_info;
codec_info.is_hardware_accelerated = false;
codec_info.has_internal_source = false;
const webrtc::SdpVideoFormat format("VP8");
EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
.WillRepeatedly(testing::Return(codec_info));
FakeWebRtcVideoEncoder* const encoder = new FakeWebRtcVideoEncoder(nullptr);
rtc::Event encoder_created;
EXPECT_CALL(*encoder_factory, CreateVideoEncoderProxy(format))

View File

@ -50,5 +50,20 @@ std::vector<SdpVideoFormat> VideoEncoderFactoryWrapper::GetSupportedFormats()
return supported_formats_;
}
VideoEncoderFactory::CodecInfo VideoEncoderFactoryWrapper::QueryVideoEncoder(
const SdpVideoFormat& format) const {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedJavaLocalRef<jobject> j_codec_info =
SdpVideoFormatToVideoCodecInfo(jni, format);
ScopedJavaLocalRef<jobject> encoder = Java_VideoEncoderFactory_createEncoder(
jni, encoder_factory_, j_codec_info);
CodecInfo codec_info;
// Check if this is a wrapped native software encoder implementation.
codec_info.is_hardware_accelerated = IsHardwareVideoEncoder(jni, encoder);
codec_info.has_internal_source = false;
return codec_info;
}
} // namespace jni
} // namespace webrtc

View File

@ -35,6 +35,8 @@ class VideoEncoderFactoryWrapper : public VideoEncoderFactory {
// Returns a list of supported codecs in order of preference.
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
private:
const ScopedJavaGlobalRef<jobject> encoder_factory_;
std::vector<SdpVideoFormat> supported_formats_;

View File

@ -29,6 +29,7 @@ class ObjCVideoEncoderFactory : public VideoEncoderFactory {
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) override;
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
private:
id<RTCVideoEncoderFactory> encoder_factory_;

View File

@ -129,6 +129,19 @@ std::vector<SdpVideoFormat> ObjCVideoEncoderFactory::GetSupportedFormats() const
return supported_formats;
}
VideoEncoderFactory::CodecInfo ObjCVideoEncoderFactory::QueryVideoEncoder(
const SdpVideoFormat &format) const {
// TODO(andersc): This is a hack until we figure out how this should be done properly.
NSString *formatName = [NSString stringForStdString:format.name];
NSSet *wrappedSoftwareFormats =
[NSSet setWithObjects:kRTCVideoCodecVp8Name, kRTCVideoCodecVp9Name, nil];
CodecInfo codec_info;
codec_info.is_hardware_accelerated = ![wrappedSoftwareFormats containsObject:formatName];
codec_info.has_internal_source = false;
return codec_info;
}
std::unique_ptr<VideoEncoder> ObjCVideoEncoderFactory::CreateVideoEncoder(
const SdpVideoFormat &format) {
RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc] initWithNativeSdpVideoFormat:format];

View File

@ -54,8 +54,6 @@ FakeEncoder::FakeEncoder(Clock* clock)
max_target_bitrate_kbps_(-1),
pending_keyframe_(true),
counter_(0),
is_hardware_accelerated_(false),
has_internal_source_(false),
debt_bytes_(0) {
// Generate some arbitrary not-all-zero data
for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) {
@ -269,19 +267,9 @@ const char* FakeEncoder::kImplementationName = "fake_encoder";
VideoEncoder::EncoderInfo FakeEncoder::GetEncoderInfo() const {
EncoderInfo info;
info.implementation_name = kImplementationName;
info.is_hardware_accelerated = is_hardware_accelerated_;
info.has_internal_source = has_internal_source_;
return info;
}
void FakeEncoder::SetIsHardwareAccelerated(bool is_hardware_accelerated) {
is_hardware_accelerated_ = is_hardware_accelerated;
}
void FakeEncoder::SetHasInternalSource(bool has_internal_source) {
has_internal_source_ = has_internal_source;
}
int FakeEncoder::GetConfiguredInputFramerate() const {
rtc::CritScope cs(&crit_sect_);
return configured_input_framerate_;

View File

@ -55,9 +55,6 @@ class FakeEncoder : public VideoEncoder {
int GetConfiguredInputFramerate() const;
EncoderInfo GetEncoderInfo() const override;
void SetIsHardwareAccelerated(bool is_hardware_accelerated);
void SetHasInternalSource(bool has_internal_source);
static const char* kImplementationName;
protected:
@ -94,9 +91,6 @@ class FakeEncoder : public VideoEncoder {
uint32_t counter_ RTC_GUARDED_BY(crit_sect_);
rtc::CriticalSection crit_sect_;
bool is_hardware_accelerated_;
bool has_internal_source_;
uint8_t encoded_buffer_[100000];
bool used_layers_[kMaxSimulcastStreams];

View File

@ -26,8 +26,10 @@ namespace test {
// a proxy for the same encoder, typically an instance of FakeEncoder.
class VideoEncoderProxyFactory final : public VideoEncoderFactory {
public:
explicit VideoEncoderProxyFactory(VideoEncoder* encoder)
: encoder_(encoder) {}
explicit VideoEncoderProxyFactory(VideoEncoder* encoder) : encoder_(encoder) {
codec_info_.is_hardware_accelerated = false;
codec_info_.has_internal_source = false;
}
// Unused by tests.
std::vector<SdpVideoFormat> GetSupportedFormats() const override {
@ -35,11 +37,22 @@ class VideoEncoderProxyFactory final : public VideoEncoderFactory {
return {};
}
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override {
return codec_info_;
}
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) override {
return absl::make_unique<EncoderProxy>(encoder_);
}
void SetIsHardwareAccelerated(bool is_hardware_accelerated) {
codec_info_.is_hardware_accelerated = is_hardware_accelerated;
}
void SetHasInternalSource(bool has_internal_source) {
codec_info_.has_internal_source = has_internal_source;
}
private:
// Wrapper class, since CreateVideoEncoder needs to surrender
// ownership to the object it returns.
@ -75,6 +88,7 @@ class VideoEncoderProxyFactory final : public VideoEncoderFactory {
};
VideoEncoder* const encoder_;
CodecInfo codec_info_;
};
} // namespace test

View File

@ -2043,10 +2043,10 @@ TEST_P(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
bitrate_config);
StartBitrateObserver encoder;
test::VideoEncoderProxyFactory encoder_factory(&encoder);
// Since this test does not use a capturer, set |internal_source| = true.
// Encoder configuration is otherwise updated on the next video frame.
encoder.SetHasInternalSource(true);
test::VideoEncoderProxyFactory encoder_factory(&encoder);
encoder_factory.SetHasInternalSource(true);
GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
CreateVideoStreams();
@ -2125,8 +2125,8 @@ class StartStopBitrateObserver : public test::FakeEncoder {
TEST_P(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
test::NullTransport transport;
StartStopBitrateObserver encoder;
encoder.SetHasInternalSource(true);
test::VideoEncoderProxyFactory encoder_factory(&encoder);
encoder_factory.SetHasInternalSource(true);
test::FrameForwarder forwarder;
task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
@ -2168,8 +2168,8 @@ TEST_P(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
TEST_P(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
test::NullTransport transport;
StartStopBitrateObserver encoder;
encoder.SetHasInternalSource(true);
test::VideoEncoderProxyFactory encoder_factory(&encoder);
encoder_factory.SetHasInternalSource(true);
test::FrameForwarder forwarder;
task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {

View File

@ -363,6 +363,7 @@ VideoStreamEncoder::VideoStreamEncoder(
pre_encode_callback_(pre_encode_callback),
max_framerate_(-1),
pending_encoder_reconfiguration_(false),
pending_encoder_creation_(false),
crop_width_(0),
crop_height_(0),
encoder_start_bitrate_bps_(0),
@ -438,9 +439,8 @@ void VideoStreamEncoder::SetSource(
}
degradation_preference_ = degradation_preference;
if (encoder_) {
if (encoder_)
ConfigureQualityScaler();
}
if (!IsFramerateScalingEnabled(degradation_preference) &&
max_framerate_ != -1) {
@ -491,13 +491,8 @@ void VideoStreamEncoder::ConfigureEncoderOnTaskQueue(
RTC_LOG(LS_INFO) << "ConfigureEncoder requested.";
max_data_payload_length_ = max_data_payload_length;
if (!encoder_ || encoder_config_.video_format != config.video_format) {
pending_encoder_ =
settings_.encoder_factory->CreateVideoEncoder(config.video_format);
// TODO(nisse): What to do if creating the encoder fails? Crash,
// or just discard incoming frames?
RTC_CHECK(pending_encoder_);
}
pending_encoder_creation_ =
(!encoder_ || encoder_config_.video_format != config.video_format);
encoder_config_ = std::move(config);
pending_encoder_reconfiguration_ = true;
@ -507,14 +502,12 @@ void VideoStreamEncoder::ConfigureEncoderOnTaskQueue(
// The codec configuration depends on incoming video frame size.
if (last_frame_info_) {
ReconfigureEncoder();
} else {
VideoEncoder* encoder =
pending_encoder_ ? pending_encoder_.get() : encoder_.get();
if (encoder->GetEncoderInfo().has_internal_source) {
} else if (settings_.encoder_factory
->QueryVideoEncoder(encoder_config_.video_format)
.has_internal_source) {
last_frame_info_ = VideoFrameInfo(176, 144, false);
ReconfigureEncoder();
}
}
}
// TODO(bugs.webrtc.org/8807): Currently this always does a hard
@ -591,21 +584,28 @@ void VideoStreamEncoder::ReconfigureEncoder() {
source_proxy_->SetMaxFramerate(max_framerate);
// Keep the same encoder, as long as the video_format is unchanged.
if (pending_encoder_) {
if (pending_encoder_creation_) {
pending_encoder_creation_ = false;
if (encoder_) {
video_sender_.RegisterExternalEncoder(nullptr, false);
}
encoder_ = std::move(pending_encoder_);
const VideoEncoder::EncoderInfo& encoder_info = encoder_->GetEncoderInfo();
encoder_ = settings_.encoder_factory->CreateVideoEncoder(
encoder_config_.video_format);
// TODO(nisse): What to do if creating the encoder fails? Crash,
// or just discard incoming frames?
RTC_CHECK(encoder_);
const webrtc::VideoEncoderFactory::CodecInfo info =
settings_.encoder_factory->QueryVideoEncoder(
encoder_config_.video_format);
overuse_detector_->StopCheckForOveruse();
overuse_detector_->StartCheckForOveruse(
GetCpuOveruseOptions(settings_, encoder_info.is_hardware_accelerated),
this);
GetCpuOveruseOptions(settings_, info.is_hardware_accelerated), this);
video_sender_.RegisterExternalEncoder(encoder_.get(),
encoder_info.has_internal_source);
info.has_internal_source);
}
// RegisterSendCodec implies an unconditional call to
// encoder_->InitEncode().

View File

@ -202,9 +202,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
rtc::ThreadChecker thread_checker_;
VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(&encoder_queue_);
// Pending encoder object (e.g. because of a codec change).
std::unique_ptr<VideoEncoder> pending_encoder_ RTC_GUARDED_BY(&encoder_queue_)
RTC_PT_GUARDED_BY(&encoder_queue_);
std::unique_ptr<VideoEncoder> encoder_ RTC_GUARDED_BY(&encoder_queue_)
RTC_PT_GUARDED_BY(&encoder_queue_);
std::unique_ptr<VideoBitrateAllocator> rate_allocator_
@ -216,6 +213,9 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// Set when ConfigureEncoder has been called in order to lazy reconfigure the
// encoder on the next frame.
bool pending_encoder_reconfiguration_ RTC_GUARDED_BY(&encoder_queue_);
// Set when configuration must create a new encoder object, e.g.,
// because of a codec change.
bool pending_encoder_creation_ RTC_GUARDED_BY(&encoder_queue_);
absl::optional<VideoFrameInfo> last_frame_info_
RTC_GUARDED_BY(&encoder_queue_);
int crop_width_ RTC_GUARDED_BY(&encoder_queue_);

View File

@ -511,8 +511,8 @@ class VideoStreamEncoderTest : public ::testing::Test {
}
VideoEncoder::EncoderInfo GetEncoderInfo() const override {
EncoderInfo info;
rtc::CritScope lock(&local_crit_sect_);
EncoderInfo info = FakeEncoder::GetEncoderInfo();
if (quality_scaling_) {
info.scaling_settings =
VideoEncoder::ScalingSettings(1, 2, kMinPixelsPerFrame);
@ -3198,7 +3198,7 @@ TEST_F(VideoStreamEncoderTest,
CpuOveruseOptions hardware_options;
hardware_options.low_encode_usage_threshold_percent = 150;
hardware_options.high_encode_usage_threshold_percent = 200;
fake_encoder_.SetIsHardwareAccelerated(true);
encoder_factory_.SetIsHardwareAccelerated(true);
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
video_source_.IncomingCapturedFrame(