diff --git a/modules/video_coding/codecs/vp8/default_temporal_layers.cc b/modules/video_coding/codecs/vp8/default_temporal_layers.cc index f070750e7b..1767c5863f 100644 --- a/modules/video_coding/codecs/vp8/default_temporal_layers.cc +++ b/modules/video_coding/codecs/vp8/default_temporal_layers.cc @@ -24,9 +24,6 @@ #include "rtc_base/logging.h" #include "system_wrappers/include/field_trial.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" - namespace webrtc { TemporalLayers::FrameConfig::FrameConfig() @@ -354,7 +351,7 @@ std::vector DefaultTemporalLayers::OnRatesUpdated( return bitrates; } -bool DefaultTemporalLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { +bool DefaultTemporalLayers::UpdateConfiguration(Vp8EncoderConfig* cfg) { if (!new_bitrates_kbps_) return false; diff --git a/modules/video_coding/codecs/vp8/default_temporal_layers.h b/modules/video_coding/codecs/vp8/default_temporal_layers.h index f192556920..0865fc8bfd 100644 --- a/modules/video_coding/codecs/vp8/default_temporal_layers.h +++ b/modules/video_coding/codecs/vp8/default_temporal_layers.h @@ -37,7 +37,7 @@ class DefaultTemporalLayers : public TemporalLayers { int max_bitrate_kbps, int framerate) override; - bool UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) override; + bool UpdateConfiguration(Vp8EncoderConfig* cfg) override; void PopulateCodecSpecific(bool frame_is_keyframe, const TemporalLayers::FrameConfig& tl_config, diff --git a/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc b/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc index 1c1d63f1f8..eeac418963 100644 --- a/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc +++ b/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc @@ -13,8 +13,6 @@ #include "modules/video_coding/include/video_codec_interface.h" #include "test/field_trial.h" #include "test/gtest.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" namespace webrtc { namespace test { @@ -54,7 +52,7 @@ enum { TEST(TemporalLayersTest, 2Layers) { DefaultTemporalLayers tl(2, 0); DefaultTemporalLayersChecker checker(2, 0); - vpx_codec_enc_cfg_t cfg; + Vp8EncoderConfig cfg; CodecSpecificInfoVP8 vp8_info; tl.OnRatesUpdated(500, 500, 30); tl.UpdateConfiguration(&cfg); @@ -102,7 +100,7 @@ TEST(TemporalLayersTest, 2Layers) { TEST(TemporalLayersTest, 3Layers) { DefaultTemporalLayers tl(3, 0); DefaultTemporalLayersChecker checker(3, 0); - vpx_codec_enc_cfg_t cfg; + Vp8EncoderConfig cfg; CodecSpecificInfoVP8 vp8_info; tl.OnRatesUpdated(500, 500, 30); tl.UpdateConfiguration(&cfg); @@ -151,7 +149,7 @@ TEST(TemporalLayersTest, Alternative3Layers) { ScopedFieldTrials field_trial("WebRTC-UseShortVP8TL3Pattern/Enabled/"); DefaultTemporalLayers tl(3, 0); DefaultTemporalLayersChecker checker(3, 0); - vpx_codec_enc_cfg_t cfg; + Vp8EncoderConfig cfg; CodecSpecificInfoVP8 vp8_info; tl.OnRatesUpdated(500, 500, 30); tl.UpdateConfiguration(&cfg); @@ -187,7 +185,7 @@ TEST(TemporalLayersTest, Alternative3Layers) { TEST(TemporalLayersTest, 4Layers) { DefaultTemporalLayers tl(4, 0); DefaultTemporalLayersChecker checker(4, 0); - vpx_codec_enc_cfg_t cfg; + Vp8EncoderConfig cfg; CodecSpecificInfoVP8 vp8_info; tl.OnRatesUpdated(500, 500, 30); tl.UpdateConfiguration(&cfg); @@ -234,7 +232,7 @@ TEST(TemporalLayersTest, 4Layers) { TEST(TemporalLayersTest, KeyFrame) { DefaultTemporalLayers tl(3, 0); DefaultTemporalLayersChecker checker(3, 0); - vpx_codec_enc_cfg_t cfg; + Vp8EncoderConfig cfg; CodecSpecificInfoVP8 vp8_info; tl.OnRatesUpdated(500, 500, 30); tl.UpdateConfiguration(&cfg); @@ -348,7 +346,7 @@ INSTANTIATE_TEST_CASE_P(DefaultTemporalLayersTest, TEST_P(TemporalLayersReferenceTest, ValidFrameConfigs) { const int num_layers = GetParam(); DefaultTemporalLayers tl(num_layers, 0); - vpx_codec_enc_cfg_t cfg; + Vp8EncoderConfig cfg; tl.OnRatesUpdated(500, 500, 30); tl.UpdateConfiguration(&cfg); diff --git a/modules/video_coding/codecs/vp8/screenshare_layers.cc b/modules/video_coding/codecs/vp8/screenshare_layers.cc index 8c63cf1a08..a857cc165c 100644 --- a/modules/video_coding/codecs/vp8/screenshare_layers.cc +++ b/modules/video_coding/codecs/vp8/screenshare_layers.cc @@ -19,8 +19,6 @@ #include "rtc_base/logging.h" #include "system_wrappers/include/clock.h" #include "system_wrappers/include/metrics.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" namespace webrtc { @@ -381,7 +379,7 @@ uint32_t ScreenshareLayers::GetCodecTargetBitrateKbps() const { return std::max(layers_[0].target_rate_kbps_, target_bitrate_kbps); } -bool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { +bool ScreenshareLayers::UpdateConfiguration(Vp8EncoderConfig* cfg) { bool cfg_updated = false; uint32_t target_bitrate_kbps = GetCodecTargetBitrateKbps(); diff --git a/modules/video_coding/codecs/vp8/screenshare_layers.h b/modules/video_coding/codecs/vp8/screenshare_layers.h index 71433514c4..794b02b852 100644 --- a/modules/video_coding/codecs/vp8/screenshare_layers.h +++ b/modules/video_coding/codecs/vp8/screenshare_layers.h @@ -45,7 +45,7 @@ class ScreenshareLayers : public TemporalLayers { // Update the encoder configuration with target bitrates or other parameters. // Returns true iff the configuration was actually modified. - bool UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) override; + bool UpdateConfiguration(Vp8EncoderConfig* cfg) override; void PopulateCodecSpecific(bool base_layer_sync, const TemporalLayers::FrameConfig& tl_config, diff --git a/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc b/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc index 818308f3b0..f220e72011 100644 --- a/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc +++ b/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc @@ -11,8 +11,6 @@ #include #include -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" #include "modules/video_coding/codecs/vp8/screenshare_layers.h" #include "modules/video_coding/codecs/vp8/vp8_impl.h" #include "modules/video_coding/include/video_codec_interface.h" @@ -96,18 +94,18 @@ class ScreenshareLayerTest : public ::testing::Test { return ((bitrate_kbps * 1000) / 8) / kFrameRate; } - vpx_codec_enc_cfg_t ConfigureBitrates() { - vpx_codec_enc_cfg_t vpx_cfg; - memset(&vpx_cfg, 0, sizeof(vpx_codec_enc_cfg_t)); - vpx_cfg.rc_min_quantizer = min_qp_; - vpx_cfg.rc_max_quantizer = max_qp_; + Vp8EncoderConfig ConfigureBitrates() { + Vp8EncoderConfig vp8_cfg; + memset(&vp8_cfg, 0, sizeof(Vp8EncoderConfig)); + vp8_cfg.rc_min_quantizer = min_qp_; + vp8_cfg.rc_max_quantizer = max_qp_; EXPECT_THAT(layers_->OnRatesUpdated(kDefaultTl0BitrateKbps, kDefaultTl1BitrateKbps, kFrameRate), ElementsAre(kDefaultTl0BitrateKbps, kDefaultTl1BitrateKbps - kDefaultTl0BitrateKbps)); - EXPECT_TRUE(layers_->UpdateConfiguration(&vpx_cfg)); - frame_size_ = FrameSizeForBitrate(vpx_cfg.rc_target_bitrate); - return vpx_cfg; + EXPECT_TRUE(layers_->UpdateConfiguration(&vp8_cfg)); + frame_size_ = FrameSizeForBitrate(vp8_cfg.rc_target_bitrate); + return vp8_cfg; } void WithQpLimits(int min_qp, int max_qp) { @@ -169,7 +167,7 @@ class ScreenshareLayerTest : public ::testing::Test { uint32_t timestamp_; TemporalLayers::FrameConfig tl_config_; - vpx_codec_enc_cfg_t cfg_; + Vp8EncoderConfig cfg_; bool config_updated_; CodecSpecificInfoVP8 vp8_info_; }; diff --git a/modules/video_coding/codecs/vp8/temporal_layers.h b/modules/video_coding/codecs/vp8/temporal_layers.h index dad718cd0f..cd47bf9f6e 100644 --- a/modules/video_coding/codecs/vp8/temporal_layers.h +++ b/modules/video_coding/codecs/vp8/temporal_layers.h @@ -16,13 +16,25 @@ #include #include "typedefs.h" // NOLINT(build/include) -struct vpx_codec_enc_cfg; -typedef struct vpx_codec_enc_cfg vpx_codec_enc_cfg_t; + +#define VP8_TS_MAX_PERIODICITY 16 +#define VP8_TS_MAX_LAYERS 5 namespace webrtc { struct CodecSpecificInfoVP8; +struct Vp8EncoderConfig { + unsigned int ts_number_layers; + unsigned int ts_target_bitrate[VP8_TS_MAX_LAYERS]; + unsigned int ts_rate_decimator[VP8_TS_MAX_LAYERS]; + unsigned int ts_periodicity; + unsigned int ts_layer_id[VP8_TS_MAX_PERIODICITY]; + unsigned int rc_target_bitrate; + unsigned int rc_min_quantizer; + unsigned int rc_max_quantizer; +}; + class TemporalLayers { public: enum BufferFlags { @@ -99,7 +111,7 @@ class TemporalLayers { // Update the encoder configuration with target bitrates or other parameters. // Returns true iff the configuration was actually modified. - virtual bool UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) = 0; + virtual bool UpdateConfiguration(Vp8EncoderConfig* cfg) = 0; virtual void PopulateCodecSpecific( bool is_keyframe, diff --git a/modules/video_coding/codecs/vp8/vp8_impl.cc b/modules/video_coding/codecs/vp8/vp8_impl.cc index c52b7cde91..f4af08cf14 100644 --- a/modules/video_coding/codecs/vp8/vp8_impl.cc +++ b/modules/video_coding/codecs/vp8/vp8_impl.cc @@ -150,6 +150,55 @@ void GetPostProcParamsFromFieldTrialGroup( *deblock_params = params; } +static_assert( + VP8_TS_MAX_PERIODICITY == VPX_TS_MAX_PERIODICITY, + "VP8_TS_MAX_PERIODICITY must be kept in sync with the constant in libvpx."); +static_assert( + VP8_TS_MAX_LAYERS == VPX_TS_MAX_LAYERS, + "VP8_TS_MAX_LAYERS must be kept in sync with the constant in libvpx."); + +static Vp8EncoderConfig GetEncoderConfig(vpx_codec_enc_cfg* vpx_config) { + Vp8EncoderConfig config; + + config.ts_number_layers = vpx_config->ts_number_layers; + memcpy(config.ts_target_bitrate, vpx_config->ts_target_bitrate, + sizeof(unsigned int) * VP8_TS_MAX_LAYERS); + memcpy(config.ts_rate_decimator, vpx_config->ts_rate_decimator, + sizeof(unsigned int) * VP8_TS_MAX_LAYERS); + config.ts_periodicity = vpx_config->ts_periodicity; + memcpy(config.ts_layer_id, vpx_config->ts_layer_id, + sizeof(unsigned int) * VP8_TS_MAX_PERIODICITY); + config.rc_target_bitrate = vpx_config->rc_target_bitrate; + config.rc_min_quantizer = vpx_config->rc_min_quantizer; + config.rc_max_quantizer = vpx_config->rc_max_quantizer; + + return config; +} + +static void FillInEncoderConfig(vpx_codec_enc_cfg* vpx_config, + const Vp8EncoderConfig& config) { + vpx_config->ts_number_layers = config.ts_number_layers; + memcpy(vpx_config->ts_target_bitrate, config.ts_target_bitrate, + sizeof(unsigned int) * VP8_TS_MAX_LAYERS); + memcpy(vpx_config->ts_rate_decimator, config.ts_rate_decimator, + sizeof(unsigned int) * VP8_TS_MAX_LAYERS); + vpx_config->ts_periodicity = config.ts_periodicity; + memcpy(vpx_config->ts_layer_id, config.ts_layer_id, + sizeof(unsigned int) * VP8_TS_MAX_PERIODICITY); + vpx_config->rc_target_bitrate = config.rc_target_bitrate; + vpx_config->rc_min_quantizer = config.rc_min_quantizer; + vpx_config->rc_max_quantizer = config.rc_max_quantizer; +} + +bool UpdateVpxConfiguration(TemporalLayers* temporal_layers, + vpx_codec_enc_cfg_t* cfg) { + Vp8EncoderConfig config = GetEncoderConfig(cfg); + const bool res = temporal_layers->UpdateConfiguration(&config); + if (res) + FillInEncoderConfig(cfg, config); + return res; +} + } // namespace std::unique_ptr VP8Encoder::Create() { @@ -298,7 +347,9 @@ int VP8EncoderImpl::SetRateAllocation(const BitrateAllocation& bitrate, SetStreamState(send_stream, stream_idx); configurations_[i].rc_target_bitrate = target_bitrate_kbps; - temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[i]); + + UpdateVpxConfiguration(temporal_layers_[stream_idx].get(), + &configurations_[i]); if (vpx_codec_enc_config_set(&encoders_[i], &configurations_[i])) { return WEBRTC_VIDEO_CODEC_ERROR; @@ -530,7 +581,9 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst, configurations_[0].rc_target_bitrate = stream_bitrates[stream_idx]; temporal_layers_[stream_idx]->OnRatesUpdated( stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate); - temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[0]); + UpdateVpxConfiguration(temporal_layers_[stream_idx].get(), + &configurations_[0]); + --stream_idx; for (size_t i = 1; i < encoders_.size(); ++i, --stream_idx) { memcpy(&configurations_[i], &configurations_[0], @@ -552,7 +605,8 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst, configurations_[i].rc_target_bitrate = stream_bitrates[stream_idx]; temporal_layers_[stream_idx]->OnRatesUpdated( stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate); - temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[i]); + UpdateVpxConfiguration(temporal_layers_[stream_idx].get(), + &configurations_[i]); } return InitAndSetControlSettings(); @@ -797,7 +851,8 @@ int VP8EncoderImpl::Encode(const VideoFrame& frame, // the next update. vpx_codec_enc_cfg_t temp_config; memcpy(&temp_config, &configurations_[i], sizeof(vpx_codec_enc_cfg_t)); - if (temporal_layers_[stream_idx]->UpdateConfiguration(&temp_config)) { + if (UpdateVpxConfiguration(temporal_layers_[stream_idx].get(), + &temp_config)) { if (vpx_codec_enc_config_set(&encoders_[i], &temp_config)) return WEBRTC_VIDEO_CODEC_ERROR; } diff --git a/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc b/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc index 44d0081bcd..dad1e8bded 100644 --- a/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc +++ b/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc @@ -31,7 +31,7 @@ class MockTemporalLayers : public TemporalLayers { public: MOCK_METHOD1(UpdateLayerConfig, TemporalLayers::FrameConfig(uint32_t)); MOCK_METHOD3(OnRatesUpdated, std::vector(int, int, int)); - MOCK_METHOD1(UpdateConfiguration, bool(vpx_codec_enc_cfg_t*)); + MOCK_METHOD1(UpdateConfiguration, bool(Vp8EncoderConfig*)); MOCK_METHOD4(PopulateCodecSpecific, void(bool, const TemporalLayers::FrameConfig&,