diff --git a/modules/video_coding/codecs/vp8/include/vp8.h b/modules/video_coding/codecs/vp8/include/vp8.h index 76ff7a804a..44efbeeb3b 100644 --- a/modules/video_coding/codecs/vp8/include/vp8.h +++ b/modules/video_coding/codecs/vp8/include/vp8.h @@ -12,7 +12,9 @@ #define MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_H_ #include +#include +#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/vp8_frame_buffer_controller.h" #include "modules/video_coding/include/video_codec_interface.h" #include "rtc_base/deprecation.h" @@ -29,7 +31,10 @@ class VP8Encoder { std::unique_ptr frame_buffer_controller_factory = nullptr; - // TODO(https://bugs.webrtc.org/11436): Add resolution_bitrate_limits. + // Allows for overriding the resolution/bitrate limits exposed through + // VideoEncoder::GetEncoderInfo(). No override is done if empty. + std::vector + resolution_bitrate_limits = {}; }; static std::unique_ptr Create(); diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index 200be24f48..335ba9fc50 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -279,6 +279,7 @@ LibvpxVp8Encoder::LibvpxVp8Encoder(std::unique_ptr interface, ExperimentalScreenshareSettings::ParseFromFieldTrials().MaxQp()), frame_buffer_controller_factory_( std::move(settings.frame_buffer_controller_factory)), + resolution_bitrate_limits_(std::move(settings.resolution_bitrate_limits)), key_frame_request_(kMaxSimulcastStreams, false), variable_framerate_experiment_(ParseVariableFramerateConfig( "WebRTC-VP8VariableFramerateScreenshare")), @@ -1230,6 +1231,9 @@ VideoEncoder::EncoderInfo LibvpxVp8Encoder::GetEncoderInfo() const { info.is_hardware_accelerated = false; info.has_internal_source = false; info.supports_simulcast = true; + if (!resolution_bitrate_limits_.empty()) { + info.resolution_bitrate_limits = resolution_bitrate_limits_; + } const bool enable_scaling = num_active_streams_ == 1 && diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h index 6e90931ff5..cc2f206814 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h @@ -112,6 +112,8 @@ class LibvpxVp8Encoder : public VideoEncoder { const std::unique_ptr frame_buffer_controller_factory_; std::unique_ptr frame_buffer_controller_; + const std::vector + resolution_bitrate_limits_; std::vector key_frame_request_; std::vector send_stream_; std::vector cpu_speed_; 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 c86d3b70c5..a1eb684d92 100644 --- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc +++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc @@ -94,10 +94,6 @@ class TestVp8Impl : public VideoCodecUnitTest { encoder_->Encode(input_frame, &frame_types)); ASSERT_TRUE(WaitForEncodedFrame(encoded_frame, codec_specific_info)); VerifyQpParser(*encoded_frame); - VideoEncoder::EncoderInfo encoder_info = encoder_->GetEncoderInfo(); - EXPECT_EQ("libvpx", encoder_info.implementation_name); - EXPECT_EQ(false, encoder_info.is_hardware_accelerated); - EXPECT_EQ(false, encoder_info.has_internal_source); EXPECT_EQ(kVideoCodecVP8, codec_specific_info->codecType); EXPECT_EQ(0, encoded_frame->SpatialIndex()); } @@ -556,6 +552,51 @@ TEST_F(TestVp8Impl, KeepsTimestampOnReencode) { encoder.Encode(NextInputFrame(), &delta_frame); } +TEST(LibvpxVp8EncoderTest, GetEncoderInfoReturnsStaticInformation) { + auto* const vpx = new NiceMock(); + LibvpxVp8Encoder encoder((std::unique_ptr(vpx)), + VP8Encoder::Settings()); + + const auto info = encoder.GetEncoderInfo(); + + EXPECT_FALSE(info.supports_native_handle); + EXPECT_FALSE(info.is_hardware_accelerated); + EXPECT_FALSE(info.has_internal_source); + EXPECT_TRUE(info.supports_simulcast); + EXPECT_EQ(info.implementation_name, "libvpx"); +} + +TEST(LibvpxVp8EncoderTest, + GetEncoderInfoReturnsEmptyResolutionBitrateLimitsByDefault) { + auto* const vpx = new NiceMock(); + LibvpxVp8Encoder encoder((std::unique_ptr(vpx)), + VP8Encoder::Settings()); + + const auto info = encoder.GetEncoderInfo(); + + EXPECT_TRUE(info.resolution_bitrate_limits.empty()); +} + +TEST(LibvpxVp8EncoderTest, + GetEncoderInfoReturnsResolutionBitrateLimitsAsConfigured) { + std::vector resolution_bitrate_limits = + {VideoEncoder::ResolutionBitrateLimits(/*frame_size_pixels=*/640 * 360, + /*min_start_bitrate_bps=*/300, + /*min_bitrate_bps=*/100, + /*max_bitrate_bps=*/1000), + VideoEncoder::ResolutionBitrateLimits(320 * 180, 100, 30, 500)}; + VP8Encoder::Settings settings; + settings.resolution_bitrate_limits = resolution_bitrate_limits; + + auto* const vpx = new NiceMock(); + LibvpxVp8Encoder encoder((std::unique_ptr(vpx)), + std::move(settings)); + + const auto info = encoder.GetEncoderInfo(); + + EXPECT_EQ(info.resolution_bitrate_limits, resolution_bitrate_limits); +} + TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationNoLayers) { FramerateFractions expected_fps_allocation[kMaxSpatialLayers] = { FramerateFractions(1, EncoderInfo::kMaxFramerateFraction)};