Move TemporalLayers to api/video_codecs.

Also renaming it Vp8TemporalLayers to show that it is codec specific.

Bug: webrtc:9012
Change-Id: I18187538b8142cdd7538f1a4ed1bada09d040f1f
Reviewed-on: https://webrtc-review.googlesource.com/c/104643
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25137}
diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn
index f2d7e9e..152caaf 100644
--- a/api/video_codecs/BUILD.gn
+++ b/api/video_codecs/BUILD.gn
@@ -28,6 +28,7 @@
     "video_encoder_config.cc",
     "video_encoder_config.h",
     "video_encoder_factory.h",
+    "vp8_temporal_layers.h",
   ]
 
   deps = [
@@ -80,6 +81,24 @@
   ]
 }
 
+rtc_static_library("create_vp8_temporal_layers") {
+  visibility = [ "*" ]
+  allow_poison = [ "software_video_codecs" ]
+  sources = [
+    "create_vp8_temporal_layers.cc",
+    "create_vp8_temporal_layers.h",
+  ]
+
+  deps = [
+    ":video_codecs_api",
+    "../..:webrtc_common",
+    "../../modules/video_coding:video_codec_interface",
+    "../../modules/video_coding:webrtc_vp8_temporal_layers",
+    "../../system_wrappers:system_wrappers",
+    "//third_party/abseil-cpp/absl/memory:memory",
+  ]
+}
+
 rtc_static_library("rtc_software_fallback_wrappers") {
   visibility = [ "*" ]
 
diff --git a/api/video_codecs/create_vp8_temporal_layers.cc b/api/video_codecs/create_vp8_temporal_layers.cc
new file mode 100644
index 0000000..dd290f3
--- /dev/null
+++ b/api/video_codecs/create_vp8_temporal_layers.cc
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/create_vp8_temporal_layers.h"
+#include "absl/memory/memory.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
+#include "modules/video_coding/codecs/vp8/default_temporal_layers.h"
+#include "modules/video_coding/codecs/vp8/screenshare_layers.h"
+#include "system_wrappers/include/clock.h"
+
+namespace webrtc {
+
+std::unique_ptr<Vp8TemporalLayers> CreateVp8TemporalLayers(
+    Vp8TemporalLayersType type,
+    int num_temporal_layers) {
+  switch (type) {
+    case Vp8TemporalLayersType::kFixedPattern:
+      return absl::make_unique<DefaultTemporalLayers>(num_temporal_layers);
+    case Vp8TemporalLayersType::kBitrateDynamic:
+      // Conference mode temporal layering for screen content in base stream.
+      return absl::make_unique<ScreenshareLayers>(num_temporal_layers,
+                                                  Clock::GetRealTimeClock());
+  }
+}
+
+}  // namespace webrtc
diff --git a/api/video_codecs/create_vp8_temporal_layers.h b/api/video_codecs/create_vp8_temporal_layers.h
new file mode 100644
index 0000000..52f14c8
--- /dev/null
+++ b/api/video_codecs/create_vp8_temporal_layers.h
@@ -0,0 +1,26 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_CREATE_VP8_TEMPORAL_LAYERS_H_
+#define API_VIDEO_CODECS_CREATE_VP8_TEMPORAL_LAYERS_H_
+
+#include <memory>
+
+#include "api/video_codecs/vp8_temporal_layers.h"
+
+namespace webrtc {
+
+std::unique_ptr<Vp8TemporalLayers> CreateVp8TemporalLayers(
+    Vp8TemporalLayersType type,
+    int num_temporal_layers);
+
+}  // namespace webrtc
+
+#endif  // API_VIDEO_CODECS_CREATE_VP8_TEMPORAL_LAYERS_H_
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 98ebed2..91d65ae 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
@@ -8,14 +8,13 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
-
 #include <utility>
 
 #include "api/video/i420_buffer.h"
 #include "api/video/video_bitrate_allocation.h"
+#include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "modules/video_coding/codecs/vp8/include/vp8.h"
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "modules/video_coding/include/video_error_codes.h"
 #include "modules/video_coding/utility/simulcast_rate_allocator.h"
diff --git a/modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h b/api/video_codecs/vp8_temporal_layers.h
similarity index 88%
rename from modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h
rename to api/video_codecs/vp8_temporal_layers.h
index b5dbc4e..70223a4 100644
--- a/modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h
+++ b/api/video_codecs/vp8_temporal_layers.h
@@ -8,8 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#ifndef MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_TEMPORAL_LAYERS_H_
-#define MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_TEMPORAL_LAYERS_H_
+#ifndef API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
+#define API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
 
 #include <memory>
 #include <vector>
@@ -17,8 +17,8 @@
 namespace webrtc {
 
 // Some notes on the prerequisites of the TemporalLayers interface.
-// * Implementations of TemporalLayers may not contain internal synchronization
-//   so caller must make sure doing so thread safe.
+// * Vp8TemporalLayers is not thread safe, synchronization is the caller's
+//   responsibility.
 // * The encoder is assumed to encode all frames in order, and callbacks to
 //   PopulateCodecSpecific() / FrameEncoded() must happen in the same order.
 //
@@ -36,15 +36,13 @@
 // FrameEncoded() for a previous one, but calls themselves must be both
 // synchronized (e.g. run on a task queue) and in order (per type).
 
-enum class TemporalLayersType { kFixedPattern, kBitrateDynamic };
+// Two different flavors of temporal layers are currently available:
+// kFixedPattern uses a fixed repeating pattern of 1-4 layers.
+// kBitrateDynamic can allocate frames dynamically to 1 or 2 layers, based on
+// the bitrate produced.
+enum class Vp8TemporalLayersType { kFixedPattern, kBitrateDynamic };
 
 struct CodecSpecificInfoVP8;
-enum class Vp8BufferReference : uint8_t {
-  kNone = 0,
-  kLast = 1,
-  kGolden = 2,
-  kAltref = 4
-};
 
 struct Vp8EncoderConfig {
   static constexpr size_t kMaxPeriodicity = 16;
@@ -72,9 +70,17 @@
   uint32_t rc_max_quantizer;
 };
 
+// Defined bit-maskable reference to the three buffers available in VP8.
+enum class Vp8BufferReference : uint8_t {
+  kNone = 0,
+  kLast = 1,
+  kGolden = 2,
+  kAltref = 4
+};
+
 // This interface defines a way of getting the encoder settings needed to
-// realize a temporal layer structure of predefined size.
-class TemporalLayers {
+// realize a temporal layer structure.
+class Vp8TemporalLayers {
  public:
   enum BufferFlags : int {
     kNone = 0,
@@ -124,9 +130,6 @@
     Vp8BufferReference first_reference;
     Vp8BufferReference second_reference;
 
-    bool operator==(const FrameConfig& o) const;
-    bool operator!=(const FrameConfig& o) const { return !(*this == o); }
-
    private:
     FrameConfig(BufferFlags last,
                 BufferFlags golden,
@@ -134,13 +137,7 @@
                 bool freeze_entropy);
   };
 
-  // Factory for TemporalLayer strategy. Default behavior is a fixed pattern
-  // of temporal layers. See default_temporal_layers.cc
-  static std::unique_ptr<TemporalLayers> CreateTemporalLayers(
-      TemporalLayersType type,
-      int num_temporal_layers);
-
-  virtual ~TemporalLayers() = default;
+  virtual ~Vp8TemporalLayers() = default;
 
   // If this method returns true, the encoder is free to drop frames for
   // instance in an effort to uphold encoding bitrate.
@@ -195,4 +192,4 @@
 
 }  // namespace webrtc
 
-#endif  // MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_TEMPORAL_LAYERS_H_
+#endif  // API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
diff --git a/media/engine/vp8_encoder_simulcast_proxy_unittest.cc b/media/engine/vp8_encoder_simulcast_proxy_unittest.cc
index d1dc9a3..fc6d5a6 100644
--- a/media/engine/vp8_encoder_simulcast_proxy_unittest.cc
+++ b/media/engine/vp8_encoder_simulcast_proxy_unittest.cc
@@ -10,12 +10,11 @@
  */
 
 #include "media/engine/vp8_encoder_simulcast_proxy.h"
-
 #include <string>
 
 #include "api/test/mock_video_encoder_factory.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "media/engine/webrtcvideoencoderfactory.h"
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index e97f4c8..b654128 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -393,22 +393,13 @@
   visibility = [ "*" ]
   poisonous = [ "software_video_codecs" ]
   sources = [
-    "codecs/vp8/default_temporal_layers.cc",
-    "codecs/vp8/default_temporal_layers.h",
-    "codecs/vp8/include/temporal_layers_checker.h",
     "codecs/vp8/include/vp8.h",
-    "codecs/vp8/include/vp8_temporal_layers.h",
     "codecs/vp8/libvpx_interface.cc",
     "codecs/vp8/libvpx_interface.h",
     "codecs/vp8/libvpx_vp8_decoder.cc",
     "codecs/vp8/libvpx_vp8_decoder.h",
     "codecs/vp8/libvpx_vp8_encoder.cc",
     "codecs/vp8/libvpx_vp8_encoder.h",
-    "codecs/vp8/screenshare_layers.cc",
-    "codecs/vp8/screenshare_layers.h",
-    "codecs/vp8/temporal_layers.h",
-    "codecs/vp8/temporal_layers_checker.cc",
-    "codecs/vp8/vp8_temporal_layers.cc",
   ]
 
   if (!build_with_chromium && is_clang) {
@@ -420,10 +411,12 @@
     ":codec_globals_headers",
     ":video_codec_interface",
     ":video_coding_utility",
+    ":webrtc_vp8_temporal_layers",
     "..:module_api",
     "../..:webrtc_common",
     "../../api/video:encoded_image",
     "../../api/video:video_frame",
+    "../../api/video_codecs:create_vp8_temporal_layers",
     "../../api/video_codecs:video_codecs_api",
     "../../common_video",
     "../../rtc_base:checks",
@@ -441,6 +434,41 @@
   }
 }
 
+rtc_static_library("webrtc_vp8_temporal_layers") {
+  visibility = [ "*" ]
+  sources = [
+    "codecs/vp8/default_temporal_layers.cc",
+    "codecs/vp8/default_temporal_layers.h",
+    "codecs/vp8/include/temporal_layers_checker.h",
+    "codecs/vp8/screenshare_layers.cc",
+    "codecs/vp8/screenshare_layers.h",
+    "codecs/vp8/temporal_layers.h",
+    "codecs/vp8/temporal_layers_checker.cc",
+  ]
+
+  if (!build_with_chromium && is_clang) {
+    # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
+    suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
+  }
+
+  deps = [
+    ":codec_globals_headers",
+    ":video_codec_interface",
+    ":video_coding_utility",
+    "..:module_api",
+    "../..:webrtc_common",
+    "../../api/video_codecs:video_codecs_api",
+    "../../rtc_base:checks",
+    "../../rtc_base:rtc_base_approved",
+    "../../rtc_base:rtc_numerics",
+    "../../system_wrappers",
+    "../../system_wrappers:field_trial",
+    "../../system_wrappers:metrics",
+    "//third_party/abseil-cpp/absl/memory",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
+}
+
 # This target includes VP9 files that may be used for any VP9 codec, internal SW or external HW.
 rtc_static_library("webrtc_vp9_helpers") {
   sources = [
@@ -848,6 +876,7 @@
       ":videocodec_test_impl",
       ":webrtc_h264",
       ":webrtc_vp8",
+      ":webrtc_vp8_temporal_layers",
       ":webrtc_vp9",
       ":webrtc_vp9_helpers",
       "..:module_api",
@@ -858,6 +887,7 @@
       "../../api/video:video_bitrate_allocator",
       "../../api/video:video_frame",
       "../../api/video:video_frame_i420",
+      "../../api/video_codecs:create_vp8_temporal_layers",
       "../../api/video_codecs:video_codecs_api",
       "../../common_video:common_video",
       "../../media:rtc_media_base",
diff --git a/modules/video_coding/codecs/vp8/default_temporal_layers.cc b/modules/video_coding/codecs/vp8/default_temporal_layers.cc
index d53f469..c5e163f 100644
--- a/modules/video_coding/codecs/vp8/default_temporal_layers.cc
+++ b/modules/video_coding/codecs/vp8/default_temporal_layers.cc
@@ -7,8 +7,6 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "modules/video_coding/codecs/vp8/default_temporal_layers.h"
-
 #include <stdlib.h>
 #include <string.h>
 
@@ -20,6 +18,7 @@
 #include <vector>
 
 #include "modules/include/module_common_types.h"
+#include "modules/video_coding/codecs/vp8/default_temporal_layers.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
@@ -27,27 +26,30 @@
 
 namespace webrtc {
 
-TemporalLayers::FrameConfig::FrameConfig()
+Vp8TemporalLayers::FrameConfig::FrameConfig()
     : FrameConfig(kNone, kNone, kNone, false) {}
 
-TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last,
-                                         TemporalLayers::BufferFlags golden,
-                                         TemporalLayers::BufferFlags arf)
+Vp8TemporalLayers::FrameConfig::FrameConfig(
+    Vp8TemporalLayers::BufferFlags last,
+    Vp8TemporalLayers::BufferFlags golden,
+    Vp8TemporalLayers::BufferFlags arf)
     : FrameConfig(last, golden, arf, false) {}
 
-TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last,
-                                         TemporalLayers::BufferFlags golden,
-                                         TemporalLayers::BufferFlags arf,
-                                         FreezeEntropy)
+Vp8TemporalLayers::FrameConfig::FrameConfig(
+    Vp8TemporalLayers::BufferFlags last,
+    Vp8TemporalLayers::BufferFlags golden,
+    Vp8TemporalLayers::BufferFlags arf,
+    FreezeEntropy)
     : FrameConfig(last, golden, arf, true) {}
 
-TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last,
-                                         TemporalLayers::BufferFlags golden,
-                                         TemporalLayers::BufferFlags arf,
-                                         bool freeze_entropy)
-    : drop_frame(last == TemporalLayers::kNone &&
-                 golden == TemporalLayers::kNone &&
-                 arf == TemporalLayers::kNone),
+Vp8TemporalLayers::FrameConfig::FrameConfig(
+    Vp8TemporalLayers::BufferFlags last,
+    Vp8TemporalLayers::BufferFlags golden,
+    Vp8TemporalLayers::BufferFlags arf,
+    bool freeze_entropy)
+    : drop_frame(last == Vp8TemporalLayers::kNone &&
+                 golden == Vp8TemporalLayers::kNone &&
+                 arf == Vp8TemporalLayers::kNone),
       last_buffer_flags(last),
       golden_buffer_flags(golden),
       arf_buffer_flags(arf),
@@ -106,15 +108,15 @@
   return {0};
 }
 
-uint8_t GetUpdatedBuffers(const TemporalLayers::FrameConfig& config) {
+uint8_t GetUpdatedBuffers(const Vp8TemporalLayers::FrameConfig& config) {
   uint8_t flags = 0;
-  if (config.last_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
+  if (config.last_buffer_flags & Vp8TemporalLayers::BufferFlags::kUpdate) {
     flags |= static_cast<uint8_t>(Vp8BufferReference::kLast);
   }
-  if (config.golden_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
+  if (config.golden_buffer_flags & Vp8TemporalLayers::BufferFlags::kUpdate) {
     flags |= static_cast<uint8_t>(Vp8BufferReference::kGolden);
   }
-  if (config.arf_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
+  if (config.arf_buffer_flags & Vp8TemporalLayers::BufferFlags::kUpdate) {
     flags |= static_cast<uint8_t>(Vp8BufferReference::kAltref);
   }
   return flags;
@@ -122,10 +124,10 @@
 
 // Find the set of buffers that are never updated by the given pattern.
 std::set<Vp8BufferReference> FindKfBuffers(
-    const std::vector<TemporalLayers::FrameConfig>& frame_configs) {
+    const std::vector<Vp8TemporalLayers::FrameConfig>& frame_configs) {
   std::set<Vp8BufferReference> kf_buffers(kAllBuffers.begin(),
                                           kAllBuffers.end());
-  for (TemporalLayers::FrameConfig config : frame_configs) {
+  for (Vp8TemporalLayers::FrameConfig config : frame_configs) {
     // Get bit-masked set of update buffers for this frame config.
     uint8_t updated_buffers = GetUpdatedBuffers(config);
     for (Vp8BufferReference buffer : kAllBuffers) {
@@ -138,7 +140,7 @@
 }
 }  // namespace
 
-std::vector<TemporalLayers::FrameConfig>
+std::vector<Vp8TemporalLayers::FrameConfig>
 DefaultTemporalLayers::GetTemporalPattern(size_t num_layers) {
   // For indexing in the patterns described below (which temporal layers they
   // belong to), see the diagram above.
@@ -262,7 +264,7 @@
       kf_buffers_(FindKfBuffers(temporal_pattern_)),
       pattern_idx_(kUninitializedPatternIndex),
       checker_(TemporalLayersChecker::CreateTemporalLayersChecker(
-          TemporalLayersType::kFixedPattern,
+          Vp8TemporalLayersType::kFixedPattern,
           number_of_temporal_layers)) {
   RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers);
   RTC_CHECK_GE(number_of_temporal_layers, 0);
@@ -278,6 +280,8 @@
   }
 }
 
+DefaultTemporalLayers::~DefaultTemporalLayers() = default;
+
 bool DefaultTemporalLayers::SupportsEncoderFrameDropping() const {
   // This class allows the encoder drop frames as it sees fit.
   return true;
@@ -346,13 +350,13 @@
   return true;
 }
 
-TemporalLayers::FrameConfig DefaultTemporalLayers::UpdateLayerConfig(
+Vp8TemporalLayers::FrameConfig DefaultTemporalLayers::UpdateLayerConfig(
     uint32_t timestamp) {
   RTC_DCHECK_GT(num_layers_, 0);
   RTC_DCHECK_LT(0, temporal_pattern_.size());
 
   pattern_idx_ = (pattern_idx_ + 1) % temporal_pattern_.size();
-  TemporalLayers::FrameConfig tl_config = temporal_pattern_[pattern_idx_];
+  Vp8TemporalLayers::FrameConfig tl_config = temporal_pattern_[pattern_idx_];
   tl_config.encoder_layer_id = tl_config.packetizer_temporal_idx =
       temporal_ids_[pattern_idx_ % temporal_ids_.size()];
 
@@ -560,9 +564,11 @@
   }
 }
 
+DefaultTemporalLayersChecker::~DefaultTemporalLayersChecker() = default;
+
 bool DefaultTemporalLayersChecker::CheckTemporalConfig(
     bool frame_is_keyframe,
-    const TemporalLayers::FrameConfig& frame_config) {
+    const Vp8TemporalLayers::FrameConfig& frame_config) {
   if (!TemporalLayersChecker::CheckTemporalConfig(frame_is_keyframe,
                                                   frame_config)) {
     return false;
@@ -613,7 +619,7 @@
   std::vector<int> dependencies;
 
   if (frame_config.last_buffer_flags &
-      TemporalLayers::BufferFlags::kReference) {
+      Vp8TemporalLayers::BufferFlags::kReference) {
     uint8_t referenced_layer = temporal_ids_[last_.pattern_idx];
     if (referenced_layer > 0) {
       need_sync = false;
@@ -628,7 +634,8 @@
     return false;
   }
 
-  if (frame_config.arf_buffer_flags & TemporalLayers::BufferFlags::kReference) {
+  if (frame_config.arf_buffer_flags &
+      Vp8TemporalLayers::BufferFlags::kReference) {
     uint8_t referenced_layer = temporal_ids_[arf_.pattern_idx];
     if (referenced_layer > 0) {
       need_sync = false;
@@ -644,7 +651,7 @@
   }
 
   if (frame_config.golden_buffer_flags &
-      TemporalLayers::BufferFlags::kReference) {
+      Vp8TemporalLayers::BufferFlags::kReference) {
     uint8_t referenced_layer = temporal_ids_[golden_.pattern_idx];
     if (referenced_layer > 0) {
       need_sync = false;
@@ -680,17 +687,19 @@
     }
   }
 
-  if (frame_config.last_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
+  if (frame_config.last_buffer_flags &
+      Vp8TemporalLayers::BufferFlags::kUpdate) {
     last_.is_updated_this_cycle = true;
     last_.pattern_idx = pattern_idx_;
     last_.is_keyframe = false;
   }
-  if (frame_config.arf_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
+  if (frame_config.arf_buffer_flags & Vp8TemporalLayers::BufferFlags::kUpdate) {
     arf_.is_updated_this_cycle = true;
     arf_.pattern_idx = pattern_idx_;
     arf_.is_keyframe = false;
   }
-  if (frame_config.golden_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
+  if (frame_config.golden_buffer_flags &
+      Vp8TemporalLayers::BufferFlags::kUpdate) {
     golden_.is_updated_this_cycle = true;
     golden_.pattern_idx = pattern_idx_;
     golden_.is_keyframe = false;
diff --git a/modules/video_coding/codecs/vp8/default_temporal_layers.h b/modules/video_coding/codecs/vp8/default_temporal_layers.h
index bda43cd..fff62a5 100644
--- a/modules/video_coding/codecs/vp8/default_temporal_layers.h
+++ b/modules/video_coding/codecs/vp8/default_temporal_layers.h
@@ -18,23 +18,23 @@
 #include <set>
 #include <vector>
 
-#include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h"
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
-
 #include "absl/types/optional.h"
 
+#include "api/video_codecs/vp8_temporal_layers.h"
+#include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h"
+
 namespace webrtc {
 
-class DefaultTemporalLayers : public TemporalLayers {
+class DefaultTemporalLayers : public Vp8TemporalLayers {
  public:
   explicit DefaultTemporalLayers(int number_of_temporal_layers);
-  virtual ~DefaultTemporalLayers() {}
+  ~DefaultTemporalLayers() override;
 
   bool SupportsEncoderFrameDropping() const override;
 
   // Returns the recommended VP8 encode flags needed. May refresh the decoder
   // and/or update the reference buffers.
-  TemporalLayers::FrameConfig UpdateLayerConfig(uint32_t timestamp) override;
+  Vp8TemporalLayers::FrameConfig UpdateLayerConfig(uint32_t timestamp) override;
 
   // New target bitrate, per temporal layer.
   void OnRatesUpdated(const std::vector<uint32_t>& bitrates_bps,
@@ -50,7 +50,7 @@
 
  private:
   static constexpr size_t kKeyframeBuffer = std::numeric_limits<size_t>::max();
-  static std::vector<TemporalLayers::FrameConfig> GetTemporalPattern(
+  static std::vector<Vp8TemporalLayers::FrameConfig> GetTemporalPattern(
       size_t num_layers);
   bool IsSyncFrame(const FrameConfig& config) const;
   void ValidateReferences(BufferFlags* flags, Vp8BufferReference ref) const;
@@ -58,7 +58,7 @@
 
   const size_t num_layers_;
   const std::vector<unsigned int> temporal_ids_;
-  const std::vector<TemporalLayers::FrameConfig> temporal_pattern_;
+  const std::vector<Vp8TemporalLayers::FrameConfig> temporal_pattern_;
   // Set of buffers that are never updated except by keyframes.
   const std::set<Vp8BufferReference> kf_buffers_;
 
@@ -95,9 +95,11 @@
 class DefaultTemporalLayersChecker : public TemporalLayersChecker {
  public:
   explicit DefaultTemporalLayersChecker(int number_of_temporal_layers);
+  ~DefaultTemporalLayersChecker() override;
+
   bool CheckTemporalConfig(
       bool frame_is_keyframe,
-      const TemporalLayers::FrameConfig& frame_config) override;
+      const Vp8TemporalLayers::FrameConfig& frame_config) override;
 
  private:
   struct BufferState {
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 ad31a6e..5ee6520 100644
--- a/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc
+++ b/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc
@@ -74,7 +74,7 @@
 constexpr int kDefaultQp = 2;
 }  // namespace
 
-using BufferFlags = TemporalLayers::BufferFlags;
+using BufferFlags = Vp8TemporalLayers::BufferFlags;
 
 TEST(TemporalLayersTest, 2Layers) {
   constexpr int kNumLayers = 2;
@@ -114,7 +114,7 @@
 
   uint32_t timestamp = 0;
   for (int i = 0; i < 16; ++i) {
-    TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+    Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
     EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
     tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
                     &vp8_info);
@@ -166,7 +166,7 @@
 
   unsigned int timestamp = 0;
   for (int i = 0; i < 16; ++i) {
-    TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+    Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
     EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
     tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
                     &vp8_info);
@@ -207,7 +207,7 @@
 
   unsigned int timestamp = 0;
   for (int i = 0; i < 8; ++i) {
-    TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+    Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
     EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
     tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
                     &vp8_info);
@@ -238,7 +238,7 @@
 
   // Start with a key-frame. tl_config flags can be ignored.
   uint32_t timestamp = 0;
-  TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+  Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
   tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                   &vp8_info);
 
@@ -282,7 +282,7 @@
 
   // Start with a key-frame. tl_config flags can be ignored.
   uint32_t timestamp = 0;
-  TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+  Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
   tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                   &vp8_info);
 
@@ -343,7 +343,7 @@
 
   uint32_t timestamp = 0;
   for (int i = 0; i < 16; ++i) {
-    TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+    Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
     EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
     tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
                     &vp8_info);
@@ -373,7 +373,7 @@
 
   // Start with a keyframe.
   uint32_t timestamp = 0;
-  TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+  Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
   tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                   &vp8_info);
 
@@ -460,7 +460,7 @@
 
   // Start with a keyframe.
   uint32_t timestamp = 0;
-  TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+  Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
   tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                   &vp8_info);
 
@@ -530,7 +530,7 @@
 
   // Start with a keyframe.
   uint32_t timestamp = 0;
-  TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+  Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
   tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                   &vp8_info);
 
@@ -610,7 +610,8 @@
     for (int j = 1; j <= i; ++j) {
       // Since last frame was always a keyframe and thus index 0 in the pattern,
       // this loop starts at index 1.
-      TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+      Vp8TemporalLayers::FrameConfig tl_config =
+          tl.UpdateLayerConfig(timestamp);
       EXPECT_EQ(expected_flags[j], LibvpxVp8Encoder::EncodeFlags(tl_config))
           << j;
       tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
@@ -622,7 +623,7 @@
       timestamp += 3000;
     }
 
-    TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
+    Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
     tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                     &vp8_info);
     EXPECT_TRUE(vp8_info.layerSync) << "Key frame should be marked layer sync.";
@@ -652,9 +653,9 @@
     bool sync;
   };
 
-  bool UpdateSyncRefState(const TemporalLayers::BufferFlags& flags,
+  bool UpdateSyncRefState(const Vp8TemporalLayers::BufferFlags& flags,
                           BufferState* buffer_state) {
-    if (flags & TemporalLayers::kReference) {
+    if (flags & Vp8TemporalLayers::kReference) {
       if (buffer_state->temporal_idx == -1)
         return true;  // References key-frame.
       if (buffer_state->temporal_idx == 0) {
@@ -668,10 +669,10 @@
     return true;  // No reference, does not affect sync frame status.
   }
 
-  void ValidateReference(const TemporalLayers::BufferFlags& flags,
+  void ValidateReference(const Vp8TemporalLayers::BufferFlags& flags,
                          const BufferState& buffer_state,
                          int temporal_layer) {
-    if (flags & TemporalLayers::kReference) {
+    if (flags & Vp8TemporalLayers::kReference) {
       if (temporal_layer > 0 && buffer_state.timestamp > 0) {
         // Check that high layer reference does not go past last sync frame.
         EXPECT_GE(buffer_state.timestamp, last_sync_timestamp_);
@@ -709,9 +710,9 @@
   // (any). If a given buffer is never updated, it is legal to reference it
   // even for sync frames. In order to be general, don't assume TL0 always
   // updates |last|.
-  std::vector<TemporalLayers::FrameConfig> tl_configs(kMaxPatternLength);
+  std::vector<Vp8TemporalLayers::FrameConfig> tl_configs(kMaxPatternLength);
   for (int i = 0; i < kMaxPatternLength; ++i) {
-    TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp_);
+    Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp_);
     tl.OnEncodeDone(timestamp_, kDefaultBytesPerFrame, i == 0, kDefaultQp,
                     &vp8_specifics);
     ++timestamp_;
@@ -752,11 +753,11 @@
 
     // Update the current layer state.
     BufferState state = {temporal_idx, timestamp_, is_sync_frame};
-    if (tl_config.last_buffer_flags & TemporalLayers::kUpdate)
+    if (tl_config.last_buffer_flags & Vp8TemporalLayers::kUpdate)
       last_state = state;
-    if (tl_config.golden_buffer_flags & TemporalLayers::kUpdate)
+    if (tl_config.golden_buffer_flags & Vp8TemporalLayers::kUpdate)
       golden_state = state;
-    if (tl_config.arf_buffer_flags & TemporalLayers::kUpdate)
+    if (tl_config.arf_buffer_flags & Vp8TemporalLayers::kUpdate)
       altref_state = state;
   }
 }
diff --git a/modules/video_coding/codecs/vp8/include/temporal_layers_checker.h b/modules/video_coding/codecs/vp8/include/temporal_layers_checker.h
index 9878ac9..ae14f68 100644
--- a/modules/video_coding/codecs/vp8/include/temporal_layers_checker.h
+++ b/modules/video_coding/codecs/vp8/include/temporal_layers_checker.h
@@ -15,7 +15,7 @@
 
 #include <memory>
 
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 
 namespace webrtc {
 
@@ -29,10 +29,10 @@
 
   virtual bool CheckTemporalConfig(
       bool frame_is_keyframe,
-      const TemporalLayers::FrameConfig& frame_config);
+      const Vp8TemporalLayers::FrameConfig& frame_config);
 
   static std::unique_ptr<TemporalLayersChecker> CreateTemporalLayersChecker(
-      TemporalLayersType type,
+      Vp8TemporalLayersType type,
       int num_temporal_layers);
 
  private:
@@ -46,7 +46,7 @@
                                  bool* need_sync,
                                  bool frame_is_keyframe,
                                  uint8_t temporal_layer,
-                                 webrtc::TemporalLayers::BufferFlags flags,
+                                 webrtc::Vp8TemporalLayers::BufferFlags flags,
                                  uint32_t sequence_number,
                                  uint32_t* lowest_sequence_referenced);
   BufferState last_;
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
index 06b2b22..a7f060f 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
@@ -14,6 +14,8 @@
 #include <vector>
 
 #include "absl/memory/memory.h"
+#include "api/video_codecs/create_vp8_temporal_layers.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "common_video/libyuv/include/webrtc_libyuv.h"
 #include "modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h"
 #include "modules/video_coding/utility/simulcast_rate_allocator.h"
@@ -113,7 +115,7 @@
   vpx_config->rc_max_quantizer = config.rc_max_quantizer;
 }
 
-bool UpdateVpxConfiguration(TemporalLayers* temporal_layers,
+bool UpdateVpxConfiguration(Vp8TemporalLayers* temporal_layers,
                             vpx_codec_enc_cfg_t* cfg) {
   Vp8EncoderConfig config = GetEncoderConfig(cfg);
   const bool res = temporal_layers->UpdateConfiguration(&config);
@@ -129,22 +131,22 @@
 }
 
 vpx_enc_frame_flags_t LibvpxVp8Encoder::EncodeFlags(
-    const TemporalLayers::FrameConfig& references) {
+    const Vp8TemporalLayers::FrameConfig& references) {
   RTC_DCHECK(!references.drop_frame);
 
   vpx_enc_frame_flags_t flags = 0;
 
-  if ((references.last_buffer_flags & TemporalLayers::kReference) == 0)
+  if ((references.last_buffer_flags & Vp8TemporalLayers::kReference) == 0)
     flags |= VP8_EFLAG_NO_REF_LAST;
-  if ((references.last_buffer_flags & TemporalLayers::kUpdate) == 0)
+  if ((references.last_buffer_flags & Vp8TemporalLayers::kUpdate) == 0)
     flags |= VP8_EFLAG_NO_UPD_LAST;
-  if ((references.golden_buffer_flags & TemporalLayers::kReference) == 0)
+  if ((references.golden_buffer_flags & Vp8TemporalLayers::kReference) == 0)
     flags |= VP8_EFLAG_NO_REF_GF;
-  if ((references.golden_buffer_flags & TemporalLayers::kUpdate) == 0)
+  if ((references.golden_buffer_flags & Vp8TemporalLayers::kUpdate) == 0)
     flags |= VP8_EFLAG_NO_UPD_GF;
-  if ((references.arf_buffer_flags & TemporalLayers::kReference) == 0)
+  if ((references.arf_buffer_flags & Vp8TemporalLayers::kReference) == 0)
     flags |= VP8_EFLAG_NO_REF_ARF;
-  if ((references.arf_buffer_flags & TemporalLayers::kUpdate) == 0)
+  if ((references.arf_buffer_flags & Vp8TemporalLayers::kUpdate) == 0)
     flags |= VP8_EFLAG_NO_UPD_ARF;
   if (references.freeze_entropy)
     flags |= VP8_EFLAG_NO_UPD_ENTROPY;
@@ -167,7 +169,6 @@
       rc_max_intra_target_(0),
       key_frame_request_(kMaxSimulcastStreams, false) {
   temporal_layers_.reserve(kMaxSimulcastStreams);
-  temporal_layers_checkers_.reserve(kMaxSimulcastStreams);
   raw_images_.reserve(kMaxSimulcastStreams);
   encoded_images_.reserve(kMaxSimulcastStreams);
   send_stream_.reserve(kMaxSimulcastStreams);
@@ -206,7 +207,6 @@
     raw_images_.pop_back();
   }
   temporal_layers_.clear();
-  temporal_layers_checkers_.clear();
   inited_ = false;
   return ret_val;
 }
@@ -294,21 +294,18 @@
   RTC_DCHECK(temporal_layers_.empty());
   int num_streams = SimulcastUtility::NumberOfSimulcastStreams(codec);
   for (int i = 0; i < num_streams; ++i) {
-    TemporalLayersType type;
+    Vp8TemporalLayersType type;
     int num_temporal_layers =
         SimulcastUtility::NumberOfTemporalLayers(codec, i);
     if (SimulcastUtility::IsConferenceModeScreenshare(codec) && i == 0) {
-      type = TemporalLayersType::kBitrateDynamic;
+      type = Vp8TemporalLayersType::kBitrateDynamic;
       // Legacy screenshare layers supports max 2 layers.
       num_temporal_layers = std::max<int>(2, num_temporal_layers);
     } else {
-      type = TemporalLayersType::kFixedPattern;
+      type = Vp8TemporalLayersType::kFixedPattern;
     }
     temporal_layers_.emplace_back(
-        TemporalLayers::CreateTemporalLayers(type, num_temporal_layers));
-    temporal_layers_checkers_.emplace_back(
-        TemporalLayersChecker::CreateTemporalLayersChecker(
-            type, num_temporal_layers));
+        CreateVp8TemporalLayers(type, num_temporal_layers));
   }
 }
 
@@ -750,7 +747,7 @@
     }
   }
   vpx_enc_frame_flags_t flags[kMaxSimulcastStreams];
-  TemporalLayers::FrameConfig tl_configs[kMaxSimulcastStreams];
+  Vp8TemporalLayers::FrameConfig tl_configs[kMaxSimulcastStreams];
   for (size_t i = 0; i < encoders_.size(); ++i) {
     tl_configs[i] = temporal_layers_[i]->UpdateLayerConfig(frame.timestamp());
     if (tl_configs[i].drop_frame) {
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
index 93888e8..40bfb08 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
@@ -17,10 +17,9 @@
 #include "api/video/encoded_image.h"
 #include "api/video/video_frame.h"
 #include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "common_types.h"  // NOLINT(build/include)
-#include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h"
 #include "modules/video_coding/codecs/vp8/include/vp8.h"
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/codecs/vp8/libvpx_interface.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 
@@ -57,7 +56,7 @@
   const char* ImplementationName() const override;
 
   static vpx_enc_frame_flags_t EncodeFlags(
-      const TemporalLayers::FrameConfig& references);
+      const Vp8TemporalLayers::FrameConfig& references);
 
  private:
   void SetupTemporalLayers(const VideoCodec& codec);
@@ -97,8 +96,7 @@
   int cpu_speed_default_;
   int number_of_cores_;
   uint32_t rc_max_intra_target_;
-  std::vector<std::unique_ptr<TemporalLayers>> temporal_layers_;
-  std::vector<std::unique_ptr<TemporalLayersChecker>> temporal_layers_checkers_;
+  std::vector<std::unique_ptr<Vp8TemporalLayers>> temporal_layers_;
   std::vector<bool> key_frame_request_;
   std::vector<bool> send_stream_;
   std::vector<int> cpu_speed_;
diff --git a/modules/video_coding/codecs/vp8/screenshare_layers.cc b/modules/video_coding/codecs/vp8/screenshare_layers.cc
index 76c4382..ede21e55 100644
--- a/modules/video_coding/codecs/vp8/screenshare_layers.cc
+++ b/modules/video_coding/codecs/vp8/screenshare_layers.cc
@@ -53,7 +53,7 @@
       encode_framerate_(1000.0f, 1000.0f),  // 1 second window, second scale.
       bitrate_updated_(false),
       checker_(TemporalLayersChecker::CreateTemporalLayersChecker(
-          TemporalLayersType::kBitrateDynamic,
+          Vp8TemporalLayersType::kBitrateDynamic,
           num_temporal_layers)) {
   RTC_CHECK_GT(number_of_temporal_layers_, 0);
   RTC_CHECK_LE(number_of_temporal_layers_, kMaxNumTemporalLayers);
@@ -68,7 +68,7 @@
   return false;
 }
 
-TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
+Vp8TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
     uint32_t timestamp) {
   auto it = pending_frame_configs_.find(timestamp);
   if (it != pending_frame_configs_.end()) {
@@ -79,7 +79,7 @@
   if (number_of_temporal_layers_ <= 1) {
     // No flags needed for 1 layer screenshare.
     // TODO(pbos): Consider updating only last, and not all buffers.
-    TemporalLayers::FrameConfig tl_config(
+    Vp8TemporalLayers::FrameConfig tl_config(
         kReferenceAndUpdate, kReferenceAndUpdate, kReferenceAndUpdate);
     pending_frame_configs_[timestamp] = tl_config;
     return tl_config;
@@ -100,7 +100,7 @@
     // averaging window, or if frame interval is below 90% of desired value,
     // drop frame.
     if (encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_)
-      return TemporalLayers::FrameConfig(kNone, kNone, kNone);
+      return Vp8TemporalLayers::FrameConfig(kNone, kNone, kNone);
 
     // Primarily check if frame interval is too short using frame timestamps,
     // as if they are correct they won't be affected by queuing in webrtc.
@@ -108,7 +108,7 @@
         kOneSecond90Khz / *target_framerate_;
     if (last_timestamp_ != -1 && ts_diff > 0) {
       if (ts_diff < 85 * expected_frame_interval_90khz / 100) {
-        return TemporalLayers::FrameConfig(kNone, kNone, kNone);
+        return Vp8TemporalLayers::FrameConfig(kNone, kNone, kNone);
       }
     } else {
       // Timestamps looks off, use realtime clock here instead.
@@ -116,7 +116,7 @@
       if (last_frame_time_ms_ != -1 &&
           now_ms - last_frame_time_ms_ <
               (85 * expected_frame_interval_ms) / 100) {
-        return TemporalLayers::FrameConfig(kNone, kNone, kNone);
+        return Vp8TemporalLayers::FrameConfig(kNone, kNone, kNone);
       }
     }
   }
@@ -182,30 +182,30 @@
       RTC_NOTREACHED();
   }
 
-  TemporalLayers::FrameConfig tl_config;
+  Vp8TemporalLayers::FrameConfig tl_config;
   // TODO(pbos): Consider referencing but not updating the 'alt' buffer for all
   // layers.
   switch (layer_state) {
     case TemporalLayerState::kDrop:
-      tl_config = TemporalLayers::FrameConfig(kNone, kNone, kNone);
+      tl_config = Vp8TemporalLayers::FrameConfig(kNone, kNone, kNone);
       break;
     case TemporalLayerState::kTl0:
       // TL0 only references and updates 'last'.
       tl_config =
-          TemporalLayers::FrameConfig(kReferenceAndUpdate, kNone, kNone);
+          Vp8TemporalLayers::FrameConfig(kReferenceAndUpdate, kNone, kNone);
       tl_config.packetizer_temporal_idx = 0;
       break;
     case TemporalLayerState::kTl1:
       // TL1 references both 'last' and 'golden' but only updates 'golden'.
-      tl_config =
-          TemporalLayers::FrameConfig(kReference, kReferenceAndUpdate, kNone);
+      tl_config = Vp8TemporalLayers::FrameConfig(kReference,
+                                                 kReferenceAndUpdate, kNone);
       tl_config.packetizer_temporal_idx = 1;
       break;
     case TemporalLayerState::kTl1Sync:
       // Predict from only TL0 to allow participants to switch to the high
       // bitrate stream. Updates 'golden' so that TL1 can continue to refer to
       // and update 'golden' from this point on.
-      tl_config = TemporalLayers::FrameConfig(kReference, kUpdate, kNone);
+      tl_config = Vp8TemporalLayers::FrameConfig(kReference, kUpdate, kNone);
       tl_config.packetizer_temporal_idx = 1;
       break;
   }
diff --git a/modules/video_coding/codecs/vp8/screenshare_layers.h b/modules/video_coding/codecs/vp8/screenshare_layers.h
index 6193be3..0359b2c 100644
--- a/modules/video_coding/codecs/vp8/screenshare_layers.h
+++ b/modules/video_coding/codecs/vp8/screenshare_layers.h
@@ -13,8 +13,8 @@
 #include <memory>
 #include <vector>
 
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h"
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/utility/frame_dropper.h"
 #include "rtc_base/rate_statistics.h"
 #include "rtc_base/timeutils.h"
@@ -24,7 +24,7 @@
 struct CodecSpecificInfoVP8;
 class Clock;
 
-class ScreenshareLayers : public TemporalLayers {
+class ScreenshareLayers : public Vp8TemporalLayers {
  public:
   static const double kMaxTL0FpsReduction;
   static const double kAcceptableTargetOvershoot;
@@ -38,7 +38,7 @@
 
   // Returns the recommended VP8 encode flags needed. May refresh the decoder
   // and/or update the reference buffers.
-  TemporalLayers::FrameConfig UpdateLayerConfig(
+  Vp8TemporalLayers::FrameConfig UpdateLayerConfig(
       uint32_t rtp_timestamp) override;
 
   // New target bitrate, per temporal layer.
@@ -74,7 +74,7 @@
   int max_qp_;
   uint32_t max_debt_bytes_;
 
-  std::map<uint32_t, TemporalLayers::FrameConfig> pending_frame_configs_;
+  std::map<uint32_t, Vp8TemporalLayers::FrameConfig> pending_frame_configs_;
 
   // Configured max framerate.
   absl::optional<uint32_t> target_framerate_;
diff --git a/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc b/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc
index 4ae7ed5..474e4f8 100644
--- a/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc
+++ b/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc
@@ -87,7 +87,7 @@
     return flags;
   }
 
-  TemporalLayers::FrameConfig UpdateLayerConfig(uint32_t timestamp) {
+  Vp8TemporalLayers::FrameConfig UpdateLayerConfig(uint32_t timestamp) {
     int64_t timestamp_ms = timestamp / 90;
     clock_.AdvanceTimeMilliseconds(timestamp_ms - clock_.TimeInMilliseconds());
     return layers_->UpdateLayerConfig(timestamp);
@@ -167,7 +167,7 @@
   std::unique_ptr<ScreenshareLayers> layers_;
 
   uint32_t timestamp_;
-  TemporalLayers::FrameConfig tl_config_;
+  Vp8TemporalLayers::FrameConfig tl_config_;
   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 788d69a..9576fb2 100644
--- a/modules/video_coding/codecs/vp8/temporal_layers.h
+++ b/modules/video_coding/codecs/vp8/temporal_layers.h
@@ -12,6 +12,6 @@
 #define MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_
 
 // TODO(webrtc:9012) Remove this file when downstream projects have updated.
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 
 #endif  // MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_
diff --git a/modules/video_coding/codecs/vp8/temporal_layers_checker.cc b/modules/video_coding/codecs/vp8/temporal_layers_checker.cc
index c0a736a..4dba7a3 100644
--- a/modules/video_coding/codecs/vp8/temporal_layers_checker.cc
+++ b/modules/video_coding/codecs/vp8/temporal_layers_checker.cc
@@ -17,13 +17,13 @@
 namespace webrtc {
 
 std::unique_ptr<TemporalLayersChecker>
-TemporalLayersChecker::CreateTemporalLayersChecker(TemporalLayersType type,
+TemporalLayersChecker::CreateTemporalLayersChecker(Vp8TemporalLayersType type,
                                                    int num_temporal_layers) {
   switch (type) {
-    case TemporalLayersType::kFixedPattern:
+    case Vp8TemporalLayersType::kFixedPattern:
       return absl::make_unique<DefaultTemporalLayersChecker>(
           num_temporal_layers);
-    case TemporalLayersType::kBitrateDynamic:
+    case Vp8TemporalLayersType::kBitrateDynamic:
       // Conference mode temporal layering for screen content in base stream.
       return absl::make_unique<TemporalLayersChecker>(num_temporal_layers);
   }
@@ -40,10 +40,10 @@
     bool* need_sync,
     bool frame_is_keyframe,
     uint8_t temporal_layer,
-    webrtc::TemporalLayers::BufferFlags flags,
+    webrtc::Vp8TemporalLayers::BufferFlags flags,
     uint32_t sequence_number,
     uint32_t* lowest_sequence_referenced) {
-  if (flags & TemporalLayers::BufferFlags::kReference) {
+  if (flags & Vp8TemporalLayers::BufferFlags::kReference) {
     if (state->temporal_layer > 0 && !state->is_keyframe) {
       *need_sync = false;
     }
@@ -57,7 +57,7 @@
       return false;
     }
   }
-  if ((flags & TemporalLayers::BufferFlags::kUpdate)) {
+  if ((flags & Vp8TemporalLayers::BufferFlags::kUpdate)) {
     state->temporal_layer = temporal_layer;
     state->sequence_number = sequence_number;
     state->is_keyframe = frame_is_keyframe;
@@ -69,7 +69,7 @@
 
 bool TemporalLayersChecker::CheckTemporalConfig(
     bool frame_is_keyframe,
-    const TemporalLayers::FrameConfig& frame_config) {
+    const Vp8TemporalLayers::FrameConfig& frame_config) {
   if (frame_config.drop_frame ||
       frame_config.packetizer_temporal_idx == kNoTemporalIdx) {
     return true;
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 23f1416..31c6e15 100644
--- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
@@ -12,10 +12,10 @@
 
 #include <memory>
 
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "common_video/libyuv/include/webrtc_libyuv.h"
 #include "modules/video_coding/codecs/test/video_codec_unittest.h"
 #include "modules/video_coding/codecs/vp8/include/vp8.h"
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h"
 #include "modules/video_coding/codecs/vp8/test/mock_libvpx_interface.h"
 #include "modules/video_coding/include/mock/mock_video_codec_interface.h"
diff --git a/modules/video_coding/codecs/vp8/vp8_temporal_layers.cc b/modules/video_coding/codecs/vp8/vp8_temporal_layers.cc
deleted file mode 100644
index 4958441..0000000
--- a/modules/video_coding/codecs/vp8/vp8_temporal_layers.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
-
-#include "absl/memory/memory.h"
-#include "modules/video_coding/codecs/vp8/default_temporal_layers.h"
-#include "modules/video_coding/codecs/vp8/screenshare_layers.h"
-#include "system_wrappers/include/clock.h"
-
-namespace webrtc {
-
-bool TemporalLayers::FrameConfig::operator==(const FrameConfig& o) const {
-  return drop_frame == o.drop_frame &&
-         last_buffer_flags == o.last_buffer_flags &&
-         golden_buffer_flags == o.golden_buffer_flags &&
-         arf_buffer_flags == o.arf_buffer_flags && layer_sync == o.layer_sync &&
-         freeze_entropy == o.freeze_entropy &&
-         encoder_layer_id == o.encoder_layer_id &&
-         packetizer_temporal_idx == o.packetizer_temporal_idx;
-}
-
-std::unique_ptr<TemporalLayers> TemporalLayers::CreateTemporalLayers(
-    TemporalLayersType type,
-    int num_temporal_layers) {
-  switch (type) {
-    case TemporalLayersType::kFixedPattern:
-      return absl::make_unique<DefaultTemporalLayers>(num_temporal_layers);
-    case TemporalLayersType::kBitrateDynamic:
-      // Conference mode temporal layering for screen content in base stream.
-      return absl::make_unique<ScreenshareLayers>(num_temporal_layers,
-                                                  Clock::GetRealTimeClock());
-  }
-}
-
-}  // namespace webrtc
diff --git a/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc b/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc
index 7f54932..bbe3f19 100644
--- a/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc
+++ b/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc
@@ -15,8 +15,7 @@
 #include <utility>
 #include <vector>
 
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
-
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "test/field_trial.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
@@ -34,9 +33,9 @@
 constexpr uint32_t kSimulcastScreenshareMinBitrateKbps = 600;
 constexpr uint32_t kSimulcastScreenshareMaxBitrateKbps = 1250;
 
-class MockTemporalLayers : public TemporalLayers {
+class MockTemporalLayers : public Vp8TemporalLayers {
  public:
-  MOCK_METHOD1(UpdateLayerConfig, TemporalLayers::FrameConfig(uint32_t));
+  MOCK_METHOD1(UpdateLayerConfig, Vp8TemporalLayers::FrameConfig(uint32_t));
   MOCK_METHOD2(OnRatesUpdated, void(const std::vector<uint32_t>&, int));
   MOCK_METHOD1(UpdateConfiguration, bool(Vp8EncoderConfig*));
   MOCK_METHOD5(OnEncodeDone,
@@ -44,7 +43,7 @@
   MOCK_METHOD3(FrameEncoded, void(uint32_t, size_t, int));
   MOCK_CONST_METHOD0(Tl0PicIdx, uint8_t());
   MOCK_CONST_METHOD1(GetTemporalLayerId,
-                     int(const TemporalLayers::FrameConfig&));
+                     int(const Vp8TemporalLayers::FrameConfig&));
 };
 }  // namespace
 
diff --git a/modules/video_coding/video_codec_initializer_unittest.cc b/modules/video_coding/video_codec_initializer_unittest.cc
index fb601f0..335ca6b 100644
--- a/modules/video_coding/video_codec_initializer_unittest.cc
+++ b/modules/video_coding/video_codec_initializer_unittest.cc
@@ -10,9 +10,10 @@
 
 #include "modules/video_coding/include/video_codec_initializer.h"
 #include "api/video/video_bitrate_allocator.h"
+#include "api/video_codecs/create_vp8_temporal_layers.h"
 #include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "common_types.h"  // NOLINT(build/include)
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
 #include "rtc_base/refcountedobject.h"
 #include "test/gtest.h"
@@ -86,9 +87,9 @@
     // Make sure temporal layers instances have been created.
     if (codec_out_.codecType == VideoCodecType::kVideoCodecVP8) {
       for (int i = 0; i < codec_out_.numberOfSimulcastStreams; ++i) {
-        temporal_layers_.emplace_back(TemporalLayers::CreateTemporalLayers(
-            TemporalLayersType::kFixedPattern,
-            codec_out_.VP8()->numberOfTemporalLayers));
+        temporal_layers_.emplace_back(
+            CreateVp8TemporalLayers(Vp8TemporalLayersType::kFixedPattern,
+                                    codec_out_.VP8()->numberOfTemporalLayers));
       }
     }
     return true;
@@ -126,7 +127,7 @@
   // Output.
   VideoCodec codec_out_;
   std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_out_;
-  std::vector<std::unique_ptr<TemporalLayers>> temporal_layers_;
+  std::vector<std::unique_ptr<Vp8TemporalLayers>> temporal_layers_;
 };
 
 TEST_F(VideoCodecInitializerTest, SingleStreamVp8Screenshare) {
diff --git a/modules/video_coding/video_sender_unittest.cc b/modules/video_coding/video_sender_unittest.cc
index 3cd9caf..eb3c09c 100644
--- a/modules/video_coding/video_sender_unittest.cc
+++ b/modules/video_coding/video_sender_unittest.cc
@@ -12,8 +12,8 @@
 #include <vector>
 
 #include "api/video/i420_buffer.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "modules/video_coding/codecs/vp8/include/vp8.h"
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/include/mock/mock_vcm_callbacks.h"
 #include "modules/video_coding/include/mock/mock_video_codec_interface.h"
 #include "modules/video_coding/include/video_coding.h"
diff --git a/test/BUILD.gn b/test/BUILD.gn
index a393448..b38e215 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -541,6 +541,7 @@
     "..:webrtc_common",
     "../api/video:encoded_image",
     "../api/video:video_frame_i420",
+    "../api/video_codecs:create_vp8_temporal_layers",
     "../api/video_codecs:video_codecs_api",
     "../common_video:common_video",
     "../modules/video_coding:video_codec_interface",
diff --git a/test/fake_encoder.cc b/test/fake_encoder.cc
index 9e1e1fe..8e2c7dd 100644
--- a/test/fake_encoder.cc
+++ b/test/fake_encoder.cc
@@ -15,8 +15,8 @@
 #include <algorithm>
 #include <memory>
 
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "common_types.h"  // NOLINT(build/include)
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "rtc_base/checks.h"
 #include "system_wrappers/include/sleep.h"
diff --git a/test/fake_vp8_encoder.cc b/test/fake_vp8_encoder.cc
index 5c299a7..82ba88b 100644
--- a/test/fake_vp8_encoder.cc
+++ b/test/fake_vp8_encoder.cc
@@ -10,8 +10,9 @@
 
 #include "test/fake_vp8_encoder.h"
 
+#include "api/video_codecs/create_vp8_temporal_layers.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "common_types.h"  // NOLINT(build/include)
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "modules/video_coding/include/video_error_codes.h"
 #include "modules/video_coding/utility/simulcast_utility.h"
@@ -83,18 +84,18 @@
 
   int num_streams = SimulcastUtility::NumberOfSimulcastStreams(codec);
   for (int i = 0; i < num_streams; ++i) {
-    TemporalLayersType type;
+    Vp8TemporalLayersType type;
     int num_temporal_layers =
         SimulcastUtility::NumberOfTemporalLayers(codec, i);
     if (SimulcastUtility::IsConferenceModeScreenshare(codec) && i == 0) {
-      type = TemporalLayersType::kBitrateDynamic;
+      type = Vp8TemporalLayersType::kBitrateDynamic;
       // Legacy screenshare layers supports max 2 layers.
       num_temporal_layers = std::max<int>(2, num_temporal_layers);
     } else {
-      type = TemporalLayersType::kFixedPattern;
+      type = Vp8TemporalLayersType::kFixedPattern;
     }
     temporal_layers_.emplace_back(
-        TemporalLayers::CreateTemporalLayers(type, num_temporal_layers));
+        CreateVp8TemporalLayers(type, num_temporal_layers));
   }
 }
 
diff --git a/test/fake_vp8_encoder.h b/test/fake_vp8_encoder.h
index 7518e3a2..8d409c2 100644
--- a/test/fake_vp8_encoder.h
+++ b/test/fake_vp8_encoder.h
@@ -14,7 +14,7 @@
 #include <memory>
 #include <vector>
 
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "test/fake_encoder.h"
 
 #include "rtc_base/criticalsection.h"
@@ -54,7 +54,7 @@
   rtc::SequencedTaskChecker sequence_checker_;
   EncodedImageCallback* callback_ RTC_GUARDED_BY(sequence_checker_);
 
-  std::vector<std::unique_ptr<TemporalLayers>> temporal_layers_
+  std::vector<std::unique_ptr<Vp8TemporalLayers>> temporal_layers_
       RTC_GUARDED_BY(sequence_checker_);
 };
 
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 5d691cc..bd49b3d 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -429,6 +429,7 @@
       "../api/video:encoded_image",
       "../api/video:video_frame",
       "../api/video:video_frame_i420",
+      "../api/video_codecs:create_vp8_temporal_layers",
       "../api/video_codecs:video_codecs_api",
       "../call:call_interfaces",
       "../call:fake_network",
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 80f8d5a..4b9de7b 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -8,13 +8,16 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include "video/video_stream_encoder.h"
+
 #include <algorithm>
 #include <limits>
 #include <utility>
 
 #include "api/video/i420_buffer.h"
+#include "api/video_codecs/create_vp8_temporal_layers.h"
+#include "api/video_codecs/vp8_temporal_layers.h"
 #include "media/base/videoadapter.h"
-#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
 #include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
 #include "modules/video_coding/utility/default_video_bitrate_allocator.h"
 #include "rtc_base/fakeclock.h"
@@ -30,7 +33,6 @@
 #include "test/gtest.h"
 #include "test/video_encoder_proxy_factory.h"
 #include "video/send_statistics_proxy.h"
-#include "video/video_stream_encoder.h"
 
 namespace webrtc {
 
@@ -569,9 +571,8 @@
         int num_streams = std::max<int>(1, config->numberOfSimulcastStreams);
         for (int i = 0; i < num_streams; ++i) {
           allocated_temporal_layers_.emplace_back(
-              TemporalLayers::CreateTemporalLayers(
-                  TemporalLayersType::kFixedPattern,
-                  config->VP8().numberOfTemporalLayers));
+              CreateVp8TemporalLayers(Vp8TemporalLayersType::kFixedPattern,
+                                      config->VP8().numberOfTemporalLayers));
         }
       }
       if (force_init_encode_failed_)
@@ -587,7 +588,7 @@
     int last_input_width_ RTC_GUARDED_BY(local_crit_sect_) = 0;
     int last_input_height_ RTC_GUARDED_BY(local_crit_sect_) = 0;
     bool quality_scaling_ RTC_GUARDED_BY(local_crit_sect_) = true;
-    std::vector<std::unique_ptr<TemporalLayers>> allocated_temporal_layers_
+    std::vector<std::unique_ptr<Vp8TemporalLayers>> allocated_temporal_layers_
         RTC_GUARDED_BY(local_crit_sect_);
     bool force_init_encode_failed_ RTC_GUARDED_BY(local_crit_sect_) = false;
   };