Delete EncoderSimulcastProxy in favor of SimulcastEncoderAdapter.

Because the adapter has a passthrough mode, it can already handle both
singlecast and simulcast cases, meaning the proxy is no longer providing
value. Let's delete.

Bug: webrtc:15001
Change-Id: I480eaba599448e9b82b8cf7f829dc35ad6ce0434
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/297740
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39579}
This commit is contained in:
Henrik Boström 2023-03-15 11:29:30 +01:00 committed by WebRTC LUCI CQ
parent b64d04bc1d
commit f6eae959bf
8 changed files with 12 additions and 426 deletions

View File

@ -139,9 +139,9 @@ rtc_library("builtin_video_encoder_factory") {
"../../api:scoped_refptr",
"../../media:codec",
"../../media:media_constants",
"../../media:rtc_encoder_simulcast_proxy",
"../../media:rtc_internal_video_codecs",
"../../media:rtc_media_base",
"../../media:rtc_simulcast_encoder_adapter",
"../../rtc_base:checks",
"../../rtc_base/system:rtc_export",
]

View File

@ -20,8 +20,8 @@
#include "api/video_codecs/video_encoder.h"
#include "media/base/codec.h"
#include "media/base/media_constants.h"
#include "media/engine/encoder_simulcast_proxy.h"
#include "media/engine/internal_encoder_factory.h"
#include "media/engine/simulcast_encoder_adapter.h"
#include "rtc_base/checks.h"
namespace webrtc {
@ -36,15 +36,17 @@ class BuiltinVideoEncoderFactory : public VideoEncoderFactory {
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) override {
// Try creating internal encoder.
std::unique_ptr<VideoEncoder> internal_encoder;
// Try creating an InternalEncoderFactory-backed SimulcastEncoderAdapter.
// The adapter has a passthrough mode for the case that simulcast is not
// used, so all responsibility can be delegated to it.
std::unique_ptr<VideoEncoder> encoder;
if (format.IsCodecInList(
internal_encoder_factory_->GetSupportedFormats())) {
internal_encoder = std::make_unique<EncoderSimulcastProxy>(
encoder = std::make_unique<SimulcastEncoderAdapter>(
internal_encoder_factory_.get(), format);
}
return internal_encoder;
return encoder;
}
std::vector<SdpVideoFormat> GetSupportedFormats() const override {

View File

@ -359,25 +359,6 @@ rtc_library("rtc_simulcast_encoder_adapter") {
]
}
rtc_library("rtc_encoder_simulcast_proxy") {
visibility = [ "*" ]
defines = []
libs = []
sources = [
"engine/encoder_simulcast_proxy.cc",
"engine/encoder_simulcast_proxy.h",
]
deps = [
":rtc_simulcast_encoder_adapter",
"../api/video:video_bitrate_allocation",
"../api/video:video_frame",
"../api/video:video_rtp_headers",
"../api/video_codecs:video_codecs_api",
"../modules/video_coding:video_codec_interface",
"../rtc_base/system:rtc_export",
]
}
rtc_library("rtc_internal_video_codecs") {
visibility = [ "*" ]
allow_poison = [ "software_video_codecs" ]
@ -386,7 +367,6 @@ rtc_library("rtc_internal_video_codecs") {
deps = [
":codec",
":media_constants",
":rtc_encoder_simulcast_proxy",
":rtc_media_base",
":rtc_simulcast_encoder_adapter",
"../api/video:encoded_image",
@ -436,10 +416,6 @@ rtc_library("rtc_internal_video_codecs") {
"engine/internal_encoder_factory.h",
"engine/multiplex_codec_factory.cc",
"engine/multiplex_codec_factory.h",
# TODO(bugs.webrtc.org/7925): stop exporting this header once downstream
# targets depend on :rtc_encoder_simulcast_proxy directly.
"engine/encoder_simulcast_proxy.h",
]
}
@ -783,7 +759,6 @@ if (rtc_include_tests) {
":codec",
":media_constants",
":rtc_audio_video",
":rtc_encoder_simulcast_proxy",
":rtc_internal_video_codecs",
":rtc_media",
":rtc_media_base",
@ -887,7 +862,6 @@ if (rtc_include_tests) {
"base/video_adapter_unittest.cc",
"base/video_broadcaster_unittest.cc",
"base/video_common_unittest.cc",
"engine/encoder_simulcast_proxy_unittest.cc",
"engine/internal_decoder_factory_unittest.cc",
"engine/internal_encoder_factory_unittest.cc",
"engine/multiplex_codec_factory_unittest.cc",

View File

@ -1,97 +0,0 @@
/*
* Copyright (c) 2017 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 "media/engine/encoder_simulcast_proxy.h"
#include "api/video_codecs/video_encoder.h"
#include "media/engine/simulcast_encoder_adapter.h"
#include "modules/video_coding/include/video_error_codes.h"
namespace webrtc {
EncoderSimulcastProxy::EncoderSimulcastProxy(VideoEncoderFactory* factory,
const SdpVideoFormat& format)
: factory_(factory), video_format_(format), callback_(nullptr) {
encoder_ = factory_->CreateVideoEncoder(format);
}
EncoderSimulcastProxy::~EncoderSimulcastProxy() = default;
int EncoderSimulcastProxy::Release() {
return encoder_->Release();
}
void EncoderSimulcastProxy::SetFecControllerOverride(
FecControllerOverride* fec_controller_override) {
encoder_->SetFecControllerOverride(fec_controller_override);
}
// TODO(eladalon): s/inst/codec_settings/g.
int EncoderSimulcastProxy::InitEncode(const VideoCodec* inst,
const VideoEncoder::Settings& settings) {
int ret;
if (inst->numberOfSimulcastStreams <= 1 ||
encoder_->GetEncoderInfo().supports_simulcast) {
// A simulcast capable encoder may still return
// WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED if the current
// configuration is not supported.
ret = encoder_->InitEncode(inst, settings);
} else {
// If the encoder does not support simulcast, fallback to
// SimulcastEncoderAdapter without trying to InitEncode().
// TODO(https://crbug.com/webrtc/14884): Delete EncoderSimulcastProxy and
// always use the simulcast adapter instead; it has a passthrough mode so
// this proxy is an unnecessary layer.
ret = WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED;
}
if (ret == WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED) {
encoder_.reset(new SimulcastEncoderAdapter(factory_, video_format_));
if (callback_) {
encoder_->RegisterEncodeCompleteCallback(callback_);
}
ret = encoder_->InitEncode(inst, settings);
}
return ret;
}
int EncoderSimulcastProxy::Encode(
const VideoFrame& input_image,
const std::vector<VideoFrameType>* frame_types) {
return encoder_->Encode(input_image, frame_types);
}
int EncoderSimulcastProxy::RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) {
callback_ = callback;
return encoder_->RegisterEncodeCompleteCallback(callback);
}
void EncoderSimulcastProxy::SetRates(const RateControlParameters& parameters) {
encoder_->SetRates(parameters);
}
void EncoderSimulcastProxy::OnPacketLossRateUpdate(float packet_loss_rate) {
encoder_->OnPacketLossRateUpdate(packet_loss_rate);
}
void EncoderSimulcastProxy::OnRttUpdate(int64_t rtt_ms) {
encoder_->OnRttUpdate(rtt_ms);
}
void EncoderSimulcastProxy::OnLossNotification(
const LossNotification& loss_notification) {
encoder_->OnLossNotification(loss_notification);
}
VideoEncoder::EncoderInfo EncoderSimulcastProxy::GetEncoderInfo() const {
return encoder_->GetEncoderInfo();
}
} // namespace webrtc

View File

@ -1,64 +0,0 @@
/*
* Copyright (c) 2017 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.
*
*/
#ifndef MEDIA_ENGINE_ENCODER_SIMULCAST_PROXY_H_
#define MEDIA_ENGINE_ENCODER_SIMULCAST_PROXY_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <vector>
#include "api/video/video_bitrate_allocation.h"
#include "api/video/video_frame.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// This class provides fallback to SimulcastEncoderAdapter if default VP8Encoder
// doesn't support simulcast for provided settings.
class RTC_EXPORT EncoderSimulcastProxy : public VideoEncoder {
public:
EncoderSimulcastProxy(VideoEncoderFactory* factory,
const SdpVideoFormat& format);
~EncoderSimulcastProxy() override;
// Implements VideoEncoder.
int Release() override;
void SetFecControllerOverride(
FecControllerOverride* fec_controller_override) override;
int InitEncode(const VideoCodec* codec_settings,
const VideoEncoder::Settings& settings) override;
int Encode(const VideoFrame& input_image,
const std::vector<VideoFrameType>* frame_types) override;
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
void SetRates(const RateControlParameters& parameters) override;
void OnPacketLossRateUpdate(float packet_loss_rate) override;
void OnRttUpdate(int64_t rtt_ms) override;
void OnLossNotification(const LossNotification& loss_notification) override;
EncoderInfo GetEncoderInfo() const override;
private:
VideoEncoderFactory* const factory_;
SdpVideoFormat video_format_;
std::unique_ptr<VideoEncoder> encoder_;
EncodedImageCallback* callback_;
};
} // namespace webrtc
#endif // MEDIA_ENGINE_ENCODER_SIMULCAST_PROXY_H_

View File

@ -1,229 +0,0 @@
/*
* Copyright (c) 2017 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 "media/engine/encoder_simulcast_proxy.h"
#include <memory>
#include <string>
#include <utility>
#include "api/test/mock_video_encoder.h"
#include "api/test/mock_video_encoder_factory.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/vp8_temporal_layers.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/video_codec_settings.h"
namespace webrtc {
namespace testing {
namespace {
const VideoEncoder::Capabilities kCapabilities(false);
const VideoEncoder::Settings kSettings(kCapabilities, 4, 1200);
constexpr const char* kImplementationName = "Fake";
constexpr const char* kSimulcastAdaptedImplementationName =
"SimulcastEncoderAdapter (Fake, Fake, Fake)";
VideoCodec CreateSimulcastVideoCodec() {
VideoCodec codec_settings;
webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
codec_settings.simulcastStream[0] = {.width = test::kTestWidth,
.height = test::kTestHeight,
.maxFramerate = test::kTestFrameRate,
.numberOfTemporalLayers = 2,
.maxBitrate = 2000,
.targetBitrate = 1000,
.minBitrate = 1000,
.qpMax = 56,
.active = true};
codec_settings.simulcastStream[1] = {.width = test::kTestWidth,
.height = test::kTestHeight,
.maxFramerate = test::kTestFrameRate,
.numberOfTemporalLayers = 2,
.maxBitrate = 3000,
.targetBitrate = 1000,
.minBitrate = 1000,
.qpMax = 56,
.active = true};
codec_settings.simulcastStream[2] = {.width = test::kTestWidth,
.height = test::kTestHeight,
.maxFramerate = test::kTestFrameRate,
.numberOfTemporalLayers = 2,
.maxBitrate = 5000,
.targetBitrate = 1000,
.minBitrate = 1000,
.qpMax = 56,
.active = true};
codec_settings.numberOfSimulcastStreams = 3;
return codec_settings;
}
} // namespace
using ::testing::_;
using ::testing::ByMove;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
TEST(EncoderSimulcastProxy, ImplementationSupportsSimulcast) {
VideoCodec codec_settings = CreateSimulcastVideoCodec();
auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>();
EXPECT_CALL(*mock_encoder, InitEncode(_, _))
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
VideoEncoder::EncoderInfo encoder_info;
encoder_info.supports_simulcast = true;
encoder_info.implementation_name = kImplementationName;
EXPECT_CALL(*mock_encoder, GetEncoderInfo())
.WillRepeatedly(Return(encoder_info));
NiceMock<MockVideoEncoderFactory> simulcast_factory;
EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
.Times(1)
.WillOnce(Return(ByMove(std::move(mock_encoder))));
EncoderSimulcastProxy simulcast_proxy(&simulcast_factory,
SdpVideoFormat("VP8"));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
simulcast_proxy.InitEncode(&codec_settings, kSettings));
EXPECT_EQ(kImplementationName,
simulcast_proxy.GetEncoderInfo().implementation_name);
// Cleanup.
simulcast_proxy.Release();
}
TEST(EncoderSimulcastProxy, ImplementationDoesNotSupportSimulcast) {
VideoCodec codec_settings = CreateSimulcastVideoCodec();
NiceMock<MockVideoEncoderFactory> simulcast_factory;
EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
.Times(4)
.WillRepeatedly([&] {
auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>();
EXPECT_CALL(*mock_encoder, InitEncode(_, _))
.WillRepeatedly(Return(WEBRTC_VIDEO_CODEC_OK));
VideoEncoder::EncoderInfo encoder_info;
encoder_info.supports_simulcast = false;
encoder_info.implementation_name = kImplementationName;
EXPECT_CALL(*mock_encoder, GetEncoderInfo())
.WillRepeatedly(Return(encoder_info));
return mock_encoder;
});
EncoderSimulcastProxy simulcast_proxy(&simulcast_factory,
SdpVideoFormat("VP8"));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
simulcast_proxy.InitEncode(&codec_settings, kSettings));
EXPECT_EQ(kSimulcastAdaptedImplementationName,
simulcast_proxy.GetEncoderInfo().implementation_name);
// Cleanup.
simulcast_proxy.Release();
}
TEST(EncoderSimulcastProxy, ImplementationFailsToInitSimulcast) {
VideoCodec codec_settings = CreateSimulcastVideoCodec();
NiceMock<MockVideoEncoderFactory> encoder_factory;
EXPECT_CALL(encoder_factory, CreateVideoEncoder).Times(4).WillRepeatedly([&] {
// This encoder claims to have simulcast support and thus will be
// attempted, but fails during InitEncode().
auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>();
EXPECT_CALL(*mock_encoder, InitEncode(_, _))
.WillRepeatedly(Invoke([](const VideoCodec* codec_settings,
const VideoEncoder::Settings& settings) {
if (codec_settings->numberOfSimulcastStreams > 1) {
return WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED;
}
return WEBRTC_VIDEO_CODEC_OK;
}));
VideoEncoder::EncoderInfo encoder_info;
encoder_info.supports_simulcast = true;
encoder_info.implementation_name = kImplementationName;
ON_CALL(*mock_encoder, GetEncoderInfo).WillByDefault(Return(encoder_info));
return mock_encoder;
});
EncoderSimulcastProxy simulcast_proxy(&encoder_factory,
SdpVideoFormat("VP8"));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
simulcast_proxy.InitEncode(&codec_settings, kSettings));
EXPECT_EQ(kSimulcastAdaptedImplementationName,
simulcast_proxy.GetEncoderInfo().implementation_name);
// Cleanup.
simulcast_proxy.Release();
}
TEST(EncoderSimulcastProxy, ForwardsTrustedSetting) {
auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>();
auto* mock_encoder = mock_encoder_owned.get();
NiceMock<MockVideoEncoderFactory> simulcast_factory;
EXPECT_CALL(*mock_encoder, InitEncode(_, _))
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
.Times(1)
.WillOnce(Return(ByMove(std::move(mock_encoder_owned))));
EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
SdpVideoFormat("VP8"));
VideoCodec codec_settings;
webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
VideoEncoder::EncoderInfo info;
info.has_trusted_rate_controller = true;
EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillRepeatedly(Return(info));
EXPECT_TRUE(
simulcast_enabled_proxy.GetEncoderInfo().has_trusted_rate_controller);
}
TEST(EncoderSimulcastProxy, ForwardsHardwareAccelerated) {
auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>();
NiceMock<MockVideoEncoder>* mock_encoder = mock_encoder_owned.get();
NiceMock<MockVideoEncoderFactory> simulcast_factory;
EXPECT_CALL(*mock_encoder, InitEncode(_, _))
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
.Times(1)
.WillOnce(Return(ByMove(std::move(mock_encoder_owned))));
EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
SdpVideoFormat("VP8"));
VideoCodec codec_settings;
webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
VideoEncoder::EncoderInfo info;
info.is_hardware_accelerated = false;
EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
EXPECT_FALSE(
simulcast_enabled_proxy.GetEncoderInfo().is_hardware_accelerated);
info.is_hardware_accelerated = true;
EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
EXPECT_TRUE(simulcast_enabled_proxy.GetEncoderInfo().is_hardware_accelerated);
}
} // namespace testing
} // namespace webrtc

View File

@ -503,9 +503,9 @@ if (rtc_include_tests) {
"../common_video",
"../media:media_constants",
"../media:rtc_audio_video",
"../media:rtc_encoder_simulcast_proxy",
"../media:rtc_internal_video_codecs",
"../media:rtc_media_base",
"../media:rtc_simulcast_encoder_adapter",
"../modules/audio_device:audio_device_api",
"../modules/audio_device:audio_device_module_from_input_and_output",
"../modules/audio_device:windows_core_audio_utility",

View File

@ -33,9 +33,9 @@
#include "call/simulated_network.h"
#include "media/base/media_constants.h"
#include "media/engine/adm_helpers.h"
#include "media/engine/encoder_simulcast_proxy.h"
#include "media/engine/fake_video_codec_factory.h"
#include "media/engine/internal_encoder_factory.h"
#include "media/engine/simulcast_encoder_adapter.h"
#include "media/engine/webrtc_video_engine.h"
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_mixer/audio_mixer_impl.h"
@ -320,8 +320,8 @@ std::unique_ptr<VideoEncoder> VideoQualityTest::CreateVideoEncoder(
VideoAnalyzer* analyzer) {
std::unique_ptr<VideoEncoder> encoder;
if (format.name == "VP8") {
encoder =
std::make_unique<EncoderSimulcastProxy>(encoder_factory_.get(), format);
encoder = std::make_unique<SimulcastEncoderAdapter>(encoder_factory_.get(),
format);
} else if (format.name == "multiplex") {
encoder = std::make_unique<MultiplexEncoderAdapter>(
encoder_factory_.get(), SdpVideoFormat(cricket::kVp9CodecName));