Break VP8 temporal_layers dependency on libvpx.

This is in preparation for
https://webrtc-review.googlesource.com/c/src/+/36340

With these changes we can avoid some strange #ifdefs in the code
that uses temporal layers.

Bug: webrtc:7925
Change-Id: I472210738ccc9f73812b8863951befeabec56f15
Reviewed-on: https://webrtc-review.googlesource.com/41280
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Anders Carlsson <andersc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21759}
diff --git a/modules/video_coding/codecs/vp8/default_temporal_layers.cc b/modules/video_coding/codecs/vp8/default_temporal_layers.cc
index f070750..1767c58 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 @@
   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 f192556..0865fc8 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 @@
                                        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 1c1d63f..eeac418 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 @@
 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, 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 @@
   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, 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, 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 @@
 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 8c63cf1..a857cc1 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 @@
   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 7143351..794b02b 100644
--- a/modules/video_coding/codecs/vp8/screenshare_layers.h
+++ b/modules/video_coding/codecs/vp8/screenshare_layers.h
@@ -45,7 +45,7 @@
 
   // 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 818308f..f220e72 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 <memory>
 #include <vector>
 
-#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 @@
     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 @@
 
   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 dad718c..cd47bf9 100644
--- a/modules/video_coding/codecs/vp8/temporal_layers.h
+++ b/modules/video_coding/codecs/vp8/temporal_layers.h
@@ -16,13 +16,25 @@
 #include <memory>
 
 #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 @@
 
   // 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 c52b7cd..f4af08c 100644
--- a/modules/video_coding/codecs/vp8/vp8_impl.cc
+++ b/modules/video_coding/codecs/vp8/vp8_impl.cc
@@ -150,6 +150,55 @@
   *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> VP8Encoder::Create() {
@@ -298,7 +347,9 @@
       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 @@
   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 @@
     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 @@
     // 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 44d0081..dad1e8b 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 @@
  public:
   MOCK_METHOD1(UpdateLayerConfig, TemporalLayers::FrameConfig(uint32_t));
   MOCK_METHOD3(OnRatesUpdated, std::vector<uint32_t>(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&,