/*
 *  Copyright (c) 2013 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>  // max
#include <memory>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
#include "api/sequence_checker.h"
#include "api/task_queue/task_queue_base.h"
#include "api/test/metrics/global_metrics_logger_and_exporter.h"
#include "api/test/metrics/metric.h"
#include "api/test/simulated_network.h"
#include "api/units/time_delta.h"
#include "api/video/builtin_video_bitrate_allocator_factory.h"
#include "api/video/encoded_image.h"
#include "api/video/video_bitrate_allocation.h"
#include "api/video_codecs/video_encoder.h"
#include "call/call.h"
#include "call/fake_network_pipe.h"
#include "call/rtp_transport_controller_send.h"
#include "call/simulated_network.h"
#include "call/video_send_stream.h"
#include "media/engine/internal_encoder_factory.h"
#include "media/engine/simulcast_encoder_adapter.h"
#include "media/engine/webrtc_video_engine.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/create_video_rtp_depacketizer.h"
#include "modules/rtp_rtcp/source/rtcp_sender.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
#include "modules/rtp_rtcp/source/rtp_util.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h"
#include "modules/video_coding/codecs/interface/common_constants.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "modules/video_coding/svc/create_scalability_structure.h"
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "modules/video_coding/svc/scalable_video_controller.h"
#include "rtc_base/checks.h"
#include "rtc_base/event.h"
#include "rtc_base/experiments/alr_experiment.h"
#include "rtc_base/logging.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/rate_limiter.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/time_utils.h"
#include "rtc_base/unique_id_generator.h"
#include "system_wrappers/include/sleep.h"
#include "test/call_test.h"
#include "test/configurable_frame_size_encoder.h"
#include "test/fake_encoder.h"
#include "test/fake_texture_frame.h"
#include "test/frame_forwarder.h"
#include "test/frame_generator_capturer.h"
#include "test/frame_utils.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/null_transport.h"
#include "test/rtcp_packet_parser.h"
#include "test/rtp_rtcp_observer.h"
#include "test/video_encoder_proxy_factory.h"
#include "test/video_test_constants.h"
#include "video/config/encoder_stream_factory.h"
#include "video/send_statistics_proxy.h"
#include "video/transport_adapter.h"
#include "video/video_send_stream_impl.h"

namespace webrtc {
namespace test {
class VideoSendStreamPeer {
 public:
  explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
      : internal_stream_(
            static_cast<internal::VideoSendStreamImpl*>(base_class_stream)) {}
  absl::optional<float> GetPacingFactorOverride() const {
    return internal_stream_->GetPacingFactorOverride();
  }

 private:
  internal::VideoSendStreamImpl const* const internal_stream_;
};
}  // namespace test

namespace {
enum : int {  // The first valid value is 1.
  kAbsSendTimeExtensionId = 1,
  kTimestampOffsetExtensionId,
  kTransportSequenceNumberExtensionId,
  kVideoContentTypeExtensionId,
  kVideoRotationExtensionId,
  kVideoTimingExtensionId,
};

// Readability convenience enum for `WaitBitrateChanged()`.
enum class WaitUntil : bool { kZero = false, kNonZero = true };

constexpr int64_t kRtcpIntervalMs = 1000;

// Some of the test cases are expected to time out.
// Use a shorter timeout window than the default one for those.
constexpr TimeDelta kReducedTimeout = TimeDelta::Seconds(10);

enum VideoFormat {
  kGeneric,
  kVP8,
};

struct Vp9TestParams {
  std::string scalability_mode;
  uint8_t num_spatial_layers;
  uint8_t num_temporal_layers;
  InterLayerPredMode inter_layer_pred;
};

using ParameterizationType = std::tuple<Vp9TestParams, bool>;

std::string ParamInfoToStr(
    const testing::TestParamInfo<ParameterizationType>& info) {
  rtc::StringBuilder sb;
  sb << std::get<0>(info.param).scalability_mode << "_"
     << (std::get<1>(info.param) ? "WithIdentifier" : "WithoutIdentifier");
  return sb.str();
}

}  // namespace

class VideoSendStreamTest : public test::CallTest {
 public:
  VideoSendStreamTest() {
    RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
                                      kTransportSequenceNumberExtensionId));
  }

 protected:
  void TestNackRetransmission(uint32_t retransmit_ssrc,
                              uint8_t retransmit_payload_type);
  void TestPacketFragmentationSize(VideoFormat format, bool with_fec);

  void TestVp9NonFlexMode(const Vp9TestParams& params,
                          bool use_scalability_mode_identifier);

  void TestRequestSourceRotateVideo(bool support_orientation_ext);

  void TestTemporalLayers(VideoEncoderFactory* encoder_factory,
                          const std::string& payload_name,
                          const std::vector<int>& num_temporal_layers,
                          const std::vector<ScalabilityMode>& scalability_mode);
};

TEST_F(VideoSendStreamTest, CanStartStartedStream) {
  SendTask(task_queue(), [this]() {
    CreateSenderCall();

    test::NullTransport transport;
    CreateSendConfig(1, 0, 0, &transport);
    CreateVideoStreams();
    GetVideoSendStream()->Start();
    GetVideoSendStream()->Start();
    DestroyStreams();
    DestroyCalls();
  });
}

TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
  SendTask(task_queue(), [this]() {
    CreateSenderCall();

    test::NullTransport transport;
    CreateSendConfig(1, 0, 0, &transport);
    CreateVideoStreams();
    GetVideoSendStream()->Stop();
    GetVideoSendStream()->Stop();
    DestroyStreams();
    DestroyCalls();
  });
}

TEST_F(VideoSendStreamTest, SupportsCName) {
  static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
  class CNameObserver : public test::SendTest {
   public:
    CNameObserver() : SendTest(test::VideoTestConstants::kDefaultTimeout) {}

   private:
    Action OnSendRtcp(rtc::ArrayView<const uint8_t> packet) override {
      test::RtcpPacketParser parser;
      EXPECT_TRUE(parser.Parse(packet));
      if (parser.sdes()->num_packets() > 0) {
        EXPECT_EQ(1u, parser.sdes()->chunks().size());
        EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);

        observation_complete_.Set();
      }

      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->rtp.c_name = kCName;
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
    }
  } test;

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
  class AbsoluteSendTimeObserver : public test::SendTest {
   public:
    AbsoluteSendTimeObserver()
        : SendTest(test::VideoTestConstants::kDefaultTimeout) {
      extensions_.Register<AbsoluteSendTime>(kAbsSendTimeExtensionId);
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      RtpPacket rtp_packet(&extensions_);
      EXPECT_TRUE(rtp_packet.Parse(packet));

      uint32_t abs_send_time = 0;
      EXPECT_FALSE(rtp_packet.HasExtension<TransmissionOffset>());
      EXPECT_TRUE(rtp_packet.GetExtension<AbsoluteSendTime>(&abs_send_time));
      if (abs_send_time != 0) {
        // Wait for at least one packet with a non-zero send time. The send time
        // is a 16-bit value derived from the system clock, and it is valid
        // for a packet to have a zero send time. To tell that from an
        // unpopulated value we'll wait for a packet with non-zero send time.
        observation_complete_.Set();
      } else {
        RTC_LOG(LS_WARNING)
            << "Got a packet with zero absoluteSendTime, waiting"
               " for another packet...";
      }

      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->rtp.extensions.clear();
      send_config->rtp.extensions.push_back(
          RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
    }

   private:
    RtpHeaderExtensionMap extensions_;
  } test;

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
  static const int kEncodeDelayMs = 5;
  class TransmissionTimeOffsetObserver : public test::SendTest {
   public:
    TransmissionTimeOffsetObserver()
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          encoder_factory_([](const Environment& env,
                              const SdpVideoFormat& format) {
            return std::make_unique<test::DelayedEncoder>(env, kEncodeDelayMs);
          }) {
      extensions_.Register<TransmissionOffset>(kTimestampOffsetExtensionId);
    }

   private:
    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      RtpPacket rtp_packet(&extensions_);
      EXPECT_TRUE(rtp_packet.Parse(packet));

      int32_t toffset = 0;
      EXPECT_TRUE(rtp_packet.GetExtension<TransmissionOffset>(&toffset));
      EXPECT_FALSE(rtp_packet.HasExtension<AbsoluteSendTime>());
      EXPECT_GT(toffset, 0);
      observation_complete_.Set();

      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->encoder_settings.encoder_factory = &encoder_factory_;
      send_config->rtp.extensions.clear();
      send_config->rtp.extensions.push_back(RtpExtension(
          RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
    }

    test::FunctionVideoEncoderFactory encoder_factory_;
    RtpHeaderExtensionMap extensions_;
  } test;

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
  static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
  class TransportWideSequenceNumberObserver : public test::SendTest {
   public:
    TransportWideSequenceNumberObserver()
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          encoder_factory_(
              [](const Environment& env, const SdpVideoFormat& format) {
                return std::make_unique<test::FakeEncoder>(env);
              }) {
      extensions_.Register<TransportSequenceNumber>(kExtensionId);
    }

   private:
    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      RtpPacket rtp_packet(&extensions_);
      EXPECT_TRUE(rtp_packet.Parse(packet));

      EXPECT_TRUE(rtp_packet.HasExtension<TransportSequenceNumber>());
      EXPECT_FALSE(rtp_packet.HasExtension<TransmissionOffset>());
      EXPECT_FALSE(rtp_packet.HasExtension<AbsoluteSendTime>());

      observation_complete_.Set();

      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->encoder_settings.encoder_factory = &encoder_factory_;
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
    }

    test::FunctionVideoEncoderFactory encoder_factory_;
    RtpHeaderExtensionMap extensions_;
  } test;

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
  class VideoRotationObserver : public test::SendTest {
   public:
    VideoRotationObserver()
        : SendTest(test::VideoTestConstants::kDefaultTimeout) {
      extensions_.Register<VideoOrientation>(kVideoRotationExtensionId);
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      RtpPacket rtp_packet(&extensions_);
      EXPECT_TRUE(rtp_packet.Parse(packet));
      // Only the last packet of the frame is required to have the extension.
      if (!rtp_packet.Marker())
        return SEND_PACKET;
      EXPECT_EQ(rtp_packet.GetExtension<VideoOrientation>(), kVideoRotation_90);
      observation_complete_.Set();
      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->rtp.extensions.clear();
      send_config->rtp.extensions.push_back(RtpExtension(
          RtpExtension::kVideoRotationUri, kVideoRotationExtensionId));
    }

    void OnFrameGeneratorCapturerCreated(
        test::FrameGeneratorCapturer* frame_generator_capturer) override {
      frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
    }

   private:
    RtpHeaderExtensionMap extensions_;
  } test;

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
  class VideoContentTypeObserver : public test::SendTest {
   public:
    VideoContentTypeObserver()
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          first_frame_sent_(false) {
      extensions_.Register<VideoContentTypeExtension>(
          kVideoContentTypeExtensionId);
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      RtpPacket rtp_packet(&extensions_);
      EXPECT_TRUE(rtp_packet.Parse(packet));
      // Only the last packet of the key-frame must have extension.
      if (!rtp_packet.Marker() || first_frame_sent_)
        return SEND_PACKET;
      // First marker bit seen means that the first frame is sent.
      first_frame_sent_ = true;
      VideoContentType type;
      EXPECT_TRUE(rtp_packet.GetExtension<VideoContentTypeExtension>(&type));
      EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(type));
      observation_complete_.Set();
      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->rtp.extensions.clear();
      send_config->rtp.extensions.push_back(RtpExtension(
          RtpExtension::kVideoContentTypeUri, kVideoContentTypeExtensionId));
      encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
    }

   private:
    bool first_frame_sent_;
    RtpHeaderExtensionMap extensions_;
  } test;

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
  class VideoTimingObserver : public test::SendTest {
   public:
    VideoTimingObserver()
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          first_frame_sent_(false) {
      extensions_.Register<VideoTimingExtension>(kVideoTimingExtensionId);
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      RtpPacket rtp_packet(&extensions_);
      EXPECT_TRUE(rtp_packet.Parse(packet));
      // Only the last packet of the frame must have extension.
      // Also don't check packets of the second frame if they happen to get
      // through before the test terminates.
      if (!rtp_packet.Marker() || first_frame_sent_)
        return SEND_PACKET;
      EXPECT_TRUE(rtp_packet.HasExtension<VideoTimingExtension>());
      observation_complete_.Set();
      first_frame_sent_ = true;
      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->rtp.extensions.clear();
      send_config->rtp.extensions.push_back(
          RtpExtension(RtpExtension::kVideoTimingUri, kVideoTimingExtensionId));
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
    }

   private:
    RtpHeaderExtensionMap extensions_;
    bool first_frame_sent_;
  } test;

  RunBaseTest(&test);
}

class FakeReceiveStatistics : public ReceiveStatisticsProvider {
 public:
  FakeReceiveStatistics(uint32_t send_ssrc,
                        uint32_t last_sequence_number,
                        uint32_t cumulative_lost,
                        uint8_t fraction_lost) {
    stat_.SetMediaSsrc(send_ssrc);
    stat_.SetExtHighestSeqNum(last_sequence_number);
    stat_.SetCumulativeLost(cumulative_lost);
    stat_.SetFractionLost(fraction_lost);
  }

  std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
    EXPECT_GE(max_blocks, 1u);
    return {stat_};
  }

 private:
  rtcp::ReportBlock stat_;
};

class UlpfecObserver : public test::EndToEndTest {
 public:
  UlpfecObserver(
      bool header_extensions_enabled,
      bool use_nack,
      bool expect_red,
      bool expect_ulpfec,
      const std::string& codec,
      VideoEncoderFactory* encoder_factory,
      const TimeDelta& timeout = test::VideoTestConstants::kDefaultTimeout)
      : EndToEndTest(timeout),
        encoder_factory_(encoder_factory),
        payload_name_(codec),
        use_nack_(use_nack),
        expect_red_(expect_red),
        expect_ulpfec_(expect_ulpfec),
        sent_media_(false),
        sent_ulpfec_(false),
        header_extensions_enabled_(header_extensions_enabled) {
    extensions_.Register<AbsoluteSendTime>(kAbsSendTimeExtensionId);
    extensions_.Register<TransportSequenceNumber>(
        kTransportSequenceNumberExtensionId);
  }

 private:
  Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
    RtpPacket rtp_packet(&extensions_);
    EXPECT_TRUE(rtp_packet.Parse(packet));

    int encapsulated_payload_type = -1;
    if (rtp_packet.PayloadType() == test::VideoTestConstants::kRedPayloadType) {
      EXPECT_TRUE(expect_red_);
      encapsulated_payload_type = rtp_packet.payload()[0];
      if (encapsulated_payload_type !=
          test::VideoTestConstants::kFakeVideoSendPayloadType) {
        EXPECT_EQ(test::VideoTestConstants::kUlpfecPayloadType,
                  encapsulated_payload_type);
      }
    } else {
      EXPECT_EQ(test::VideoTestConstants::kFakeVideoSendPayloadType,
                rtp_packet.PayloadType());
      if (rtp_packet.payload_size() > 0) {
        // Not padding-only, media received outside of RED.
        EXPECT_FALSE(expect_red_);
        sent_media_ = true;
      }
    }

    if (header_extensions_enabled_) {
      uint32_t abs_send_time;
      EXPECT_TRUE(rtp_packet.GetExtension<AbsoluteSendTime>(&abs_send_time));
      uint16_t transport_seq_num;
      EXPECT_TRUE(
          rtp_packet.GetExtension<TransportSequenceNumber>(&transport_seq_num));
      if (!first_packet_) {
        uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
        if (abs_send_time <= kHalf24BitsSpace &&
            prev_abs_send_time_ > kHalf24BitsSpace) {
          // 24 bits wrap.
          EXPECT_GT(prev_abs_send_time_, abs_send_time);
        } else {
          EXPECT_GE(abs_send_time, prev_abs_send_time_);
        }

        uint16_t seq_num_diff = transport_seq_num - prev_transport_seq_num_;
        EXPECT_EQ(1, seq_num_diff);
      }
      first_packet_ = false;
      prev_abs_send_time_ = abs_send_time;
      prev_transport_seq_num_ = transport_seq_num;
    }

    if (encapsulated_payload_type != -1) {
      if (encapsulated_payload_type ==
          test::VideoTestConstants::kUlpfecPayloadType) {
        EXPECT_TRUE(expect_ulpfec_);
        sent_ulpfec_ = true;
      } else {
        sent_media_ = true;
      }
    }

    if (sent_media_ && sent_ulpfec_) {
      observation_complete_.Set();
    }

    return SEND_PACKET;
  }

  BuiltInNetworkBehaviorConfig GetSendTransportConfig() const override {
    // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
    // Configure some network delay.
    const int kNetworkDelayMs = 100;
    BuiltInNetworkBehaviorConfig config;
    config.loss_percent = 5;
    config.queue_delay_ms = kNetworkDelayMs;
    return config;
  }

  void ModifyVideoConfigs(
      VideoSendStream::Config* send_config,
      std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
      VideoEncoderConfig* encoder_config) override {
    if (use_nack_) {
      send_config->rtp.nack.rtp_history_ms =
          (*receive_configs)[0].rtp.nack.rtp_history_ms =
              test::VideoTestConstants::kNackRtpHistoryMs;
    }
    send_config->encoder_settings.encoder_factory = encoder_factory_;
    send_config->rtp.payload_name = payload_name_;
    send_config->rtp.ulpfec.red_payload_type =
        test::VideoTestConstants::kRedPayloadType;
    send_config->rtp.ulpfec.ulpfec_payload_type =
        test::VideoTestConstants::kUlpfecPayloadType;
    if (!header_extensions_enabled_) {
      send_config->rtp.extensions.clear();
    } else {
      send_config->rtp.extensions.push_back(
          RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
    }
    encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
    (*receive_configs)[0].rtp.red_payload_type =
        send_config->rtp.ulpfec.red_payload_type;
    (*receive_configs)[0].rtp.ulpfec_payload_type =
        send_config->rtp.ulpfec.ulpfec_payload_type;
  }

  void PerformTest() override {
    EXPECT_EQ(expect_ulpfec_, Wait())
        << "Timed out waiting for ULPFEC and/or media packets.";
  }

  VideoEncoderFactory* encoder_factory_;
  RtpHeaderExtensionMap extensions_;
  const std::string payload_name_;
  const bool use_nack_;
  const bool expect_red_;
  const bool expect_ulpfec_;
  bool sent_media_;
  bool sent_ulpfec_;
  const bool header_extensions_enabled_;
  bool first_packet_ = true;
  uint32_t prev_abs_send_time_ = 0;
  uint16_t prev_transport_seq_num_ = 0;
};

TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });
  UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });
  UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
  RunBaseTest(&test);
}

class VideoSendStreamWithoutUlpfecTest : public test::CallTest {
 protected:
  VideoSendStreamWithoutUlpfecTest()
      : field_trial_(field_trials_, "WebRTC-DisableUlpFecExperiment/Enabled/") {
  }

  test::ScopedKeyValueConfig field_trial_;
};

TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });
  UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory,
                      kReducedTimeout);
  RunBaseTest(&test);
}

// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
// since we'll still have to re-request FEC packets, effectively wasting
// bandwidth since the receiver has to wait for FEC retransmissions to determine
// that the received state is actually decodable.
TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return std::make_unique<test::FakeH264Encoder>(env);
      });
  UlpfecObserver test(false, true, false, false, "H264", &encoder_factory,
                      kReducedTimeout);
  RunBaseTest(&test);
}

// Without retransmissions FEC for H264 is fine.
TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return std::make_unique<test::FakeH264Encoder>(env);
      });
  UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp8WithNackEnabled) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });
  UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
  RunBaseTest(&test);
}

#if defined(RTC_ENABLE_VP9)
TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp9WithNackEnabled) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp9Encoder(env);
      });
  // Use kLongTimeout timeout because the test is flaky with kDefaultTimeout.
  UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory,
                      test::VideoTestConstants::kLongTimeout);
  RunBaseTest(&test);
}
#endif  // defined(RTC_ENABLE_VP9)

TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [&](const Environment& env, const SdpVideoFormat& format) {
        return std::make_unique<test::MultithreadedFakeH264Encoder>(env);
      });
  UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
  RunBaseTest(&test);
}

// TODO(brandtr): Move these FlexFEC tests when we have created
// FlexfecSendStream.
class FlexfecObserver : public test::EndToEndTest {
 public:
  FlexfecObserver(bool header_extensions_enabled,
                  bool use_nack,
                  const std::string& codec,
                  VideoEncoderFactory* encoder_factory,
                  size_t num_video_streams)
      : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
        encoder_factory_(encoder_factory),
        payload_name_(codec),
        use_nack_(use_nack),
        sent_media_(false),
        sent_flexfec_(false),
        header_extensions_enabled_(header_extensions_enabled),
        num_video_streams_(num_video_streams) {
    extensions_.Register<AbsoluteSendTime>(kAbsSendTimeExtensionId);
    extensions_.Register<TransmissionOffset>(kTimestampOffsetExtensionId);
    extensions_.Register<TransportSequenceNumber>(
        kTransportSequenceNumberExtensionId);
  }

  size_t GetNumFlexfecStreams() const override { return 1; }
  size_t GetNumVideoStreams() const override { return num_video_streams_; }

 private:
  Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
    RtpPacket rtp_packet(&extensions_);
    EXPECT_TRUE(rtp_packet.Parse(packet));

    if (rtp_packet.PayloadType() ==
        test::VideoTestConstants::kFlexfecPayloadType) {
      EXPECT_EQ(test::VideoTestConstants::kFlexfecSendSsrc, rtp_packet.Ssrc());
      sent_flexfec_ = true;
    } else {
      EXPECT_EQ(test::VideoTestConstants::kFakeVideoSendPayloadType,
                rtp_packet.PayloadType());
      EXPECT_THAT(
          ::testing::make_tuple(test::VideoTestConstants::kVideoSendSsrcs,
                                num_video_streams_),
          ::testing::Contains(rtp_packet.Ssrc()));
      sent_media_ = true;
    }

    if (header_extensions_enabled_) {
      EXPECT_TRUE(rtp_packet.HasExtension<AbsoluteSendTime>());
      EXPECT_TRUE(rtp_packet.HasExtension<TransmissionOffset>());
      EXPECT_TRUE(rtp_packet.HasExtension<TransportSequenceNumber>());
    }

    if (sent_media_ && sent_flexfec_) {
      observation_complete_.Set();
    }

    return SEND_PACKET;
  }

  BuiltInNetworkBehaviorConfig GetSendTransportConfig() const {
    // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
    // Therefore we need some network delay.
    const int kNetworkDelayMs = 100;
    BuiltInNetworkBehaviorConfig config;
    config.loss_percent = 5;
    config.queue_delay_ms = kNetworkDelayMs;
    return config;
  }

  BuiltInNetworkBehaviorConfig GetReceiveTransportConfig() const {
    // We need the RTT to be >200 ms to send FEC and the network delay for the
    // send transport is 100 ms, so add 100 ms (but no loss) on the return link.
    BuiltInNetworkBehaviorConfig config;
    config.loss_percent = 0;
    config.queue_delay_ms = 100;
    return config;
  }

  void ModifyVideoConfigs(
      VideoSendStream::Config* send_config,
      std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
      VideoEncoderConfig* encoder_config) override {
    if (use_nack_) {
      send_config->rtp.nack.rtp_history_ms =
          (*receive_configs)[0].rtp.nack.rtp_history_ms =
              test::VideoTestConstants::kNackRtpHistoryMs;
    }
    send_config->encoder_settings.encoder_factory = encoder_factory_;
    send_config->rtp.payload_name = payload_name_;
    if (header_extensions_enabled_) {
      send_config->rtp.extensions.push_back(
          RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
      send_config->rtp.extensions.push_back(RtpExtension(
          RtpExtension::kTimestampOffsetUri, kTimestampOffsetExtensionId));
    } else {
      send_config->rtp.extensions.clear();
    }
    encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
  }

  void PerformTest() override {
    EXPECT_TRUE(Wait())
        << "Timed out waiting for FlexFEC and/or media packets.";
  }

  VideoEncoderFactory* encoder_factory_;
  RtpHeaderExtensionMap extensions_;
  const std::string payload_name_;
  const bool use_nack_;
  bool sent_media_;
  bool sent_flexfec_;
  const bool header_extensions_enabled_;
  const size_t num_video_streams_;
};

TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });
  FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });
  FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });
  FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });
  FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
  RunBaseTest(&test);
}

#if defined(RTC_ENABLE_VP9)
TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp9Encoder(env);
      });
  FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp9Encoder(env);
      });
  FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
  RunBaseTest(&test);
}
#endif  // defined(RTC_ENABLE_VP9)

TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return std::make_unique<test::FakeH264Encoder>(env);
      });
  FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return std::make_unique<test::FakeH264Encoder>(env);
      });
  FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [&](const Environment& env, const SdpVideoFormat& format) {
        return std::make_unique<test::MultithreadedFakeH264Encoder>(env);
      });

  FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
  RunBaseTest(&test);
}

void VideoSendStreamTest::TestNackRetransmission(
    uint32_t retransmit_ssrc,
    uint8_t retransmit_payload_type) {
  class NackObserver : public test::SendTest {
   public:
    explicit NackObserver(uint32_t retransmit_ssrc,
                          uint8_t retransmit_payload_type)
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          send_count_(0),
          retransmit_count_(0),
          retransmit_ssrc_(retransmit_ssrc),
          retransmit_payload_type_(retransmit_payload_type) {}

   private:
    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      RtpPacket rtp_packet;
      EXPECT_TRUE(rtp_packet.Parse(packet));

      // NACK packets two times at some arbitrary points.
      const int kNackedPacketsAtOnceCount = 3;
      const int kRetransmitTarget = kNackedPacketsAtOnceCount * 2;

      // Skip padding packets because they will never be retransmitted.
      if (rtp_packet.payload_size() == 0) {
        return SEND_PACKET;
      }

      ++send_count_;

      // NACK packets at arbitrary points.
      if (send_count_ % 25 == 0) {
        RTCPSender::Configuration config;
        config.clock = Clock::GetRealTimeClock();
        config.outgoing_transport = transport_adapter_.get();
        config.rtcp_report_interval = TimeDelta::Millis(kRtcpIntervalMs);
        config.local_media_ssrc =
            test::VideoTestConstants::kReceiverLocalVideoSsrc;
        RTCPSender rtcp_sender(config);

        rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
        rtcp_sender.SetRemoteSSRC(test::VideoTestConstants::kVideoSendSsrcs[0]);

        RTCPSender::FeedbackState feedback_state;
        uint16_t nack_sequence_numbers[kNackedPacketsAtOnceCount];
        int nack_count = 0;
        for (uint16_t sequence_number :
             sequence_numbers_pending_retransmission_) {
          if (nack_count < kNackedPacketsAtOnceCount) {
            nack_sequence_numbers[nack_count++] = sequence_number;
          } else {
            break;
          }
        }

        EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpNack, nack_count,
                                          nack_sequence_numbers));
      }

      uint16_t sequence_number = rtp_packet.SequenceNumber();
      if (rtp_packet.Ssrc() == retransmit_ssrc_ &&
          retransmit_ssrc_ != test::VideoTestConstants::kVideoSendSsrcs[0]) {
        // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
        // number.
        const uint8_t* rtx_header = rtp_packet.payload().data();
        sequence_number = (rtx_header[0] << 8) + rtx_header[1];
      }

      auto it = sequence_numbers_pending_retransmission_.find(sequence_number);
      if (it == sequence_numbers_pending_retransmission_.end()) {
        // Not currently pending retransmission. Add it to retransmission queue
        // if media and limit not reached.
        if (rtp_packet.Ssrc() == test::VideoTestConstants::kVideoSendSsrcs[0] &&
            rtp_packet.payload_size() > 0 &&
            retransmit_count_ +
                    sequence_numbers_pending_retransmission_.size() <
                kRetransmitTarget) {
          sequence_numbers_pending_retransmission_.insert(sequence_number);
          return DROP_PACKET;
        }
      } else {
        // Packet is a retransmission, remove it from queue and check if done.
        sequence_numbers_pending_retransmission_.erase(it);
        if (++retransmit_count_ == kRetransmitTarget) {
          EXPECT_EQ(retransmit_ssrc_, rtp_packet.Ssrc());
          EXPECT_EQ(retransmit_payload_type_, rtp_packet.PayloadType());
          observation_complete_.Set();
        }
      }

      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      transport_adapter_.reset(
          new internal::TransportAdapter(send_config->send_transport));
      transport_adapter_->Enable();
      send_config->rtp.nack.rtp_history_ms =
          test::VideoTestConstants::kNackRtpHistoryMs;
      send_config->rtp.rtx.payload_type = retransmit_payload_type_;
      if (retransmit_ssrc_ != test::VideoTestConstants::kVideoSendSsrcs[0])
        send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
    }

    std::unique_ptr<internal::TransportAdapter> transport_adapter_;
    int send_count_;
    int retransmit_count_;
    const uint32_t retransmit_ssrc_;
    const uint8_t retransmit_payload_type_;
    std::set<uint16_t> sequence_numbers_pending_retransmission_;
  } test(retransmit_ssrc, retransmit_payload_type);

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, RetransmitsNack) {
  // Normal NACKs should use the send SSRC.
  TestNackRetransmission(test::VideoTestConstants::kVideoSendSsrcs[0],
                         test::VideoTestConstants::kFakeVideoSendPayloadType);
}

TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
  // NACKs over RTX should use a separate SSRC.
  TestNackRetransmission(test::VideoTestConstants::kSendRtxSsrcs[0],
                         test::VideoTestConstants::kSendRtxPayloadType);
}

void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
                                                      bool with_fec) {
  // Use a fake encoder to output a frame of every size in the range [90, 290],
  // for each size making sure that the exact number of payload bytes received
  // is correct and that packets are fragmented to respect max packet size.
  static const size_t kMaxPacketSize = 128;
  static const size_t start = 90;
  static const size_t stop = 290;

  // Observer that verifies that the expected number of packets and bytes
  // arrive for each frame size, from start_size to stop_size.
  class FrameFragmentationTest : public test::SendTest {
   public:
    FrameFragmentationTest(size_t max_packet_size,
                           size_t start_size,
                           size_t stop_size,
                           bool test_generic_packetization,
                           bool use_fec)
        : SendTest(test::VideoTestConstants::kLongTimeout),
          encoder_(stop),
          encoder_factory_(&encoder_),
          max_packet_size_(max_packet_size),
          stop_size_(stop_size),
          test_generic_packetization_(test_generic_packetization),
          use_fec_(use_fec),
          packet_count_(0),
          packets_lost_(0),
          last_packet_count_(0),
          last_packets_lost_(0),
          accumulated_size_(0),
          accumulated_payload_(0),
          fec_packet_received_(false),
          current_size_rtp_(start_size),
          current_size_frame_(static_cast<int>(start_size)) {
      // Fragmentation required, this test doesn't make sense without it.
      encoder_.SetFrameSize(start_size);
      RTC_DCHECK_GT(stop_size, max_packet_size);
      if (!test_generic_packetization_)
        encoder_.SetCodecType(kVideoCodecVP8);
    }

   private:
    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      size_t length = packet.size();
      RtpPacket rtp_packet;
      EXPECT_TRUE(rtp_packet.Parse(packet));

      EXPECT_LE(length, max_packet_size_);

      if (use_fec_ && rtp_packet.payload_size() > 0) {
        uint8_t payload_type = rtp_packet.payload()[0];
        bool is_fec =
            rtp_packet.PayloadType() ==
                test::VideoTestConstants::kRedPayloadType &&
            payload_type == test::VideoTestConstants::kUlpfecPayloadType;
        if (is_fec) {
          fec_packet_received_ = true;
          return SEND_PACKET;
        }
      }

      accumulated_size_ += length;

      if (use_fec_)
        TriggerLossReport(rtp_packet);

      if (test_generic_packetization_) {
        size_t overhead = rtp_packet.headers_size() + rtp_packet.padding_size();
        // Only remove payload header and RED header if the packet actually
        // contains payload.
        if (length > overhead) {
          overhead += (1 /* Generic header */);
          if (use_fec_)
            overhead += 1;  // RED for FEC header.
        }
        EXPECT_GE(length, overhead);
        accumulated_payload_ += length - overhead;
      }

      // Marker bit set indicates last packet of a frame.
      if (rtp_packet.Marker()) {
        if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
          // With FEC enabled, frame size is incremented asynchronously, so
          // "old" frames one byte too small may arrive. Accept, but don't
          // increase expected frame size.
          accumulated_size_ = 0;
          accumulated_payload_ = 0;
          return SEND_PACKET;
        }

        EXPECT_GE(accumulated_size_, current_size_rtp_);
        if (test_generic_packetization_) {
          EXPECT_EQ(current_size_rtp_, accumulated_payload_);
        }

        // Last packet of frame; reset counters.
        accumulated_size_ = 0;
        accumulated_payload_ = 0;
        if (current_size_rtp_ == stop_size_) {
          // Done! (Don't increase size again, might arrive more @ stop_size).
          observation_complete_.Set();
        } else {
          // Increase next expected frame size. If testing with FEC, make sure
          // a FEC packet has been received for this frame size before
          // proceeding, to make sure that redundancy packets don't exceed
          // size limit.
          if (!use_fec_) {
            ++current_size_rtp_;
          } else if (fec_packet_received_) {
            fec_packet_received_ = false;
            ++current_size_rtp_;

            MutexLock lock(&mutex_);
            ++current_size_frame_;
          }
        }
      }

      return SEND_PACKET;
    }

    void TriggerLossReport(const RtpPacket& rtp_packet) {
      // Send lossy receive reports to trigger FEC enabling.
      const int kLossPercent = 5;
      if (++packet_count_ % (100 / kLossPercent) == 0) {
        packets_lost_++;
        int loss_delta = packets_lost_ - last_packets_lost_;
        int packets_delta = packet_count_ - last_packet_count_;
        last_packet_count_ = packet_count_;
        last_packets_lost_ = packets_lost_;
        uint8_t loss_ratio =
            static_cast<uint8_t>(loss_delta * 255 / packets_delta);
        FakeReceiveStatistics lossy_receive_stats(
            test::VideoTestConstants::kVideoSendSsrcs[0],
            rtp_packet.SequenceNumber(),
            packets_lost_,  // Cumulative lost.
            loss_ratio);    // Loss percent.
        RTCPSender::Configuration config;
        config.clock = Clock::GetRealTimeClock();
        config.receive_statistics = &lossy_receive_stats;
        config.outgoing_transport = transport_adapter_.get();
        config.rtcp_report_interval = TimeDelta::Millis(kRtcpIntervalMs);
        config.local_media_ssrc = test::VideoTestConstants::kVideoSendSsrcs[0];
        RTCPSender rtcp_sender(config);

        rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
        rtcp_sender.SetRemoteSSRC(test::VideoTestConstants::kVideoSendSsrcs[0]);

        RTCPSender::FeedbackState feedback_state;

        EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
      }
    }

    void UpdateConfiguration() {
      MutexLock lock(&mutex_);
      // Increase frame size for next encoded frame, in the context of the
      // encoder thread.
      if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
        ++current_size_frame_;
      }
      encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
    }
    void ModifySenderBitrateConfig(
        BitrateConstraints* bitrate_config) override {
      const int kMinBitrateBps = 300000;
      bitrate_config->min_bitrate_bps = kMinBitrateBps;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      transport_adapter_.reset(
          new internal::TransportAdapter(send_config->send_transport));
      transport_adapter_->Enable();
      if (use_fec_) {
        send_config->rtp.ulpfec.red_payload_type =
            test::VideoTestConstants::kRedPayloadType;
        send_config->rtp.ulpfec.ulpfec_payload_type =
            test::VideoTestConstants::kUlpfecPayloadType;
      }

      if (!test_generic_packetization_)
        send_config->rtp.payload_name = "VP8";

      send_config->encoder_settings.encoder_factory = &encoder_factory_;
      send_config->rtp.max_packet_size = kMaxPacketSize;
      encoder_.RegisterPostEncodeCallback([this]() { UpdateConfiguration(); });

      // Make sure there is at least one extension header, to make the RTP
      // header larger than the base length of 12 bytes.
      EXPECT_FALSE(send_config->rtp.extensions.empty());

      // Setup screen content disables frame dropping which makes this easier.
      EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
      encoder_config->simulcast_layers[0].num_temporal_layers = 2;
      encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
    }

    std::unique_ptr<internal::TransportAdapter> transport_adapter_;
    test::ConfigurableFrameSizeEncoder encoder_;
    test::VideoEncoderProxyFactory encoder_factory_;

    const size_t max_packet_size_;
    const size_t stop_size_;
    const bool test_generic_packetization_;
    const bool use_fec_;

    uint32_t packet_count_;
    uint32_t packets_lost_;
    uint32_t last_packet_count_;
    uint32_t last_packets_lost_;
    size_t accumulated_size_;
    size_t accumulated_payload_;
    bool fec_packet_received_;

    size_t current_size_rtp_;
    Mutex mutex_;
    int current_size_frame_ RTC_GUARDED_BY(mutex_);
  };

  // Don't auto increment if FEC is used; continue sending frame size until
  // a FEC packet has been received.
  FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
                              with_fec);

  RunBaseTest(&test);
}

// TODO(sprang): Is there any way of speeding up these tests?
TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
  TestPacketFragmentationSize(kGeneric, false);
}

TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
  TestPacketFragmentationSize(kGeneric, true);
}

TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
  TestPacketFragmentationSize(kVP8, false);
}

TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
  TestPacketFragmentationSize(kVP8, true);
}

// This test that padding stops being send after a while if the Camera stops
// producing video frames and that padding resumes if the camera restarts.
TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
  class NoPaddingWhenVideoIsMuted : public test::SendTest {
   public:
    NoPaddingWhenVideoIsMuted()
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          clock_(Clock::GetRealTimeClock()),
          capturer_(nullptr) {}

   private:
    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      MutexLock lock(&mutex_);
      last_packet_time_ms_ = clock_->TimeInMilliseconds();

      RtpPacket rtp_packet;
      rtp_packet.Parse(packet);
      const bool only_padding = rtp_packet.payload_size() == 0;

      if (test_state_ == kBeforeStopCapture) {
        // Packets are flowing, stop camera.
        capturer_->Stop();
        test_state_ = kWaitingForPadding;
      } else if (test_state_ == kWaitingForPadding && only_padding) {
        // We're still getting padding, after stopping camera.
        test_state_ = kWaitingForNoPackets;
      } else if (test_state_ == kWaitingForMediaAfterCameraRestart &&
                 !only_padding) {
        // Media packets are flowing again, stop camera a second time.
        capturer_->Stop();
        test_state_ = kWaitingForPaddingAfterCameraStopsAgain;
      } else if (test_state_ == kWaitingForPaddingAfterCameraStopsAgain &&
                 only_padding) {
        // Padding is still flowing, test ok.
        observation_complete_.Set();
      }
      return SEND_PACKET;
    }

    Action OnSendRtcp(rtc::ArrayView<const uint8_t> packet) override {
      MutexLock lock(&mutex_);
      const int kNoPacketsThresholdMs = 2000;
      if (test_state_ == kWaitingForNoPackets &&
          (last_packet_time_ms_ &&
           clock_->TimeInMilliseconds() - last_packet_time_ms_.value() >
               kNoPacketsThresholdMs)) {
        // No packets seen for `kNoPacketsThresholdMs`, restart camera.
        capturer_->Start();
        test_state_ = kWaitingForMediaAfterCameraRestart;
      }
      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      // Make sure padding is sent if encoder is not producing media.
      encoder_config->min_transmit_bitrate_bps = 50000;
    }

    void OnFrameGeneratorCapturerCreated(
        test::FrameGeneratorCapturer* frame_generator_capturer) override {
      MutexLock lock(&mutex_);
      capturer_ = frame_generator_capturer;
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait())
          << "Timed out while waiting for RTP packets to stop being sent.";
    }

    enum TestState {
      kBeforeStopCapture,
      kWaitingForPadding,
      kWaitingForNoPackets,
      kWaitingForMediaAfterCameraRestart,
      kWaitingForPaddingAfterCameraStopsAgain
    };

    TestState test_state_ = kBeforeStopCapture;
    Clock* const clock_;
    Mutex mutex_;
    absl::optional<int64_t> last_packet_time_ms_ RTC_GUARDED_BY(mutex_);
    test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(mutex_);
  } test;

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
  const int kCapacityKbps = 10000;  // 10 Mbps
  class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
   public:
    PaddingIsPrimarilyRetransmissions()
        : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
          clock_(Clock::GetRealTimeClock()),
          padding_length_(0),
          total_length_(0),
          call_(nullptr) {}

   private:
    void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
      call_ = sender_call;
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      MutexLock lock(&mutex_);

      RtpPacket rtp_packet;
      rtp_packet.Parse(packet);
      padding_length_ += rtp_packet.padding_size();
      total_length_ += packet.size();
      return SEND_PACKET;
    }

    BuiltInNetworkBehaviorConfig GetSendTransportConfig() const override {
      const int kNetworkDelayMs = 50;
      BuiltInNetworkBehaviorConfig config;
      config.loss_percent = 10;
      config.link_capacity_kbps = kCapacityKbps;
      config.queue_delay_ms = kNetworkDelayMs;
      return config;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      // Turn on RTX.
      send_config->rtp.rtx.payload_type =
          test::VideoTestConstants::kFakeVideoSendPayloadType;
      send_config->rtp.rtx.ssrcs.push_back(
          test::VideoTestConstants::kSendRtxSsrcs[0]);
    }

    void PerformTest() override {
      // TODO(isheriff): Some platforms do not ramp up as expected to full
      // capacity due to packet scheduling delays. Fix that before getting
      // rid of this.
      SleepMs(5000);
      {
        MutexLock lock(&mutex_);
        // Expect padding to be a small percentage of total bytes sent.
        EXPECT_LT(padding_length_, .1 * total_length_);
      }
    }

    Mutex mutex_;
    Clock* const clock_;
    size_t padding_length_ RTC_GUARDED_BY(mutex_);
    size_t total_length_ RTC_GUARDED_BY(mutex_);
    Call* call_;
  } test;

  RunBaseTest(&test);
}

// This test first observes "high" bitrate use at which point it sends a REMB to
// indicate that it should be lowered significantly. The test then observes that
// the bitrate observed is sinking well below the min-transmit-bitrate threshold
// to verify that the min-transmit bitrate respects incoming REMB.
//
// Note that the test starts at "high" bitrate and does not ramp up to "higher"
// bitrate since no receiver block or remb is sent in the initial phase.
TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
  static const int kMinTransmitBitrateBps = 400000;
  static const int kHighBitrateBps = 150000;
  static const int kRembBitrateBps = 80000;
  static const int kRembRespectedBitrateBps = 100000;
  class BitrateObserver : public test::SendTest {
   public:
    explicit BitrateObserver(TaskQueueBase* task_queue)
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          task_queue_(task_queue),
          retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
          stream_(nullptr),
          bitrate_capped_(false),
          task_safety_flag_(PendingTaskSafetyFlag::CreateDetached()) {}

   private:
    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      if (IsRtcpPacket(packet))
        return DROP_PACKET;

      RtpPacket rtp_packet;
      RTC_CHECK(rtp_packet.Parse(packet));
      const uint32_t ssrc = rtp_packet.Ssrc();
      RTC_DCHECK(stream_);

      task_queue_->PostTask(SafeTask(task_safety_flag_, [this, ssrc]() {
        VideoSendStream::Stats stats = stream_->GetStats();
        if (!stats.substreams.empty()) {
          EXPECT_EQ(1u, stats.substreams.size());
          int total_bitrate_bps =
              stats.substreams.begin()->second.total_bitrate_bps;
          test::GetGlobalMetricsLogger()->LogSingleValueMetric(
              "bitrate_stats_min_transmit_bitrate_low_remb", "bitrate_bps",
              static_cast<size_t>(total_bitrate_bps) / 1000.0,
              test::Unit::kKilobitsPerSecond,
              test::ImprovementDirection::kNeitherIsBetter);
          if (total_bitrate_bps > kHighBitrateBps) {
            rtp_rtcp_->SetRemb(kRembBitrateBps, {ssrc});
            bitrate_capped_ = true;
          } else if (bitrate_capped_ &&
                     total_bitrate_bps < kRembRespectedBitrateBps) {
            observation_complete_.Set();
          }
        }
      }));

      // Packets don't have to be delivered since the test is the receiver.
      return DROP_PACKET;
    }

    void OnVideoStreamsCreated(VideoSendStream* send_stream,
                               const std::vector<VideoReceiveStreamInterface*>&
                                   receive_streams) override {
      stream_ = send_stream;
      RtpRtcpInterface::Configuration config;
      config.clock = Clock::GetRealTimeClock();
      config.outgoing_transport = feedback_transport_.get();
      config.retransmission_rate_limiter = &retranmission_rate_limiter_;
      rtp_rtcp_ = ModuleRtpRtcpImpl2::Create(config);
      rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      feedback_transport_.reset(
          new internal::TransportAdapter(send_config->send_transport));
      feedback_transport_->Enable();
      encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
    }

    void OnStreamsStopped() override {
      task_safety_flag_->SetNotAlive();
      rtp_rtcp_.reset();
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait())
          << "Timeout while waiting for low bitrate stats after REMB.";
    }

    TaskQueueBase* const task_queue_;
    std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_;
    std::unique_ptr<internal::TransportAdapter> feedback_transport_;
    RateLimiter retranmission_rate_limiter_;
    VideoSendStream* stream_;
    bool bitrate_capped_;
    rtc::scoped_refptr<PendingTaskSafetyFlag> task_safety_flag_;
  } test(task_queue());

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
  static const int kStartBitrateBps = 300000;
  static const int kNewMaxBitrateBps = 1234567;
  static const uint8_t kExtensionId = kTransportSequenceNumberExtensionId;
  class ChangingNetworkRouteTest : public test::EndToEndTest {
   public:
    explicit ChangingNetworkRouteTest(TaskQueueBase* task_queue)
        : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
          task_queue_(task_queue),
          call_(nullptr) {
      module_process_thread_.Detach();
      task_queue_thread_.Detach();
      extensions_.Register<TransportSequenceNumber>(kExtensionId);
    }

    ~ChangingNetworkRouteTest() {
      // Block until all already posted tasks run to avoid 'use after free'
      // when such task accesses `this`.
      SendTask(task_queue_, [] {});
    }

    void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
      RTC_DCHECK_RUN_ON(&task_queue_thread_);
      RTC_DCHECK(!call_);
      call_ = sender_call;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      RTC_DCHECK_RUN_ON(&task_queue_thread_);
      send_config->rtp.extensions.clear();
      send_config->rtp.extensions.push_back(RtpExtension(
          RtpExtension::kTransportSequenceNumberUri, kExtensionId));
    }

    void ModifyAudioConfigs(AudioSendStream::Config* send_config,
                            std::vector<AudioReceiveStreamInterface::Config>*
                                receive_configs) override {
      RTC_DCHECK_RUN_ON(&task_queue_thread_);
      send_config->rtp.extensions.clear();
      send_config->rtp.extensions.push_back(RtpExtension(
          RtpExtension::kTransportSequenceNumberUri, kExtensionId));
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      RTC_DCHECK_RUN_ON(&module_process_thread_);
      task_queue_->PostTask([this]() {
        RTC_DCHECK_RUN_ON(&task_queue_thread_);
        if (!call_)
          return;
        Call::Stats stats = call_->GetStats();
        if (stats.send_bandwidth_bps > kStartBitrateBps)
          observation_complete_.Set();
      });
      return SEND_PACKET;
    }

    void OnStreamsStopped() override {
      RTC_DCHECK_RUN_ON(&task_queue_thread_);
      call_ = nullptr;
    }

    void PerformTest() override {
      rtc::NetworkRoute new_route;
      new_route.connected = true;
      new_route.local = rtc::RouteEndpoint::CreateWithNetworkId(10);
      new_route.remote = rtc::RouteEndpoint::CreateWithNetworkId(20);
      BitrateConstraints bitrate_config;

      SendTask(task_queue_, [this, &new_route, &bitrate_config]() {
        RTC_DCHECK_RUN_ON(&task_queue_thread_);
        call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
                                                                   new_route);
        bitrate_config.start_bitrate_bps = kStartBitrateBps;
        call_->GetTransportControllerSend()->SetSdpBitrateParameters(
            bitrate_config);
      });

      EXPECT_TRUE(Wait())
          << "Timed out while waiting for start bitrate to be exceeded.";

      SendTask(task_queue_, [this, &new_route, &bitrate_config]() {
        RTC_DCHECK_RUN_ON(&task_queue_thread_);
        bitrate_config.start_bitrate_bps = -1;
        bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
        call_->GetTransportControllerSend()->SetSdpBitrateParameters(
            bitrate_config);
        // TODO(holmer): We should set the last sent packet id here and
        // verify that we correctly ignore any packet loss reported prior to
        // that id.
        new_route.local = rtc::RouteEndpoint::CreateWithNetworkId(
            new_route.local.network_id() + 1);
        call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
                                                                   new_route);
        EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
      });
    }

   private:
    webrtc::SequenceChecker module_process_thread_;
    webrtc::SequenceChecker task_queue_thread_;
    TaskQueueBase* const task_queue_;
    RtpHeaderExtensionMap extensions_;
    Call* call_ RTC_GUARDED_BY(task_queue_thread_);
  } test(task_queue());

  RunBaseTest(&test);
}

// Test that if specified, relay cap is lifted on transition to direct
// connection.
// TODO(https://bugs.webrtc.org/13353): Test disabled  due to flakiness.
TEST_F(VideoSendStreamTest, DISABLED_RelayToDirectRoute) {
  static const int kStartBitrateBps = 300000;
  static const int kRelayBandwidthCapBps = 800000;
  static const int kMinPacketsToSend = 100;
  webrtc::test::ScopedKeyValueConfig field_trials(
      field_trials_, "WebRTC-Bwe-NetworkRouteConstraints/relay_cap:" +
                         std::to_string(kRelayBandwidthCapBps) + "bps/");

  class RelayToDirectRouteTest : public test::EndToEndTest {
   public:
    explicit RelayToDirectRouteTest(TaskQueueBase* task_queue)
        : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
          task_queue_(task_queue),
          call_(nullptr),
          packets_sent_(0),
          relayed_phase_(true) {
      module_process_thread_.Detach();
      task_queue_thread_.Detach();
    }

    ~RelayToDirectRouteTest() {
      // Block until all already posted tasks run to avoid 'use after free'
      // when such task accesses `this`.
      SendTask(task_queue_, [] {});
    }

    void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
      RTC_DCHECK_RUN_ON(&task_queue_thread_);
      RTC_DCHECK(!call_);
      call_ = sender_call;
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      RTC_DCHECK_RUN_ON(&module_process_thread_);
      task_queue_->PostTask([this]() {
        RTC_DCHECK_RUN_ON(&task_queue_thread_);
        if (!call_)
          return;
        bool had_time_to_exceed_cap_in_relayed_phase =
            relayed_phase_ && ++packets_sent_ > kMinPacketsToSend;
        bool did_exceed_cap =
            call_->GetStats().send_bandwidth_bps > kRelayBandwidthCapBps;
        if (did_exceed_cap || had_time_to_exceed_cap_in_relayed_phase)
          observation_complete_.Set();
      });
      return SEND_PACKET;
    }

    void OnStreamsStopped() override {
      RTC_DCHECK_RUN_ON(&task_queue_thread_);
      call_ = nullptr;
    }

    void PerformTest() override {
      rtc::NetworkRoute route;
      route.connected = true;
      route.local = rtc::RouteEndpoint::CreateWithNetworkId(10);
      route.remote = rtc::RouteEndpoint::CreateWithNetworkId(20);

      SendTask(task_queue_, [this, &route]() {
        RTC_DCHECK_RUN_ON(&task_queue_thread_);
        relayed_phase_ = true;
        route.remote = route.remote.CreateWithTurn(true);
        call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
                                                                   route);
        BitrateConstraints bitrate_config;
        bitrate_config.start_bitrate_bps = kStartBitrateBps;

        call_->GetTransportControllerSend()->SetSdpBitrateParameters(
            bitrate_config);
      });

      EXPECT_TRUE(Wait())
          << "Timeout waiting for sufficient packets sent count.";

      SendTask(task_queue_, [this, &route]() {
        RTC_DCHECK_RUN_ON(&task_queue_thread_);
        EXPECT_LE(call_->GetStats().send_bandwidth_bps, kRelayBandwidthCapBps);

        route.remote = route.remote.CreateWithTurn(false);
        call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
                                                                   route);
        relayed_phase_ = false;
        observation_complete_.Reset();
      });

      EXPECT_TRUE(Wait())
          << "Timeout while waiting for bandwidth to outgrow relay cap.";
    }

   private:
    webrtc::SequenceChecker module_process_thread_;
    webrtc::SequenceChecker task_queue_thread_;
    TaskQueueBase* const task_queue_;
    Call* call_ RTC_GUARDED_BY(task_queue_thread_);
    int packets_sent_ RTC_GUARDED_BY(task_queue_thread_);
    bool relayed_phase_ RTC_GUARDED_BY(task_queue_thread_);
  } test(task_queue());

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
  class ChangingTransportOverheadTest : public test::EndToEndTest {
   public:
    explicit ChangingTransportOverheadTest(TaskQueueBase* task_queue)
        : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
          task_queue_(task_queue),
          call_(nullptr),
          packets_sent_(0),
          transport_overhead_(0) {}

    void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
      call_ = sender_call;
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      EXPECT_LE(packet.size(), kMaxRtpPacketSize);
      MutexLock lock(&lock_);
      if (++packets_sent_ < 100)
        return SEND_PACKET;
      observation_complete_.Set();
      return SEND_PACKET;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->rtp.max_packet_size = kMaxRtpPacketSize;
    }

    void PerformTest() override {
      SendTask(task_queue_, [this]() {
        transport_overhead_ = 100;
        call_->GetTransportControllerSend()->OnTransportOverheadChanged(
            transport_overhead_);
      });

      EXPECT_TRUE(Wait());

      {
        MutexLock lock(&lock_);
        packets_sent_ = 0;
      }

      SendTask(task_queue_, [this]() {
        transport_overhead_ = 500;
        call_->GetTransportControllerSend()->OnTransportOverheadChanged(
            transport_overhead_);
      });

      EXPECT_TRUE(Wait());
    }

   private:
    TaskQueueBase* const task_queue_;
    Call* call_;
    Mutex lock_;
    int packets_sent_ RTC_GUARDED_BY(lock_);
    int transport_overhead_;
    const size_t kMaxRtpPacketSize = 1000;
  } test(task_queue());

  RunBaseTest(&test);
}

// Test class takes takes as argument a switch selecting if type switch should
// occur and a function pointer to reset the send stream. This is necessary
// since you cannot change the content type of a VideoSendStream, you need to
// recreate it. Stopping and recreating the stream can only be done on the main
// thread and in the context of VideoSendStreamTest (not BaseTest).
template <typename T>
class MaxPaddingSetTest : public test::SendTest {
 public:
  static const uint32_t kMinTransmitBitrateBps = 400000;
  static const uint32_t kActualEncodeBitrateBps = 40000;
  static const uint32_t kMinPacketsToSend = 50;

  MaxPaddingSetTest(bool test_switch_content_type,
                    T* stream_reset_fun,
                    TaskQueueBase* task_queue)
      : SendTest(test::VideoTestConstants::kDefaultTimeout),
        running_without_padding_(test_switch_content_type),
        stream_resetter_(stream_reset_fun),
        task_queue_(task_queue) {
    RTC_DCHECK(stream_resetter_);
    module_process_thread_.Detach();
    task_queue_thread_.Detach();
  }

  ~MaxPaddingSetTest() {
    // Block until all already posted tasks run to avoid 'use after free'
    // when such task accesses `this`.
    SendTask(task_queue_, [] {});
  }

  void ModifyVideoConfigs(
      VideoSendStream::Config* send_config,
      std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
      VideoEncoderConfig* encoder_config) override {
    RTC_DCHECK_RUN_ON(&task_queue_thread_);
    RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
    if (running_without_padding_) {
      encoder_config->min_transmit_bitrate_bps = 0;
      encoder_config->content_type =
          VideoEncoderConfig::ContentType::kRealtimeVideo;
    } else {
      encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
      encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
    }
    send_stream_config_ = send_config->Copy();
    encoder_config_ = encoder_config->Copy();
  }

  void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
    RTC_DCHECK_RUN_ON(&task_queue_thread_);
    RTC_DCHECK(task_queue_->IsCurrent());
    RTC_DCHECK(!call_);
    RTC_DCHECK(sender_call);
    call_ = sender_call;
  }

  // Called on the pacer thread.
  Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
    RTC_DCHECK_RUN_ON(&module_process_thread_);

    // Check the stats on the correct thread and signal the 'complete' flag
    // once we detect that we're done.

    task_queue_->PostTask([this]() {
      RTC_DCHECK_RUN_ON(&task_queue_thread_);
      // In case we get a callback during teardown.
      // When this happens, OnStreamsStopped() has been called already,
      // `call_` is null and the streams are being torn down.
      if (!call_)
        return;

      ++packets_sent_;

      Call::Stats stats = call_->GetStats();
      if (running_without_padding_) {
        EXPECT_EQ(0, stats.max_padding_bitrate_bps);

        // Wait until at least kMinPacketsToSend frames have been encoded, so
        // that we have reliable data.
        if (packets_sent_ < kMinPacketsToSend)
          return;

        // We've sent kMinPacketsToSend packets with default configuration,
        // switch to enabling screen content and setting min transmit bitrate.
        // Note that we need to recreate the stream if changing content type.
        packets_sent_ = 0;

        encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
        encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;

        running_without_padding_ = false;
        (*stream_resetter_)(send_stream_config_, encoder_config_);
      } else {
        // Make sure the pacer has been configured with a min transmit bitrate.
        if (stats.max_padding_bitrate_bps > 0) {
          observation_complete_.Set();
        }
      }
    });

    return SEND_PACKET;
  }

  // Called on `task_queue_`
  void OnStreamsStopped() override {
    RTC_DCHECK_RUN_ON(&task_queue_thread_);
    RTC_DCHECK(task_queue_->IsCurrent());
    call_ = nullptr;
  }

  void PerformTest() override {
    ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
  }

 private:
  webrtc::SequenceChecker task_queue_thread_;
  Call* call_ RTC_GUARDED_BY(task_queue_thread_) = nullptr;
  VideoSendStream::Config send_stream_config_{nullptr};
  VideoEncoderConfig encoder_config_;
  webrtc::SequenceChecker module_process_thread_;
  uint32_t packets_sent_ RTC_GUARDED_BY(task_queue_thread_) = 0;
  bool running_without_padding_ RTC_GUARDED_BY(task_queue_thread_);
  T* const stream_resetter_;
  TaskQueueBase* const task_queue_;
};

TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
  auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
                      const VideoEncoderConfig& encoder_config) {};
  MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun, task_queue());
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
  // Function for removing and recreating the send stream with a new config.
  auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
                          const VideoEncoderConfig& encoder_config) {
    RTC_DCHECK(task_queue()->IsCurrent());
    Stop();
    DestroyVideoSendStreams();
    SetVideoSendConfig(send_stream_config);
    SetVideoEncoderConfig(encoder_config);
    CreateVideoSendStreams();
    SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
    Start();
  };
  MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun, task_queue());
  RunBaseTest(&test);
}

// This test verifies that new frame sizes reconfigures encoders even though not
// (yet) sending. The purpose of this is to permit encoding as quickly as
// possible once we start sending. Likely the frames being input are from the
// same source that will be sent later, which just means that we're ready
// earlier.
TEST_F(VideoSendStreamTest,
       EncoderReconfigureOnResolutionChangeWhenNotSending) {
  class EncoderObserver : public test::FakeEncoder {
   public:
    explicit EncoderObserver(const Environment& env)
        : FakeEncoder(env),
          last_initialized_frame_width_(0),
          last_initialized_frame_height_(0) {}

    void WaitForResolution(int width, int height) {
      {
        MutexLock lock(&mutex_);
        if (last_initialized_frame_width_ == width &&
            last_initialized_frame_height_ == height) {
          return;
        }
      }
      EXPECT_TRUE(
          init_encode_called_.Wait(test::VideoTestConstants::kDefaultTimeout));
      {
        MutexLock lock(&mutex_);
        EXPECT_EQ(width, last_initialized_frame_width_);
        EXPECT_EQ(height, last_initialized_frame_height_);
      }
    }

   private:
    int32_t InitEncode(const VideoCodec* config,
                       const Settings& settings) override {
      MutexLock lock(&mutex_);
      last_initialized_frame_width_ = config->width;
      last_initialized_frame_height_ = config->height;
      init_encode_called_.Set();
      return FakeEncoder::InitEncode(config, settings);
    }

    int32_t Encode(const VideoFrame& input_image,
                   const std::vector<VideoFrameType>* frame_types) override {
      ADD_FAILURE()
          << "Unexpected Encode call since the send stream is not started";
      return 0;
    }

    Mutex mutex_;
    rtc::Event init_encode_called_;
    int last_initialized_frame_width_ RTC_GUARDED_BY(&mutex_);
    int last_initialized_frame_height_ RTC_GUARDED_BY(&mutex_);
  };

  test::NullTransport transport;
  EncoderObserver encoder(env());
  test::VideoEncoderProxyFactory encoder_factory(&encoder);

  SendTask(task_queue(), [this, &transport, &encoder_factory]() {
    CreateSenderCall();
    CreateSendConfig(1, 0, 0, &transport);
    GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
    CreateVideoStreams();
    CreateFrameGeneratorCapturer(test::VideoTestConstants::kDefaultFramerate,
                                 test::VideoTestConstants::kDefaultWidth,
                                 test::VideoTestConstants::kDefaultHeight);
    frame_generator_capturer_->Start();
  });

  encoder.WaitForResolution(test::VideoTestConstants::kDefaultWidth,
                            test::VideoTestConstants::kDefaultHeight);

  SendTask(task_queue(), [this]() {
    frame_generator_capturer_->ChangeResolution(
        test::VideoTestConstants::kDefaultWidth * 2,
        test::VideoTestConstants::kDefaultHeight * 2);
  });

  encoder.WaitForResolution(test::VideoTestConstants::kDefaultWidth * 2,
                            test::VideoTestConstants::kDefaultHeight * 2);

  SendTask(task_queue(), [this]() {
    DestroyStreams();
    DestroyCalls();
  });
}

TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
  class StartBitrateObserver : public test::FakeEncoder {
   public:
    explicit StartBitrateObserver(const Environment& env)
        : FakeEncoder(env), start_bitrate_kbps_(0) {}
    int32_t InitEncode(const VideoCodec* config,
                       const Settings& settings) override {
      MutexLock lock(&mutex_);
      start_bitrate_kbps_ = config->startBitrate;
      start_bitrate_changed_.Set();
      return FakeEncoder::InitEncode(config, settings);
    }

    void SetRates(const RateControlParameters& parameters) override {
      MutexLock lock(&mutex_);
      start_bitrate_kbps_ = parameters.bitrate.get_sum_kbps();
      start_bitrate_changed_.Set();
      FakeEncoder::SetRates(parameters);
    }

    int GetStartBitrateKbps() const {
      MutexLock lock(&mutex_);
      return start_bitrate_kbps_;
    }

    bool WaitForStartBitrate() {
      return start_bitrate_changed_.Wait(
          test::VideoTestConstants::kDefaultTimeout);
    }

   private:
    mutable Mutex mutex_;
    rtc::Event start_bitrate_changed_;
    int start_bitrate_kbps_ RTC_GUARDED_BY(mutex_);
  };

  CreateSenderCall();

  test::NullTransport transport;
  CreateSendConfig(1, 0, 0, &transport);

  BitrateConstraints bitrate_config;
  bitrate_config.start_bitrate_bps =
      2 * GetVideoEncoderConfig()->max_bitrate_bps;
  sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
      bitrate_config);

  StartBitrateObserver encoder(env());
  test::VideoEncoderProxyFactory encoder_factory(&encoder);
  GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;

  CreateVideoStreams();

  // Start capturing and encoding frames to force encoder reconfiguration.
  CreateFrameGeneratorCapturer(test::VideoTestConstants::kDefaultFramerate,
                               test::VideoTestConstants::kDefaultWidth,
                               test::VideoTestConstants::kDefaultHeight);
  frame_generator_capturer_->Start();
  // TODO(crbug/1255737): Added manual current thread message processing because
  // the test code context is interpreted as the worker thread and we assume
  // progress on it. The test should probably be ported to use simulated time
  // instead (ported to a scenario test perhaps?).
  rtc::Thread::Current()->ProcessMessages(5000);

  EXPECT_TRUE(encoder.WaitForStartBitrate());
  EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
            encoder.GetStartBitrateKbps());

  GetVideoEncoderConfig()->max_bitrate_bps =
      2 * bitrate_config.start_bitrate_bps;
  GetVideoSendStream()->ReconfigureVideoEncoder(
      GetVideoEncoderConfig()->Copy());
  // TODO(crbug/1255737): Added manual current thread message processing because
  // the test code context is interpreted as the worker thread and we assume
  // progress on it. The test should probably be ported to use simulated time
  // instead (ported to a scenario test perhaps?).
  rtc::Thread::Current()->ProcessMessages(5000);

  // New bitrate should be reconfigured above the previous max. As there's no
  // network connection this shouldn't be flaky, as no bitrate should've been
  // reported in between.
  EXPECT_TRUE(encoder.WaitForStartBitrate());
  EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
            encoder.GetStartBitrateKbps());

  DestroyStreams();
}

TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
  class EncoderStateObserver : public test::SendTest, public VideoEncoder {
   public:
    explicit EncoderStateObserver(TaskQueueBase* task_queue)
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          task_queue_(task_queue),
          stream_(nullptr),
          initialized_(false),
          callback_registered_(false),
          num_releases_(0),
          released_(false),
          encoder_factory_(this) {}

    bool IsReleased() RTC_LOCKS_EXCLUDED(mutex_) {
      MutexLock lock(&mutex_);
      return released_;
    }

    bool IsReadyForEncode() RTC_LOCKS_EXCLUDED(mutex_) {
      MutexLock lock(&mutex_);
      return IsReadyForEncodeLocked();
    }

    size_t num_releases() RTC_LOCKS_EXCLUDED(mutex_) {
      MutexLock lock(&mutex_);
      return num_releases_;
    }

   private:
    bool IsReadyForEncodeLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
      return initialized_ && callback_registered_;
    }

    void SetFecControllerOverride(
        FecControllerOverride* fec_controller_override) override {
      // Ignored.
    }

    int32_t InitEncode(const VideoCodec* codecSettings,
                       const Settings& settings) override
        RTC_LOCKS_EXCLUDED(mutex_) {
      MutexLock lock(&mutex_);
      EXPECT_FALSE(initialized_);
      initialized_ = true;
      released_ = false;
      return 0;
    }

    int32_t Encode(const VideoFrame& inputImage,
                   const std::vector<VideoFrameType>* frame_types) override {
      EXPECT_TRUE(IsReadyForEncode());

      observation_complete_.Set();
      return 0;
    }

    int32_t RegisterEncodeCompleteCallback(
        EncodedImageCallback* callback) override RTC_LOCKS_EXCLUDED(mutex_) {
      MutexLock lock(&mutex_);
      EXPECT_TRUE(initialized_);
      callback_registered_ = true;
      return 0;
    }

    int32_t Release() override RTC_LOCKS_EXCLUDED(mutex_) {
      MutexLock lock(&mutex_);
      EXPECT_TRUE(IsReadyForEncodeLocked());
      EXPECT_FALSE(released_);
      initialized_ = false;
      callback_registered_ = false;
      released_ = true;
      ++num_releases_;
      return 0;
    }

    void SetRates(const RateControlParameters& parameters) override {
      EXPECT_TRUE(IsReadyForEncode());
    }

    EncoderInfo GetEncoderInfo() const override { return EncoderInfo(); }

    void OnVideoStreamsCreated(VideoSendStream* send_stream,
                               const std::vector<VideoReceiveStreamInterface*>&
                                   receive_streams) override {
      stream_ = send_stream;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->encoder_settings.encoder_factory = &encoder_factory_;
      encoder_config_ = encoder_config->Copy();
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";

      SendTask(task_queue_, [this]() {
        EXPECT_EQ(0u, num_releases());
        stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
        EXPECT_EQ(0u, num_releases());
        stream_->Stop();
        // Encoder should not be released before destroying the VideoSendStream.
        EXPECT_FALSE(IsReleased());
        EXPECT_TRUE(IsReadyForEncode());
        stream_->Start();
      });

      // Sanity check, make sure we still encode frames with this encoder.
      EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
    }

    TaskQueueBase* const task_queue_;
    Mutex mutex_;
    VideoSendStream* stream_;
    bool initialized_ RTC_GUARDED_BY(mutex_);
    bool callback_registered_ RTC_GUARDED_BY(mutex_);
    size_t num_releases_ RTC_GUARDED_BY(mutex_);
    bool released_ RTC_GUARDED_BY(mutex_);
    test::VideoEncoderProxyFactory encoder_factory_;
    VideoEncoderConfig encoder_config_;
  } test_encoder(task_queue());

  RunBaseTest(&test_encoder);

  EXPECT_TRUE(test_encoder.IsReleased());
  EXPECT_EQ(1u, test_encoder.num_releases());
}

static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
template <typename T>
class VideoCodecConfigObserver : public test::SendTest,
                                 public test::FakeEncoder {
 public:
  VideoCodecConfigObserver(const Environment& env,
                           VideoCodecType video_codec_type,
                           TaskQueueBase* task_queue)
      : SendTest(test::VideoTestConstants::kDefaultTimeout),
        FakeEncoder(env),
        video_codec_type_(video_codec_type),
        stream_(nullptr),
        encoder_factory_(this),
        task_queue_(task_queue) {
    InitCodecSpecifics();
  }

 private:
  void ModifyVideoConfigs(
      VideoSendStream::Config* send_config,
      std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
      VideoEncoderConfig* encoder_config) override {
    send_config->encoder_settings.encoder_factory = &encoder_factory_;
    send_config->rtp.payload_name = CodecTypeToPayloadString(video_codec_type_);

    encoder_config->codec_type = video_codec_type_;
    encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
    EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
    encoder_config->simulcast_layers[0].num_temporal_layers =
        kVideoCodecConfigObserverNumberOfTemporalLayers;
    encoder_config_ = encoder_config->Copy();
  }

  void OnVideoStreamsCreated(VideoSendStream* send_stream,
                             const std::vector<VideoReceiveStreamInterface*>&
                                 receive_streams) override {
    stream_ = send_stream;
  }

  int32_t InitEncode(const VideoCodec* config,
                     const Settings& settings) override {
    EXPECT_EQ(video_codec_type_, config->codecType);
    VerifyCodecSpecifics(*config);
    int ret = FakeEncoder::InitEncode(config, settings);
    init_encode_event_.Set();
    return ret;
  }

  void InitCodecSpecifics();
  void VerifyCodecSpecifics(const VideoCodec& config) const;
  rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
  GetEncoderSpecificSettings() const;

  void PerformTest() override {
    EXPECT_TRUE(
        init_encode_event_.Wait(test::VideoTestConstants::kDefaultTimeout));
    ASSERT_EQ(1, FakeEncoder::GetNumInitializations())
        << "VideoEncoder not initialized.";

    // Change encoder settings to actually trigger reconfiguration.
    encoder_config_.frame_drop_enabled = !encoder_config_.frame_drop_enabled;
    encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
    SendTask(task_queue_, [&]() {
      stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
    });
    ASSERT_TRUE(
        init_encode_event_.Wait(test::VideoTestConstants::kDefaultTimeout));
    EXPECT_EQ(2, FakeEncoder::GetNumInitializations())
        << "ReconfigureVideoEncoder did not reinitialize the encoder with "
           "new encoder settings.";
  }

  int32_t Encode(const VideoFrame& input_image,
                 const std::vector<VideoFrameType>* frame_types) override {
    // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
    return 0;
  }

  T encoder_settings_;
  const VideoCodecType video_codec_type_;
  rtc::Event init_encode_event_;
  VideoSendStream* stream_;
  test::VideoEncoderProxyFactory encoder_factory_;
  VideoEncoderConfig encoder_config_;
  TaskQueueBase* task_queue_;
};

template <>
void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {}

template <>
void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
    const VideoCodec& config) const {
  // Check that the number of temporal layers has propagated properly to
  // VideoCodec.
  EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
            config.H264().numberOfTemporalLayers);

  for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
    EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
              config.simulcastStream[i].numberOfTemporalLayers);
  }

  // Set expected temporal layers as they should have been set when
  // reconfiguring the encoder and not match the set config.
  VideoCodecH264 encoder_settings = VideoEncoder::GetDefaultH264Settings();
  encoder_settings.numberOfTemporalLayers =
      kVideoCodecConfigObserverNumberOfTemporalLayers;
  EXPECT_EQ(config.H264(), encoder_settings);
}

template <>
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
  return nullptr;
}

template <>
void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
  encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
}

template <>
void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
    const VideoCodec& config) const {
  // Check that the number of temporal layers has propagated properly to
  // VideoCodec.
  EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
            config.VP8().numberOfTemporalLayers);

  for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
    EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
              config.simulcastStream[i].numberOfTemporalLayers);
  }

  // Set expected temporal layers as they should have been set when
  // reconfiguring the encoder and not match the set config.
  VideoCodecVP8 encoder_settings = encoder_settings_;
  encoder_settings.numberOfTemporalLayers =
      kVideoCodecConfigObserverNumberOfTemporalLayers;
  EXPECT_EQ(
      0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
}

template <>
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
  return rtc::make_ref_counted<VideoEncoderConfig::Vp8EncoderSpecificSettings>(
      encoder_settings_);
}

template <>
void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
  encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
}

template <>
void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
    const VideoCodec& config) const {
  // Check that the number of temporal layers has propagated properly to
  // VideoCodec.
  EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
            config.VP9().numberOfTemporalLayers);

  for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
    EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
              config.simulcastStream[i].numberOfTemporalLayers);
  }

  // Set expected temporal layers as they should have been set when
  // reconfiguring the encoder and not match the set config.
  VideoCodecVP9 encoder_settings = encoder_settings_;
  encoder_settings.numberOfTemporalLayers =
      kVideoCodecConfigObserverNumberOfTemporalLayers;
  EXPECT_EQ(
      0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
}

template <>
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
  return rtc::make_ref_counted<VideoEncoderConfig::Vp9EncoderSpecificSettings>(
      encoder_settings_);
}

TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
  VideoCodecConfigObserver<VideoCodecVP8> test(env(), kVideoCodecVP8,
                                               task_queue());
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
  VideoCodecConfigObserver<VideoCodecVP9> test(env(), kVideoCodecVP9,
                                               task_queue());
  RunBaseTest(&test);
}

// Fails on MSAN: https://bugs.chromium.org/p/webrtc/issues/detail?id=11376.
#if defined(MEMORY_SANITIZER)
#define MAYBE_EncoderSetupPropagatesH264Config \
  DISABLED_EncoderSetupPropagatesH264Config
#else
#define MAYBE_EncoderSetupPropagatesH264Config EncoderSetupPropagatesH264Config
#endif
TEST_F(VideoSendStreamTest, MAYBE_EncoderSetupPropagatesH264Config) {
  VideoCodecConfigObserver<VideoCodecH264> test(env(), kVideoCodecH264,
                                                task_queue());
  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
  class RtcpSenderReportTest : public test::SendTest {
   public:
    RtcpSenderReportTest()
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          rtp_packets_sent_(0),
          media_bytes_sent_(0) {}

   private:
    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      MutexLock lock(&mutex_);
      RtpPacket rtp_packet;
      EXPECT_TRUE(rtp_packet.Parse(packet));
      ++rtp_packets_sent_;
      media_bytes_sent_ += rtp_packet.payload_size();
      return SEND_PACKET;
    }

    Action OnSendRtcp(rtc::ArrayView<const uint8_t> packet) override {
      MutexLock lock(&mutex_);
      test::RtcpPacketParser parser;
      EXPECT_TRUE(parser.Parse(packet));

      if (parser.sender_report()->num_packets() > 0) {
        // Only compare sent media bytes if SenderPacketCount matches the
        // number of sent rtp packets (a new rtp packet could be sent before
        // the rtcp packet).
        if (parser.sender_report()->sender_octet_count() > 0 &&
            parser.sender_report()->sender_packet_count() ==
                rtp_packets_sent_) {
          EXPECT_EQ(media_bytes_sent_,
                    parser.sender_report()->sender_octet_count());
          observation_complete_.Set();
        }
      }

      return SEND_PACKET;
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
    }

    Mutex mutex_;
    size_t rtp_packets_sent_ RTC_GUARDED_BY(&mutex_);
    size_t media_bytes_sent_ RTC_GUARDED_BY(&mutex_);
  } test;

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
  static const int kScreencastMaxTargetBitrateDeltaKbps = 1;

  class VideoStreamFactory
      : public VideoEncoderConfig::VideoStreamFactoryInterface {
   public:
    VideoStreamFactory() {}

   private:
    std::vector<VideoStream> CreateEncoderStreams(
        const FieldTrialsView& /*field_trials*/,
        int frame_width,
        int frame_height,
        const VideoEncoderConfig& encoder_config) override {
      std::vector<VideoStream> streams =
          test::CreateVideoStreams(frame_width, frame_height, encoder_config);
      RTC_CHECK_GT(streams[0].max_bitrate_bps,
                   kScreencastMaxTargetBitrateDeltaKbps);
      streams[0].target_bitrate_bps =
          streams[0].max_bitrate_bps -
          kScreencastMaxTargetBitrateDeltaKbps * 1000;
      return streams;
    }
  };

  class ScreencastTargetBitrateTest : public test::SendTest,
                                      public test::FakeEncoder {
   public:
    explicit ScreencastTargetBitrateTest(const Environment& env)
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          test::FakeEncoder(env),
          encoder_factory_(this) {}

   private:
    int32_t InitEncode(const VideoCodec* config,
                       const Settings& settings) override {
      EXPECT_EQ(config->numberOfSimulcastStreams, 1);
      EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
                config->simulcastStream[0].maxBitrate -
                    config->simulcastStream[0].targetBitrate);
      observation_complete_.Set();
      return test::FakeEncoder::InitEncode(config, settings);
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->encoder_settings.encoder_factory = &encoder_factory_;
      EXPECT_EQ(1u, encoder_config->number_of_streams);
      encoder_config->video_stream_factory =
          rtc::make_ref_counted<VideoStreamFactory>();
      EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
      encoder_config->simulcast_layers[0].num_temporal_layers = 2;
      encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait())
          << "Timed out while waiting for the encoder to be initialized.";
    }
    test::VideoEncoderProxyFactory encoder_factory_;
  } test(env());

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
  // These are chosen to be "kind of odd" to not be accidentally checked against
  // default values.
  static const int kMinBitrateKbps = 137;
  static const int kStartBitrateKbps = 345;
  static const int kLowerMaxBitrateKbps = 312;
  static const int kMaxBitrateKbps = 413;
  static const int kIncreasedStartBitrateKbps = 451;
  static const int kIncreasedMaxBitrateKbps = 597;
  // TODO(bugs.webrtc.org/12058): If these fields trial are on, we get lower
  // bitrates than expected by this test, due to encoder pushback and subtracted
  // overhead.
  webrtc::test::ScopedKeyValueConfig field_trials(
      field_trials_, "WebRTC-VideoRateControl/bitrate_adjuster:false/");

  class EncoderBitrateThresholdObserver : public test::SendTest,
                                          public VideoBitrateAllocatorFactory,
                                          public test::FakeEncoder {
   public:
    explicit EncoderBitrateThresholdObserver(const Environment& env,
                                             TaskQueueBase* task_queue)
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          FakeEncoder(env),
          task_queue_(task_queue),
          target_bitrate_(0),
          num_rate_allocator_creations_(0),
          num_encoder_initializations_(0),
          call_(nullptr),
          send_stream_(nullptr),
          encoder_factory_(this),
          bitrate_allocator_factory_(
              CreateBuiltinVideoBitrateAllocatorFactory()) {}

   private:
    std::unique_ptr<VideoBitrateAllocator> CreateVideoBitrateAllocator(
        const VideoCodec& codec) override {
      EXPECT_GE(codec.startBitrate, codec.minBitrate);
      EXPECT_LE(codec.startBitrate, codec.maxBitrate);
      if (num_rate_allocator_creations_ == 0) {
        EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps), codec.minBitrate);
        EXPECT_NEAR(static_cast<unsigned int>(kStartBitrateKbps),
                    codec.startBitrate, 10);
        EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps), codec.maxBitrate);
      } else if (num_rate_allocator_creations_ == 1) {
        EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
                  codec.maxBitrate);
        // The start bitrate should be kept (-1) and capped to the max bitrate.
        // Since this is not an end-to-end call no receiver should have been
        // returning a REMB that could lower this estimate.
        EXPECT_EQ(codec.startBitrate, codec.maxBitrate);
      } else if (num_rate_allocator_creations_ == 2) {
        EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
                  codec.maxBitrate);
        // The start bitrate will be whatever the rate BitRateController has
        // currently configured but in the span of the set max and min bitrate.
      }
      ++num_rate_allocator_creations_;
      create_rate_allocator_event_.Set();

      return bitrate_allocator_factory_->CreateVideoBitrateAllocator(codec);
    }

    int32_t InitEncode(const VideoCodec* codecSettings,
                       const Settings& settings) override {
      EXPECT_EQ(0, num_encoder_initializations_);
      EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
                codecSettings->minBitrate);
      EXPECT_NEAR(static_cast<unsigned int>(kStartBitrateKbps),
                  codecSettings->startBitrate, 10);
      EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
                codecSettings->maxBitrate);

      ++num_encoder_initializations_;

      observation_complete_.Set();
      init_encode_event_.Set();

      return FakeEncoder::InitEncode(codecSettings, settings);
    }

    void SetRates(const RateControlParameters& parameters) override {
      {
        MutexLock lock(&mutex_);
        if (target_bitrate_ == parameters.bitrate.get_sum_kbps()) {
          FakeEncoder::SetRates(parameters);
          return;
        }
        target_bitrate_ = parameters.bitrate.get_sum_kbps();
      }
      bitrate_changed_event_.Set();
      FakeEncoder::SetRates(parameters);
    }

    void WaitForSetRates(uint32_t expected_bitrate, int abs_error) {
      // Wait for the expected rate to be set. In some cases there can be
      // more than one update pending, in which case we keep waiting
      // until the correct value has been observed.
      // The target_bitrate_ is reduced by the calculated packet overhead.
      const int64_t start_time = rtc::TimeMillis();
      do {
        MutexLock lock(&mutex_);

        int error = target_bitrate_ - expected_bitrate;
        if ((error < 0 && error >= -abs_error) ||
            (error >= 0 && error <= abs_error)) {
          return;
        }
      } while (bitrate_changed_event_.Wait(
          std::max(TimeDelta::Millis(1),
                   test::VideoTestConstants::kDefaultTimeout -
                       TimeDelta::Millis(rtc::TimeMillis() - start_time))));
      MutexLock lock(&mutex_);
      EXPECT_NEAR(target_bitrate_, expected_bitrate, abs_error)
          << "Timed out while waiting encoder rate to be set.";
    }

    void ModifySenderBitrateConfig(
        BitrateConstraints* bitrate_config) override {
      bitrate_config->min_bitrate_bps = kMinBitrateKbps * 1000;
      bitrate_config->start_bitrate_bps = kStartBitrateKbps * 1000;
      bitrate_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->encoder_settings.encoder_factory = &encoder_factory_;
      send_config->encoder_settings.bitrate_allocator_factory = this;
      // Set bitrates lower/higher than min/max to make sure they are properly
      // capped.
      encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
      EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
      encoder_config->simulcast_layers[0].min_bitrate_bps =
          kMinBitrateKbps * 1000;
      encoder_config_ = encoder_config->Copy();
    }

    void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
      call_ = sender_call;
    }

    void OnVideoStreamsCreated(VideoSendStream* send_stream,
                               const std::vector<VideoReceiveStreamInterface*>&
                                   receive_streams) override {
      send_stream_ = send_stream;
    }

    void PerformTest() override {
      ASSERT_TRUE(create_rate_allocator_event_.Wait(
          test::VideoTestConstants::kDefaultTimeout))
          << "Timed out while waiting for rate allocator to be created.";
      ASSERT_TRUE(
          init_encode_event_.Wait(test::VideoTestConstants::kDefaultTimeout))
          << "Timed out while waiting for encoder to be configured.";
      WaitForSetRates(kStartBitrateKbps, 80);
      BitrateConstraints bitrate_config;
      bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
      bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
      SendTask(task_queue_, [this, &bitrate_config]() {
        call_->GetTransportControllerSend()->SetSdpBitrateParameters(
            bitrate_config);
      });
      // Encoder rate is capped by EncoderConfig max_bitrate_bps.
      WaitForSetRates(kMaxBitrateKbps, 10);
      encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
      SendTask(task_queue_, [&]() {
        send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
      });
      ASSERT_TRUE(create_rate_allocator_event_.Wait(
          test::VideoTestConstants::kDefaultTimeout));
      EXPECT_EQ(2, num_rate_allocator_creations_)
          << "Rate allocator should have been recreated.";

      WaitForSetRates(kLowerMaxBitrateKbps, 10);
      EXPECT_EQ(1, num_encoder_initializations_);

      encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
      SendTask(task_queue_, [&]() {
        send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
      });
      ASSERT_TRUE(create_rate_allocator_event_.Wait(
          test::VideoTestConstants::kDefaultTimeout));
      EXPECT_EQ(3, num_rate_allocator_creations_)
          << "Rate allocator should have been recreated.";

      // Expected target bitrate is the start bitrate set in the call to
      // call_->GetTransportControllerSend()->SetSdpBitrateParameters.
      WaitForSetRates(kIncreasedStartBitrateKbps, 10);
      EXPECT_EQ(1, num_encoder_initializations_);
    }

    TaskQueueBase* const task_queue_;
    rtc::Event create_rate_allocator_event_;
    rtc::Event init_encode_event_;
    rtc::Event bitrate_changed_event_;
    Mutex mutex_;
    uint32_t target_bitrate_ RTC_GUARDED_BY(&mutex_);

    int num_rate_allocator_creations_;
    int num_encoder_initializations_;
    webrtc::Call* call_;
    webrtc::VideoSendStream* send_stream_;
    test::VideoEncoderProxyFactory encoder_factory_;
    std::unique_ptr<VideoBitrateAllocatorFactory> bitrate_allocator_factory_;
    webrtc::VideoEncoderConfig encoder_config_;
  } test(env(), task_queue());

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, ReportsSentResolution) {
  static const size_t kNumStreams = 3;
  // Unusual resolutions to make sure that they are the ones being reported.
  static const struct {
    int width;
    int height;
  } kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
  class ScreencastTargetBitrateTest : public test::SendTest,
                                      public test::FakeEncoder {
   public:
    explicit ScreencastTargetBitrateTest(const Environment& env,
                                         TaskQueueBase* task_queue)
        : SendTest(test::VideoTestConstants::kDefaultTimeout),
          test::FakeEncoder(env),
          send_stream_(nullptr),
          encoder_factory_(this),
          task_queue_(task_queue) {}

   private:
    int32_t Encode(const VideoFrame& input_image,
                   const std::vector<VideoFrameType>* frame_types) override {
      CodecSpecificInfo specifics;
      specifics.codecType = kVideoCodecGeneric;

      EncodedImage encoded;
      auto buffer = EncodedImageBuffer::Create(16);
      memset(buffer->data(), 0, 16);
      encoded.SetEncodedData(buffer);
      encoded.SetRtpTimestamp(input_image.rtp_timestamp());
      encoded.capture_time_ms_ = input_image.render_time_ms();

      for (size_t i = 0; i < kNumStreams; ++i) {
        encoded._frameType = (*frame_types)[i];
        encoded._encodedWidth = kEncodedResolution[i].width;
        encoded._encodedHeight = kEncodedResolution[i].height;
        encoded.SetSimulcastIndex(i);
        EncodedImageCallback* callback;
        {
          MutexLock lock(&mutex_);
          callback = callback_;
        }
        RTC_DCHECK(callback);
        if (callback->OnEncodedImage(encoded, &specifics).error !=
            EncodedImageCallback::Result::OK) {
          return -1;
        }
      }

      observation_complete_.Set();
      return 0;
    }
    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->encoder_settings.encoder_factory = &encoder_factory_;
      EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
    }

    size_t GetNumVideoStreams() const override { return kNumStreams; }

    void PerformTest() override {
      EXPECT_TRUE(Wait())
          << "Timed out while waiting for the encoder to send one frame.";
      VideoSendStream::Stats stats;
      SendTask(task_queue_, [&]() { stats = send_stream_->GetStats(); });

      for (size_t i = 0; i < kNumStreams; ++i) {
        ASSERT_TRUE(stats.substreams.find(
                        test::VideoTestConstants::kVideoSendSsrcs[i]) !=
                    stats.substreams.end())
            << "No stats for SSRC: "
            << test::VideoTestConstants::kVideoSendSsrcs[i]
            << ", stats should exist as soon as frames have been encoded.";
        VideoSendStream::StreamStats ssrc_stats =
            stats.substreams[test::VideoTestConstants::kVideoSendSsrcs[i]];
        EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
        EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
      }
    }

    void OnVideoStreamsCreated(VideoSendStream* send_stream,
                               const std::vector<VideoReceiveStreamInterface*>&
                                   receive_streams) override {
      send_stream_ = send_stream;
    }

    VideoSendStream* send_stream_;
    test::VideoEncoderProxyFactory encoder_factory_;
    TaskQueueBase* const task_queue_;
  } test(env(), task_queue());

  RunBaseTest(&test);
}

#if defined(RTC_ENABLE_VP9)
class Vp9HeaderObserver : public test::SendTest {
 public:
  explicit Vp9HeaderObserver(const Vp9TestParams& params)
      : SendTest(test::VideoTestConstants::kLongTimeout),
        encoder_factory_(
            [](const Environment& env, const SdpVideoFormat& format) {
              return CreateVp9Encoder(env);
            }),
        params_(params),
        vp9_settings_(VideoEncoder::GetDefaultVp9Settings()) {}

  virtual void ModifyVideoConfigsHook(
      VideoSendStream::Config* send_config,
      std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
      VideoEncoderConfig* encoder_config) {}

  virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;

 private:
  const int kVp9PayloadType = test::VideoTestConstants::kVideoSendPayloadType;

  void ModifyVideoConfigs(
      VideoSendStream::Config* send_config,
      std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
      VideoEncoderConfig* encoder_config) override {
    send_config->encoder_settings.encoder_factory = &encoder_factory_;
    send_config->rtp.payload_name = "VP9";
    send_config->rtp.payload_type = kVp9PayloadType;
    ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
    encoder_config->encoder_specific_settings =
        rtc::make_ref_counted<VideoEncoderConfig::Vp9EncoderSpecificSettings>(
            vp9_settings_);
    EXPECT_EQ(1u, encoder_config->number_of_streams);
    EXPECT_EQ(1u, encoder_config->simulcast_layers.size());
    encoder_config_ = encoder_config->Copy();
  }

  void ModifyVideoCaptureStartResolution(int* width,
                                         int* height,
                                         int* frame_rate) override {
    expected_width_ = *width;
    expected_height_ = *height;
  }

  void PerformTest() override {
    bool wait = Wait();
    {
      // In case of time out, OnSendRtp might still access frames_sent_;
      MutexLock lock(&mutex_);
      EXPECT_TRUE(wait) << "Test timed out waiting for VP9 packet, num frames "
                        << frames_sent_;
    }
  }

  Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
    RtpPacket rtp_packet;
    EXPECT_TRUE(rtp_packet.Parse(packet));

    EXPECT_EQ(kVp9PayloadType, rtp_packet.PayloadType());
    rtc::ArrayView<const uint8_t> rtp_payload = rtp_packet.payload();

    bool new_packet = !last_packet_sequence_number_.has_value() ||
                      IsNewerSequenceNumber(rtp_packet.SequenceNumber(),
                                            *last_packet_sequence_number_);
    if (!rtp_payload.empty() && new_packet) {
      RTPVideoHeader video_header;
      EXPECT_NE(
          VideoRtpDepacketizerVp9::ParseRtpPayload(rtp_payload, &video_header),
          0);
      EXPECT_EQ(VideoCodecType::kVideoCodecVP9, video_header.codec);
      // Verify common fields for all configurations.
      const auto& vp9_header =
          absl::get<RTPVideoHeaderVP9>(video_header.video_type_header);
      VerifyCommonHeader(vp9_header);
      CompareConsecutiveFrames(rtp_packet, video_header);
      // Verify configuration specific settings.
      InspectHeader(vp9_header);

      if (rtp_packet.Marker()) {
        MutexLock lock(&mutex_);
        ++frames_sent_;
      }
      last_packet_marker_ = rtp_packet.Marker();
      last_packet_sequence_number_ = rtp_packet.SequenceNumber();
      last_packet_timestamp_ = rtp_packet.Timestamp();
      last_vp9_ = vp9_header;
      last_temporal_idx_by_spatial_idx_[vp9_header.spatial_idx] =
          vp9_header.temporal_idx;
    }
    return SEND_PACKET;
  }

 protected:
  bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
    if (last_vp9_.picture_id > vp9.picture_id) {
      return vp9.picture_id == 0;  // Wrap.
    } else {
      return vp9.picture_id == last_vp9_.picture_id + 1;
    }
  }

  bool IsTemporalShiftEnabled() const {
    return params_.scalability_mode.find("_SHIFT") != std::string::npos;
  }

  void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
    bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
    EXPECT_EQ(new_layer, vp9.beginning_of_frame);
    EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
    EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
              vp9.spatial_idx);
  }

  void VerifyTemporalIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
    if (!IsTemporalShiftEnabled()) {
      EXPECT_EQ(vp9.temporal_idx, last_vp9_.temporal_idx);
      return;
    }
    // Temporal shift.
    EXPECT_EQ(params_.num_temporal_layers, 2);
    if (vp9.spatial_idx == params_.num_spatial_layers - 1) {
      // Lower spatial layers should be shifted.
      int expected_tid =
          (!vp9.inter_pic_predicted || vp9.temporal_idx == 1) ? 0 : 1;
      for (int i = 0; i < vp9.spatial_idx; ++i) {
        EXPECT_EQ(last_temporal_idx_by_spatial_idx_.at(i), expected_tid);
      }
    }
    // Same within spatial layer.
    bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
    if (!new_layer) {
      EXPECT_EQ(vp9.temporal_idx, last_vp9_.temporal_idx);
    }
  }

  void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
                                         uint8_t num_layers) const {
    switch (num_layers) {
      case 0:
        VerifyTemporalLayerStructure0(vp9);
        break;
      case 1:
        VerifyTemporalLayerStructure1(vp9);
        break;
      case 2:
        VerifyTemporalLayerStructure2(vp9);
        break;
      case 3:
        VerifyTemporalLayerStructure3(vp9);
        break;
      default:
        RTC_DCHECK_NOTREACHED();
    }
  }

  void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
    EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
    EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx);  // no tid
    // Technically true, but layer indices not available.
    EXPECT_FALSE(vp9.temporal_up_switch);
  }

  void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
    EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
    EXPECT_EQ(0, vp9.temporal_idx);  // 0,0,0,...
  }

  void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
    EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
    EXPECT_GE(vp9.temporal_idx, 0);  // 0,1,0,1,... (tid reset on I-frames).
    EXPECT_LE(vp9.temporal_idx, 1);
    EXPECT_TRUE(vp9.temporal_up_switch);
    // Verify temporal structure for the highest spatial layer (the structure
    // may be shifted for lower spatial layer if temporal shift is configured).
    if (IsHighestSpatialLayer(vp9) && vp9.beginning_of_frame) {
      int expected_tid =
          (!vp9.inter_pic_predicted ||
           last_temporal_idx_by_spatial_idx_.at(vp9.spatial_idx) == 1)
              ? 0
              : 1;
      EXPECT_EQ(vp9.temporal_idx, expected_tid);
    }
  }

  void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
    EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
    EXPECT_GE(vp9.temporal_idx, 0);  // 0,2,1,2,... (tid reset on I-frames).
    EXPECT_LE(vp9.temporal_idx, 2);
    if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
      EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
      EXPECT_TRUE(vp9.temporal_up_switch);
      switch (vp9.temporal_idx) {
        case 0:
          EXPECT_EQ(last_vp9_.temporal_idx, 2);
          break;
        case 1:
          EXPECT_EQ(last_vp9_.temporal_idx, 2);
          break;
        case 2:
          EXPECT_LT(last_vp9_.temporal_idx, 2);
          break;
      }
    }
  }

  void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
    if (vp9.tl0_pic_idx == kNoTl0PicIdx)
      return;

    uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
    if (vp9.temporal_idx == 0)
      ++expected_tl0_idx;
    EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
  }

  bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
    return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
  }

  bool IsHighestSpatialLayer(const RTPVideoHeaderVP9& vp9) const {
    return vp9.spatial_idx == params_.num_spatial_layers - 1 ||
           vp9.spatial_idx == kNoSpatialIdx;
  }

  // Flexible mode (F=1):    Non-flexible mode (F=0):
  //
  //      +-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+
  //      |I|P|L|F|B|E|V|-|     |I|P|L|F|B|E|V|-|
  //      +-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+
  // I:   |M| PICTURE ID  |  I: |M| PICTURE ID  |
  //      +-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+
  // M:   | EXTENDED PID  |  M: | EXTENDED PID  |
  //      +-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+
  // L:   |  T  |U|  S  |D|  L: |  T  |U|  S  |D|
  //      +-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+
  // P,F: | P_DIFF    |X|N|     |   TL0PICIDX   |
  //      +-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+
  // X:   |EXTENDED P_DIFF|  V: | SS  ..        |
  //      +-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+
  // V:   | SS  ..        |
  //      +-+-+-+-+-+-+-+-+
  void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
    EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id);       // M:1
    EXPECT_NE(kNoPictureId, vp9.picture_id);                   // I:1
    EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode);  // F

    if (params_.num_spatial_layers > 1) {
      EXPECT_LT(vp9.spatial_idx, params_.num_spatial_layers);
    } else if (params_.num_temporal_layers > 1) {
      EXPECT_EQ(vp9.spatial_idx, 0);
    } else {
      EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
    }

    if (params_.num_temporal_layers > 1) {
      EXPECT_LT(vp9.temporal_idx, params_.num_temporal_layers);
    } else if (params_.num_spatial_layers > 1) {
      EXPECT_EQ(vp9.temporal_idx, 0);
    } else {
      EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
    }

    if (vp9.ss_data_available)  // V
      VerifySsData(vp9);

    if (frames_sent_ == 0)
      EXPECT_FALSE(vp9.inter_pic_predicted);  // P

    if (!vp9.inter_pic_predicted) {
      if (vp9.temporal_idx == kNoTemporalIdx) {
        EXPECT_FALSE(vp9.temporal_up_switch);
      } else {
        EXPECT_EQ(vp9.temporal_idx, 0);
        EXPECT_TRUE(vp9.temporal_up_switch);
      }
    }
  }

  // Scalability structure (SS).
  //
  //      +-+-+-+-+-+-+-+-+
  // V:   | N_S |Y|G|-|-|-|
  //      +-+-+-+-+-+-+-+-+
  // Y:   |    WIDTH      |  N_S + 1 times
  //      +-+-+-+-+-+-+-+-+
  //      |    HEIGHT     |
  //      +-+-+-+-+-+-+-+-+
  // G:   |      N_G      |
  //      +-+-+-+-+-+-+-+-+
  // N_G: |  T  |U| R |-|-|  N_G times
  //      +-+-+-+-+-+-+-+-+
  //      |    P_DIFF     |  R times
  //      +-+-+-+-+-+-+-+-+
  void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
    EXPECT_TRUE(vp9.ss_data_available);    // V
    EXPECT_EQ(params_.num_spatial_layers,  // N_S + 1
              vp9.num_spatial_layers);
    EXPECT_TRUE(vp9.spatial_layer_resolution_present);  // Y:1

    ScalableVideoController::StreamLayersConfig config = GetScalabilityConfig();
    for (int i = config.num_spatial_layers - 1; i >= 0; --i) {
      double ratio = static_cast<double>(config.scaling_factor_num[i]) /
                     config.scaling_factor_den[i];
      EXPECT_EQ(expected_width_ * ratio, vp9.width[i]);    // WIDTH
      EXPECT_EQ(expected_height_ * ratio, vp9.height[i]);  // HEIGHT
    }
  }

  void CompareConsecutiveFrames(const RtpPacket& rtp_packet,
                                const RTPVideoHeader& video) const {
    const auto& vp9_header =
        absl::get<RTPVideoHeaderVP9>(video.video_type_header);

    const bool new_temporal_unit =
        !last_packet_timestamp_.has_value() ||
        IsNewerTimestamp(rtp_packet.Timestamp(), *last_packet_timestamp_);
    const bool new_frame =
        new_temporal_unit || last_vp9_.spatial_idx != vp9_header.spatial_idx;

    EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
    if (!new_temporal_unit) {
      EXPECT_FALSE(last_packet_marker_);
      EXPECT_EQ(*last_packet_timestamp_, rtp_packet.Timestamp());
      EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
      EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
      VerifySpatialIdxWithinFrame(vp9_header);
      VerifyTemporalIdxWithinFrame(vp9_header);
      return;
    }
    // New frame.
    EXPECT_TRUE(vp9_header.beginning_of_frame);

    // Compare with last packet in previous frame.
    if (frames_sent_ == 0)
      return;
    EXPECT_TRUE(last_vp9_.end_of_frame);
    EXPECT_TRUE(last_packet_marker_);
    EXPECT_TRUE(ContinuousPictureId(vp9_header));
    VerifyTl0Idx(vp9_header);
  }

  ScalableVideoController::StreamLayersConfig GetScalabilityConfig() const {
    absl::optional<ScalabilityMode> scalability_mode =
        ScalabilityModeFromString(params_.scalability_mode);
    EXPECT_TRUE(scalability_mode.has_value());
    absl::optional<ScalableVideoController::StreamLayersConfig> config =
        ScalabilityStructureConfig(*scalability_mode);
    EXPECT_TRUE(config.has_value());
    EXPECT_EQ(config->num_spatial_layers, params_.num_spatial_layers);
    return *config;
  }

  test::FunctionVideoEncoderFactory encoder_factory_;
  const Vp9TestParams params_;
  VideoCodecVP9 vp9_settings_;
  webrtc::VideoEncoderConfig encoder_config_;
  bool last_packet_marker_ = false;
  absl::optional<uint16_t> last_packet_sequence_number_;
  absl::optional<uint32_t> last_packet_timestamp_;
  RTPVideoHeaderVP9 last_vp9_;
  std::map<int, int> last_temporal_idx_by_spatial_idx_;
  Mutex mutex_;
  size_t frames_sent_ = 0;
  int expected_width_ = 0;
  int expected_height_ = 0;
};

class Vp9Test : public VideoSendStreamTest,
                public ::testing::WithParamInterface<ParameterizationType> {
 public:
  Vp9Test()
      : params_(::testing::get<Vp9TestParams>(GetParam())),
        use_scalability_mode_identifier_(::testing::get<bool>(GetParam())) {}

 protected:
  const Vp9TestParams params_;
  const bool use_scalability_mode_identifier_;
};

INSTANTIATE_TEST_SUITE_P(
    ScalabilityMode,
    Vp9Test,
    ::testing::Combine(
        ::testing::ValuesIn<Vp9TestParams>(
            {{"L1T1", 1, 1, InterLayerPredMode::kOn},
             {"L1T2", 1, 2, InterLayerPredMode::kOn},
             {"L1T3", 1, 3, InterLayerPredMode::kOn},
             {"L2T1", 2, 1, InterLayerPredMode::kOn},
             {"L2T1_KEY", 2, 1, InterLayerPredMode::kOnKeyPic},
             {"L2T2", 2, 2, InterLayerPredMode::kOn},
             {"L2T2_KEY", 2, 2, InterLayerPredMode::kOnKeyPic},
             {"L2T3", 2, 3, InterLayerPredMode::kOn},
             {"L2T3_KEY", 2, 3, InterLayerPredMode::kOnKeyPic},
             {"L3T1", 3, 1, InterLayerPredMode::kOn},
             {"L3T1_KEY", 3, 1, InterLayerPredMode::kOnKeyPic},
             {"L3T2", 3, 2, InterLayerPredMode::kOn},
             {"L3T2_KEY", 3, 2, InterLayerPredMode::kOnKeyPic},
             {"L3T3", 3, 3, InterLayerPredMode::kOn},
             {"L3T3_KEY", 3, 3, InterLayerPredMode::kOnKeyPic},
             {"S2T1", 2, 1, InterLayerPredMode::kOff},
             {"S2T2", 2, 2, InterLayerPredMode::kOff},
             {"S2T3", 2, 3, InterLayerPredMode::kOff},
             {"S3T1", 3, 1, InterLayerPredMode::kOff},
             {"S3T2", 3, 2, InterLayerPredMode::kOff},
             {"S3T3", 3, 3, InterLayerPredMode::kOff}}),
        ::testing::Values(false, true)),  // use_scalability_mode_identifier
    ParamInfoToStr);

INSTANTIATE_TEST_SUITE_P(
    ScalabilityModeOn,
    Vp9Test,
    ::testing::Combine(
        ::testing::ValuesIn<Vp9TestParams>(
            {{"L2T1h", 2, 1, InterLayerPredMode::kOn},
             {"L2T2h", 2, 2, InterLayerPredMode::kOn},
             {"L2T3h", 2, 3, InterLayerPredMode::kOn},
             {"L2T2_KEY_SHIFT", 2, 2, InterLayerPredMode::kOnKeyPic},
             {"L3T1h", 3, 1, InterLayerPredMode::kOn},
             {"L3T2h", 3, 2, InterLayerPredMode::kOn},
             {"L3T3h", 3, 3, InterLayerPredMode::kOn},
             {"S2T1h", 2, 1, InterLayerPredMode::kOff},
             {"S2T2h", 2, 2, InterLayerPredMode::kOff},
             {"S2T3h", 2, 3, InterLayerPredMode::kOff},
             {"S3T1h", 3, 1, InterLayerPredMode::kOff},
             {"S3T2h", 3, 2, InterLayerPredMode::kOff},
             {"S3T3h", 3, 3, InterLayerPredMode::kOff}}),
        ::testing::Values(true)),  // use_scalability_mode_identifier
    ParamInfoToStr);

TEST_P(Vp9Test, NonFlexMode) {
  TestVp9NonFlexMode(params_, use_scalability_mode_identifier_);
}

void VideoSendStreamTest::TestVp9NonFlexMode(
    const Vp9TestParams& params,
    bool use_scalability_mode_identifier) {
  static const size_t kNumFramesToSend = 100;
  // Set to < kNumFramesToSend and coprime to length of temporal layer
  // structures to verify temporal id reset on key frame.
  static const int kKeyFrameInterval = 31;

  static const int kWidth = kMinVp9SpatialLayerLongSideLength;
  static const int kHeight = kMinVp9SpatialLayerShortSideLength;
  static const float kGoodBitsPerPixel = 0.1f;
  class NonFlexibleMode : public Vp9HeaderObserver {
   public:
    NonFlexibleMode(const Vp9TestParams& params,
                    bool use_scalability_mode_identifier)
        : Vp9HeaderObserver(params),
          use_scalability_mode_identifier_(use_scalability_mode_identifier),
          l_field_(params.num_temporal_layers > 1 ||
                   params.num_spatial_layers > 1) {}

    void ModifyVideoConfigsHook(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      encoder_config->codec_type = kVideoCodecVP9;
      int bitrate_bps = 0;
      for (int sl_idx = 0; sl_idx < params_.num_spatial_layers; ++sl_idx) {
        const int width = kWidth << sl_idx;
        const int height = kHeight << sl_idx;
        const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
        bitrate_bps += static_cast<int>(width * height * bpp * 30);
      }
      encoder_config->max_bitrate_bps = bitrate_bps * 2;

      encoder_config->frame_drop_enabled = false;

      vp9_settings_.flexibleMode = false;
      vp9_settings_.automaticResizeOn = false;
      vp9_settings_.keyFrameInterval = kKeyFrameInterval;
      if (!use_scalability_mode_identifier_) {
        vp9_settings_.numberOfTemporalLayers = params_.num_temporal_layers;
        vp9_settings_.numberOfSpatialLayers = params_.num_spatial_layers;
        vp9_settings_.interLayerPred = params_.inter_layer_pred;
      } else {
        absl::optional<ScalabilityMode> mode =
            ScalabilityModeFromString(params_.scalability_mode);
        encoder_config->simulcast_layers[0].scalability_mode = mode;
        EXPECT_TRUE(mode.has_value());
      }
    }

    int GetRequiredDivisibility() const {
      ScalableVideoController::StreamLayersConfig config =
          GetScalabilityConfig();
      int required_divisibility = 1;
      for (int sl_idx = 0; sl_idx < config.num_spatial_layers; ++sl_idx) {
        required_divisibility = cricket::LeastCommonMultiple(
            required_divisibility, config.scaling_factor_den[sl_idx]);
      }
      return required_divisibility;
    }

    void ModifyVideoCaptureStartResolution(int* width,
                                           int* height,
                                           int* frame_rate) override {
      expected_width_ = kWidth << (params_.num_spatial_layers - 1);
      expected_height_ = kHeight << (params_.num_spatial_layers - 1);
      *width = expected_width_;
      *height = expected_height_;
      // Top layer may be adjusted to ensure evenly divided layers.
      int divisibility = GetRequiredDivisibility();
      expected_width_ -= (expected_width_ % divisibility);
      expected_height_ -= (expected_height_ % divisibility);
    }

    void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
      bool ss_data_expected = !vp9.inter_pic_predicted &&
                              vp9.beginning_of_frame &&
                              !vp9.inter_layer_predicted;
      EXPECT_EQ(ss_data_expected, vp9.ss_data_available);

      bool is_key_frame = frames_sent_ % kKeyFrameInterval == 0;
      if (params_.num_spatial_layers > 1) {
        switch (params_.inter_layer_pred) {
          case InterLayerPredMode::kOff:
            EXPECT_FALSE(vp9.inter_layer_predicted);
            break;
          case InterLayerPredMode::kOn:
            EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
            break;
          case InterLayerPredMode::kOnKeyPic:
            EXPECT_EQ(is_key_frame && vp9.spatial_idx > 0,
                      vp9.inter_layer_predicted);
            break;
        }
      } else {
        EXPECT_FALSE(vp9.inter_layer_predicted);
      }

      EXPECT_EQ(is_key_frame, !vp9.inter_pic_predicted);

      if (IsNewPictureId(vp9)) {
        if (params_.num_temporal_layers == 1 &&
            params_.num_spatial_layers == 1) {
          EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
        } else {
          EXPECT_EQ(0, vp9.spatial_idx);
        }
        if (params_.num_spatial_layers > 1)
          EXPECT_EQ(params_.num_spatial_layers - 1, last_vp9_.spatial_idx);
      }

      VerifyFixedTemporalLayerStructure(
          vp9, l_field_ ? params_.num_temporal_layers : 0);

      if (frames_sent_ > kNumFramesToSend)
        observation_complete_.Set();
    }
    const bool use_scalability_mode_identifier_;
    const bool l_field_;

   private:
    void ModifySenderBitrateConfig(
        BitrateConstraints* bitrate_config) override {
      const int kBitrateBps = 800000;
      bitrate_config->min_bitrate_bps = kBitrateBps;
      bitrate_config->start_bitrate_bps = kBitrateBps;
    }
  } test(params, use_scalability_mode_identifier);

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
  static const size_t kNumFramesToSend = 50;
  static const int kWidth = 4;
  static const int kHeight = 4;
  class NonFlexibleModeResolution : public Vp9HeaderObserver {
   public:
    explicit NonFlexibleModeResolution(const Vp9TestParams& params)
        : Vp9HeaderObserver(params) {}

   private:
    void ModifyVideoConfigsHook(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      encoder_config->codec_type = kVideoCodecVP9;
      vp9_settings_.flexibleMode = false;
      vp9_settings_.numberOfTemporalLayers = params_.num_temporal_layers;
      vp9_settings_.numberOfSpatialLayers = params_.num_spatial_layers;
      vp9_settings_.interLayerPred = params_.inter_layer_pred;
    }

    void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
      if (frames_sent_ > kNumFramesToSend)
        observation_complete_.Set();
    }

    void ModifyVideoCaptureStartResolution(int* width,
                                           int* height,
                                           int* frame_rate) override {
      expected_width_ = kWidth;
      expected_height_ = kHeight;
      *width = kWidth;
      *height = kHeight;
    }
  };

  Vp9TestParams params{"L1T1", 1, 1, InterLayerPredMode::kOn};
  NonFlexibleModeResolution test(params);

  RunBaseTest(&test);
}

#if defined(WEBRTC_ANDROID)
// Crashes on Android; bugs.webrtc.org/7401
#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
#else
// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
// the test after webrtc:9270 is implemented.
#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
#endif
TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
  class FlexibleMode : public Vp9HeaderObserver {
   public:
    explicit FlexibleMode(const Vp9TestParams& params)
        : Vp9HeaderObserver(params) {}

   private:
    void ModifyVideoConfigsHook(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      encoder_config->codec_type = kVideoCodecVP9;
      encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
      vp9_settings_.flexibleMode = true;
      vp9_settings_.numberOfTemporalLayers = params_.num_temporal_layers;
      vp9_settings_.numberOfSpatialLayers = params_.num_spatial_layers;
      vp9_settings_.interLayerPred = params_.inter_layer_pred;
    }

    void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
      EXPECT_TRUE(vp9_header.flexible_mode);
      EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
      if (vp9_header.inter_pic_predicted) {
        EXPECT_GT(vp9_header.num_ref_pics, 0u);
        observation_complete_.Set();
      }
    }
  };

  Vp9TestParams params{"L2T1", 2, 1, InterLayerPredMode::kOn};
  FlexibleMode test(params);

  RunBaseTest(&test);
}
#endif  // defined(RTC_ENABLE_VP9)

void VideoSendStreamTest::TestRequestSourceRotateVideo(
    bool support_orientation_ext) {
  CreateSenderCall();

  test::NullTransport transport;
  CreateSendConfig(1, 0, 0, &transport);
  GetVideoSendConfig()->rtp.extensions.clear();
  if (support_orientation_ext) {
    GetVideoSendConfig()->rtp.extensions.push_back(
        RtpExtension(RtpExtension::kVideoRotationUri, 1));
  }

  CreateVideoStreams();
  test::FrameForwarder forwarder;
  GetVideoSendStream()->SetSource(&forwarder,
                                  DegradationPreference::MAINTAIN_FRAMERATE);

  EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
              support_orientation_ext);

  DestroyStreams();
}

TEST_F(VideoSendStreamTest,
       RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
  TestRequestSourceRotateVideo(false);
}

TEST_F(VideoSendStreamTest,
       DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
  TestRequestSourceRotateVideo(true);
}

TEST_F(VideoSendStreamTest, EncoderConfigMaxFramerateReportedToSource) {
  static const int kMaxFps = 22;
  class FpsObserver : public test::SendTest,
                      public test::FrameGeneratorCapturer::SinkWantsObserver {
   public:
    FpsObserver() : SendTest(test::VideoTestConstants::kDefaultTimeout) {}

    void OnFrameGeneratorCapturerCreated(
        test::FrameGeneratorCapturer* frame_generator_capturer) override {
      frame_generator_capturer->SetSinkWantsObserver(this);
    }

    void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
                            const rtc::VideoSinkWants& wants) override {
      if (wants.max_framerate_fps == kMaxFps)
        observation_complete_.Set();
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      encoder_config->simulcast_layers[0].max_framerate = kMaxFps;
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out while waiting for fps to be reported.";
    }
  } test;

  RunBaseTest(&test);
}

// This test verifies that overhead is removed from the bandwidth estimate by
// testing that the maximum possible target payload rate is smaller than the
// maximum bandwidth estimate by the overhead rate.
TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
  class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
                                          public test::FakeEncoder {
   public:
    explicit RemoveOverheadFromBandwidthTest(const Environment& env,
                                             TaskQueueBase* task_queue)
        : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
          FakeEncoder(env),
          task_queue_(task_queue),
          encoder_factory_(this),
          call_(nullptr),
          max_bitrate_bps_(0),
          first_packet_sent_(false) {}

    void SetRates(const RateControlParameters& parameters) override {
      MutexLock lock(&mutex_);
      // Wait for the first sent packet so that videosendstream knows
      // rtp_overhead.
      if (first_packet_sent_) {
        max_bitrate_bps_ = parameters.bitrate.get_sum_bps();
        bitrate_changed_event_.Set();
      }
      return FakeEncoder::SetRates(parameters);
    }

    void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
      call_ = sender_call;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      send_config->rtp.max_packet_size = 1200;
      send_config->encoder_settings.encoder_factory = &encoder_factory_;
      EXPECT_FALSE(send_config->rtp.extensions.empty());
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      MutexLock lock(&mutex_);
      first_packet_sent_ = true;
      return SEND_PACKET;
    }

    void PerformTest() override {
      BitrateConstraints bitrate_config;
      constexpr int kStartBitrateBps = 60000;
      constexpr int kMaxBitrateBps = 60000;
      constexpr int kMinBitrateBps = 10000;
      bitrate_config.start_bitrate_bps = kStartBitrateBps;
      bitrate_config.max_bitrate_bps = kMaxBitrateBps;
      bitrate_config.min_bitrate_bps = kMinBitrateBps;
      SendTask(task_queue_, [this, &bitrate_config]() {
        call_->GetTransportControllerSend()->SetSdpBitrateParameters(
            bitrate_config);
        call_->GetTransportControllerSend()->OnTransportOverheadChanged(40);
      });

      // At a bitrate of 60kbps with a packet size of 1200B video and an
      // overhead of 40B per packet video produces 2240bps overhead.
      // So the encoder BW should be set to 57760bps.
      EXPECT_TRUE(bitrate_changed_event_.Wait(
          test::VideoTestConstants::kDefaultTimeout));
      {
        MutexLock lock(&mutex_);
        EXPECT_LE(max_bitrate_bps_, 57760u);
      }
    }

   private:
    TaskQueueBase* const task_queue_;
    test::VideoEncoderProxyFactory encoder_factory_;
    Call* call_;
    Mutex mutex_;
    uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&mutex_);
    bool first_packet_sent_ RTC_GUARDED_BY(&mutex_);
    rtc::Event bitrate_changed_event_;
  } test(env(), task_queue());
  RunBaseTest(&test);
}

class PacingFactorObserver : public test::SendTest {
 public:
  PacingFactorObserver(bool configure_send_side,
                       absl::optional<float> expected_pacing_factor)
      : test::SendTest(test::VideoTestConstants::kDefaultTimeout),
        configure_send_side_(configure_send_side),
        expected_pacing_factor_(expected_pacing_factor) {}

  void ModifyVideoConfigs(
      VideoSendStream::Config* send_config,
      std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
      VideoEncoderConfig* encoder_config) override {
    // Check if send-side bwe extension is already present, and remove it if
    // it is not desired.
    bool has_send_side = false;
    for (auto it = send_config->rtp.extensions.begin();
         it != send_config->rtp.extensions.end(); ++it) {
      if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
        if (configure_send_side_) {
          has_send_side = true;
        } else {
          send_config->rtp.extensions.erase(it);
        }
        break;
      }
    }

    if (configure_send_side_ && !has_send_side) {
      rtc::UniqueNumberGenerator<int> unique_id_generator;
      unique_id_generator.AddKnownId(0);  // First valid RTP extension ID is 1.
      for (const RtpExtension& extension : send_config->rtp.extensions) {
        unique_id_generator.AddKnownId(extension.id);
      }
      // Want send side, not present by default, so add it.
      send_config->rtp.extensions.emplace_back(
          RtpExtension::kTransportSequenceNumberUri,
          unique_id_generator.GenerateNumber());
    }

    // ALR only enabled for screenshare.
    encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
  }

  void OnVideoStreamsCreated(VideoSendStream* send_stream,
                             const std::vector<VideoReceiveStreamInterface*>&
                                 receive_streams) override {
    auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
    // Video streams created, check that pacing factor is correctly configured.
    EXPECT_EQ(expected_pacing_factor_,
              internal_send_peer.GetPacingFactorOverride());
    observation_complete_.Set();
  }

  void PerformTest() override {
    EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
  }

 private:
  const bool configure_send_side_;
  const absl::optional<float> expected_pacing_factor_;
};

std::string GetAlrProbingExperimentString() {
  return std::string(
             AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
         "/1.0,2875,80,40,-60,3/";
}
const float kAlrProbingExperimentPaceMultiplier = 1.0f;

TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
  test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
  // Send-side bwe on, use pacing factor from `kAlrProbingExperiment` above.
  PacingFactorObserver test_with_send_side(true,
                                           kAlrProbingExperimentPaceMultiplier);
  RunBaseTest(&test_with_send_side);
}

TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
  test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
  // Send-side bwe off, use configuration should not be overridden.
  PacingFactorObserver test_without_send_side(false, absl::nullopt);
  RunBaseTest(&test_without_send_side);
}

// Test class takes as argument a function pointer to reset the send
// stream and call OnVideoStreamsCreated. This is necessary since you cannot
// change the content type of a VideoSendStream, you need to recreate it.
// Stopping and recreating the stream can only be done on the main thread and in
// the context of VideoSendStreamTest (not BaseTest). The test switches from
// realtime to screenshare and back.
template <typename T>
class ContentSwitchTest : public test::SendTest {
 public:
  enum class StreamState {
    kBeforeSwitch = 0,
    kInScreenshare = 1,
    kAfterSwitchBack = 2,
  };
  static const uint32_t kMinPacketsToSend = 50;

  explicit ContentSwitchTest(T* stream_reset_fun, TaskQueueBase* task_queue)
      : SendTest(test::VideoTestConstants::kDefaultTimeout),
        call_(nullptr),
        state_(StreamState::kBeforeSwitch),
        send_stream_(nullptr),
        send_stream_config_(nullptr),
        packets_sent_(0),
        stream_resetter_(stream_reset_fun),
        task_queue_(task_queue) {
    RTC_DCHECK(stream_resetter_);
  }

  void OnVideoStreamsCreated(VideoSendStream* send_stream,
                             const std::vector<VideoReceiveStreamInterface*>&
                                 receive_streams) override {
    MutexLock lock(&mutex_);
    send_stream_ = send_stream;
  }

  void ModifyVideoConfigs(
      VideoSendStream::Config* send_config,
      std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
      VideoEncoderConfig* encoder_config) override {
    RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
    encoder_config->min_transmit_bitrate_bps = 0;
    encoder_config->content_type =
        VideoEncoderConfig::ContentType::kRealtimeVideo;
    send_stream_config_ = send_config->Copy();
    encoder_config_ = encoder_config->Copy();
  }

  void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
    call_ = sender_call;
  }

  void OnStreamsStopped() override {
    MutexLock lock(&mutex_);
    done_ = true;
  }

  Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
    task_queue_->PostTask([this]() {
      MutexLock lock(&mutex_);
      if (done_)
        return;

      auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
      float pacing_factor =
          internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
      float expected_pacing_factor = 1.1;  // Strict pacing factor.
      VideoSendStream::Stats stats = send_stream_->GetStats();
      if (stats.content_type == webrtc::VideoContentType::SCREENSHARE) {
        expected_pacing_factor = 1.0f;  // Currently used pacing factor in ALR.
      }

      EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);

      // Wait until at least kMinPacketsToSend packets to be sent, so that
      // some frames would be encoded.
      if (++packets_sent_ < kMinPacketsToSend)
        return;

      if (state_ != StreamState::kAfterSwitchBack) {
        // We've sent kMinPacketsToSend packets, switch the content type and
        // move move to the next state. Note that we need to recreate the stream
        // if changing content type.
        packets_sent_ = 0;
        if (encoder_config_.content_type ==
            VideoEncoderConfig::ContentType::kRealtimeVideo) {
          encoder_config_.content_type =
              VideoEncoderConfig::ContentType::kScreen;
        } else {
          encoder_config_.content_type =
              VideoEncoderConfig::ContentType::kRealtimeVideo;
        }
        switch (state_) {
          case StreamState::kBeforeSwitch:
            state_ = StreamState::kInScreenshare;
            break;
          case StreamState::kInScreenshare:
            state_ = StreamState::kAfterSwitchBack;
            break;
          case StreamState::kAfterSwitchBack:
            RTC_DCHECK_NOTREACHED();
            break;
        }
        content_switch_event_.Set();
        return;
      }
      observation_complete_.Set();
    });

    return SEND_PACKET;
  }

  void PerformTest() override {
    while (GetStreamState() != StreamState::kAfterSwitchBack) {
      ASSERT_TRUE(content_switch_event_.Wait(
          test::VideoTestConstants::kDefaultTimeout));
      (*stream_resetter_)(send_stream_config_, encoder_config_, this);
    }

    ASSERT_TRUE(Wait())
        << "Timed out waiting for a frame sent after switch back";
  }

 private:
  StreamState GetStreamState() {
    MutexLock lock(&mutex_);
    return state_;
  }

  Mutex mutex_;
  rtc::Event content_switch_event_;
  Call* call_;
  bool done_ RTC_GUARDED_BY(mutex_) = false;
  StreamState state_ RTC_GUARDED_BY(mutex_);
  VideoSendStream* send_stream_ RTC_GUARDED_BY(mutex_);
  VideoSendStream::Config send_stream_config_;
  VideoEncoderConfig encoder_config_;
  uint32_t packets_sent_ RTC_GUARDED_BY(mutex_);
  T* stream_resetter_;
  TaskQueueBase* task_queue_;
};

TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
  auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
                          const VideoEncoderConfig& encoder_config,
                          test::BaseTest* test) {
    SendTask(task_queue(), [this, &send_stream_config, &encoder_config,
                            &test]() {
      Stop();
      DestroyVideoSendStreams();
      SetVideoSendConfig(send_stream_config);
      SetVideoEncoderConfig(encoder_config);
      CreateVideoSendStreams();
      SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
      test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
      Start();
    });
  };
  ContentSwitchTest<decltype(reset_fun)> test(&reset_fun, task_queue());
  RunBaseTest(&test);
}

void VideoSendStreamTest::TestTemporalLayers(
    VideoEncoderFactory* encoder_factory,
    const std::string& payload_name,
    const std::vector<int>& num_temporal_layers,
    const std::vector<ScalabilityMode>& scalability_mode) {
  static constexpr int kMaxBitrateBps = 1000000;
  static constexpr int kMinFramesToObservePerStream = 8;

  class TemporalLayerObserver
      : public test::EndToEndTest,
        public test::FrameGeneratorCapturer::SinkWantsObserver {
   public:
    TemporalLayerObserver(VideoEncoderFactory* encoder_factory,
                          const std::string& payload_name,
                          const std::vector<int>& num_temporal_layers,
                          const std::vector<ScalabilityMode>& scalability_mode)
        : EndToEndTest(test::VideoTestConstants::kDefaultTimeout),
          encoder_factory_(encoder_factory),
          payload_name_(payload_name),
          num_temporal_layers_(num_temporal_layers),
          scalability_mode_(scalability_mode),
          depacketizer_(CreateVideoRtpDepacketizer(
              PayloadStringToCodecType(payload_name))) {}

   private:
    void OnFrameGeneratorCapturerCreated(
        test::FrameGeneratorCapturer* frame_generator_capturer) override {
      frame_generator_capturer->ChangeResolution(640, 360);
    }

    void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
                            const rtc::VideoSinkWants& wants) override {}

    void ModifySenderBitrateConfig(
        BitrateConstraints* bitrate_config) override {
      bitrate_config->start_bitrate_bps = kMaxBitrateBps / 2;
    }

    size_t GetNumVideoStreams() const override {
      if (scalability_mode_.empty()) {
        return num_temporal_layers_.size();
      } else {
        return scalability_mode_.size();
      }
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      webrtc::VideoEncoder::EncoderInfo encoder_info;
      send_config->encoder_settings.encoder_factory = encoder_factory_;
      send_config->rtp.payload_name = payload_name_;
      send_config->rtp.payload_type =
          test::VideoTestConstants::kVideoSendPayloadType;
      encoder_config->video_format.name = payload_name_;
      encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
      encoder_config->video_stream_factory =
          rtc::make_ref_counted<cricket::EncoderStreamFactory>(
              payload_name_, /*max_qp=*/56, /*is_screenshare=*/false,
              /*conference_mode=*/false, encoder_info);
      encoder_config->max_bitrate_bps = kMaxBitrateBps;
      if (absl::EqualsIgnoreCase(payload_name_, "VP9")) {
        encoder_config->encoder_specific_settings = rtc::make_ref_counted<
            VideoEncoderConfig::Vp9EncoderSpecificSettings>(
            VideoEncoder::GetDefaultVp9Settings());
      }
      if (scalability_mode_.empty()) {
        for (size_t i = 0; i < num_temporal_layers_.size(); ++i) {
          VideoStream& stream = encoder_config->simulcast_layers[i];
          stream.num_temporal_layers = num_temporal_layers_[i];
          configured_num_temporal_layers_[send_config->rtp.ssrcs[i]] =
              num_temporal_layers_[i];
        }
      } else {
        for (size_t i = 0; i < scalability_mode_.size(); ++i) {
          VideoStream& stream = encoder_config->simulcast_layers[i];
          stream.scalability_mode = scalability_mode_[i];

          configured_num_temporal_layers_[send_config->rtp.ssrcs[i]] =
              ScalabilityModeToNumTemporalLayers(scalability_mode_[i]);
        }
      }
    }

    struct ParsedPacket {
      uint32_t timestamp;
      uint32_t ssrc;
      int temporal_idx;
    };

    bool ParsePayload(rtc::ArrayView<const uint8_t> packet,
                      ParsedPacket& parsed) const {
      RtpPacket rtp_packet;
      EXPECT_TRUE(rtp_packet.Parse(packet));

      if (rtp_packet.payload_size() == 0) {
        return false;  // Padding packet.
      }
      parsed.timestamp = rtp_packet.Timestamp();
      parsed.ssrc = rtp_packet.Ssrc();

      absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
          depacketizer_->Parse(rtp_packet.PayloadBuffer());
      EXPECT_TRUE(parsed_payload);

      if (const auto* vp8_header = absl::get_if<RTPVideoHeaderVP8>(
              &parsed_payload->video_header.video_type_header)) {
        parsed.temporal_idx = vp8_header->temporalIdx;
      } else if (const auto* vp9_header = absl::get_if<RTPVideoHeaderVP9>(
                     &parsed_payload->video_header.video_type_header)) {
        parsed.temporal_idx = vp9_header->temporal_idx;
      } else {
        RTC_DCHECK_NOTREACHED();
      }
      return true;
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      ParsedPacket parsed;
      if (!ParsePayload(packet, parsed))
        return SEND_PACKET;

      uint32_t ssrc = parsed.ssrc;
      int temporal_idx =
          parsed.temporal_idx == kNoTemporalIdx ? 0 : parsed.temporal_idx;
      max_observed_tl_idxs_[ssrc] =
          std::max(temporal_idx, max_observed_tl_idxs_[ssrc]);

      if (last_observed_packet_.count(ssrc) == 0 ||
          parsed.timestamp != last_observed_packet_[ssrc].timestamp) {
        num_observed_frames_[ssrc]++;
      }
      last_observed_packet_[ssrc] = parsed;

      if (HighestTemporalLayerSentPerStream())
        observation_complete_.Set();

      return SEND_PACKET;
    }

    bool HighestTemporalLayerSentPerStream() const {
      if (num_observed_frames_.size() !=
          configured_num_temporal_layers_.size()) {
        return false;
      }
      for (const auto& num_frames : num_observed_frames_) {
        if (num_frames.second < kMinFramesToObservePerStream) {
          return false;
        }
      }
      if (max_observed_tl_idxs_.size() !=
          configured_num_temporal_layers_.size()) {
        return false;
      }
      for (const auto& max_tl_idx : max_observed_tl_idxs_) {
        uint32_t ssrc = max_tl_idx.first;
        int configured_num_tls =
            configured_num_temporal_layers_.find(ssrc)->second;
        if (max_tl_idx.second != configured_num_tls - 1)
          return false;
      }
      return true;
    }

    void PerformTest() override { EXPECT_TRUE(Wait()); }

    VideoEncoderFactory* const encoder_factory_;
    const std::string payload_name_;
    const std::vector<int> num_temporal_layers_;
    const std::vector<ScalabilityMode> scalability_mode_;
    const std::unique_ptr<VideoRtpDepacketizer> depacketizer_;
    // Mapped by SSRC.
    std::map<uint32_t, int> configured_num_temporal_layers_;
    std::map<uint32_t, int> max_observed_tl_idxs_;
    std::map<uint32_t, int> num_observed_frames_;
    std::map<uint32_t, ParsedPacket> last_observed_packet_;
  } test(encoder_factory, payload_name, num_temporal_layers, scalability_mode);

  RunBaseTest(&test);
}

TEST_F(VideoSendStreamTest, TestTemporalLayersVp8) {
  InternalEncoderFactory internal_encoder_factory;
  test::FunctionVideoEncoderFactory encoder_factory(
      [&internal_encoder_factory](const Environment& env,
                                  const SdpVideoFormat& format) {
        return std::make_unique<SimulcastEncoderAdapter>(
            env, &internal_encoder_factory, nullptr, SdpVideoFormat::VP8());
      });

  TestTemporalLayers(&encoder_factory, "VP8",
                     /*num_temporal_layers=*/{2},
                     /*scalability_mode=*/{});
}

TEST_F(VideoSendStreamTest, TestTemporalLayersVp8Simulcast) {
  InternalEncoderFactory internal_encoder_factory;
  test::FunctionVideoEncoderFactory encoder_factory(
      [&internal_encoder_factory](const Environment& env,
                                  const SdpVideoFormat& format) {
        return std::make_unique<SimulcastEncoderAdapter>(
            env, &internal_encoder_factory, nullptr, SdpVideoFormat::VP8());
      });

  TestTemporalLayers(&encoder_factory, "VP8",
                     /*num_temporal_layers=*/{2, 2},
                     /*scalability_mode=*/{});
}

TEST_F(VideoSendStreamTest, TestTemporalLayersVp8SimulcastWithDifferentNumTls) {
  InternalEncoderFactory internal_encoder_factory;
  test::FunctionVideoEncoderFactory encoder_factory(
      [&internal_encoder_factory](const Environment& env,
                                  const SdpVideoFormat& format) {
        return std::make_unique<SimulcastEncoderAdapter>(
            env, &internal_encoder_factory, nullptr, SdpVideoFormat::VP8());
      });

  TestTemporalLayers(&encoder_factory, "VP8",
                     /*num_temporal_layers=*/{3, 1},
                     /*scalability_mode=*/{});
}

TEST_F(VideoSendStreamTest, TestTemporalLayersVp8SimulcastWithoutSimAdapter) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });

  TestTemporalLayers(&encoder_factory, "VP8",
                     /*num_temporal_layers=*/{2, 2},
                     /*scalability_mode=*/{});
}

TEST_F(VideoSendStreamTest, TestScalabilityModeVp8L1T2) {
  InternalEncoderFactory internal_encoder_factory;
  test::FunctionVideoEncoderFactory encoder_factory(
      [&internal_encoder_factory](const Environment& env,
                                  const SdpVideoFormat& format) {
        return std::make_unique<SimulcastEncoderAdapter>(
            env, &internal_encoder_factory, nullptr, SdpVideoFormat::VP8());
      });

  TestTemporalLayers(&encoder_factory, "VP8",
                     /*num_temporal_layers=*/{}, {ScalabilityMode::kL1T2});
}

TEST_F(VideoSendStreamTest, TestScalabilityModeVp8Simulcast) {
  InternalEncoderFactory internal_encoder_factory;
  test::FunctionVideoEncoderFactory encoder_factory(
      [&internal_encoder_factory](const Environment& env,
                                  const SdpVideoFormat& format) {
        return std::make_unique<SimulcastEncoderAdapter>(
            env, &internal_encoder_factory, nullptr, SdpVideoFormat::VP8());
      });

  TestTemporalLayers(&encoder_factory, "VP8",
                     /*num_temporal_layers=*/{},
                     {ScalabilityMode::kL1T2, ScalabilityMode::kL1T2});
}

TEST_F(VideoSendStreamTest, TestScalabilityModeVp8SimulcastWithDifferentMode) {
  InternalEncoderFactory internal_encoder_factory;
  test::FunctionVideoEncoderFactory encoder_factory(
      [&internal_encoder_factory](const Environment& env,
                                  const SdpVideoFormat& format) {
        return std::make_unique<SimulcastEncoderAdapter>(
            env, &internal_encoder_factory, nullptr, SdpVideoFormat::VP8());
      });

  TestTemporalLayers(&encoder_factory, "VP8",
                     /*num_temporal_layers=*/{},
                     {ScalabilityMode::kL1T3, ScalabilityMode::kL1T1});
}

TEST_F(VideoSendStreamTest, TestScalabilityModeVp8SimulcastWithoutSimAdapter) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp8Encoder(env);
      });

  TestTemporalLayers(&encoder_factory, "VP8",
                     /*num_temporal_layers=*/{},
                     {ScalabilityMode::kL1T2, ScalabilityMode::kL1T2});
}

TEST_F(VideoSendStreamTest, TestTemporalLayersVp9) {
  test::FunctionVideoEncoderFactory encoder_factory(
      [](const Environment& env, const SdpVideoFormat& format) {
        return CreateVp9Encoder(env);
      });

  TestTemporalLayers(&encoder_factory, "VP9",
                     /*num_temporal_layers=*/{2},
                     /*scalability_mode=*/{});
}

}  // namespace webrtc
