Move VideoCodecTest configuration classes to api/test.

These files are required when implementing tests based on the test fixture,
and should be exposed as part of the test api.

This CL also removes a usage of stringstream and fixes some chromium-style
lint issues.

Bug: webrtc:8982, webrtc:163
Change-Id: I132aea0da79a79587887f21897236fc9802b7574
Reviewed-on: https://webrtc-review.googlesource.com/74586
Commit-Queue: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
Reviewed-by: Patrik Höglund <phoglund@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23346}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index dd77987..09a13d1 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -351,9 +351,12 @@
     testonly = true
     sources = [
       "test/videocodec_test_fixture.h",
+      "test/videocodec_test_stats.cc",
+      "test/videocodec_test_stats.h",
     ]
     deps = [
-      "../modules/video_coding:video_codecs_test_framework",
+      "..:webrtc_common",
+      "../modules/video_coding:video_codec_interface",
       "video_codecs:video_codecs_api",
     ]
   }
diff --git a/api/DEPS b/api/DEPS
index d7f00eb..adbe10b 100644
--- a/api/DEPS
+++ b/api/DEPS
@@ -23,5 +23,6 @@
   ".*\.cc": [
     "+modules/audio_coding",
     "+modules/audio_processing",
+    "+modules/video_coding",
   ],
 }
diff --git a/api/test/DEPS b/api/test/DEPS
index cd91a9f..0a269fe 100644
--- a/api/test/DEPS
+++ b/api/test/DEPS
@@ -1,6 +1,5 @@
-# TODO(kthelgason): Move the relevant included files to api/test.
 specific_include_rules = {
   ".*": [
-    "+modules/video_coding/codecs/test",
+    "+modules/video_coding",
   ],
 }
diff --git a/api/test/create_videocodec_test_fixture.cc b/api/test/create_videocodec_test_fixture.cc
index 9a0aacc..007d91b 100644
--- a/api/test/create_videocodec_test_fixture.cc
+++ b/api/test/create_videocodec_test_fixture.cc
@@ -20,14 +20,16 @@
 namespace webrtc {
 namespace test {
 
+using Config = VideoCodecTestFixture::Config;
+
 std::unique_ptr<VideoCodecTestFixture>
-CreateVideoCodecTestFixture(const TestConfig& config) {
+CreateVideoCodecTestFixture(const Config& config) {
   return rtc::MakeUnique<VideoCodecTestFixtureImpl>(config);
 }
 
 std::unique_ptr<VideoCodecTestFixture>
 CreateVideoCodecTestFixture(
-    const TestConfig& config,
+    const Config& config,
     std::unique_ptr<VideoDecoderFactory> decoder_factory,
     std::unique_ptr<VideoEncoderFactory> encoder_factory) {
   return rtc::MakeUnique<VideoCodecTestFixtureImpl>(
diff --git a/api/test/create_videocodec_test_fixture.h b/api/test/create_videocodec_test_fixture.h
index 24e17fd..7a44f6b 100644
--- a/api/test/create_videocodec_test_fixture.h
+++ b/api/test/create_videocodec_test_fixture.h
@@ -16,17 +16,15 @@
 #include "api/test/videocodec_test_fixture.h"
 #include "api/video_codecs/video_decoder_factory.h"
 #include "api/video_codecs/video_encoder_factory.h"
-#include "modules/video_coding/codecs/test/test_config.h"
 
 namespace webrtc {
 namespace test {
 
-std::unique_ptr<VideoCodecTestFixture>
-CreateVideoCodecTestFixture(const TestConfig& config);
+std::unique_ptr<VideoCodecTestFixture> CreateVideoCodecTestFixture(
+    const VideoCodecTestFixture::Config& config);
 
-std::unique_ptr<VideoCodecTestFixture>
-CreateVideoCodecTestFixture(
-    const TestConfig& config,
+std::unique_ptr<VideoCodecTestFixture> CreateVideoCodecTestFixture(
+    const VideoCodecTestFixture::Config& config,
     std::unique_ptr<VideoDecoderFactory> decoder_factory,
     std::unique_ptr<VideoEncoderFactory> encoder_factory);
 
diff --git a/api/test/videocodec_test_fixture.h b/api/test/videocodec_test_fixture.h
index 88da7df..68e0637 100644
--- a/api/test/videocodec_test_fixture.h
+++ b/api/test/videocodec_test_fixture.h
@@ -11,11 +11,13 @@
 #ifndef API_TEST_VIDEOCODEC_TEST_FIXTURE_H_
 #define API_TEST_VIDEOCODEC_TEST_FIXTURE_H_
 
+#include <string>
 #include <vector>
 
+#include "api/test/videocodec_test_stats.h"
 #include "api/video_codecs/video_decoder_factory.h"
 #include "api/video_codecs/video_encoder_factory.h"
-#include "modules/video_coding/codecs/test/stats.h"
+#include "modules/video_coding/include/video_codec_interface.h"
 
 namespace webrtc {
 namespace test {
@@ -58,6 +60,89 @@
 
 class VideoCodecTestFixture {
  public:
+  class EncodedFrameChecker {
+   public:
+    virtual ~EncodedFrameChecker() = default;
+    virtual void CheckEncodedFrame(webrtc::VideoCodecType codec,
+                                   const EncodedImage& encoded_frame) const = 0;
+  };
+  struct Config {
+    Config();
+    void SetCodecSettings(std::string codec_name,
+                          size_t num_simulcast_streams,
+                          size_t num_spatial_layers,
+                          size_t num_temporal_layers,
+                          bool denoising_on,
+                          bool frame_dropper_on,
+                          bool spatial_resize_on,
+                          size_t width,
+                          size_t height);
+
+    size_t NumberOfCores() const;
+    size_t NumberOfTemporalLayers() const;
+    size_t NumberOfSpatialLayers() const;
+    size_t NumberOfSimulcastStreams() const;
+
+    std::string ToString() const;
+    std::string CodecName() const;
+    bool IsAsyncCodec() const;
+
+    // Plain name of YUV file to process without file extension.
+    std::string filename;
+
+    // File to process. This must be a video file in the YUV format.
+    std::string filepath;
+
+    // Number of frames to process.
+    size_t num_frames = 0;
+
+    // Bitstream constraints.
+    size_t max_payload_size_bytes = 1440;
+
+    // Should we decode the encoded frames?
+    bool decode = true;
+
+    // Force the encoder and decoder to use a single core for processing.
+    bool use_single_core = false;
+
+    // Should cpu usage be measured?
+    // If set to true, the encoding will run in real-time.
+    bool measure_cpu = false;
+
+    // If > 0: forces the encoder to create a keyframe every Nth frame.
+    size_t keyframe_interval = 0;
+
+    // Codec settings to use.
+    webrtc::VideoCodec codec_settings;
+
+    // Name of the codec being tested.
+    std::string codec_name;
+
+    // H.264 specific settings.
+    struct H264CodecSettings {
+      H264::Profile profile = H264::kProfileConstrainedBaseline;
+      H264PacketizationMode packetization_mode =
+          webrtc::H264PacketizationMode::NonInterleaved;
+    } h264_codec_settings;
+
+    // Should hardware accelerated codecs be used?
+    bool hw_encoder = false;
+    bool hw_decoder = false;
+
+    // Should the encoder be wrapped in a SimulcastEncoderAdapter?
+    bool simulcast_adapted_encoder = false;
+
+    // Should the hardware codecs be wrapped in software fallbacks?
+    bool sw_fallback_encoder = false;
+    bool sw_fallback_decoder = false;
+
+    // Custom checker that will be called for each frame.
+    const EncodedFrameChecker* encoded_frame_checker = nullptr;
+
+    // Print out frame level stats.
+    bool print_frame_level_stats = false;
+  };
+
   virtual ~VideoCodecTestFixture() = default;
 
   virtual void RunTest(const std::vector<RateProfile>& rate_profiles,
@@ -65,7 +150,7 @@
                        const std::vector<QualityThresholds>* quality_thresholds,
                        const BitstreamThresholds* bs_thresholds,
                        const VisualizationParams* visualization_params) = 0;
-  virtual Stats GetStats() = 0;
+  virtual VideoCodecTestStats& GetStats() = 0;
 };
 
 }  // namespace test
diff --git a/api/test/videocodec_test_stats.cc b/api/test/videocodec_test_stats.cc
new file mode 100644
index 0000000..7252278
--- /dev/null
+++ b/api/test/videocodec_test_stats.cc
@@ -0,0 +1,95 @@
+/*
+ *  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/test/videocodec_test_stats.h"
+
+namespace webrtc {
+namespace test {
+
+std::string VideoCodecTestStats::FrameStatistics::ToString() const {
+  std::stringstream ss;
+  ss << "frame_number " << frame_number;
+  ss << " decoded_width " << decoded_width;
+  ss << " decoded_height " << decoded_height;
+  ss << " spatial_idx " << spatial_idx;
+  ss << " temporal_idx " << temporal_idx;
+  ss << " inter_layer_predicted " << inter_layer_predicted;
+  ss << " non_ref_for_inter_layer_pred " << non_ref_for_inter_layer_pred;
+  ss << " frame_type " << frame_type;
+  ss << " length_bytes " << length_bytes;
+  ss << " qp " << qp;
+  ss << " psnr " << psnr;
+  ss << " psnr_y " << psnr_y;
+  ss << " psnr_u " << psnr_u;
+  ss << " psnr_v " << psnr_v;
+  ss << " ssim " << ssim;
+  ss << " encode_time_us " << encode_time_us;
+  ss << " decode_time_us " << decode_time_us;
+  ss << " rtp_timestamp " << rtp_timestamp;
+  ss << " target_bitrate_kbps " << target_bitrate_kbps;
+  return ss.str();
+}
+
+VideoCodecTestStats::VideoStatistics::VideoStatistics() = default;
+VideoCodecTestStats::VideoStatistics::VideoStatistics(const VideoStatistics&) =
+    default;
+
+std::string VideoCodecTestStats::VideoStatistics::ToString(
+    std::string prefix) const {
+  std::stringstream ss;
+  ss << prefix << "target_bitrate_kbps: " << target_bitrate_kbps;
+  ss << "\n" << prefix << "input_framerate_fps: " << input_framerate_fps;
+  ss << "\n" << prefix << "spatial_idx: " << spatial_idx;
+  ss << "\n" << prefix << "temporal_idx: " << temporal_idx;
+  ss << "\n" << prefix << "width: " << width;
+  ss << "\n" << prefix << "height: " << height;
+  ss << "\n" << prefix << "length_bytes: " << length_bytes;
+  ss << "\n" << prefix << "bitrate_kbps: " << bitrate_kbps;
+  ss << "\n" << prefix << "framerate_fps: " << framerate_fps;
+  ss << "\n" << prefix << "enc_speed_fps: " << enc_speed_fps;
+  ss << "\n" << prefix << "dec_speed_fps: " << dec_speed_fps;
+  ss << "\n" << prefix << "avg_delay_sec: " << avg_delay_sec;
+  ss << "\n"
+     << prefix << "max_key_frame_delay_sec: " << max_key_frame_delay_sec;
+  ss << "\n"
+     << prefix << "max_delta_frame_delay_sec: " << max_delta_frame_delay_sec;
+  ss << "\n"
+     << prefix << "time_to_reach_target_bitrate_sec: "
+     << time_to_reach_target_bitrate_sec;
+  ss << "\n"
+     << prefix << "avg_key_frame_size_bytes: " << avg_key_frame_size_bytes;
+  ss << "\n"
+     << prefix << "avg_delta_frame_size_bytes: " << avg_delta_frame_size_bytes;
+  ss << "\n" << prefix << "avg_qp: " << avg_qp;
+  ss << "\n" << prefix << "avg_psnr: " << avg_psnr;
+  ss << "\n" << prefix << "min_psnr: " << min_psnr;
+  ss << "\n" << prefix << "avg_ssim: " << avg_ssim;
+  ss << "\n" << prefix << "min_ssim: " << min_ssim;
+  ss << "\n" << prefix << "num_input_frames: " << num_input_frames;
+  ss << "\n" << prefix << "num_encoded_frames: " << num_encoded_frames;
+  ss << "\n" << prefix << "num_decoded_frames: " << num_decoded_frames;
+  ss << "\n"
+     << prefix
+     << "num_dropped_frames: " << num_input_frames - num_encoded_frames;
+  ss << "\n" << prefix << "num_key_frames: " << num_key_frames;
+  ss << "\n" << prefix << "num_spatial_resizes: " << num_spatial_resizes;
+  ss << "\n" << prefix << "max_nalu_size_bytes: " << max_nalu_size_bytes;
+  return ss.str();
+}
+
+VideoCodecTestStats::FrameStatistics::FrameStatistics(size_t frame_number,
+                                                      size_t rtp_timestamp)
+    : frame_number(frame_number), rtp_timestamp(rtp_timestamp) {}
+
+VideoCodecTestStats::FrameStatistics::FrameStatistics(
+    const FrameStatistics& rhs) = default;
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/api/test/videocodec_test_stats.h b/api/test/videocodec_test_stats.h
new file mode 100644
index 0000000..de6d350
--- /dev/null
+++ b/api/test/videocodec_test_stats.h
@@ -0,0 +1,149 @@
+/*
+ *  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_TEST_VIDEOCODEC_TEST_STATS_H_
+#define API_TEST_VIDEOCODEC_TEST_STATS_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "common_types.h"  // NOLINT(build/include)
+
+namespace webrtc {
+namespace test {
+
+// Statistics for a sequence of processed frames. This class is not thread safe.
+class VideoCodecTestStats {
+ public:
+  // Statistics for one processed frame.
+  struct FrameStatistics {
+    FrameStatistics(size_t frame_number, size_t rtp_timestamp);
+    FrameStatistics(const FrameStatistics& rhs);
+
+    std::string ToString() const;
+
+    size_t frame_number = 0;
+    size_t rtp_timestamp = 0;
+
+    // Encoding.
+    int64_t encode_start_ns = 0;
+    int encode_return_code = 0;
+    bool encoding_successful = false;
+    size_t encode_time_us = 0;
+    size_t target_bitrate_kbps = 0;
+    size_t length_bytes = 0;
+    webrtc::FrameType frame_type = kVideoFrameDelta;
+
+    // Layering.
+    size_t spatial_idx = 0;
+    size_t temporal_idx = 0;
+    bool inter_layer_predicted = false;
+    bool non_ref_for_inter_layer_pred = true;
+
+    // H264 specific.
+    size_t max_nalu_size_bytes = 0;
+
+    // Decoding.
+    int64_t decode_start_ns = 0;
+    int decode_return_code = 0;
+    bool decoding_successful = false;
+    size_t decode_time_us = 0;
+    size_t decoded_width = 0;
+    size_t decoded_height = 0;
+
+    // Quantization.
+    int qp = -1;
+
+    // Quality.
+    float psnr_y = 0.0f;
+    float psnr_u = 0.0f;
+    float psnr_v = 0.0f;
+    float psnr = 0.0f;  // 10 * log10(255^2 / (mse_y + mse_u + mse_v)).
+    float ssim = 0.0f;  // 0.8 * ssim_y + 0.1 * (ssim_u + ssim_v).
+  };
+
+  struct VideoStatistics {
+    VideoStatistics();
+    VideoStatistics(const VideoStatistics&);
+
+    std::string ToString(std::string prefix) const;
+
+    size_t target_bitrate_kbps = 0;
+    float input_framerate_fps = 0.0f;
+
+    size_t spatial_idx = 0;
+    size_t temporal_idx = 0;
+
+    size_t width = 0;
+    size_t height = 0;
+
+    size_t length_bytes = 0;
+    size_t bitrate_kbps = 0;
+    float framerate_fps = 0;
+
+    float enc_speed_fps = 0.0f;
+    float dec_speed_fps = 0.0f;
+
+    float avg_delay_sec = 0.0f;
+    float max_key_frame_delay_sec = 0.0f;
+    float max_delta_frame_delay_sec = 0.0f;
+    float time_to_reach_target_bitrate_sec = 0.0f;
+
+    float avg_key_frame_size_bytes = 0.0f;
+    float avg_delta_frame_size_bytes = 0.0f;
+    float avg_qp = 0.0f;
+
+    float avg_psnr_y = 0.0f;
+    float avg_psnr_u = 0.0f;
+    float avg_psnr_v = 0.0f;
+    float avg_psnr = 0.0f;
+    float min_psnr = 0.0f;
+    float avg_ssim = 0.0f;
+    float min_ssim = 0.0f;
+
+    size_t num_input_frames = 0;
+    size_t num_encoded_frames = 0;
+    size_t num_decoded_frames = 0;
+    size_t num_key_frames = 0;
+    size_t num_spatial_resizes = 0;
+    size_t max_nalu_size_bytes = 0;
+  };
+
+  virtual ~VideoCodecTestStats() = default;
+
+  // Creates a FrameStatistics for the next frame to be processed.
+  virtual FrameStatistics* AddFrame(size_t timestamp, size_t spatial_idx) = 0;
+
+  // Returns the FrameStatistics corresponding to |frame_number| or |timestamp|.
+  virtual FrameStatistics* GetFrame(size_t frame_number,
+                                    size_t spatial_idx) = 0;
+  virtual FrameStatistics* GetFrameWithTimestamp(size_t timestamp,
+                                                 size_t spatial_idx) = 0;
+
+  virtual std::vector<VideoStatistics> SliceAndCalcLayerVideoStatistic(
+      size_t first_frame_num,
+      size_t last_frame_num) = 0;
+
+  virtual VideoStatistics SliceAndCalcAggregatedVideoStatistic(
+      size_t first_frame_num,
+      size_t last_frame_num) = 0;
+
+  virtual void PrintFrameStatistics() = 0;
+
+  virtual size_t Size(size_t spatial_idx) = 0;
+
+  virtual void Clear() = 0;
+};
+
+}  // namespace test
+}  // namespace webrtc
+
+#endif  // API_TEST_VIDEOCODEC_TEST_STATS_H_
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 7947455..998f83f 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -587,10 +587,6 @@
   rtc_source_set("video_codecs_test_framework") {
     testonly = true
     sources = [
-      "codecs/test/stats.cc",
-      "codecs/test/stats.h",
-      "codecs/test/test_config.cc",
-      "codecs/test/test_config.h",
       "codecs/test/video_codec_unittest.cc",
       "codecs/test/video_codec_unittest.h",
       "codecs/test/videoprocessor.cc",
@@ -603,7 +599,6 @@
     }
 
     deps = [
-      ":codec_globals_headers",
       ":video_codec_interface",
       ":video_coding",
       ":video_coding_utility",
@@ -611,21 +606,16 @@
       ":webrtc_vp9_helpers",
       "../..:webrtc_common",
       "../../:typedefs",
+      "../../api:videocodec_test_fixture_api",
       "../../api/video:video_frame",
       "../../api/video:video_frame_i420",
       "../../api/video_codecs:video_codecs_api",
       "../../common_video:common_video",
-      "../../media:rtc_audio_video",
-      "../../media:rtc_h264_profile_id",
-      "../../media:rtc_media_base",
       "../../rtc_base:checks",
       "../../rtc_base:rtc_base_approved",
       "../../rtc_base:rtc_task_queue",
       "../../rtc_base:rtc_task_queue_for_test",
       "../../rtc_base:sequenced_task_checker",
-      "../../system_wrappers",
-      "../../test:fileutils",
-      "../../test:test_common",
       "../../test:test_support",
       "../../test:video_test_common",
       "../../test:video_test_support",
@@ -674,6 +664,8 @@
     sources = [
       "codecs/test/videocodec_test_fixture_impl.cc",
       "codecs/test/videocodec_test_fixture_impl.h",
+      "codecs/test/videocodec_test_stats_impl.cc",
+      "codecs/test/videocodec_test_stats_impl.h",
     ]
     deps = [
       ":video_codec_interface",
@@ -686,7 +678,10 @@
       "../..:webrtc_common",
       "../../api:videocodec_test_fixture_api",
       "../../api/video_codecs:video_codecs_api",
+      "../../call:video_stream_api",
       "../../common_video",
+      "../../media:rtc_audio_video",
+      "../../media:rtc_h264_profile_id",
       "../../media:rtc_internal_video_codecs",
       "../../media:rtc_software_fallback_wrappers",
       "../../rtc_base:checks",
@@ -695,8 +690,11 @@
       "../../rtc_base:rtc_task_queue_for_test",
       "../../system_wrappers",
       "../../test:fileutils",
+      "../../test:test_common",
       "../../test:test_support",
+      "../../test:video_test_common",
       "../../test:video_test_support",
+      "../rtp_rtcp:rtp_rtcp_format",
     ]
     if (!build_with_chromium && is_clang) {
       # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
@@ -778,8 +776,8 @@
     testonly = true
 
     sources = [
-      "codecs/test/stats_unittest.cc",
-      "codecs/test/test_config_unittest.cc",
+      "codecs/test/videocodec_test_fixture_config_unittest.cc",
+      "codecs/test/videocodec_test_stats_impl_unittest.cc",
       "codecs/test/videoprocessor_unittest.cc",
       "codecs/vp8/default_temporal_layers_unittest.cc",
       "codecs/vp8/screenshare_layers_unittest.cc",
@@ -829,6 +827,7 @@
       ":video_codecs_test_framework",
       ":video_coding",
       ":video_coding_utility",
+      ":videocodec_test_impl",
       ":webrtc_h264",
       ":webrtc_vp8",
       ":webrtc_vp8_helpers",
@@ -837,6 +836,7 @@
       "..:module_api",
       "../..:webrtc_common",
       "../../:typedefs",
+      "../../api:videocodec_test_fixture_api",
       "../../api/video:video_frame",
       "../../api/video:video_frame_i420",
       "../../api/video_codecs:video_codecs_api",
diff --git a/modules/video_coding/codecs/test/stats.h b/modules/video_coding/codecs/test/stats.h
deleted file mode 100644
index 0cd6899..0000000
--- a/modules/video_coding/codecs/test/stats.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- *  Copyright (c) 2011 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 MODULES_VIDEO_CODING_CODECS_TEST_STATS_H_
-#define MODULES_VIDEO_CODING_CODECS_TEST_STATS_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "common_types.h"  // NOLINT(build/include)
-
-namespace webrtc {
-namespace test {
-
-// Statistics for one processed frame.
-struct FrameStatistics {
-  FrameStatistics(size_t frame_number, size_t rtp_timestamp)
-      : frame_number(frame_number), rtp_timestamp(rtp_timestamp) {}
-
-  std::string ToString() const;
-
-  size_t frame_number = 0;
-  size_t rtp_timestamp = 0;
-
-  // Encoding.
-  int64_t encode_start_ns = 0;
-  int encode_return_code = 0;
-  bool encoding_successful = false;
-  size_t encode_time_us = 0;
-  size_t target_bitrate_kbps = 0;
-  size_t length_bytes = 0;
-  webrtc::FrameType frame_type = kVideoFrameDelta;
-
-  // Layering.
-  size_t spatial_idx = 0;
-  size_t temporal_idx = 0;
-  bool inter_layer_predicted = false;
-  bool non_ref_for_inter_layer_pred = true;
-
-  // H264 specific.
-  size_t max_nalu_size_bytes = 0;
-
-  // Decoding.
-  int64_t decode_start_ns = 0;
-  int decode_return_code = 0;
-  bool decoding_successful = false;
-  size_t decode_time_us = 0;
-  size_t decoded_width = 0;
-  size_t decoded_height = 0;
-
-  // Quantization.
-  int qp = -1;
-
-  // Quality.
-  float psnr_y = 0.0f;
-  float psnr_u = 0.0f;
-  float psnr_v = 0.0f;
-  float psnr = 0.0f;  // 10 * log10(255^2 / (mse_y + mse_u + mse_v)).
-  float ssim = 0.0f;  // 0.8 * ssim_y + 0.1 * (ssim_u + ssim_v).
-};
-
-struct VideoStatistics {
-  std::string ToString(std::string prefix) const;
-
-  size_t target_bitrate_kbps = 0;
-  float input_framerate_fps = 0.0f;
-
-  size_t spatial_idx = 0;
-  size_t temporal_idx = 0;
-
-  size_t width = 0;
-  size_t height = 0;
-
-  size_t length_bytes = 0;
-  size_t bitrate_kbps = 0;
-  float framerate_fps = 0;
-
-  float enc_speed_fps = 0.0f;
-  float dec_speed_fps = 0.0f;
-
-  float avg_delay_sec = 0.0f;
-  float max_key_frame_delay_sec = 0.0f;
-  float max_delta_frame_delay_sec = 0.0f;
-  float time_to_reach_target_bitrate_sec = 0.0f;
-
-  float avg_key_frame_size_bytes = 0.0f;
-  float avg_delta_frame_size_bytes = 0.0f;
-  float avg_qp = 0.0f;
-
-  float avg_psnr_y = 0.0f;
-  float avg_psnr_u = 0.0f;
-  float avg_psnr_v = 0.0f;
-  float avg_psnr = 0.0f;
-  float min_psnr = 0.0f;
-  float avg_ssim = 0.0f;
-  float min_ssim = 0.0f;
-
-  size_t num_input_frames = 0;
-  size_t num_encoded_frames = 0;
-  size_t num_decoded_frames = 0;
-  size_t num_key_frames = 0;
-  size_t num_spatial_resizes = 0;
-  size_t max_nalu_size_bytes = 0;
-};
-
-// Statistics for a sequence of processed frames. This class is not thread safe.
-class Stats {
- public:
-  Stats() = default;
-  ~Stats() = default;
-
-  // Creates a FrameStatistics for the next frame to be processed.
-  FrameStatistics* AddFrame(size_t timestamp, size_t spatial_idx);
-
-  // Returns the FrameStatistics corresponding to |frame_number| or |timestamp|.
-  FrameStatistics* GetFrame(size_t frame_number, size_t spatial_idx);
-  FrameStatistics* GetFrameWithTimestamp(size_t timestamp, size_t spatial_idx);
-
-  std::vector<VideoStatistics> SliceAndCalcLayerVideoStatistic(
-      size_t first_frame_num,
-      size_t last_frame_num);
-
-  VideoStatistics SliceAndCalcAggregatedVideoStatistic(size_t first_frame_num,
-                                                       size_t last_frame_num);
-
-  void PrintFrameStatistics();
-
-  size_t Size(size_t spatial_idx);
-
-  void Clear();
-
- private:
-  FrameStatistics AggregateFrameStatistic(size_t frame_num,
-                                          size_t spatial_idx,
-                                          bool aggregate_independent_layers);
-
-  size_t CalcLayerTargetBitrateKbps(size_t first_frame_num,
-                                    size_t last_frame_num,
-                                    size_t spatial_idx,
-                                    size_t temporal_idx,
-                                    bool aggregate_independent_layers);
-
-  VideoStatistics SliceAndCalcVideoStatistic(size_t first_frame_num,
-                                             size_t last_frame_num,
-                                             size_t spatial_idx,
-                                             size_t temporal_idx,
-                                             bool aggregate_independent_layers);
-
-  void GetNumberOfEncodedLayers(size_t first_frame_num,
-                                size_t last_frame_num,
-                                size_t* num_encoded_spatial_layers,
-                                size_t* num_encoded_temporal_layers);
-
-  // layer_idx -> stats.
-  std::map<size_t, std::vector<FrameStatistics>> layer_stats_;
-  // layer_idx -> rtp_timestamp -> frame_num.
-  std::map<size_t, std::map<size_t, size_t>> rtp_timestamp_to_frame_num_;
-};
-
-}  // namespace test
-}  // namespace webrtc
-
-#endif  // MODULES_VIDEO_CODING_CODECS_TEST_STATS_H_
diff --git a/modules/video_coding/codecs/test/test_config.cc b/modules/video_coding/codecs/test/test_config.cc
deleted file mode 100644
index 0d02ba7..0000000
--- a/modules/video_coding/codecs/test/test_config.cc
+++ /dev/null
@@ -1,282 +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/test/test_config.h"
-
-#include <sstream>
-
-#include "media/base/h264_profile_level_id.h"
-#include "media/base/mediaconstants.h"
-#include "media/engine/simulcast.h"
-#include "modules/video_coding/codecs/vp9/svc_config.h"
-#include "modules/video_coding/include/video_codec_interface.h"
-#include "rtc_base/checks.h"
-#include "system_wrappers/include/cpu_info.h"
-#include "test/video_codec_settings.h"
-
-namespace webrtc {
-namespace test {
-
-namespace {
-
-const int kBaseKeyFrameInterval = 3000;
-const int kMaxBitrateBps = 5000 * 1000;  // From kSimulcastFormats.
-const int kMaxFramerateFps = 30;
-const int kMaxQp = 56;
-
-void ConfigureSimulcast(VideoCodec* codec_settings) {
-  const std::vector<webrtc::VideoStream> streams = cricket::GetSimulcastConfig(
-      codec_settings->numberOfSimulcastStreams, codec_settings->width,
-      codec_settings->height, kMaxBitrateBps, kMaxQp, kMaxFramerateFps, false);
-
-  for (size_t i = 0; i < streams.size(); ++i) {
-    SimulcastStream* ss = &codec_settings->simulcastStream[i];
-    ss->width = static_cast<uint16_t>(streams[i].width);
-    ss->height = static_cast<uint16_t>(streams[i].height);
-    ss->numberOfTemporalLayers =
-        static_cast<unsigned char>(*streams[i].num_temporal_layers);
-    ss->maxBitrate = streams[i].max_bitrate_bps / 1000;
-    ss->targetBitrate = streams[i].target_bitrate_bps / 1000;
-    ss->minBitrate = streams[i].min_bitrate_bps / 1000;
-    ss->qpMax = streams[i].max_qp;
-    ss->active = true;
-  }
-}
-
-void ConfigureSvc(VideoCodec* codec_settings) {
-  RTC_CHECK_EQ(kVideoCodecVP9, codec_settings->codecType);
-
-  const std::vector<SpatialLayer> layers =
-      GetSvcConfig(codec_settings->width, codec_settings->height,
-                   codec_settings->VP9()->numberOfSpatialLayers,
-                   codec_settings->VP9()->numberOfTemporalLayers, false);
-
-  for (size_t i = 0; i < layers.size(); ++i) {
-    codec_settings->spatialLayers[i] = layers[i];
-  }
-}
-
-std::string CodecSpecificToString(const VideoCodec& codec) {
-  std::stringstream ss;
-  switch (codec.codecType) {
-    case kVideoCodecVP8:
-      ss << "complexity: " << codec.VP8().complexity;
-      ss << "\nnum_temporal_layers: "
-         << static_cast<int>(codec.VP8().numberOfTemporalLayers);
-      ss << "\ndenoising: " << codec.VP8().denoisingOn;
-      ss << "\nautomatic_resize: " << codec.VP8().automaticResizeOn;
-      ss << "\nframe_dropping: " << codec.VP8().frameDroppingOn;
-      ss << "\nkey_frame_interval: " << codec.VP8().keyFrameInterval;
-      break;
-    case kVideoCodecVP9:
-      ss << "complexity: " << codec.VP9().complexity;
-      ss << "\nnum_temporal_layers: "
-         << static_cast<int>(codec.VP9().numberOfTemporalLayers);
-      ss << "\nnum_spatial_layers: "
-         << static_cast<int>(codec.VP9().numberOfSpatialLayers);
-      ss << "\ndenoising: " << codec.VP9().denoisingOn;
-      ss << "\nframe_dropping: " << codec.VP9().frameDroppingOn;
-      ss << "\nkey_frame_interval: " << codec.VP9().keyFrameInterval;
-      ss << "\nadaptive_qp_mode: " << codec.VP9().adaptiveQpMode;
-      ss << "\nautomatic_resize: " << codec.VP9().automaticResizeOn;
-      ss << "\nflexible_mode: " << codec.VP9().flexibleMode;
-      break;
-    case kVideoCodecH264:
-      ss << "frame_dropping: " << codec.H264().frameDroppingOn;
-      ss << "\nkey_frame_interval: " << codec.H264().keyFrameInterval;
-      ss << "\nprofile: " << codec.H264().profile;
-      break;
-    default:
-      break;
-  }
-  ss << "\n";
-  return ss.str();
-}
-
-}  // namespace
-
-void TestConfig::SetCodecSettings(std::string codec_name,
-                                  size_t num_simulcast_streams,
-                                  size_t num_spatial_layers,
-                                  size_t num_temporal_layers,
-                                  bool denoising_on,
-                                  bool frame_dropper_on,
-                                  bool spatial_resize_on,
-                                  size_t width,
-                                  size_t height) {
-  this->codec_name = codec_name;
-  VideoCodecType codec_type = PayloadStringToCodecType(codec_name);
-  webrtc::test::CodecSettings(codec_type, &codec_settings);
-
-  // TODO(brandtr): Move the setting of |width| and |height| to the tests, and
-  // DCHECK that they are set before initializing the codec instead.
-  codec_settings.width = static_cast<uint16_t>(width);
-  codec_settings.height = static_cast<uint16_t>(height);
-
-  RTC_CHECK(num_simulcast_streams >= 1 &&
-            num_simulcast_streams <= kMaxSimulcastStreams);
-  RTC_CHECK(num_spatial_layers >= 1 && num_spatial_layers <= kMaxSpatialLayers);
-  RTC_CHECK(num_temporal_layers >= 1 &&
-            num_temporal_layers <= kMaxTemporalStreams);
-
-  // Simulcast is only available with VP8.
-  RTC_CHECK(num_simulcast_streams < 2 || codec_type == kVideoCodecVP8);
-
-  // Spatial scalability is only available with VP9.
-  RTC_CHECK(num_spatial_layers < 2 || codec_type == kVideoCodecVP9);
-
-  // Some base code requires numberOfSimulcastStreams to be set to zero
-  // when simulcast is not used.
-  codec_settings.numberOfSimulcastStreams =
-      num_simulcast_streams <= 1 ? 0
-                                 : static_cast<uint8_t>(num_simulcast_streams);
-
-  switch (codec_settings.codecType) {
-    case kVideoCodecVP8:
-      codec_settings.VP8()->numberOfTemporalLayers =
-          static_cast<uint8_t>(num_temporal_layers);
-      codec_settings.VP8()->denoisingOn = denoising_on;
-      codec_settings.VP8()->automaticResizeOn = spatial_resize_on;
-      codec_settings.VP8()->frameDroppingOn = frame_dropper_on;
-      codec_settings.VP8()->keyFrameInterval = kBaseKeyFrameInterval;
-      break;
-    case kVideoCodecVP9:
-      codec_settings.VP9()->numberOfTemporalLayers =
-          static_cast<uint8_t>(num_temporal_layers);
-      codec_settings.VP9()->denoisingOn = denoising_on;
-      codec_settings.VP9()->frameDroppingOn = frame_dropper_on;
-      codec_settings.VP9()->keyFrameInterval = kBaseKeyFrameInterval;
-      codec_settings.VP9()->automaticResizeOn = spatial_resize_on;
-      codec_settings.VP9()->numberOfSpatialLayers =
-          static_cast<uint8_t>(num_spatial_layers);
-      break;
-    case kVideoCodecH264:
-      codec_settings.H264()->frameDroppingOn = frame_dropper_on;
-      codec_settings.H264()->keyFrameInterval = kBaseKeyFrameInterval;
-      break;
-    default:
-      break;
-  }
-
-  if (codec_settings.numberOfSimulcastStreams > 1) {
-    ConfigureSimulcast(&codec_settings);
-  } else if (codec_settings.codecType == kVideoCodecVP9 &&
-             codec_settings.VP9()->numberOfSpatialLayers > 1) {
-    ConfigureSvc(&codec_settings);
-  }
-}
-
-size_t TestConfig::NumberOfCores() const {
-  return use_single_core ? 1 : CpuInfo::DetectNumberOfCores();
-}
-
-size_t TestConfig::NumberOfTemporalLayers() const {
-  if (codec_settings.codecType == kVideoCodecVP8) {
-    return codec_settings.VP8().numberOfTemporalLayers;
-  } else if (codec_settings.codecType == kVideoCodecVP9) {
-    return codec_settings.VP9().numberOfTemporalLayers;
-  } else {
-    return 1;
-  }
-}
-
-size_t TestConfig::NumberOfSpatialLayers() const {
-  if (codec_settings.codecType == kVideoCodecVP9) {
-    return codec_settings.VP9().numberOfSpatialLayers;
-  } else {
-    return 1;
-  }
-}
-
-size_t TestConfig::NumberOfSimulcastStreams() const {
-  return codec_settings.numberOfSimulcastStreams;
-}
-
-std::vector<FrameType> TestConfig::FrameTypeForFrame(size_t frame_idx) const {
-  if (keyframe_interval > 0 && (frame_idx % keyframe_interval == 0)) {
-    return {kVideoFrameKey};
-  }
-  return {kVideoFrameDelta};
-}
-
-std::string TestConfig::ToString() const {
-  std::string codec_type = CodecTypeToPayloadString(codec_settings.codecType);
-  std::stringstream ss;
-  ss << "filename: " << filename;
-  ss << "\nnum_frames: " << num_frames;
-  ss << "\nmax_payload_size_bytes: " << max_payload_size_bytes;
-  ss << "\ndecode: " << decode;
-  ss << "\nuse_single_core: " << use_single_core;
-  ss << "\nmeasure_cpu: " << measure_cpu;
-  ss << "\nnum_cores: " << NumberOfCores();
-  ss << "\nkeyframe_interval: " << keyframe_interval;
-  ss << "\ncodec_type: " << codec_type;
-  ss << "\n--> codec_settings";
-  ss << "\nwidth: " << codec_settings.width;
-  ss << "\nheight: " << codec_settings.height;
-  ss << "\nmax_framerate_fps: " << codec_settings.maxFramerate;
-  ss << "\nstart_bitrate_kbps: " << codec_settings.startBitrate;
-  ss << "\nmax_bitrate_kbps: " << codec_settings.maxBitrate;
-  ss << "\nmin_bitrate_kbps: " << codec_settings.minBitrate;
-  ss << "\nmax_qp: " << codec_settings.qpMax;
-  ss << "\nnum_simulcast_streams : "
-     << static_cast<int>(codec_settings.numberOfSimulcastStreams);
-  ss << "\n"
-     << "--> codec_settings." << codec_type << "\n";
-  ss << CodecSpecificToString(codec_settings);
-  return ss.str();
-}
-
-SdpVideoFormat TestConfig::ToSdpVideoFormat() const {
-  if (codec_settings.codecType == kVideoCodecH264) {
-    const char* packetization_mode =
-        h264_codec_settings.packetization_mode ==
-                H264PacketizationMode::NonInterleaved
-            ? "1"
-            : "0";
-    return SdpVideoFormat(
-        codec_name,
-        {{cricket::kH264FmtpProfileLevelId,
-          *H264::ProfileLevelIdToString(H264::ProfileLevelId(
-              h264_codec_settings.profile, H264::kLevel3_1))},
-         {cricket::kH264FmtpPacketizationMode, packetization_mode}});
-  }
-  return SdpVideoFormat(codec_name);
-}
-
-std::string TestConfig::CodecName() const {
-  std::string name = codec_name;
-  if (name.empty()) {
-    name = CodecTypeToPayloadString(codec_settings.codecType);
-  }
-  if (codec_settings.codecType == kVideoCodecH264) {
-    if (h264_codec_settings.profile == H264::kProfileConstrainedHigh) {
-      return name + "-CHP";
-    } else {
-      RTC_DCHECK_EQ(h264_codec_settings.profile,
-                    H264::kProfileConstrainedBaseline);
-      return name + "-CBP";
-    }
-  }
-  return name;
-}
-
-std::string TestConfig::FilenameWithParams() const {
-  std::string implementation_type = hw_encoder ? "hw" : "sw";
-  return filename + "_" + CodecName() + "_" + implementation_type + "_" +
-         std::to_string(codec_settings.startBitrate);
-}
-
-bool TestConfig::IsAsyncCodec() const {
-  return hw_encoder || hw_decoder;
-}
-
-}  // namespace test
-}  // namespace webrtc
diff --git a/modules/video_coding/codecs/test/test_config.h b/modules/video_coding/codecs/test/test_config.h
deleted file mode 100644
index 8c2b725..0000000
--- a/modules/video_coding/codecs/test/test_config.h
+++ /dev/null
@@ -1,115 +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.
- */
-
-#ifndef MODULES_VIDEO_CODING_CODECS_TEST_TEST_CONFIG_H_
-#define MODULES_VIDEO_CODING_CODECS_TEST_TEST_CONFIG_H_
-
-#include <string>
-#include <vector>
-
-#include "api/video_codecs/sdp_video_format.h"
-#include "common_types.h"  // NOLINT(build/include)
-#include "modules/video_coding/codecs/h264/include/h264_globals.h"
-#include "modules/video_coding/include/video_codec_interface.h"
-
-namespace webrtc {
-namespace test {
-
-struct TestConfig {
-  class EncodedFrameChecker {
-   public:
-    virtual ~EncodedFrameChecker() = default;
-
-    virtual void CheckEncodedFrame(webrtc::VideoCodecType codec,
-                                   const EncodedImage& encoded_frame) const = 0;
-  };
-
-  void SetCodecSettings(std::string codec_name,
-                        size_t num_simulcast_streams,
-                        size_t num_spatial_layers,
-                        size_t num_temporal_layers,
-                        bool denoising_on,
-                        bool frame_dropper_on,
-                        bool spatial_resize_on,
-                        size_t width,
-                        size_t height);
-
-  size_t NumberOfCores() const;
-  size_t NumberOfTemporalLayers() const;
-  size_t NumberOfSpatialLayers() const;
-  size_t NumberOfSimulcastStreams() const;
-
-  std::vector<FrameType> FrameTypeForFrame(size_t frame_idx) const;
-  std::string ToString() const;
-  SdpVideoFormat ToSdpVideoFormat() const;
-  std::string CodecName() const;
-  std::string FilenameWithParams() const;
-  bool IsAsyncCodec() const;
-
-  // Plain name of YUV file to process without file extension.
-  std::string filename;
-
-  // File to process. This must be a video file in the YUV format.
-  std::string filepath;
-
-  // Number of frames to process.
-  size_t num_frames = 0;
-
-  // Bitstream constraints.
-  size_t max_payload_size_bytes = 1440;
-
-  // Should we decode the encoded frames?
-  bool decode = true;
-
-  // Force the encoder and decoder to use a single core for processing.
-  bool use_single_core = false;
-
-  // Should cpu usage be measured?
-  // If set to true, the encoding will run in real-time.
-  bool measure_cpu = false;
-
-  // If > 0: forces the encoder to create a keyframe every Nth frame.
-  size_t keyframe_interval = 0;
-
-  // Codec settings to use.
-  webrtc::VideoCodec codec_settings;
-
-  // Name of the codec being tested.
-  std::string codec_name;
-
-  // H.264 specific settings.
-  struct H264CodecSettings {
-    H264::Profile profile = H264::kProfileConstrainedBaseline;
-    H264PacketizationMode packetization_mode =
-        webrtc::H264PacketizationMode::NonInterleaved;
-  } h264_codec_settings;
-
-  // Should hardware accelerated codecs be used?
-  bool hw_encoder = false;
-  bool hw_decoder = false;
-
-  // Should the encoder be wrapped in a SimulcastEncoderAdapter?
-  bool simulcast_adapted_encoder = false;
-
-  // Should the hardware codecs be wrapped in software fallbacks?
-  bool sw_fallback_encoder = false;
-  bool sw_fallback_decoder = false;
-
-  // Custom checker that will be called for each frame.
-  const EncodedFrameChecker* encoded_frame_checker = nullptr;
-
-  // Print out frame level stats.
-  bool print_frame_level_stats = false;
-};
-
-}  // namespace test
-}  // namespace webrtc
-
-#endif  // MODULES_VIDEO_CODING_CODECS_TEST_TEST_CONFIG_H_
diff --git a/modules/video_coding/codecs/test/test_config_unittest.cc b/modules/video_coding/codecs/test/test_config_unittest.cc
deleted file mode 100644
index 2202f91..0000000
--- a/modules/video_coding/codecs/test/test_config_unittest.cc
+++ /dev/null
@@ -1,86 +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/test/test_config.h"
-#include "test/gmock.h"
-#include "test/gtest.h"
-#include "test/video_codec_settings.h"
-
-using ::testing::ElementsAre;
-
-namespace webrtc {
-namespace test {
-
-namespace {
-const size_t kNumTemporalLayers = 2;
-}  // namespace
-
-TEST(TestConfig, NumberOfCoresWithUseSingleCore) {
-  TestConfig config;
-  config.use_single_core = true;
-  EXPECT_EQ(1u, config.NumberOfCores());
-}
-
-TEST(TestConfig, NumberOfCoresWithoutUseSingleCore) {
-  TestConfig config;
-  config.use_single_core = false;
-  EXPECT_GE(config.NumberOfCores(), 1u);
-}
-
-TEST(TestConfig, NumberOfTemporalLayersIsOne) {
-  TestConfig config;
-  webrtc::test::CodecSettings(kVideoCodecH264, &config.codec_settings);
-  EXPECT_EQ(1u, config.NumberOfTemporalLayers());
-}
-
-TEST(TestConfig, NumberOfTemporalLayers_Vp8) {
-  TestConfig config;
-  webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings);
-  config.codec_settings.VP8()->numberOfTemporalLayers = kNumTemporalLayers;
-  EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers());
-}
-
-TEST(TestConfig, NumberOfTemporalLayers_Vp9) {
-  TestConfig config;
-  webrtc::test::CodecSettings(kVideoCodecVP9, &config.codec_settings);
-  config.codec_settings.VP9()->numberOfTemporalLayers = kNumTemporalLayers;
-  EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers());
-}
-
-TEST(TestConfig, ForcedKeyFrameIntervalOff) {
-  TestConfig config;
-  config.keyframe_interval = 0;
-  EXPECT_THAT(config.FrameTypeForFrame(0), ElementsAre(kVideoFrameDelta));
-  EXPECT_THAT(config.FrameTypeForFrame(1), ElementsAre(kVideoFrameDelta));
-  EXPECT_THAT(config.FrameTypeForFrame(2), ElementsAre(kVideoFrameDelta));
-}
-
-TEST(TestConfig, ForcedKeyFrameIntervalOn) {
-  TestConfig config;
-  config.keyframe_interval = 3;
-  EXPECT_THAT(config.FrameTypeForFrame(0), ElementsAre(kVideoFrameKey));
-  EXPECT_THAT(config.FrameTypeForFrame(1), ElementsAre(kVideoFrameDelta));
-  EXPECT_THAT(config.FrameTypeForFrame(2), ElementsAre(kVideoFrameDelta));
-  EXPECT_THAT(config.FrameTypeForFrame(3), ElementsAre(kVideoFrameKey));
-  EXPECT_THAT(config.FrameTypeForFrame(4), ElementsAre(kVideoFrameDelta));
-  EXPECT_THAT(config.FrameTypeForFrame(5), ElementsAre(kVideoFrameDelta));
-}
-
-TEST(TestConfig, FilenameWithParams) {
-  TestConfig config;
-  config.filename = "filename";
-  webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings);
-  config.hw_encoder = true;
-  config.codec_settings.startBitrate = 400;
-  EXPECT_EQ("filename_VP8_hw_400", config.FilenameWithParams());
-}
-
-}  // namespace test
-}  // namespace webrtc
diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_config_unittest.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_config_unittest.cc
new file mode 100644
index 0000000..d01a842
--- /dev/null
+++ b/modules/video_coding/codecs/test/videocodec_test_fixture_config_unittest.cc
@@ -0,0 +1,60 @@
+/*
+ *  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 "api/test/videocodec_test_fixture.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+#include "test/video_codec_settings.h"
+
+using ::testing::ElementsAre;
+
+namespace webrtc {
+namespace test {
+
+using Config = VideoCodecTestFixture::Config;
+
+namespace {
+const size_t kNumTemporalLayers = 2;
+}  // namespace
+
+TEST(Config, NumberOfCoresWithUseSingleCore) {
+  Config config;
+  config.use_single_core = true;
+  EXPECT_EQ(1u, config.NumberOfCores());
+}
+
+TEST(Config, NumberOfCoresWithoutUseSingleCore) {
+  Config config;
+  config.use_single_core = false;
+  EXPECT_GE(config.NumberOfCores(), 1u);
+}
+
+TEST(Config, NumberOfTemporalLayersIsOne) {
+  Config config;
+  webrtc::test::CodecSettings(kVideoCodecH264, &config.codec_settings);
+  EXPECT_EQ(1u, config.NumberOfTemporalLayers());
+}
+
+TEST(Config, NumberOfTemporalLayers_Vp8) {
+  Config config;
+  webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings);
+  config.codec_settings.VP8()->numberOfTemporalLayers = kNumTemporalLayers;
+  EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers());
+}
+
+TEST(Config, NumberOfTemporalLayers_Vp9) {
+  Config config;
+  webrtc::test::CodecSettings(kVideoCodecVP9, &config.codec_settings);
+  config.codec_settings.VP9()->numberOfTemporalLayers = kNumTemporalLayers;
+  EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers());
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
index 8954cc3..5885119 100644
--- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
@@ -19,13 +19,17 @@
 #endif
 
 #include "api/video_codecs/sdp_video_format.h"
+#include "call/video_config.h"
 #include "common_types.h"  // NOLINT(build/include)
+#include "media/base/h264_profile_level_id.h"
 #include "media/engine/internaldecoderfactory.h"
 #include "media/engine/internalencoderfactory.h"
+#include "media/engine/simulcast.h"
 #include "media/engine/simulcast_encoder_adapter.h"
 #include "media/engine/videodecodersoftwarefallbackwrapper.h"
 #include "media/engine/videoencodersoftwarefallbackwrapper.h"
 #include "modules/video_coding/codecs/vp8/include/vp8_common_types.h"
+#include "modules/video_coding/codecs/vp9/svc_config.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "modules/video_coding/include/video_coding.h"
 #include "rtc_base/checks.h"
@@ -33,16 +37,95 @@
 #include "rtc_base/event.h"
 #include "rtc_base/file.h"
 #include "rtc_base/ptr_util.h"
+#include "rtc_base/strings/string_builder.h"
+#include "system_wrappers/include/cpu_info.h"
 #include "system_wrappers/include/sleep.h"
 #include "test/gtest.h"
 #include "test/testsupport/fileutils.h"
+#include "test/video_codec_settings.h"
 
 namespace webrtc {
 namespace test {
 
-namespace {
+using VideoStatistics = VideoCodecTestStats::VideoStatistics;
 
-bool RunEncodeInRealTime(const TestConfig& config) {
+namespace {
+const int kBaseKeyFrameInterval = 3000;
+const int kMaxBitrateBps = 5000 * 1000;  // From kSimulcastFormats.
+const int kMaxFramerateFps = 30;
+const int kMaxQp = 56;
+
+void ConfigureSimulcast(VideoCodec* codec_settings) {
+  const std::vector<webrtc::VideoStream> streams = cricket::GetSimulcastConfig(
+      codec_settings->numberOfSimulcastStreams, codec_settings->width,
+      codec_settings->height, kMaxBitrateBps, kMaxQp, kMaxFramerateFps, false);
+
+  for (size_t i = 0; i < streams.size(); ++i) {
+    SimulcastStream* ss = &codec_settings->simulcastStream[i];
+    ss->width = static_cast<uint16_t>(streams[i].width);
+    ss->height = static_cast<uint16_t>(streams[i].height);
+    ss->numberOfTemporalLayers =
+        static_cast<unsigned char>(*streams[i].num_temporal_layers);
+    ss->maxBitrate = streams[i].max_bitrate_bps / 1000;
+    ss->targetBitrate = streams[i].target_bitrate_bps / 1000;
+    ss->minBitrate = streams[i].min_bitrate_bps / 1000;
+    ss->qpMax = streams[i].max_qp;
+    ss->active = true;
+  }
+}
+
+void ConfigureSvc(VideoCodec* codec_settings) {
+  RTC_CHECK_EQ(kVideoCodecVP9, codec_settings->codecType);
+
+  const std::vector<SpatialLayer> layers =
+      GetSvcConfig(codec_settings->width, codec_settings->height,
+                   codec_settings->VP9()->numberOfSpatialLayers,
+                   codec_settings->VP9()->numberOfTemporalLayers, false);
+
+  for (size_t i = 0; i < layers.size(); ++i) {
+    codec_settings->spatialLayers[i] = layers[i];
+  }
+}
+
+std::string CodecSpecificToString(const VideoCodec& codec) {
+  char buf[1024];
+  rtc::SimpleStringBuilder ss(buf);
+  switch (codec.codecType) {
+    case kVideoCodecVP8:
+      ss << "complexity: " << codec.VP8().complexity;
+      ss << "\nnum_temporal_layers: "
+         << static_cast<int>(codec.VP8().numberOfTemporalLayers);
+      ss << "\ndenoising: " << codec.VP8().denoisingOn;
+      ss << "\nautomatic_resize: " << codec.VP8().automaticResizeOn;
+      ss << "\nframe_dropping: " << codec.VP8().frameDroppingOn;
+      ss << "\nkey_frame_interval: " << codec.VP8().keyFrameInterval;
+      break;
+    case kVideoCodecVP9:
+      ss << "complexity: " << codec.VP9().complexity;
+      ss << "\nnum_temporal_layers: "
+         << static_cast<int>(codec.VP9().numberOfTemporalLayers);
+      ss << "\nnum_spatial_layers: "
+         << static_cast<int>(codec.VP9().numberOfSpatialLayers);
+      ss << "\ndenoising: " << codec.VP9().denoisingOn;
+      ss << "\nframe_dropping: " << codec.VP9().frameDroppingOn;
+      ss << "\nkey_frame_interval: " << codec.VP9().keyFrameInterval;
+      ss << "\nadaptive_qp_mode: " << codec.VP9().adaptiveQpMode;
+      ss << "\nautomatic_resize: " << codec.VP9().automaticResizeOn;
+      ss << "\nflexible_mode: " << codec.VP9().flexibleMode;
+      break;
+    case kVideoCodecH264:
+      ss << "frame_dropping: " << codec.H264().frameDroppingOn;
+      ss << "\nkey_frame_interval: " << codec.H264().keyFrameInterval;
+      ss << "\nprofile: " << codec.H264().profile;
+      break;
+    default:
+      break;
+  }
+  ss << "\n";
+  return ss.str();
+}
+
+bool RunEncodeInRealTime(const VideoCodecTestFixtureImpl::Config& config) {
   if (config.measure_cpu) {
     return true;
   }
@@ -54,8 +137,165 @@
 #endif
 }
 
+std::string FilenameWithParams(
+    const VideoCodecTestFixtureImpl::Config& config) {
+  std::string implementation_type = config.hw_encoder ? "hw" : "sw";
+  return config.filename + "_" + config.CodecName() + "_" +
+         implementation_type + "_" +
+         std::to_string(config.codec_settings.startBitrate);
+}
+
 }  // namespace
 
+VideoCodecTestFixtureImpl::Config::Config() = default;
+
+void VideoCodecTestFixtureImpl::Config::SetCodecSettings(
+    std::string codec_name,
+    size_t num_simulcast_streams,
+    size_t num_spatial_layers,
+    size_t num_temporal_layers,
+    bool denoising_on,
+    bool frame_dropper_on,
+    bool spatial_resize_on,
+    size_t width,
+    size_t height) {
+  this->codec_name = codec_name;
+  VideoCodecType codec_type = PayloadStringToCodecType(codec_name);
+  webrtc::test::CodecSettings(codec_type, &codec_settings);
+
+  // TODO(brandtr): Move the setting of |width| and |height| to the tests, and
+  // DCHECK that they are set before initializing the codec instead.
+  codec_settings.width = static_cast<uint16_t>(width);
+  codec_settings.height = static_cast<uint16_t>(height);
+
+  RTC_CHECK(num_simulcast_streams >= 1 &&
+            num_simulcast_streams <= kMaxSimulcastStreams);
+  RTC_CHECK(num_spatial_layers >= 1 && num_spatial_layers <= kMaxSpatialLayers);
+  RTC_CHECK(num_temporal_layers >= 1 &&
+            num_temporal_layers <= kMaxTemporalStreams);
+
+  // Simulcast is only available with VP8.
+  RTC_CHECK(num_simulcast_streams < 2 || codec_type == kVideoCodecVP8);
+
+  // Spatial scalability is only available with VP9.
+  RTC_CHECK(num_spatial_layers < 2 || codec_type == kVideoCodecVP9);
+
+  // Some base code requires numberOfSimulcastStreams to be set to zero
+  // when simulcast is not used.
+  codec_settings.numberOfSimulcastStreams =
+      num_simulcast_streams <= 1 ? 0
+                                 : static_cast<uint8_t>(num_simulcast_streams);
+
+  switch (codec_settings.codecType) {
+    case kVideoCodecVP8:
+      codec_settings.VP8()->numberOfTemporalLayers =
+          static_cast<uint8_t>(num_temporal_layers);
+      codec_settings.VP8()->denoisingOn = denoising_on;
+      codec_settings.VP8()->automaticResizeOn = spatial_resize_on;
+      codec_settings.VP8()->frameDroppingOn = frame_dropper_on;
+      codec_settings.VP8()->keyFrameInterval = kBaseKeyFrameInterval;
+      break;
+    case kVideoCodecVP9:
+      codec_settings.VP9()->numberOfTemporalLayers =
+          static_cast<uint8_t>(num_temporal_layers);
+      codec_settings.VP9()->denoisingOn = denoising_on;
+      codec_settings.VP9()->frameDroppingOn = frame_dropper_on;
+      codec_settings.VP9()->keyFrameInterval = kBaseKeyFrameInterval;
+      codec_settings.VP9()->automaticResizeOn = spatial_resize_on;
+      codec_settings.VP9()->numberOfSpatialLayers =
+          static_cast<uint8_t>(num_spatial_layers);
+      break;
+    case kVideoCodecH264:
+      codec_settings.H264()->frameDroppingOn = frame_dropper_on;
+      codec_settings.H264()->keyFrameInterval = kBaseKeyFrameInterval;
+      break;
+    default:
+      break;
+  }
+
+  if (codec_settings.numberOfSimulcastStreams > 1) {
+    ConfigureSimulcast(&codec_settings);
+  } else if (codec_settings.codecType == kVideoCodecVP9 &&
+             codec_settings.VP9()->numberOfSpatialLayers > 1) {
+    ConfigureSvc(&codec_settings);
+  }
+}
+
+size_t VideoCodecTestFixtureImpl::Config::NumberOfCores() const {
+  return use_single_core ? 1 : CpuInfo::DetectNumberOfCores();
+}
+
+size_t VideoCodecTestFixtureImpl::Config::NumberOfTemporalLayers() const {
+  if (codec_settings.codecType == kVideoCodecVP8) {
+    return codec_settings.VP8().numberOfTemporalLayers;
+  } else if (codec_settings.codecType == kVideoCodecVP9) {
+    return codec_settings.VP9().numberOfTemporalLayers;
+  } else {
+    return 1;
+  }
+}
+
+size_t VideoCodecTestFixtureImpl::Config::NumberOfSpatialLayers() const {
+  if (codec_settings.codecType == kVideoCodecVP9) {
+    return codec_settings.VP9().numberOfSpatialLayers;
+  } else {
+    return 1;
+  }
+}
+
+size_t VideoCodecTestFixtureImpl::Config::NumberOfSimulcastStreams() const {
+  return codec_settings.numberOfSimulcastStreams;
+}
+
+std::string VideoCodecTestFixtureImpl::Config::ToString() const {
+  std::string codec_type = CodecTypeToPayloadString(codec_settings.codecType);
+  std::stringstream ss;
+  ss << "filename: " << filename;
+  ss << "\nnum_frames: " << num_frames;
+  ss << "\nmax_payload_size_bytes: " << max_payload_size_bytes;
+  ss << "\ndecode: " << decode;
+  ss << "\nuse_single_core: " << use_single_core;
+  ss << "\nmeasure_cpu: " << measure_cpu;
+  ss << "\nnum_cores: " << NumberOfCores();
+  ss << "\nkeyframe_interval: " << keyframe_interval;
+  ss << "\ncodec_type: " << codec_type;
+  ss << "\n--> codec_settings";
+  ss << "\nwidth: " << codec_settings.width;
+  ss << "\nheight: " << codec_settings.height;
+  ss << "\nmax_framerate_fps: " << codec_settings.maxFramerate;
+  ss << "\nstart_bitrate_kbps: " << codec_settings.startBitrate;
+  ss << "\nmax_bitrate_kbps: " << codec_settings.maxBitrate;
+  ss << "\nmin_bitrate_kbps: " << codec_settings.minBitrate;
+  ss << "\nmax_qp: " << codec_settings.qpMax;
+  ss << "\nnum_simulcast_streams : "
+     << static_cast<int>(codec_settings.numberOfSimulcastStreams);
+  ss << "\n"
+     << "--> codec_settings." << codec_type << "\n";
+  ss << CodecSpecificToString(codec_settings);
+  return ss.str();
+}
+
+std::string VideoCodecTestFixtureImpl::Config::CodecName() const {
+  std::string name = codec_name;
+  if (name.empty()) {
+    name = CodecTypeToPayloadString(codec_settings.codecType);
+  }
+  if (codec_settings.codecType == kVideoCodecH264) {
+    if (h264_codec_settings.profile == H264::kProfileConstrainedHigh) {
+      return name + "-CHP";
+    } else {
+      RTC_DCHECK_EQ(h264_codec_settings.profile,
+                    H264::kProfileConstrainedBaseline);
+      return name + "-CBP";
+    }
+  }
+  return name;
+}
+
+bool VideoCodecTestFixtureImpl::Config::IsAsyncCodec() const {
+  return hw_encoder || hw_decoder;
+}
+
 // TODO(kthelgason): Move this out of the test fixture impl and
 // make available as a shared utility class.
 void VideoCodecTestFixtureImpl::H264KeyframeChecker::
@@ -94,7 +334,7 @@
 
 class VideoCodecTestFixtureImpl::CpuProcessTime final {
  public:
-  explicit CpuProcessTime(const TestConfig& config) : config_(config) {}
+  explicit CpuProcessTime(const Config& config) : config_(config) {}
   ~CpuProcessTime() {}
 
   void Start() {
@@ -122,13 +362,13 @@
     return static_cast<double>(cpu_time_) / wallclock_time_ * 100.0;
   }
 
-  const TestConfig config_;
+  const Config config_;
   int64_t cpu_time_ = 0;
   int64_t wallclock_time_ = 0;
 };
 
 VideoCodecTestFixtureImpl::
-    VideoCodecTestFixtureImpl(TestConfig config)
+    VideoCodecTestFixtureImpl(Config config)
     : config_(config) {
 #if defined(WEBRTC_ANDROID)
   InitializeAndroidObjects();
@@ -137,7 +377,7 @@
 
 VideoCodecTestFixtureImpl::
     VideoCodecTestFixtureImpl(
-        TestConfig config,
+        Config config,
         std::unique_ptr<VideoDecoderFactory> decoder_factory,
         std::unique_ptr<VideoEncoderFactory> encoder_factory)
     : decoder_factory_(std::move(decoder_factory)),
@@ -345,7 +585,21 @@
 }
 
 void VideoCodecTestFixtureImpl::CreateEncoderAndDecoder() {
-  const SdpVideoFormat format = config_.ToSdpVideoFormat();
+  SdpVideoFormat::Parameters params;
+  if (config_.codec_settings.codecType == kVideoCodecH264) {
+    const char* packetization_mode =
+        config_.h264_codec_settings.packetization_mode ==
+                H264PacketizationMode::NonInterleaved
+            ? "1"
+            : "0";
+    params = {{cricket::kH264FmtpProfileLevelId,
+               *H264::ProfileLevelIdToString(H264::ProfileLevelId(
+                   config_.h264_codec_settings.profile, H264::kLevel3_1))},
+              {cricket::kH264FmtpPacketizationMode, packetization_mode}};
+  } else {
+    params = {};
+  }
+  SdpVideoFormat format(config_.codec_name);
   if (!decoder_factory_)
     decoder_factory_ = CreateDecoderFactory();
   if (!encoder_factory_)
@@ -393,7 +647,7 @@
   encoder_.reset();
 }
 
-Stats VideoCodecTestFixtureImpl::GetStats() {
+VideoCodecTestStats& VideoCodecTestFixtureImpl::GetStats() {
   return stats_;
 }
 
@@ -422,7 +676,7 @@
          simulcast_svc_idx < num_simulcast_or_spatial_layers;
          ++simulcast_svc_idx) {
       const std::string output_filename_base =
-          OutputPath() + config_.FilenameWithParams() + "_" +
+          OutputPath() + FilenameWithParams(config_) + "_" +
           std::to_string(simulcast_svc_idx);
 
       if (visualization_params->save_encoded_ivf) {
@@ -480,7 +734,7 @@
 
 void VideoCodecTestFixtureImpl::PrintSettings(
     rtc::test::TaskQueueForTest* task_queue) const {
-  printf("==> TestConfig\n");
+  printf("==> Config\n");
   printf("%s\n", config_.ToString().c_str());
 
   printf("==> Codec names\n");
diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.h b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.h
index 7d9b25d..324983c 100644
--- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.h
+++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.h
@@ -20,8 +20,7 @@
 #include "api/video_codecs/video_encoder_factory.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "common_video/h264/h264_common.h"
-#include "modules/video_coding/codecs/test/stats.h"
-#include "modules/video_coding/codecs/test/test_config.h"
+#include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
 #include "modules/video_coding/codecs/test/videoprocessor.h"
 #include "modules/video_coding/utility/ivf_file_writer.h"
 #include "rtc_base/task_queue_for_test.h"
@@ -38,15 +37,15 @@
 class VideoCodecTestFixtureImpl : public VideoCodecTestFixture {
   // Verifies that all H.264 keyframes contain SPS/PPS/IDR NALUs.
  public:
-  class H264KeyframeChecker : public TestConfig::EncodedFrameChecker {
+  class H264KeyframeChecker : public EncodedFrameChecker {
    public:
     void CheckEncodedFrame(webrtc::VideoCodecType codec,
                            const EncodedImage& encoded_frame) const override;
   };
 
-  explicit VideoCodecTestFixtureImpl(TestConfig config);
+  explicit VideoCodecTestFixtureImpl(Config config);
   VideoCodecTestFixtureImpl(
-      TestConfig config,
+      Config config,
       std::unique_ptr<VideoDecoderFactory> decoder_factory,
       std::unique_ptr<VideoEncoderFactory> encoder_factory);
   ~VideoCodecTestFixtureImpl() override;
@@ -57,7 +56,7 @@
                const BitstreamThresholds* bs_thresholds,
                const VisualizationParams* visualization_params) override;
 
-  Stats GetStats() override;
+  VideoCodecTestStats& GetStats() override;
 
  private:
   class CpuProcessTime;
@@ -78,12 +77,13 @@
       const std::vector<QualityThresholds>* quality_thresholds,
       const BitstreamThresholds* bs_thresholds);
 
-  void VerifyVideoStatistic(const VideoStatistics& video_stat,
-                            const RateControlThresholds* rc_thresholds,
-                            const QualityThresholds* quality_thresholds,
-                            const BitstreamThresholds* bs_thresholds,
-                            size_t target_bitrate_kbps,
-                            float input_framerate_fps);
+  void VerifyVideoStatistic(
+      const VideoCodecTestStats::VideoStatistics& video_stat,
+      const RateControlThresholds* rc_thresholds,
+      const QualityThresholds* quality_thresholds,
+      const BitstreamThresholds* bs_thresholds,
+      size_t target_bitrate_kbps,
+      float input_framerate_fps);
 
   void PrintSettings(rtc::test::TaskQueueForTest* task_queue) const;
   std::unique_ptr<VideoDecoderFactory> CreateDecoderFactory();
@@ -96,8 +96,8 @@
   VideoProcessor::VideoDecoderList decoders_;
 
   // Helper objects.
-  TestConfig config_;
-  Stats stats_;
+  Config config_;
+  VideoCodecTestStatsImpl stats_;
   std::unique_ptr<FrameReader> source_frame_reader_;
   VideoProcessor::IvfFileWriterList encoded_frame_writers_;
   VideoProcessor::FrameWriterList decoded_frame_writers_;
diff --git a/modules/video_coding/codecs/test/videocodec_test_libvpx.cc b/modules/video_coding/codecs/test/videocodec_test_libvpx.cc
index fb1dfb5..f65b9e6 100644
--- a/modules/video_coding/codecs/test/videocodec_test_libvpx.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_libvpx.cc
@@ -12,7 +12,6 @@
 
 #include "api/test/create_videocodec_test_fixture.h"
 #include "media/base/mediaconstants.h"
-#include "modules/video_coding/codecs/test/test_config.h"
 #include "modules/video_coding/utility/vp8_header_parser.h"
 #include "modules/video_coding/utility/vp9_uncompressed_header_parser.h"
 #include "rtc_base/ptr_util.h"
@@ -22,6 +21,8 @@
 namespace webrtc {
 namespace test {
 
+using VideoStatistics = VideoCodecTestStats::VideoStatistics;
+
 namespace {
 // Codec settings.
 const int kCifWidth = 352;
@@ -33,7 +34,7 @@
                                      1800, 2000, 2200, 2500};
 const size_t kNumFirstFramesToSkipAtRdPerfAnalysis = 60;
 
-class QpFrameChecker : public TestConfig::EncodedFrameChecker {
+class QpFrameChecker : public VideoCodecTestFixture::EncodedFrameChecker {
  public:
   void CheckEncodedFrame(webrtc::VideoCodecType codec,
                          const EncodedImage& encoded_frame) const override {
@@ -51,8 +52,8 @@
   }
 };
 
-TestConfig CreateTestConfig() {
-  TestConfig config;
+VideoCodecTestFixture::Config CreateConfig() {
+  VideoCodecTestFixture::Config config;
   config.filename = "foreman_cif";
   config.filepath = ResourcePath(config.filename, "yuv");
   config.num_frames = kNumFramesLong;
@@ -88,7 +89,7 @@
 
 #if !defined(RTC_DISABLE_VP9)
 TEST(VideoCodecTestLibvpx, HighBitrateVP9) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, false, true, false,
                           kCifWidth, kCifHeight);
   config.num_frames = kNumFramesShort;
@@ -108,7 +109,7 @@
 }
 
 TEST(VideoCodecTestLibvpx, ChangeBitrateVP9) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, false, true, false,
                           kCifWidth, kCifHeight);
   const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@@ -133,7 +134,7 @@
 }
 
 TEST(VideoCodecTestLibvpx, ChangeFramerateVP9) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, false, true, false,
                           kCifWidth, kCifHeight);
   const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@@ -160,7 +161,7 @@
 }
 
 TEST(VideoCodecTestLibvpx, DenoiserOnVP9) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, true, true, false,
                           kCifWidth, kCifHeight);
   config.num_frames = kNumFramesShort;
@@ -180,7 +181,7 @@
 }
 
 TEST(VideoCodecTestLibvpx, VeryLowBitrateVP9) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, false, true, true,
                           kCifWidth, kCifHeight);
   const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@@ -204,7 +205,7 @@
 #endif  // !defined(RTC_DISABLE_VP9)
 
 TEST(VideoCodecTestLibvpx, HighBitrateVP8) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 1, true, true, false,
                           kCifWidth, kCifHeight);
   config.num_frames = kNumFramesShort;
@@ -242,7 +243,7 @@
 #define MAYBE_ChangeBitrateVP8 ChangeBitrateVP8
 #endif
 TEST(VideoCodecTestLibvpx, MAYBE_ChangeBitrateVP8) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 1, true, true, false,
                           kCifWidth, kCifHeight);
   const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@@ -277,7 +278,7 @@
 #define MAYBE_ChangeFramerateVP8 ChangeFramerateVP8
 #endif
 TEST(VideoCodecTestLibvpx, MAYBE_ChangeFramerateVP8) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 1, true, true, false,
                           kCifWidth, kCifHeight);
   const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@@ -317,7 +318,7 @@
 #define MAYBE_TemporalLayersVP8 TemporalLayersVP8
 #endif
 TEST(VideoCodecTestLibvpx, MAYBE_TemporalLayersVP8) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 3, true, true, false,
                           kCifWidth, kCifHeight);
   const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@@ -353,7 +354,7 @@
 #define MAYBE_MultiresVP8 MultiresVP8
 #endif
 TEST(VideoCodecTestLibvpx, MAYBE_MultiresVP8) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.filename = "ConferenceMotion_1280_720_50";
   config.filepath = ResourcePath(config.filename, "yuv");
   config.num_frames = 100;
@@ -379,7 +380,7 @@
 #define MAYBE_SimulcastVP8 SimulcastVP8
 #endif
 TEST(VideoCodecTestLibvpx, MAYBE_SimulcastVP8) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.filename = "ConferenceMotion_1280_720_50";
   config.filepath = ResourcePath(config.filename, "yuv");
   config.num_frames = 100;
@@ -406,7 +407,7 @@
 #define MAYBE_SvcVP9 SvcVP9
 #endif
 TEST(VideoCodecTestLibvpx, MAYBE_SvcVP9) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.filename = "ConferenceMotion_1280_720_50";
   config.filepath = ResourcePath(config.filename, "yuv");
   config.num_frames = 100;
@@ -427,7 +428,7 @@
 }
 
 TEST(VideoCodecTestLibvpx, DISABLED_MultiresVP8RdPerf) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.filename = "FourPeople_1280x720_30";
   config.filepath = ResourcePath(config.filename, "yuv");
   config.num_frames = 300;
@@ -454,7 +455,7 @@
 }
 
 TEST(VideoCodecTestLibvpx, DISABLED_SvcVP9RdPerf) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.filename = "FourPeople_1280x720_30";
   config.filepath = ResourcePath(config.filename, "yuv");
   config.num_frames = 300;
diff --git a/modules/video_coding/codecs/test/videocodec_test_mediacodec.cc b/modules/video_coding/codecs/test/videocodec_test_mediacodec.cc
index 2bbbda9..a0b3637 100644
--- a/modules/video_coding/codecs/test/videocodec_test_mediacodec.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_mediacodec.cc
@@ -26,8 +26,8 @@
 const int kForemanNumFrames = 300;
 const int kForemanFramerateFps = 30;
 
-TestConfig CreateTestConfig() {
-  TestConfig config;
+VideoCodecTestFixture::Config CreateConfig() {
+  VideoCodecTestFixture::Config config;
   config.filename = "foreman_cif";
   config.filepath = ResourcePath(config.filename, "yuv");
   config.num_frames = kForemanNumFrames;
@@ -38,7 +38,7 @@
 }  // namespace
 
 TEST(VideoCodecTestMediaCodec, ForemanCif500kbpsVp8) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 1, false, false, false,
                           352, 288);
   auto fixture = CreateVideoCodecTestFixture(config);
@@ -59,7 +59,7 @@
 }
 
 TEST(VideoCodecTestMediaCodec, ForemanCif500kbpsH264CBP) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   const auto frame_checker = rtc::MakeUnique<
       VideoCodecTestFixtureImpl::H264KeyframeChecker>();
   config.encoded_frame_checker = frame_checker.get();
@@ -85,7 +85,7 @@
 // TODO(brandtr): Enable this test when we have trybots/buildbots with
 // HW encoders that support CHP.
 TEST(VideoCodecTestMediaCodec, DISABLED_ForemanCif500kbpsH264CHP) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   const auto frame_checker = rtc::MakeUnique<
       VideoCodecTestFixtureImpl::H264KeyframeChecker>();
 
@@ -111,7 +111,7 @@
 }
 
 TEST(VideoCodecTestMediaCodec, ForemanMixedRes100kbpsVp8H264) {
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   const int kNumFrames = 30;
   const std::vector<std::string> codecs = {cricket::kVp8CodecName,
                                            cricket::kH264CodecName};
diff --git a/modules/video_coding/codecs/test/videocodec_test_openh264.cc b/modules/video_coding/codecs/test/videocodec_test_openh264.cc
index d2bcc7f..3a0561a 100644
--- a/modules/video_coding/codecs/test/videocodec_test_openh264.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_openh264.cc
@@ -25,8 +25,8 @@
 const int kCifHeight = 288;
 const int kNumFrames = 100;
 
-TestConfig CreateTestConfig() {
-  TestConfig config;
+VideoCodecTestFixture::Config CreateConfig() {
+  VideoCodecTestFixture::Config config;
   config.filename = "foreman_cif";
   config.filepath = ResourcePath(config.filename, "yuv");
   config.num_frames = kNumFrames;
@@ -41,7 +41,7 @@
 TEST(VideoCodecTestOpenH264, ConstantHighBitrate) {
   auto frame_checker = rtc::MakeUnique<
       VideoCodecTestFixtureImpl::H264KeyframeChecker>();
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kH264CodecName, 1, 1, 1, false, true, false,
                           kCifWidth, kCifHeight);
   config.encoded_frame_checker = frame_checker.get();
@@ -63,7 +63,7 @@
 TEST(VideoCodecTestOpenH264, SingleNalUnit) {
   auto frame_checker = rtc::MakeUnique<
       VideoCodecTestFixtureImpl::H264KeyframeChecker>();
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.h264_codec_settings.packetization_mode =
       H264PacketizationMode::SingleNalUnit;
   config.max_payload_size_bytes = 500;
diff --git a/modules/video_coding/codecs/test/videocodec_test_parameterized.cc b/modules/video_coding/codecs/test/videocodec_test_parameterized.cc
index c0c8a14..a9118c5 100644
--- a/modules/video_coding/codecs/test/videocodec_test_parameterized.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_parameterized.cc
@@ -55,7 +55,7 @@
                size_t height,
                size_t framerate,
                const std::string& filename) {
-    TestConfig config;
+    VideoCodecTestFixture::Config config;
     config.filename = filename;
     config.filepath = ResourcePath(filename, "yuv");
     config.use_single_core = kUseSingleCore;
diff --git a/modules/video_coding/codecs/test/stats.cc b/modules/video_coding/codecs/test/videocodec_test_stats_impl.cc
similarity index 72%
rename from modules/video_coding/codecs/test/stats.cc
rename to modules/video_coding/codecs/test/videocodec_test_stats_impl.cc
index d4a6576..37c38e8 100644
--- a/modules/video_coding/codecs/test/stats.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_stats_impl.cc
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "modules/video_coding/codecs/test/stats.h"
+#include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
 
 #include <algorithm>
 #include <cmath>
@@ -21,77 +21,18 @@
 namespace webrtc {
 namespace test {
 
+using FrameStatistics = VideoCodecTestStats::FrameStatistics;
+using VideoStatistics = VideoCodecTestStats::VideoStatistics;
+
 namespace {
 const int kMaxBitrateMismatchPercent = 20;
 }
 
-std::string FrameStatistics::ToString() const {
-  std::stringstream ss;
-  ss << "frame_number " << frame_number;
-  ss << " decoded_width " << decoded_width;
-  ss << " decoded_height " << decoded_height;
-  ss << " spatial_idx " << spatial_idx;
-  ss << " temporal_idx " << temporal_idx;
-  ss << " inter_layer_predicted " << inter_layer_predicted;
-  ss << " non_ref_for_inter_layer_pred " << non_ref_for_inter_layer_pred;
-  ss << " frame_type " << frame_type;
-  ss << " length_bytes " << length_bytes;
-  ss << " qp " << qp;
-  ss << " psnr " << psnr;
-  ss << " psnr_y " << psnr_y;
-  ss << " psnr_u " << psnr_u;
-  ss << " psnr_v " << psnr_v;
-  ss << " ssim " << ssim;
-  ss << " encode_time_us " << encode_time_us;
-  ss << " decode_time_us " << decode_time_us;
-  ss << " rtp_timestamp " << rtp_timestamp;
-  ss << " target_bitrate_kbps " << target_bitrate_kbps;
-  return ss.str();
-}
+VideoCodecTestStatsImpl::VideoCodecTestStatsImpl() = default;
+VideoCodecTestStatsImpl::~VideoCodecTestStatsImpl() = default;
 
-std::string VideoStatistics::ToString(std::string prefix) const {
-  std::stringstream ss;
-  ss << prefix << "target_bitrate_kbps: " << target_bitrate_kbps;
-  ss << "\n" << prefix << "input_framerate_fps: " << input_framerate_fps;
-  ss << "\n" << prefix << "spatial_idx: " << spatial_idx;
-  ss << "\n" << prefix << "temporal_idx: " << temporal_idx;
-  ss << "\n" << prefix << "width: " << width;
-  ss << "\n" << prefix << "height: " << height;
-  ss << "\n" << prefix << "length_bytes: " << length_bytes;
-  ss << "\n" << prefix << "bitrate_kbps: " << bitrate_kbps;
-  ss << "\n" << prefix << "framerate_fps: " << framerate_fps;
-  ss << "\n" << prefix << "enc_speed_fps: " << enc_speed_fps;
-  ss << "\n" << prefix << "dec_speed_fps: " << dec_speed_fps;
-  ss << "\n" << prefix << "avg_delay_sec: " << avg_delay_sec;
-  ss << "\n"
-     << prefix << "max_key_frame_delay_sec: " << max_key_frame_delay_sec;
-  ss << "\n"
-     << prefix << "max_delta_frame_delay_sec: " << max_delta_frame_delay_sec;
-  ss << "\n"
-     << prefix << "time_to_reach_target_bitrate_sec: "
-     << time_to_reach_target_bitrate_sec;
-  ss << "\n"
-     << prefix << "avg_key_frame_size_bytes: " << avg_key_frame_size_bytes;
-  ss << "\n"
-     << prefix << "avg_delta_frame_size_bytes: " << avg_delta_frame_size_bytes;
-  ss << "\n" << prefix << "avg_qp: " << avg_qp;
-  ss << "\n" << prefix << "avg_psnr: " << avg_psnr;
-  ss << "\n" << prefix << "min_psnr: " << min_psnr;
-  ss << "\n" << prefix << "avg_ssim: " << avg_ssim;
-  ss << "\n" << prefix << "min_ssim: " << min_ssim;
-  ss << "\n" << prefix << "num_input_frames: " << num_input_frames;
-  ss << "\n" << prefix << "num_encoded_frames: " << num_encoded_frames;
-  ss << "\n" << prefix << "num_decoded_frames: " << num_decoded_frames;
-  ss << "\n"
-     << prefix
-     << "num_dropped_frames: " << num_input_frames - num_encoded_frames;
-  ss << "\n" << prefix << "num_key_frames: " << num_key_frames;
-  ss << "\n" << prefix << "num_spatial_resizes: " << num_spatial_resizes;
-  ss << "\n" << prefix << "max_nalu_size_bytes: " << max_nalu_size_bytes;
-  return ss.str();
-}
-
-FrameStatistics* Stats::AddFrame(size_t timestamp, size_t layer_idx) {
+FrameStatistics* VideoCodecTestStatsImpl::AddFrame(size_t timestamp,
+                                                   size_t layer_idx) {
   RTC_DCHECK(rtp_timestamp_to_frame_num_[layer_idx].find(timestamp) ==
              rtp_timestamp_to_frame_num_[layer_idx].end());
   const size_t frame_num = layer_stats_[layer_idx].size();
@@ -100,20 +41,23 @@
   return &layer_stats_[layer_idx].back();
 }
 
-FrameStatistics* Stats::GetFrame(size_t frame_num, size_t layer_idx) {
+FrameStatistics* VideoCodecTestStatsImpl::GetFrame(size_t frame_num,
+                                                   size_t layer_idx) {
   RTC_CHECK_LT(frame_num, layer_stats_[layer_idx].size());
   return &layer_stats_[layer_idx][frame_num];
 }
 
-FrameStatistics* Stats::GetFrameWithTimestamp(size_t timestamp,
-                                              size_t layer_idx) {
+FrameStatistics* VideoCodecTestStatsImpl::GetFrameWithTimestamp(
+    size_t timestamp,
+    size_t layer_idx) {
   RTC_DCHECK(rtp_timestamp_to_frame_num_[layer_idx].find(timestamp) !=
              rtp_timestamp_to_frame_num_[layer_idx].end());
 
   return GetFrame(rtp_timestamp_to_frame_num_[layer_idx][timestamp], layer_idx);
 }
 
-std::vector<VideoStatistics> Stats::SliceAndCalcLayerVideoStatistic(
+std::vector<VideoStatistics>
+VideoCodecTestStatsImpl::SliceAndCalcLayerVideoStatistic(
     size_t first_frame_num,
     size_t last_frame_num) {
   std::vector<VideoStatistics> layer_stats;
@@ -138,7 +82,7 @@
   return layer_stats;
 }
 
-VideoStatistics Stats::SliceAndCalcAggregatedVideoStatistic(
+VideoStatistics VideoCodecTestStatsImpl::SliceAndCalcAggregatedVideoStatistic(
     size_t first_frame_num,
     size_t last_frame_num) {
   size_t num_spatial_layers = 0;
@@ -153,7 +97,7 @@
                                     num_temporal_layers - 1, true);
 }
 
-void Stats::PrintFrameStatistics() {
+void VideoCodecTestStatsImpl::PrintFrameStatistics() {
   for (size_t frame_num = 0; frame_num < layer_stats_[0].size(); ++frame_num) {
     for (const auto& it : layer_stats_) {
       const FrameStatistics& frame_stat = it.second[frame_num];
@@ -162,16 +106,16 @@
   }
 }
 
-size_t Stats::Size(size_t spatial_idx) {
+size_t VideoCodecTestStatsImpl::Size(size_t spatial_idx) {
   return layer_stats_[spatial_idx].size();
 }
 
-void Stats::Clear() {
+void VideoCodecTestStatsImpl::Clear() {
   layer_stats_.clear();
   rtp_timestamp_to_frame_num_.clear();
 }
 
-FrameStatistics Stats::AggregateFrameStatistic(
+FrameStatistics VideoCodecTestStatsImpl::AggregateFrameStatistic(
     size_t frame_num,
     size_t spatial_idx,
     bool aggregate_independent_layers) {
@@ -190,11 +134,12 @@
   return frame_stat;
 }
 
-size_t Stats::CalcLayerTargetBitrateKbps(size_t first_frame_num,
-                                         size_t last_frame_num,
-                                         size_t spatial_idx,
-                                         size_t temporal_idx,
-                                         bool aggregate_independent_layers) {
+size_t VideoCodecTestStatsImpl::CalcLayerTargetBitrateKbps(
+    size_t first_frame_num,
+    size_t last_frame_num,
+    size_t spatial_idx,
+    size_t temporal_idx,
+    bool aggregate_independent_layers) {
   size_t target_bitrate_kbps = 0;
 
   // We don't know if superframe includes all required spatial layers because
@@ -216,7 +161,7 @@
   return target_bitrate_kbps;
 }
 
-VideoStatistics Stats::SliceAndCalcVideoStatistic(
+VideoStatistics VideoCodecTestStatsImpl::SliceAndCalcVideoStatistic(
     size_t first_frame_num,
     size_t last_frame_num,
     size_t spatial_idx,
@@ -380,10 +325,11 @@
   return video_stat;
 }
 
-void Stats::GetNumberOfEncodedLayers(size_t first_frame_num,
-                                     size_t last_frame_num,
-                                     size_t* num_encoded_spatial_layers,
-                                     size_t* num_encoded_temporal_layers) {
+void VideoCodecTestStatsImpl::GetNumberOfEncodedLayers(
+    size_t first_frame_num,
+    size_t last_frame_num,
+    size_t* num_encoded_spatial_layers,
+    size_t* num_encoded_temporal_layers) {
   *num_encoded_spatial_layers = 0;
   *num_encoded_temporal_layers = 0;
 
diff --git a/modules/video_coding/codecs/test/videocodec_test_stats_impl.h b/modules/video_coding/codecs/test/videocodec_test_stats_impl.h
new file mode 100644
index 0000000..a2b2a0a
--- /dev/null
+++ b/modules/video_coding/codecs/test/videocodec_test_stats_impl.h
@@ -0,0 +1,85 @@
+/*
+ *  Copyright (c) 2011 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 MODULES_VIDEO_CODING_CODECS_TEST_VIDEOCODEC_TEST_STATS_IMPL_H_
+#define MODULES_VIDEO_CODING_CODECS_TEST_VIDEOCODEC_TEST_STATS_IMPL_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "api/test/videocodec_test_stats.h"  // NOLINT(build/include)
+#include "common_types.h"                    // NOLINT(build/include)
+
+namespace webrtc {
+namespace test {
+
+// Statistics for a sequence of processed frames. This class is not thread safe.
+class VideoCodecTestStatsImpl : public VideoCodecTestStats {
+ public:
+  VideoCodecTestStatsImpl();
+  ~VideoCodecTestStatsImpl() override;
+
+  // Creates a FrameStatistics for the next frame to be processed.
+  FrameStatistics* AddFrame(size_t timestamp, size_t spatial_idx) override;
+
+  // Returns the FrameStatistics corresponding to |frame_number| or |timestamp|.
+  FrameStatistics* GetFrame(size_t frame_number, size_t spatial_idx) override;
+  FrameStatistics* GetFrameWithTimestamp(size_t timestamp,
+                                         size_t spatial_idx) override;
+
+  std::vector<VideoStatistics> SliceAndCalcLayerVideoStatistic(
+      size_t first_frame_num,
+      size_t last_frame_num) override;
+
+  VideoStatistics SliceAndCalcAggregatedVideoStatistic(
+      size_t first_frame_num,
+      size_t last_frame_num) override;
+
+  void PrintFrameStatistics() override;
+
+  size_t Size(size_t spatial_idx) override;
+
+  void Clear() override;
+
+ private:
+  VideoCodecTestStats::FrameStatistics AggregateFrameStatistic(
+      size_t frame_num,
+      size_t spatial_idx,
+      bool aggregate_independent_layers);
+
+  size_t CalcLayerTargetBitrateKbps(size_t first_frame_num,
+                                    size_t last_frame_num,
+                                    size_t spatial_idx,
+                                    size_t temporal_idx,
+                                    bool aggregate_independent_layers);
+
+  VideoCodecTestStats::VideoStatistics SliceAndCalcVideoStatistic(
+      size_t first_frame_num,
+      size_t last_frame_num,
+      size_t spatial_idx,
+      size_t temporal_idx,
+      bool aggregate_independent_layers);
+
+  void GetNumberOfEncodedLayers(size_t first_frame_num,
+                                size_t last_frame_num,
+                                size_t* num_encoded_spatial_layers,
+                                size_t* num_encoded_temporal_layers);
+
+  // layer_idx -> stats.
+  std::map<size_t, std::vector<FrameStatistics>> layer_stats_;
+  // layer_idx -> rtp_timestamp -> frame_num.
+  std::map<size_t, std::map<size_t, size_t>> rtp_timestamp_to_frame_num_;
+};
+
+}  // namespace test
+}  // namespace webrtc
+
+#endif  // MODULES_VIDEO_CODING_CODECS_TEST_VIDEOCODEC_TEST_STATS_IMPL_H_
diff --git a/modules/video_coding/codecs/test/stats_unittest.cc b/modules/video_coding/codecs/test/videocodec_test_stats_impl_unittest.cc
similarity index 87%
rename from modules/video_coding/codecs/test/stats_unittest.cc
rename to modules/video_coding/codecs/test/videocodec_test_stats_impl_unittest.cc
index 3ef46a6..145b251 100644
--- a/modules/video_coding/codecs/test/stats_unittest.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_stats_impl_unittest.cc
@@ -8,18 +8,19 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "modules/video_coding/codecs/test/stats.h"
+#include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
 
 #include "test/gtest.h"
 
 namespace webrtc {
 namespace test {
+using FrameStatistics = VideoCodecTestStatsImpl::FrameStatistics;
 namespace {
 const size_t kTimestamp = 12345;
 }  // namespace
 
 TEST(StatsTest, AddFrame) {
-  Stats stats;
+  VideoCodecTestStatsImpl stats;
   FrameStatistics* frame_stat = stats.AddFrame(kTimestamp, 0);
   EXPECT_EQ(0ull, frame_stat->frame_number);
   EXPECT_EQ(kTimestamp, frame_stat->rtp_timestamp);
@@ -27,7 +28,7 @@
 }
 
 TEST(StatsTest, GetFrame) {
-  Stats stats;
+  VideoCodecTestStatsImpl stats;
   stats.AddFrame(kTimestamp, 0);
   FrameStatistics* frame_stat = stats.GetFrame(0u, 0);
   EXPECT_EQ(0u, frame_stat->frame_number);
@@ -35,7 +36,7 @@
 }
 
 TEST(StatsTest, AddFrames) {
-  Stats stats;
+  VideoCodecTestStatsImpl stats;
   const size_t kNumFrames = 1000;
   for (size_t i = 0; i < kNumFrames; ++i) {
     FrameStatistics* frame_stat = stats.AddFrame(kTimestamp + i, 0);
@@ -51,7 +52,7 @@
 }
 
 TEST(StatsTest, AddFrameLayering) {
-  Stats stats;
+  VideoCodecTestStatsImpl stats;
   for (size_t i = 0; i < 3; ++i) {
     stats.AddFrame(kTimestamp + i, i);
     FrameStatistics* frame_stat = stats.GetFrame(0u, i);
diff --git a/modules/video_coding/codecs/test/videocodec_test_videotoolbox.cc b/modules/video_coding/codecs/test/videocodec_test_videotoolbox.cc
index 6d1ec8e..787162f 100644
--- a/modules/video_coding/codecs/test/videocodec_test_videotoolbox.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_videotoolbox.cc
@@ -23,8 +23,8 @@
 namespace {
 const int kForemanNumFrames = 300;
 
-TestConfig CreateTestConfig() {
-  TestConfig config;
+VideoCodecTestFixture::Config CreateConfig() {
+  VideoCodecTestFixture::Config config;
   config.filename = "foreman_cif";
   config.filepath = ResourcePath(config.filename, "yuv");
   config.num_frames = kForemanNumFrames;
@@ -34,7 +34,7 @@
 }
 
 std::unique_ptr<VideoCodecTestFixture> CreateTestFixtureWithConfig(
-    TestConfig config) {
+    VideoCodecTestFixture::Config config) {
   auto decoder_factory = CreateObjCDecoderFactory();
   auto encoder_factory = CreateObjCEncoderFactory();
   return CreateVideoCodecTestFixture(
@@ -55,7 +55,7 @@
 MAYBE_TEST(VideoCodecTestVideoToolbox, ForemanCif500kbpsH264CBP) {
   const auto frame_checker = rtc::MakeUnique<
       VideoCodecTestFixtureImpl::H264KeyframeChecker>();
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.SetCodecSettings(cricket::kH264CodecName, 1, 1, 1, false, false, false,
                           352, 288);
   config.encoded_frame_checker = frame_checker.get();
@@ -72,7 +72,7 @@
 MAYBE_TEST(VideoCodecTestVideoToolbox, ForemanCif500kbpsH264CHP) {
   const auto frame_checker = rtc::MakeUnique<
       VideoCodecTestFixtureImpl::H264KeyframeChecker>();
-  auto config = CreateTestConfig();
+  auto config = CreateConfig();
   config.h264_codec_settings.profile = H264::kProfileConstrainedHigh;
   config.SetCodecSettings(cricket::kH264CodecName, 1, 1, 1, false, false, false,
                           352, 288);
diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc
index 50322f8..a4b8edb 100644
--- a/modules/video_coding/codecs/test/videoprocessor.cc
+++ b/modules/video_coding/codecs/test/videoprocessor.cc
@@ -32,13 +32,14 @@
 namespace webrtc {
 namespace test {
 
-namespace {
+using FrameStatistics = VideoCodecTestStats::FrameStatistics;
 
+namespace {
 const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000;
 const int kMaxBufferedInputFrames = 10;
 
 size_t GetMaxNaluSizeBytes(const EncodedImage& encoded_frame,
-                           const TestConfig& config) {
+                           const VideoCodecTestFixture::Config& config) {
   if (config.codec_settings.codecType != kVideoCodecH264)
     return 0;
 
@@ -151,13 +152,23 @@
   }
 }
 
+std::vector<FrameType> FrameTypeForFrame(
+    const VideoCodecTestFixture::Config& config,
+    size_t frame_idx) {
+  if (config.keyframe_interval > 0 &&
+      (frame_idx % config.keyframe_interval == 0)) {
+    return {kVideoFrameKey};
+  }
+  return {kVideoFrameDelta};
+}
+
 }  // namespace
 
 VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
                                VideoDecoderList* decoders,
                                FrameReader* input_frame_reader,
-                               const TestConfig& config,
-                               Stats* stats,
+                               const VideoCodecTestFixture::Config& config,
+                               VideoCodecTestStats* stats,
                                IvfFileWriterList* encoded_frame_writers,
                                FrameWriterList* decoded_frame_writers)
     : config_(config),
@@ -279,7 +290,7 @@
 
   // Encode.
   const std::vector<FrameType> frame_types =
-      config_.FrameTypeForFrame(frame_number);
+      FrameTypeForFrame(config_, frame_number);
   const int encode_return_code =
       encoder_->Encode(input_frame, nullptr, &frame_types);
   for (size_t i = 0; i < num_simulcast_or_spatial_layers_; ++i) {
diff --git a/modules/video_coding/codecs/test/videoprocessor.h b/modules/video_coding/codecs/test/videoprocessor.h
index 1799b8a..ae90e11 100644
--- a/modules/video_coding/codecs/test/videoprocessor.h
+++ b/modules/video_coding/codecs/test/videoprocessor.h
@@ -16,10 +16,11 @@
 #include <string>
 #include <vector>
 
+#include "api/test/videocodec_test_fixture.h"
+#include "api/test/videocodec_test_stats.h"
 #include "api/video/video_frame.h"
 #include "common_video/include/video_bitrate_allocator.h"
-#include "modules/video_coding/codecs/test/stats.h"
-#include "modules/video_coding/codecs/test/test_config.h"
+#include "modules/video_coding/include/video_codec_interface.h"
 #include "modules/video_coding/utility/ivf_file_writer.h"
 #include "rtc_base/buffer.h"
 #include "rtc_base/constructormagic.h"
@@ -45,8 +46,8 @@
   VideoProcessor(webrtc::VideoEncoder* encoder,
                  VideoDecoderList* decoders,
                  FrameReader* input_frame_reader,
-                 const TestConfig& config,
-                 Stats* stats,
+                 const VideoCodecTestFixture::Config& config,
+                 VideoCodecTestStats* stats,
                  IvfFileWriterList* encoded_frame_writers,
                  FrameWriterList* decoded_frame_writers);
   ~VideoProcessor();
@@ -180,9 +181,9 @@
       bool inter_layer_predicted) RTC_RUN_ON(sequence_checker_);
 
   // Test input/output.
-  TestConfig config_ RTC_GUARDED_BY(sequence_checker_);
+  VideoCodecTestFixture::Config config_ RTC_GUARDED_BY(sequence_checker_);
   const size_t num_simulcast_or_spatial_layers_;
-  Stats* const stats_;
+  VideoCodecTestStats* const stats_;
 
   // Codecs.
   webrtc::VideoEncoder* const encoder_;
diff --git a/modules/video_coding/codecs/test/videoprocessor_unittest.cc b/modules/video_coding/codecs/test/videoprocessor_unittest.cc
index 2bd4c03..8d70bf7 100644
--- a/modules/video_coding/codecs/test/videoprocessor_unittest.cc
+++ b/modules/video_coding/codecs/test/videoprocessor_unittest.cc
@@ -10,9 +10,11 @@
 
 #include <memory>
 
+#include "api/test/videocodec_test_fixture.h"
 #include "api/video/i420_buffer.h"
 #include "common_types.h"  // NOLINT(build/include)
 #include "media/base/mediaconstants.h"
+#include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
 #include "modules/video_coding/codecs/test/videoprocessor.h"
 #include "modules/video_coding/include/mock/mock_video_codec_interface.h"
 #include "modules/video_coding/include/video_coding.h"
@@ -79,13 +81,13 @@
 
   rtc::test::TaskQueueForTest q_;
 
-  TestConfig config_;
+  VideoCodecTestFixture::Config config_;
 
   MockVideoEncoder encoder_mock_;
   MockVideoDecoder* decoder_mock_;
   std::vector<std::unique_ptr<VideoDecoder>> decoders_;
   MockFrameReader frame_reader_mock_;
-  Stats stats_;
+  VideoCodecTestStatsImpl stats_;
   std::unique_ptr<VideoProcessor> video_processor_;
 };