Move encoder metadata into EncoderInfo struct.

This deprecates the following methods in VideoEncoder:
  virtual ScalingSettings GetScalingSettings() const;
  virtual bool SupportsNativeHandle() const;
  virtual const char* ImplementationName() const;

Though they are not marked RTC_DEPRECATED since we still want to call
them from within the default GetEncoderInfo() until downstream
projects have been updated.

Furthmore, implementation name is changed from const char* to
std:string, which prevents some lifetime issues with dynamic encoder
names, and CodecSpecificInfo.codec_name is removed in favor of getting
the implementation name via GetEncoderInfo().

This CL removes calls to these deprecated methods, follow-ups will also
remove implementations of the methods and replace them with new
GetEncoderInfo() substitutions.

Bug: webrtc:9890
Change-Id: I6fd6e531480c0b952f53dbd5105e0b0adc3e3b0c
Reviewed-on: https://webrtc-review.googlesource.com/c/106905
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25351}
This commit is contained in:
Erik Språng 2018-10-24 11:32:39 +02:00 committed by Commit Bot
parent 2d3a1fb950
commit e2fd86a79c
22 changed files with 171 additions and 102 deletions

View File

@ -11,6 +11,7 @@
#ifndef API_VIDEO_VIDEO_STREAM_ENCODER_OBSERVER_H_
#define API_VIDEO_VIDEO_STREAM_ENCODER_OBSERVER_H_
#include <string>
#include <vector>
#include "absl/types/optional.h"
@ -68,6 +69,9 @@ class VideoStreamEncoderObserver : public CpuOveruseMetricsObserver {
virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_info) = 0;
virtual void OnEncoderImplementationChanged(
const std::string& implementation_name) = 0;
virtual void OnFrameDropped(DropReason reason) = 0;
// Used to indicate change in content type, which may require a change in

View File

@ -61,9 +61,7 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
++encode_count_;
if (encode_complete_callback_ &&
encode_return_code_ == WEBRTC_VIDEO_CODEC_OK) {
CodecSpecificInfo info;
info.codec_name = ImplementationName();
encode_complete_callback_->OnEncodedImage(EncodedImage(), &info,
encode_complete_callback_->OnEncodedImage(EncodedImage(), nullptr,
nullptr);
}
return encode_return_code_;
@ -91,15 +89,10 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
return WEBRTC_VIDEO_CODEC_OK;
}
bool SupportsNativeHandle() const override {
EncoderInfo GetEncoderInfo() const override {
++supports_native_handle_count_;
return supports_native_handle_;
}
const char* ImplementationName() const override { return "fake-encoder"; }
VideoEncoder::ScalingSettings GetScalingSettings() const override {
return VideoEncoder::ScalingSettings(kLowThreshold, kHighThreshold);
return EncoderInfo(ScalingSettings(kLowThreshold, kHighThreshold),
supports_native_handle_, "fake-encoder");
}
int init_encode_count_ = 0;
@ -121,11 +114,9 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) override {
++callback_count_;
last_codec_name_ = codec_specific_info->codec_name;
return Result(Result::OK, callback_count_);
}
int callback_count_ = 0;
std::string last_codec_name_;
};
void UtilizeFallbackEncoder();
@ -133,7 +124,8 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
void EncodeFrame();
void EncodeFrame(int expected_ret);
void CheckLastEncoderName(const char* expected_name) {
EXPECT_STREQ(expected_name, callback_.last_codec_name_.c_str());
EXPECT_EQ(expected_name,
fallback_wrapper_->GetEncoderInfo().implementation_name);
}
test::ScopedFieldTrials override_field_trials_;
@ -290,15 +282,19 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
SupportsNativeHandleForwardedWithoutFallback) {
fallback_wrapper_->SupportsNativeHandle();
fallback_wrapper_->GetEncoderInfo();
EXPECT_EQ(1, fake_encoder_->supports_native_handle_count_);
}
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
SupportsNativeHandleNotForwardedDuringFallback) {
// Fake encoder signals support for native handle, default (libvpx) does not.
fake_encoder_->supports_native_handle_ = true;
EXPECT_TRUE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
UtilizeFallbackEncoder();
fallback_wrapper_->SupportsNativeHandle();
EXPECT_EQ(0, fake_encoder_->supports_native_handle_count_);
EXPECT_FALSE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
// Both times, both encoders are queried.
EXPECT_EQ(2, fake_encoder_->supports_native_handle_count_);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
}
@ -488,7 +484,7 @@ TEST_F(ForcedFallbackTestDisabled, GetScaleSettings) {
EncodeFrameAndVerifyLastName("fake-encoder");
// Default min pixels per frame should be used.
const auto settings = fallback_wrapper_->GetScalingSettings();
const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
EXPECT_TRUE(settings.thresholds.has_value());
EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame);
}
@ -499,7 +495,7 @@ TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithNoFallback) {
EncodeFrameAndVerifyLastName("fake-encoder");
// Configured min pixels per frame should be used.
const auto settings = fallback_wrapper_->GetScalingSettings();
const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
ASSERT_TRUE(settings.thresholds);
EXPECT_EQ(kLowThreshold, settings.thresholds->low);
@ -512,7 +508,7 @@ TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithFallback) {
EncodeFrameAndVerifyLastName("libvpx");
// Configured min pixels per frame should be used.
const auto settings = fallback_wrapper_->GetScalingSettings();
const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
EXPECT_TRUE(settings.thresholds.has_value());
EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
}
@ -524,7 +520,7 @@ TEST_F(ForcedFallbackTestEnabled, ScalingDisabledIfResizeOff) {
EncodeFrameAndVerifyLastName("libvpx");
// Should be disabled for automatic resize off.
const auto settings = fallback_wrapper_->GetScalingSettings();
const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
EXPECT_FALSE(settings.thresholds.has_value());
}

View File

@ -83,6 +83,20 @@ VideoEncoder::ScalingSettings::~ScalingSettings() {}
constexpr VideoEncoder::ScalingSettings::KOff
VideoEncoder::ScalingSettings::kOff;
VideoEncoder::EncoderInfo::EncoderInfo()
: scaling_settings(VideoEncoder::ScalingSettings::kOff),
supports_native_handle(false),
implementation_name("unknown") {}
VideoEncoder::EncoderInfo::EncoderInfo(const ScalingSettings& scaling_settings,
bool supports_native_handle,
const std::string& implementation_name)
: scaling_settings(scaling_settings),
supports_native_handle(supports_native_handle),
implementation_name(implementation_name) {}
VideoEncoder::EncoderInfo::~EncoderInfo() = default;
int32_t VideoEncoder::SetRates(uint32_t bitrate, uint32_t framerate) {
RTC_NOTREACHED() << "SetRate(uint32_t, uint32_t) is deprecated.";
return -1;
@ -105,4 +119,9 @@ bool VideoEncoder::SupportsNativeHandle() const {
const char* VideoEncoder::ImplementationName() const {
return "unknown";
}
VideoEncoder::EncoderInfo VideoEncoder::GetEncoderInfo() const {
return EncoderInfo(GetScalingSettings(), SupportsNativeHandle(),
ImplementationName());
}
} // namespace webrtc

View File

@ -103,13 +103,13 @@ class RTC_EXPORT VideoEncoder {
ScalingSettings(KOff); // NOLINT(runtime/explicit)
~ScalingSettings();
const absl::optional<QpThresholds> thresholds;
absl::optional<QpThresholds> thresholds;
// We will never ask for a resolution lower than this.
// TODO(kthelgason): Lower this limit when better testing
// on MediaCodec and fallback implementations are in place.
// See https://bugs.chromium.org/p/webrtc/issues/detail?id=7206
const int min_pixels_per_frame = 320 * 180;
int min_pixels_per_frame = 320 * 180;
private:
// Private constructor; to get an object without thresholds, use
@ -117,6 +117,28 @@ class RTC_EXPORT VideoEncoder {
ScalingSettings();
};
// Struct containing metadata about the encoder implementing this interface.
struct EncoderInfo {
EncoderInfo();
EncoderInfo(const ScalingSettings& scaling_settings,
bool supports_native_handle,
const std::string& implementation_name);
// EncoderInfo(const EncoderInfo& rhs);
// EncoderInfo& operator=(const EncoderInfo& rhs);
~EncoderInfo();
// Any encoder implementation wishing to use the WebRTC provided
// quality scaler must populate this field.
ScalingSettings scaling_settings;
// If true, encoder supports working with a native handle (e.g. texture
// handle for hw codecs) rather than requiring a raw I420 buffer.
bool supports_native_handle;
// The name of this particular encoder implementation, e.g. "libvpx".
std::string implementation_name;
};
static VideoCodecVP8 GetDefaultVp8Settings();
static VideoCodecVP9 GetDefaultVp9Settings();
static VideoCodecH264 GetDefaultH264Settings();
@ -197,12 +219,13 @@ class RTC_EXPORT VideoEncoder {
virtual int32_t SetRateAllocation(const VideoBitrateAllocation& allocation,
uint32_t framerate);
// Any encoder implementation wishing to use the WebRTC provided
// quality scaler must implement this method.
// GetScalingSettings(), SupportsNativeHandle(), ImplementationName() are
// deprecated, use GetEncoderInfo() instead.
virtual ScalingSettings GetScalingSettings() const;
virtual bool SupportsNativeHandle() const;
virtual const char* ImplementationName() const;
virtual EncoderInfo GetEncoderInfo() const;
};
} // namespace webrtc
#endif // API_VIDEO_CODECS_VIDEO_ENCODER_H_

View File

@ -90,9 +90,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override;
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
uint32_t framerate) override;
bool SupportsNativeHandle() const override;
ScalingSettings GetScalingSettings() const override;
const char* ImplementationName() const override;
EncoderInfo GetEncoderInfo() const override;
private:
bool InitFallbackEncoder();
@ -162,7 +160,7 @@ VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
if (forced_fallback_possible_) {
GetForcedFallbackParamsFromFieldTrialGroup(
&forced_fallback_.min_pixels_, &forced_fallback_.max_pixels_,
encoder_->GetScalingSettings().min_pixels_per_frame -
encoder_->GetEncoderInfo().scaling_settings.min_pixels_per_frame -
1); // No HW below.
}
}
@ -294,29 +292,29 @@ int32_t VideoEncoderSoftwareFallbackWrapper::SetRateAllocation(
return ret;
}
bool VideoEncoderSoftwareFallbackWrapper::SupportsNativeHandle() const {
return use_fallback_encoder_ ? fallback_encoder_->SupportsNativeHandle()
: encoder_->SupportsNativeHandle();
}
VideoEncoder::EncoderInfo VideoEncoderSoftwareFallbackWrapper::GetEncoderInfo()
const {
EncoderInfo fallback_encoder_info = fallback_encoder_->GetEncoderInfo();
EncoderInfo default_encoder_info = encoder_->GetEncoderInfo();
EncoderInfo info =
use_fallback_encoder_ ? fallback_encoder_info : default_encoder_info;
VideoEncoder::ScalingSettings
VideoEncoderSoftwareFallbackWrapper::GetScalingSettings() const {
if (forced_fallback_possible_) {
const auto settings = forced_fallback_.active_
? fallback_encoder_->GetScalingSettings()
: encoder_->GetScalingSettings();
return settings.thresholds
? VideoEncoder::ScalingSettings(settings.thresholds->low,
settings.thresholds->high,
forced_fallback_.min_pixels_)
: VideoEncoder::ScalingSettings::kOff;
? fallback_encoder_info.scaling_settings
: default_encoder_info.scaling_settings;
info.scaling_settings =
settings.thresholds
? VideoEncoder::ScalingSettings(settings.thresholds->low,
settings.thresholds->high,
forced_fallback_.min_pixels_)
: VideoEncoder::ScalingSettings::kOff;
} else {
info.scaling_settings = default_encoder_info.scaling_settings;
}
return encoder_->GetScalingSettings();
}
const char* VideoEncoderSoftwareFallbackWrapper::ImplementationName() const {
return use_fallback_encoder_ ? fallback_encoder_->ImplementationName()
: encoder_->ImplementationName();
return info;
}
bool VideoEncoderSoftwareFallbackWrapper::IsForcedFallbackActive() const {

View File

@ -256,7 +256,8 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
if (i != 0) {
implementation_name += ", ";
}
implementation_name += streaminfos_[i].encoder->ImplementationName();
implementation_name +=
streaminfos_[i].encoder->GetEncoderInfo().implementation_name;
}
if (doing_simulcast) {
@ -451,7 +452,6 @@ EncodedImageCallback::Result SimulcastEncoderAdapter::OnEncodedImage(
const RTPFragmentationHeader* fragmentation) {
EncodedImage stream_image(encodedImage);
CodecSpecificInfo stream_codec_specific = *codecSpecificInfo;
stream_codec_specific.codec_name = implementation_name_.c_str();
stream_image.SetSpatialIndex(stream_idx);
@ -519,7 +519,6 @@ void SimulcastEncoderAdapter::DestroyStoredEncoders() {
bool SimulcastEncoderAdapter::SupportsNativeHandle() const {
RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_);
// We should not be calling this method before streaminfos_ are configured.
RTC_DCHECK(!streaminfos_.empty());
for (const auto& streaminfo : streaminfos_) {
if (!streaminfo.encoder->SupportsNativeHandle()) {
return false;

View File

@ -735,9 +735,9 @@ TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
adapter_->RegisterEncodeCompleteCallback(this);
ASSERT_EQ(1u, helper_->factory()->encoders().size());
helper_->factory()->encoders()[0]->set_supports_native_handle(true);
EXPECT_TRUE(adapter_->SupportsNativeHandle());
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
helper_->factory()->encoders()[0]->set_supports_native_handle(false);
EXPECT_FALSE(adapter_->SupportsNativeHandle());
EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
}
TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
@ -770,7 +770,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
}
TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
EXPECT_STREQ("SimulcastEncoderAdapter", adapter_->ImplementationName());
EXPECT_EQ("SimulcastEncoderAdapter",
adapter_->GetEncoderInfo().implementation_name);
SimulcastTestFixtureImpl::DefaultSettings(
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
kVideoCodecVP8);
@ -780,8 +781,8 @@ TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
encoder_names.push_back("codec3");
helper_->factory()->SetEncoderNames(encoder_names);
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
EXPECT_STREQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
adapter_->ImplementationName());
EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
adapter_->GetEncoderInfo().implementation_name);
// Single streams should not expose "SimulcastEncoderAdapter" in name.
EXPECT_EQ(0, adapter_->Release());
@ -789,7 +790,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
adapter_->RegisterEncodeCompleteCallback(this);
ASSERT_EQ(1u, helper_->factory()->encoders().size());
EXPECT_STREQ("codec1", adapter_->ImplementationName());
EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
}
TEST_F(TestSimulcastEncoderAdapterFake,
@ -805,10 +806,10 @@ TEST_F(TestSimulcastEncoderAdapterFake,
encoder->set_supports_native_handle(true);
// If one encoder doesn't support it, then overall support is disabled.
helper_->factory()->encoders()[0]->set_supports_native_handle(false);
EXPECT_FALSE(adapter_->SupportsNativeHandle());
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_TRUE(adapter_->SupportsNativeHandle());
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
}
// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
@ -844,7 +845,7 @@ TEST_F(TestSimulcastEncoderAdapterFake,
ASSERT_EQ(3u, helper_->factory()->encoders().size());
for (MockVideoEncoder* encoder : helper_->factory()->encoders())
encoder->set_supports_native_handle(true);
EXPECT_TRUE(adapter_->SupportsNativeHandle());
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
rtc::scoped_refptr<VideoFrameBuffer> buffer(
new rtc::RefCountedObject<FakeNativeBufferNoI420>(1280, 720));

View File

@ -104,7 +104,8 @@ TEST(VP8EncoderSimulcastProxy, ChoosesCorrectImplementation) {
SdpVideoFormat("VP8"));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200));
EXPECT_EQ(kImplementationName, simulcast_enabled_proxy.ImplementationName());
EXPECT_EQ(kImplementationName,
simulcast_enabled_proxy.GetEncoderInfo().implementation_name);
NiceMock<MockEncoder>* mock_encoder1 = new NiceMock<MockEncoder>();
NiceMock<MockEncoder>* mock_encoder2 = new NiceMock<MockEncoder>();
@ -145,7 +146,7 @@ TEST(VP8EncoderSimulcastProxy, ChoosesCorrectImplementation) {
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
simulcast_disabled_proxy.InitEncode(&codec_settings, 4, 1200));
EXPECT_EQ(kSimulcastAdaptedImplementationName,
simulcast_disabled_proxy.ImplementationName());
simulcast_disabled_proxy.GetEncoderInfo().implementation_name);
// Cleanup.
simulcast_enabled_proxy.Release();

View File

@ -671,7 +671,7 @@ void VideoCodecTestFixtureImpl::PrintSettings(
std::string encoder_name;
std::string decoder_name;
task_queue->SendTask([this, &encoder_name, &decoder_name] {
encoder_name = encoder_->ImplementationName();
encoder_name = encoder_->GetEncoderInfo().implementation_name;
decoder_name = decoders_.at(0)->ImplementationName();
});
printf("enc_impl_name: %s\n", encoder_name.c_str());

View File

@ -843,7 +843,6 @@ void LibvpxVp8Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
uint32_t timestamp) {
assert(codec_specific != NULL);
codec_specific->codecType = kVideoCodecVP8;
codec_specific->codec_name = ImplementationName();
CodecSpecificInfoVP8* vp8Info = &(codec_specific->codecSpecific.VP8);
vp8Info->keyIdx = kNoKeyIdx; // TODO(hlundin) populate this
vp8Info->nonReference = (pkt.data.frame.flags & VPX_FRAME_IS_DROPPABLE) != 0;

View File

@ -77,7 +77,7 @@ class TestVp8Impl : public VideoCodecUnitTest {
encoder_->Encode(input_frame, nullptr, &frame_types));
ASSERT_TRUE(WaitForEncodedFrame(encoded_frame, codec_specific_info));
VerifyQpParser(*encoded_frame);
EXPECT_STREQ("libvpx", codec_specific_info->codec_name);
EXPECT_EQ("libvpx", encoder_->GetEncoderInfo().implementation_name);
EXPECT_EQ(kVideoCodecVP8, codec_specific_info->codecType);
EXPECT_EQ(0, encoded_frame->SpatialIndex());
}
@ -334,7 +334,8 @@ TEST_F(TestVp8Impl, ScalingDisabledIfAutomaticResizeOff) {
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
VideoEncoder::ScalingSettings settings = encoder_->GetScalingSettings();
VideoEncoder::ScalingSettings settings =
encoder_->GetEncoderInfo().scaling_settings;
EXPECT_FALSE(settings.thresholds.has_value());
}
@ -344,7 +345,8 @@ TEST_F(TestVp8Impl, ScalingEnabledIfAutomaticResizeOn) {
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
VideoEncoder::ScalingSettings settings = encoder_->GetScalingSettings();
VideoEncoder::ScalingSettings settings =
encoder_->GetEncoderInfo().scaling_settings;
EXPECT_TRUE(settings.thresholds.has_value());
EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame);
}

View File

@ -837,7 +837,6 @@ void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
bool first_frame_in_picture) {
RTC_CHECK(codec_specific != nullptr);
codec_specific->codecType = kVideoCodecVP9;
codec_specific->codec_name = ImplementationName();
CodecSpecificInfoVP9* vp9_info = &(codec_specific->codecSpecific.VP9);
vp9_info->first_frame_in_picture = first_frame_in_picture;

View File

@ -166,7 +166,7 @@ bool VCMGenericEncoder::InternalSource() const {
bool VCMGenericEncoder::SupportsNativeHandle() const {
RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
return encoder_->SupportsNativeHandle();
return encoder_->GetEncoderInfo().supports_native_handle;
}
VCMEncodedFrameCallback::VCMEncodedFrameCallback(

View File

@ -79,6 +79,7 @@ struct CodecSpecificInfo {
memset(&codecSpecific, 0, sizeof(codecSpecific));
}
VideoCodecType codecType;
// |codec_name| is deprecated, use name provided by VideoEncoder instead.
const char* codec_name;
CodecSpecificInfoUnion codecSpecific;
};

View File

@ -385,7 +385,6 @@ CodecSpecificInfo VideoEncoderWrapper::ParseCodecSpecificInfo(
CodecSpecificInfo info;
memset(&info, 0, sizeof(info));
info.codecType = codec_settings_.codecType;
info.codec_name = implementation_name_.c_str();
switch (codec_settings_.codecType) {
case kVideoCodecVP8:

View File

@ -128,7 +128,6 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
? VideoContentType::SCREENSHARE
: VideoContentType::UNSPECIFIED;
encoded.SetSpatialIndex(i);
specifics.codec_name = ImplementationName();
if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
EncodedImageCallback::Result::OK) {
return -1;

View File

@ -106,7 +106,6 @@ void FakeVP8Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
uint32_t timestamp) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
codec_specific->codecType = kVideoCodecVP8;
codec_specific->codec_name = ImplementationName();
CodecSpecificInfoVP8* vp8Info = &(codec_specific->codecSpecific.VP8);
vp8Info->keyIdx = kNoKeyIdx;
vp8Info->nonReference = false;

View File

@ -823,10 +823,13 @@ void SendStatisticsProxy::UpdateEncoderFallbackStats(
const int64_t now_ms = clock_->TimeInMilliseconds();
bool is_active = fallback_info->is_active;
if (codec_info->codec_name != stats_.encoder_implementation_name) {
if (encoder_changed_) {
// Implementation changed.
is_active = strcmp(codec_info->codec_name, kVp8SwCodecName) == 0;
if (!is_active && stats_.encoder_implementation_name != kVp8SwCodecName) {
const bool last_was_vp8_software =
encoder_changed_->previous_encoder_implementation == kVp8SwCodecName;
is_active = encoder_changed_->new_encoder_implementation == kVp8SwCodecName;
encoder_changed_.reset();
if (!is_active && !last_was_vp8_software) {
// First or not a VP8 SW change, update stats on next call.
return;
}
@ -865,7 +868,7 @@ void SendStatisticsProxy::UpdateFallbackDisabledStats(
}
if (!IsForcedFallbackPossible(codec_info, simulcast_index) ||
strcmp(codec_info->codec_name, kVp8SwCodecName) == 0) {
stats_.encoder_implementation_name == kVp8SwCodecName) {
uma_container_->fallback_info_disabled_.is_possible = false;
return;
}
@ -895,13 +898,9 @@ void SendStatisticsProxy::OnSendEncodedImage(
rtc::CritScope lock(&crit_);
++stats_.frames_encoded;
if (codec_info) {
if (codec_info->codec_name) {
UpdateEncoderFallbackStats(
codec_info,
encoded_image._encodedWidth * encoded_image._encodedHeight,
simulcast_idx);
stats_.encoder_implementation_name = codec_info->codec_name;
}
UpdateEncoderFallbackStats(
codec_info, encoded_image._encodedWidth * encoded_image._encodedHeight,
simulcast_idx);
}
if (static_cast<size_t>(simulcast_idx) >= rtp_config_.ssrcs.size()) {
@ -981,6 +980,14 @@ void SendStatisticsProxy::OnSendEncodedImage(
}
}
void SendStatisticsProxy::OnEncoderImplementationChanged(
const std::string& implementation_name) {
rtc::CritScope lock(&crit_);
encoder_changed_ = EncoderChangeEvent{stats_.encoder_implementation_name,
implementation_name};
stats_.encoder_implementation_name = implementation_name;
}
int SendStatisticsProxy::GetInputFrameRate() const {
rtc::CritScope lock(&crit_);
return round(uma_container_->input_frame_rate_tracker_.ComputeRate());

View File

@ -53,6 +53,10 @@ class SendStatisticsProxy : public VideoStreamEncoderObserver,
void OnSendEncodedImage(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_info) override;
void OnEncoderImplementationChanged(
const std::string& implementation_name) override;
// Used to update incoming frame rate.
void OnIncomingFrame(int width, int height) override;
@ -241,6 +245,14 @@ class SendStatisticsProxy : public VideoStreamEncoderObserver,
absl::optional<int64_t> last_outlier_timestamp_ RTC_GUARDED_BY(crit_);
struct EncoderChangeEvent {
std::string previous_encoder_implementation;
std::string new_encoder_implementation;
};
// Stores the last change in encoder implementation in an optional, so that
// the event can be consumed.
absl::optional<EncoderChangeEvent> encoder_changed_;
// Contains stats used for UMA histograms. These stats will be reset if
// content type changes between real-time video and screenshare, since these
// will be reported separately.

View File

@ -2167,13 +2167,9 @@ TEST_F(SendStatisticsProxyTest, FecBitrateNotReportedWhenNotEnabled) {
}
TEST_F(SendStatisticsProxyTest, GetStatsReportsEncoderImplementationName) {
const char* kName = "encoderName";
EncodedImage encoded_image;
CodecSpecificInfo codec_info;
codec_info.codec_name = kName;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
EXPECT_STREQ(
kName, statistics_proxy_->GetStats().encoder_implementation_name.c_str());
const std::string kName = "encoderName";
statistics_proxy_->OnEncoderImplementationChanged(kName);
EXPECT_EQ(kName, statistics_proxy_->GetStats().encoder_implementation_name);
}
TEST_F(SendStatisticsProxyTest, Vp9SvcLowSpatialLayerDoesNotUpdateResolution) {
@ -2219,7 +2215,6 @@ class ForcedFallbackTest : public SendStatisticsProxyTest {
: SendStatisticsProxyTest(field_trials) {
codec_info_.codecType = kVideoCodecVP8;
codec_info_.codecSpecific.VP8.temporalIdx = 0;
codec_info_.codec_name = "fake_codec";
encoded_image_._encodedWidth = kWidth;
encoded_image_._encodedHeight = kHeight;
encoded_image_.SetSpatialIndex(0);
@ -2229,6 +2224,8 @@ class ForcedFallbackTest : public SendStatisticsProxyTest {
protected:
void InsertEncodedFrames(int num_frames, int interval_ms) {
statistics_proxy_->OnEncoderImplementationChanged(codec_name_);
// First frame is not updating stats, insert initial frame.
if (statistics_proxy_->GetStats().frames_encoded == 0) {
statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
@ -2243,6 +2240,7 @@ class ForcedFallbackTest : public SendStatisticsProxyTest {
EncodedImage encoded_image_;
CodecSpecificInfo codec_info_;
std::string codec_name_;
const std::string kPrefix = "WebRTC.Video.Encoder.ForcedSw";
const int kFrameIntervalMs = 1000;
const int kMinFrames = 20; // Min run time 20 sec.
@ -2321,7 +2319,7 @@ TEST_F(ForcedFallbackEnabled, EnteredLowResolutionNotSetIfNotLibvpx) {
}
TEST_F(ForcedFallbackEnabled, EnteredLowResolutionSetIfLibvpx) {
codec_info_.codec_name = "libvpx";
codec_name_ = "libvpx";
InsertEncodedFrames(1, kFrameIntervalMs);
EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
}
@ -2333,7 +2331,7 @@ TEST_F(ForcedFallbackDisabled, EnteredLowResolutionNotSetIfAboveMaxPixels) {
}
TEST_F(ForcedFallbackDisabled, EnteredLowResolutionNotSetIfLibvpx) {
codec_info_.codec_name = "libvpx";
codec_name_ = "libvpx";
InsertEncodedFrames(1, kFrameIntervalMs);
EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
}
@ -2351,7 +2349,7 @@ TEST_F(ForcedFallbackEnabled, OneFallbackEvent) {
EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
InsertEncodedFrames(15, 1000);
EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
codec_info_.codec_name = "libvpx";
codec_name_ = "libvpx";
InsertEncodedFrames(5, 1000);
EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
@ -2369,18 +2367,18 @@ TEST_F(ForcedFallbackEnabled, ThreeFallbackEvents) {
// Three changes. Video: 60000 ms, fallback: 15000 ms (25%).
InsertEncodedFrames(10, 1000);
EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
codec_info_.codec_name = "libvpx";
codec_name_ = "libvpx";
InsertEncodedFrames(15, 500);
EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
codec_info_.codec_name = "notlibvpx";
codec_name_ = "notlibvpx";
InsertEncodedFrames(20, 1000);
InsertEncodedFrames(3, kMaxFrameDiffMs); // Should not be included.
InsertEncodedFrames(10, 1000);
EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
codec_info_.codec_name = "notlibvpx2";
codec_name_ = "notlibvpx2";
InsertEncodedFrames(10, 500);
EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
codec_info_.codec_name = "libvpx";
codec_name_ = "libvpx";
InsertEncodedFrames(15, 500);
EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
@ -2393,7 +2391,7 @@ TEST_F(ForcedFallbackEnabled, ThreeFallbackEvents) {
TEST_F(ForcedFallbackEnabled, NoFallbackIfAboveMaxPixels) {
encoded_image_._encodedWidth = kWidth + 1;
codec_info_.codec_name = "libvpx";
codec_name_ = "libvpx";
InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
@ -2404,7 +2402,7 @@ TEST_F(ForcedFallbackEnabled, NoFallbackIfAboveMaxPixels) {
TEST_F(ForcedFallbackEnabled, FallbackIfAtMaxPixels) {
encoded_image_._encodedWidth = kWidth;
codec_info_.codec_name = "libvpx";
codec_name_ = "libvpx";
InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);

View File

@ -363,6 +363,8 @@ VideoStreamEncoder::VideoStreamEncoder(
max_framerate_(-1),
pending_encoder_reconfiguration_(false),
pending_encoder_creation_(false),
crop_width_(0),
crop_height_(0),
encoder_start_bitrate_bps_(0),
max_data_payload_length_(0),
last_observed_bitrate_bps_(0),
@ -376,6 +378,7 @@ VideoStreamEncoder::VideoStreamEncoder(
last_frame_log_ms_(clock_->TimeInMilliseconds()),
captured_frame_count_(0),
dropped_frame_count_(0),
pending_frame_post_time_us_(0),
bitrate_observer_(nullptr),
encoder_queue_("EncoderQueue") {
RTC_DCHECK(encoder_stats_observer);
@ -629,7 +632,7 @@ void VideoStreamEncoder::ReconfigureEncoder() {
void VideoStreamEncoder::ConfigureQualityScaler() {
RTC_DCHECK_RUN_ON(&encoder_queue_);
const auto scaling_settings = encoder_->GetScalingSettings();
const auto scaling_settings = encoder_->GetEncoderInfo().scaling_settings;
const bool quality_scaling_allowed =
IsResolutionScalingEnabled(degradation_preference_) &&
scaling_settings.thresholds;
@ -887,6 +890,14 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
overuse_detector_->FrameCaptured(out_frame, time_when_posted_us);
// Encoder metadata needs to be updated before encode complete callback.
VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo();
if (info.implementation_name != encoder_info_.implementation_name) {
encoder_stats_observer_->OnEncoderImplementationChanged(
info.implementation_name);
}
encoder_info_ = info;
video_sender_.AddVideoFrame(out_frame, nullptr);
}
@ -1085,7 +1096,7 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
bool min_pixels_reached = false;
if (!source_proxy_->RequestResolutionLowerThan(
adaptation_request.input_pixel_count_,
encoder_->GetScalingSettings().min_pixels_per_frame,
encoder_->GetEncoderInfo().scaling_settings.min_pixels_per_frame,
&min_pixels_reached)) {
if (min_pixels_reached)
encoder_stats_observer_->OnMinPixelLimitReached();

View File

@ -268,6 +268,8 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
absl::optional<int64_t> last_parameters_update_ms_
RTC_GUARDED_BY(&encoder_queue_);
VideoEncoder::EncoderInfo encoder_info_ RTC_GUARDED_BY(&encoder_queue_);
// All public methods are proxied to |encoder_queue_|. It must must be
// destroyed first to make sure no tasks are run that use other members.
rtc::TaskQueue encoder_queue_;