/*
 *  Copyright (c) 2022 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 <algorithm>
#include <cstdint>
#include <iterator>
#include <limits>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "absl/flags/flag.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/test/metrics/global_metrics_logger_and_exporter.h"
#include "api/units/data_rate.h"
#include "api/units/frequency.h"
#include "api/video/resolution.h"
#include "api/video_codecs/builtin_video_decoder_factory.h"
#include "api/video_codecs/builtin_video_encoder_factory.h"
#include "api/video_codecs/scalability_mode.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "rtc_base/checks.h"
#if defined(WEBRTC_ANDROID)
#include "modules/video_coding/codecs/test/android_codec_factory_helper.h"
#endif
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
#include "test/create_test_field_trials.h"
#include "test/gtest.h"
#include "test/test_flags.h"
#include "test/testsupport/file_utils.h"
#include "test/video_codec_tester.h"

ABSL_FLAG(std::string,
          input_path,
          webrtc::test::ResourcePath("FourPeople_1280x720_30", "yuv"),
          "Path to input video file.");
ABSL_FLAG(int, input_width, 1280, "Input video width.");
ABSL_FLAG(int, input_height, 720, "Input video height.");
ABSL_FLAG(double, input_framerate_fps, 30, "Input video framerate, fps.");
ABSL_FLAG(std::string,
          encoder,
          "libaom-av1",
          "Encoder: libaom-av1, libvpx-vp9, libvpx-vp8, openh264, hw-vp8, "
          "hw-vp9, hw-av1, hw-h264, hw-h265");
ABSL_FLAG(std::string,
          decoder,
          "dav1d",
          "Decoder: dav1d, libvpx-vp9, libvpx-vp8, ffmpeg-h264, hw-vp8, "
          "hw-vp9, hw-av1, hw-h264, hw-h265");
ABSL_FLAG(std::string, scalability_mode, "L1T1", "Scalability mode.");
ABSL_FLAG(std::optional<int>, width, std::nullopt, "Encode width.");
ABSL_FLAG(std::optional<int>, height, std::nullopt, "Encode height.");
ABSL_FLAG(std::vector<std::string>,
          bitrate_kbps,
          {"1024"},
          "Encode target bitrate per layer (l0t0,l0t1,...l1t0,l1t1 and so on) "
          "in kbps.");
ABSL_FLAG(std::optional<double>,
          framerate_fps,
          std::nullopt,
          "Encode target frame rate of the top temporal layer in fps.");
ABSL_FLAG(bool, screencast, false, "Enable screen encoding mode.");
ABSL_FLAG(bool, frame_drop, true, "Enable frame dropping.");
ABSL_FLAG(int,
          key_interval,
          std::numeric_limits<int>::max(),
          "Keyframe interval in frames.");
ABSL_FLAG(int, num_frames, 300, "Number of frames to encode and/or decode.");
ABSL_FLAG(std::string, test_name, "", "Test name.");
ABSL_FLAG(bool, dump_decoder_input, false, "Dump decoder input.");
ABSL_FLAG(bool, dump_decoder_output, false, "Dump decoder output.");
ABSL_FLAG(bool, dump_encoder_input, false, "Dump encoder input.");
ABSL_FLAG(bool, dump_encoder_output, false, "Dump encoder output.");
ABSL_FLAG(bool, write_csv, false, "Write metrics to a CSV file.");

namespace webrtc {
namespace test {

namespace {
using ::testing::Combine;
using ::testing::Values;
using VideoSourceSettings = VideoCodecTester::VideoSourceSettings;
using EncodingSettings = VideoCodecTester::EncodingSettings;
using VideoCodecStats = VideoCodecTester::VideoCodecStats;
using Filter = VideoCodecStats::Filter;
using PacingMode = VideoCodecTester::PacingSettings::PacingMode;

struct VideoInfo {
  std::string name;
  Resolution resolution;
  Frequency framerate;
};

VideoInfo kFourPeople_1280x720_30 = {
    .name = "FourPeople_1280x720_30",
    .resolution = {.width = 1280, .height = 720},
    .framerate = Frequency::Hertz(30)};

constexpr Frequency k90kHz = Frequency::Hertz(90000);

VideoSourceSettings ToSourceSettings(VideoInfo video_info) {
  return VideoSourceSettings{.file_path = ResourcePath(video_info.name, "yuv"),
                             .resolution = video_info.resolution,
                             .framerate = video_info.framerate};
}

std::string CodecNameToCodecType(std::string name) {
  if (name.find("av1") != std::string::npos) {
    return "AV1";
  }
  if (name.find("vp9") != std::string::npos) {
    return "VP9";
  }
  if (name.find("vp8") != std::string::npos) {
    return "VP8";
  }
  if (name.find("h264") != std::string::npos) {
    return "H264";
  }
  if (name.find("h265") != std::string::npos) {
    return "H265";
  }
  RTC_CHECK_NOTREACHED();
}

// TODO(webrtc:14852): Make Create[Encoder,Decoder]Factory to work with codec
// name directly.
std::string CodecNameToCodecImpl(std::string name) {
  if (name.find("hw") != std::string::npos) {
    return "mediacodec";
  }
  return "builtin";
}

std::unique_ptr<VideoEncoderFactory> CreateEncoderFactory(std::string impl) {
  if (impl == "builtin") {
    return CreateBuiltinVideoEncoderFactory();
  }
#if defined(WEBRTC_ANDROID)
  InitializeAndroidObjects();
  return CreateAndroidEncoderFactory();
#else
  return nullptr;
#endif
}

std::unique_ptr<VideoDecoderFactory> CreateDecoderFactory(std::string impl) {
  if (impl == "builtin") {
    return CreateBuiltinVideoDecoderFactory();
  }
#if defined(WEBRTC_ANDROID)
  InitializeAndroidObjects();
  return CreateAndroidDecoderFactory();
#else
  return nullptr;
#endif
}

std::string TestName() {
  std::string test_name = absl::GetFlag(FLAGS_test_name);
  if (!test_name.empty()) {
    return test_name;
  }
  return ::testing::UnitTest::GetInstance()->current_test_info()->name();
}

std::string TestOutputPath() {
  std::string output_path =
      (StringBuilder() << OutputPath() << TestName()).str();
  std::string output_dir = DirName(output_path);
  bool result = CreateDir(output_dir);
  RTC_CHECK(result) << "Cannot create " << output_dir;
  return output_path;
}
}  // namespace

std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
    const Environment& env,
    std::string encoder_impl,
    std::string decoder_impl,
    const VideoSourceSettings& source_settings,
    const std::map<uint32_t, EncodingSettings>& encoding_settings) {
  const SdpVideoFormat& sdp_video_format =
      encoding_settings.begin()->second.sdp_video_format;

  std::unique_ptr<VideoEncoderFactory> encoder_factory =
      CreateEncoderFactory(encoder_impl);
  if (!encoder_factory
           ->QueryCodecSupport(sdp_video_format,
                               /*scalability_mode=*/std::nullopt)
           .is_supported) {
    RTC_LOG(LS_WARNING) << "No " << encoder_impl << " encoder for video format "
                        << sdp_video_format.ToString();
    return nullptr;
  }

  std::unique_ptr<VideoDecoderFactory> decoder_factory =
      CreateDecoderFactory(decoder_impl);
  if (!decoder_factory
           ->QueryCodecSupport(sdp_video_format,
                               /*reference_scaling=*/false)
           .is_supported) {
    RTC_LOG(LS_WARNING) << "No " << decoder_impl << " decoder for video format "
                        << sdp_video_format.ToString()
                        << ". Trying built-in decoder.";
    // TODO(ssilkin): No H264 support in ffmpeg on ARM. Consider trying HW
    // decoder.
    decoder_factory = CreateDecoderFactory("builtin");
    if (!decoder_factory
             ->QueryCodecSupport(sdp_video_format,
                                 /*reference_scaling=*/false)
             .is_supported) {
      RTC_LOG(LS_WARNING) << "No " << decoder_impl
                          << " decoder for video format "
                          << sdp_video_format.ToString();
      return nullptr;
    }
  }

  std::string output_path = TestOutputPath();

  VideoCodecTester::EncoderSettings encoder_settings;
  encoder_settings.pacing_settings.mode =
      encoder_impl == "builtin" ? PacingMode::kNoPacing : PacingMode::kRealTime;
  if (absl::GetFlag(FLAGS_dump_encoder_input)) {
    encoder_settings.encoder_input_base_path = output_path + "_enc_input";
  }
  if (absl::GetFlag(FLAGS_dump_encoder_output)) {
    encoder_settings.encoder_output_base_path = output_path + "_enc_output";
  }

  VideoCodecTester::DecoderSettings decoder_settings;
  decoder_settings.pacing_settings.mode =
      decoder_impl == "builtin" ? PacingMode::kNoPacing : PacingMode::kRealTime;
  if (absl::GetFlag(FLAGS_dump_decoder_input)) {
    decoder_settings.decoder_input_base_path = output_path + "_dec_input";
  }
  if (absl::GetFlag(FLAGS_dump_decoder_output)) {
    decoder_settings.decoder_output_base_path = output_path + "_dec_output";
  }

  return VideoCodecTester::RunEncodeDecodeTest(
      env, source_settings, encoder_factory.get(), decoder_factory.get(),
      encoder_settings, decoder_settings, encoding_settings);
}

std::unique_ptr<VideoCodecStats> RunEncodeTest(
    const Environment& env,
    std::string encoder_impl,
    const VideoSourceSettings& source_settings,
    const std::map<uint32_t, EncodingSettings>& encoding_settings) {
  const SdpVideoFormat& sdp_video_format =
      encoding_settings.begin()->second.sdp_video_format;

  std::unique_ptr<VideoEncoderFactory> encoder_factory =
      CreateEncoderFactory(encoder_impl);
  if (!encoder_factory
           ->QueryCodecSupport(sdp_video_format,
                               /*scalability_mode=*/std::nullopt)
           .is_supported) {
    RTC_LOG(LS_WARNING) << "No encoder for video format "
                        << sdp_video_format.ToString();
    return nullptr;
  }

  std::string output_path = TestOutputPath();
  VideoCodecTester::EncoderSettings encoder_settings;
  encoder_settings.pacing_settings.mode =
      encoder_impl == "builtin" ? PacingMode::kNoPacing : PacingMode::kRealTime;
  if (absl::GetFlag(FLAGS_dump_encoder_input)) {
    encoder_settings.encoder_input_base_path = output_path + "_enc_input";
  }
  if (absl::GetFlag(FLAGS_dump_encoder_output)) {
    encoder_settings.encoder_output_base_path = output_path + "_enc_output";
  }

  return VideoCodecTester::RunEncodeTest(env, source_settings,
                                         encoder_factory.get(),
                                         encoder_settings, encoding_settings);
}

class SpatialQualityTest : public ::testing::TestWithParam<std::tuple<
                               /*codec_type=*/std::string,
                               /*codec_impl=*/std::string,
                               VideoInfo,
                               std::tuple</*width=*/int,
                                          /*height=*/int,
                                          /*framerate_fps=*/double,
                                          /*bitrate_kbps=*/int,
                                          /*expected_min_psnr=*/double>>> {
 public:
  static std::string TestParamsToString(
      const ::testing::TestParamInfo<SpatialQualityTest::ParamType>& info) {
    auto [codec_type, codec_impl, video_info, coding_settings] = info.param;
    auto [width, height, framerate_fps, bitrate_kbps, psnr] = coding_settings;
    return std::string(codec_type + codec_impl + video_info.name +
                       std::to_string(width) + "x" + std::to_string(height) +
                       "p" +
                       std::to_string(static_cast<int>(1000 * framerate_fps)) +
                       "mhz" + std::to_string(bitrate_kbps) + "kbps");
  }
};

TEST_P(SpatialQualityTest, SpatialQuality) {
  const Environment env = CreateEnvironment();
  auto [codec_type, codec_impl, video_info, coding_settings] = GetParam();
  auto [width, height, framerate_fps, bitrate_kbps, expected_min_psnr] =
      coding_settings;
  int duration_s = 10;
  int num_frames = duration_s * framerate_fps;

  VideoSourceSettings source_settings = ToSourceSettings(video_info);

  EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings(
      env, codec_type, /*scalability_name=*/"L1T1", width, height,
      {DataRate::KilobitsPerSec(bitrate_kbps)},
      Frequency::Hertz(framerate_fps));

  std::map<uint32_t, EncodingSettings> frame_settings =
      VideoCodecTester::CreateFrameSettings(encoding_settings, num_frames);

  std::unique_ptr<VideoCodecStats> stats = RunEncodeDecodeTest(
      env, codec_impl, codec_impl, source_settings, frame_settings);

  VideoCodecStats::Stream stream;
  if (stats != nullptr) {
    stream = stats->Aggregate(Filter{});
    if (absl::GetFlag(FLAGS_webrtc_quick_perf_test)) {
      EXPECT_GE(stream.psnr.y.GetAverage(), expected_min_psnr);
    }
  }

  stream.LogMetrics(
      GetGlobalMetricsLogger(),
      ::testing::UnitTest::GetInstance()->current_test_info()->name(),
      /*prefix=*/"",
      /*metadata=*/
      {{"video_name", video_info.name},
       {"codec_type", codec_type},
       {"codec_impl", codec_impl}});

  if (absl::GetFlag(FLAGS_write_csv)) {
    stats->LogMetrics((StringBuilder() << TestOutputPath() << ".csv").str(),
                      stats->Slice(Filter{}, /*merge=*/false), /*metadata=*/
                      {{"test_name", TestName()}});
  }
}

INSTANTIATE_TEST_SUITE_P(
    All,
    SpatialQualityTest,
    Combine(Values("AV1", "VP9", "VP8", "H264", "H265"),
#if defined(WEBRTC_ANDROID)
            Values("builtin", "mediacodec"),
#else
            Values("builtin"),
#endif
            Values(kFourPeople_1280x720_30),
            Values(std::make_tuple(320, 180, 30, 32, 26),
                   std::make_tuple(320, 180, 30, 64, 29),
                   std::make_tuple(320, 180, 30, 128, 32),
                   std::make_tuple(320, 180, 30, 256, 36),
                   std::make_tuple(640, 360, 30, 128, 29),
                   std::make_tuple(640, 360, 30, 256, 33),
                   std::make_tuple(640, 360, 30, 384, 35),
                   std::make_tuple(640, 360, 30, 512, 36),
                   std::make_tuple(1280, 720, 30, 256, 30),
                   std::make_tuple(1280, 720, 30, 512, 34),
                   std::make_tuple(1280, 720, 30, 1024, 37),
                   std::make_tuple(1280, 720, 30, 2048, 39))),
    SpatialQualityTest::TestParamsToString);

class BitrateAdaptationTest
    : public ::testing::TestWithParam<
          std::tuple</*codec_type=*/std::string,
                     /*codec_impl=*/std::string,
                     VideoInfo,
                     std::pair</*bitrate_kbps=*/int, /*bitrate_kbps=*/int>>> {
 public:
  static std::string TestParamsToString(
      const ::testing::TestParamInfo<BitrateAdaptationTest::ParamType>& info) {
    auto [codec_type, codec_impl, video_info, bitrate_kbps] = info.param;
    return std::string(codec_type + codec_impl + video_info.name +
                       std::to_string(bitrate_kbps.first) + "kbps" +
                       std::to_string(bitrate_kbps.second) + "kbps");
  }
};

TEST_P(BitrateAdaptationTest, BitrateAdaptation) {
  auto [codec_type, codec_impl, video_info, bitrate_kbps] = GetParam();
  const Environment env = CreateEnvironment();

  int duration_s = 10;  // Duration of fixed rate interval.
  int num_frames =
      static_cast<int>(duration_s * video_info.framerate.hertz<double>());

  VideoSourceSettings source_settings = ToSourceSettings(video_info);

  EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings(
      env, codec_type, /*scalability_name=*/"L1T1",
      /*width=*/640, /*height=*/360,
      {DataRate::KilobitsPerSec(bitrate_kbps.first)},
      /*framerate=*/Frequency::Hertz(30));

  EncodingSettings encoding_settings2 =
      VideoCodecTester::CreateEncodingSettings(
          env, codec_type, /*scalability_name=*/"L1T1",
          /*width=*/640, /*height=*/360,
          {DataRate::KilobitsPerSec(bitrate_kbps.second)},
          /*framerate=*/Frequency::Hertz(30));

  std::map<uint32_t, EncodingSettings> frame_settings =
      VideoCodecTester::CreateFrameSettings(encoding_settings, num_frames);

  uint32_t timestamp_rtp =
      frame_settings.rbegin()->first + k90kHz / Frequency::Hertz(30);
  std::map<uint32_t, EncodingSettings> frame_settings2 =
      VideoCodecTester::CreateFrameSettings(encoding_settings2, num_frames,
                                            timestamp_rtp);

  frame_settings.merge(frame_settings2);

  std::unique_ptr<VideoCodecStats> stats =
      RunEncodeTest(env, codec_impl, source_settings, frame_settings);

  VideoCodecStats::Stream stream;
  if (stats != nullptr) {
    stream = stats->Aggregate({.min_timestamp_rtp = timestamp_rtp});
    if (absl::GetFlag(FLAGS_webrtc_quick_perf_test)) {
      EXPECT_NEAR(stream.bitrate_mismatch_pct.GetAverage(), 0, 10);
      EXPECT_NEAR(stream.framerate_mismatch_pct.GetAverage(), 0, 10);
    }
  }

  stream.LogMetrics(
      GetGlobalMetricsLogger(),
      ::testing::UnitTest::GetInstance()->current_test_info()->name(),
      /*prefix=*/"",
      /*metadata=*/
      {{"codec_type", codec_type},
       {"codec_impl", codec_impl},
       {"video_name", video_info.name},
       {"rate_profile", std::to_string(bitrate_kbps.first) + "," +
                            std::to_string(bitrate_kbps.second)}});

  if (absl::GetFlag(FLAGS_write_csv)) {
    stats->LogMetrics((StringBuilder() << TestOutputPath() << ".csv").str(),
                      stats->Slice(Filter{}, /*merge=*/false), /*metadata=*/
                      {{"test_name", TestName()}});
  }
}

INSTANTIATE_TEST_SUITE_P(All,
                         BitrateAdaptationTest,
                         Combine(Values("AV1", "VP9", "VP8", "H264", "H265"),
#if defined(WEBRTC_ANDROID)
                                 Values("builtin", "mediacodec"),
#else
                                 Values("builtin"),
#endif
                                 Values(kFourPeople_1280x720_30),
                                 Values(std::pair(1024, 512),
                                        std::pair(512, 1024))),
                         BitrateAdaptationTest::TestParamsToString);

class FramerateAdaptationTest
    : public ::testing::TestWithParam<std::tuple</*codec_type=*/std::string,
                                                 /*codec_impl=*/std::string,
                                                 VideoInfo,
                                                 std::pair<double, double>>> {
 public:
  static std::string TestParamsToString(
      const ::testing::TestParamInfo<FramerateAdaptationTest::ParamType>&
          info) {
    auto [codec_type, codec_impl, video_info, framerate_fps] = info.param;
    return std::string(
        codec_type + codec_impl + video_info.name +
        std::to_string(static_cast<int>(1000 * framerate_fps.first)) + "mhz" +
        std::to_string(static_cast<int>(1000 * framerate_fps.second)) + "mhz");
  }
};

TEST_P(FramerateAdaptationTest, FramerateAdaptation) {
  auto [codec_type, codec_impl, video_info, framerate_fps] = GetParam();
  const Environment env = CreateEnvironment();

  int duration_s = 10;  // Duration of fixed rate interval.

  VideoSourceSettings source_settings = ToSourceSettings(video_info);

  EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings(
      env, codec_type, /*scalability_name=*/"L1T1",
      /*width=*/640, /*height=*/360,
      /*bitrate=*/{DataRate::KilobitsPerSec(512)},
      Frequency::Hertz(framerate_fps.first));

  EncodingSettings encoding_settings2 =
      VideoCodecTester::CreateEncodingSettings(
          env, codec_type, /*scalability_name=*/"L1T1",
          /*width=*/640, /*height=*/360,
          /*bitrate=*/{DataRate::KilobitsPerSec(512)},
          Frequency::Hertz(framerate_fps.second));

  int num_frames = static_cast<int>(duration_s * framerate_fps.first);
  std::map<uint32_t, EncodingSettings> frame_settings =
      VideoCodecTester::CreateFrameSettings(encoding_settings, num_frames);

  uint32_t timestamp_rtp = frame_settings.rbegin()->first +
                           k90kHz / Frequency::Hertz(framerate_fps.first);

  num_frames = static_cast<int>(duration_s * framerate_fps.second);
  std::map<uint32_t, EncodingSettings> frame_settings2 =
      VideoCodecTester::CreateFrameSettings(encoding_settings2, num_frames,
                                            timestamp_rtp);

  frame_settings.merge(frame_settings2);

  std::unique_ptr<VideoCodecStats> stats =
      RunEncodeTest(env, codec_impl, source_settings, frame_settings);

  VideoCodecStats::Stream stream;
  if (stats != nullptr) {
    stream = stats->Aggregate({.min_timestamp_rtp = timestamp_rtp});
    if (absl::GetFlag(FLAGS_webrtc_quick_perf_test)) {
      EXPECT_NEAR(stream.bitrate_mismatch_pct.GetAverage(), 0, 10);
      EXPECT_NEAR(stream.framerate_mismatch_pct.GetAverage(), 0, 10);
    }
  }

  stream.LogMetrics(
      GetGlobalMetricsLogger(),
      ::testing::UnitTest::GetInstance()->current_test_info()->name(),
      /*prefix=*/"",
      /*metadata=*/
      {{"codec_type", codec_type},
       {"codec_impl", codec_impl},
       {"video_name", video_info.name},
       {"rate_profile", std::to_string(framerate_fps.first) + "," +
                            std::to_string(framerate_fps.second)}});

  if (absl::GetFlag(FLAGS_write_csv)) {
    stats->LogMetrics((StringBuilder() << TestOutputPath() << ".csv").str(),
                      stats->Slice(Filter{}, /*merge=*/false), /*metadata=*/
                      {{"test_name", TestName()}});
  }
}

INSTANTIATE_TEST_SUITE_P(All,
                         FramerateAdaptationTest,
                         Combine(Values("AV1", "VP9", "VP8", "H264", "H265"),
#if defined(WEBRTC_ANDROID)
                                 Values("builtin", "mediacodec"),
#else
                                 Values("builtin"),
#endif
                                 Values(kFourPeople_1280x720_30),
                                 Values(std::pair(30, 15), std::pair(15, 30))),
                         FramerateAdaptationTest::TestParamsToString);

TEST(VideoCodecTest, DISABLED_EncodeDecode) {
  const Environment env = CreateEnvironment(CreateTestFieldTrialsPtr());

  VideoSourceSettings source_settings{
      .file_path = absl::GetFlag(FLAGS_input_path),
      .resolution = {.width = absl::GetFlag(FLAGS_input_width),
                     .height = absl::GetFlag(FLAGS_input_height)},
      .framerate =
          Frequency::Hertz<double>(absl::GetFlag(FLAGS_input_framerate_fps))};

  std::vector<std::string> bitrate_str = absl::GetFlag(FLAGS_bitrate_kbps);
  std::vector<DataRate> bitrate;
  std::transform(bitrate_str.begin(), bitrate_str.end(),
                 std::back_inserter(bitrate), [](const std::string& str) {
                   return DataRate::KilobitsPerSec(std::stoi(str));
                 });

  Frequency framerate = Frequency::Hertz<double>(
      absl::GetFlag(FLAGS_framerate_fps)
          .value_or(absl::GetFlag(FLAGS_input_framerate_fps)));

  EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings(
      env, CodecNameToCodecType(absl::GetFlag(FLAGS_encoder)),
      absl::GetFlag(FLAGS_scalability_mode),
      absl::GetFlag(FLAGS_width).value_or(absl::GetFlag(FLAGS_input_width)),
      absl::GetFlag(FLAGS_height).value_or(absl::GetFlag(FLAGS_input_height)),
      {bitrate}, framerate, absl::GetFlag(FLAGS_screencast),
      absl::GetFlag(FLAGS_frame_drop));

  int num_frames = absl::GetFlag(FLAGS_num_frames);
  int key_interval = absl::GetFlag(FLAGS_key_interval);
  uint32_t timestamp_rtp = 90000;
  std::map<uint32_t, EncodingSettings> frame_settings;
  for (int frame_num = 0; frame_num < num_frames; ++frame_num) {
    encoding_settings.keyframe =
        (key_interval > 0 && (frame_num % key_interval) == 0);
    frame_settings.emplace(timestamp_rtp, encoding_settings);
    timestamp_rtp += k90kHz / framerate;
  }

  std::unique_ptr<VideoCodecStats> stats;
  std::string decoder = absl::GetFlag(FLAGS_decoder);
  if (decoder == "null") {
    stats =
        RunEncodeTest(env, CodecNameToCodecImpl(absl::GetFlag(FLAGS_encoder)),
                      source_settings, frame_settings);
  } else {
    // TODO(webrtc:14852): Pass encoder and decoder names directly, and update
    // logged test name (implies lossing history in the chromeperf dashboard).
    // Sync with changes in Stream::LogMetrics (see TODOs there).
    stats = RunEncodeDecodeTest(
        env, CodecNameToCodecImpl(absl::GetFlag(FLAGS_encoder)),
        CodecNameToCodecImpl(decoder), source_settings, frame_settings);
  }
  ASSERT_NE(nullptr, stats);

  // Log unsliced metrics.
  VideoCodecStats::Stream stream = stats->Aggregate(Filter{});
  stream.LogMetrics(GetGlobalMetricsLogger(), TestName(), /*prefix=*/"",
                    /*metadata=*/{});

  // Log metrics sliced on spatial and temporal layer.
  ScalabilityMode scalability_mode =
      *ScalabilityModeFromString(absl::GetFlag(FLAGS_scalability_mode));
  int num_spatial_layers = ScalabilityModeToNumSpatialLayers(scalability_mode);
  int num_temporal_layers =
      ScalabilityModeToNumTemporalLayers(scalability_mode);
  for (int sidx = 0; sidx < num_spatial_layers; ++sidx) {
    for (int tidx = 0; tidx < num_temporal_layers; ++tidx) {
      std::string metric_name_prefix =
          (StringBuilder() << "s" << sidx << "t" << tidx << "_").str();
      stream = stats->Aggregate(
          {.layer_id = {{.spatial_idx = sidx, .temporal_idx = tidx}}});
      stream.LogMetrics(GetGlobalMetricsLogger(), TestName(),
                        metric_name_prefix,
                        /*metadata=*/{});
    }
  }

  if (absl::GetFlag(FLAGS_write_csv)) {
    stats->LogMetrics((StringBuilder() << TestOutputPath() << ".csv").str(),
                      stats->Slice(Filter{}, /*merge=*/false), /*metadata=*/
                      {{"test_name", TestName()}});
  }
}

}  // namespace test

}  // namespace webrtc
