diff --git a/api/test/mock_video_encoder.h b/api/test/mock_video_encoder.h index 9333b89375..adc6859bd3 100644 --- a/api/test/mock_video_encoder.h +++ b/api/test/mock_video_encoder.h @@ -37,6 +37,10 @@ class MockVideoEncoder : public VideoEncoder { int32_t(const VideoCodec* codecSettings, int32_t numberOfCores, size_t maxPayloadSize)); + MOCK_METHOD2(InitEncode, + int32_t(const VideoCodec* codecSettings, + const VideoEncoder::Settings& settings)); + MOCK_METHOD2(Encode, int32_t(const VideoFrame& inputImage, const std::vector* frame_types)); diff --git a/api/video/video_stream_encoder_settings.h b/api/video/video_stream_encoder_settings.h index 37c1de7015..0183d4cac1 100644 --- a/api/video/video_stream_encoder_settings.h +++ b/api/video/video_stream_encoder_settings.h @@ -12,12 +12,15 @@ #define API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_ #include "api/video/video_bitrate_allocator_factory.h" +#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_factory.h" namespace webrtc { struct VideoStreamEncoderSettings { - VideoStreamEncoderSettings() = default; + explicit VideoStreamEncoderSettings( + const VideoEncoder::Capabilities& capabilities) + : capabilities(capabilities) {} // Enables the new method to estimate the cpu load from encoding, used for // cpu adaptation. @@ -28,6 +31,10 @@ struct VideoStreamEncoderSettings { // Ownership stays with WebrtcVideoEngine (delegated from PeerConnection). VideoBitrateAllocatorFactory* bitrate_allocator_factory = nullptr; + + // Negotiated capabilities which the VideoEncoder may expect the other + // side to use. + VideoEncoder::Capabilities capabilities; }; } // namespace webrtc diff --git a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc index 201afc8ac1..55afb68d99 100644 --- a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc +++ b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc @@ -50,6 +50,11 @@ const int kDefaultMinPixelsPerFrame = 320 * 180; const int kLowThreshold = 10; const int kHighThreshold = 20; +const VideoEncoder::Capabilities kCapabilities(false); +const VideoEncoder::Settings kSettings(kCapabilities, + kNumCores, + kMaxPayloadSize); + VideoEncoder::EncoderInfo GetEncoderInfoWithTrustedRateController( bool trusted_rate_controller) { VideoEncoder::EncoderInfo info; @@ -87,11 +92,11 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test { class CountingFakeEncoder : public VideoEncoder { public: int32_t InitEncode(const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) override { + const VideoEncoder::Settings& settings) override { ++init_encode_count_; return init_encode_return_code_; } + int32_t Encode(const VideoFrame& frame, const std::vector* frame_types) override { ++encode_count_; @@ -202,7 +207,7 @@ void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() { fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize)); + fallback_wrapper_->InitEncode(&codec_, kSettings)); fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters( rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); @@ -221,7 +226,7 @@ void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() { codec_.height = kHeight; codec_.VP8()->numberOfTemporalLayers = 1; rate_allocator_.reset(new SimulcastRateAllocator(codec_)); - fallback_wrapper_->InitEncode(&codec_, 2, kMaxPayloadSize); + fallback_wrapper_->InitEncode(&codec_, kSettings); fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters( rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); EXPECT_EQ(1, fake_encoder_->init_encode_count_); @@ -238,7 +243,7 @@ void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() { TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) { VideoCodec codec = {}; - fallback_wrapper_->InitEncode(&codec, 2, kMaxPayloadSize); + fallback_wrapper_->InitEncode(&codec, kSettings); EXPECT_EQ(1, fake_encoder_->init_encode_count_); } @@ -324,7 +329,7 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) { codec_.width = kWidth; codec_.height = kHeight; fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_); - fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize); + fallback_wrapper_->InitEncode(&codec_, kSettings); EncodeFrame(); CheckLastEncoderName("fake-encoder"); } @@ -375,8 +380,8 @@ class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest { void InitEncode(int width, int height) { codec_.width = width; codec_.height = height; - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->InitEncode( - &codec_, kNumCores, kMaxPayloadSize)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + fallback_wrapper_->InitEncode(&codec_, kSettings)); SetRateAllocation(kBitrateKbps); } @@ -590,6 +595,9 @@ TEST(SoftwareFallbackEncoderTest, HwRateControllerTrusted) { std::unique_ptr(hw_encoder)); EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller); + VideoCodec codec_ = {}; + wrapper->InitEncode(&codec_, kSettings); + // Trigger fallback to software. EXPECT_CALL(*hw_encoder, Encode) .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)); @@ -630,6 +638,9 @@ TEST(SoftwareFallbackEncoderTest, ReportsHardwareAccelerated) { std::unique_ptr(hw_encoder)); EXPECT_TRUE(wrapper->GetEncoderInfo().is_hardware_accelerated); + VideoCodec codec_ = {}; + wrapper->InitEncode(&codec_, kSettings); + // Trigger fallback to software. EXPECT_CALL(*hw_encoder, Encode) .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)); @@ -654,6 +665,9 @@ TEST(SoftwareFallbackEncoderTest, ReportsInternalSource) { std::unique_ptr(hw_encoder)); EXPECT_TRUE(wrapper->GetEncoderInfo().has_internal_source); + VideoCodec codec_ = {}; + wrapper->InitEncode(&codec_, kSettings); + // Trigger fallback to software. EXPECT_CALL(*hw_encoder, Encode) .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)); diff --git a/api/video_codecs/video_encoder.cc b/api/video_codecs/video_encoder.cc index 710d90d2d6..ffdcf8b4a5 100644 --- a/api/video_codecs/video_encoder.cc +++ b/api/video_codecs/video_encoder.cc @@ -118,6 +118,29 @@ VideoEncoder::RateControlParameters::RateControlParameters( VideoEncoder::RateControlParameters::~RateControlParameters() = default; +int32_t VideoEncoder::InitEncode(const VideoCodec* codec_settings, + int32_t number_of_cores, + size_t max_payload_size) { + const VideoEncoder::Capabilities capabilities(/* loss_notification= */ false); + const VideoEncoder::Settings settings(capabilities, number_of_cores, + max_payload_size); + // In theory, this and the other version of InitEncode() could end up calling + // each other in a loop until we get a stack overflow. + // In practice, any subclass of VideoEncoder would overload at least one + // of these, and we have a TODO in the header file to make this pure virtual. + return InitEncode(codec_settings, settings); +} + +int VideoEncoder::InitEncode(const VideoCodec* codec_settings, + const VideoEncoder::Settings& settings) { + // In theory, this and the other version of InitEncode() could end up calling + // each other in a loop until we get a stack overflow. + // In practice, any subclass of VideoEncoder would overload at least one + // of these, and we have a TODO in the header file to make this pure virtual. + return InitEncode(codec_settings, settings.number_of_cores, + settings.max_payload_size); +} + void VideoEncoder::OnPacketLossRateUpdate(float packet_loss_rate) {} void VideoEncoder::OnRttUpdate(int64_t rtt_ms) {} diff --git a/api/video_codecs/video_encoder.h b/api/video_codecs/video_encoder.h index c01309f3e6..d2e4877b84 100644 --- a/api/video_codecs/video_encoder.h +++ b/api/video_codecs/video_encoder.h @@ -86,6 +86,7 @@ class RTC_EXPORT VideoEncoder { int low; int high; }; + // Quality scaling is enabled if thresholds are provided. struct ScalingSettings { private: @@ -237,6 +238,27 @@ class RTC_EXPORT VideoEncoder { absl::optional last_received_decodable; }; + // Negotiated capabilities which the VideoEncoder may expect the other + // side to use. + struct Capabilities { + explicit Capabilities(bool loss_notification) + : loss_notification(loss_notification) {} + bool loss_notification; + }; + + struct Settings { + Settings(const Capabilities& capabilities, + int number_of_cores, + size_t max_payload_size) + : capabilities(capabilities), + number_of_cores(number_of_cores), + max_payload_size(max_payload_size) {} + + Capabilities capabilities; + int number_of_cores; + size_t max_payload_size; + }; + static VideoCodecVP8 GetDefaultVp8Settings(); static VideoCodecVP9 GetDefaultVp9Settings(); static VideoCodecH264 GetDefaultH264Settings(); @@ -247,6 +269,8 @@ class RTC_EXPORT VideoEncoder { // // Input: // - codec_settings : Codec settings + // - settings : Settings affecting the encoding itself. + // Input for deprecated version: // - number_of_cores : Number of cores available for the encoder // - max_payload_size : The maximum size each payload is allowed // to have. Usually MTU - overhead. @@ -257,9 +281,15 @@ class RTC_EXPORT VideoEncoder { // WEBRTC_VIDEO_CODEC_ERR_SIZE // WEBRTC_VIDEO_CODEC_MEMORY // WEBRTC_VIDEO_CODEC_ERROR - virtual int32_t InitEncode(const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) = 0; + // TODO(bugs.webrtc.org/10720): After updating downstream projects and posting + // an announcement to discuss-webrtc, remove the three-parameters variant + // and make the two-parameters variant pure-virtual. + /* RTC_DEPRECATED */ virtual int32_t InitEncode( + const VideoCodec* codec_settings, + int32_t number_of_cores, + size_t max_payload_size); + virtual int InitEncode(const VideoCodec* codec_settings, + const VideoEncoder::Settings& settings); // Register an encode complete callback object. // diff --git a/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/api/video_codecs/video_encoder_software_fallback_wrapper.cc index a687b84ba6..1ccc5a2090 100644 --- a/api/video_codecs/video_encoder_software_fallback_wrapper.cc +++ b/api/video_codecs/video_encoder_software_fallback_wrapper.cc @@ -21,6 +21,7 @@ #include "api/video/video_bitrate_allocation.h" #include "api/video/video_frame.h" #include "api/video_codecs/video_codec.h" +#include "api/video_codecs/video_encoder.h" #include "modules/video_coding/include/video_error_codes.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" @@ -79,8 +80,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder { ~VideoEncoderSoftwareFallbackWrapper() override; int32_t InitEncode(const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) override; + const VideoEncoder::Settings& settings) override; int32_t RegisterEncodeCompleteCallback( EncodedImageCallback* callback) override; @@ -118,8 +118,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder { // Settings used in the last InitEncode call and used if a dynamic fallback to // software is required. VideoCodec codec_settings_; - int32_t number_of_cores_; - size_t max_payload_size_; + absl::optional encoder_settings_; // The last rate control settings, if set. absl::optional rate_control_parameters_; @@ -142,9 +141,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder { VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper( std::unique_ptr sw_encoder, std::unique_ptr hw_encoder) - : number_of_cores_(0), - max_payload_size_(0), - channel_parameters_set_(false), + : channel_parameters_set_(false), packet_loss_(0), rtt_(0), use_fallback_encoder_(false), @@ -165,8 +162,9 @@ VideoEncoderSoftwareFallbackWrapper::~VideoEncoderSoftwareFallbackWrapper() = bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() { RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding."; - const int ret = fallback_encoder_->InitEncode( - &codec_settings_, number_of_cores_, max_payload_size_); + RTC_DCHECK(encoder_settings_.has_value()); + const int ret = fallback_encoder_->InitEncode(&codec_settings_, + encoder_settings_.value()); use_fallback_encoder_ = (ret == WEBRTC_VIDEO_CODEC_OK); if (!use_fallback_encoder_) { RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback."; @@ -188,13 +186,11 @@ bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() { int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) { + const VideoEncoder::Settings& settings) { // Store settings, in case we need to dynamically switch to the fallback // encoder after a failed Encode call. codec_settings_ = *codec_settings; - number_of_cores_ = number_of_cores; - max_payload_size_ = max_payload_size; + encoder_settings_ = settings; // Clear stored rate/channel parameters. rate_control_parameters_ = absl::nullopt; ValidateSettingsForForcedFallback(); @@ -209,8 +205,7 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( } forced_fallback_.active_ = false; - int32_t ret = - encoder_->InitEncode(codec_settings, number_of_cores, max_payload_size); + int32_t ret = encoder_->InitEncode(codec_settings, settings); if (ret == WEBRTC_VIDEO_CODEC_OK) { if (use_fallback_encoder_) { RTC_LOG(LS_WARNING) @@ -319,14 +314,17 @@ bool VideoEncoderSoftwareFallbackWrapper::TryReInitForcedFallbackEncoder() { if (!IsForcedFallbackActive()) { return false; } + // Forced fallback active. if (!forced_fallback_.IsValid(codec_settings_)) { RTC_LOG(LS_INFO) << "Stop forced SW encoder fallback, max pixels exceeded."; return false; } + // Settings valid, reinitialize the forced fallback encoder. - if (fallback_encoder_->InitEncode(&codec_settings_, number_of_cores_, - max_payload_size_) != + RTC_DCHECK(encoder_settings_.has_value()); + if (fallback_encoder_->InitEncode(&codec_settings_, + encoder_settings_.value()) != WEBRTC_VIDEO_CODEC_OK) { RTC_LOG(LS_ERROR) << "Failed to init forced SW encoder fallback."; return false; diff --git a/call/call_perf_tests.cc b/call/call_perf_tests.cc index 0bbf03425c..d869c87dd8 100644 --- a/call/call_perf_tests.cc +++ b/call/call_perf_tests.cc @@ -18,6 +18,7 @@ #include "api/test/simulated_network.h" #include "api/video/builtin_video_bitrate_allocator_factory.h" #include "api/video/video_bitrate_allocation.h" +#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_config.h" #include "call/call.h" #include "call/fake_network_pipe.h" @@ -749,8 +750,7 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) { CreateBuiltinVideoBitrateAllocatorFactory()) {} int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { + const VideoEncoder::Settings& settings) override { ++encoder_inits_; if (encoder_inits_ == 1) { // First time initialization. Frame size is known. @@ -771,7 +771,7 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) { << "Encoder reconfigured with bitrate too far away from last set."; observation_complete_.Set(); } - return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); + return FakeEncoder::InitEncode(config, settings); } void SetRates(const RateControlParameters& parameters) override { diff --git a/call/video_send_stream.cc b/call/video_send_stream.cc index fa2d4f2f8c..dac4029876 100644 --- a/call/video_send_stream.cc +++ b/call/video_send_stream.cc @@ -77,7 +77,10 @@ VideoSendStream::Config::Config(const Config&) = default; VideoSendStream::Config::Config(Config&&) = default; VideoSendStream::Config::Config(Transport* send_transport, MediaTransportInterface* media_transport) - : send_transport(send_transport), media_transport(media_transport) {} + : rtp(), + encoder_settings(VideoEncoder::Capabilities(rtp.lntf.enabled)), + send_transport(send_transport), + media_transport(media_transport) {} VideoSendStream::Config::Config(Transport* send_transport) : Config(send_transport, nullptr) {} diff --git a/call/video_send_stream.h b/call/video_send_stream.h index 850996e858..f38f7bcead 100644 --- a/call/video_send_stream.h +++ b/call/video_send_stream.h @@ -126,10 +126,10 @@ class VideoSendStream { std::string ToString() const; - VideoStreamEncoderSettings encoder_settings; - RtpConfig rtp; + VideoStreamEncoderSettings encoder_settings; + // Time interval between RTCP report for video int rtcp_report_interval_ms = 1000; diff --git a/media/engine/encoder_simulcast_proxy.cc b/media/engine/encoder_simulcast_proxy.cc index 88cff1b567..da769a9c85 100644 --- a/media/engine/encoder_simulcast_proxy.cc +++ b/media/engine/encoder_simulcast_proxy.cc @@ -10,10 +10,12 @@ #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) { @@ -29,16 +31,16 @@ int EncoderSimulcastProxy::Release() { return encoder_->Release(); } +// TODO(eladalon): s/inst/codec_settings/g. int EncoderSimulcastProxy::InitEncode(const VideoCodec* inst, - int number_of_cores, - size_t max_payload_size) { - int ret = encoder_->InitEncode(inst, number_of_cores, max_payload_size); + const VideoEncoder::Settings& settings) { + int ret = encoder_->InitEncode(inst, settings); 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, number_of_cores, max_payload_size); + ret = encoder_->InitEncode(inst, settings); } return ret; } diff --git a/media/engine/encoder_simulcast_proxy.h b/media/engine/encoder_simulcast_proxy.h index 41ffcba162..7709aa205a 100644 --- a/media/engine/encoder_simulcast_proxy.h +++ b/media/engine/encoder_simulcast_proxy.h @@ -42,9 +42,8 @@ class RTC_EXPORT EncoderSimulcastProxy : public VideoEncoder { // Implements VideoEncoder. int Release() override; - int InitEncode(const VideoCodec* inst, - int number_of_cores, - size_t max_payload_size) override; + int InitEncode(const VideoCodec* codec_settings, + const VideoEncoder::Settings& settings) override; int Encode(const VideoFrame& input_image, const std::vector* frame_types) override; int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override; diff --git a/media/engine/encoder_simulcast_proxy_unittest.cc b/media/engine/encoder_simulcast_proxy_unittest.cc index daa4d3e66a..f52575a73e 100644 --- a/media/engine/encoder_simulcast_proxy_unittest.cc +++ b/media/engine/encoder_simulcast_proxy_unittest.cc @@ -14,6 +14,7 @@ #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" @@ -22,6 +23,10 @@ namespace webrtc { namespace testing { +namespace { +const VideoEncoder::Capabilities kCapabilities(false); +const VideoEncoder::Settings kSettings(kCapabilities, 4, 1200); +} // namespace using ::testing::_; using ::testing::NiceMock; @@ -62,7 +67,7 @@ TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) { NiceMock* mock_encoder = new NiceMock(); NiceMock simulcast_factory; - EXPECT_CALL(*mock_encoder, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder, InitEncode(_, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); VideoEncoder::EncoderInfo encoder_info; encoder_info.implementation_name = kImplementationName; @@ -76,7 +81,7 @@ TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) { EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory, SdpVideoFormat("VP8")); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200)); + simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings)); EXPECT_EQ(kImplementationName, simulcast_enabled_proxy.GetEncoderInfo().implementation_name); @@ -86,23 +91,23 @@ TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) { NiceMock* mock_encoder4 = new NiceMock(); NiceMock nonsimulcast_factory; - EXPECT_CALL(*mock_encoder1, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder1, InitEncode(_, _)) .WillOnce( Return(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED)); EXPECT_CALL(*mock_encoder1, GetEncoderInfo()) .WillRepeatedly(Return(encoder_info)); - EXPECT_CALL(*mock_encoder2, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder2, InitEncode(_, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(*mock_encoder2, GetEncoderInfo()) .WillRepeatedly(Return(encoder_info)); - EXPECT_CALL(*mock_encoder3, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder3, InitEncode(_, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(*mock_encoder3, GetEncoderInfo()) .WillRepeatedly(Return(encoder_info)); - EXPECT_CALL(*mock_encoder4, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder4, InitEncode(_, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(*mock_encoder4, GetEncoderInfo()) .WillRepeatedly(Return(encoder_info)); @@ -117,7 +122,7 @@ TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) { EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory, SdpVideoFormat("VP8")); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - simulcast_disabled_proxy.InitEncode(&codec_settings, 4, 1200)); + simulcast_disabled_proxy.InitEncode(&codec_settings, kSettings)); EXPECT_EQ(kSimulcastAdaptedImplementationName, simulcast_disabled_proxy.GetEncoderInfo().implementation_name); @@ -130,7 +135,7 @@ TEST(EncoderSimulcastProxy, ForwardsTrustedSetting) { NiceMock* mock_encoder = new NiceMock(); NiceMock simulcast_factory; - EXPECT_CALL(*mock_encoder, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder, InitEncode(_, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_)) @@ -142,7 +147,7 @@ TEST(EncoderSimulcastProxy, ForwardsTrustedSetting) { VideoCodec codec_settings; webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200)); + simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings)); VideoEncoder::EncoderInfo info; info.has_trusted_rate_controller = true; @@ -156,7 +161,7 @@ TEST(EncoderSimulcastProxy, ForwardsHardwareAccelerated) { NiceMock* mock_encoder = new NiceMock(); NiceMock simulcast_factory; - EXPECT_CALL(*mock_encoder, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder, InitEncode(_, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_)) @@ -168,7 +173,7 @@ TEST(EncoderSimulcastProxy, ForwardsHardwareAccelerated) { VideoCodec codec_settings; webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200)); + simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings)); VideoEncoder::EncoderInfo info; @@ -186,7 +191,7 @@ TEST(EncoderSimulcastProxy, ForwardsInternalSource) { NiceMock* mock_encoder = new NiceMock(); NiceMock simulcast_factory; - EXPECT_CALL(*mock_encoder, InitEncode(_, _, _)) + EXPECT_CALL(*mock_encoder, InitEncode(_, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_)) @@ -198,7 +203,7 @@ TEST(EncoderSimulcastProxy, ForwardsInternalSource) { VideoCodec codec_settings; webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200)); + simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings)); VideoEncoder::EncoderInfo info; diff --git a/media/engine/fake_webrtc_video_engine.cc b/media/engine/fake_webrtc_video_engine.cc index 7e7e3ce42e..bdc9178305 100644 --- a/media/engine/fake_webrtc_video_engine.cc +++ b/media/engine/fake_webrtc_video_engine.cc @@ -139,8 +139,7 @@ FakeWebRtcVideoEncoder::~FakeWebRtcVideoEncoder() { int32_t FakeWebRtcVideoEncoder::InitEncode( const webrtc::VideoCodec* codecSettings, - int32_t numberOfCores, - size_t maxPayloadSize) { + const VideoEncoder::Settings& settings) { rtc::CritScope lock(&crit_); codec_settings_ = *codecSettings; init_encode_event_.Set(); diff --git a/media/engine/fake_webrtc_video_engine.h b/media/engine/fake_webrtc_video_engine.h index 3fea1750d6..364ec9e769 100644 --- a/media/engine/fake_webrtc_video_engine.h +++ b/media/engine/fake_webrtc_video_engine.h @@ -84,8 +84,7 @@ class FakeWebRtcVideoEncoder : public webrtc::VideoEncoder { ~FakeWebRtcVideoEncoder(); int32_t InitEncode(const webrtc::VideoCodec* codecSettings, - int32_t numberOfCores, - size_t maxPayloadSize) override; + const VideoEncoder::Settings& settings) override; int32_t Encode( const webrtc::VideoFrame& inputImage, const std::vector* frame_types) override; diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc index b7b2d7627e..6d8bedbf52 100644 --- a/media/engine/simulcast_encoder_adapter.cc +++ b/media/engine/simulcast_encoder_adapter.cc @@ -22,6 +22,7 @@ #include "api/video/video_codec_constants.h" #include "api/video/video_frame_buffer.h" #include "api/video/video_rotation.h" +#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_factory.h" #include "modules/video_coding/include/video_error_codes.h" #include "modules/video_coding/utility/simulcast_rate_allocator.h" @@ -167,12 +168,13 @@ int SimulcastEncoderAdapter::Release() { return WEBRTC_VIDEO_CODEC_OK; } -int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst, - int number_of_cores, - size_t max_payload_size) { +// TODO(eladalon): s/inst/codec_settings/g. +int SimulcastEncoderAdapter::InitEncode( + const VideoCodec* inst, + const VideoEncoder::Settings& settings) { RTC_DCHECK_RUN_ON(&encoder_queue_); - if (number_of_cores < 1) { + if (settings.number_of_cores < 1) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } @@ -256,7 +258,7 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst, codec_.codecType == webrtc::kVideoCodecVP8 ? "VP8" : "H264")); } - ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size); + ret = encoder->InitEncode(&stream_codec, settings); if (ret < 0) { // Explicitly destroy the current encoder; because we haven't registered a // StreamInfo for it yet, Release won't do anything about it. diff --git a/media/engine/simulcast_encoder_adapter.h b/media/engine/simulcast_encoder_adapter.h index 5bc0bec994..94762569e9 100644 --- a/media/engine/simulcast_encoder_adapter.h +++ b/media/engine/simulcast_encoder_adapter.h @@ -20,6 +20,7 @@ #include "absl/types/optional.h" #include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_encoder.h" #include "modules/video_coding/include/video_codec_interface.h" #include "rtc_base/atomic_ops.h" #include "rtc_base/synchronization/sequence_checker.h" @@ -42,9 +43,8 @@ class RTC_EXPORT SimulcastEncoderAdapter : public VideoEncoder { // Implements VideoEncoder. int Release() override; - int InitEncode(const VideoCodec* inst, - int number_of_cores, - size_t max_payload_size) override; + int InitEncode(const VideoCodec* codec_settings, + const VideoEncoder::Settings& settings) override; int Encode(const VideoFrame& input_image, const std::vector* frame_types) override; int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override; diff --git a/media/engine/simulcast_encoder_adapter_unittest.cc b/media/engine/simulcast_encoder_adapter_unittest.cc index 1bab49af8a..6bf99a520a 100644 --- a/media/engine/simulcast_encoder_adapter_unittest.cc +++ b/media/engine/simulcast_encoder_adapter_unittest.cc @@ -18,6 +18,7 @@ #include "api/test/video/function_video_decoder_factory.h" #include "api/test/video/function_video_encoder_factory.h" #include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_factory.h" #include "common_video/include/video_frame_buffer.h" #include "media/base/media_constants.h" @@ -43,6 +44,9 @@ namespace { constexpr int kDefaultWidth = 1280; constexpr int kDefaultHeight = 720; +const VideoEncoder::Capabilities kCapabilities(false); +const VideoEncoder::Settings kSettings(kCapabilities, 1, 1200); + std::unique_ptr CreateSpecificSimulcastTestFixture( VideoEncoderFactory* internal_encoder_factory) { std::unique_ptr encoder_factory = @@ -188,8 +192,7 @@ class MockVideoEncoder : public VideoEncoder { // warnings from -Winconsistent-missing-override. See // http://crbug.com/428099. int32_t InitEncode(const VideoCodec* codecSettings, - int32_t numberOfCores, - size_t maxPayloadSize) /* override */ { + const VideoEncoder::Settings& settings) /* override */ { codec_ = *codecSettings; return init_encode_return_value_; } @@ -394,7 +397,7 @@ class TestSimulcastEncoderAdapterFake : public ::testing::Test, &codec_, static_cast(kTestTemporalLayerProfile), kVideoCodecVP8); rate_allocator_.reset(new SimulcastRateAllocator(codec_)); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->RegisterEncodeCompleteCallback(this); } @@ -491,7 +494,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, Reinit) { SetupCodec(); EXPECT_EQ(0, adapter_->Release()); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); } TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) { @@ -557,7 +560,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) { std::vector frame_types; // Encode with three streams. - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); VerifyCodecSettings(); adapter_->SetRates(VideoEncoder::RateControlParameters( rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); @@ -585,7 +588,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) { codec_.width /= 2; codec_.height /= 2; codec_.numberOfSimulcastStreams = 2; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->SetRates(VideoEncoder::RateControlParameters( rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); std::vector new_encoders = helper_->factory()->encoders(); @@ -608,7 +611,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) { codec_.width /= 2; codec_.height /= 2; codec_.numberOfSimulcastStreams = 1; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->SetRates(VideoEncoder::RateControlParameters( rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); new_encoders = helper_->factory()->encoders(); @@ -626,7 +629,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) { codec_.width *= 4; codec_.height *= 4; codec_.numberOfSimulcastStreams = 3; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->SetRates(VideoEncoder::RateControlParameters( rate_allocator_->GetAllocation(target_bitrate, 30), 30.0)); new_encoders = helper_->factory()->encoders(); @@ -680,7 +683,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) { // Reinitialize and verify that the new codec settings are the same. EXPECT_EQ(0, adapter_->Release()); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); for (int i = 0; i < 3; ++i) { const VideoCodec& codec_before = codecs_before[i]; const VideoCodec& codec_after = encoders[i]->codec(); @@ -735,7 +738,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) { // Reinitialize. EXPECT_EQ(0, adapter_->Release()); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->SetRates(VideoEncoder::RateControlParameters( rate_allocator_->GetAllocation(1200, 30), 30.0)); @@ -758,14 +761,14 @@ TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) { &codec_, static_cast(kTestTemporalLayerProfile), kVideoCodecVP8); codec_.numberOfSimulcastStreams = 1; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); 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_EQ(0, adapter_->InitEncode(&codec_, kSettings)); 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_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle); } @@ -775,7 +778,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) { kVideoCodecVP8); codec_.minBitrate = 50; codec_.numberOfSimulcastStreams = 1; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); rate_allocator_.reset(new SimulcastRateAllocator(codec_)); // Above min should be respected. @@ -811,14 +814,14 @@ TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) { encoder_names.push_back("codec2"); encoder_names.push_back("codec3"); helper_->factory()->SetEncoderNames(encoder_names); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)", adapter_->GetEncoderInfo().implementation_name); // Single streams should not expose "SimulcastEncoderAdapter" in name. EXPECT_EQ(0, adapter_->Release()); codec_.numberOfSimulcastStreams = 1; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->RegisterEncodeCompleteCallback(this); ASSERT_EQ(1u, helper_->factory()->encoders().size()); EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name); @@ -830,7 +833,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, &codec_, static_cast(kTestTemporalLayerProfile), kVideoCodecVP8); codec_.numberOfSimulcastStreams = 3; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->RegisterEncodeCompleteCallback(this); ASSERT_EQ(3u, helper_->factory()->encoders().size()); for (MockVideoEncoder* encoder : helper_->factory()->encoders()) @@ -840,7 +843,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_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle); } @@ -872,12 +875,12 @@ TEST_F(TestSimulcastEncoderAdapterFake, codec_.numberOfSimulcastStreams = 3; // High start bitrate, so all streams are enabled. codec_.startBitrate = 3000; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->RegisterEncodeCompleteCallback(this); 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_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle); rtc::scoped_refptr buffer( @@ -901,7 +904,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) { &codec_, static_cast(kTestTemporalLayerProfile), kVideoCodecVP8); codec_.numberOfSimulcastStreams = 3; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->RegisterEncodeCompleteCallback(this); ASSERT_EQ(3u, helper_->factory()->encoders().size()); // Tell the 2nd encoder to request software fallback. @@ -931,7 +934,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) { helper_->factory()->set_init_encode_return_value( WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE); EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE, - adapter_->InitEncode(&codec_, 1, 1200)); + adapter_->InitEncode(&codec_, kSettings)); EXPECT_TRUE(helper_->factory()->encoders().empty()); } @@ -946,7 +949,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) { codec_.simulcastStream[0].qpMax = kHighMaxQp; codec_.mode = VideoCodecMode::kScreensharing; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_EQ(3u, helper_->factory()->encoders().size()); // Just check the lowest stream, which is the one that where the adapter @@ -961,7 +964,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) { // Change the max qp and try again. codec_.simulcastStream[0].qpMax = kLowMaxQp; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_EQ(3u, helper_->factory()->encoders().size()); ref_codec.qpMax = kLowMaxQp; VerifyCodec(ref_codec, 0); @@ -979,7 +982,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, codec_.simulcastStream[2].qpMax = kHighMaxQp; codec_.mode = VideoCodecMode::kScreensharing; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_EQ(3u, helper_->factory()->encoders().size()); // Just check the lowest stream, which is the one that where the adapter @@ -994,7 +997,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, // Change the max qp and try again. codec_.simulcastStream[2].qpMax = kLowMaxQp; - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_EQ(3u, helper_->factory()->encoders().size()); ref_codec.qpMax = kLowMaxQp; VerifyCodec(ref_codec, 2); @@ -1023,7 +1026,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) { .build(); // Encode with three streams. - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); std::vector original_encoders = helper_->factory()->encoders(); ASSERT_EQ(3u, original_encoders.size()); @@ -1061,7 +1064,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) { .build(); // No encoder trusted, so simulcast adapter should not be either. - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller); // Encode with three streams. @@ -1072,18 +1075,18 @@ TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) { original_encoders[0]->set_has_trusted_rate_controller(true); original_encoders[1]->set_has_trusted_rate_controller(true); original_encoders[2]->set_has_trusted_rate_controller(true); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller); // One encoder not trusted, so simulcast adapter should not be either. original_encoders[2]->set_has_trusted_rate_controller(false); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller); // No encoder trusted, so simulcast adapter should not be either. original_encoders[0]->set_has_trusted_rate_controller(false); original_encoders[1]->set_has_trusted_rate_controller(false); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller); } @@ -1093,19 +1096,19 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsHardwareAccelerated) { kVideoCodecVP8); codec_.numberOfSimulcastStreams = 3; adapter_->RegisterEncodeCompleteCallback(this); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); ASSERT_EQ(3u, helper_->factory()->encoders().size()); // None of the encoders uses HW support, so simulcast adapter reports false. for (MockVideoEncoder* encoder : helper_->factory()->encoders()) { encoder->set_is_hardware_accelerated(false); } - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated); // One encoder uses HW support, so simulcast adapter reports true. helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated); } @@ -1115,19 +1118,19 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) { kVideoCodecVP8); codec_.numberOfSimulcastStreams = 3; adapter_->RegisterEncodeCompleteCallback(this); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); ASSERT_EQ(3u, helper_->factory()->encoders().size()); // All encoders have internal source, simulcast adapter reports true. for (MockVideoEncoder* encoder : helper_->factory()->encoders()) { encoder->set_has_internal_source(true); } - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source); // One encoder does not have internal source, simulcast adapter reports false. helper_->factory()->encoders()[2]->set_has_internal_source(false); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source); } @@ -1137,7 +1140,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) { kVideoCodecVP8); codec_.numberOfSimulcastStreams = 3; adapter_->RegisterEncodeCompleteCallback(this); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); ASSERT_EQ(3u, helper_->factory()->encoders().size()); // Combination of three different supported mode: @@ -1155,7 +1158,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) { MockVideoEncoder* encoder = helper_->factory()->encoders()[i]; encoder->set_fps_allocation(expected_fps_allocation[i]); } - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); EXPECT_THAT(adapter_->GetEncoderInfo().fps_allocation, ::testing::ElementsAreArray(expected_fps_allocation)); } @@ -1172,7 +1175,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) { const DataRate bandwidth_allocation = target_bitrate + DataRate::kbps(600); rate_allocator_.reset(new SimulcastRateAllocator(codec_)); - EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings)); adapter_->RegisterEncodeCompleteCallback(this); // Set bitrates so that we send all layers. diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index ae366d66cd..d650f3ae94 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -1895,7 +1895,9 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec( } } - parameters_.config.rtp.lntf.enabled = HasLntf(codec_settings.codec); + const bool has_lntf = HasLntf(codec_settings.codec); + parameters_.config.rtp.lntf.enabled = has_lntf; + parameters_.config.encoder_settings.capabilities.loss_notification = has_lntf; parameters_.config.rtp.nack.rtp_history_ms = HasNack(codec_settings.codec) ? kNackHistoryMs : 0; diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/modules/video_coding/codecs/h264/h264_encoder_impl.cc index 2fc1ca94a1..1cf9daded3 100644 --- a/modules/video_coding/codecs/h264/h264_encoder_impl.cc +++ b/modules/video_coding/codecs/h264/h264_encoder_impl.cc @@ -191,8 +191,7 @@ H264EncoderImpl::~H264EncoderImpl() { } int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst, - int32_t number_of_cores, - size_t max_payload_size) { + const VideoEncoder::Settings& settings) { ReportInit(); if (!inst || inst->codecType != kVideoCodecH264) { ReportError(); @@ -226,8 +225,8 @@ int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst, pictures_.resize(number_of_streams); configurations_.resize(number_of_streams); - number_of_cores_ = number_of_cores; - max_payload_size_ = max_payload_size; + number_of_cores_ = settings.number_of_cores; + max_payload_size_ = settings.max_payload_size; codec_ = *inst; // Code expects simulcastStream resolutions to be correct, make sure they are diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.h b/modules/video_coding/codecs/h264/h264_encoder_impl.h index 09ca367073..6097388030 100644 --- a/modules/video_coding/codecs/h264/h264_encoder_impl.h +++ b/modules/video_coding/codecs/h264/h264_encoder_impl.h @@ -25,6 +25,7 @@ #include #include "api/video/i420_buffer.h" +#include "api/video_codecs/video_encoder.h" #include "common_video/h264/h264_bitstream_parser.h" #include "modules/video_coding/codecs/h264/include/h264.h" #include "modules/video_coding/utility/quality_scaler.h" @@ -56,7 +57,7 @@ class H264EncoderImpl : public H264Encoder { explicit H264EncoderImpl(const cricket::VideoCodec& codec); ~H264EncoderImpl() override; - // |max_payload_size| is ignored. + // |settings.max_payload_size| is ignored. // The following members of |codec_settings| are used. The rest are ignored. // - codecType (must be kVideoCodecH264) // - targetBitrate @@ -64,8 +65,7 @@ class H264EncoderImpl : public H264Encoder { // - width // - height int32_t InitEncode(const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) override; + const VideoEncoder::Settings& settings) override; int32_t Release() override; int32_t RegisterEncodeCompleteCallback( diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl_unittest.cc b/modules/video_coding/codecs/h264/h264_encoder_impl_unittest.cc index b8b10aef2a..e81c15736b 100644 --- a/modules/video_coding/codecs/h264/h264_encoder_impl_unittest.cc +++ b/modules/video_coding/codecs/h264/h264_encoder_impl_unittest.cc @@ -11,6 +11,7 @@ #include "modules/video_coding/codecs/h264/h264_encoder_impl.h" +#include "api/video_codecs/video_encoder.h" #include "test/gtest.h" namespace webrtc { @@ -20,6 +21,11 @@ namespace { const int kMaxPayloadSize = 1024; const int kNumCores = 1; +const VideoEncoder::Capabilities kCapabilities(false); +const VideoEncoder::Settings kSettings(kCapabilities, + kNumCores, + kMaxPayloadSize); + void SetDefaultSettings(VideoCodec* codec_settings) { codec_settings->codecType = kVideoCodecH264; codec_settings->maxFramerate = 60; @@ -37,7 +43,7 @@ TEST(H264EncoderImplTest, CanInitializeWithDefaultParameters) { VideoCodec codec_settings; SetDefaultSettings(&codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize)); + encoder.InitEncode(&codec_settings, kSettings)); EXPECT_EQ(H264PacketizationMode::NonInterleaved, encoder.PacketizationModeForTesting()); } @@ -49,7 +55,7 @@ TEST(H264EncoderImplTest, CanInitializeWithNonInterleavedModeExplicitly) { VideoCodec codec_settings; SetDefaultSettings(&codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize)); + encoder.InitEncode(&codec_settings, kSettings)); EXPECT_EQ(H264PacketizationMode::NonInterleaved, encoder.PacketizationModeForTesting()); } @@ -61,7 +67,7 @@ TEST(H264EncoderImplTest, CanInitializeWithSingleNalUnitModeExplicitly) { VideoCodec codec_settings; SetDefaultSettings(&codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize)); + encoder.InitEncode(&codec_settings, kSettings)); EXPECT_EQ(H264PacketizationMode::SingleNalUnit, encoder.PacketizationModeForTesting()); } @@ -73,7 +79,7 @@ TEST(H264EncoderImplTest, CanInitializeWithRemovedParameter) { VideoCodec codec_settings; SetDefaultSettings(&codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize)); + encoder.InitEncode(&codec_settings, kSettings)); EXPECT_EQ(H264PacketizationMode::SingleNalUnit, encoder.PacketizationModeForTesting()); } diff --git a/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h b/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h index bb00b542e1..9c17ba4c83 100644 --- a/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h +++ b/modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h @@ -40,8 +40,7 @@ class MultiplexEncoderAdapter : public VideoEncoder { // Implements VideoEncoder int InitEncode(const VideoCodec* inst, - int number_of_cores, - size_t max_payload_size) override; + const VideoEncoder::Settings& settings) override; int Encode(const VideoFrame& input_image, const std::vector* frame_types) override; int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override; diff --git a/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc b/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc index 8c866995f4..59d59c1efd 100644 --- a/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc +++ b/modules/video_coding/codecs/multiplex/multiplex_encoder_adapter.cc @@ -13,6 +13,7 @@ #include #include "api/video/encoded_image.h" +#include "api/video_codecs/video_encoder.h" #include "common_video/include/video_frame_buffer.h" #include "common_video/libyuv/include/webrtc_libyuv.h" #include "modules/include/module_common_types.h" @@ -60,9 +61,9 @@ MultiplexEncoderAdapter::~MultiplexEncoderAdapter() { Release(); } -int MultiplexEncoderAdapter::InitEncode(const VideoCodec* inst, - int number_of_cores, - size_t max_payload_size) { +int MultiplexEncoderAdapter::InitEncode( + const VideoCodec* inst, + const VideoEncoder::Settings& settings) { const size_t buffer_size = CalcBufferSize(VideoType::kI420, inst->width, inst->height); multiplex_dummy_planes_.resize(buffer_size); @@ -71,23 +72,23 @@ int MultiplexEncoderAdapter::InitEncode(const VideoCodec* inst, 0x80); RTC_DCHECK_EQ(kVideoCodecMultiplex, inst->codecType); - VideoCodec settings = *inst; - settings.codecType = PayloadStringToCodecType(associated_format_.name); + VideoCodec video_codec = *inst; + video_codec.codecType = PayloadStringToCodecType(associated_format_.name); // Take over the key frame interval at adapter level, because we have to // sync the key frames for both sub-encoders. - switch (settings.codecType) { + switch (video_codec.codecType) { case kVideoCodecVP8: - key_frame_interval_ = settings.VP8()->keyFrameInterval; - settings.VP8()->keyFrameInterval = 0; + key_frame_interval_ = video_codec.VP8()->keyFrameInterval; + video_codec.VP8()->keyFrameInterval = 0; break; case kVideoCodecVP9: - key_frame_interval_ = settings.VP9()->keyFrameInterval; - settings.VP9()->keyFrameInterval = 0; + key_frame_interval_ = video_codec.VP9()->keyFrameInterval; + video_codec.VP9()->keyFrameInterval = 0; break; case kVideoCodecH264: - key_frame_interval_ = settings.H264()->keyFrameInterval; - settings.H264()->keyFrameInterval = 0; + key_frame_interval_ = video_codec.H264()->keyFrameInterval; + video_codec.H264()->keyFrameInterval = 0; break; default: break; @@ -101,8 +102,7 @@ int MultiplexEncoderAdapter::InitEncode(const VideoCodec* inst, for (size_t i = 0; i < kAlphaCodecStreams; ++i) { std::unique_ptr encoder = factory_->CreateVideoEncoder(associated_format_); - const int rv = - encoder->InitEncode(&settings, number_of_cores, max_payload_size); + const int rv = encoder->InitEncode(&video_codec, settings); if (rv) { RTC_LOG(LS_ERROR) << "Failed to create multiplex codec index " << i; return rv; diff --git a/modules/video_coding/codecs/test/video_codec_unittest.cc b/modules/video_coding/codecs/test/video_codec_unittest.cc index b9a911f58c..bb83903374 100644 --- a/modules/video_coding/codecs/test/video_codec_unittest.cc +++ b/modules/video_coding/codecs/test/video_codec_unittest.cc @@ -10,6 +10,7 @@ #include +#include "api/video_codecs/video_encoder.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/video_coding/codecs/test/video_codec_unittest.h" #include "modules/video_coding/include/video_error_codes.h" @@ -25,6 +26,9 @@ static const int kHeight = 144; // Height of the input image. static const int kMaxFramerate = 30; // Arbitrary value. namespace webrtc { +namespace { +const VideoEncoder::Capabilities kCapabilities(false); +} EncodedImageCallback::Result VideoCodecUnitTest::FakeEncodeCompleteCallback::OnEncodedImage( @@ -78,8 +82,10 @@ void VideoCodecUnitTest::SetUp() { decoder_->RegisterDecodeCompleteCallback(&decode_complete_callback_); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode( + &codec_settings_, + VideoEncoder::Settings(kCapabilities, 1 /* number of cores */, + 0 /* max payload size (unused) */))); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->InitDecode(&codec_settings_, 1 /* number of cores */)); } diff --git a/modules/video_coding/codecs/test/video_encoder_decoder_instantiation_tests.cc b/modules/video_coding/codecs/test/video_encoder_decoder_instantiation_tests.cc index 6fc898dcac..e5cce13f54 100644 --- a/modules/video_coding/codecs/test/video_encoder_decoder_instantiation_tests.cc +++ b/modules/video_coding/codecs/test/video_encoder_decoder_instantiation_tests.cc @@ -28,6 +28,7 @@ namespace webrtc { namespace test { namespace { +const VideoEncoder::Capabilities kCapabilities(false); int32_t InitEncoder(VideoCodecType codec_type, VideoEncoder* encoder) { VideoCodec codec; @@ -36,8 +37,9 @@ int32_t InitEncoder(VideoCodecType codec_type, VideoEncoder* encoder) { codec.height = 480; codec.maxFramerate = 30; RTC_CHECK(encoder); - return encoder->InitEncode(&codec, 1 /* number_of_cores */, - 1200 /* max_payload_size */); + return encoder->InitEncode( + &codec, VideoEncoder::Settings(kCapabilities, 1 /* number_of_cores */, + 1200 /* max_payload_size */)); } int32_t InitDecoder(VideoCodecType codec_type, VideoDecoder* decoder) { diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc index c05729a245..d0db13983f 100644 --- a/modules/video_coding/codecs/test/videoprocessor.cc +++ b/modules/video_coding/codecs/test/videoprocessor.cc @@ -24,6 +24,7 @@ #include "api/video/video_frame_buffer.h" #include "api/video/video_rotation.h" #include "api/video_codecs/video_codec.h" +#include "api/video_codecs/video_encoder.h" #include "common_video/h264/h264_common.h" #include "common_video/libyuv/include/webrtc_libyuv.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" @@ -45,6 +46,8 @@ namespace { const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000; const int kMaxBufferedInputFrames = 20; +const VideoEncoder::Capabilities kCapabilities(false); + size_t GetMaxNaluSizeBytes(const EncodedImage& encoded_frame, const VideoCodecTestFixture::Config& config) { if (config.codec_settings.codecType != kVideoCodecH264) @@ -207,9 +210,11 @@ VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder, WEBRTC_VIDEO_CODEC_OK); // Initialize codecs so that they are ready to receive frames. - RTC_CHECK_EQ(encoder_->InitEncode(&config_.codec_settings, - static_cast(config_.NumberOfCores()), - config_.max_payload_size_bytes), + RTC_CHECK_EQ(encoder_->InitEncode( + &config_.codec_settings, + VideoEncoder::Settings( + kCapabilities, static_cast(config_.NumberOfCores()), + config_.max_payload_size_bytes)), WEBRTC_VIDEO_CODEC_OK); for (size_t i = 0; i < num_simulcast_or_spatial_layers_; ++i) { diff --git a/modules/video_coding/codecs/test/videoprocessor_unittest.cc b/modules/video_coding/codecs/test/videoprocessor_unittest.cc index de1d798f1c..d2b71a7ac6 100644 --- a/modules/video_coding/codecs/test/videoprocessor_unittest.cc +++ b/modules/video_coding/codecs/test/videoprocessor_unittest.cc @@ -66,7 +66,7 @@ class VideoProcessorTest : public ::testing::Test { } void ExpectInit() { - EXPECT_CALL(encoder_mock_, InitEncode(_, _, _)).Times(1); + EXPECT_CALL(encoder_mock_, InitEncode(_, _)).Times(1); EXPECT_CALL(encoder_mock_, RegisterEncodeCompleteCallback(_)).Times(1); EXPECT_CALL(*decoder_mock_, InitDecode(_, _)).Times(1); EXPECT_CALL(*decoder_mock_, RegisterDecodeCompleteCallback(_)).Times(1); diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index f740b80b3d..06cf870944 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -450,9 +450,10 @@ void LibvpxVp8Encoder::SetStreamState(bool send_stream, int stream_idx) { send_stream_[stream_idx] = send_stream; } +// TODO(eladalon): s/inst/codec_settings/g. +// TODO(bugs.webrtc.org/10720): Pass |capabilities| to frame buffer controller. int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, - int number_of_cores, - size_t /*maxPayloadSize */) { + const VideoEncoder::Settings& settings) { if (inst == NULL) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } @@ -466,7 +467,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, if (inst->width < 1 || inst->height < 1) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } - if (number_of_cores < 1) { + if (settings.number_of_cores < 1) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } if (inst->VP8().automaticResizeOn && inst->numberOfSimulcastStreams > 1) { @@ -492,7 +493,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, } RTC_DCHECK(frame_buffer_controller_); - number_of_cores_ = number_of_cores; + number_of_cores_ = settings.number_of_cores; timestamp_ = 0; codec_ = *inst; @@ -611,7 +612,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, // Determine number of threads based on the image size and #cores. // TODO(fbarchard): Consider number of Simulcast layers. vpx_configs_[0].g_threads = NumberOfThreads( - vpx_configs_[0].g_w, vpx_configs_[0].g_h, number_of_cores); + vpx_configs_[0].g_w, vpx_configs_[0].g_h, settings.number_of_cores); // Creating a wrapper to the image - setting image data to NULL. // Actual pointer will be set in encode. Setting align to 1, as it diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h index 214b969d3a..90532073d9 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h @@ -46,8 +46,7 @@ class LibvpxVp8Encoder : public VideoEncoder { int Release() override; int InitEncode(const VideoCodec* codec_settings, - int number_of_cores, - size_t max_payload_size) override; + const VideoEncoder::Settings& settings) override; int Encode(const VideoFrame& input_image, const std::vector* frame_types) override; diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc index eb6b89fe8e..b5e11f4fcb 100644 --- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc +++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc @@ -14,6 +14,7 @@ #include "api/test/mock_video_decoder.h" #include "api/test/mock_video_encoder.h" +#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/vp8_temporal_layers.h" #include "common_video/libyuv/include/webrtc_libyuv.h" #include "common_video/test/utilities.h" @@ -51,6 +52,11 @@ constexpr int kDefaultMinPixelsPerFrame = 320 * 180; constexpr int kWidth = 172; constexpr int kHeight = 144; constexpr float kFramerateFps = 30; + +const VideoEncoder::Capabilities kCapabilities(false); +const VideoEncoder::Settings kSettings(kCapabilities, + kNumCores, + kMaxPayloadSize); } // namespace class TestVp8Impl : public VideoCodecUnitTest { @@ -117,7 +123,8 @@ TEST_F(TestVp8Impl, SetRates) { auto* const vpx = new NiceMock(); LibvpxVp8Encoder encoder((std::unique_ptr(vpx))); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder.InitEncode(&codec_settings_, 1, 1000)); + encoder.InitEncode(&codec_settings_, + VideoEncoder::Settings(kCapabilities, 1, 1000))); const uint32_t kBitrateBps = 300000; VideoBitrateAllocation bitrate_allocation; @@ -143,7 +150,8 @@ TEST_F(TestVp8Impl, DynamicSetRates) { auto* const vpx = new NiceMock(); LibvpxVp8Encoder encoder((std::unique_ptr(vpx))); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder.InitEncode(&codec_settings_, 1, 1000)); + encoder.InitEncode(&codec_settings_, + VideoEncoder::Settings(kCapabilities, 1, 1000))); const uint32_t kBitrateBps = 300000; VideoEncoder::RateControlParameters rate_settings; @@ -199,7 +207,7 @@ TEST_F(TestVp8Impl, DynamicSetRates) { TEST_F(TestVp8Impl, EncodeFrameAndRelease) { EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); EncodedImage encoded_frame; CodecSpecificInfo codec_specific_info; @@ -257,7 +265,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) { codec_settings_.simulcastStream[1] = {kWidth / 2, kHeight / 2, 30, 3, 4000, 3000, 2000, 80}; EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); codec_settings_.numberOfSimulcastStreams = 3; // Resolutions are not in ascending order. codec_settings_.simulcastStream[0] = { @@ -267,7 +275,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) { codec_settings_.simulcastStream[2] = {kWidth, kHeight, 30, 1, 4000, 3000, 2000, 80}; EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Resolutions are not in ascending order. codec_settings_.simulcastStream[0] = {kWidth, kHeight, kFramerateFps, 1, 4000, 3000, 2000, 80}; @@ -276,7 +284,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) { codec_settings_.simulcastStream[2] = { kWidth - 1, kHeight - 1, kFramerateFps, 1, 4000, 3000, 2000, 80}; EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Temporal layers do not match. codec_settings_.simulcastStream[0] = { kWidth / 4, kHeight / 4, kFramerateFps, 1, 4000, 3000, 2000, 80}; @@ -285,7 +293,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) { codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 3, 4000, 3000, 2000, 80}; EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Resolutions do not match codec config. codec_settings_.simulcastStream[0] = { kWidth / 4 + 1, kHeight / 4 + 1, kFramerateFps, 1, 4000, 3000, 2000, 80}; @@ -294,7 +302,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) { codec_settings_.simulcastStream[2] = { kWidth + 4, kHeight + 4, kFramerateFps, 1, 4000, 3000, 2000, 80}; EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Everything fine: scaling by 2, top resolution matches video, temporal // settings are the same for all layers. codec_settings_.simulcastStream[0] = { @@ -304,7 +312,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) { codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 1, 4000, 3000, 2000, 80}; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Everything fine: custom scaling, top resolution matches video, temporal // settings are the same for all layers. codec_settings_.simulcastStream[0] = { @@ -314,7 +322,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) { codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 1, 4000, 3000, 2000, 80}; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); } #if defined(WEBRTC_ANDROID) @@ -378,7 +386,7 @@ TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) { TEST_F(TestVp8Impl, EncoderWith2TemporalLayers) { codec_settings_.VP8()->numberOfTemporalLayers = 2; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Temporal layer 0. EncodedImage encoded_frame; @@ -399,7 +407,7 @@ TEST_F(TestVp8Impl, ScalingDisabledIfAutomaticResizeOff) { codec_settings_.VP8()->frameDroppingOn = true; codec_settings_.VP8()->automaticResizeOn = false; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoEncoder::ScalingSettings settings = encoder_->GetEncoderInfo().scaling_settings; @@ -410,7 +418,7 @@ TEST_F(TestVp8Impl, ScalingEnabledIfAutomaticResizeOn) { codec_settings_.VP8()->frameDroppingOn = true; codec_settings_.VP8()->automaticResizeOn = true; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoEncoder::ScalingSettings settings = encoder_->GetEncoderInfo().scaling_settings; @@ -442,7 +450,7 @@ TEST_F(TestVp8Impl, DontDropKeyframes) { /* num_squares = */ absl::optional(300)); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoBitrateAllocation bitrate_allocation; // Bitrate only enough for TL0. @@ -480,7 +488,8 @@ TEST_F(TestVp8Impl, KeepsTimestampOnReencode) { return img; })); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder.InitEncode(&codec_settings_, 1, 1000)); + encoder.InitEncode(&codec_settings_, + VideoEncoder::Settings(kCapabilities, 1, 1000))); MockEncodedImageCallback callback; encoder.RegisterEncodeCompleteCallback(&callback); @@ -512,7 +521,7 @@ TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationTwoTemporalLayers) { codec_settings_.simulcastStream[0].maxBitrate = 100; codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); FramerateFractions expected_fps_allocation[kMaxSpatialLayers]; expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 2); @@ -530,7 +539,7 @@ TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationThreeTemporalLayers) { codec_settings_.simulcastStream[0].maxBitrate = 100; codec_settings_.simulcastStream[0].numberOfTemporalLayers = 3; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); FramerateFractions expected_fps_allocation[kMaxSpatialLayers]; expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4); @@ -553,7 +562,7 @@ TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationScreenshareLayers) { kLegacyScreenshareTl1BitrateKbps; codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Expect empty vector, since this mode doesn't have a fixed framerate. FramerateFractions expected_fps_allocation[kMaxSpatialLayers]; @@ -581,7 +590,7 @@ TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationSimulcastVideo) { } EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); + encoder_->InitEncode(&codec_settings_, kSettings)); FramerateFractions expected_fps_allocation[kMaxSpatialLayers]; expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4); diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc index d8062390dc..ae509a65ec 100644 --- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc +++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc @@ -10,6 +10,7 @@ #include "api/video/color_space.h" #include "api/video/i420_buffer.h" +#include "api/video_codecs/video_encoder.h" #include "common_video/libyuv/include/webrtc_libyuv.h" #include "media/base/vp9_profile.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" @@ -31,6 +32,11 @@ using FramerateFractions = namespace { const size_t kWidth = 1280; const size_t kHeight = 720; + +const VideoEncoder::Capabilities kCapabilities(false); +const VideoEncoder::Settings kSettings(kCapabilities, + /*number_of_cores=*/1, + /*max_payload_size=*/0); } // namespace class TestVp9Impl : public VideoCodecUnitTest { @@ -199,8 +205,7 @@ TEST_F(TestVp9Impl, EncoderWith2TemporalLayers) { // Tl0PidIdx is only used in non-flexible mode. codec_settings_.VP9()->flexibleMode = false; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Temporal layer 0. EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, @@ -229,8 +234,7 @@ TEST_F(TestVp9Impl, EncoderWith2TemporalLayers) { TEST_F(TestVp9Impl, EncoderWith2SpatialLayers) { codec_settings_.VP9()->numberOfSpatialLayers = 2; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); SetWaitForEncodedFramesThreshold(2); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, @@ -273,8 +277,7 @@ TEST_F(TestVp9Impl, EncoderExplicitLayering) { codec_settings_.spatialLayers[1].maxFramerate = codec_settings_.maxFramerate; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Ensure it fails if scaling factors in horz/vert dimentions are different. codec_settings_.spatialLayers[0].width = codec_settings_.width; @@ -282,8 +285,7 @@ TEST_F(TestVp9Impl, EncoderExplicitLayering) { codec_settings_.spatialLayers[1].width = codec_settings_.width; codec_settings_.spatialLayers[1].height = codec_settings_.height; EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_PARAMETER, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Ensure it fails if scaling factor is not power of two. codec_settings_.spatialLayers[0].width = codec_settings_.width / 3; @@ -291,8 +293,7 @@ TEST_F(TestVp9Impl, EncoderExplicitLayering) { codec_settings_.spatialLayers[1].width = codec_settings_.width; codec_settings_.spatialLayers[1].height = codec_settings_.height; EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_PARAMETER, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); } TEST_F(TestVp9Impl, EnableDisableSpatialLayers) { @@ -309,8 +310,7 @@ TEST_F(TestVp9Impl, EnableDisableSpatialLayers) { codec_settings_.VP9()->frameDroppingOn = true; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoBitrateAllocation bitrate_allocation; for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { @@ -357,8 +357,7 @@ TEST_F(TestVp9Impl, EndOfPicture) { ConfigureSvc(num_spatial_layers); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Encode both base and upper layers. Check that end-of-superframe flag is // set on upper layer frame but not on base layer frame. @@ -385,8 +384,7 @@ TEST_F(TestVp9Impl, EndOfPicture) { encoder_->SetRates(VideoEncoder::RateControlParameters( bitrate_allocation, codec_settings_.maxFramerate)); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); SetWaitForEncodedFramesThreshold(1); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, @@ -415,8 +413,7 @@ TEST_F(TestVp9Impl, InterLayerPred) { for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) { codec_settings_.VP9()->interLayerPred = inter_layer_pred; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); encoder_->SetRates(VideoEncoder::RateControlParameters( bitrate_allocation, codec_settings_.maxFramerate)); @@ -485,8 +482,7 @@ TEST_F(TestVp9Impl, for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) { codec_settings_.VP9()->interLayerPred = inter_layer_pred; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoBitrateAllocation bitrate_allocation; for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { @@ -544,8 +540,7 @@ TEST_F(TestVp9Impl, for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) { codec_settings_.VP9()->interLayerPred = inter_layer_pred; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoBitrateAllocation bitrate_allocation; for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { @@ -595,8 +590,7 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerInTheSameGof) { codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoBitrateAllocation bitrate_allocation; @@ -670,8 +664,7 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerAccrossGof) { codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoBitrateAllocation bitrate_allocation; @@ -761,8 +754,7 @@ TEST_F(TestVp9Impl, EnablingNewLayerIsDelayedInScreenshareAndAddsSsInfo) { codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn; codec_settings_.VP9()->flexibleMode = true; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Enable all but the last layer. VideoBitrateAllocation bitrate_allocation; @@ -830,8 +822,7 @@ TEST_F(TestVp9Impl, ScreenshareFrameDropping) { codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn; codec_settings_.VP9()->flexibleMode = true; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Enable all but the last layer. VideoBitrateAllocation bitrate_allocation; @@ -924,8 +915,7 @@ TEST_F(TestVp9Impl, RemovingLayerIsNotDelayedInScreenshareAndAddsSsInfo) { codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn; codec_settings_.VP9()->flexibleMode = true; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); // All layers are enabled from the start. VideoBitrateAllocation bitrate_allocation; @@ -1007,8 +997,7 @@ TEST_F(TestVp9Impl, DisableNewLayerInVideoDelaysSsInfoTillTL0) { codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOnKeyPic; codec_settings_.VP9()->flexibleMode = false; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); // Enable all the layers. VideoBitrateAllocation bitrate_allocation; @@ -1069,8 +1058,7 @@ TEST_F(TestVp9Impl, codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoBitrateAllocation bitrate_allocation; bitrate_allocation.SetBitrate( @@ -1089,8 +1077,7 @@ TEST_F(TestVp9Impl, TEST_F(TestVp9Impl, ScalabilityStructureIsAvailableInFlexibleMode) { codec_settings_.VP9()->flexibleMode = true; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(*NextInputFrame(), nullptr)); @@ -1123,8 +1110,7 @@ TEST_F(TestVp9Impl, EncoderInfoFpsAllocation) { } EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); FramerateFractions expected_fps_allocation[kMaxSpatialLayers]; expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4); @@ -1161,8 +1147,7 @@ TEST_F(TestVp9Impl, EncoderInfoFpsAllocationFlexibleMode) { } EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); // No temporal layers allowed when spatial layers have different fps targets. FramerateFractions expected_fps_allocation[kMaxSpatialLayers]; @@ -1195,8 +1180,7 @@ TEST_P(TestVp9ImplWithLayering, FlexibleMode) { codec_settings_.VP9()->numberOfSpatialLayers = num_spatial_layers_; codec_settings_.VP9()->numberOfTemporalLayers = num_temporal_layers_; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); GofInfoVP9 gof; if (num_temporal_layers_ == 1) { @@ -1234,8 +1218,7 @@ TEST_P(TestVp9ImplWithLayering, ExternalRefControl) { codec_settings_.VP9()->numberOfSpatialLayers = num_spatial_layers_; codec_settings_.VP9()->numberOfTemporalLayers = num_temporal_layers_; EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); GofInfoVP9 gof; if (num_temporal_layers_ == 1) { @@ -1291,8 +1274,7 @@ TEST_F(TestVp9ImplFrameDropping, PreEncodeFrameDropping) { codec_settings_.maxFramerate = static_cast(expected_framerate_fps); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); VideoFrame* input_frame = NextInputFrame(); for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) { @@ -1341,8 +1323,7 @@ TEST_F(TestVp9ImplFrameDropping, DifferentFrameratePerSpatialLayer) { } EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, - encoder_->InitEncode(&codec_settings_, 1 /* number of cores */, - 0 /* max payload size (unused) */)); + encoder_->InitEncode(&codec_settings_, kSettings)); encoder_->SetRates(VideoEncoder::RateControlParameters( bitrate_allocation, codec_settings_.maxFramerate)); diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc index 18acf02a04..d81c615a09 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -401,9 +401,9 @@ void VP9EncoderImpl::SetRates(const RateControlParameters& parameters) { return; } +// TODO(eladalon): s/inst/codec_settings/g. int VP9EncoderImpl::InitEncode(const VideoCodec* inst, - int number_of_cores, - size_t /*max_payload_size*/) { + const Settings& settings) { if (inst == nullptr) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } @@ -417,7 +417,7 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst, if (inst->width < 1 || inst->height < 1) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } - if (number_of_cores < 1) { + if (settings.number_of_cores < 1) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } if (inst->VP9().numberOfTemporalLayers > 3) { @@ -526,7 +526,7 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst, config_->rc_resize_allowed = inst->VP9().automaticResizeOn ? 1 : 0; // Determine number of threads based on the image size and #cores. config_->g_threads = - NumberOfThreads(config_->g_w, config_->g_h, number_of_cores); + NumberOfThreads(config_->g_w, config_->g_h, settings.number_of_cores); cpu_speed_ = GetCpuSpeed(config_->g_w, config_->g_h); diff --git a/modules/video_coding/codecs/vp9/vp9_impl.h b/modules/video_coding/codecs/vp9/vp9_impl.h index f58fc34df0..7ceb69970b 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.h +++ b/modules/video_coding/codecs/vp9/vp9_impl.h @@ -21,6 +21,7 @@ #include "modules/video_coding/codecs/vp9/include/vp9.h" +#include "api/video_codecs/video_encoder.h" #include "media/base/vp9_profile.h" #include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h" #include "modules/video_coding/utility/framerate_controller.h" @@ -40,8 +41,7 @@ class VP9EncoderImpl : public VP9Encoder { int Release() override; int InitEncode(const VideoCodec* codec_settings, - int number_of_cores, - size_t max_payload_size) override; + const Settings& settings) override; int Encode(const VideoFrame& input_image, const std::vector* frame_types) override; diff --git a/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/modules/video_coding/utility/simulcast_test_fixture_impl.cc index 91e55089af..eadb5a23a2 100644 --- a/modules/video_coding/utility/simulcast_test_fixture_impl.cc +++ b/modules/video_coding/utility/simulcast_test_fixture_impl.cc @@ -18,6 +18,7 @@ #include "absl/memory/memory.h" #include "api/video/encoded_image.h" #include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_encoder.h" #include "common_video/libyuv/include/webrtc_libyuv.h" #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_coding_defines.h" @@ -46,6 +47,9 @@ const int kTargetBitrates[kNumberOfSimulcastStreams] = {100, 450, 1000}; const int kDefaultTemporalLayerProfile[3] = {3, 3, 3}; const int kNoTemporalLayerProfile[3] = {0, 0, 0}; +const VideoEncoder::Capabilities kCapabilities(false); +const VideoEncoder::Settings kSettings(kCapabilities, 1, 1200); + template void SetExpectedValues3(T value0, T value1, T value2, T* expected_values) { expected_values[0] = value0; @@ -271,7 +275,7 @@ void SimulcastTestFixtureImpl::SetUpCodec(const int* temporal_layer_profile) { decoder_->RegisterDecodeCompleteCallback(&decoder_callback_); DefaultSettings(&settings_, temporal_layer_profile, codec_type_); SetUpRateAllocator(); - EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200)); + EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings)); EXPECT_EQ(0, decoder_->InitDecode(&settings_, 1)); input_buffer_ = I420Buffer::Create(kDefaultWidth, kDefaultHeight); input_buffer_->InitializeData(); @@ -323,7 +327,7 @@ void SimulcastTestFixtureImpl::UpdateActiveStreams( // allocator has support for updating active streams without a // reinitialization, we can just call that here instead. SetUpRateAllocator(); - EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200)); + EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings)); } void SimulcastTestFixtureImpl::ExpectStreams( @@ -617,7 +621,7 @@ void SimulcastTestFixtureImpl::SwitchingToOneStream(int width, int height) { settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].height = settings_.height; SetUpRateAllocator(); - EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200)); + EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings)); // Encode one frame and verify. SetRates(kMaxBitrates[0] + kMaxBitrates[1], 30); @@ -640,7 +644,7 @@ void SimulcastTestFixtureImpl::SwitchingToOneStream(int width, int height) { // Start at the lowest bitrate for enabling base stream. settings_.startBitrate = kMinBitrates[0]; SetUpRateAllocator(); - EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200)); + EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings)); SetRates(settings_.startBitrate, 30); ExpectStreams(VideoFrameType::kVideoFrameKey, 1); // Resize |input_frame_| to the new resolution. diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 187f885afb..8ffc959d70 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -710,6 +710,7 @@ if (is_android) { "../../rtc_base:checks", "../../rtc_base:rtc_task_queue", "../../rtc_base/task_utils:to_queued_task", + "//third_party/abseil-cpp/absl/types:optional", "//third_party/libyuv", ] } diff --git a/sdk/android/api/org/webrtc/VideoEncoder.java b/sdk/android/api/org/webrtc/VideoEncoder.java index b37f5aa507..a5b2c4dc75 100644 --- a/sdk/android/api/org/webrtc/VideoEncoder.java +++ b/sdk/android/api/org/webrtc/VideoEncoder.java @@ -28,10 +28,19 @@ public interface VideoEncoder { public final int maxFramerate; public final int numberOfSimulcastStreams; public final boolean automaticResizeOn; + public final Capabilities capabilities; + + // TODO(bugs.webrtc.org/10720): Remove. + @Deprecated + public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate, + int numberOfSimulcastStreams, boolean automaticResizeOn) { + this(numberOfCores, width, height, startBitrate, maxFramerate, numberOfSimulcastStreams, + automaticResizeOn, new VideoEncoder.Capabilities(false /* lossNotification */)); + } @CalledByNative("Settings") public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate, - int numberOfSimulcastStreams, boolean automaticResizeOn) { + int numberOfSimulcastStreams, boolean automaticResizeOn, Capabilities capabilities) { this.numberOfCores = numberOfCores; this.width = width; this.height = height; @@ -39,6 +48,21 @@ public interface VideoEncoder { this.maxFramerate = maxFramerate; this.numberOfSimulcastStreams = numberOfSimulcastStreams; this.automaticResizeOn = automaticResizeOn; + this.capabilities = capabilities; + } + } + + /** Capabilities (loss notification, etc.) passed to the encoder by WebRTC. */ + public class Capabilities { + /** + * The remote side has support for the loss notification RTCP feedback message format, and will + * be sending these feedback messages if necessary. + */ + public final boolean lossNotification; + + @CalledByNative("Capabilities") + public Capabilities(boolean lossNotification) { + this.lossNotification = lossNotification; } } diff --git a/sdk/android/instrumentationtests/src/org/webrtc/AndroidVideoDecoderInstrumentationTest.java b/sdk/android/instrumentationtests/src/org/webrtc/AndroidVideoDecoderInstrumentationTest.java index 211b93a604..723012bf81 100644 --- a/sdk/android/instrumentationtests/src/org/webrtc/AndroidVideoDecoderInstrumentationTest.java +++ b/sdk/android/instrumentationtests/src/org/webrtc/AndroidVideoDecoderInstrumentationTest.java @@ -76,7 +76,8 @@ public final class AndroidVideoDecoderInstrumentationTest { private static final boolean ENABLE_H264_HIGH_PROFILE = true; private static final VideoEncoder.Settings ENCODER_SETTINGS = new VideoEncoder.Settings(1 /* core */, TEST_FRAME_WIDTH, TEST_FRAME_HEIGHT, 300 /* kbps */, - 30 /* fps */, 1 /* numberOfSimulcastStreams */, true /* automaticResizeOn */); + 30 /* fps */, 1 /* numberOfSimulcastStreams */, true /* automaticResizeOn */, + /* capabilities= */ new VideoEncoder.Capabilities(false /* lossNotification */)); private static final int DECODE_TIMEOUT_MS = 1000; private static final VideoDecoder.Settings SETTINGS = diff --git a/sdk/android/instrumentationtests/src/org/webrtc/HardwareVideoEncoderTest.java b/sdk/android/instrumentationtests/src/org/webrtc/HardwareVideoEncoderTest.java index 8c7587868b..639c54db3c 100644 --- a/sdk/android/instrumentationtests/src/org/webrtc/HardwareVideoEncoderTest.java +++ b/sdk/android/instrumentationtests/src/org/webrtc/HardwareVideoEncoderTest.java @@ -70,7 +70,8 @@ public class HardwareVideoEncoderTest { private static final boolean ENABLE_H264_HIGH_PROFILE = true; private static final VideoEncoder.Settings SETTINGS = new VideoEncoder.Settings(1 /* core */, 640 /* width */, 480 /* height */, 300 /* kbps */, - 30 /* fps */, 1 /* numberOfSimulcastStreams */, true /* automaticResizeOn */); + 30 /* fps */, 1 /* numberOfSimulcastStreams */, true /* automaticResizeOn */, + /* capabilities= */ new VideoEncoder.Capabilities(false /* lossNotification */)); private static final int ENCODE_TIMEOUT_MS = 1000; private static final int NUM_TEST_FRAMES = 10; private static final int NUM_ENCODE_TRIES = 100; diff --git a/sdk/android/src/jni/android_media_encoder.cc b/sdk/android/src/jni/android_media_encoder.cc index 4bca01fc7e..5a5f90b609 100644 --- a/sdk/android/src/jni/android_media_encoder.cc +++ b/sdk/android/src/jni/android_media_encoder.cc @@ -97,8 +97,7 @@ class MediaCodecVideoEncoder : public VideoEncoder { // VideoEncoder implementation. int32_t InitEncode(const VideoCodec* codec_settings, - int32_t /* number_of_cores */, - size_t /* max_payload_size */) override; + const Settings& settings) override; int32_t Encode(const VideoFrame& input_image, const std::vector* frame_types) override; int32_t RegisterEncodeCompleteCallback( @@ -304,8 +303,7 @@ MediaCodecVideoEncoder::MediaCodecVideoEncoder(JNIEnv* jni, } int32_t MediaCodecVideoEncoder::InitEncode(const VideoCodec* codec_settings, - int32_t /* number_of_cores */, - size_t /* max_payload_size */) { + const Settings& settings) { RTC_DCHECK_RUN_ON(&encoder_queue_checker_); if (codec_settings == NULL) { ALOGE << "NULL VideoCodec instance"; diff --git a/sdk/android/src/jni/video_encoder_wrapper.cc b/sdk/android/src/jni/video_encoder_wrapper.cc index aac4c27a8b..e051b77e07 100644 --- a/sdk/android/src/jni/video_encoder_wrapper.cc +++ b/sdk/android/src/jni/video_encoder_wrapper.cc @@ -38,13 +38,13 @@ VideoEncoderWrapper::VideoEncoderWrapper(JNIEnv* jni, } VideoEncoderWrapper::~VideoEncoderWrapper() = default; -int32_t VideoEncoderWrapper::InitEncode(const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) { +int VideoEncoderWrapper::InitEncode(const VideoCodec* codec_settings, + const Settings& settings) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); - number_of_cores_ = number_of_cores; codec_settings_ = *codec_settings; + capabilities_ = settings.capabilities; + number_of_cores_ = settings.number_of_cores; num_resets_ = 0; { rtc::CritScope lock(&encoder_queue_crit_); @@ -69,12 +69,16 @@ int32_t VideoEncoderWrapper::InitEncodeInternal(JNIEnv* jni) { automatic_resize_on = true; } + RTC_DCHECK(capabilities_); + ScopedJavaLocalRef capabilities = + Java_Capabilities_Constructor(jni, capabilities_->loss_notification); + ScopedJavaLocalRef settings = Java_Settings_Constructor( jni, number_of_cores_, codec_settings_.width, codec_settings_.height, static_cast(codec_settings_.startBitrate), static_cast(codec_settings_.maxFramerate), static_cast(codec_settings_.numberOfSimulcastStreams), - automatic_resize_on); + automatic_resize_on, capabilities); ScopedJavaLocalRef callback = Java_VideoEncoderWrapper_createEncoderCallback(jni, diff --git a/sdk/android/src/jni/video_encoder_wrapper.h b/sdk/android/src/jni/video_encoder_wrapper.h index c1404951d1..43d1f6fff3 100644 --- a/sdk/android/src/jni/video_encoder_wrapper.h +++ b/sdk/android/src/jni/video_encoder_wrapper.h @@ -16,6 +16,7 @@ #include #include +#include "absl/types/optional.h" #include "api/task_queue/task_queue_base.h" #include "api/video_codecs/video_encoder.h" #include "common_video/h264/h264_bitstream_parser.h" @@ -33,8 +34,7 @@ class VideoEncoderWrapper : public VideoEncoder { ~VideoEncoderWrapper() override; int32_t InitEncode(const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) override; + const Settings& settings) override; int32_t RegisterEncodeCompleteCallback( EncodedImageCallback* callback) override; @@ -95,6 +95,7 @@ class VideoEncoderWrapper : public VideoEncoder { EncodedImageCallback* callback_; bool initialized_; int num_resets_; + absl::optional capabilities_; int number_of_cores_; VideoCodec codec_settings_; EncoderInfo encoder_info_; diff --git a/sdk/android/tests/src/org/webrtc/HardwareVideoEncoderTest.java b/sdk/android/tests/src/org/webrtc/HardwareVideoEncoderTest.java index 336988e0f2..a08157dc20 100644 --- a/sdk/android/tests/src/org/webrtc/HardwareVideoEncoderTest.java +++ b/sdk/android/tests/src/org/webrtc/HardwareVideoEncoderTest.java @@ -58,7 +58,8 @@ public class HardwareVideoEncoderTest { /* startBitrate= */ 10000, /* maxFramerate= */ 30, /* numberOfSimulcastStreams= */ 1, - /* automaticResizeOn= */ true); + /* automaticResizeOn= */ true, + /* capabilities= */ new VideoEncoder.Capabilities(false /* lossNotification */)); private static final long POLL_DELAY_MS = 10; private static final long DELIVER_ENCODED_IMAGE_DELAY_MS = 10; diff --git a/sdk/objc/native/src/objc_video_encoder_factory.mm b/sdk/objc/native/src/objc_video_encoder_factory.mm index 7de9875eac..e59c1a1163 100644 --- a/sdk/objc/native/src/objc_video_encoder_factory.mm +++ b/sdk/objc/native/src/objc_video_encoder_factory.mm @@ -41,12 +41,11 @@ class ObjCVideoEncoder : public VideoEncoder { ObjCVideoEncoder(id encoder) : encoder_(encoder), implementation_name_([encoder implementationName].stdString) {} - int32_t InitEncode(const VideoCodec *codec_settings, - int32_t number_of_cores, - size_t max_payload_size) override { + int32_t InitEncode(const VideoCodec *codec_settings, const Settings &encoder_settings) override { RTCVideoEncoderSettings *settings = [[RTCVideoEncoderSettings alloc] initWithNativeVideoCodec:codec_settings]; - return [encoder_ startEncodeWithSettings:settings numberOfCores:number_of_cores]; + return [encoder_ startEncodeWithSettings:settings + numberOfCores:encoder_settings.number_of_cores]; } int32_t RegisterEncodeCompleteCallback(EncodedImageCallback *callback) override { diff --git a/sdk/objc/unittests/objc_video_encoder_factory_tests.mm b/sdk/objc/unittests/objc_video_encoder_factory_tests.mm index 567622c657..70ef068fe7 100644 --- a/sdk/objc/unittests/objc_video_encoder_factory_tests.mm +++ b/sdk/objc/unittests/objc_video_encoder_factory_tests.mm @@ -13,12 +13,12 @@ #include "sdk/objc/native/src/objc_video_encoder_factory.h" +#include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_encoder.h" #import "base/RTCVideoEncoder.h" #import "base/RTCVideoEncoderFactory.h" #import "base/RTCVideoFrameBuffer.h" #import "components/video_frame_buffer/RTCCVPixelBuffer.h" - -#include "api/video_codecs/sdp_video_format.h" #include "modules/include/module_common_types.h" #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_error_codes.h" @@ -61,14 +61,18 @@ TEST(ObjCVideoEncoderFactoryTest, InitEncodeReturnsOKOnSuccess) { std::unique_ptr encoder = GetObjCEncoder(CreateOKEncoderFactory()); auto* settings = new webrtc::VideoCodec(); - EXPECT_EQ(encoder->InitEncode(settings, 1, 0), WEBRTC_VIDEO_CODEC_OK); + const webrtc::VideoEncoder::Capabilities kCapabilities(false); + EXPECT_EQ(encoder->InitEncode(settings, webrtc::VideoEncoder::Settings(kCapabilities, 1, 0)), + WEBRTC_VIDEO_CODEC_OK); } TEST(ObjCVideoEncoderFactoryTest, InitEncodeReturnsErrorOnFail) { std::unique_ptr encoder = GetObjCEncoder(CreateErrorEncoderFactory()); auto* settings = new webrtc::VideoCodec(); - EXPECT_EQ(encoder->InitEncode(settings, 1, 0), WEBRTC_VIDEO_CODEC_ERROR); + const webrtc::VideoEncoder::Capabilities kCapabilities(false); + EXPECT_EQ(encoder->InitEncode(settings, webrtc::VideoEncoder::Settings(kCapabilities, 1, 0)), + WEBRTC_VIDEO_CODEC_ERROR); } TEST(ObjCVideoEncoderFactoryTest, EncodeReturnsOKOnSuccess) { diff --git a/test/configurable_frame_size_encoder.cc b/test/configurable_frame_size_encoder.cc index ba529cba51..77326077ba 100644 --- a/test/configurable_frame_size_encoder.cc +++ b/test/configurable_frame_size_encoder.cc @@ -38,8 +38,7 @@ ConfigurableFrameSizeEncoder::~ConfigurableFrameSizeEncoder() {} int32_t ConfigurableFrameSizeEncoder::InitEncode( const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) { + const Settings& settings) { return WEBRTC_VIDEO_CODEC_OK; } diff --git a/test/configurable_frame_size_encoder.h b/test/configurable_frame_size_encoder.h index ddf763f04e..679d3bd9d0 100644 --- a/test/configurable_frame_size_encoder.h +++ b/test/configurable_frame_size_encoder.h @@ -33,8 +33,7 @@ class ConfigurableFrameSizeEncoder : public VideoEncoder { ~ConfigurableFrameSizeEncoder() override; int32_t InitEncode(const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) override; + const Settings& settings) override; int32_t Encode(const VideoFrame& input_image, const std::vector* frame_types) override; diff --git a/test/fake_encoder.cc b/test/fake_encoder.cc index fa7641c8df..23b6094fc3 100644 --- a/test/fake_encoder.cc +++ b/test/fake_encoder.cc @@ -68,8 +68,7 @@ void FakeEncoder::SetMaxBitrate(int max_kbps) { } int32_t FakeEncoder::InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) { + const Settings& settings) { rtc::CritScope cs(&crit_sect_); config_ = *config; current_rate_settings_.bitrate.SetBitrate(0, 0, config_.startBitrate * 1000); @@ -364,8 +363,7 @@ MultithreadedFakeH264Encoder::MultithreadedFakeH264Encoder( } int32_t MultithreadedFakeH264Encoder::InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) { + const Settings& settings) { RTC_DCHECK_RUN_ON(&sequence_checker_); queue1_ = task_queue_factory_->CreateTaskQueue( @@ -373,7 +371,7 @@ int32_t MultithreadedFakeH264Encoder::InitEncode(const VideoCodec* config, queue2_ = task_queue_factory_->CreateTaskQueue( "Queue 2", TaskQueueFactory::Priority::NORMAL); - return FakeH264Encoder::InitEncode(config, number_of_cores, max_payload_size); + return FakeH264Encoder::InitEncode(config, settings); } class MultithreadedFakeH264Encoder::EncodeTask : public QueuedTask { diff --git a/test/fake_encoder.h b/test/fake_encoder.h index 7e1c1a1174..f23ec1ed31 100644 --- a/test/fake_encoder.h +++ b/test/fake_encoder.h @@ -41,8 +41,7 @@ class FakeEncoder : public VideoEncoder { void SetMaxBitrate(int max_kbps); int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override; + const Settings& settings) override; int32_t Encode(const VideoFrame& input_image, const std::vector* frame_types) override; int32_t RegisterEncodeCompleteCallback( @@ -139,8 +138,7 @@ class MultithreadedFakeH264Encoder : public test::FakeH264Encoder { virtual ~MultithreadedFakeH264Encoder() = default; int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override; + const Settings& settings) override; int32_t Encode(const VideoFrame& input_image, const std::vector* frame_types) override; diff --git a/test/fake_vp8_encoder.cc b/test/fake_vp8_encoder.cc index dd60a48197..ee7a7ab7c1 100644 --- a/test/fake_vp8_encoder.cc +++ b/test/fake_vp8_encoder.cc @@ -13,6 +13,7 @@ #include #include "absl/types/optional.h" +#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/vp8_temporal_layers.h" #include "api/video_codecs/vp8_temporal_layers_factory.h" #include "modules/video_coding/codecs/interface/common_constants.h" @@ -49,11 +50,9 @@ FakeVP8Encoder::FakeVP8Encoder(Clock* clock) : FakeEncoder(clock) { } int32_t FakeVP8Encoder::InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) { + const Settings& settings) { RTC_DCHECK_RUN_ON(&sequence_checker_); - auto result = - FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); + auto result = FakeEncoder::InitEncode(config, settings); if (result != WEBRTC_VIDEO_CODEC_OK) { return result; } diff --git a/test/fake_vp8_encoder.h b/test/fake_vp8_encoder.h index b5733c8fda..dcfa5ad491 100644 --- a/test/fake_vp8_encoder.h +++ b/test/fake_vp8_encoder.h @@ -37,8 +37,7 @@ class FakeVP8Encoder : public FakeEncoder { virtual ~FakeVP8Encoder() = default; int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override; + const Settings& settings) override; int32_t Release() override; diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc index 272f80f7c9..3fa9a5be51 100644 --- a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc +++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc @@ -15,6 +15,7 @@ #include "absl/memory/memory.h" #include "api/video/video_codec_type.h" +#include "api/video_codecs/video_encoder.h" #include "modules/video_coding/include/video_error_codes.h" #include "rtc_base/critical_section.h" #include "rtc_base/logging.h" @@ -70,8 +71,7 @@ QualityAnalyzingVideoEncoder::~QualityAnalyzingVideoEncoder() = default; int32_t QualityAnalyzingVideoEncoder::InitEncode( const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) { + const Settings& settings) { rtc::CritScope crit(&lock_); codec_settings_ = *codec_settings; mode_ = SimulcastMode::kNormal; @@ -96,8 +96,7 @@ int32_t QualityAnalyzingVideoEncoder::InitEncode( if (codec_settings->numberOfSimulcastStreams > 1) { mode_ = SimulcastMode::kSimulcast; } - return delegate_->InitEncode(codec_settings, number_of_cores, - max_payload_size); + return delegate_->InitEncode(codec_settings, settings); } int32_t QualityAnalyzingVideoEncoder::RegisterEncodeCompleteCallback( diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h index 4861d4c989..6b22ae2369 100644 --- a/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h +++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h @@ -63,8 +63,7 @@ class QualityAnalyzingVideoEncoder : public VideoEncoder, // Methods of VideoEncoder interface. int32_t InitEncode(const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) override; + const Settings& settings) override; int32_t RegisterEncodeCompleteCallback( EncodedImageCallback* callback) override; int32_t Release() override; diff --git a/test/video_encoder_proxy_factory.h b/test/video_encoder_proxy_factory.h index 49a4e2d4e7..81183d3d70 100644 --- a/test/video_encoder_proxy_factory.h +++ b/test/video_encoder_proxy_factory.h @@ -21,6 +21,10 @@ namespace webrtc { namespace test { +namespace { +const VideoEncoder::Capabilities kCapabilities(false); +} + // An encoder factory with a single underlying VideoEncoder object, // intended for test purposes. Each call to CreateVideoEncoder returns // a proxy for the same encoder, typically an instance of FakeEncoder. @@ -66,9 +70,8 @@ class VideoEncoderProxyFactory final : public VideoEncoderFactory { return encoder_->Encode(input_image, frame_types); } int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { - return encoder_->InitEncode(config, number_of_cores, max_payload_size); + const Settings& settings) override { + return encoder_->InitEncode(config, settings); } int32_t RegisterEncodeCompleteCallback( EncodedImageCallback* callback) override { diff --git a/video/BUILD.gn b/video/BUILD.gn index 0ae719a6b1..ea09c16946 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -262,6 +262,7 @@ if (rtc_include_tests) { "../api/video:video_bitrate_allocator_factory", "../api/video:video_frame", "../api/video:video_rtp_headers", + "../api/video_codecs:video_codecs_api", "../call:fake_network", "../call:simulated_network", "../common_video", diff --git a/video/end_to_end_tests/network_state_tests.cc b/video/end_to_end_tests/network_state_tests.cc index a863076437..218414ec69 100644 --- a/video/end_to_end_tests/network_state_tests.cc +++ b/video/end_to_end_tests/network_state_tests.cc @@ -10,6 +10,7 @@ #include "absl/memory/memory.h" #include "api/test/simulated_network.h" +#include "api/video_codecs/video_encoder.h" #include "call/fake_network_pipe.h" #include "call/simulated_network.h" #include "system_wrappers/include/sleep.h" @@ -356,8 +357,7 @@ TEST_F(NetworkStateEndToEndTest, NewVideoSendStreamsRespectVideoNetworkDown) { UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {} int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { + const Settings& settings) override { EXPECT_GT(config->startBitrate, 0u); return 0; } diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc index cc30c79b26..4a45357ad5 100644 --- a/video/video_quality_test.cc +++ b/video/video_quality_test.cc @@ -21,6 +21,7 @@ #include "api/rtc_event_log_output_file.h" #include "api/task_queue/default_task_queue_factory.h" #include "api/video/builtin_video_bitrate_allocator_factory.h" +#include "api/video_codecs/video_encoder.h" #include "call/fake_network_pipe.h" #include "call/simulated_network.h" #include "media/engine/adm_helpers.h" @@ -67,6 +68,8 @@ constexpr uint32_t kThumbnailRtxSsrcStart = 0xF0000; constexpr int kDefaultMaxQp = cricket::WebRtcVideoChannel::kDefaultQpMax; +const VideoEncoder::Capabilities kCapabilities(false); + std::pair GetMinMaxBitratesBps(const VideoCodec& codec, size_t spatial_idx) { uint32_t min_bitrate = codec.minBitrate; @@ -132,11 +135,9 @@ class QualityTestVideoEncoder : public VideoEncoder, // Implement VideoEncoder int32_t InitEncode(const VideoCodec* codec_settings, - int32_t number_of_cores, - size_t max_payload_size) override { + const Settings& settings) override { codec_settings_ = *codec_settings; - return encoder_->InitEncode(codec_settings, number_of_cores, - max_payload_size); + return encoder_->InitEncode(codec_settings, settings); } int32_t RegisterEncodeCompleteCallback( diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc index 480ae6c569..fc5a5b9ff7 100644 --- a/video/video_send_stream_tests.cc +++ b/video/video_send_stream_tests.cc @@ -17,6 +17,7 @@ #include "api/test/simulated_network.h" #include "api/video/encoded_image.h" #include "api/video/video_bitrate_allocation.h" +#include "api/video_codecs/video_encoder.h" #include "call/call.h" #include "call/fake_network_pipe.h" #include "call/rtp_transport_controller_send.h" @@ -1976,14 +1977,13 @@ TEST_F(VideoSendStreamTest, private: int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { + const Settings& settings) override { rtc::CritScope lock(&crit_); last_initialized_frame_width_ = config->width; last_initialized_frame_height_ = config->height; ++number_of_initializations_; init_encode_called_.Set(); - return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); + return FakeEncoder::InitEncode(config, settings); } int32_t Encode(const VideoFrame& input_image, @@ -2036,12 +2036,11 @@ TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) { : FakeEncoder(Clock::GetRealTimeClock()), start_bitrate_kbps_(0) {} int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { + const Settings& settings) override { rtc::CritScope lock(&crit_); start_bitrate_kbps_ = config->startBitrate; start_bitrate_changed_.Set(); - return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); + return FakeEncoder::InitEncode(config, settings); } void SetRates(const RateControlParameters& parameters) override { @@ -2110,11 +2109,10 @@ class StartStopBitrateObserver : public test::FakeEncoder { public: StartStopBitrateObserver() : FakeEncoder(Clock::GetRealTimeClock()) {} int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { + const Settings& settings) override { rtc::CritScope lock(&crit_); encoder_init_.Set(); - return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); + return FakeEncoder::InitEncode(config, settings); } void SetRates(const RateControlParameters& parameters) override { @@ -2309,8 +2307,7 @@ TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) { private: int32_t InitEncode(const VideoCodec* codecSettings, - int32_t numberOfCores, - size_t maxPayloadSize) override { + const Settings& settings) override { rtc::CritScope lock(&crit_); EXPECT_FALSE(initialized_); initialized_ = true; @@ -2426,8 +2423,7 @@ TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) { } int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { + const Settings& settings) override { if (num_initializations_ == 0) { // Verify default values. EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate); @@ -2437,7 +2433,7 @@ TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) { } ++num_initializations_; init_encode_event_.Set(); - return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); + return FakeEncoder::InitEncode(config, settings); } void PerformTest() override { @@ -2505,13 +2501,12 @@ class VideoCodecConfigObserver : public test::SendTest, } int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { + const Settings& settings) override { EXPECT_EQ(video_codec_type_, config->codecType); VerifyCodecSpecifics(*config); ++num_initializations_; init_encode_event_.Set(); - return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); + return FakeEncoder::InitEncode(config, settings); } void InitCodecSpecifics(); @@ -2753,16 +2748,15 @@ TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) { private: int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { + const Settings& settings) override { EXPECT_EQ(config->numberOfSimulcastStreams, 1); EXPECT_EQ(static_cast(kScreencastMaxTargetBitrateDeltaKbps), config->simulcastStream[0].maxBitrate - config->simulcastStream[0].targetBitrate); observation_complete_.Set(); - return test::FakeEncoder::InitEncode(config, number_of_cores, - max_payload_size); + return test::FakeEncoder::InitEncode(config, settings); } + void ModifyVideoConfigs( VideoSendStream::Config* send_config, std::vector* receive_configs, @@ -2818,8 +2812,7 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { private: int32_t InitEncode(const VideoCodec* codecSettings, - int32_t numberOfCores, - size_t maxPayloadSize) override { + const Settings& settings) override { EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate); EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate); if (num_initializations_ == 0) { @@ -2847,8 +2840,7 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { ++num_initializations_; init_encode_event_.Set(); - return FakeEncoder::InitEncode(codecSettings, numberOfCores, - maxPayloadSize); + return FakeEncoder::InitEncode(codecSettings, settings); } void SetRates(const RateControlParameters& parameters) override { diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index fab3d57068..56835d6ef6 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -20,6 +20,7 @@ #include "api/video/encoded_image.h" #include "api/video/i420_buffer.h" #include "api/video/video_bitrate_allocator_factory.h" +#include "api/video_codecs/video_encoder.h" #include "modules/video_coding/codecs/vp9/svc_rate_allocator.h" #include "modules/video_coding/include/video_codec_initializer.h" #include "modules/video_coding/include/video_coding.h" @@ -732,10 +733,13 @@ void VideoStreamEncoder::ReconfigureEncoder() { encoder_config_.video_format); } - if (encoder_->InitEncode(&send_codec_, number_of_cores_, - max_data_payload_length_ > 0 - ? max_data_payload_length_ - : kDefaultPayloadSize) != 0) { + const size_t max_data_payload_length = max_data_payload_length_ > 0 + ? max_data_payload_length_ + : kDefaultPayloadSize; + if (encoder_->InitEncode( + &send_codec_, + VideoEncoder::Settings(settings_.capabilities, number_of_cores_, + max_data_payload_length)) != 0) { RTC_LOG(LS_ERROR) << "Failed to initialize the encoder associated with " "codec type: " << CodecTypeToPayloadString(send_codec_.codecType) diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc index 1cf9436892..1486606d46 100644 --- a/video/video_stream_encoder_unittest.cc +++ b/video/video_stream_encoder_unittest.cc @@ -20,6 +20,7 @@ #include "api/video/builtin_video_bitrate_allocator_factory.h" #include "api/video/i420_buffer.h" #include "api/video/video_bitrate_allocation.h" +#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/vp8_temporal_layers.h" #include "api/video_codecs/vp8_temporal_layers_factory.h" #include "common_video/h264/h264_common.h" @@ -717,10 +718,8 @@ class VideoStreamEncoderTest : public ::testing::Test { } int32_t InitEncode(const VideoCodec* config, - int32_t number_of_cores, - size_t max_payload_size) override { - int res = - FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); + const Settings& settings) override { + int res = FakeEncoder::InitEncode(config, settings); rtc::CritScope lock(&local_crit_sect_); EXPECT_EQ(initialized_, EncoderState::kUninitialized); if (config->codecType == kVideoCodecVP8) {