/*
 *  Copyright (c) 2004 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 "media/engine/webrtc_video_engine.h"

#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/memory/memory.h"
#include "absl/strings/match.h"
#include "api/rtc_event_log/rtc_event_log.h"
#include "api/rtp_parameters.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "api/test/mock_video_bitrate_allocator.h"
#include "api/test/mock_video_bitrate_allocator_factory.h"
#include "api/test/mock_video_decoder_factory.h"
#include "api/test/mock_video_encoder_factory.h"
#include "api/test/video/function_video_decoder_factory.h"
#include "api/transport/field_trial_based_config.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/builtin_video_bitrate_allocator_factory.h"
#include "api/video/i420_buffer.h"
#include "api/video/video_bitrate_allocation.h"
#include "api/video_codecs/builtin_video_decoder_factory.h"
#include "api/video_codecs/builtin_video_encoder_factory.h"
#include "api/video_codecs/h264_profile_level_id.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "call/flexfec_receive_stream.h"
#include "media/base/fake_frame_source.h"
#include "media/base/fake_network_interface.h"
#include "media/base/fake_video_renderer.h"
#include "media/base/media_constants.h"
#include "media/base/rtp_utils.h"
#include "media/base/test_utils.h"
#include "media/engine/fake_webrtc_call.h"
#include "media/engine/fake_webrtc_video_engine.h"
#include "media/engine/simulcast.h"
#include "media/engine/webrtc_voice_engine.h"
#include "modules/rtp_rtcp/source/rtp_packet.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/event.h"
#include "rtc_base/experiments/min_video_bitrate_experiment.h"
#include "rtc_base/fake_clock.h"
#include "rtc_base/gunit.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/time_utils.h"
#include "test/fake_decoder.h"
#include "test/frame_forwarder.h"
#include "test/gmock.h"
#include "test/scoped_key_value_config.h"
#include "test/time_controller/simulated_time_controller.h"

using ::testing::_;
using ::testing::Contains;
using ::testing::Each;
using ::testing::ElementsAreArray;
using ::testing::Eq;
using ::testing::Field;
using ::testing::IsEmpty;
using ::testing::Pair;
using ::testing::Return;
using ::testing::SizeIs;
using ::testing::StrNe;
using ::testing::Values;
using ::webrtc::BitrateConstraints;
using ::webrtc::RtpExtension;
using ::webrtc::RtpPacket;

namespace {
static const int kDefaultQpMax = 56;

static const uint8_t kRedRtxPayloadType = 125;

static const uint32_t kTimeout = 5000U;
static const uint32_t kSsrc = 1234u;
static const uint32_t kSsrcs4[] = {1, 2, 3, 4};
static const int kVideoWidth = 640;
static const int kVideoHeight = 360;
static const int kFramerate = 30;

static const uint32_t kSsrcs1[] = {1};
static const uint32_t kSsrcs3[] = {1, 2, 3};
static const uint32_t kRtxSsrcs1[] = {4};
static const uint32_t kFlexfecSsrc = 5;
static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
static const int64_t kUnsignalledReceiveStreamCooldownMs = 500;

constexpr uint32_t kRtpHeaderSize = 12;

static const char kUnsupportedExtensionName[] =
    "urn:ietf:params:rtp-hdrext:unsupported";

cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
  codec.feedback_params = cricket::FeedbackParams();
  return std::move(codec);
}

void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec,
                                         bool lntf_expected) {
  EXPECT_EQ(lntf_expected,
            codec.HasFeedbackParam(cricket::FeedbackParam(
                cricket::kRtcpFbParamLntf, cricket::kParamValueEmpty)));
  EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
  EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
  EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
  EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
  EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
      cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
}

// Return true if any codec in `codecs` is an RTX codec with associated payload
// type `payload_type`.
bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
                 int payload_type) {
  for (const cricket::VideoCodec& codec : codecs) {
    int associated_payload_type;
    if (absl::EqualsIgnoreCase(codec.name.c_str(), "rtx") &&
        codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
                       &associated_payload_type) &&
        associated_payload_type == payload_type) {
      return true;
    }
  }
  return false;
}

// Return true if any codec in `codecs` is an RTX codec, independent of
// payload type.
bool HasAnyRtxCodec(const std::vector<cricket::VideoCodec>& codecs) {
  for (const cricket::VideoCodec& codec : codecs) {
    if (absl::EqualsIgnoreCase(codec.name.c_str(), "rtx")) {
      return true;
    }
  }
  return false;
}

// TODO(nisse): Duplicated in call.cc.
const int* FindKeyByValue(const std::map<int, int>& m, int v) {
  for (const auto& kv : m) {
    if (kv.second == v)
      return &kv.first;
  }
  return nullptr;
}

bool HasRtxReceiveAssociation(
    const webrtc::VideoReceiveStreamInterface::Config& config,
    int payload_type) {
  return FindKeyByValue(config.rtp.rtx_associated_payload_types,
                        payload_type) != nullptr;
}

// Check that there's an Rtx payload type for each decoder.
bool VerifyRtxReceiveAssociations(
    const webrtc::VideoReceiveStreamInterface::Config& config) {
  for (const auto& decoder : config.decoders) {
    if (!HasRtxReceiveAssociation(config, decoder.payload_type))
      return false;
  }
  return true;
}

rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
    int width,
    int height) {
  rtc::scoped_refptr<webrtc::I420Buffer> buffer =
      webrtc::I420Buffer::Create(width, height);
  webrtc::I420Buffer::SetBlack(buffer.get());
  return buffer;
}

void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
                                 const std::map<int, int>& rtx_types) {
  std::map<int, int>::const_iterator it;
  it = rtx_types.find(config.rtp.payload_type);
  EXPECT_TRUE(it != rtx_types.end() &&
              it->second == config.rtp.rtx.payload_type);

  if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
    it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
    EXPECT_TRUE(it != rtx_types.end() &&
                it->second == config.rtp.ulpfec.red_rtx_payload_type);
  }
}

cricket::MediaConfig GetMediaConfig() {
  cricket::MediaConfig media_config;
  media_config.video.enable_cpu_adaptation = false;
  return media_config;
}

// Values from GetMaxDefaultVideoBitrateKbps in webrtcvideoengine.cc.
int GetMaxDefaultBitrateBps(size_t width, size_t height) {
  if (width * height <= 320 * 240) {
    return 600000;
  } else if (width * height <= 640 * 480) {
    return 1700000;
  } else if (width * height <= 960 * 540) {
    return 2000000;
  } else {
    return 2500000;
  }
}

class MockVideoSource : public rtc::VideoSourceInterface<webrtc::VideoFrame> {
 public:
  MOCK_METHOD(void,
              AddOrUpdateSink,
              (rtc::VideoSinkInterface<webrtc::VideoFrame> * sink,
               const rtc::VideoSinkWants& wants),
              (override));
  MOCK_METHOD(void,
              RemoveSink,
              (rtc::VideoSinkInterface<webrtc::VideoFrame> * sink),
              (override));
};

}  // namespace

#define EXPECT_FRAME_WAIT(c, w, h, t)                        \
  EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
  EXPECT_EQ((w), renderer_.width());                         \
  EXPECT_EQ((h), renderer_.height());

#define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t)   \
  EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
  EXPECT_EQ((w), (r).width());                         \
  EXPECT_EQ((h), (r).height());

namespace cricket {
class WebRtcVideoEngineTest : public ::testing::Test {
 public:
  WebRtcVideoEngineTest() : WebRtcVideoEngineTest("") {}
  explicit WebRtcVideoEngineTest(const std::string& field_trials)
      : field_trials_(field_trials),
        time_controller_(webrtc::Timestamp::Millis(4711)),
        task_queue_factory_(time_controller_.CreateTaskQueueFactory()),
        call_(webrtc::Call::Create([&] {
          webrtc::Call::Config call_config(&event_log_);
          call_config.task_queue_factory = task_queue_factory_.get();
          call_config.trials = &field_trials_;
          return call_config;
        }())),
        encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
        decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
        video_bitrate_allocator_factory_(
            webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
        engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
                    encoder_factory_),
                std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
                    decoder_factory_),
                field_trials_) {}

 protected:
  void AssignDefaultAptRtxTypes();
  void AssignDefaultCodec();

  // Find the index of the codec in the engine with the given name. The codec
  // must be present.
  size_t GetEngineCodecIndex(const std::string& name) const;

  // Find the codec in the engine with the given name. The codec must be
  // present.
  cricket::VideoCodec GetEngineCodec(const std::string& name) const;
  void AddSupportedVideoCodecType(const std::string& name);
  VideoMediaChannel* SetSendParamsWithAllSupportedCodecs();

  VideoMediaChannel* SetRecvParamsWithSupportedCodecs(
      const std::vector<VideoCodec>& codecs);

  void ExpectRtpCapabilitySupport(const char* uri, bool supported) const;

  webrtc::test::ScopedKeyValueConfig field_trials_;
  webrtc::GlobalSimulatedTimeController time_controller_;
  webrtc::RtcEventLogNull event_log_;
  std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
  // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly
  // initialized when the constructor is called.
  std::unique_ptr<webrtc::Call> call_;
  cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
  cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
  std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
      video_bitrate_allocator_factory_;
  WebRtcVideoEngine engine_;
  VideoCodec default_codec_;
  std::map<int, int> default_apt_rtx_types_;
};

TEST_F(WebRtcVideoEngineTest, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
  encoder_factory_->AddSupportedVideoCodecType("VP8");
  AssignDefaultCodec();

  std::vector<VideoCodec> engine_codecs = engine_.send_codecs();
  for (size_t i = 0; i < engine_codecs.size(); ++i) {
    if (engine_codecs[i].name != kRtxCodecName)
      continue;
    int associated_payload_type;
    EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
                                          &associated_payload_type));
    EXPECT_EQ(default_codec_.id, associated_payload_type);
    return;
  }
  FAIL() << "No RTX codec found among default codecs.";
}

TEST_F(WebRtcVideoEngineTest, SupportsTimestampOffsetHeaderExtension) {
  ExpectRtpCapabilitySupport(RtpExtension::kTimestampOffsetUri, true);
}

TEST_F(WebRtcVideoEngineTest, SupportsAbsoluteSenderTimeHeaderExtension) {
  ExpectRtpCapabilitySupport(RtpExtension::kAbsSendTimeUri, true);
}

TEST_F(WebRtcVideoEngineTest, SupportsTransportSequenceNumberHeaderExtension) {
  ExpectRtpCapabilitySupport(RtpExtension::kTransportSequenceNumberUri, true);
}

TEST_F(WebRtcVideoEngineTest, SupportsVideoRotationHeaderExtension) {
  ExpectRtpCapabilitySupport(RtpExtension::kVideoRotationUri, true);
}

TEST_F(WebRtcVideoEngineTest, SupportsPlayoutDelayHeaderExtension) {
  ExpectRtpCapabilitySupport(RtpExtension::kPlayoutDelayUri, true);
}

TEST_F(WebRtcVideoEngineTest, SupportsVideoContentTypeHeaderExtension) {
  ExpectRtpCapabilitySupport(RtpExtension::kVideoContentTypeUri, true);
}

TEST_F(WebRtcVideoEngineTest, SupportsVideoTimingHeaderExtension) {
  ExpectRtpCapabilitySupport(RtpExtension::kVideoTimingUri, true);
}

TEST_F(WebRtcVideoEngineTest, SupportsColorSpaceHeaderExtension) {
  ExpectRtpCapabilitySupport(RtpExtension::kColorSpaceUri, true);
}

TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor00) {
  ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, false);
}

class WebRtcVideoEngineTestWithGenericDescriptor
    : public WebRtcVideoEngineTest {
 public:
  WebRtcVideoEngineTestWithGenericDescriptor()
      : WebRtcVideoEngineTest("WebRTC-GenericDescriptorAdvertised/Enabled/") {}
};

TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,
       AdvertiseGenericDescriptor00) {
  ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, true);
}

class WebRtcVideoEngineTestWithDependencyDescriptor
    : public WebRtcVideoEngineTest {
 public:
  WebRtcVideoEngineTestWithDependencyDescriptor()
      : WebRtcVideoEngineTest(
            "WebRTC-DependencyDescriptorAdvertised/Enabled/") {}
};

TEST_F(WebRtcVideoEngineTestWithDependencyDescriptor,
       AdvertiseDependencyDescriptor) {
  ExpectRtpCapabilitySupport(RtpExtension::kDependencyDescriptorUri, true);
}

TEST_F(WebRtcVideoEngineTest, AdvertiseVideoLayersAllocation) {
  ExpectRtpCapabilitySupport(RtpExtension::kVideoLayersAllocationUri, false);
}

class WebRtcVideoEngineTestWithVideoLayersAllocation
    : public WebRtcVideoEngineTest {
 public:
  WebRtcVideoEngineTestWithVideoLayersAllocation()
      : WebRtcVideoEngineTest(
            "WebRTC-VideoLayersAllocationAdvertised/Enabled/") {}
};

TEST_F(WebRtcVideoEngineTestWithVideoLayersAllocation,
       AdvertiseVideoLayersAllocation) {
  ExpectRtpCapabilitySupport(RtpExtension::kVideoLayersAllocationUri, true);
}

class WebRtcVideoFrameTrackingId : public WebRtcVideoEngineTest {
 public:
  WebRtcVideoFrameTrackingId()
      : WebRtcVideoEngineTest(
            "WebRTC-VideoFrameTrackingIdAdvertised/Enabled/") {}
};

TEST_F(WebRtcVideoFrameTrackingId, AdvertiseVideoFrameTrackingId) {
  ExpectRtpCapabilitySupport(RtpExtension::kVideoFrameTrackingIdUri, true);
}

TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
  // Allocate the source first to prevent early destruction before channel's
  // dtor is called.
  ::testing::NiceMock<MockVideoSource> video_source;

  AddSupportedVideoCodecType("VP8");

  std::unique_ptr<VideoMediaChannel> channel(
      SetSendParamsWithAllSupportedCodecs());
  EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));

  // Add CVO extension.
  const int id = 1;
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.extensions.push_back(
      RtpExtension(RtpExtension::kVideoRotationUri, id));
  EXPECT_TRUE(channel->SetSendParameters(parameters));

  EXPECT_CALL(
      video_source,
      AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, false)));
  // Set capturer.
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));

  // Verify capturer has turned off applying rotation.
  ::testing::Mock::VerifyAndClear(&video_source);

  // Verify removing header extension turns on applying rotation.
  parameters.extensions.clear();
  EXPECT_CALL(
      video_source,
      AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, true)));

  EXPECT_TRUE(channel->SetSendParameters(parameters));
}

TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
  // Allocate the source first to prevent early destruction before channel's
  // dtor is called.
  ::testing::NiceMock<MockVideoSource> video_source;

  AddSupportedVideoCodecType("VP8");

  std::unique_ptr<VideoMediaChannel> channel(
      SetSendParamsWithAllSupportedCodecs());
  // Add CVO extension.
  const int id = 1;
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.extensions.push_back(
      RtpExtension(RtpExtension::kVideoRotationUri, id));
  EXPECT_TRUE(channel->SetSendParameters(parameters));
  EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));

  // Set source.
  EXPECT_CALL(
      video_source,
      AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, false)));
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
}

TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
  ::testing::NiceMock<MockVideoSource> video_source;

  AddSupportedVideoCodecType("VP8");
  AddSupportedVideoCodecType("VP9");

  std::unique_ptr<VideoMediaChannel> channel(
      SetSendParamsWithAllSupportedCodecs());
  EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));

  // Set capturer.
  EXPECT_CALL(
      video_source,
      AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, true)));
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));

  // Verify capturer has turned on applying rotation.
  ::testing::Mock::VerifyAndClear(&video_source);

  // Add CVO extension.
  const int id = 1;
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  parameters.extensions.push_back(
      RtpExtension(RtpExtension::kVideoRotationUri, id));
  // Also remove the first codec to trigger a codec change as well.
  parameters.codecs.erase(parameters.codecs.begin());
  EXPECT_CALL(
      video_source,
      AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, false)));
  EXPECT_TRUE(channel->SetSendParameters(parameters));

  // Verify capturer has turned off applying rotation.
  ::testing::Mock::VerifyAndClear(&video_source);

  // Verify removing header extension turns on applying rotation.
  parameters.extensions.clear();
  EXPECT_CALL(
      video_source,
      AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, true)));
  EXPECT_TRUE(channel->SetSendParameters(parameters));
}

TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
  AddSupportedVideoCodecType("VP8");

  std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
      call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));

  EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));

  EXPECT_FALSE(channel->SetSend(true))
      << "Channel should not start without codecs.";
  EXPECT_TRUE(channel->SetSend(false))
      << "Channel should be stoppable even without set codecs.";
}

TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
  AddSupportedVideoCodecType("VP8");

  std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
      call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
  VideoMediaInfo info;
  channel->GetStats(&info);
}

TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) {
  AddSupportedVideoCodecType("VP8");

  std::unique_ptr<VideoMediaChannel> channel(
      SetSendParamsWithAllSupportedCodecs());
  channel->OnReadyToSend(true);

  EXPECT_TRUE(
      channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
  EXPECT_EQ(0, encoder_factory_->GetNumCreatedEncoders());
  EXPECT_TRUE(channel->SetSend(true));
  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  time_controller_.AdvanceTime(webrtc::TimeDelta::Zero());
  // Sending one frame will have allocate the encoder.
  ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
  EXPECT_TRUE_WAIT(encoder_factory_->encoders()[0]->GetNumEncodedFrames() > 0,
                   kTimeout);

  int num_created_encoders = encoder_factory_->GetNumCreatedEncoders();
  EXPECT_EQ(num_created_encoders, 1);

  // Setting codecs of the same type should not reallocate any encoders
  // (expecting a no-op).
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel->SetSendParameters(parameters));
  EXPECT_EQ(num_created_encoders, encoder_factory_->GetNumCreatedEncoders());

  // Remove stream previously added to free the external encoder instance.
  EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
  EXPECT_EQ(0u, encoder_factory_->encoders().size());
}

// Test that when an encoder factory supports H264, we add an RTX
// codec for it.
// TODO(deadbeef): This test should be updated if/when we start
// adding RTX codecs for unrecognized codec names.
TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) {
  using webrtc::H264Level;
  using webrtc::H264Profile;
  using webrtc::H264ProfileLevelId;
  using webrtc::H264ProfileLevelIdToString;
  webrtc::SdpVideoFormat h264_constrained_baseline("H264");
  h264_constrained_baseline.parameters[kH264FmtpProfileLevelId] =
      *H264ProfileLevelIdToString(H264ProfileLevelId(
          H264Profile::kProfileConstrainedBaseline, H264Level::kLevel1));
  webrtc::SdpVideoFormat h264_constrained_high("H264");
  h264_constrained_high.parameters[kH264FmtpProfileLevelId] =
      *H264ProfileLevelIdToString(H264ProfileLevelId(
          H264Profile::kProfileConstrainedHigh, H264Level::kLevel1));
  webrtc::SdpVideoFormat h264_high("H264");
  h264_high.parameters[kH264FmtpProfileLevelId] = *H264ProfileLevelIdToString(
      H264ProfileLevelId(H264Profile::kProfileHigh, H264Level::kLevel1));

  encoder_factory_->AddSupportedVideoCodec(h264_constrained_baseline);
  encoder_factory_->AddSupportedVideoCodec(h264_constrained_high);
  encoder_factory_->AddSupportedVideoCodec(h264_high);

  // First figure out what payload types the test codecs got assigned.
  const std::vector<cricket::VideoCodec> codecs = engine_.send_codecs();
  // Now search for RTX codecs for them. Expect that they all have associated
  // RTX codecs.
  EXPECT_TRUE(HasRtxCodec(
      codecs,
      FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_baseline))
          ->id));
  EXPECT_TRUE(HasRtxCodec(
      codecs,
      FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_high))
          ->id));
  EXPECT_TRUE(HasRtxCodec(
      codecs, FindMatchingCodec(codecs, cricket::VideoCodec(h264_high))->id));
}

#if defined(RTC_ENABLE_VP9)
TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
  AddSupportedVideoCodecType("VP9");

  std::unique_ptr<VideoMediaChannel> channel(
      SetSendParamsWithAllSupportedCodecs());

  EXPECT_TRUE(
      channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
}
#endif  // defined(RTC_ENABLE_VP9)

TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) {
  AddSupportedVideoCodecType("VP8");
  FakeCall* fake_call = new FakeCall();
  call_.reset(fake_call);
  std::unique_ptr<VideoMediaChannel> channel(
      SetSendParamsWithAllSupportedCodecs());

  EXPECT_TRUE(
      channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));

  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 60);
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
  channel->SetSend(true);

  FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];

  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  int64_t last_timestamp = stream->GetLastTimestamp();
  for (int i = 0; i < 10; i++) {
    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
    int64_t timestamp = stream->GetLastTimestamp();
    int64_t interval = timestamp - last_timestamp;

    // Precision changes from nanosecond to millisecond.
    // Allow error to be no more than 1.
    EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);

    last_timestamp = timestamp;
  }

  frame_forwarder.IncomingCapturedFrame(
      frame_source.GetFrame(1280, 720, webrtc::VideoRotation::kVideoRotation_0,
                            rtc::kNumMicrosecsPerSec / 30));
  last_timestamp = stream->GetLastTimestamp();
  for (int i = 0; i < 10; i++) {
    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame(
        1280, 720, webrtc::VideoRotation::kVideoRotation_0,
        rtc::kNumMicrosecsPerSec / 30));
    int64_t timestamp = stream->GetLastTimestamp();
    int64_t interval = timestamp - last_timestamp;

    // Precision changes from nanosecond to millisecond.
    // Allow error to be no more than 1.
    EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);

    last_timestamp = timestamp;
  }

  // Remove stream previously added to free the external encoder instance.
  EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
}

void WebRtcVideoEngineTest::AssignDefaultAptRtxTypes() {
  std::vector<VideoCodec> engine_codecs = engine_.send_codecs();
  RTC_DCHECK(!engine_codecs.empty());
  for (const cricket::VideoCodec& codec : engine_codecs) {
    if (codec.name == "rtx") {
      int associated_payload_type;
      if (codec.GetParam(kCodecParamAssociatedPayloadType,
                         &associated_payload_type)) {
        default_apt_rtx_types_[associated_payload_type] = codec.id;
      }
    }
  }
}

void WebRtcVideoEngineTest::AssignDefaultCodec() {
  std::vector<VideoCodec> engine_codecs = engine_.send_codecs();
  RTC_DCHECK(!engine_codecs.empty());
  bool codec_set = false;
  for (const cricket::VideoCodec& codec : engine_codecs) {
    if (!codec_set && codec.name != "rtx" && codec.name != "red" &&
        codec.name != "ulpfec" && codec.name != "flexfec-03") {
      default_codec_ = codec;
      codec_set = true;
    }
  }

  RTC_DCHECK(codec_set);
}

size_t WebRtcVideoEngineTest::GetEngineCodecIndex(
    const std::string& name) const {
  const std::vector<cricket::VideoCodec> codecs = engine_.send_codecs();
  for (size_t i = 0; i < codecs.size(); ++i) {
    const cricket::VideoCodec engine_codec = codecs[i];
    if (!absl::EqualsIgnoreCase(name, engine_codec.name))
      continue;
    // The tests only use H264 Constrained Baseline. Make sure we don't return
    // an internal H264 codec from the engine with a different H264 profile.
    if (absl::EqualsIgnoreCase(name.c_str(), kH264CodecName)) {
      const absl::optional<webrtc::H264ProfileLevelId> profile_level_id =
          webrtc::ParseSdpForH264ProfileLevelId(engine_codec.params);
      if (profile_level_id->profile !=
          webrtc::H264Profile::kProfileConstrainedBaseline) {
        continue;
      }
    }
    return i;
  }
  // This point should never be reached.
  ADD_FAILURE() << "Unrecognized codec name: " << name;
  return -1;
}

cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec(
    const std::string& name) const {
  return engine_.send_codecs()[GetEngineCodecIndex(name)];
}

void WebRtcVideoEngineTest::AddSupportedVideoCodecType(
    const std::string& name) {
  encoder_factory_->AddSupportedVideoCodecType(name);
  decoder_factory_->AddSupportedVideoCodecType(name);
}

VideoMediaChannel*
WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() {
  VideoMediaChannel* channel = engine_.CreateMediaChannel(
      call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get());
  cricket::VideoSendParameters parameters;
  // We need to look up the codec in the engine to get the correct payload type.
  for (const webrtc::SdpVideoFormat& format :
       encoder_factory_->GetSupportedFormats()) {
    cricket::VideoCodec engine_codec = GetEngineCodec(format.name);
    if (!absl::c_linear_search(parameters.codecs, engine_codec)) {
      parameters.codecs.push_back(engine_codec);
    }
  }

  EXPECT_TRUE(channel->SetSendParameters(parameters));

  return channel;
}

VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs(
    const std::vector<VideoCodec>& codecs) {
  VideoMediaChannel* channel = engine_.CreateMediaChannel(
      call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get());
  cricket::VideoRecvParameters parameters;
  parameters.codecs = codecs;
  EXPECT_TRUE(channel->SetRecvParameters(parameters));

  return channel;
}

void WebRtcVideoEngineTest::ExpectRtpCapabilitySupport(const char* uri,
                                                       bool supported) const {
  const std::vector<webrtc::RtpExtension> header_extensions =
      GetDefaultEnabledRtpHeaderExtensions(engine_);
  if (supported) {
    EXPECT_THAT(header_extensions, Contains(Field(&RtpExtension::uri, uri)));
  } else {
    EXPECT_THAT(header_extensions, Each(Field(&RtpExtension::uri, StrNe(uri))));
  }
}

TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
  AddSupportedVideoCodecType("VP8");

  std::unique_ptr<VideoMediaChannel> channel(
      SetSendParamsWithAllSupportedCodecs());

  std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);

  EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
  EXPECT_TRUE(channel->SetSend(true));

  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 60);
  EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  time_controller_.AdvanceTime(webrtc::TimeDelta::Zero());
  ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));

  // Verify that encoders are configured for simulcast through adapter
  // (increasing resolution and only configured to send one stream each).
  int prev_width = -1;
  for (size_t i = 0; i < encoder_factory_->encoders().size(); ++i) {
    ASSERT_TRUE(encoder_factory_->encoders()[i]->WaitForInitEncode());
    webrtc::VideoCodec codec_settings =
        encoder_factory_->encoders()[i]->GetCodecSettings();
    EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
    EXPECT_GT(codec_settings.width, prev_width);
    prev_width = codec_settings.width;
  }

  EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, nullptr));

  channel.reset();
  ASSERT_EQ(0u, encoder_factory_->encoders().size());
}

TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) {
  AddSupportedVideoCodecType("VP8");
  AddSupportedVideoCodecType("H264");

  // Frame source.
  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);

  std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
      call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("H264"));
  EXPECT_TRUE(channel->SetSendParameters(parameters));

  EXPECT_TRUE(
      channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
  // Sending one frame will have allocate the encoder.
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  time_controller_.AdvanceTime(webrtc::TimeDelta::Zero());

  ASSERT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);

  cricket::VideoSendParameters new_parameters;
  new_parameters.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel->SetSendParameters(new_parameters));

  // Sending one frame will switch encoder.
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  time_controller_.AdvanceTime(webrtc::TimeDelta::Zero());

  EXPECT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
}

TEST_F(WebRtcVideoEngineTest,
       UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
  AddSupportedVideoCodecType("VP8");
  AddSupportedVideoCodecType("H264");

  std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
      call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel->SetSendParameters(parameters));

  std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);

  EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
  EXPECT_TRUE(channel->SetSend(true));

  // Send a fake frame, or else the media engine will configure the simulcast
  // encoder adapter at a low-enough size that it'll only create a single
  // encoder layer.
  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);
  EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  time_controller_.AdvanceTime(webrtc::TimeDelta::Zero());

  ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
  ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
  EXPECT_EQ(webrtc::kVideoCodecVP8,
            encoder_factory_->encoders()[0]->GetCodecSettings().codecType);

  channel.reset();
  // Make sure DestroyVideoEncoder was called on the factory.
  EXPECT_EQ(0u, encoder_factory_->encoders().size());
}

TEST_F(WebRtcVideoEngineTest,
       DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
  AddSupportedVideoCodecType("VP8");
  AddSupportedVideoCodecType("H264");

  std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
      call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("H264"));
  EXPECT_TRUE(channel->SetSendParameters(parameters));

  EXPECT_TRUE(
      channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));

  // Send a frame of 720p. This should trigger a "real" encoder initialization.
  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  time_controller_.AdvanceTime(webrtc::TimeDelta::Zero());
  ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
  ASSERT_EQ(1u, encoder_factory_->encoders().size());
  ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
  EXPECT_EQ(webrtc::kVideoCodecH264,
            encoder_factory_->encoders()[0]->GetCodecSettings().codecType);

  channel.reset();
  // Make sure DestroyVideoEncoder was called on the factory.
  ASSERT_EQ(0u, encoder_factory_->encoders().size());
}

TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) {
  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_, "WebRTC-H264Simulcast/Enabled/");
  AddSupportedVideoCodecType("H264");

  std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
      call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("H264"));
  EXPECT_TRUE(channel->SetSendParameters(parameters));

  const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
  EXPECT_TRUE(
      channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));

  // Send a frame of 720p. This should trigger a "real" encoder initialization.
  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);
  EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  time_controller_.AdvanceTime(webrtc::TimeDelta::Zero());

  ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
  ASSERT_EQ(1u, encoder_factory_->encoders().size());
  FakeWebRtcVideoEncoder* encoder = encoder_factory_->encoders()[0];
  ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
  EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
  EXPECT_LT(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
  EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, nullptr));
}

// Test that FlexFEC is not supported as a send video codec by default.
// Only enabling field trial should allow advertising FlexFEC send codec.
TEST_F(WebRtcVideoEngineTest, Flexfec03SendCodecEnablesWithFieldTrial) {
  encoder_factory_->AddSupportedVideoCodecType("VP8");

  auto flexfec = Field("name", &VideoCodec::name, "flexfec-03");

  EXPECT_THAT(engine_.send_codecs(), Not(Contains(flexfec)));

  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_, "WebRTC-FlexFEC-03-Advertised/Enabled/");
  EXPECT_THAT(engine_.send_codecs(), Contains(flexfec));
}

// Test that FlexFEC is supported as a receive video codec by default.
// Disabling field trial should prevent advertising FlexFEC receive codec.
TEST_F(WebRtcVideoEngineTest, Flexfec03ReceiveCodecDisablesWithFieldTrial) {
  decoder_factory_->AddSupportedVideoCodecType("VP8");

  auto flexfec = Field("name", &VideoCodec::name, "flexfec-03");

  EXPECT_THAT(engine_.recv_codecs(), Contains(flexfec));

  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_, "WebRTC-FlexFEC-03-Advertised/Disabled/");
  EXPECT_THAT(engine_.recv_codecs(), Not(Contains(flexfec)));
}

// Test that the FlexFEC "codec" gets assigned to the lower payload type range
TEST_F(WebRtcVideoEngineTest, Flexfec03LowerPayloadTypeRange) {
  encoder_factory_->AddSupportedVideoCodecType("VP8");

  auto flexfec = Field("name", &VideoCodec::name, "flexfec-03");

  // FlexFEC is active with field trial.
  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_, "WebRTC-FlexFEC-03-Advertised/Enabled/");
  auto send_codecs = engine_.send_codecs();
  auto it = std::find_if(send_codecs.begin(), send_codecs.end(),
                         [](const cricket::VideoCodec& codec) {
                           return codec.name == "flexfec-03";
                         });
  ASSERT_NE(it, send_codecs.end());
  EXPECT_LE(35, it->id);
  EXPECT_GE(65, it->id);
}

// Test that codecs are added in the order they are reported from the factory.
TEST_F(WebRtcVideoEngineTest, ReportSupportedCodecs) {
  encoder_factory_->AddSupportedVideoCodecType("VP8");
  const char* kFakeCodecName = "FakeCodec";
  encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);

  // The last reported codec should appear after the first codec in the vector.
  const size_t vp8_index = GetEngineCodecIndex("VP8");
  const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
  EXPECT_LT(vp8_index, fake_codec_index);
}

// Test that a codec that was added after the engine was initialized
// does show up in the codec list after it was added.
TEST_F(WebRtcVideoEngineTest, ReportSupportedAddedCodec) {
  const char* kFakeExternalCodecName1 = "FakeExternalCodec1";
  const char* kFakeExternalCodecName2 = "FakeExternalCodec2";

  // Set up external encoder factory with first codec, and initialize engine.
  encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName1);

  std::vector<cricket::VideoCodec> codecs_before(engine_.send_codecs());

  // Add second codec.
  encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName2);
  std::vector<cricket::VideoCodec> codecs_after(engine_.send_codecs());
  // The codec itself and RTX should have been added.
  EXPECT_EQ(codecs_before.size() + 2, codecs_after.size());

  // Check that both fake codecs are present and that the second fake codec
  // appears after the first fake codec.
  const size_t fake_codec_index1 = GetEngineCodecIndex(kFakeExternalCodecName1);
  const size_t fake_codec_index2 = GetEngineCodecIndex(kFakeExternalCodecName2);
  EXPECT_LT(fake_codec_index1, fake_codec_index2);
}

TEST_F(WebRtcVideoEngineTest, ReportRtxForExternalCodec) {
  const char* kFakeCodecName = "FakeCodec";
  encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);

  const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
  EXPECT_EQ("rtx", engine_.send_codecs().at(fake_codec_index + 1).name);
}

TEST_F(WebRtcVideoEngineTest, RegisterDecodersIfSupported) {
  AddSupportedVideoCodecType("VP8");
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));

  std::unique_ptr<VideoMediaChannel> channel(
      SetRecvParamsWithSupportedCodecs(parameters.codecs));

  EXPECT_TRUE(
      channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
  ASSERT_EQ(1u, decoder_factory_->decoders().size());

  // Setting codecs of the same type should not reallocate the decoder.
  EXPECT_TRUE(channel->SetRecvParameters(parameters));
  EXPECT_EQ(1, decoder_factory_->GetNumCreatedDecoders());

  // Remove stream previously added to free the external decoder instance.
  EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
  EXPECT_EQ(0u, decoder_factory_->decoders().size());
}

// Verifies that we can set up decoders.
TEST_F(WebRtcVideoEngineTest, RegisterH264DecoderIfSupported) {
  // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
  // can't even query the WebRtcVideoDecoderFactory for supported codecs.
  // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
  // codecs.
  AddSupportedVideoCodecType("H264");
  std::vector<cricket::VideoCodec> codecs;
  codecs.push_back(GetEngineCodec("H264"));

  std::unique_ptr<VideoMediaChannel> channel(
      SetRecvParamsWithSupportedCodecs(codecs));

  EXPECT_TRUE(
      channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
  ASSERT_EQ(1u, decoder_factory_->decoders().size());
}

// Tests when GetSources is called with non-existing ssrc, it will return an
// empty list of RtpSource without crashing.
TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) {
  // Setup an recv stream with `kSsrc`.
  AddSupportedVideoCodecType("VP8");
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  std::unique_ptr<VideoMediaChannel> channel(
      SetRecvParamsWithSupportedCodecs(parameters.codecs));

  EXPECT_TRUE(
      channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));

  // Call GetSources with |kSsrc + 1| which doesn't exist.
  std::vector<webrtc::RtpSource> sources = channel->GetSources(kSsrc + 1);
  EXPECT_EQ(0u, sources.size());
}

TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) {
  std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
  std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
  webrtc::FieldTrialBasedConfig trials;
  WebRtcVideoEngine engine(std::move(encoder_factory),
                           std::move(decoder_factory), trials);
  EXPECT_EQ(0u, engine.send_codecs().size());
  EXPECT_EQ(0u, engine.recv_codecs().size());
}

TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) {
  // `engine` take ownership of the factories.
  webrtc::MockVideoEncoderFactory* encoder_factory =
      new webrtc::MockVideoEncoderFactory();
  webrtc::MockVideoDecoderFactory* decoder_factory =
      new webrtc::MockVideoDecoderFactory();
  webrtc::FieldTrialBasedConfig trials;
  WebRtcVideoEngine engine(
      (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
      (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)), trials);
  // TODO(kron): Change to Times(1) once send and receive codecs are changed
  // to be treated independently.
  EXPECT_CALL(*encoder_factory, GetSupportedFormats()).Times(1);
  EXPECT_EQ(0u, engine.send_codecs().size());
  EXPECT_EQ(0u, engine.recv_codecs().size());
  EXPECT_CALL(*encoder_factory, Die());
  EXPECT_CALL(*decoder_factory, Die());
}

// Test full behavior in the video engine when video codec factories of the new
// type are injected supporting the single codec Vp8. Check the returned codecs
// from the engine and that we will create a Vp8 encoder and decoder using the
// new factories.
TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
  // `engine` take ownership of the factories.
  webrtc::MockVideoEncoderFactory* encoder_factory =
      new webrtc::MockVideoEncoderFactory();
  webrtc::MockVideoDecoderFactory* decoder_factory =
      new webrtc::MockVideoDecoderFactory();
  std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
      rate_allocator_factory =
          std::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
  EXPECT_CALL(*rate_allocator_factory,
              CreateVideoBitrateAllocator(Field(&webrtc::VideoCodec::codecType,
                                                webrtc::kVideoCodecVP8)))
      .WillOnce(
          [] { return std::make_unique<webrtc::MockVideoBitrateAllocator>(); });
  webrtc::FieldTrialBasedConfig trials;
  WebRtcVideoEngine engine(
      (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
      (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)), trials);
  const webrtc::SdpVideoFormat vp8_format("VP8");
  const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
  EXPECT_CALL(*encoder_factory, GetSupportedFormats())
      .WillRepeatedly(Return(supported_formats));
  EXPECT_CALL(*decoder_factory, GetSupportedFormats())
      .WillRepeatedly(Return(supported_formats));

  // Verify the codecs from the engine.
  const std::vector<VideoCodec> engine_codecs = engine.send_codecs();
  // Verify default codecs has been added correctly.
  EXPECT_EQ(5u, engine_codecs.size());
  EXPECT_EQ("VP8", engine_codecs.at(0).name);

  // RTX codec for VP8.
  EXPECT_EQ("rtx", engine_codecs.at(1).name);
  int vp8_associated_payload;
  EXPECT_TRUE(engine_codecs.at(1).GetParam(kCodecParamAssociatedPayloadType,
                                           &vp8_associated_payload));
  EXPECT_EQ(vp8_associated_payload, engine_codecs.at(0).id);

  EXPECT_EQ(kRedCodecName, engine_codecs.at(2).name);

  // RTX codec for RED.
  EXPECT_EQ("rtx", engine_codecs.at(3).name);
  int red_associated_payload;
  EXPECT_TRUE(engine_codecs.at(3).GetParam(kCodecParamAssociatedPayloadType,
                                           &red_associated_payload));
  EXPECT_EQ(red_associated_payload, engine_codecs.at(2).id);

  EXPECT_EQ(kUlpfecCodecName, engine_codecs.at(4).name);

  int associated_payload_type;
  EXPECT_TRUE(engine_codecs.at(1).GetParam(
      cricket::kCodecParamAssociatedPayloadType, &associated_payload_type));
  EXPECT_EQ(engine_codecs.at(0).id, associated_payload_type);
  // Verify default parameters has been added to the VP8 codec.
  VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0),
                                      /*lntf_expected=*/false);

  // Mock encoder creation. `engine` take ownership of the encoder.
  const webrtc::SdpVideoFormat format("VP8");
  EXPECT_CALL(*encoder_factory, CreateVideoEncoder(format)).WillOnce([&] {
    return std::make_unique<FakeWebRtcVideoEncoder>(nullptr);
  });

  // Mock decoder creation. `engine` take ownership of the decoder.
  EXPECT_CALL(*decoder_factory, CreateVideoDecoder(format)).WillOnce([] {
    return std::make_unique<FakeWebRtcVideoDecoder>(nullptr);
  });

  // Create a call.
  webrtc::RtcEventLogNull event_log;
  webrtc::GlobalSimulatedTimeController time_controller(
      webrtc::Timestamp::Millis(4711));
  auto task_queue_factory = time_controller.CreateTaskQueueFactory();
  webrtc::Call::Config call_config(&event_log);
  webrtc::FieldTrialBasedConfig field_trials;
  call_config.trials = &field_trials;
  call_config.task_queue_factory = task_queue_factory.get();
  const auto call = absl::WrapUnique(webrtc::Call::Create(call_config));

  // Create send channel.
  const int send_ssrc = 123;
  std::unique_ptr<VideoMediaChannel> send_channel(engine.CreateMediaChannel(
      call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      rate_allocator_factory.get()));
  cricket::VideoSendParameters send_parameters;
  send_parameters.codecs.push_back(engine_codecs.at(0));
  EXPECT_TRUE(send_channel->SetSendParameters(send_parameters));
  send_channel->OnReadyToSend(true);
  EXPECT_TRUE(
      send_channel->AddSendStream(StreamParams::CreateLegacy(send_ssrc)));
  EXPECT_TRUE(send_channel->SetSend(true));

  // Set capturer.
  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);
  EXPECT_TRUE(send_channel->SetVideoSend(send_ssrc, nullptr, &frame_forwarder));
  // Sending one frame will allocate the encoder.
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  time_controller.AdvanceTime(webrtc::TimeDelta::Zero());

  // Create recv channel.
  const int recv_ssrc = 321;
  std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
      call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      rate_allocator_factory.get()));
  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(engine_codecs.at(0));
  EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
  EXPECT_TRUE(recv_channel->AddRecvStream(
      cricket::StreamParams::CreateLegacy(recv_ssrc)));

  // Remove streams previously added to free the encoder and decoder instance.
  EXPECT_CALL(*encoder_factory, Die());
  EXPECT_CALL(*decoder_factory, Die());
  EXPECT_CALL(*rate_allocator_factory, Die());
  EXPECT_TRUE(send_channel->RemoveSendStream(send_ssrc));
  EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
}

// Test behavior when decoder factory fails to create a decoder (returns null).
TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullDecoder) {
  rtc::AutoThread main_thread_;
  // `engine` take ownership of the factories.
  webrtc::MockVideoEncoderFactory* encoder_factory =
      new webrtc::MockVideoEncoderFactory();
  webrtc::MockVideoDecoderFactory* decoder_factory =
      new webrtc::MockVideoDecoderFactory();
  std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
      rate_allocator_factory =
          std::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
  webrtc::FieldTrialBasedConfig trials;
  WebRtcVideoEngine engine(
      (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
      (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)), trials);
  const webrtc::SdpVideoFormat vp8_format("VP8");
  const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
  EXPECT_CALL(*encoder_factory, GetSupportedFormats())
      .WillRepeatedly(Return(supported_formats));

  // Decoder creation fails.
  EXPECT_CALL(*decoder_factory, CreateVideoDecoder).WillOnce([] {
    return nullptr;
  });

  // Create a call.
  webrtc::RtcEventLogNull event_log;
  auto task_queue_factory = webrtc::CreateDefaultTaskQueueFactory();
  webrtc::Call::Config call_config(&event_log);
  webrtc::FieldTrialBasedConfig field_trials;
  call_config.trials = &field_trials;
  call_config.task_queue_factory = task_queue_factory.get();
  const auto call = absl::WrapUnique(webrtc::Call::Create(call_config));

  // Create recv channel.
  EXPECT_CALL(*decoder_factory, GetSupportedFormats())
      .WillRepeatedly(::testing::Return(supported_formats));
  const int recv_ssrc = 321;
  std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
      call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
      rate_allocator_factory.get()));
  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(engine.recv_codecs().front());
  EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
  EXPECT_TRUE(recv_channel->AddRecvStream(
      cricket::StreamParams::CreateLegacy(recv_ssrc)));

  // Remove streams previously added to free the encoder and decoder instance.
  EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
}

TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
  encoder_factory_->AddSupportedVideoCodecType("VP8");
  std::unique_ptr<FakeCall> fake_call(new FakeCall());
  std::unique_ptr<VideoMediaChannel> channel(
      SetSendParamsWithAllSupportedCodecs());
  ASSERT_TRUE(
      channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
  cricket::VideoCodec codec = GetEngineCodec("VP8");
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(codec);
  channel->OnReadyToSend(true);
  channel->SetSend(true);
  ASSERT_TRUE(channel->SetSendParameters(parameters));

  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);
  VideoOptions options;
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));

  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
  EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
            encoder_factory_->encoders().back()->GetCodecSettings().mode);

  EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  // No change in content type, keep current encoder.
  EXPECT_EQ(1, encoder_factory_->GetNumCreatedEncoders());

  options.is_screencast.emplace(true);
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  // Change to screen content, recreate encoder. For the simulcast encoder
  // adapter case, this will result in two calls since InitEncode triggers a
  // a new instance.
  ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
  EXPECT_EQ(webrtc::VideoCodecMode::kScreensharing,
            encoder_factory_->encoders().back()->GetCodecSettings().mode);

  EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  // Still screen content, no need to update encoder.
  EXPECT_EQ(2, encoder_factory_->GetNumCreatedEncoders());

  options.is_screencast.emplace(false);
  options.video_noise_reduction.emplace(false);
  EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
  // Change back to regular video content, update encoder. Also change
  // a non `is_screencast` option just to verify it doesn't affect recreation.
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(3));
  EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
            encoder_factory_->encoders().back()->GetCodecSettings().mode);

  // Remove stream previously added to free the external encoder instance.
  EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
  EXPECT_EQ(0u, encoder_factory_->encoders().size());
}

TEST_F(WebRtcVideoEngineTest, SetVideoRtxEnabled) {
  AddSupportedVideoCodecType("VP8");
  std::vector<VideoCodec> send_codecs;
  std::vector<VideoCodec> recv_codecs;

  webrtc::test::ScopedKeyValueConfig field_trials;

  // Don't want RTX
  send_codecs = engine_.send_codecs(false);
  EXPECT_FALSE(HasAnyRtxCodec(send_codecs));
  recv_codecs = engine_.recv_codecs(false);
  EXPECT_FALSE(HasAnyRtxCodec(recv_codecs));

  // Want RTX
  send_codecs = engine_.send_codecs(true);
  EXPECT_TRUE(HasAnyRtxCodec(send_codecs));
  recv_codecs = engine_.recv_codecs(true);
  EXPECT_TRUE(HasAnyRtxCodec(recv_codecs));
}

class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test {
 protected:
  webrtc::Call::Config GetCallConfig(
      webrtc::RtcEventLogNull* event_log,
      webrtc::TaskQueueFactory* task_queue_factory) {
    webrtc::Call::Config call_config(event_log);
    call_config.task_queue_factory = task_queue_factory;
    call_config.trials = &field_trials_;
    return call_config;
  }

  WebRtcVideoChannelEncodedFrameCallbackTest()
      : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
        call_(absl::WrapUnique(webrtc::Call::Create(
            GetCallConfig(&event_log_, task_queue_factory_.get())))),
        video_bitrate_allocator_factory_(
            webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
        engine_(
            webrtc::CreateBuiltinVideoEncoderFactory(),
            std::make_unique<webrtc::test::FunctionVideoDecoderFactory>(
                []() { return std::make_unique<webrtc::test::FakeDecoder>(); },
                kSdpVideoFormats),
            field_trials_),
        channel_(absl::WrapUnique(static_cast<cricket::WebRtcVideoChannel*>(
            engine_.CreateMediaChannel(
                call_.get(),
                cricket::MediaConfig(),
                cricket::VideoOptions(),
                webrtc::CryptoOptions(),
                video_bitrate_allocator_factory_.get())))) {
    network_interface_.SetDestination(channel_.get());
    channel_->SetInterface(&network_interface_);
    cricket::VideoRecvParameters parameters;
    parameters.codecs = engine_.recv_codecs();
    channel_->SetRecvParameters(parameters);
  }

  ~WebRtcVideoChannelEncodedFrameCallbackTest() override {
    channel_->SetInterface(nullptr);
  }

  void DeliverKeyFrame(uint32_t ssrc) {
    RtpPacket packet;
    packet.SetMarker(true);
    packet.SetPayloadType(96);  // VP8
    packet.SetSsrc(ssrc);

    // VP8 Keyframe + 1 byte payload
    uint8_t* buf_ptr = packet.AllocatePayload(11);
    memset(buf_ptr, 0, 11);  // Pass MSAN (don't care about bytes 1-9)
    buf_ptr[0] = 0x10;       // Partition ID 0 + beginning of partition.
    constexpr unsigned width = 1080;
    constexpr unsigned height = 720;
    buf_ptr[6] = width & 255;
    buf_ptr[7] = width >> 8;
    buf_ptr[8] = height & 255;
    buf_ptr[9] = height >> 8;

    call_->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO, packet.Buffer(),
                                     /*packet_time_us=*/0);
  }

  void DeliverKeyFrameAndWait(uint32_t ssrc) {
    DeliverKeyFrame(ssrc);
    EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
  }

  static const std::vector<webrtc::SdpVideoFormat> kSdpVideoFormats;
  rtc::AutoThread main_thread_;
  webrtc::test::ScopedKeyValueConfig field_trials_;
  webrtc::RtcEventLogNull event_log_;
  std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
  std::unique_ptr<webrtc::Call> call_;
  std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
      video_bitrate_allocator_factory_;
  WebRtcVideoEngine engine_;
  std::unique_ptr<WebRtcVideoChannel> channel_;
  cricket::FakeNetworkInterface network_interface_;
  cricket::FakeVideoRenderer renderer_;
};

const std::vector<webrtc::SdpVideoFormat>
    WebRtcVideoChannelEncodedFrameCallbackTest::kSdpVideoFormats = {
        webrtc::SdpVideoFormat("VP8")};

TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
       SetEncodedFrameBufferFunction_DefaultStream) {
  testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)> callback;
  EXPECT_CALL(callback, Call);
  EXPECT_TRUE(channel_->AddRecvStream(
      cricket::StreamParams::CreateLegacy(kSsrc), /*is_default_stream=*/true));
  channel_->SetRecordableEncodedFrameCallback(/*ssrc=*/0,
                                              callback.AsStdFunction());
  EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
  DeliverKeyFrame(kSsrc);
  EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
  channel_->RemoveRecvStream(kSsrc);
}

TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
       SetEncodedFrameBufferFunction_MatchSsrcWithDefaultStream) {
  testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)> callback;
  EXPECT_CALL(callback, Call);
  EXPECT_TRUE(channel_->AddRecvStream(
      cricket::StreamParams::CreateLegacy(kSsrc), /*is_default_stream=*/true));
  EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
  channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
  DeliverKeyFrame(kSsrc);
  EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
  channel_->RemoveRecvStream(kSsrc);
}

TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
       SetEncodedFrameBufferFunction_MatchSsrc) {
  testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)> callback;
  EXPECT_CALL(callback, Call);
  EXPECT_TRUE(channel_->AddRecvStream(
      cricket::StreamParams::CreateLegacy(kSsrc), /*is_default_stream=*/false));
  EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
  channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
  DeliverKeyFrame(kSsrc);
  EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
  channel_->RemoveRecvStream(kSsrc);
}

TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
       SetEncodedFrameBufferFunction_MismatchSsrc) {
  testing::StrictMock<
      testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)>>
      callback;
  EXPECT_TRUE(
      channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc + 1),
                              /*is_default_stream=*/false));
  EXPECT_TRUE(channel_->SetSink(kSsrc + 1, &renderer_));
  channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
  DeliverKeyFrame(kSsrc);  // Expected to not cause function to fire.
  DeliverKeyFrameAndWait(kSsrc + 1);
  channel_->RemoveRecvStream(kSsrc + 1);
}

TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
       SetEncodedFrameBufferFunction_MismatchSsrcWithDefaultStream) {
  testing::StrictMock<
      testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)>>
      callback;
  EXPECT_TRUE(
      channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc + 1),
                              /*is_default_stream=*/true));
  EXPECT_TRUE(channel_->SetSink(kSsrc + 1, &renderer_));
  channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
  DeliverKeyFrame(kSsrc);  // Expected to not cause function to fire.
  DeliverKeyFrameAndWait(kSsrc + 1);
  channel_->RemoveRecvStream(kSsrc + 1);
}

class WebRtcVideoChannelBaseTest : public ::testing::Test {
 protected:
  WebRtcVideoChannelBaseTest()
      : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
        video_bitrate_allocator_factory_(
            webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
        engine_(webrtc::CreateBuiltinVideoEncoderFactory(),
                webrtc::CreateBuiltinVideoDecoderFactory(),
                field_trials_) {}

  void SetUp() override {
    // One testcase calls SetUp in a loop, only create call_ once.
    if (!call_) {
      webrtc::Call::Config call_config(&event_log_);
      call_config.task_queue_factory = task_queue_factory_.get();
      call_config.trials = &field_trials_;
      call_.reset(webrtc::Call::Create(call_config));
    }
    cricket::MediaConfig media_config;
    // Disabling cpu overuse detection actually disables quality scaling too; it
    // implies DegradationPreference kMaintainResolution. Automatic scaling
    // needs to be disabled, otherwise, tests which check the size of received
    // frames become flaky.
    media_config.video.enable_cpu_adaptation = false;
    channel_.reset(
        static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
            call_.get(), media_config, cricket::VideoOptions(),
            webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())));
    channel_->OnReadyToSend(true);
    EXPECT_TRUE(channel_.get() != NULL);
    network_interface_.SetDestination(channel_.get());
    channel_->SetInterface(&network_interface_);
    cricket::VideoRecvParameters parameters;
    parameters.codecs = engine_.send_codecs();
    channel_->SetRecvParameters(parameters);
    EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
    frame_forwarder_ = std::make_unique<webrtc::test::FrameForwarder>();
    frame_source_ = std::make_unique<cricket::FakeFrameSource>(
        640, 480, rtc::kNumMicrosecsPerSec / kFramerate);
    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
  }

  // Utility method to setup an additional stream to send and receive video.
  // Used to test send and recv between two streams.
  void SetUpSecondStream() {
    SetUpSecondStreamWithNoRecv();
    // Setup recv for second stream.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc + 2)));
    // Make the second renderer available for use by a new stream.
    EXPECT_TRUE(channel_->SetSink(kSsrc + 2, &renderer2_));
  }

  // Setup an additional stream just to send video. Defer add recv stream.
  // This is required if you want to test unsignalled recv of video rtp packets.
  void SetUpSecondStreamWithNoRecv() {
    // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
    EXPECT_TRUE(
        channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
    EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
    EXPECT_FALSE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(kSsrc + 2)));
    // We dont add recv for the second stream.

    // Setup the receive and renderer for second stream after send.
    frame_forwarder_2_ = std::make_unique<webrtc::test::FrameForwarder>();
    EXPECT_TRUE(
        channel_->SetVideoSend(kSsrc + 2, nullptr, frame_forwarder_2_.get()));
  }

  void TearDown() override {
    channel_->SetInterface(nullptr);
    channel_.reset();
  }

  void ResetTest() {
    TearDown();
    SetUp();
  }

  bool SetDefaultCodec() { return SetOneCodec(DefaultCodec()); }

  bool SetOneCodec(const cricket::VideoCodec& codec) {
    frame_source_ = std::make_unique<cricket::FakeFrameSource>(
        kVideoWidth, kVideoHeight, rtc::kNumMicrosecsPerSec / kFramerate);

    bool sending = channel_->sending();
    bool success = SetSend(false);
    if (success) {
      cricket::VideoSendParameters parameters;
      parameters.codecs.push_back(codec);
      success = channel_->SetSendParameters(parameters);
    }
    if (success) {
      success = SetSend(sending);
    }
    return success;
  }
  bool SetSend(bool send) { return channel_->SetSend(send); }
  void SendFrame() {
    if (frame_forwarder_2_) {
      frame_forwarder_2_->IncomingCapturedFrame(frame_source_->GetFrame());
    }
    frame_forwarder_->IncomingCapturedFrame(frame_source_->GetFrame());
  }
  bool WaitAndSendFrame(int wait_ms) {
    bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms);
    SendFrame();
    return ret;
  }
  int NumRtpBytes() { return network_interface_.NumRtpBytes(); }
  int NumRtpBytes(uint32_t ssrc) {
    return network_interface_.NumRtpBytes(ssrc);
  }
  int NumRtpPackets() { return network_interface_.NumRtpPackets(); }
  int NumRtpPackets(uint32_t ssrc) {
    return network_interface_.NumRtpPackets(ssrc);
  }
  int NumSentSsrcs() { return network_interface_.NumSentSsrcs(); }
  rtc::CopyOnWriteBuffer GetRtpPacket(int index) {
    return network_interface_.GetRtpPacket(index);
  }
  static int GetPayloadType(rtc::CopyOnWriteBuffer p) {
    RtpPacket header;
    EXPECT_TRUE(header.Parse(std::move(p)));
    return header.PayloadType();
  }

  // Tests that we can send and receive frames.
  void SendAndReceive(const cricket::VideoCodec& codec) {
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));
    channel_->SetDefaultSink(&renderer_);
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    SendFrame();
    EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
    EXPECT_EQ(codec.id, GetPayloadType(GetRtpPacket(0)));
  }

  void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
                                  int duration_sec,
                                  int fps) {
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));
    channel_->SetDefaultSink(&renderer_);
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    for (int i = 0; i < duration_sec; ++i) {
      for (int frame = 1; frame <= fps; ++frame) {
        EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
        EXPECT_FRAME_WAIT(frame + i * fps, kVideoWidth, kVideoHeight, kTimeout);
      }
    }
    EXPECT_EQ(codec.id, GetPayloadType(GetRtpPacket(0)));
  }

  cricket::VideoSenderInfo GetSenderStats(size_t i) {
    cricket::VideoMediaInfo info;
    EXPECT_TRUE(channel_->GetStats(&info));
    return info.senders[i];
  }

  cricket::VideoReceiverInfo GetReceiverStats(size_t i) {
    cricket::VideoMediaInfo info;
    EXPECT_TRUE(channel_->GetStats(&info));
    return info.receivers[i];
  }

  // Two streams one channel tests.

  // Tests that we can send and receive frames.
  void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
    SetUpSecondStream();
    // Test sending and receiving on first stream.
    SendAndReceive(codec);
    // Test sending and receiving on second stream.
    EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
    EXPECT_GT(NumRtpPackets(), 0);
    EXPECT_EQ(1, renderer2_.num_rendered_frames());
  }

  cricket::VideoCodec GetEngineCodec(const std::string& name) {
    for (const cricket::VideoCodec& engine_codec : engine_.send_codecs()) {
      if (absl::EqualsIgnoreCase(name, engine_codec.name))
        return engine_codec;
    }
    // This point should never be reached.
    ADD_FAILURE() << "Unrecognized codec name: " << name;
    return cricket::VideoCodec();
  }

  cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }

  cricket::StreamParams DefaultSendStreamParams() {
    return cricket::StreamParams::CreateLegacy(kSsrc);
  }

  rtc::AutoThread main_thread_;
  webrtc::RtcEventLogNull event_log_;
  webrtc::test::ScopedKeyValueConfig field_trials_;
  std::unique_ptr<webrtc::test::ScopedKeyValueConfig> override_field_trials_;
  std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
  std::unique_ptr<webrtc::Call> call_;
  std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
      video_bitrate_allocator_factory_;
  WebRtcVideoEngine engine_;

  std::unique_ptr<cricket::FakeFrameSource> frame_source_;
  std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_;
  std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_2_;

  std::unique_ptr<WebRtcVideoChannel> channel_;
  cricket::FakeNetworkInterface network_interface_;
  cricket::FakeVideoRenderer renderer_;

  // Used by test cases where 2 streams are run on the same channel.
  cricket::FakeVideoRenderer renderer2_;
};

// Test that SetSend works.
TEST_F(WebRtcVideoChannelBaseTest, SetSend) {
  EXPECT_FALSE(channel_->sending());
  EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  EXPECT_FALSE(channel_->sending());
  EXPECT_TRUE(SetSend(true));
  EXPECT_TRUE(channel_->sending());
  SendFrame();
  EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
  EXPECT_TRUE(SetSend(false));
  EXPECT_FALSE(channel_->sending());
}

// Test that SetSend fails without codecs being set.
TEST_F(WebRtcVideoChannelBaseTest, SetSendWithoutCodecs) {
  EXPECT_FALSE(channel_->sending());
  EXPECT_FALSE(SetSend(true));
  EXPECT_FALSE(channel_->sending());
}

// Test that we properly set the send and recv buffer sizes by the time
// SetSend is called.
TEST_F(WebRtcVideoChannelBaseTest, SetSendSetsTransportBufferSizes) {
  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  EXPECT_TRUE(SetSend(true));
  EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
  EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
}

// Test that we properly set the send and recv buffer sizes when overriding
// via field trials.
TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSize) {
  // Set field trial to override the default recv buffer size, and then re-run
  // setup where the interface is created and configured.
  const int kCustomRecvBufferSize = 123456;
  override_field_trials_ = std::make_unique<webrtc::test::ScopedKeyValueConfig>(
      field_trials_, "WebRTC-IncreasedReceivebuffers/123456/");

  ResetTest();

  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  EXPECT_TRUE(SetSend(true));
  EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
  EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
}

// Test that we properly set the send and recv buffer sizes when overriding
// via field trials with suffix.
TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSizeWithSuffix) {
  // Set field trial to override the default recv buffer size, and then re-run
  // setup where the interface is created and configured.
  const int kCustomRecvBufferSize = 123456;
  override_field_trials_ = std::make_unique<webrtc::test::ScopedKeyValueConfig>(
      field_trials_, "WebRTC-IncreasedReceivebuffers/123456_Dogfood/");
  ResetTest();

  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  EXPECT_TRUE(SetSend(true));
  EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
  EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
}

class InvalidRecvBufferSizeFieldTrial
    : public WebRtcVideoChannelBaseTest,
      public ::testing::WithParamInterface<const char*> {};

// Test that we properly set the send and recv buffer sizes when overriding
// via field trials that don't make any sense.
TEST_P(InvalidRecvBufferSizeFieldTrial, InvalidRecvBufferSize) {
  // Set bogus field trial values to override the default recv buffer size, and
  // then re-run setup where the interface is created and configured. The
  // default value should still be used.
  override_field_trials_ = std::make_unique<webrtc::test::ScopedKeyValueConfig>(
      field_trials_,
      std::string("WebRTC-IncreasedReceivebuffers/") + GetParam() + "/");

  ResetTest();

  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  EXPECT_TRUE(SetSend(true));
  EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
  EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
}

INSTANTIATE_TEST_SUITE_P(All,
                         InvalidRecvBufferSizeFieldTrial,
                         Values("NotANumber", "-1", " ", "0"));

// Test that stats work properly for a 1-1 call.
TEST_F(WebRtcVideoChannelBaseTest, GetStats) {
  const int kDurationSec = 3;
  const int kFps = 10;
  SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);

  cricket::VideoMediaInfo info;
  EXPECT_TRUE(channel_->GetStats(&info));

  ASSERT_EQ(1U, info.senders.size());
  // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
  // For webrtc, bytes_sent does not include the RTP header length.
  EXPECT_EQ(info.senders[0].payload_bytes_sent,
            NumRtpBytes() - kRtpHeaderSize * NumRtpPackets());
  EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
  EXPECT_EQ(0.0, info.senders[0].fraction_lost);
  ASSERT_TRUE(info.senders[0].codec_payload_type);
  EXPECT_EQ(DefaultCodec().id, *info.senders[0].codec_payload_type);
  EXPECT_EQ(0, info.senders[0].firs_rcvd);
  EXPECT_EQ(0, info.senders[0].plis_rcvd);
  EXPECT_EQ(0u, info.senders[0].nacks_rcvd);
  EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
  EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
  EXPECT_GT(info.senders[0].framerate_input, 0);
  EXPECT_GT(info.senders[0].framerate_sent, 0);

  EXPECT_EQ(1U, info.send_codecs.count(DefaultCodec().id));
  EXPECT_EQ(DefaultCodec().ToCodecParameters(),
            info.send_codecs[DefaultCodec().id]);

  ASSERT_EQ(1U, info.receivers.size());
  EXPECT_EQ(1U, info.senders[0].ssrcs().size());
  EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
  EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
  ASSERT_TRUE(info.receivers[0].codec_payload_type);
  EXPECT_EQ(DefaultCodec().id, *info.receivers[0].codec_payload_type);
  EXPECT_EQ(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(),
            info.receivers[0].payload_bytes_rcvd);
  EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
  EXPECT_EQ(0, info.receivers[0].packets_lost);
  // TODO(asapersson): Not set for webrtc. Handle missing stats.
  // EXPECT_EQ(0, info.receivers[0].packets_concealed);
  EXPECT_EQ(0, info.receivers[0].firs_sent);
  EXPECT_EQ(0, info.receivers[0].plis_sent);
  EXPECT_EQ(0U, info.receivers[0].nacks_sent);
  EXPECT_EQ(kVideoWidth, info.receivers[0].frame_width);
  EXPECT_EQ(kVideoHeight, info.receivers[0].frame_height);
  EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
  EXPECT_GT(info.receivers[0].framerate_decoded, 0);
  EXPECT_GT(info.receivers[0].framerate_output, 0);

  EXPECT_EQ(1U, info.receive_codecs.count(DefaultCodec().id));
  EXPECT_EQ(DefaultCodec().ToCodecParameters(),
            info.receive_codecs[DefaultCodec().id]);
}

// Test that stats work properly for a conf call with multiple recv streams.
TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) {
  cricket::FakeVideoRenderer renderer1, renderer2;
  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(DefaultCodec());
  parameters.conference_mode = true;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  EXPECT_TRUE(SetSend(true));
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
  EXPECT_TRUE(channel_->SetSink(1, &renderer1));
  EXPECT_TRUE(channel_->SetSink(2, &renderer2));
  EXPECT_EQ(0, renderer1.num_rendered_frames());
  EXPECT_EQ(0, renderer2.num_rendered_frames());
  std::vector<uint32_t> ssrcs;
  ssrcs.push_back(1);
  ssrcs.push_back(2);
  network_interface_.SetConferenceMode(true, ssrcs);
  SendFrame();
  EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
                                kTimeout);
  EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
                                kTimeout);

  EXPECT_TRUE(channel_->SetSend(false));

  cricket::VideoMediaInfo info;
  EXPECT_TRUE(channel_->GetStats(&info));
  ASSERT_EQ(1U, info.senders.size());
  // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
  // For webrtc, bytes_sent does not include the RTP header length.
  EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(),
                 GetSenderStats(0).payload_bytes_sent, kTimeout);
  EXPECT_EQ_WAIT(NumRtpPackets(), GetSenderStats(0).packets_sent, kTimeout);
  EXPECT_EQ(kVideoWidth, GetSenderStats(0).send_frame_width);
  EXPECT_EQ(kVideoHeight, GetSenderStats(0).send_frame_height);

  ASSERT_EQ(2U, info.receivers.size());
  for (size_t i = 0; i < info.receivers.size(); ++i) {
    EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size());
    EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]);
    EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(),
                   GetReceiverStats(i).payload_bytes_rcvd, kTimeout);
    EXPECT_EQ_WAIT(NumRtpPackets(), GetReceiverStats(i).packets_rcvd, kTimeout);
    EXPECT_EQ_WAIT(kVideoWidth, GetReceiverStats(i).frame_width, kTimeout);
    EXPECT_EQ_WAIT(kVideoHeight, GetReceiverStats(i).frame_height, kTimeout);
  }
}

// Test that stats work properly for a conf call with multiple send streams.
TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) {
  // Normal setup; note that we set the SSRC explicitly to ensure that
  // it will come first in the senders map.
  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(DefaultCodec());
  parameters.conference_mode = true;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  EXPECT_TRUE(
      channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
  EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
  EXPECT_TRUE(SetSend(true));
  SendFrame();
  EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
  EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);

  // Add an additional capturer, and hook up a renderer to receive it.
  cricket::FakeVideoRenderer renderer2;
  webrtc::test::FrameForwarder frame_forwarder;
  const int kTestWidth = 160;
  const int kTestHeight = 120;
  cricket::FakeFrameSource frame_source(kTestWidth, kTestHeight,
                                        rtc::kNumMicrosecsPerSec / 5);
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(5678)));
  EXPECT_TRUE(channel_->SetVideoSend(5678, nullptr, &frame_forwarder));
  EXPECT_TRUE(
      channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(5678)));
  EXPECT_TRUE(channel_->SetSink(5678, &renderer2));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
                                kTimeout);

  // Get stats, and make sure they are correct for two senders. We wait until
  // the number of expected packets have been sent to avoid races where we
  // check stats before it has been updated.
  cricket::VideoMediaInfo info;
  for (uint32_t i = 0; i < kTimeout; ++i) {
    rtc::Thread::Current()->ProcessMessages(1);
    EXPECT_TRUE(channel_->GetStats(&info));
    ASSERT_EQ(2U, info.senders.size());
    if (info.senders[0].packets_sent + info.senders[1].packets_sent ==
        NumRtpPackets()) {
      // Stats have been updated for both sent frames, expectations can be
      // checked now.
      break;
    }
  }
  EXPECT_EQ(NumRtpPackets(),
            info.senders[0].packets_sent + info.senders[1].packets_sent)
      << "Timed out while waiting for packet counts for all sent packets.";
  EXPECT_EQ(1U, info.senders[0].ssrcs().size());
  EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
  EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
  EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
  EXPECT_EQ(1U, info.senders[1].ssrcs().size());
  EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
  EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
  EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
  // The capturer must be unregistered here as it runs out of it's scope next.
  channel_->SetVideoSend(5678, nullptr, nullptr);
}

// Test that we can set the bandwidth.
TEST_F(WebRtcVideoChannelBaseTest, SetSendBandwidth) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(DefaultCodec());
  parameters.max_bandwidth_bps = -1;  // <= 0 means unlimited.
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  parameters.max_bandwidth_bps = 128 * 1024;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
}

// Test that we can set the SSRC for the default send source.
TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrc) {
  EXPECT_TRUE(SetDefaultCodec());
  EXPECT_TRUE(SetSend(true));
  SendFrame();
  EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
  RtpPacket header;
  EXPECT_TRUE(header.Parse(GetRtpPacket(0)));
  EXPECT_EQ(kSsrc, header.Ssrc());

  // Packets are being paced out, so these can mismatch between the first and
  // second call to NumRtpPackets until pending packets are paced out.
  EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.Ssrc()), kTimeout);
  EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.Ssrc()), kTimeout);
  EXPECT_EQ(1, NumSentSsrcs());
  EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
  EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
}

// Test that we can set the SSRC even after codecs are set.
TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrcAfterSetCodecs) {
  // Remove stream added in Setup.
  EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
  EXPECT_TRUE(SetDefaultCodec());
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(999)));
  EXPECT_TRUE(channel_->SetVideoSend(999u, nullptr, frame_forwarder_.get()));
  EXPECT_TRUE(SetSend(true));
  EXPECT_TRUE(WaitAndSendFrame(0));
  EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
  RtpPacket header;
  EXPECT_TRUE(header.Parse(GetRtpPacket(0)));
  EXPECT_EQ(999u, header.Ssrc());
  // Packets are being paced out, so these can mismatch between the first and
  // second call to NumRtpPackets until pending packets are paced out.
  EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.Ssrc()), kTimeout);
  EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.Ssrc()), kTimeout);
  EXPECT_EQ(1, NumSentSsrcs());
  EXPECT_EQ(0, NumRtpPackets(kSsrc));
  EXPECT_EQ(0, NumRtpBytes(kSsrc));
}

// Test that we can set the default video renderer before and after
// media is received.
TEST_F(WebRtcVideoChannelBaseTest, SetSink) {
  RtpPacket packet;
  packet.SetSsrc(kSsrc);
  channel_->SetDefaultSink(NULL);
  EXPECT_TRUE(SetDefaultCodec());
  EXPECT_TRUE(SetSend(true));
  EXPECT_EQ(0, renderer_.num_rendered_frames());
  channel_->OnPacketReceived(packet.Buffer(), /* packet_time_us */ -1);
  channel_->SetDefaultSink(&renderer_);
  SendFrame();
  EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
}

// Tests setting up and configuring a send stream.
TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) {
  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  EXPECT_TRUE(SetSend(true));
  channel_->SetDefaultSink(&renderer_);
  SendFrame();
  EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
  EXPECT_GT(NumRtpPackets(), 0);
  RtpPacket header;
  size_t last_packet = NumRtpPackets() - 1;
  EXPECT_TRUE(header.Parse(GetRtpPacket(static_cast<int>(last_packet))));
  EXPECT_EQ(kSsrc, header.Ssrc());

  // Remove the send stream that was added during Setup.
  EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
  int rtp_packets = NumRtpPackets();

  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
  EXPECT_TRUE(channel_->SetVideoSend(789u, nullptr, frame_forwarder_.get()));
  EXPECT_EQ(rtp_packets, NumRtpPackets());
  // Wait 30ms to guarantee the engine does not drop the frame.
  EXPECT_TRUE(WaitAndSendFrame(30));
  EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);

  last_packet = NumRtpPackets() - 1;
  EXPECT_TRUE(header.Parse(GetRtpPacket(static_cast<int>(last_packet))));
  EXPECT_EQ(789u, header.Ssrc());
}

// Tests the behavior of incoming streams in a conference scenario.
TEST_F(WebRtcVideoChannelBaseTest, SimulateConference) {
  cricket::FakeVideoRenderer renderer1, renderer2;
  EXPECT_TRUE(SetDefaultCodec());
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(DefaultCodec());
  parameters.conference_mode = true;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  EXPECT_TRUE(SetSend(true));
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
  EXPECT_TRUE(channel_->SetSink(1, &renderer1));
  EXPECT_TRUE(channel_->SetSink(2, &renderer2));
  EXPECT_EQ(0, renderer1.num_rendered_frames());
  EXPECT_EQ(0, renderer2.num_rendered_frames());
  std::vector<uint32_t> ssrcs;
  ssrcs.push_back(1);
  ssrcs.push_back(2);
  network_interface_.SetConferenceMode(true, ssrcs);
  SendFrame();
  EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
                                kTimeout);
  EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
                                kTimeout);

  EXPECT_EQ(DefaultCodec().id, GetPayloadType(GetRtpPacket(0)));
  EXPECT_EQ(kVideoWidth, renderer1.width());
  EXPECT_EQ(kVideoHeight, renderer1.height());
  EXPECT_EQ(kVideoWidth, renderer2.width());
  EXPECT_EQ(kVideoHeight, renderer2.height());
  EXPECT_TRUE(channel_->RemoveRecvStream(2));
  EXPECT_TRUE(channel_->RemoveRecvStream(1));
}

// Tests that we can add and remove capturers and frames are sent out properly
TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) {
  using cricket::FOURCC_I420;
  using cricket::VideoCodec;
  using cricket::VideoFormat;
  using cricket::VideoOptions;

  VideoCodec codec = DefaultCodec();
  const int time_between_send_ms = VideoFormat::FpsToInterval(kFramerate);
  EXPECT_TRUE(SetOneCodec(codec));
  EXPECT_TRUE(SetSend(true));
  channel_->SetDefaultSink(&renderer_);
  EXPECT_EQ(0, renderer_.num_rendered_frames());
  SendFrame();
  EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);

  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(480, 360, rtc::kNumMicrosecsPerSec / 30,
                                        rtc::kNumMicrosecsPerSec / 30);

  // TODO(nisse): This testcase fails if we don't configure
  // screencast. It's unclear why, I see nothing obvious in this
  // test which is related to screencast logic.
  VideoOptions video_options;
  video_options.is_screencast = true;
  channel_->SetVideoSend(kSsrc, &video_options, nullptr);

  int captured_frames = 1;
  for (int iterations = 0; iterations < 2; ++iterations) {
    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
    rtc::Thread::Current()->ProcessMessages(time_between_send_ms);
    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    ++captured_frames;
    // Wait until frame of right size is captured.
    EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
                         480 == renderer_.width() &&
                         360 == renderer_.height() && !renderer_.black_frame(),
                     kTimeout);
    EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
    EXPECT_EQ(480, renderer_.width());
    EXPECT_EQ(360, renderer_.height());
    captured_frames = renderer_.num_rendered_frames() + 1;
    EXPECT_FALSE(renderer_.black_frame());
    EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
    // Make sure a black frame is generated within the specified timeout.
    // The black frame should be the resolution of the previous frame to
    // prevent expensive encoder reconfigurations.
    EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
                         480 == renderer_.width() &&
                         360 == renderer_.height() && renderer_.black_frame(),
                     kTimeout);
    EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
    EXPECT_EQ(480, renderer_.width());
    EXPECT_EQ(360, renderer_.height());
    EXPECT_TRUE(renderer_.black_frame());

    // The black frame has the same timestamp as the next frame since it's
    // timestamp is set to the last frame's timestamp + interval. WebRTC will
    // not render a frame with the same timestamp so capture another frame
    // with the frame capturer to increment the next frame's timestamp.
    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  }
}

// Tests that if SetVideoSend is called with a NULL capturer after the
// capturer was already removed, the application doesn't crash (and no black
// frame is sent).
TEST_F(WebRtcVideoChannelBaseTest, RemoveCapturerWithoutAdd) {
  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  EXPECT_TRUE(SetSend(true));
  channel_->SetDefaultSink(&renderer_);
  EXPECT_EQ(0, renderer_.num_rendered_frames());
  SendFrame();
  EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
  // Wait for one frame so they don't get dropped because we send frames too
  // tightly.
  rtc::Thread::Current()->ProcessMessages(30);
  // Remove the capturer.
  EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));

  // No capturer was added, so this SetVideoSend shouldn't do anything.
  EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
  rtc::Thread::Current()->ProcessMessages(300);
  // Verify no more frames were sent.
  EXPECT_EQ(1, renderer_.num_rendered_frames());
}

// Tests that we can add and remove capturer as unique sources.
TEST_F(WebRtcVideoChannelBaseTest, AddRemoveCapturerMultipleSources) {
  // WebRTC implementation will drop frames if pushed to quickly. Wait the
  // interval time to avoid that.
  // WebRTC implementation will drop frames if pushed to quickly. Wait the
  // interval time to avoid that.
  // Set up the stream associated with the engine.
  EXPECT_TRUE(
      channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
  EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
  cricket::VideoFormat capture_format(
      kVideoWidth, kVideoHeight,
      cricket::VideoFormat::FpsToInterval(kFramerate), cricket::FOURCC_I420);
  // Set up additional stream 1.
  cricket::FakeVideoRenderer renderer1;
  EXPECT_FALSE(channel_->SetSink(1, &renderer1));
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
  EXPECT_TRUE(channel_->SetSink(1, &renderer1));
  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));

  webrtc::test::FrameForwarder frame_forwarder1;
  cricket::FakeFrameSource frame_source(kVideoWidth, kVideoHeight,
                                        rtc::kNumMicrosecsPerSec / kFramerate);

  // Set up additional stream 2.
  cricket::FakeVideoRenderer renderer2;
  EXPECT_FALSE(channel_->SetSink(2, &renderer2));
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
  EXPECT_TRUE(channel_->SetSink(2, &renderer2));
  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
  webrtc::test::FrameForwarder frame_forwarder2;

  // State for all the streams.
  EXPECT_TRUE(SetOneCodec(DefaultCodec()));
  // A limitation in the lmi implementation requires that SetVideoSend() is
  // called after SetOneCodec().
  // TODO(hellner): this seems like an unnecessary constraint, fix it.
  EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, &frame_forwarder1));
  EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, &frame_forwarder2));
  EXPECT_TRUE(SetSend(true));
  // Test capturer associated with engine.
  const int kTestWidth = 160;
  const int kTestHeight = 120;
  frame_forwarder1.IncomingCapturedFrame(frame_source.GetFrame(
      kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
      rtc::kNumMicrosecsPerSec / kFramerate));
  EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kTestWidth, kTestHeight,
                                kTimeout);
  // Capture a frame with additional capturer2, frames should be received
  frame_forwarder2.IncomingCapturedFrame(frame_source.GetFrame(
      kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
      rtc::kNumMicrosecsPerSec / kFramerate));
  EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
                                kTimeout);
  // Successfully remove the capturer.
  EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
  // The capturers must be unregistered here as it runs out of it's scope
  // next.
  EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, nullptr));
  EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, nullptr));
}

// Tests empty StreamParams is rejected.
TEST_F(WebRtcVideoChannelBaseTest, RejectEmptyStreamParams) {
  // Remove the send stream that was added during Setup.
  EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));

  cricket::StreamParams empty;
  EXPECT_FALSE(channel_->AddSendStream(empty));
  EXPECT_TRUE(
      channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
}

// Test that multiple send streams can be created and deleted properly.
TEST_F(WebRtcVideoChannelBaseTest, MultipleSendStreams) {
  // Remove stream added in Setup. I.e. remove stream corresponding to default
  // channel.
  EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
  const unsigned int kSsrcsSize = sizeof(kSsrcs4) / sizeof(kSsrcs4[0]);
  for (unsigned int i = 0; i < kSsrcsSize; ++i) {
    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
  }
  // Delete one of the non default channel streams, let the destructor delete
  // the remaining ones.
  EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
  // Stream should already be deleted.
  EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
}

TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Vga) {
  SendAndReceive(GetEngineCodec("VP8"));
}

TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Qvga) {
  SendAndReceive(GetEngineCodec("VP8"));
}

TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8SvcQqvga) {
  SendAndReceive(GetEngineCodec("VP8"));
}

TEST_F(WebRtcVideoChannelBaseTest, TwoStreamsSendAndReceive) {
  // Set a high bitrate to not be downscaled by VP8 due to low initial start
  // bitrates. This currently happens at <250k, and two streams sharing 300k
  // initially will use QVGA instead of VGA.
  // TODO(pbos): Set up the quality scaler so that both senders reliably start
  // at QVGA, then verify that instead.
  cricket::VideoCodec codec = GetEngineCodec("VP8");
  codec.params[kCodecParamStartBitrate] = "1000000";
  TwoStreamsSendAndReceive(codec);
}

#if defined(RTC_ENABLE_VP9)

TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderFallback) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  VideoCodec codec;
  ASSERT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_EQ("VP9", codec.name);

  // RequestEncoderFallback will post a task to the worker thread (which is also
  // the current thread), hence the ProcessMessages call.
  channel_->RequestEncoderFallback();
  rtc::Thread::Current()->ProcessMessages(30);
  ASSERT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_EQ("VP8", codec.name);

  // No other codec to fall back to, keep using VP8.
  channel_->RequestEncoderFallback();
  rtc::Thread::Current()->ProcessMessages(30);
  ASSERT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_EQ("VP8", codec.name);
}

TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchDefaultFallback) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  VideoCodec codec;
  ASSERT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_EQ("VP9", codec.name);

  // RequestEncoderSwitch will post a task to the worker thread (which is also
  // the current thread), hence the ProcessMessages call.
  channel_->RequestEncoderSwitch(webrtc::SdpVideoFormat("UnavailableCodec"),
                                 /*allow_default_fallback=*/true);
  rtc::Thread::Current()->ProcessMessages(30);

  // Requested encoder is not available. Default fallback is allowed. Switch to
  // the next negotiated codec, VP8.
  ASSERT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_EQ("VP8", codec.name);
}

TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchStrictPreference) {
  VideoCodec vp9 = GetEngineCodec("VP9");
  vp9.params["profile-id"] = "0";

  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(vp9);
  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  VideoCodec codec;
  ASSERT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_EQ("VP8", codec.name);

  channel_->RequestEncoderSwitch(
      webrtc::SdpVideoFormat("VP9", {{"profile-id", "1"}}),
      /*allow_default_fallback=*/false);
  rtc::Thread::Current()->ProcessMessages(30);

  // VP9 profile_id=1 is not available. Default fallback is not allowed. Switch
  // is not performed.
  ASSERT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_EQ("VP8", codec.name);

  channel_->RequestEncoderSwitch(
      webrtc::SdpVideoFormat("VP9", {{"profile-id", "0"}}),
      /*allow_default_fallback=*/false);
  rtc::Thread::Current()->ProcessMessages(30);

  // VP9 profile_id=0 is available. Switch encoder.
  ASSERT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_EQ("VP9", codec.name);
}

TEST_F(WebRtcVideoChannelBaseTest, SendCodecIsMovedToFrontInRtpParameters) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  channel_->SetVideoCodecSwitchingEnabled(true);

  auto send_codecs = channel_->GetRtpSendParameters(kSsrc).codecs;
  ASSERT_EQ(send_codecs.size(), 2u);
  EXPECT_THAT("VP9", send_codecs[0].name);

  // RequestEncoderFallback will post a task to the worker thread (which is also
  // the current thread), hence the ProcessMessages call.
  channel_->RequestEncoderFallback();
  rtc::Thread::Current()->ProcessMessages(30);

  send_codecs = channel_->GetRtpSendParameters(kSsrc).codecs;
  ASSERT_EQ(send_codecs.size(), 2u);
  EXPECT_THAT("VP8", send_codecs[0].name);
}

#endif  // defined(RTC_ENABLE_VP9)

class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
 public:
  WebRtcVideoChannelTest() : WebRtcVideoChannelTest("") {}
  explicit WebRtcVideoChannelTest(const char* field_trials)
      : WebRtcVideoEngineTest(field_trials),
        frame_source_(1280, 720, rtc::kNumMicrosecsPerSec / 30),
        last_ssrc_(0) {}
  void SetUp() override {
    AddSupportedVideoCodecType("VP8");
    AddSupportedVideoCodecType("VP9");
#if defined(WEBRTC_USE_H264)
    AddSupportedVideoCodecType("H264");
#endif

    fake_call_.reset(new FakeCall(&field_trials_));
    channel_.reset(engine_.CreateMediaChannel(
        fake_call_.get(), GetMediaConfig(), VideoOptions(),
        webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
    channel_->OnReadyToSend(true);
    last_ssrc_ = 123;
    send_parameters_.codecs = engine_.send_codecs();
    recv_parameters_.codecs = engine_.recv_codecs();
    ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
  }

  void TearDown() override {
    channel_->SetInterface(nullptr);
    channel_ = nullptr;
    fake_call_ = nullptr;
  }

  void ResetTest() {
    TearDown();
    SetUp();
  }

  cricket::VideoCodec GetEngineCodec(const std::string& name) {
    for (const cricket::VideoCodec& engine_codec : engine_.send_codecs()) {
      if (absl::EqualsIgnoreCase(name, engine_codec.name))
        return engine_codec;
    }
    // This point should never be reached.
    ADD_FAILURE() << "Unrecognized codec name: " << name;
    return cricket::VideoCodec();
  }

  cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }

  // After receciving and processing the packet, enough time is advanced that
  // the unsignalled receive stream cooldown is no longer in effect.
  void ReceivePacketAndAdvanceTime(rtc::CopyOnWriteBuffer packet,
                                   int64_t packet_time_us) {
    channel_->OnPacketReceived(packet, packet_time_us);
    rtc::Thread::Current()->ProcessMessages(0);
    time_controller_.AdvanceTime(
        webrtc::TimeDelta::Millis(kUnsignalledReceiveStreamCooldownMs));
  }

 protected:
  FakeVideoSendStream* AddSendStream() {
    return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
  }

  FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
    size_t num_streams = fake_call_->GetVideoSendStreams().size();
    EXPECT_TRUE(channel_->AddSendStream(sp));
    std::vector<FakeVideoSendStream*> streams =
        fake_call_->GetVideoSendStreams();
    EXPECT_EQ(num_streams + 1, streams.size());
    return streams[streams.size() - 1];
  }

  std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
    return fake_call_->GetVideoSendStreams();
  }

  FakeVideoReceiveStream* AddRecvStream() {
    return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
  }

  FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
    size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
    EXPECT_TRUE(channel_->AddRecvStream(sp));
    std::vector<FakeVideoReceiveStream*> streams =
        fake_call_->GetVideoReceiveStreams();
    EXPECT_EQ(num_streams + 1, streams.size());
    return streams[streams.size() - 1];
  }

  void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
                                          int expected_min_bitrate_bps,
                                          const char* start_bitrate_kbps,
                                          int expected_start_bitrate_bps,
                                          const char* max_bitrate_kbps,
                                          int expected_max_bitrate_bps) {
    ExpectSetBitrateParameters(expected_min_bitrate_bps,
                               expected_start_bitrate_bps,
                               expected_max_bitrate_bps);
    auto& codecs = send_parameters_.codecs;
    codecs.clear();
    codecs.push_back(GetEngineCodec("VP8"));
    codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
    codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
    codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
    EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
  }

  void ExpectSetBitrateParameters(int min_bitrate_bps,
                                  int start_bitrate_bps,
                                  int max_bitrate_bps) {
    EXPECT_CALL(
        *fake_call_->GetMockTransportControllerSend(),
        SetSdpBitrateParameters(AllOf(
            Field(&BitrateConstraints::min_bitrate_bps, min_bitrate_bps),
            Field(&BitrateConstraints::start_bitrate_bps, start_bitrate_bps),
            Field(&BitrateConstraints::max_bitrate_bps, max_bitrate_bps))));
  }

  void ExpectSetMaxBitrate(int max_bitrate_bps) {
    EXPECT_CALL(*fake_call_->GetMockTransportControllerSend(),
                SetSdpBitrateParameters(Field(
                    &BitrateConstraints::max_bitrate_bps, max_bitrate_bps)));
  }

  void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
    // For a caller, the answer will be applied in set remote description
    // where SetSendParameters() is called.
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
    send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
    EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
    const webrtc::VideoSendStream::Config& config =
        fake_call_->GetVideoSendStreams()[0]->GetConfig();
    EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
  }

  void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
    // For a callee, the answer will be applied in set local description
    // where SetExtmapAllowMixed() and AddSendStream() are called.
    channel_->SetExtmapAllowMixed(extmap_allow_mixed);
    EXPECT_TRUE(
        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
    const webrtc::VideoSendStream::Config& config =
        fake_call_->GetVideoSendStreams()[0]->GetConfig();
    EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
  }

  void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
    // Enable extension.
    const int id = 1;
    cricket::VideoSendParameters parameters = send_parameters_;
    parameters.extensions.push_back(RtpExtension(ext_uri, id));
    EXPECT_TRUE(channel_->SetSendParameters(parameters));
    FakeVideoSendStream* send_stream =
        AddSendStream(cricket::StreamParams::CreateLegacy(123));

    // Verify the send extension id.
    ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
    EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
    EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
    // Verify call with same set of extensions returns true.
    EXPECT_TRUE(channel_->SetSendParameters(parameters));
    // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
    // receivers.
    EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
                    ->GetConfig()
                    .rtp.extensions.empty());

    // Verify that existing RTP header extensions can be removed.
    EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
    ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
    send_stream = fake_call_->GetVideoSendStreams()[0];
    EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());

    // Verify that adding receive RTP header extensions adds them for existing
    // streams.
    EXPECT_TRUE(channel_->SetSendParameters(parameters));
    send_stream = fake_call_->GetVideoSendStreams()[0];
    ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
    EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
    EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
  }

  void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
    // Enable extension.
    const int id = 1;
    cricket::VideoRecvParameters parameters = recv_parameters_;
    parameters.extensions.push_back(RtpExtension(ext_uri, id));
    EXPECT_TRUE(channel_->SetRecvParameters(parameters));

    FakeVideoReceiveStream* recv_stream =
        AddRecvStream(cricket::StreamParams::CreateLegacy(123));

    // Verify the recv extension id.
    ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
    EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
    EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
    // Verify call with same set of extensions returns true.
    EXPECT_TRUE(channel_->SetRecvParameters(parameters));

    // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
    // senders.
    EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
                    ->GetConfig()
                    .rtp.extensions.empty());

    // Verify that existing RTP header extensions can be removed.
    EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
    ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
    recv_stream = fake_call_->GetVideoReceiveStreams()[0];
    EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());

    // Verify that adding receive RTP header extensions adds them for existing
    // streams.
    EXPECT_TRUE(channel_->SetRecvParameters(parameters));
    recv_stream = fake_call_->GetVideoReceiveStreams()[0];
    ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
    EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
    EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
  }

  void TestLossNotificationState(bool expect_lntf_enabled) {
    AssignDefaultCodec();
    VerifyCodecHasDefaultFeedbackParams(default_codec_, expect_lntf_enabled);

    cricket::VideoSendParameters parameters;
    parameters.codecs = engine_.send_codecs();
    EXPECT_TRUE(channel_->SetSendParameters(parameters));
    EXPECT_TRUE(channel_->SetSend(true));

    // Send side.
    FakeVideoSendStream* send_stream =
        AddSendStream(cricket::StreamParams::CreateLegacy(1));
    EXPECT_EQ(send_stream->GetConfig().rtp.lntf.enabled, expect_lntf_enabled);

    // Receiver side.
    FakeVideoReceiveStream* recv_stream =
        AddRecvStream(cricket::StreamParams::CreateLegacy(1));
    EXPECT_EQ(recv_stream->GetConfig().rtp.lntf.enabled, expect_lntf_enabled);
  }

  void TestExtensionFilter(const std::vector<std::string>& extensions,
                           const std::string& expected_extension) {
    cricket::VideoSendParameters parameters = send_parameters_;
    int expected_id = -1;
    int id = 1;
    for (const std::string& extension : extensions) {
      if (extension == expected_extension)
        expected_id = id;
      parameters.extensions.push_back(RtpExtension(extension, id++));
    }
    EXPECT_TRUE(channel_->SetSendParameters(parameters));
    FakeVideoSendStream* send_stream =
        AddSendStream(cricket::StreamParams::CreateLegacy(123));

    // Verify that only one of them has been set, and that it is the one with
    // highest priority (transport sequence number).
    ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
    EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
    EXPECT_EQ(expected_extension,
              send_stream->GetConfig().rtp.extensions[0].uri);
  }

  void TestDegradationPreference(bool resolution_scaling_enabled,
                                 bool fps_scaling_enabled);

  void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
  void TestReceiverLocalSsrcConfiguration(bool receiver_first);
  void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
                                       bool expect_created_receive_stream);

  FakeVideoSendStream* SetDenoisingOption(
      uint32_t ssrc,
      webrtc::test::FrameForwarder* frame_forwarder,
      bool enabled) {
    cricket::VideoOptions options;
    options.video_noise_reduction = enabled;
    EXPECT_TRUE(channel_->SetVideoSend(ssrc, &options, frame_forwarder));
    // Options only take effect on the next frame.
    frame_forwarder->IncomingCapturedFrame(frame_source_.GetFrame());

    return fake_call_->GetVideoSendStreams().back();
  }

  FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
    const int kRtxSsrcOffset = 0xDEADBEEF;
    last_ssrc_ += 3;
    std::vector<uint32_t> ssrcs;
    std::vector<uint32_t> rtx_ssrcs;
    uint32_t num_streams = enabled ? 3 : 1;
    for (uint32_t i = 0; i < num_streams; ++i) {
      uint32_t ssrc = last_ssrc_ + i;
      ssrcs.push_back(ssrc);
      if (with_rtx) {
        rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
      }
    }
    if (with_rtx) {
      return AddSendStream(
          cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
    }
    return AddSendStream(CreateSimStreamParams("cname", ssrcs));
  }

  int GetMaxEncoderBitrate() {
    std::vector<FakeVideoSendStream*> streams =
        fake_call_->GetVideoSendStreams();
    EXPECT_EQ(1u, streams.size());
    FakeVideoSendStream* stream = streams[streams.size() - 1];
    EXPECT_EQ(1u, stream->GetEncoderConfig().number_of_streams);
    return stream->GetVideoStreams()[0].max_bitrate_bps;
  }

  void SetAndExpectMaxBitrate(int global_max,
                              int stream_max,
                              int expected_encoder_bitrate) {
    VideoSendParameters limited_send_params = send_parameters_;
    limited_send_params.max_bandwidth_bps = global_max;
    EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
    webrtc::RtpParameters parameters =
        channel_->GetRtpSendParameters(last_ssrc_);
    EXPECT_EQ(1UL, parameters.encodings.size());
    parameters.encodings[0].max_bitrate_bps = stream_max;
    EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
    // Read back the parameteres and verify they have the correct value
    parameters = channel_->GetRtpSendParameters(last_ssrc_);
    EXPECT_EQ(1UL, parameters.encodings.size());
    EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
    // Verify that the new value propagated down to the encoder
    EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
  }

  // Values from kSimulcastConfigs in simulcast.cc.
  const std::vector<webrtc::VideoStream> GetSimulcastBitrates720p() const {
    std::vector<webrtc::VideoStream> layers(3);
    layers[0].min_bitrate_bps = 30000;
    layers[0].target_bitrate_bps = 150000;
    layers[0].max_bitrate_bps = 200000;
    layers[1].min_bitrate_bps = 150000;
    layers[1].target_bitrate_bps = 500000;
    layers[1].max_bitrate_bps = 700000;
    layers[2].min_bitrate_bps = 600000;
    layers[2].target_bitrate_bps = 2500000;
    layers[2].max_bitrate_bps = 2500000;
    return layers;
  }

  cricket::FakeFrameSource frame_source_;
  std::unique_ptr<FakeCall> fake_call_;
  std::unique_ptr<VideoMediaChannel> channel_;
  cricket::VideoSendParameters send_parameters_;
  cricket::VideoRecvParameters recv_parameters_;
  uint32_t last_ssrc_;
};

TEST_F(WebRtcVideoChannelTest, SetsSyncGroupFromSyncLabel) {
  const uint32_t kVideoSsrc = 123;
  const std::string kSyncLabel = "AvSyncLabel";

  cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
  sp.set_stream_ids({kSyncLabel});
  EXPECT_TRUE(channel_->AddRecvStream(sp));

  EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
  EXPECT_EQ(kSyncLabel,
            fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
      << "SyncGroup should be set based on sync_label";
}

TEST_F(WebRtcVideoChannelTest, RecvStreamWithSimAndRtx) {
  cricket::VideoSendParameters parameters;
  parameters.codecs = engine_.send_codecs();
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  EXPECT_TRUE(channel_->SetSend(true));
  parameters.conference_mode = true;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  // Send side.
  const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
  const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
  FakeVideoSendStream* send_stream = AddSendStream(
      cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));

  ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
  for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
    EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);

  // Receiver side.
  FakeVideoReceiveStream* recv_stream = AddRecvStream(
      cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
  EXPECT_FALSE(
      recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
  EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
      << "RTX should be mapped for all decoders/payload types.";
  EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
                                       GetEngineCodec("red").id))
      << "RTX should be mapped for the RED payload type";

  EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
}

TEST_F(WebRtcVideoChannelTest, RecvStreamWithRtx) {
  // Setup one channel with an associated RTX stream.
  cricket::StreamParams params =
      cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
  params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
  FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
  EXPECT_EQ(kRtxSsrcs1[0], recv_stream->GetConfig().rtp.rtx_ssrc);

  EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
      << "RTX should be mapped for all decoders/payload types.";
  EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
                                       GetEngineCodec("red").id))
      << "RTX should be mapped for the RED payload type";
}

TEST_F(WebRtcVideoChannelTest, RecvStreamNoRtx) {
  // Setup one channel without an associated RTX stream.
  cricket::StreamParams params =
      cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
  FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
  ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
}

// Test propagation of extmap allow mixed setting.
TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCaller) {
  TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
}
TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCaller) {
  TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
}
TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCallee) {
  TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
}
TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCallee) {
  TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
}

TEST_F(WebRtcVideoChannelTest, NoHeaderExtesionsByDefault) {
  FakeVideoSendStream* send_stream =
      AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
  ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());

  FakeVideoReceiveStream* recv_stream =
      AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
  ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
}

// Test support for RTP timestamp offset header extension.
TEST_F(WebRtcVideoChannelTest, SendRtpTimestampOffsetHeaderExtensions) {
  TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
}

TEST_F(WebRtcVideoChannelTest, RecvRtpTimestampOffsetHeaderExtensions) {
  TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
}

// Test support for absolute send time header extension.
TEST_F(WebRtcVideoChannelTest, SendAbsoluteSendTimeHeaderExtensions) {
  TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
}

TEST_F(WebRtcVideoChannelTest, RecvAbsoluteSendTimeHeaderExtensions) {
  TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
}

TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksTransportSeqNum) {
  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_, "WebRTC-FilterAbsSendTimeExtension/Enabled/");
  // Enable three redundant extensions.
  std::vector<std::string> extensions;
  extensions.push_back(RtpExtension::kAbsSendTimeUri);
  extensions.push_back(RtpExtension::kTimestampOffsetUri);
  extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
  TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
}

TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksAbsSendTime) {
  // Enable two redundant extensions.
  std::vector<std::string> extensions;
  extensions.push_back(RtpExtension::kAbsSendTimeUri);
  extensions.push_back(RtpExtension::kTimestampOffsetUri);
  TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
}

// Test support for transport sequence number header extension.
TEST_F(WebRtcVideoChannelTest, SendTransportSequenceNumberHeaderExtensions) {
  TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
}
TEST_F(WebRtcVideoChannelTest, RecvTransportSequenceNumberHeaderExtensions) {
  TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
}

// Test support for video rotation header extension.
TEST_F(WebRtcVideoChannelTest, SendVideoRotationHeaderExtensions) {
  TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
}
TEST_F(WebRtcVideoChannelTest, RecvVideoRotationHeaderExtensions) {
  TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
}

TEST_F(WebRtcVideoChannelTest, IdenticalSendExtensionsDoesntRecreateStream) {
  const int kAbsSendTimeId = 1;
  const int kVideoRotationId = 2;
  send_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
  send_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));

  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
  FakeVideoSendStream* send_stream =
      AddSendStream(cricket::StreamParams::CreateLegacy(123));

  EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
  ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());

  // Setting the same extensions (even if in different order) shouldn't
  // reallocate the stream.
  absl::c_reverse(send_parameters_.extensions);
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());

  // Setting different extensions should recreate the stream.
  send_parameters_.extensions.resize(1);
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
}

TEST_F(WebRtcVideoChannelTest, IdenticalRecvExtensionsDoesntRecreateStream) {
  const int kTOffsetId = 1;
  const int kAbsSendTimeId = 2;
  const int kVideoRotationId = 3;
  recv_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
  recv_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
  recv_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));

  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
  FakeVideoReceiveStream* recv_stream =
      AddRecvStream(cricket::StreamParams::CreateLegacy(123));

  EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
  ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());

  // Setting the same extensions (even if in different order) shouldn't
  // reallocate the stream.
  absl::c_reverse(recv_parameters_.extensions);
  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));

  EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());

  // Setting different extensions should not require the stream to be recreated.
  recv_parameters_.extensions.resize(1);
  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));

  EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
}

TEST_F(WebRtcVideoChannelTest,
       SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
  const int kUnsupportedId = 1;
  const int kTOffsetId = 2;

  send_parameters_.extensions.push_back(
      RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
  send_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
  FakeVideoSendStream* send_stream =
      AddSendStream(cricket::StreamParams::CreateLegacy(123));

  // Only timestamp offset extension is set to send stream,
  // unsupported rtp extension is ignored.
  ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
  EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
               send_stream->GetConfig().rtp.extensions[0].uri.c_str());
}

TEST_F(WebRtcVideoChannelTest,
       SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
  const int kUnsupportedId = 1;
  const int kTOffsetId = 2;

  recv_parameters_.extensions.push_back(
      RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
  recv_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
  FakeVideoReceiveStream* recv_stream =
      AddRecvStream(cricket::StreamParams::CreateLegacy(123));

  // Only timestamp offset extension is set to receive stream,
  // unsupported rtp extension is ignored.
  ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
  EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
               recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
}

TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
  const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
  for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
    send_parameters_.extensions.push_back(
        RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
    EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
        << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
  }
}

TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
  const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
  for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
    recv_parameters_.extensions.push_back(
        RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
    EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
        << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
  }
}

TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
  const int id = 1;
  send_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, id));
  send_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kAbsSendTimeUri, id));
  EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));

  // Duplicate entries are also not supported.
  send_parameters_.extensions.clear();
  send_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, id));
  send_parameters_.extensions.push_back(send_parameters_.extensions.back());
  EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
}

TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
  const int id = 1;
  recv_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, id));
  recv_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kAbsSendTimeUri, id));
  EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));

  // Duplicate entries are also not supported.
  recv_parameters_.extensions.clear();
  recv_parameters_.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, id));
  recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
  EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
}

TEST_F(WebRtcVideoChannelTest, AddRecvStreamOnlyUsesOneReceiveStream) {
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
  EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
}

TEST_F(WebRtcVideoChannelTest, RtcpIsCompoundByDefault) {
  FakeVideoReceiveStream* stream = AddRecvStream();
  EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
}

TEST_F(WebRtcVideoChannelTest, TransportCcIsEnabledByDefault) {
  FakeVideoReceiveStream* stream = AddRecvStream();
  EXPECT_TRUE(stream->transport_cc());
}

TEST_F(WebRtcVideoChannelTest, TransportCcCanBeEnabledAndDisabled) {
  FakeVideoReceiveStream* stream = AddRecvStream();
  EXPECT_TRUE(stream->transport_cc());

  // Verify that transport cc feedback is turned off when send(!) codecs without
  // transport cc feedback are set.
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
  EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_FALSE(stream->transport_cc());

  // Verify that transport cc feedback is turned on when setting default codecs
  // since the default codecs have transport cc feedback enabled.
  parameters.codecs = engine_.send_codecs();
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_TRUE(stream->transport_cc());
}

TEST_F(WebRtcVideoChannelTest, LossNotificationIsDisabledByDefault) {
  TestLossNotificationState(false);
}

TEST_F(WebRtcVideoChannelTest, LossNotificationIsEnabledByFieldTrial) {
  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_, "WebRTC-RtcpLossNotification/Enabled/");
  ResetTest();
  TestLossNotificationState(true);
}

TEST_F(WebRtcVideoChannelTest, LossNotificationCanBeEnabledAndDisabled) {
  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_, "WebRTC-RtcpLossNotification/Enabled/");
  ResetTest();

  AssignDefaultCodec();
  VerifyCodecHasDefaultFeedbackParams(default_codec_, true);

  {
    cricket::VideoSendParameters parameters;
    parameters.codecs = engine_.send_codecs();
    EXPECT_TRUE(channel_->SetSendParameters(parameters));
    EXPECT_TRUE(channel_->SetSend(true));
  }

  // Start with LNTF enabled.
  FakeVideoSendStream* send_stream =
      AddSendStream(cricket::StreamParams::CreateLegacy(1));
  ASSERT_TRUE(send_stream->GetConfig().rtp.lntf.enabled);
  FakeVideoReceiveStream* recv_stream =
      AddRecvStream(cricket::StreamParams::CreateLegacy(1));
  ASSERT_TRUE(recv_stream->GetConfig().rtp.lntf.enabled);

  // Verify that LNTF is turned off when send(!) codecs without LNTF are set.
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
  EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  recv_stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_FALSE(recv_stream->GetConfig().rtp.lntf.enabled);
  send_stream = fake_call_->GetVideoSendStreams()[0];
  EXPECT_FALSE(send_stream->GetConfig().rtp.lntf.enabled);

  // Setting the default codecs again, including VP8, turns LNTF back on.
  parameters.codecs = engine_.send_codecs();
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  recv_stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_TRUE(recv_stream->GetConfig().rtp.lntf.enabled);
  send_stream = fake_call_->GetVideoSendStreams()[0];
  EXPECT_TRUE(send_stream->GetConfig().rtp.lntf.enabled);
}

TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) {
  AssignDefaultCodec();
  VerifyCodecHasDefaultFeedbackParams(default_codec_, false);

  cricket::VideoSendParameters parameters;
  parameters.codecs = engine_.send_codecs();
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  EXPECT_TRUE(channel_->SetSend(true));

  // Send side.
  FakeVideoSendStream* send_stream =
      AddSendStream(cricket::StreamParams::CreateLegacy(1));
  EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);

  // Receiver side.
  FakeVideoReceiveStream* recv_stream =
      AddRecvStream(cricket::StreamParams::CreateLegacy(1));
  EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);

  // Nack history size should match between sender and receiver.
  EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
            recv_stream->GetConfig().rtp.nack.rtp_history_ms);
}

TEST_F(WebRtcVideoChannelTest, NackCanBeEnabledAndDisabled) {
  FakeVideoSendStream* send_stream = AddSendStream();
  FakeVideoReceiveStream* recv_stream = AddRecvStream();

  EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
  EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);

  // Verify that NACK is turned off when send(!) codecs without NACK are set.
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
  EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  recv_stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
  send_stream = fake_call_->GetVideoSendStreams()[0];
  EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);

  // Verify that NACK is turned on when setting default codecs since the
  // default codecs have NACK enabled.
  parameters.codecs = engine_.send_codecs();
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  recv_stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
  send_stream = fake_call_->GetVideoSendStreams()[0];
  EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
}

// 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(WebRtcVideoChannelTest, ReconfiguresEncodersWhenNotSending) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  channel_->SetSend(false);

  FakeVideoSendStream* stream = AddSendStream();

  // No frames entered.
  std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
  EXPECT_EQ(0u, streams[0].width);
  EXPECT_EQ(0u, streams[0].height);

  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

  // Frame entered, should be reconfigured to new dimensions.
  streams = stream->GetVideoStreams();
  EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams[0].width);
  EXPECT_EQ(rtc::checked_cast<size_t>(720), streams[0].height);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest, UsesCorrectSettingsForScreencast) {
  static const int kScreenshareMinBitrateKbps = 800;
  cricket::VideoCodec codec = GetEngineCodec("VP8");
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(codec);
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  AddSendStream();

  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);
  VideoOptions min_bitrate_options;
  min_bitrate_options.screencast_min_bitrate_kbps = kScreenshareMinBitrateKbps;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &min_bitrate_options,
                                     &frame_forwarder));

  EXPECT_TRUE(channel_->SetSend(true));

  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
  FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();

  EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());

  // Verify non-screencast settings.
  webrtc::VideoEncoderConfig encoder_config =
      send_stream->GetEncoderConfig().Copy();
  EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
            encoder_config.content_type);
  std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
  EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
  EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
  EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
      << "Non-screenshare shouldn't use min-transmit bitrate.";

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
  EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
  VideoOptions screencast_options;
  screencast_options.is_screencast = true;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &screencast_options,
                                     &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  // Send stream recreated after option change.
  ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
  send_stream = fake_call_->GetVideoSendStreams().front();
  EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());

  // Verify screencast settings.
  encoder_config = send_stream->GetEncoderConfig().Copy();
  EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
            encoder_config.content_type);
  EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
            encoder_config.min_transmit_bitrate_bps);

  streams = send_stream->GetVideoStreams();
  EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
  EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
  EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       ConferenceModeScreencastConfiguresTemporalLayer) {
  static const int kConferenceScreencastTemporalBitrateBps = 200 * 1000;
  send_parameters_.conference_mode = true;
  channel_->SetSendParameters(send_parameters_);

  AddSendStream();
  VideoOptions options;
  options.is_screencast = true;
  webrtc::test::FrameForwarder frame_forwarder;
  cricket::FakeFrameSource frame_source(1280, 720,
                                        rtc::kNumMicrosecsPerSec / 30);
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  EXPECT_TRUE(channel_->SetSend(true));

  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
  ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
  FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();

  webrtc::VideoEncoderConfig encoder_config =
      send_stream->GetEncoderConfig().Copy();

  // Verify screencast settings.
  encoder_config = send_stream->GetEncoderConfig().Copy();
  EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
            encoder_config.content_type);

  std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
  ASSERT_EQ(1u, streams.size());
  ASSERT_EQ(2u, streams[0].num_temporal_layers);
  EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
            streams[0].target_bitrate_bps);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest, SuspendBelowMinBitrateDisabledByDefault) {
  FakeVideoSendStream* stream = AddSendStream();
  EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
}

TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
  MediaConfig media_config = GetMediaConfig();
  media_config.video.suspend_below_min_bitrate = true;

  channel_.reset(engine_.CreateMediaChannel(
      fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  channel_->OnReadyToSend(true);

  channel_->SetSendParameters(send_parameters_);

  FakeVideoSendStream* stream = AddSendStream();
  EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);

  media_config.video.suspend_below_min_bitrate = false;
  channel_.reset(engine_.CreateMediaChannel(
      fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  channel_->OnReadyToSend(true);

  channel_->SetSendParameters(send_parameters_);

  stream = AddSendStream();
  EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
}

TEST_F(WebRtcVideoChannelTest, Vp8DenoisingEnabledByDefault) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoCodecVP8 vp8_settings;
  ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
  EXPECT_TRUE(vp8_settings.denoisingOn);
}

TEST_F(WebRtcVideoChannelTest, VerifyVp8SpecificSettings) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  // Single-stream settings should apply with RTX as well (verifies that we
  // check number of regular SSRCs and not StreamParams::ssrcs which contains
  // both RTX and regular SSRCs).
  FakeVideoSendStream* stream = SetUpSimulcast(false, true);

  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
  channel_->SetSend(true);

  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  webrtc::VideoCodecVP8 vp8_settings;
  ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
  EXPECT_TRUE(vp8_settings.denoisingOn)
      << "VP8 denoising should be on by default.";

  stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);

  ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
  EXPECT_FALSE(vp8_settings.denoisingOn);
  EXPECT_TRUE(vp8_settings.automaticResizeOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled);

  stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);

  ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
  EXPECT_TRUE(vp8_settings.denoisingOn);
  EXPECT_TRUE(vp8_settings.automaticResizeOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
  stream = SetUpSimulcast(true, false);
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  EXPECT_EQ(3u, stream->GetVideoStreams().size());
  ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
  // Autmatic resize off when using simulcast.
  EXPECT_FALSE(vp8_settings.automaticResizeOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled);

  // In screen-share mode, denoising is forced off.
  VideoOptions options;
  options.is_screencast = true;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));

  stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);

  EXPECT_EQ(3u, stream->GetVideoStreams().size());
  ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
  EXPECT_FALSE(vp8_settings.denoisingOn);
  // Resizing always off for screen sharing.
  EXPECT_FALSE(vp8_settings.automaticResizeOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled);

  stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);

  ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
  EXPECT_FALSE(vp8_settings.denoisingOn);
  EXPECT_FALSE(vp8_settings.automaticResizeOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

// Test that setting the same options doesn't result in the encoder being
// reconfigured.
TEST_F(WebRtcVideoChannelTest, SetIdenticalOptionsDoesntReconfigureEncoder) {
  VideoOptions options;
  webrtc::test::FrameForwarder frame_forwarder;

  AddSendStream();
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
  // Expect 1 reconfigurations at this point from the initial configuration.
  EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());

  // Set the options one more time and expect no additional reconfigurations.
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());

  // Change `options` and expect 2 reconfigurations.
  options.video_noise_reduction = true;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

class Vp9SettingsTest : public WebRtcVideoChannelTest {
 public:
  Vp9SettingsTest() : Vp9SettingsTest("") {}
  explicit Vp9SettingsTest(const char* field_trials)
      : WebRtcVideoChannelTest(field_trials) {
    encoder_factory_->AddSupportedVideoCodecType("VP9");
  }
  virtual ~Vp9SettingsTest() {}

 protected:
  void TearDown() override {
    // Remove references to encoder_factory_ since this will be destroyed
    // before channel_ and engine_.
    ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
  }
};

TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  FakeVideoSendStream* stream = SetUpSimulcast(false, false);

  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
  channel_->SetSend(true);

  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  webrtc::VideoCodecVP9 vp9_settings;
  ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
  EXPECT_TRUE(vp9_settings.denoisingOn)
      << "VP9 denoising should be on by default.";
  EXPECT_TRUE(vp9_settings.automaticResizeOn)
      << "Automatic resize on for one active stream.";

  stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);

  ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
  EXPECT_FALSE(vp9_settings.denoisingOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled)
      << "Frame dropping always on for real time video.";
  EXPECT_TRUE(vp9_settings.automaticResizeOn);

  stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);

  ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
  EXPECT_TRUE(vp9_settings.denoisingOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled);
  EXPECT_TRUE(vp9_settings.automaticResizeOn);

  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_THAT(
      rtp_parameters.encodings,
      ElementsAre(Field(&webrtc::RtpEncodingParameters::scalability_mode,
                        absl::nullopt)));
  rtp_parameters.encodings[0].scalability_mode = "L2T1";
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());

  ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
  EXPECT_TRUE(vp9_settings.denoisingOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled);
  EXPECT_FALSE(vp9_settings.automaticResizeOn)
      << "Automatic resize off for multiple spatial layers.";

  rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_THAT(rtp_parameters.encodings,
              ElementsAre(Field(
                  &webrtc::RtpEncodingParameters::scalability_mode, "L2T1")));
  rtp_parameters.encodings[0].scalability_mode = "L1T1";
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());

  ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
  EXPECT_TRUE(vp9_settings.denoisingOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled);
  EXPECT_TRUE(vp9_settings.automaticResizeOn)
      << "Automatic resize on for one spatial layer.";

  // In screen-share mode, denoising is forced off.
  VideoOptions options;
  options.is_screencast = true;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));

  stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);

  ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
  EXPECT_FALSE(vp9_settings.denoisingOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled)
      << "Frame dropping always on for screen sharing.";
  EXPECT_FALSE(vp9_settings.automaticResizeOn)
      << "Automatic resize off for screencast.";

  stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);

  ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
  EXPECT_FALSE(vp9_settings.denoisingOn);
  EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled);
  EXPECT_FALSE(vp9_settings.automaticResizeOn);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);

  FakeVideoSendStream* stream =
      AddSendStream(CreateSimStreamParams("cname", ssrcs));

  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
  channel_->SetSend(true);

  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  webrtc::VideoCodecVP9 vp9_settings;
  ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";

  const size_t kNumSpatialLayers = ssrcs.size();
  const size_t kNumTemporalLayers = 3;
  EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
  EXPECT_EQ(vp9_settings.numberOfTemporalLayers, kNumTemporalLayers);

  EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
}

TEST_F(Vp9SettingsTest, SvcModeCreatesSingleRtpStream) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);

  FakeVideoSendStream* stream =
      AddSendStream(CreateSimStreamParams("cname", ssrcs));

  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  // Despite 3 ssrcs provided, single layer is used.
  EXPECT_EQ(1u, config.rtp.ssrcs.size());

  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
  channel_->SetSend(true);

  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  webrtc::VideoCodecVP9 vp9_settings;
  ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";

  const size_t kNumSpatialLayers = ssrcs.size();
  EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);

  EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
}

TEST_F(Vp9SettingsTest, AllEncodingParametersCopied) {
  cricket::VideoSendParameters send_parameters;
  send_parameters.codecs.push_back(GetEngineCodec("VP9"));
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters));

  const size_t kNumSpatialLayers = 3;
  std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);

  FakeVideoSendStream* stream =
      AddSendStream(CreateSimStreamParams("cname", ssrcs));

  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrcs[0]);
  ASSERT_EQ(kNumSpatialLayers, parameters.encodings.size());
  ASSERT_TRUE(parameters.encodings[0].active);
  ASSERT_TRUE(parameters.encodings[1].active);
  ASSERT_TRUE(parameters.encodings[2].active);
  // Invert value to verify copying.
  parameters.encodings[1].active = false;
  EXPECT_TRUE(channel_->SetRtpSendParameters(ssrcs[0], parameters).ok());

  webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();

  // number_of_streams should be 1 since all spatial layers are sent on the
  // same SSRC. But encoding parameters of all layers is supposed to be copied
  // and stored in simulcast_layers[].
  EXPECT_EQ(1u, encoder_config.number_of_streams);
  EXPECT_EQ(encoder_config.simulcast_layers.size(), kNumSpatialLayers);
  EXPECT_TRUE(encoder_config.simulcast_layers[0].active);
  EXPECT_FALSE(encoder_config.simulcast_layers[1].active);
  EXPECT_TRUE(encoder_config.simulcast_layers[2].active);
}

class Vp9SettingsTestWithFieldTrial
    : public Vp9SettingsTest,
      public ::testing::WithParamInterface<
          ::testing::tuple<const char*, int, int, webrtc::InterLayerPredMode>> {
 protected:
  Vp9SettingsTestWithFieldTrial()
      : Vp9SettingsTest(::testing::get<0>(GetParam())),
        num_spatial_layers_(::testing::get<1>(GetParam())),
        num_temporal_layers_(::testing::get<2>(GetParam())),
        inter_layer_pred_mode_(::testing::get<3>(GetParam())) {}

  void VerifySettings(int num_spatial_layers,
                      int num_temporal_layers,
                      webrtc::InterLayerPredMode interLayerPred) {
    cricket::VideoSendParameters parameters;
    parameters.codecs.push_back(GetEngineCodec("VP9"));
    ASSERT_TRUE(channel_->SetSendParameters(parameters));

    FakeVideoSendStream* stream = SetUpSimulcast(false, false);

    webrtc::test::FrameForwarder frame_forwarder;
    EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
    channel_->SetSend(true);

    frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

    webrtc::VideoCodecVP9 vp9_settings;
    ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
    EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
    EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
    EXPECT_EQ(inter_layer_pred_mode_, vp9_settings.interLayerPred);

    EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
  }

  const uint8_t num_spatial_layers_;
  const uint8_t num_temporal_layers_;
  const webrtc::InterLayerPredMode inter_layer_pred_mode_;
};

TEST_P(Vp9SettingsTestWithFieldTrial, VerifyCodecSettings) {
  VerifySettings(num_spatial_layers_, num_temporal_layers_,
                 inter_layer_pred_mode_);
}

INSTANTIATE_TEST_SUITE_P(
    All,
    Vp9SettingsTestWithFieldTrial,
    Values(
        std::make_tuple("", 1, 1, webrtc::InterLayerPredMode::kOnKeyPic),
        std::make_tuple("WebRTC-Vp9InterLayerPred/Default/",
                        1,
                        1,
                        webrtc::InterLayerPredMode::kOnKeyPic),
        std::make_tuple("WebRTC-Vp9InterLayerPred/Disabled/",
                        1,
                        1,
                        webrtc::InterLayerPredMode::kOnKeyPic),
        std::make_tuple(
            "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:off/",
            1,
            1,
            webrtc::InterLayerPredMode::kOff),
        std::make_tuple(
            "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:on/",
            1,
            1,
            webrtc::InterLayerPredMode::kOn),
        std::make_tuple(
            "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:onkeypic/",
            1,
            1,
            webrtc::InterLayerPredMode::kOnKeyPic)));

TEST_F(WebRtcVideoChannelTest, VerifyMinBitrate) {
  std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
  ASSERT_EQ(1u, streams.size());
  EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps, streams[0].min_bitrate_bps);
}

TEST_F(WebRtcVideoChannelTest, VerifyMinBitrateWithForcedFallbackFieldTrial) {
  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_,
      "WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1,2,34567/");
  std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
  ASSERT_EQ(1u, streams.size());
  EXPECT_EQ(34567, streams[0].min_bitrate_bps);
}

TEST_F(WebRtcVideoChannelTest,
       BalancedDegradationPreferenceNotSupportedWithoutFieldtrial) {
  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_, "WebRTC-Video-BalancedDegradation/Disabled/");
  const bool kResolutionScalingEnabled = true;
  const bool kFpsScalingEnabled = false;
  TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
}

TEST_F(WebRtcVideoChannelTest,
       BalancedDegradationPreferenceSupportedBehindFieldtrial) {
  webrtc::test::ScopedKeyValueConfig override_field_trials(
      field_trials_, "WebRTC-Video-BalancedDegradation/Enabled/");
  const bool kResolutionScalingEnabled = true;
  const bool kFpsScalingEnabled = true;
  TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
}

TEST_F(WebRtcVideoChannelTest, AdaptsOnOveruse) {
  TestCpuAdaptation(true, false);
}

TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenDisabled) {
  TestCpuAdaptation(false, false);
}

TEST_F(WebRtcVideoChannelTest, DoesNotAdaptWhenScreeensharing) {
  TestCpuAdaptation(false, true);
}

TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenScreensharing) {
  TestCpuAdaptation(true, true);
}

TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) {
  cricket::VideoCodec codec = GetEngineCodec("VP8");
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(codec);

  MediaConfig media_config = GetMediaConfig();
  media_config.video.enable_cpu_adaptation = true;
  channel_.reset(engine_.CreateMediaChannel(
      fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  channel_->OnReadyToSend(true);
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  AddSendStream();
  webrtc::test::FrameForwarder frame_forwarder;

  ASSERT_TRUE(channel_->SetSend(true));
  cricket::VideoOptions camera_options;
  camera_options.is_screencast = false;
  channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);

  ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
  FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();

  EXPECT_TRUE(send_stream->resolution_scaling_enabled());
  // Dont' expect anything on framerate_scaling_enabled, since the default is
  // transitioning from MAINTAIN_FRAMERATE to BALANCED.

  // Switch to screen share. Expect no resolution scaling.
  cricket::VideoOptions screenshare_options;
  screenshare_options.is_screencast = true;
  channel_->SetVideoSend(last_ssrc_, &screenshare_options, &frame_forwarder);
  ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
  send_stream = fake_call_->GetVideoSendStreams().front();
  EXPECT_FALSE(send_stream->resolution_scaling_enabled());

  // Switch back to the normal capturer. Expect resolution scaling to be
  // reenabled.
  channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
  send_stream = fake_call_->GetVideoSendStreams().front();
  ASSERT_EQ(3, fake_call_->GetNumCreatedSendStreams());
  send_stream = fake_call_->GetVideoSendStreams().front();
  EXPECT_TRUE(send_stream->resolution_scaling_enabled());

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

// TODO(asapersson): Remove this test when the balanced field trial is removed.
void WebRtcVideoChannelTest::TestDegradationPreference(
    bool resolution_scaling_enabled,
    bool fps_scaling_enabled) {
  cricket::VideoCodec codec = GetEngineCodec("VP8");
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(codec);

  MediaConfig media_config = GetMediaConfig();
  media_config.video.enable_cpu_adaptation = true;
  channel_.reset(engine_.CreateMediaChannel(
      fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  channel_->OnReadyToSend(true);

  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  AddSendStream();

  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));

  EXPECT_TRUE(channel_->SetSend(true));

  FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
  EXPECT_EQ(resolution_scaling_enabled,
            send_stream->resolution_scaling_enabled());
  EXPECT_EQ(fps_scaling_enabled, send_stream->framerate_scaling_enabled());

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse,
                                               bool is_screenshare) {
  cricket::VideoCodec codec = GetEngineCodec("VP8");
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(codec);

  MediaConfig media_config = GetMediaConfig();
  if (enable_overuse) {
    media_config.video.enable_cpu_adaptation = true;
  }
  channel_.reset(engine_.CreateMediaChannel(
      fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
      video_bitrate_allocator_factory_.get()));
  channel_->OnReadyToSend(true);

  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  AddSendStream();

  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  options.is_screencast = is_screenshare;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));

  EXPECT_TRUE(channel_->SetSend(true));

  FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();

  if (!enable_overuse) {
    EXPECT_FALSE(send_stream->resolution_scaling_enabled());
    EXPECT_FALSE(send_stream->framerate_scaling_enabled());
  } else if (is_screenshare) {
    EXPECT_FALSE(send_stream->resolution_scaling_enabled());
    EXPECT_TRUE(send_stream->framerate_scaling_enabled());
  } else {
    EXPECT_TRUE(send_stream->resolution_scaling_enabled());
    EXPECT_FALSE(send_stream->framerate_scaling_enabled());
  }
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest, EstimatesNtpStartTimeCorrectly) {
  // Start at last timestamp to verify that wraparounds are estimated correctly.
  static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
  static const int64_t kInitialNtpTimeMs = 1247891230;
  static const int kFrameOffsetMs = 20;
  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));

  FakeVideoReceiveStream* stream = AddRecvStream();
  cricket::FakeVideoRenderer renderer;
  EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));

  webrtc::VideoFrame video_frame =
      webrtc::VideoFrame::Builder()
          .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
          .set_timestamp_rtp(kInitialTimestamp)
          .set_timestamp_us(0)
          .set_rotation(webrtc::kVideoRotation_0)
          .build();
  // Initial NTP time is not available on the first frame, but should still be
  // able to be estimated.
  stream->InjectFrame(video_frame);

  EXPECT_EQ(1, renderer.num_rendered_frames());

  // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
  // triggers a constant-overflow warning, hence we're calculating it explicitly
  // here.
  time_controller_.AdvanceTime(webrtc::TimeDelta::Millis(kFrameOffsetMs));
  video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
  video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
  stream->InjectFrame(video_frame);

  EXPECT_EQ(2, renderer.num_rendered_frames());

  // Verify that NTP time has been correctly deduced.
  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  ASSERT_EQ(1u, info.receivers.size());
  EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
}

TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) {
  AssignDefaultAptRtxTypes();
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));

  VideoCodec codec;
  EXPECT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_TRUE(codec.Matches(engine_.send_codecs()[0], &field_trials_));

  // Using a RTX setup to verify that the default RTX payload type is good.
  const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
  const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
  FakeVideoSendStream* stream = AddSendStream(
      cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  // Make sure NACK and FEC are enabled on the correct payload types.
  EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
  EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
  EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);

  EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
  EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
  VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
  // TODO(juberti): Check RTCP, PLI, TMMBR.
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutPacketization) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  FakeVideoSendStream* stream = AddSendStream();
  const webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
  EXPECT_FALSE(config.rtp.raw_payload);
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithPacketization) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.back().packetization = kPacketizationParamRaw;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  FakeVideoSendStream* stream = AddSendStream();
  const webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
  EXPECT_TRUE(config.rtp.raw_payload);
}

// The following four tests ensures that FlexFEC is not activated by default
// when the field trials are not enabled.
// TODO(brandtr): Remove or update these tests when FlexFEC _is_ enabled by
// default.
TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithoutSsrcNotExposedByDefault) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
  EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
  EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
}

TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithSsrcNotExposedByDefault) {
  FakeVideoSendStream* stream = AddSendStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
  EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
  EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
}

TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithoutSsrcNotExposedByDefault) {
  AddRecvStream();

  const std::vector<FakeFlexfecReceiveStream*>& streams =
      fake_call_->GetFlexfecReceiveStreams();
  EXPECT_TRUE(streams.empty());
}

TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithSsrcExposedByDefault) {
  AddRecvStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));

  const std::vector<FakeFlexfecReceiveStream*>& streams =
      fake_call_->GetFlexfecReceiveStreams();
  EXPECT_EQ(1U, streams.size());
}

// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
// tests that use this test fixture into the corresponding "non-field trial"
// tests.
class WebRtcVideoChannelFlexfecRecvTest : public WebRtcVideoChannelTest {
 public:
  WebRtcVideoChannelFlexfecRecvTest()
      : WebRtcVideoChannelTest("WebRTC-FlexFEC-03-Advertised/Enabled/") {}
};

TEST_F(WebRtcVideoChannelFlexfecRecvTest,
       DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam) {
  EXPECT_TRUE(cricket::HasTransportCc(GetEngineCodec("flexfec-03")));
  EXPECT_TRUE(cricket::HasRemb(GetEngineCodec("flexfec-03")));
}

TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithoutSsrc) {
  AddRecvStream();

  const std::vector<FakeFlexfecReceiveStream*>& streams =
      fake_call_->GetFlexfecReceiveStreams();
  EXPECT_TRUE(streams.empty());

  const std::vector<FakeVideoReceiveStream*>& video_streams =
      fake_call_->GetVideoReceiveStreams();
  ASSERT_EQ(1U, video_streams.size());
  const FakeVideoReceiveStream& video_stream = *video_streams.front();
  const webrtc::VideoReceiveStreamInterface::Config& video_config =
      video_stream.GetConfig();
  EXPECT_FALSE(video_config.rtp.protected_by_flexfec);
  EXPECT_EQ(video_config.rtp.packet_sink_, nullptr);
}

TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithSsrc) {
  AddRecvStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));

  const std::vector<FakeFlexfecReceiveStream*>& streams =
      fake_call_->GetFlexfecReceiveStreams();
  ASSERT_EQ(1U, streams.size());
  const auto* stream = streams.front();
  const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
  EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
  EXPECT_EQ(kFlexfecSsrc, config.rtp.remote_ssrc);
  ASSERT_EQ(1U, config.protected_media_ssrcs.size());
  EXPECT_EQ(kSsrcs1[0], config.protected_media_ssrcs[0]);

  const std::vector<FakeVideoReceiveStream*>& video_streams =
      fake_call_->GetVideoReceiveStreams();
  ASSERT_EQ(1U, video_streams.size());
  const FakeVideoReceiveStream& video_stream = *video_streams.front();
  const webrtc::VideoReceiveStreamInterface::Config& video_config =
      video_stream.GetConfig();
  EXPECT_TRUE(video_config.rtp.protected_by_flexfec);
  EXPECT_NE(video_config.rtp.packet_sink_, nullptr);
}

// Test changing the configuration after a video stream has been created and
// turn on flexfec. This will result in the video stream being recreated because
// the flexfec stream pointer is injected to the video stream at construction.
TEST_F(WebRtcVideoChannelFlexfecRecvTest,
       EnablingFlexfecRecreatesVideoReceiveStream) {
  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));

  AddRecvStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
  EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
  const std::vector<FakeVideoReceiveStream*>& video_streams =
      fake_call_->GetVideoReceiveStreams();
  ASSERT_EQ(1U, video_streams.size());
  const FakeVideoReceiveStream* video_stream = video_streams.front();
  const webrtc::VideoReceiveStreamInterface::Config* video_config =
      &video_stream->GetConfig();
  EXPECT_FALSE(video_config->rtp.protected_by_flexfec);
  EXPECT_EQ(video_config->rtp.packet_sink_, nullptr);

  // Enable FlexFEC.
  recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));

  // Now the count of created streams will be 3 since the video stream was
  // recreated and a flexfec stream was created.
  EXPECT_EQ(3, fake_call_->GetNumCreatedReceiveStreams())
      << "Enabling FlexFEC should create FlexfecReceiveStream.";

  EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
      << "Enabling FlexFEC should not create VideoReceiveStreamInterface.";
  EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size())
      << "Enabling FlexFEC should create a single FlexfecReceiveStream.";
  video_stream = video_streams.front();
  video_config = &video_stream->GetConfig();
  EXPECT_TRUE(video_config->rtp.protected_by_flexfec);
  EXPECT_NE(video_config->rtp.packet_sink_, nullptr);
}

// Test changing the configuration after a video stream has been created with
// flexfec enabled and then turn off flexfec. This will result in the video
// stream being recreated because the flexfec stream pointer is injected to the
// video stream at construction and that config needs to be torn down.
TEST_F(WebRtcVideoChannelFlexfecRecvTest,
       DisablingFlexfecRecreatesVideoReceiveStream) {
  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
  recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));

  AddRecvStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
  EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
  EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size());
  const std::vector<FakeVideoReceiveStream*>& video_streams =
      fake_call_->GetVideoReceiveStreams();
  ASSERT_EQ(1U, video_streams.size());
  const FakeVideoReceiveStream* video_stream = video_streams.front();
  const webrtc::VideoReceiveStreamInterface::Config* video_config =
      &video_stream->GetConfig();
  EXPECT_TRUE(video_config->rtp.protected_by_flexfec);
  EXPECT_NE(video_config->rtp.packet_sink_, nullptr);

  // Disable FlexFEC.
  recv_parameters.codecs.clear();
  recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
  // Now the count of created streams will be 3 since the video stream had to
  // be recreated on account of the flexfec stream being deleted.
  EXPECT_EQ(3, fake_call_->GetNumCreatedReceiveStreams())
      << "Disabling FlexFEC should not recreate VideoReceiveStreamInterface.";
  EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
      << "Disabling FlexFEC should not destroy VideoReceiveStreamInterface.";
  EXPECT_TRUE(fake_call_->GetFlexfecReceiveStreams().empty())
      << "Disabling FlexFEC should destroy FlexfecReceiveStream.";
  video_stream = video_streams.front();
  video_config = &video_stream->GetConfig();
  EXPECT_FALSE(video_config->rtp.protected_by_flexfec);
  EXPECT_EQ(video_config->rtp.packet_sink_, nullptr);
}

TEST_F(WebRtcVideoChannelFlexfecRecvTest, DuplicateFlexfecCodecIsDropped) {
  constexpr int kUnusedPayloadType1 = 127;

  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
  recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  cricket::VideoCodec duplicate = GetEngineCodec("flexfec-03");
  duplicate.id = kUnusedPayloadType1;
  recv_parameters.codecs.push_back(duplicate);
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));

  AddRecvStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));

  const std::vector<FakeFlexfecReceiveStream*>& streams =
      fake_call_->GetFlexfecReceiveStreams();
  ASSERT_EQ(1U, streams.size());
  const auto* stream = streams.front();
  const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
  EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
}

// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
// tests that use this test fixture into the corresponding "non-field trial"
// tests.
class WebRtcVideoChannelFlexfecSendRecvTest : public WebRtcVideoChannelTest {
 public:
  WebRtcVideoChannelFlexfecSendRecvTest()
      : WebRtcVideoChannelTest(
            "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/") {
  }
};

TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithoutSsrc) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
  EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
  EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
}

TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithSsrc) {
  FakeVideoSendStream* stream = AddSendStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
  EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
  ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
  EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFec) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
  EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
}

TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetSendCodecsWithoutFec) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
}

TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) {
  AddRecvStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));

  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
  recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));

  const std::vector<FakeFlexfecReceiveStream*>& flexfec_streams =
      fake_call_->GetFlexfecReceiveStreams();
  ASSERT_EQ(1U, flexfec_streams.size());
  const FakeFlexfecReceiveStream* flexfec_stream = flexfec_streams.front();
  const webrtc::FlexfecReceiveStream::Config& flexfec_stream_config =
      flexfec_stream->GetConfig();
  EXPECT_EQ(GetEngineCodec("flexfec-03").id,
            flexfec_stream_config.payload_type);
  EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.rtp.remote_ssrc);
  ASSERT_EQ(1U, flexfec_stream_config.protected_media_ssrcs.size());
  EXPECT_EQ(kSsrcs1[0], flexfec_stream_config.protected_media_ssrcs[0]);
  const std::vector<FakeVideoReceiveStream*>& video_streams =
      fake_call_->GetVideoReceiveStreams();
  const FakeVideoReceiveStream* video_stream = video_streams.front();
  const webrtc::VideoReceiveStreamInterface::Config& video_stream_config =
      video_stream->GetConfig();
  EXPECT_EQ(video_stream_config.rtp.local_ssrc,
            flexfec_stream_config.rtp.local_ssrc);
  EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
  EXPECT_EQ(video_stream_config.rtcp_send_transport,
            flexfec_stream_config.rtcp_send_transport);
  // TODO(brandtr): Update this EXPECT when we set `transport_cc` in a
  // spec-compliant way.
  EXPECT_EQ(video_stream_config.rtp.transport_cc,
            flexfec_stream_config.rtp.transport_cc);
  EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
  EXPECT_EQ(video_stream_config.rtp.extensions,
            flexfec_stream_config.rtp.extensions);
}

// We should not send FlexFEC, even if we advertise it, unless the right
// field trial is set.
// TODO(brandtr): Remove when FlexFEC is enabled by default.
TEST_F(WebRtcVideoChannelFlexfecRecvTest,
       SetSendCodecsWithoutSsrcWithFecDoesNotEnableFec) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
  EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
  EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
}

TEST_F(WebRtcVideoChannelFlexfecRecvTest,
       SetSendCodecsWithSsrcWithFecDoesNotEnableFec) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  FakeVideoSendStream* stream = AddSendStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
  EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
  EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
}

TEST_F(WebRtcVideoChannelTest,
       SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
  const int kUnusedPayloadType = 127;
  EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType));

  cricket::VideoSendParameters parameters;
  cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
  parameters.codecs.push_back(rtx_codec);
  EXPECT_FALSE(channel_->SetSendParameters(parameters))
      << "RTX codec without associated payload type should be rejected.";
}

TEST_F(WebRtcVideoChannelTest,
       SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
  const int kUnusedPayloadType1 = 126;
  const int kUnusedPayloadType2 = 127;
  EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType1));
  EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType2));
  {
    cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
        kUnusedPayloadType1, GetEngineCodec("VP8").id);
    cricket::VideoSendParameters parameters;
    parameters.codecs.push_back(GetEngineCodec("VP8"));
    parameters.codecs.push_back(rtx_codec);
    ASSERT_TRUE(channel_->SetSendParameters(parameters));
  }
  {
    cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
        kUnusedPayloadType1, kUnusedPayloadType2);
    cricket::VideoSendParameters parameters;
    parameters.codecs.push_back(GetEngineCodec("VP8"));
    parameters.codecs.push_back(rtx_codec);
    EXPECT_FALSE(channel_->SetSendParameters(parameters))
        << "RTX without matching video codec should be rejected.";
  }
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithChangedRtxPayloadType) {
  const int kUnusedPayloadType1 = 126;
  const int kUnusedPayloadType2 = 127;
  EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType1));
  EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType2));

  // SSRCs for RTX.
  cricket::StreamParams params =
      cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
  params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
  AddSendStream(params);

  // Original payload type for RTX.
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
  rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
  parameters.codecs.push_back(rtx_codec);
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
  const webrtc::VideoSendStream::Config& config_before =
      fake_call_->GetVideoSendStreams()[0]->GetConfig();
  EXPECT_EQ(kUnusedPayloadType1, config_before.rtp.rtx.payload_type);
  ASSERT_EQ(1U, config_before.rtp.rtx.ssrcs.size());
  EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx.ssrcs[0]);

  // Change payload type for RTX.
  parameters.codecs[1].id = kUnusedPayloadType2;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
  const webrtc::VideoSendStream::Config& config_after =
      fake_call_->GetVideoSendStreams()[0]->GetConfig();
  EXPECT_EQ(kUnusedPayloadType2, config_after.rtp.rtx.payload_type);
  ASSERT_EQ(1U, config_after.rtp.rtx.ssrcs.size());
  EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx.ssrcs[0]);
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFecDisablesFec) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("ulpfec"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);

  parameters.codecs.pop_back();
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  stream = fake_call_->GetVideoSendStreams()[0];
  ASSERT_TRUE(stream != nullptr);
  config = stream->GetConfig().Copy();
  EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
      << "SetSendCodec without ULPFEC should disable current ULPFEC.";
}

TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
       SetSendCodecsWithoutFecDisablesFec) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));

  FakeVideoSendStream* stream = AddSendStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
  webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();

  EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
  EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
  ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
  EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);

  parameters.codecs.pop_back();
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  stream = fake_call_->GetVideoSendStreams()[0];
  ASSERT_TRUE(stream != nullptr);
  config = stream->GetConfig().Copy();
  EXPECT_EQ(-1, config.rtp.flexfec.payload_type)
      << "SetSendCodec without FlexFEC should disable current FlexFEC.";
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
  cricket::VideoSendParameters parameters;
  cricket::VideoCodec codec(100, "VP8");
  codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
  parameters.codecs.push_back(codec);

  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  channel_->SetSend(true);

  FakeVideoSendStream* stream = AddSendStream();
  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));

  std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
  EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);

  parameters.codecs.clear();
  codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
  parameters.codecs.push_back(codec);
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
  EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitrates) {
  SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
                                     200000);
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithHighMaxBitrate) {
  SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
  std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
  ASSERT_EQ(1u, streams.size());
  EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
}

TEST_F(WebRtcVideoChannelTest,
       SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
  SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsCapsMinAndStartBitrate) {
  SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectsMaxLessThanMinBitrate) {
  send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
  send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
  EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
}

// Test that when both the codec-specific bitrate params and max_bandwidth_bps
// are present in the same send parameters, the settings are combined correctly.
TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
  send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
  send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
  send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
  send_parameters_.max_bandwidth_bps = 400000;
  // We expect max_bandwidth_bps to take priority, if set.
  ExpectSetBitrateParameters(100000, 200000, 400000);
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
  // Since the codec isn't changing, start_bitrate_bps should be -1.
  ExpectSetBitrateParameters(100000, -1, 350000);

  // Decrease max_bandwidth_bps.
  send_parameters_.max_bandwidth_bps = 350000;
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  // Now try again with the values flipped around.
  send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
  send_parameters_.max_bandwidth_bps = 300000;
  ExpectSetBitrateParameters(100000, 200000, 300000);
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  // If we change the codec max, max_bandwidth_bps should still apply.
  send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
  ExpectSetBitrateParameters(100000, 200000, 300000);
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
}

TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldPreserveOtherBitrates) {
  SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
                                     200000);
  send_parameters_.max_bandwidth_bps = 300000;
  // Setting max bitrate should keep previous min bitrate.
  // Setting max bitrate should not reset start bitrate.
  ExpectSetBitrateParameters(100000, -1, 300000);
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
}

TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldBeRemovable) {
  send_parameters_.max_bandwidth_bps = 300000;
  ExpectSetMaxBitrate(300000);
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
  // -1 means to disable max bitrate (set infinite).
  send_parameters_.max_bandwidth_bps = -1;
  ExpectSetMaxBitrate(-1);
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
}

TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthAndAddSendStream) {
  send_parameters_.max_bandwidth_bps = 99999;
  FakeVideoSendStream* stream = AddSendStream();
  ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
  ASSERT_EQ(1u, stream->GetVideoStreams().size());
  EXPECT_EQ(send_parameters_.max_bandwidth_bps,
            stream->GetVideoStreams()[0].max_bitrate_bps);

  send_parameters_.max_bandwidth_bps = 77777;
  ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
  EXPECT_EQ(send_parameters_.max_bandwidth_bps,
            stream->GetVideoStreams()[0].max_bitrate_bps);
}

// Tests that when the codec specific max bitrate and VideoSendParameters
// max_bandwidth_bps are used, that it sets the VideoStream's max bitrate
// appropriately.
TEST_F(WebRtcVideoChannelTest,
       MaxBitratePrioritizesVideoSendParametersOverCodecMaxBitrate) {
  send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
  send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
  send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
  send_parameters_.max_bandwidth_bps = -1;
  AddSendStream();
  ExpectSetMaxBitrate(300000);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));

  std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
  ASSERT_EQ(1u, video_send_streams.size());
  FakeVideoSendStream* video_send_stream = video_send_streams[0];
  ASSERT_EQ(1u, video_send_streams[0]->GetVideoStreams().size());
  // First the max bitrate is set based upon the codec param.
  EXPECT_EQ(300000,
            video_send_streams[0]->GetVideoStreams()[0].max_bitrate_bps);

  // The VideoSendParameters max bitrate overrides the codec's.
  send_parameters_.max_bandwidth_bps = 500000;
  ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
  ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
  EXPECT_EQ(500000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
}

// Tests that when the codec specific max bitrate and RtpParameters
// max_bitrate_bps are used, that it sets the VideoStream's max bitrate
// appropriately.
TEST_F(WebRtcVideoChannelTest,
       MaxBitratePrioritizesRtpParametersOverCodecMaxBitrate) {
  send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
  send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
  send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
  send_parameters_.max_bandwidth_bps = -1;
  AddSendStream();
  ExpectSetMaxBitrate(300000);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));

  std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
  ASSERT_EQ(1u, video_send_streams.size());
  FakeVideoSendStream* video_send_stream = video_send_streams[0];
  ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
  // First the max bitrate is set based upon the codec param.
  EXPECT_EQ(300000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);

  // The RtpParameter max bitrate overrides the codec's.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  ASSERT_EQ(1u, parameters.encodings.size());
  parameters.encodings[0].max_bitrate_bps = 500000;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
  EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
            video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
}

TEST_F(WebRtcVideoChannelTest,
       MaxBitrateIsMinimumOfMaxSendBandwidthAndMaxEncodingBitrate) {
  send_parameters_.max_bandwidth_bps = 99999;
  FakeVideoSendStream* stream = AddSendStream();
  ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
  ASSERT_EQ(1u, stream->GetVideoStreams().size());
  EXPECT_EQ(send_parameters_.max_bandwidth_bps,
            stream->GetVideoStreams()[0].max_bitrate_bps);

  // Get and set the rtp encoding parameters.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1u, parameters.encodings.size());

  parameters.encodings[0].max_bitrate_bps = 99999 - 1;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
            stream->GetVideoStreams()[0].max_bitrate_bps);

  parameters.encodings[0].max_bitrate_bps = 99999 + 1;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  EXPECT_EQ(send_parameters_.max_bandwidth_bps,
            stream->GetVideoStreams()[0].max_bitrate_bps);
}

TEST_F(WebRtcVideoChannelTest, SetMaxSendBitrateCanIncreaseSenderBitrate) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  channel_->SetSend(true);

  FakeVideoSendStream* stream = AddSendStream();

  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));

  std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
  int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
  EXPECT_GT(initial_max_bitrate_bps, 0);

  parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  // Insert a frame to update the encoder config.
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
  streams = stream->GetVideoStreams();
  EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  channel_->SetSend(true);

  FakeVideoSendStream* stream = AddSendStream(
      cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));

  // Send a frame to make sure this scales up to >1 stream (simulcast).
  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, &frame_forwarder));
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
  ASSERT_GT(streams.size(), 1u)
      << "Without simulcast this test doesn't make sense.";
  int initial_max_bitrate_bps = GetTotalMaxBitrate(streams).bps();
  EXPECT_GT(initial_max_bitrate_bps, 0);

  parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  // Insert a frame to update the encoder config.
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
  streams = stream->GetVideoStreams();
  int increased_max_bitrate_bps = GetTotalMaxBitrate(streams).bps();
  EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);

  EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithMaxQuantization) {
  static const char* kMaxQuantization = "21";
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
  EXPECT_TRUE(channel_->SetSendParameters(parameters));
  EXPECT_EQ(atoi(kMaxQuantization),
            AddSendStream()->GetVideoStreams().back().max_qp);

  VideoCodec codec;
  EXPECT_TRUE(channel_->GetSendCodec(&codec));
  EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectBadPayloadTypes) {
  // TODO(pbos): Should we only allow the dynamic range?
  static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
    parameters.codecs[0].id = kIncorrectPayloads[i];
    EXPECT_FALSE(channel_->SetSendParameters(parameters))
        << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
  }
}

TEST_F(WebRtcVideoChannelTest, SetSendCodecsAcceptAllValidPayloadTypes) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  for (int payload_type = 96; payload_type <= 127; ++payload_type) {
    parameters.codecs[0].id = payload_type;
    EXPECT_TRUE(channel_->SetSendParameters(parameters))
        << "Payload type '" << payload_type << "' rejected.";
  }
}

// Test that setting the a different set of codecs but with an identical front
// codec doesn't result in the stream being recreated.
// This may happen when a subsequent negotiation includes fewer codecs, as a
// result of one of the codecs being rejected.
TEST_F(WebRtcVideoChannelTest,
       SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
  cricket::VideoSendParameters parameters1;
  parameters1.codecs.push_back(GetEngineCodec("VP8"));
  parameters1.codecs.push_back(GetEngineCodec("VP9"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters1));

  AddSendStream();
  EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());

  cricket::VideoSendParameters parameters2;
  parameters2.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters2));
  EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithOnlyVp8) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
}

// Test that we set our inbound RTX codecs properly.
TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithRtx) {
  const int kUnusedPayloadType1 = 126;
  const int kUnusedPayloadType2 = 127;
  EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType1));
  EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType2));

  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
  parameters.codecs.push_back(rtx_codec);
  EXPECT_FALSE(channel_->SetRecvParameters(parameters))
      << "RTX codec without associated payload should be rejected.";

  parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
  EXPECT_FALSE(channel_->SetRecvParameters(parameters))
      << "RTX codec with invalid associated payload type should be rejected.";

  parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
  rtx_codec2.SetParam("apt", rtx_codec.id);
  parameters.codecs.push_back(rtx_codec2);

  EXPECT_FALSE(channel_->SetRecvParameters(parameters))
      << "RTX codec with another RTX as associated payload type should be "
         "rejected.";
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithPacketization) {
  cricket::VideoCodec vp8_codec = GetEngineCodec("VP8");
  vp8_codec.packetization = kPacketizationParamRaw;

  cricket::VideoRecvParameters parameters;
  parameters.codecs = {vp8_codec, GetEngineCodec("VP9")};
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  const cricket::StreamParams params =
      cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
  AddRecvStream(params);
  ASSERT_THAT(fake_call_->GetVideoReceiveStreams(), testing::SizeIs(1));

  const webrtc::VideoReceiveStreamInterface::Config& config =
      fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
  ASSERT_THAT(config.rtp.raw_payload_types, testing::SizeIs(1));
  EXPECT_EQ(config.rtp.raw_payload_types.count(vp8_codec.id), 1U);
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithPacketizationRecreatesStream) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs = {GetEngineCodec("VP8"), GetEngineCodec("VP9")};
  parameters.codecs.back().packetization = kPacketizationParamRaw;
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  const cricket::StreamParams params =
      cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
  AddRecvStream(params);
  ASSERT_THAT(fake_call_->GetVideoReceiveStreams(), testing::SizeIs(1));
  EXPECT_EQ(fake_call_->GetNumCreatedReceiveStreams(), 1);

  parameters.codecs.back().packetization.reset();
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_EQ(fake_call_->GetNumCreatedReceiveStreams(), 2);
}

TEST_F(WebRtcVideoChannelTest, DuplicateUlpfecCodecIsDropped) {
  constexpr int kFirstUlpfecPayloadType = 126;
  constexpr int kSecondUlpfecPayloadType = 127;

  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(
      cricket::VideoCodec(kFirstUlpfecPayloadType, cricket::kUlpfecCodecName));
  parameters.codecs.push_back(
      cricket::VideoCodec(kSecondUlpfecPayloadType, cricket::kUlpfecCodecName));
  ASSERT_TRUE(channel_->SetRecvParameters(parameters));

  FakeVideoReceiveStream* recv_stream = AddRecvStream();
  EXPECT_EQ(kFirstUlpfecPayloadType,
            recv_stream->GetConfig().rtp.ulpfec_payload_type);
}

TEST_F(WebRtcVideoChannelTest, DuplicateRedCodecIsDropped) {
  constexpr int kFirstRedPayloadType = 126;
  constexpr int kSecondRedPayloadType = 127;

  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(
      cricket::VideoCodec(kFirstRedPayloadType, cricket::kRedCodecName));
  parameters.codecs.push_back(
      cricket::VideoCodec(kSecondRedPayloadType, cricket::kRedCodecName));
  ASSERT_TRUE(channel_->SetRecvParameters(parameters));

  FakeVideoReceiveStream* recv_stream = AddRecvStream();
  EXPECT_EQ(kFirstRedPayloadType,
            recv_stream->GetConfig().rtp.red_payload_type);
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithChangedRtxPayloadType) {
  const int kUnusedPayloadType1 = 126;
  const int kUnusedPayloadType2 = 127;
  EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType1));
  EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType2));

  // SSRCs for RTX.
  cricket::StreamParams params =
      cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
  params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
  AddRecvStream(params);

  // Original payload type for RTX.
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
  rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
  parameters.codecs.push_back(rtx_codec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
  const webrtc::VideoReceiveStreamInterface::Config& config_before =
      fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
  EXPECT_EQ(1U, config_before.rtp.rtx_associated_payload_types.size());
  const int* payload_type_before = FindKeyByValue(
      config_before.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
  ASSERT_NE(payload_type_before, nullptr);
  EXPECT_EQ(kUnusedPayloadType1, *payload_type_before);
  EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx_ssrc);

  // Change payload type for RTX.
  parameters.codecs[1].id = kUnusedPayloadType2;
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
  const webrtc::VideoReceiveStreamInterface::Config& config_after =
      fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
  EXPECT_EQ(1U, config_after.rtp.rtx_associated_payload_types.size());
  const int* payload_type_after = FindKeyByValue(
      config_after.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
  ASSERT_NE(payload_type_after, nullptr);
  EXPECT_EQ(kUnusedPayloadType2, *payload_type_after);
  EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx_ssrc);
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRtxWithRtxTime) {
  const int kUnusedPayloadType1 = 126;
  const int kUnusedPayloadType2 = 127;
  EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType1));
  EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType2));

  // SSRCs for RTX.
  cricket::StreamParams params =
      cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
  params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
  AddRecvStream(params);

  // Payload type for RTX.
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
  rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
  parameters.codecs.push_back(rtx_codec);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
  const webrtc::VideoReceiveStreamInterface::Config& config =
      fake_call_->GetVideoReceiveStreams()[0]->GetConfig();

  const int kRtxTime = 343;
  // Assert that the default value is different from the ones we test
  // and store the default value.
  EXPECT_NE(config.rtp.nack.rtp_history_ms, kRtxTime);
  int default_history_ms = config.rtp.nack.rtp_history_ms;

  // Set rtx-time.
  parameters.codecs[1].SetParam(kCodecParamRtxTime, kRtxTime);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams()[0]
                ->GetConfig()
                .rtp.nack.rtp_history_ms,
            kRtxTime);

  // Negative values are ignored so the default value applies.
  parameters.codecs[1].SetParam(kCodecParamRtxTime, -1);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_NE(fake_call_->GetVideoReceiveStreams()[0]
                ->GetConfig()
                .rtp.nack.rtp_history_ms,
            -1);
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams()[0]
                ->GetConfig()
                .rtp.nack.rtp_history_ms,
            default_history_ms);

  // 0 is ignored so the default applies.
  parameters.codecs[1].SetParam(kCodecParamRtxTime, 0);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_NE(fake_call_->GetVideoReceiveStreams()[0]
                ->GetConfig()
                .rtp.nack.rtp_history_ms,
            0);
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams()[0]
                ->GetConfig()
                .rtp.nack.rtp_history_ms,
            default_history_ms);

  // Values larger than the default are clamped to the default.
  parameters.codecs[1].SetParam(kCodecParamRtxTime, default_history_ms + 100);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams()[0]
                ->GetConfig()
                .rtp.nack.rtp_history_ms,
            default_history_ms);
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsDifferentPayloadType) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs[0].id = 99;
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptDefaultCodecs) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs = engine_.recv_codecs();
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  FakeVideoReceiveStream* stream = AddRecvStream();
  const webrtc::VideoReceiveStreamInterface::Config& config =
      stream->GetConfig();
  EXPECT_EQ(engine_.recv_codecs()[0].name,
            config.decoders[0].video_format.name);
  EXPECT_EQ(engine_.recv_codecs()[0].id, config.decoders[0].payload_type);
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(VideoCodec(101, "WTF3"));
  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptsMultipleVideoCodecs) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithoutFecDisablesFec) {
  cricket::VideoSendParameters send_parameters;
  send_parameters.codecs.push_back(GetEngineCodec("VP8"));
  send_parameters.codecs.push_back(GetEngineCodec("red"));
  send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters));

  FakeVideoReceiveStream* stream = AddRecvStream();

  EXPECT_EQ(GetEngineCodec("ulpfec").id,
            stream->GetConfig().rtp.ulpfec_payload_type);

  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
  stream = fake_call_->GetVideoReceiveStreams()[0];
  ASSERT_TRUE(stream != nullptr);
  EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec_payload_type)
      << "SetSendCodec without ULPFEC should disable current ULPFEC.";
}

TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvParamsWithoutFecDisablesFec) {
  AddRecvStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
  const std::vector<FakeFlexfecReceiveStream*>& streams =
      fake_call_->GetFlexfecReceiveStreams();

  ASSERT_EQ(1U, streams.size());
  const FakeFlexfecReceiveStream* stream = streams.front();
  EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type);
  EXPECT_EQ(kFlexfecSsrc, stream->remote_ssrc());
  ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size());
  EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]);

  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
  EXPECT_TRUE(streams.empty())
      << "SetSendCodec without FlexFEC should disable current FlexFEC.";
}

TEST_F(WebRtcVideoChannelTest, SetSendParamsWithFecEnablesFec) {
  FakeVideoReceiveStream* stream = AddRecvStream();
  EXPECT_EQ(GetEngineCodec("ulpfec").id,
            stream->GetConfig().rtp.ulpfec_payload_type);

  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
  recv_parameters.codecs.push_back(GetEngineCodec("red"));
  recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
  stream = fake_call_->GetVideoReceiveStreams()[0];
  ASSERT_TRUE(stream != nullptr);
  EXPECT_EQ(GetEngineCodec("ulpfec").id,
            stream->GetConfig().rtp.ulpfec_payload_type)
      << "ULPFEC should be enabled on the receive stream.";

  cricket::VideoSendParameters send_parameters;
  send_parameters.codecs.push_back(GetEngineCodec("VP8"));
  send_parameters.codecs.push_back(GetEngineCodec("red"));
  send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
  stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_EQ(GetEngineCodec("ulpfec").id,
            stream->GetConfig().rtp.ulpfec_payload_type)
      << "ULPFEC should be enabled on the receive stream.";
}

TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
       SetSendRecvParamsWithFecEnablesFec) {
  AddRecvStream(
      CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
  const std::vector<FakeFlexfecReceiveStream*>& streams =
      fake_call_->GetFlexfecReceiveStreams();

  cricket::VideoRecvParameters recv_parameters;
  recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
  recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
  ASSERT_EQ(1U, streams.size());
  const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
  EXPECT_EQ(GetEngineCodec("flexfec-03").id,
            stream_with_recv_params->GetConfig().payload_type);
  EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().rtp.remote_ssrc);
  EXPECT_EQ(1U,
            stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
  EXPECT_EQ(kSsrcs1[0],
            stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);

  cricket::VideoSendParameters send_parameters;
  send_parameters.codecs.push_back(GetEngineCodec("VP8"));
  send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
  ASSERT_EQ(1U, streams.size());
  const FakeFlexfecReceiveStream* stream_with_send_params = streams.front();
  EXPECT_EQ(GetEngineCodec("flexfec-03").id,
            stream_with_send_params->GetConfig().payload_type);
  EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().rtp.remote_ssrc);
  EXPECT_EQ(1U,
            stream_with_send_params->GetConfig().protected_media_ssrcs.size());
  EXPECT_EQ(kSsrcs1[0],
            stream_with_send_params->GetConfig().protected_media_ssrcs[0]);
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateFecPayloads) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("red"));
  parameters.codecs[1].id = parameters.codecs[0].id;
  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
}

TEST_F(WebRtcVideoChannelFlexfecRecvTest,
       SetRecvCodecsRejectDuplicateFecPayloads) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
  parameters.codecs[1].id = parameters.codecs[0].id;
  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
}

TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateCodecPayloads) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  parameters.codecs[1].id = parameters.codecs[0].id;
  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
}

TEST_F(WebRtcVideoChannelTest,
       SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs[1].id += 1;
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
}

// Test that setting the same codecs but with a different order
// doesn't result in the stream being recreated.
TEST_F(WebRtcVideoChannelTest,
       SetRecvCodecsDifferentOrderDoesntRecreateStream) {
  cricket::VideoRecvParameters parameters1;
  parameters1.codecs.push_back(GetEngineCodec("VP8"));
  parameters1.codecs.push_back(GetEngineCodec("red"));
  EXPECT_TRUE(channel_->SetRecvParameters(parameters1));

  AddRecvStream(cricket::StreamParams::CreateLegacy(123));
  EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());

  cricket::VideoRecvParameters parameters2;
  parameters2.codecs.push_back(GetEngineCodec("red"));
  parameters2.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
  EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
}

TEST_F(WebRtcVideoChannelTest, SendStreamNotSendingByDefault) {
  EXPECT_FALSE(AddSendStream()->IsSending());
}

TEST_F(WebRtcVideoChannelTest, ReceiveStreamReceivingByDefault) {
  EXPECT_TRUE(AddRecvStream()->IsReceiving());
}

TEST_F(WebRtcVideoChannelTest, SetSend) {
  FakeVideoSendStream* stream = AddSendStream();
  EXPECT_FALSE(stream->IsSending());

  // false->true
  EXPECT_TRUE(channel_->SetSend(true));
  EXPECT_TRUE(stream->IsSending());
  // true->true
  EXPECT_TRUE(channel_->SetSend(true));
  EXPECT_TRUE(stream->IsSending());
  // true->false
  EXPECT_TRUE(channel_->SetSend(false));
  EXPECT_FALSE(stream->IsSending());
  // false->false
  EXPECT_TRUE(channel_->SetSend(false));
  EXPECT_FALSE(stream->IsSending());

  EXPECT_TRUE(channel_->SetSend(true));
  FakeVideoSendStream* new_stream = AddSendStream();
  EXPECT_TRUE(new_stream->IsSending())
      << "Send stream created after SetSend(true) not sending initially.";
}

// This test verifies DSCP settings are properly applied on video media channel.
TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
  std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
      new cricket::FakeNetworkInterface);
  MediaConfig config;
  std::unique_ptr<cricket::WebRtcVideoChannel> channel;
  webrtc::RtpParameters parameters;

  channel.reset(
      static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
          call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
          video_bitrate_allocator_factory_.get())));
  channel->SetInterface(network_interface.get());
  // Default value when DSCP is disabled should be DSCP_DEFAULT.
  EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
  channel->SetInterface(nullptr);

  // Default value when DSCP is enabled is also DSCP_DEFAULT, until it is set
  // through rtp parameters.
  config.enable_dscp = true;
  channel.reset(
      static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
          call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
          video_bitrate_allocator_factory_.get())));
  channel->SetInterface(network_interface.get());
  EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());

  // Create a send stream to configure
  EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
  parameters = channel->GetRtpSendParameters(kSsrc);
  ASSERT_FALSE(parameters.encodings.empty());

  // Various priorities map to various dscp values.
  parameters.encodings[0].network_priority = webrtc::Priority::kHigh;
  ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
  EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
  parameters.encodings[0].network_priority = webrtc::Priority::kVeryLow;
  ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
  EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());

  // Packets should also self-identify their dscp in PacketOptions.
  const uint8_t kData[10] = {0};
  EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get())
                  ->SendRtcp(kData, sizeof(kData)));
  EXPECT_EQ(rtc::DSCP_CS1, network_interface->options().dscp);
  channel->SetInterface(nullptr);

  // Verify that setting the option to false resets the
  // DiffServCodePoint.
  config.enable_dscp = false;
  channel.reset(
      static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
          call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
          video_bitrate_allocator_factory_.get())));
  channel->SetInterface(network_interface.get());
  EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
  channel->SetInterface(nullptr);
}

// This test verifies that the RTCP reduced size mode is properly applied to
// send video streams.
TEST_F(WebRtcVideoChannelTest, TestSetSendRtcpReducedSize) {
  // Create stream, expecting that default mode is "compound".
  FakeVideoSendStream* stream1 = AddSendStream();
  EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_FALSE(rtp_parameters.rtcp.reduced_size);

  // Now enable reduced size mode.
  send_parameters_.rtcp.reduced_size = true;
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
  stream1 = fake_call_->GetVideoSendStreams()[0];
  EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
  rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_TRUE(rtp_parameters.rtcp.reduced_size);

  // Create a new stream and ensure it picks up the reduced size mode.
  FakeVideoSendStream* stream2 = AddSendStream();
  EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
}

// This test verifies that the RTCP reduced size mode is properly applied to
// receive video streams.
TEST_F(WebRtcVideoChannelTest, TestSetRecvRtcpReducedSize) {
  // Create stream, expecting that default mode is "compound".
  FakeVideoReceiveStream* stream1 = AddRecvStream();
  EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);

  // Now enable reduced size mode.
  // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
  // the reduced_size flag should come from that.
  send_parameters_.rtcp.reduced_size = true;
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
  stream1 = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);

  // Create a new stream and ensure it picks up the reduced size mode.
  FakeVideoReceiveStream* stream2 = AddRecvStream();
  EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
}

TEST_F(WebRtcVideoChannelTest, OnReadyToSendSignalsNetworkState) {
  EXPECT_EQ(webrtc::kNetworkUp,
            fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
  EXPECT_EQ(webrtc::kNetworkUp,
            fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));

  channel_->OnReadyToSend(false);
  EXPECT_EQ(webrtc::kNetworkDown,
            fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
  EXPECT_EQ(webrtc::kNetworkUp,
            fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));

  channel_->OnReadyToSend(true);
  EXPECT_EQ(webrtc::kNetworkUp,
            fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
  EXPECT_EQ(webrtc::kNetworkUp,
            fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
}

TEST_F(WebRtcVideoChannelTest, GetStatsReportsSentCodecName) {
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  AddSendStream();

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ("VP8", info.senders[0].codec_name);
}

TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.encoder_implementation_name = "encoder_implementation_name";
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(stats.encoder_implementation_name,
            info.senders[0].encoder_implementation_name);
}

TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.avg_encode_time_ms = 13;
  stats.encode_usage_percent = 42;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
  EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
}

TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.frames_encoded = 13;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
}

TEST_F(WebRtcVideoChannelTest, GetStatsReportsKeyFramesEncoded) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.substreams[123].frame_counts.key_frames = 10;
  stats.substreams[456].frame_counts.key_frames = 87;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(info.senders.size(), 2u);
  EXPECT_EQ(10u, info.senders[0].key_frames_encoded);
  EXPECT_EQ(87u, info.senders[1].key_frames_encoded);
  EXPECT_EQ(97u, info.aggregated_senders[0].key_frames_encoded);
}

TEST_F(WebRtcVideoChannelTest, GetStatsReportsPerLayerQpSum) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.substreams[123].qp_sum = 15;
  stats.substreams[456].qp_sum = 11;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(info.senders.size(), 2u);
  EXPECT_EQ(stats.substreams[123].qp_sum, info.senders[0].qp_sum);
  EXPECT_EQ(stats.substreams[456].qp_sum, info.senders[1].qp_sum);
  EXPECT_EQ(*info.aggregated_senders[0].qp_sum, 26u);
}

webrtc::VideoSendStream::Stats GetInitialisedStats() {
  webrtc::VideoSendStream::Stats stats;
  stats.encoder_implementation_name = "vp";
  stats.input_frame_rate = 1.0;
  stats.encode_frame_rate = 2;
  stats.avg_encode_time_ms = 3;
  stats.encode_usage_percent = 4;
  stats.frames_encoded = 5;
  stats.total_encode_time_ms = 6;
  stats.frames_dropped_by_capturer = 7;
  stats.frames_dropped_by_encoder_queue = 8;
  stats.frames_dropped_by_rate_limiter = 9;
  stats.frames_dropped_by_congestion_window = 10;
  stats.frames_dropped_by_encoder = 11;
  stats.target_media_bitrate_bps = 13;
  stats.media_bitrate_bps = 14;
  stats.suspended = true;
  stats.bw_limited_resolution = true;
  stats.cpu_limited_resolution = true;
  // Not wired.
  stats.bw_limited_framerate = true;
  // Not wired.
  stats.cpu_limited_framerate = true;
  stats.quality_limitation_reason = webrtc::QualityLimitationReason::kCpu;
  stats.quality_limitation_durations_ms[webrtc::QualityLimitationReason::kCpu] =
      15;
  stats.quality_limitation_resolution_changes = 16;
  stats.number_of_cpu_adapt_changes = 17;
  stats.number_of_quality_adapt_changes = 18;
  stats.has_entered_low_resolution = true;
  stats.content_type = webrtc::VideoContentType::SCREENSHARE;
  stats.frames_sent = 19;
  stats.huge_frames_sent = 20;

  return stats;
}

TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportWithoutSubStreams) {
  FakeVideoSendStream* stream = AddSendStream();
  auto stats = GetInitialisedStats();
  stream->SetStats(stats);
  cricket::VideoMediaInfo video_media_info;
  ASSERT_TRUE(channel_->GetStats(&video_media_info));
  EXPECT_EQ(video_media_info.aggregated_senders.size(), 1u);
  auto& sender = video_media_info.aggregated_senders[0];

  // MediaSenderInfo

  EXPECT_EQ(sender.payload_bytes_sent, 0);
  EXPECT_EQ(sender.header_and_padding_bytes_sent, 0);
  EXPECT_EQ(sender.retransmitted_bytes_sent, 0u);
  EXPECT_EQ(sender.packets_sent, 0);
  EXPECT_EQ(sender.retransmitted_packets_sent, 0u);
  EXPECT_EQ(sender.packets_lost, 0);
  EXPECT_EQ(sender.fraction_lost, 0.0f);
  EXPECT_EQ(sender.rtt_ms, 0);
  EXPECT_EQ(sender.codec_name, DefaultCodec().name);
  EXPECT_EQ(sender.codec_payload_type, DefaultCodec().id);
  EXPECT_EQ(sender.local_stats.size(), 1u);
  EXPECT_EQ(sender.local_stats[0].ssrc, last_ssrc_);
  EXPECT_EQ(sender.local_stats[0].timestamp, 0.0f);
  EXPECT_EQ(sender.remote_stats.size(), 0u);
  EXPECT_EQ(sender.report_block_datas.size(), 0u);

  // VideoSenderInfo

  EXPECT_EQ(sender.ssrc_groups.size(), 0u);
  EXPECT_EQ(sender.encoder_implementation_name,
            stats.encoder_implementation_name);
  // Comes from substream only.
  EXPECT_EQ(sender.firs_rcvd, 0);
  EXPECT_EQ(sender.plis_rcvd, 0);
  EXPECT_EQ(sender.nacks_rcvd, 0u);
  EXPECT_EQ(sender.send_frame_width, 0);
  EXPECT_EQ(sender.send_frame_height, 0);

  EXPECT_EQ(sender.framerate_input, stats.input_frame_rate);
  EXPECT_EQ(sender.framerate_sent, stats.encode_frame_rate);
  EXPECT_EQ(sender.nominal_bitrate, stats.media_bitrate_bps);
  EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_CPU, 0);
  EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_BANDWIDTH, 0);
  EXPECT_EQ(sender.adapt_changes, stats.number_of_cpu_adapt_changes);
  EXPECT_EQ(sender.quality_limitation_reason, stats.quality_limitation_reason);
  EXPECT_EQ(sender.quality_limitation_durations_ms,
            stats.quality_limitation_durations_ms);
  EXPECT_EQ(sender.quality_limitation_resolution_changes,
            stats.quality_limitation_resolution_changes);
  EXPECT_EQ(sender.avg_encode_ms, stats.avg_encode_time_ms);
  EXPECT_EQ(sender.encode_usage_percent, stats.encode_usage_percent);
  EXPECT_EQ(sender.frames_encoded, stats.frames_encoded);
  // Comes from substream only.
  EXPECT_EQ(sender.key_frames_encoded, 0u);

  EXPECT_EQ(sender.total_encode_time_ms, stats.total_encode_time_ms);
  EXPECT_EQ(sender.total_encoded_bytes_target,
            stats.total_encoded_bytes_target);
  // Comes from substream only.
  EXPECT_EQ(sender.total_packet_send_delay_ms, 0u);
  EXPECT_EQ(sender.qp_sum, absl::nullopt);

  EXPECT_EQ(sender.has_entered_low_resolution,
            stats.has_entered_low_resolution);
  EXPECT_EQ(sender.content_type, webrtc::VideoContentType::SCREENSHARE);
  EXPECT_EQ(sender.frames_sent, stats.frames_encoded);
  EXPECT_EQ(sender.huge_frames_sent, stats.huge_frames_sent);
  EXPECT_EQ(sender.rid, absl::nullopt);
}

TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportForSubStreams) {
  FakeVideoSendStream* stream = AddSendStream();
  auto stats = GetInitialisedStats();

  const uint32_t ssrc_1 = 123u;
  const uint32_t ssrc_2 = 456u;

  auto& substream = stats.substreams[ssrc_1];
  substream.frame_counts.key_frames = 1;
  substream.frame_counts.delta_frames = 2;
  substream.width = 3;
  substream.height = 4;
  substream.total_bitrate_bps = 5;
  substream.retransmit_bitrate_bps = 6;
  substream.avg_delay_ms = 7;
  substream.max_delay_ms = 8;
  substream.total_packet_send_delay_ms = 9;
  substream.rtp_stats.transmitted.header_bytes = 10;
  substream.rtp_stats.transmitted.padding_bytes = 11;
  substream.rtp_stats.retransmitted.payload_bytes = 12;
  substream.rtp_stats.retransmitted.packets = 13;
  substream.rtcp_packet_type_counts.fir_packets = 14;
  substream.rtcp_packet_type_counts.nack_packets = 15;
  substream.rtcp_packet_type_counts.pli_packets = 16;
  webrtc::RTCPReportBlock report_block;
  report_block.packets_lost = 17;
  report_block.fraction_lost = 18;
  webrtc::ReportBlockData report_block_data;
  report_block_data.SetReportBlock(report_block, 0);
  report_block_data.AddRoundTripTimeSample(19);
  substream.report_block_data = report_block_data;
  substream.encode_frame_rate = 20.0;
  substream.frames_encoded = 21;
  substream.qp_sum = 22;
  substream.total_encode_time_ms = 23;
  substream.total_encoded_bytes_target = 24;
  substream.huge_frames_sent = 25;

  stats.substreams[ssrc_2] = substream;

  stream->SetStats(stats);

  cricket::VideoMediaInfo video_media_info;
  ASSERT_TRUE(channel_->GetStats(&video_media_info));
  EXPECT_EQ(video_media_info.aggregated_senders.size(), 1u);
  auto& sender = video_media_info.aggregated_senders[0];

  // MediaSenderInfo

  EXPECT_EQ(
      sender.payload_bytes_sent,
      static_cast<int64_t>(2u * substream.rtp_stats.transmitted.payload_bytes));
  EXPECT_EQ(sender.header_and_padding_bytes_sent,
            static_cast<int64_t>(
                2u * (substream.rtp_stats.transmitted.header_bytes +
                      substream.rtp_stats.transmitted.padding_bytes)));
  EXPECT_EQ(sender.retransmitted_bytes_sent,
            2u * substream.rtp_stats.retransmitted.payload_bytes);
  EXPECT_EQ(sender.packets_sent,
            static_cast<int>(2 * substream.rtp_stats.transmitted.packets));
  EXPECT_EQ(sender.retransmitted_packets_sent,
            2u * substream.rtp_stats.retransmitted.packets);
  EXPECT_EQ(sender.packets_lost,
            2 * substream.report_block_data->report_block().packets_lost);
  EXPECT_EQ(sender.fraction_lost,
            static_cast<float>(
                substream.report_block_data->report_block().fraction_lost) /
                (1 << 8));
  EXPECT_EQ(sender.rtt_ms, 0);
  EXPECT_EQ(sender.codec_name, DefaultCodec().name);
  EXPECT_EQ(sender.codec_payload_type, DefaultCodec().id);
  EXPECT_EQ(sender.local_stats.size(), 1u);
  EXPECT_EQ(sender.local_stats[0].ssrc, last_ssrc_);
  EXPECT_EQ(sender.local_stats[0].timestamp, 0.0f);
  EXPECT_EQ(sender.remote_stats.size(), 0u);
  EXPECT_EQ(sender.report_block_datas.size(), 2u * 1);

  // VideoSenderInfo

  EXPECT_EQ(sender.ssrc_groups.size(), 0u);
  EXPECT_EQ(sender.encoder_implementation_name,
            stats.encoder_implementation_name);
  EXPECT_EQ(
      sender.firs_rcvd,
      static_cast<int>(2 * substream.rtcp_packet_type_counts.fir_packets));
  EXPECT_EQ(
      sender.plis_rcvd,
      static_cast<int>(2 * substream.rtcp_packet_type_counts.pli_packets));
  EXPECT_EQ(sender.nacks_rcvd,
            2 * substream.rtcp_packet_type_counts.nack_packets);
  EXPECT_EQ(sender.send_frame_width, substream.width);
  EXPECT_EQ(sender.send_frame_height, substream.height);

  EXPECT_EQ(sender.framerate_input, stats.input_frame_rate);
  EXPECT_EQ(sender.framerate_sent, stats.encode_frame_rate);
  EXPECT_EQ(sender.nominal_bitrate, stats.media_bitrate_bps);
  EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_CPU, 0);
  EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_BANDWIDTH, 0);
  EXPECT_EQ(sender.adapt_changes, stats.number_of_cpu_adapt_changes);
  EXPECT_EQ(sender.quality_limitation_reason, stats.quality_limitation_reason);
  EXPECT_EQ(sender.quality_limitation_durations_ms,
            stats.quality_limitation_durations_ms);
  EXPECT_EQ(sender.quality_limitation_resolution_changes,
            stats.quality_limitation_resolution_changes);
  EXPECT_EQ(sender.avg_encode_ms, stats.avg_encode_time_ms);
  EXPECT_EQ(sender.encode_usage_percent, stats.encode_usage_percent);
  EXPECT_EQ(sender.frames_encoded, 2u * substream.frames_encoded);
  EXPECT_EQ(sender.key_frames_encoded, 2u * substream.frame_counts.key_frames);
  EXPECT_EQ(sender.total_encode_time_ms, 2u * substream.total_encode_time_ms);
  EXPECT_EQ(sender.total_encoded_bytes_target,
            2u * substream.total_encoded_bytes_target);
  EXPECT_EQ(sender.total_packet_send_delay_ms,
            2u * substream.total_packet_send_delay_ms);
  EXPECT_EQ(sender.has_entered_low_resolution,
            stats.has_entered_low_resolution);
  EXPECT_EQ(sender.qp_sum, 2u * *substream.qp_sum);
  EXPECT_EQ(sender.content_type, webrtc::VideoContentType::SCREENSHARE);
  EXPECT_EQ(sender.frames_sent, 2u * substream.frames_encoded);
  EXPECT_EQ(sender.huge_frames_sent, stats.huge_frames_sent);
  EXPECT_EQ(sender.rid, absl::nullopt);
}

TEST_F(WebRtcVideoChannelTest, GetPerLayerStatsReportForSubStreams) {
  FakeVideoSendStream* stream = AddSendStream();
  auto stats = GetInitialisedStats();

  const uint32_t ssrc_1 = 123u;
  const uint32_t ssrc_2 = 456u;

  auto& substream = stats.substreams[ssrc_1];
  substream.frame_counts.key_frames = 1;
  substream.frame_counts.delta_frames = 2;
  substream.width = 3;
  substream.height = 4;
  substream.total_bitrate_bps = 5;
  substream.retransmit_bitrate_bps = 6;
  substream.avg_delay_ms = 7;
  substream.max_delay_ms = 8;
  substream.total_packet_send_delay_ms = 9;
  substream.rtp_stats.transmitted.header_bytes = 10;
  substream.rtp_stats.transmitted.padding_bytes = 11;
  substream.rtp_stats.retransmitted.payload_bytes = 12;
  substream.rtp_stats.retransmitted.packets = 13;
  substream.rtcp_packet_type_counts.fir_packets = 14;
  substream.rtcp_packet_type_counts.nack_packets = 15;
  substream.rtcp_packet_type_counts.pli_packets = 16;
  webrtc::RTCPReportBlock report_block;
  report_block.packets_lost = 17;
  report_block.fraction_lost = 18;
  webrtc::ReportBlockData report_block_data;
  report_block_data.SetReportBlock(report_block, 0);
  report_block_data.AddRoundTripTimeSample(19);
  substream.report_block_data = report_block_data;
  substream.encode_frame_rate = 20.0;
  substream.frames_encoded = 21;
  substream.qp_sum = 22;
  substream.total_encode_time_ms = 23;
  substream.total_encoded_bytes_target = 24;
  substream.huge_frames_sent = 25;

  stats.substreams[ssrc_2] = substream;

  stream->SetStats(stats);

  cricket::VideoMediaInfo video_media_info;
  ASSERT_TRUE(channel_->GetStats(&video_media_info));
  EXPECT_EQ(video_media_info.senders.size(), 2u);
  auto& sender = video_media_info.senders[0];

  // MediaSenderInfo

  EXPECT_EQ(
      sender.payload_bytes_sent,
      static_cast<int64_t>(substream.rtp_stats.transmitted.payload_bytes));
  EXPECT_EQ(
      sender.header_and_padding_bytes_sent,
      static_cast<int64_t>(substream.rtp_stats.transmitted.header_bytes +
                           substream.rtp_stats.transmitted.padding_bytes));
  EXPECT_EQ(sender.retransmitted_bytes_sent,
            substream.rtp_stats.retransmitted.payload_bytes);
  EXPECT_EQ(sender.packets_sent,
            static_cast<int>(substream.rtp_stats.transmitted.packets));
  EXPECT_EQ(sender.retransmitted_packets_sent,
            substream.rtp_stats.retransmitted.packets);
  EXPECT_EQ(sender.packets_lost,
            substream.report_block_data->report_block().packets_lost);
  EXPECT_EQ(sender.fraction_lost,
            static_cast<float>(
                substream.report_block_data->report_block().fraction_lost) /
                (1 << 8));
  EXPECT_EQ(sender.rtt_ms, 0);
  EXPECT_EQ(sender.codec_name, DefaultCodec().name);
  EXPECT_EQ(sender.codec_payload_type, DefaultCodec().id);
  EXPECT_EQ(sender.local_stats.size(), 1u);
  EXPECT_EQ(sender.local_stats[0].ssrc, ssrc_1);
  EXPECT_EQ(sender.local_stats[0].timestamp, 0.0f);
  EXPECT_EQ(sender.remote_stats.size(), 0u);
  EXPECT_EQ(sender.report_block_datas.size(), 1u);

  // VideoSenderInfo

  EXPECT_EQ(sender.ssrc_groups.size(), 0u);
  EXPECT_EQ(sender.encoder_implementation_name,
            stats.encoder_implementation_name);
  EXPECT_EQ(sender.firs_rcvd,
            static_cast<int>(substream.rtcp_packet_type_counts.fir_packets));
  EXPECT_EQ(sender.plis_rcvd,
            static_cast<int>(substream.rtcp_packet_type_counts.pli_packets));
  EXPECT_EQ(sender.nacks_rcvd, substream.rtcp_packet_type_counts.nack_packets);
  EXPECT_EQ(sender.send_frame_width, substream.width);
  EXPECT_EQ(sender.send_frame_height, substream.height);

  EXPECT_EQ(sender.framerate_input, stats.input_frame_rate);
  EXPECT_EQ(sender.framerate_sent, substream.encode_frame_rate);
  EXPECT_EQ(sender.nominal_bitrate, stats.media_bitrate_bps);
  EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_CPU, 0);
  EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_BANDWIDTH, 0);
  EXPECT_EQ(sender.adapt_changes, stats.number_of_cpu_adapt_changes);
  EXPECT_EQ(sender.quality_limitation_reason, stats.quality_limitation_reason);
  EXPECT_EQ(sender.quality_limitation_durations_ms,
            stats.quality_limitation_durations_ms);
  EXPECT_EQ(sender.quality_limitation_resolution_changes,
            stats.quality_limitation_resolution_changes);
  EXPECT_EQ(sender.avg_encode_ms, stats.avg_encode_time_ms);
  EXPECT_EQ(sender.encode_usage_percent, stats.encode_usage_percent);
  EXPECT_EQ(sender.frames_encoded,
            static_cast<uint32_t>(substream.frames_encoded));
  EXPECT_EQ(sender.key_frames_encoded,
            static_cast<uint32_t>(substream.frame_counts.key_frames));
  EXPECT_EQ(sender.total_encode_time_ms, substream.total_encode_time_ms);
  EXPECT_EQ(sender.total_encoded_bytes_target,
            substream.total_encoded_bytes_target);
  EXPECT_EQ(sender.total_packet_send_delay_ms,
            substream.total_packet_send_delay_ms);
  EXPECT_EQ(sender.has_entered_low_resolution,
            stats.has_entered_low_resolution);
  EXPECT_EQ(sender.qp_sum, *substream.qp_sum);
  EXPECT_EQ(sender.content_type, webrtc::VideoContentType::SCREENSHARE);
  EXPECT_EQ(sender.frames_sent,
            static_cast<uint32_t>(substream.frames_encoded));
  EXPECT_EQ(sender.huge_frames_sent, substream.huge_frames_sent);
  EXPECT_EQ(sender.rid, absl::nullopt);
}

TEST_F(WebRtcVideoChannelTest, MediaSubstreamMissingProducesEmpyStats) {
  FakeVideoSendStream* stream = AddSendStream();

  const uint32_t kRtxSsrc = 123u;
  const uint32_t kMissingMediaSsrc = 124u;

  // Set up a scenarios where we have a substream that is not kMedia (in this
  // case: kRtx) but its associated kMedia stream does not exist yet. This
  // results in zero GetPerLayerVideoSenderInfos despite non-empty substreams.
  // Covers https://crbug.com/1090712.
  auto stats = GetInitialisedStats();
  auto& substream = stats.substreams[kRtxSsrc];
  substream.type = webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
  substream.referenced_media_ssrc = kMissingMediaSsrc;
  stream->SetStats(stats);

  cricket::VideoMediaInfo video_media_info;
  ASSERT_TRUE(channel_->GetStats(&video_media_info));
  EXPECT_TRUE(video_media_info.senders.empty());
}

TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.substreams[17].width = 123;
  stats.substreams[17].height = 40;
  stats.substreams[42].width = 80;
  stats.substreams[42].height = 31;
  stats.substreams[11].width = 20;
  stats.substreams[11].height = 90;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  ASSERT_EQ(1u, info.aggregated_senders.size());
  ASSERT_EQ(3u, info.senders.size());
  EXPECT_EQ(123, info.senders[1].send_frame_width);
  EXPECT_EQ(40, info.senders[1].send_frame_height);
  EXPECT_EQ(80, info.senders[2].send_frame_width);
  EXPECT_EQ(31, info.senders[2].send_frame_height);
  EXPECT_EQ(20, info.senders[0].send_frame_width);
  EXPECT_EQ(90, info.senders[0].send_frame_height);
  EXPECT_EQ(123, info.aggregated_senders[0].send_frame_width);
  EXPECT_EQ(90, info.aggregated_senders[0].send_frame_height);
}

TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.number_of_cpu_adapt_changes = 2;
  stats.cpu_limited_resolution = true;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  EXPECT_TRUE(channel_->GetStats(&info));
  ASSERT_EQ(1U, info.senders.size());
  EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, info.senders[0].adapt_reason);
  EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
}

TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.number_of_cpu_adapt_changes = 2;
  stats.cpu_limited_resolution = true;
  stats.bw_limited_resolution = true;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  EXPECT_TRUE(channel_->GetStats(&info));
  ASSERT_EQ(1U, info.senders.size());
  EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU |
                WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
            info.senders[0].adapt_reason);
  EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
}

TEST(WebRtcVideoChannelHelperTest, MergeInfoAboutOutboundRtpSubstreams) {
  const uint32_t kFirstMediaStreamSsrc = 10;
  const uint32_t kSecondMediaStreamSsrc = 20;
  const uint32_t kRtxSsrc = 30;
  const uint32_t kFlexfecSsrc = 40;
  std::map<uint32_t, webrtc::VideoSendStream::StreamStats> substreams;
  // First kMedia stream.
  substreams[kFirstMediaStreamSsrc].type =
      webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
  substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.header_bytes = 1;
  substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.padding_bytes = 2;
  substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.payload_bytes = 3;
  substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.packets = 4;
  substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.header_bytes = 5;
  substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.padding_bytes = 6;
  substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.payload_bytes = 7;
  substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.packets = 8;
  substreams[kFirstMediaStreamSsrc].referenced_media_ssrc = absl::nullopt;
  substreams[kFirstMediaStreamSsrc].width = 1280;
  substreams[kFirstMediaStreamSsrc].height = 720;
  // Second kMedia stream.
  substreams[kSecondMediaStreamSsrc].type =
      webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
  substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.header_bytes = 10;
  substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.padding_bytes = 11;
  substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.payload_bytes = 12;
  substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.packets = 13;
  substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.header_bytes = 14;
  substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.padding_bytes = 15;
  substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.payload_bytes = 16;
  substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.packets = 17;
  substreams[kSecondMediaStreamSsrc].referenced_media_ssrc = absl::nullopt;
  substreams[kSecondMediaStreamSsrc].width = 640;
  substreams[kSecondMediaStreamSsrc].height = 480;
  // kRtx stream referencing the first kMedia stream.
  substreams[kRtxSsrc].type =
      webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
  substreams[kRtxSsrc].rtp_stats.transmitted.header_bytes = 19;
  substreams[kRtxSsrc].rtp_stats.transmitted.padding_bytes = 20;
  substreams[kRtxSsrc].rtp_stats.transmitted.payload_bytes = 21;
  substreams[kRtxSsrc].rtp_stats.transmitted.packets = 22;
  substreams[kRtxSsrc].rtp_stats.retransmitted.header_bytes = 23;
  substreams[kRtxSsrc].rtp_stats.retransmitted.padding_bytes = 24;
  substreams[kRtxSsrc].rtp_stats.retransmitted.payload_bytes = 25;
  substreams[kRtxSsrc].rtp_stats.retransmitted.packets = 26;
  substreams[kRtxSsrc].referenced_media_ssrc = kFirstMediaStreamSsrc;
  // kFlexfec stream referencing the second kMedia stream.
  substreams[kFlexfecSsrc].type =
      webrtc::VideoSendStream::StreamStats::StreamType::kFlexfec;
  substreams[kFlexfecSsrc].rtp_stats.transmitted.header_bytes = 19;
  substreams[kFlexfecSsrc].rtp_stats.transmitted.padding_bytes = 20;
  substreams[kFlexfecSsrc].rtp_stats.transmitted.payload_bytes = 21;
  substreams[kFlexfecSsrc].rtp_stats.transmitted.packets = 22;
  substreams[kFlexfecSsrc].rtp_stats.retransmitted.header_bytes = 23;
  substreams[kFlexfecSsrc].rtp_stats.retransmitted.padding_bytes = 24;
  substreams[kFlexfecSsrc].rtp_stats.retransmitted.payload_bytes = 25;
  substreams[kFlexfecSsrc].rtp_stats.retransmitted.packets = 26;
  substreams[kFlexfecSsrc].referenced_media_ssrc = kSecondMediaStreamSsrc;

  auto merged_substreams =
      MergeInfoAboutOutboundRtpSubstreamsForTesting(substreams);
  // Only kMedia substreams remain.
  EXPECT_TRUE(merged_substreams.find(kFirstMediaStreamSsrc) !=
              merged_substreams.end());
  EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].type,
            webrtc::VideoSendStream::StreamStats::StreamType::kMedia);
  EXPECT_TRUE(merged_substreams.find(kSecondMediaStreamSsrc) !=
              merged_substreams.end());
  EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].type,
            webrtc::VideoSendStream::StreamStats::StreamType::kMedia);
  EXPECT_FALSE(merged_substreams.find(kRtxSsrc) != merged_substreams.end());
  EXPECT_FALSE(merged_substreams.find(kFlexfecSsrc) != merged_substreams.end());
  // Expect kFirstMediaStreamSsrc's rtp_stats to be merged with kRtxSsrc.
  webrtc::StreamDataCounters first_media_expected_rtp_stats =
      substreams[kFirstMediaStreamSsrc].rtp_stats;
  first_media_expected_rtp_stats.Add(substreams[kRtxSsrc].rtp_stats);
  EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted,
            first_media_expected_rtp_stats.transmitted);
  EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted,
            first_media_expected_rtp_stats.retransmitted);
  // Expect kSecondMediaStreamSsrc' rtp_stats to be merged with kFlexfecSsrc.
  webrtc::StreamDataCounters second_media_expected_rtp_stats =
      substreams[kSecondMediaStreamSsrc].rtp_stats;
  second_media_expected_rtp_stats.Add(substreams[kFlexfecSsrc].rtp_stats);
  EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted,
            second_media_expected_rtp_stats.transmitted);
  EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted,
            second_media_expected_rtp_stats.retransmitted);
  // Expect other metrics to come from the original kMedia stats.
  EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].width,
            substreams[kFirstMediaStreamSsrc].width);
  EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].height,
            substreams[kFirstMediaStreamSsrc].height);
  EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].width,
            substreams[kSecondMediaStreamSsrc].width);
  EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].height,
            substreams[kSecondMediaStreamSsrc].height);
}

TEST_F(WebRtcVideoChannelTest,
       GetStatsReportsTransmittedAndRetransmittedBytesAndPacketsCorrectly) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  // Simulcast layer 1, RTP stream. header+padding=10, payload=20, packets=3.
  stats.substreams[101].type =
      webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
  stats.substreams[101].rtp_stats.transmitted.header_bytes = 5;
  stats.substreams[101].rtp_stats.transmitted.padding_bytes = 5;
  stats.substreams[101].rtp_stats.transmitted.payload_bytes = 20;
  stats.substreams[101].rtp_stats.transmitted.packets = 3;
  stats.substreams[101].rtp_stats.retransmitted.header_bytes = 0;
  stats.substreams[101].rtp_stats.retransmitted.padding_bytes = 0;
  stats.substreams[101].rtp_stats.retransmitted.payload_bytes = 0;
  stats.substreams[101].rtp_stats.retransmitted.packets = 0;
  stats.substreams[101].referenced_media_ssrc = absl::nullopt;
  // Simulcast layer 1, RTX stream. header+padding=5, payload=10, packets=1.
  stats.substreams[102].type =
      webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
  stats.substreams[102].rtp_stats.retransmitted.header_bytes = 3;
  stats.substreams[102].rtp_stats.retransmitted.padding_bytes = 2;
  stats.substreams[102].rtp_stats.retransmitted.payload_bytes = 10;
  stats.substreams[102].rtp_stats.retransmitted.packets = 1;
  stats.substreams[102].rtp_stats.transmitted =
      stats.substreams[102].rtp_stats.retransmitted;
  stats.substreams[102].referenced_media_ssrc = 101;
  // Simulcast layer 2, RTP stream. header+padding=20, payload=40, packets=7.
  stats.substreams[201].type =
      webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
  stats.substreams[201].rtp_stats.transmitted.header_bytes = 10;
  stats.substreams[201].rtp_stats.transmitted.padding_bytes = 10;
  stats.substreams[201].rtp_stats.transmitted.payload_bytes = 40;
  stats.substreams[201].rtp_stats.transmitted.packets = 7;
  stats.substreams[201].rtp_stats.retransmitted.header_bytes = 0;
  stats.substreams[201].rtp_stats.retransmitted.padding_bytes = 0;
  stats.substreams[201].rtp_stats.retransmitted.payload_bytes = 0;
  stats.substreams[201].rtp_stats.retransmitted.packets = 0;
  stats.substreams[201].referenced_media_ssrc = absl::nullopt;
  // Simulcast layer 2, RTX stream. header+padding=10, payload=20, packets=4.
  stats.substreams[202].type =
      webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
  stats.substreams[202].rtp_stats.retransmitted.header_bytes = 6;
  stats.substreams[202].rtp_stats.retransmitted.padding_bytes = 4;
  stats.substreams[202].rtp_stats.retransmitted.payload_bytes = 20;
  stats.substreams[202].rtp_stats.retransmitted.packets = 4;
  stats.substreams[202].rtp_stats.transmitted =
      stats.substreams[202].rtp_stats.retransmitted;
  stats.substreams[202].referenced_media_ssrc = 201;
  // FlexFEC stream associated with the Simulcast layer 2.
  // header+padding=15, payload=17, packets=5.
  stats.substreams[301].type =
      webrtc::VideoSendStream::StreamStats::StreamType::kFlexfec;
  stats.substreams[301].rtp_stats.transmitted.header_bytes = 13;
  stats.substreams[301].rtp_stats.transmitted.padding_bytes = 2;
  stats.substreams[301].rtp_stats.transmitted.payload_bytes = 17;
  stats.substreams[301].rtp_stats.transmitted.packets = 5;
  stats.substreams[301].rtp_stats.retransmitted.header_bytes = 0;
  stats.substreams[301].rtp_stats.retransmitted.padding_bytes = 0;
  stats.substreams[301].rtp_stats.retransmitted.payload_bytes = 0;
  stats.substreams[301].rtp_stats.retransmitted.packets = 0;
  stats.substreams[301].referenced_media_ssrc = 201;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(info.senders.size(), 2u);
  EXPECT_EQ(15u, info.senders[0].header_and_padding_bytes_sent);
  EXPECT_EQ(30u, info.senders[0].payload_bytes_sent);
  EXPECT_EQ(4, info.senders[0].packets_sent);
  EXPECT_EQ(10u, info.senders[0].retransmitted_bytes_sent);
  EXPECT_EQ(1u, info.senders[0].retransmitted_packets_sent);

  EXPECT_EQ(45u, info.senders[1].header_and_padding_bytes_sent);
  EXPECT_EQ(77u, info.senders[1].payload_bytes_sent);
  EXPECT_EQ(16, info.senders[1].packets_sent);
  EXPECT_EQ(20u, info.senders[1].retransmitted_bytes_sent);
  EXPECT_EQ(4u, info.senders[1].retransmitted_packets_sent);
}

TEST_F(WebRtcVideoChannelTest,
       GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.bw_limited_resolution = true;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  EXPECT_TRUE(channel_->GetStats(&info));
  ASSERT_EQ(1U, info.senders.size());
  EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
            info.senders[0].adapt_reason);
}

TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
  stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
  stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;

  stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
  stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
  stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;

  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(2, info.senders[0].firs_rcvd);
  EXPECT_EQ(3u, info.senders[0].nacks_rcvd);
  EXPECT_EQ(4, info.senders[0].plis_rcvd);

  EXPECT_EQ(5, info.senders[1].firs_rcvd);
  EXPECT_EQ(7u, info.senders[1].nacks_rcvd);
  EXPECT_EQ(9, info.senders[1].plis_rcvd);

  EXPECT_EQ(7, info.aggregated_senders[0].firs_rcvd);
  EXPECT_EQ(10u, info.aggregated_senders[0].nacks_rcvd);
  EXPECT_EQ(13, info.aggregated_senders[0].plis_rcvd);
}

TEST_F(WebRtcVideoChannelTest,
       GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
  FakeVideoReceiveStream* stream = AddRecvStream();
  webrtc::VideoReceiveStreamInterface::Stats stats;
  stats.rtcp_packet_type_counts.fir_packets = 2;
  stats.rtcp_packet_type_counts.nack_packets = 3;
  stats.rtcp_packet_type_counts.pli_packets = 4;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
            rtc::checked_cast<unsigned int>(info.receivers[0].firs_sent));
  EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
            info.receivers[0].nacks_sent);
  EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
            rtc::checked_cast<unsigned int>(info.receivers[0].plis_sent));
}

TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
  FakeVideoReceiveStream* stream = AddRecvStream();
  webrtc::VideoReceiveStreamInterface::Stats stats;
  stats.decoder_implementation_name = "decoder_implementation_name";
  stats.decode_ms = 2;
  stats.max_decode_ms = 3;
  stats.current_delay_ms = 4;
  stats.target_delay_ms = 5;
  stats.jitter_buffer_ms = 6;
  stats.jitter_buffer_delay_seconds = 60;
  stats.jitter_buffer_emitted_count = 6;
  stats.min_playout_delay_ms = 7;
  stats.render_delay_ms = 8;
  stats.width = 9;
  stats.height = 10;
  stats.frame_counts.key_frames = 11;
  stats.frame_counts.delta_frames = 12;
  stats.frames_rendered = 13;
  stats.frames_decoded = 14;
  stats.qp_sum = 15;
  stats.total_decode_time_ms = 16;
  stats.total_assembly_time = webrtc::TimeDelta::Millis(4);
  stats.frames_assembled_from_multiple_packets = 2;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(stats.decoder_implementation_name,
            info.receivers[0].decoder_implementation_name);
  EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
  EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
  EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
  EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
  EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
  EXPECT_EQ(stats.jitter_buffer_delay_seconds,
            info.receivers[0].jitter_buffer_delay_seconds);
  EXPECT_EQ(stats.jitter_buffer_emitted_count,
            info.receivers[0].jitter_buffer_emitted_count);
  EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
  EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
  EXPECT_EQ(stats.width, info.receivers[0].frame_width);
  EXPECT_EQ(stats.height, info.receivers[0].frame_height);
  EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames +
                                            stats.frame_counts.delta_frames),
            info.receivers[0].frames_received);
  EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
  EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
  EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames),
            info.receivers[0].key_frames_decoded);
  EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum);
  EXPECT_EQ(stats.total_decode_time_ms, info.receivers[0].total_decode_time_ms);
  EXPECT_EQ(stats.total_assembly_time, info.receivers[0].total_assembly_time);
  EXPECT_EQ(stats.frames_assembled_from_multiple_packets,
            info.receivers[0].frames_assembled_from_multiple_packets);
}

TEST_F(WebRtcVideoChannelTest,
       GetStatsTranslatesInterFrameDelayStatsCorrectly) {
  FakeVideoReceiveStream* stream = AddRecvStream();
  webrtc::VideoReceiveStreamInterface::Stats stats;
  stats.total_inter_frame_delay = 0.123;
  stats.total_squared_inter_frame_delay = 0.00456;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(stats.total_inter_frame_delay,
            info.receivers[0].total_inter_frame_delay);
  EXPECT_EQ(stats.total_squared_inter_frame_delay,
            info.receivers[0].total_squared_inter_frame_delay);
}

TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) {
  FakeVideoReceiveStream* stream = AddRecvStream();
  webrtc::VideoReceiveStreamInterface::Stats stats;
  stats.rtp_stats.packet_counter.payload_bytes = 2;
  stats.rtp_stats.packet_counter.header_bytes = 3;
  stats.rtp_stats.packet_counter.padding_bytes = 4;
  stats.rtp_stats.packet_counter.packets = 5;
  stats.rtp_stats.packets_lost = 6;
  stream->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_EQ(stats.rtp_stats.packet_counter.payload_bytes,
            rtc::checked_cast<size_t>(info.receivers[0].payload_bytes_rcvd));
  EXPECT_EQ(stats.rtp_stats.packet_counter.packets,
            rtc::checked_cast<unsigned int>(info.receivers[0].packets_rcvd));
  EXPECT_EQ(stats.rtp_stats.packets_lost, info.receivers[0].packets_lost);
}

TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) {
  AddSendStream();
  AddSendStream();
  webrtc::Call::Stats stats;
  stats.rtt_ms = 123;
  fake_call_->SetStats(stats);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  ASSERT_EQ(2u, info.senders.size());
  EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
  EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
}

TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) {
  FakeVideoSendStream* stream = AddSendStream();
  webrtc::VideoSendStream::Stats stats;
  stats.target_media_bitrate_bps = 156;
  stats.media_bitrate_bps = 123;
  stats.substreams[17].total_bitrate_bps = 1;
  stats.substreams[17].retransmit_bitrate_bps = 2;
  stats.substreams[42].total_bitrate_bps = 3;
  stats.substreams[42].retransmit_bitrate_bps = 4;
  stream->SetStats(stats);

  FakeVideoSendStream* stream2 = AddSendStream();
  webrtc::VideoSendStream::Stats stats2;
  stats2.target_media_bitrate_bps = 200;
  stats2.media_bitrate_bps = 321;
  stats2.substreams[13].total_bitrate_bps = 5;
  stats2.substreams[13].retransmit_bitrate_bps = 6;
  stats2.substreams[21].total_bitrate_bps = 7;
  stats2.substreams[21].retransmit_bitrate_bps = 8;
  stream2->SetStats(stats2);

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));
  ASSERT_EQ(2u, info.aggregated_senders.size());
  ASSERT_EQ(4u, info.senders.size());
  BandwidthEstimationInfo bwe_info;
  channel_->FillBitrateInfo(&bwe_info);
  // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
  // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
  EXPECT_EQ(stats.media_bitrate_bps,
            info.aggregated_senders[0].nominal_bitrate);
  EXPECT_EQ(stats2.media_bitrate_bps,
            info.aggregated_senders[1].nominal_bitrate);
  EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
            bwe_info.target_enc_bitrate);
  EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
            bwe_info.actual_enc_bitrate);
  EXPECT_EQ(1 + 3 + 5 + 7, bwe_info.transmit_bitrate)
      << "Bandwidth stats should take all streams into account.";
  EXPECT_EQ(2 + 4 + 6 + 8, bwe_info.retransmit_bitrate)
      << "Bandwidth stats should take all streams into account.";
}

TEST_F(WebRtcVideoChannelTest, DefaultReceiveStreamReconfiguresToUseRtx) {
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
  const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);

  ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
  RtpPacket packet;
  packet.SetSsrc(ssrcs[0]);
  ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);

  ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
      << "No default receive stream created.";
  FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx_ssrc)
      << "Default receive stream should not have configured RTX";

  EXPECT_TRUE(channel_->AddRecvStream(
      cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
  ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
      << "AddRecvStream should have reconfigured, not added a new receiver.";
  recv_stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_FALSE(
      recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
  EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
      << "RTX should be mapped for all decoders/payload types.";
  EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
                                       GetEngineCodec("red").id))
      << "RTX should be mapped also for the RED payload type";
  EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
}

TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithMissingSsrcsForRtx) {
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
  const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);

  StreamParams sp =
      cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
  sp.ssrcs = ssrcs;  // Without RTXs, this is the important part.

  EXPECT_FALSE(channel_->AddSendStream(sp));
  EXPECT_FALSE(channel_->AddRecvStream(sp));
}

TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
  const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);

  StreamParams sp =
      cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);

  EXPECT_TRUE(channel_->AddSendStream(sp));
  EXPECT_TRUE(channel_->AddRecvStream(sp));

  // The RTX SSRC is already used in previous streams, using it should fail.
  sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
  EXPECT_FALSE(channel_->AddSendStream(sp));
  EXPECT_FALSE(channel_->AddRecvStream(sp));

  // After removing the original stream this should be fine to add (makes sure
  // that RTX ssrcs are not forever taken).
  EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
  EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
  EXPECT_TRUE(channel_->AddSendStream(sp));
  EXPECT_TRUE(channel_->AddRecvStream(sp));
}

TEST_F(WebRtcVideoChannelTest,
       RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
  static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
  static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  StreamParams sp =
      cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));

  EXPECT_TRUE(channel_->AddSendStream(sp));
  EXPECT_TRUE(channel_->AddRecvStream(sp));

  // One of the SSRCs is already used in previous streams, using it should fail.
  sp = cricket::CreateSimStreamParams("cname",
                                      MAKE_VECTOR(kOverlappingStreamSsrcs));
  EXPECT_FALSE(channel_->AddSendStream(sp));
  EXPECT_FALSE(channel_->AddRecvStream(sp));

  // After removing the original stream this should be fine to add (makes sure
  // that RTX ssrcs are not forever taken).
  EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
  EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
  EXPECT_TRUE(channel_->AddSendStream(sp));
  EXPECT_TRUE(channel_->AddRecvStream(sp));
}

TEST_F(WebRtcVideoChannelTest, ReportsSsrcGroupsInStats) {
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  static const uint32_t kSenderSsrcs[] = {4, 7, 10};
  static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};

  StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
      "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));

  EXPECT_TRUE(channel_->AddSendStream(sender_sp));

  static const uint32_t kReceiverSsrcs[] = {3};
  static const uint32_t kReceiverRtxSsrcs[] = {2};

  StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
      "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
  EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));

  cricket::VideoMediaInfo info;
  ASSERT_TRUE(channel_->GetStats(&info));

  ASSERT_EQ(1u, info.senders.size());
  ASSERT_EQ(1u, info.receivers.size());

  EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
  EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
  EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
}

TEST_F(WebRtcVideoChannelTest, MapsReceivedPayloadTypeToCodecName) {
  FakeVideoReceiveStream* stream = AddRecvStream();
  webrtc::VideoReceiveStreamInterface::Stats stats;
  cricket::VideoMediaInfo info;

  // Report no codec name before receiving.
  stream->SetStats(stats);
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_STREQ("", info.receivers[0].codec_name.c_str());

  // Report VP8 if we're receiving it.
  stats.current_payload_type = GetEngineCodec("VP8").id;
  stream->SetStats(stats);
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());

  // Report no codec name for unknown playload types.
  stats.current_payload_type = 3;
  stream->SetStats(stats);
  ASSERT_TRUE(channel_->GetStats(&info));
  EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
}

// Tests that when we add a stream without SSRCs, but contains a stream_id
// that it is stored and its stream id is later used when the first packet
// arrives to properly create a receive stream with a sync label.
TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) {
  const char kSyncLabel[] = "sync_label";
  cricket::StreamParams unsignaled_stream;
  unsignaled_stream.set_stream_ids({kSyncLabel});
  ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
  channel_->OnDemuxerCriteriaUpdatePending();
  channel_->OnDemuxerCriteriaUpdateComplete();
  rtc::Thread::Current()->ProcessMessages(0);
  // The stream shouldn't have been created at this point because it doesn't
  // have any SSRCs.
  EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());

  // Create and deliver packet.
  RtpPacket packet;
  packet.SetSsrc(kIncomingUnsignalledSsrc);
  ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);

  // The stream should now be created with the appropriate sync label.
  EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
  EXPECT_EQ(kSyncLabel,
            fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group);

  // Reset the unsignaled stream to clear the cache. This deletes the receive
  // stream.
  channel_->ResetUnsignaledRecvStream();
  channel_->OnDemuxerCriteriaUpdatePending();
  EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());

  // Until the demuxer criteria has been updated, we ignore in-flight ssrcs of
  // the recently removed unsignaled receive stream.
  ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());

  // After the demuxer criteria has been updated, we should proceed to create
  // unsignalled receive streams. This time when a default video receive stream
  // is created it won't have a sync_group.
  channel_->OnDemuxerCriteriaUpdateComplete();
  ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
  EXPECT_TRUE(
      fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group.empty());
}

TEST_F(WebRtcVideoChannelTest,
       ResetUnsignaledRecvStreamDeletesAllDefaultStreams) {
  // No receive streams to start with.
  EXPECT_TRUE(fake_call_->GetVideoReceiveStreams().empty());

  // Packet with unsignaled SSRC is received.
  RtpPacket packet;
  packet.SetSsrc(kIncomingUnsignalledSsrc);
  ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);

  // Default receive stream created.
  const auto& receivers1 = fake_call_->GetVideoReceiveStreams();
  ASSERT_EQ(receivers1.size(), 1u);
  EXPECT_EQ(receivers1[0]->GetConfig().rtp.remote_ssrc,
            kIncomingUnsignalledSsrc);

  // Stream with another SSRC gets signaled.
  channel_->ResetUnsignaledRecvStream();
  constexpr uint32_t kIncomingSignalledSsrc = kIncomingUnsignalledSsrc + 1;
  ASSERT_TRUE(channel_->AddRecvStream(
      cricket::StreamParams::CreateLegacy(kIncomingSignalledSsrc)));

  // New receiver is for the signaled stream.
  const auto& receivers2 = fake_call_->GetVideoReceiveStreams();
  ASSERT_EQ(receivers2.size(), 1u);
  EXPECT_EQ(receivers2[0]->GetConfig().rtp.remote_ssrc, kIncomingSignalledSsrc);
}

TEST_F(WebRtcVideoChannelTest,
       RecentlyAddedSsrcsDoNotCreateUnsignalledRecvStreams) {
  const uint32_t kSsrc1 = 1;
  const uint32_t kSsrc2 = 2;

  // Starting point: receiving kSsrc1.
  EXPECT_TRUE(channel_->AddRecvStream(StreamParams::CreateLegacy(kSsrc1)));
  channel_->OnDemuxerCriteriaUpdatePending();
  channel_->OnDemuxerCriteriaUpdateComplete();
  rtc::Thread::Current()->ProcessMessages(0);
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);

  // If this is the only m= section the demuxer might be configure to forward
  // all packets, regardless of ssrc, to this channel. When we go to multiple m=
  // sections, there can thus be a window of time where packets that should
  // never have belonged to this channel arrive anyway.

  // Emulate a second m= section being created by updating the demuxer criteria
  // without adding any streams.
  channel_->OnDemuxerCriteriaUpdatePending();

  // Emulate there being in-flight packets for kSsrc1 and kSsrc2 arriving before
  // the demuxer is updated.
  {
    // Receive a packet for kSsrc1.
    RtpPacket packet;
    packet.SetSsrc(kSsrc1);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }
  {
    // Receive a packet for kSsrc2.
    RtpPacket packet;
    packet.SetSsrc(kSsrc2);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }

  // No unsignaled ssrc for kSsrc2 should have been created, but kSsrc1 should
  // arrive since it already has a stream.
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 0u);

  // Signal that the demuxer update is complete. Because there are no more
  // pending demuxer updates, receiving unknown ssrcs (kSsrc2) should again
  // result in unsignalled receive streams being created.
  channel_->OnDemuxerCriteriaUpdateComplete();
  rtc::Thread::Current()->ProcessMessages(0);

  // Receive packets for kSsrc1 and kSsrc2 again.
  {
    // Receive a packet for kSsrc1.
    RtpPacket packet;
    packet.SetSsrc(kSsrc1);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }
  {
    // Receive a packet for kSsrc2.
    RtpPacket packet;
    packet.SetSsrc(kSsrc2);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }

  // An unsignalled ssrc for kSsrc2 should be created and the packet counter
  // should increase for both ssrcs.
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 2u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 2u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 1u);
}

TEST_F(WebRtcVideoChannelTest,
       RecentlyRemovedSsrcsDoNotCreateUnsignalledRecvStreams) {
  const uint32_t kSsrc1 = 1;
  const uint32_t kSsrc2 = 2;

  // Starting point: receiving kSsrc1 and kSsrc2.
  EXPECT_TRUE(channel_->AddRecvStream(StreamParams::CreateLegacy(kSsrc1)));
  EXPECT_TRUE(channel_->AddRecvStream(StreamParams::CreateLegacy(kSsrc2)));
  channel_->OnDemuxerCriteriaUpdatePending();
  channel_->OnDemuxerCriteriaUpdateComplete();
  rtc::Thread::Current()->ProcessMessages(0);
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 2u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 0u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 0u);

  // Remove kSsrc1, signal that a demuxer criteria update is pending, but not
  // completed yet.
  EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
  channel_->OnDemuxerCriteriaUpdatePending();

  // We only have a receiver for kSsrc2 now.
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);

  // Emulate there being in-flight packets for kSsrc1 and kSsrc2 arriving before
  // the demuxer is updated.
  {
    // Receive a packet for kSsrc1.
    RtpPacket packet;
    packet.SetSsrc(kSsrc1);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }
  {
    // Receive a packet for kSsrc2.
    RtpPacket packet;
    packet.SetSsrc(kSsrc2);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }

  // No unsignaled ssrc for kSsrc1 should have been created, but the packet
  // count for kSsrc2 should increase.
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 0u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 1u);

  // Signal that the demuxer update is complete. This means we should stop
  // ignorning kSsrc1.
  channel_->OnDemuxerCriteriaUpdateComplete();
  rtc::Thread::Current()->ProcessMessages(0);

  // Receive packets for kSsrc1 and kSsrc2 again.
  {
    // Receive a packet for kSsrc1.
    RtpPacket packet;
    packet.SetSsrc(kSsrc1);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }
  {
    // Receive a packet for kSsrc2.
    RtpPacket packet;
    packet.SetSsrc(kSsrc2);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }

  // An unsignalled ssrc for kSsrc1 should be created and the packet counter
  // should increase for both ssrcs.
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 2u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 2u);
}

TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) {
  const uint32_t kSsrc = 1;

  // Starting point: receiving kSsrc.
  EXPECT_TRUE(channel_->AddRecvStream(StreamParams::CreateLegacy(kSsrc)));
  channel_->OnDemuxerCriteriaUpdatePending();
  channel_->OnDemuxerCriteriaUpdateComplete();
  rtc::Thread::Current()->ProcessMessages(0);
  ASSERT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);

  // Remove kSsrc...
  EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc));
  channel_->OnDemuxerCriteriaUpdatePending();
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 0u);
  // And then add it back again, before the demuxer knows about the new
  // criteria!
  EXPECT_TRUE(channel_->AddRecvStream(StreamParams::CreateLegacy(kSsrc)));
  channel_->OnDemuxerCriteriaUpdatePending();
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);

  // In-flight packets should arrive because the stream was recreated, even
  // though demuxer criteria updates are pending...
  {
    RtpPacket packet;
    packet.SetSsrc(kSsrc);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 1u);

  // Signal that the demuxer knows about the first update: the removal.
  channel_->OnDemuxerCriteriaUpdateComplete();
  rtc::Thread::Current()->ProcessMessages(0);

  // This still should not prevent in-flight packets from arriving because we
  // have a receive stream for it.
  {
    RtpPacket packet;
    packet.SetSsrc(kSsrc);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 2u);

  // Remove the kSsrc again while previous demuxer updates are still pending.
  EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc));
  channel_->OnDemuxerCriteriaUpdatePending();
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 0u);

  // Now the packet should be dropped and not create an unsignalled receive
  // stream.
  {
    RtpPacket packet;
    packet.SetSsrc(kSsrc);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 0u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 2u);

  // Signal that the demuxer knows about the second update: adding it back.
  channel_->OnDemuxerCriteriaUpdateComplete();
  rtc::Thread::Current()->ProcessMessages(0);

  // The packets should continue to be dropped because removal happened after
  // the most recently completed demuxer update.
  {
    RtpPacket packet;
    packet.SetSsrc(kSsrc);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 0u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 2u);

  // Signal that the demuxer knows about the last update: the second removal.
  channel_->OnDemuxerCriteriaUpdateComplete();
  rtc::Thread::Current()->ProcessMessages(0);

  // If packets still arrive after the demuxer knows about the latest removal we
  // should finally create an unsignalled receive stream.
  {
    RtpPacket packet;
    packet.SetSsrc(kSsrc);
    ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);
  }
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc), 3u);
}

TEST_F(WebRtcVideoChannelTest, UnsignalledSsrcHasACooldown) {
  const uint32_t kSsrc1 = 1;
  const uint32_t kSsrc2 = 2;

  // Send packets for kSsrc1, creating an unsignalled receive stream.
  {
    // Receive a packet for kSsrc1.
    RtpPacket packet;
    packet.SetSsrc(kSsrc1);
    channel_->OnPacketReceived(packet.Buffer(), /* packet_time_us */ -1);
  }
  rtc::Thread::Current()->ProcessMessages(0);
  time_controller_.AdvanceTime(
      webrtc::TimeDelta::Millis(kUnsignalledReceiveStreamCooldownMs - 1));

  // We now have an unsignalled receive stream for kSsrc1.
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 0u);

  {
    // Receive a packet for kSsrc2.
    RtpPacket packet;
    packet.SetSsrc(kSsrc2);
    channel_->OnPacketReceived(packet.Buffer(), /* packet_time_us */ -1);
  }
  rtc::Thread::Current()->ProcessMessages(0);

  // Not enough time has passed to replace the unsignalled receive stream, so
  // the kSsrc2 should be ignored.
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 0u);

  // After 500 ms, kSsrc2 should trigger a new unsignalled receive stream that
  // replaces the old one.
  time_controller_.AdvanceTime(webrtc::TimeDelta::Millis(1));
  {
    // Receive a packet for kSsrc2.
    RtpPacket packet;
    packet.SetSsrc(kSsrc2);
    channel_->OnPacketReceived(packet.Buffer(), /* packet_time_us */ -1);
  }
  rtc::Thread::Current()->ProcessMessages(0);

  // The old unsignalled receive stream was destroyed and replaced, so we still
  // only have one unsignalled receive stream. But tha packet counter for kSsrc2
  // has now increased.
  EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 1u);
  EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 1u);
}

// Test BaseMinimumPlayoutDelayMs on receive streams.
TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMs) {
  // Test that set won't work for non-existing receive streams.
  EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc + 2, 200));
  // Test that get won't work for non-existing receive streams.
  EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrc + 2));

  EXPECT_TRUE(AddRecvStream());
  // Test that set works for the existing receive stream.
  EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(last_ssrc_, 200));
  auto* recv_stream = fake_call_->GetVideoReceiveStream(last_ssrc_);
  EXPECT_TRUE(recv_stream);
  EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
  EXPECT_EQ(channel_->GetBaseMinimumPlayoutDelayMs(last_ssrc_).value_or(0),
            200);
}

// Test BaseMinimumPlayoutDelayMs on unsignaled receive streams.
TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
  absl::optional<int> delay_ms;
  const FakeVideoReceiveStream* recv_stream;

  // Set default stream with SSRC 0
  EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 200));
  EXPECT_EQ(200, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));

  // Spawn an unsignaled stream by sending a packet, it should inherit
  // default delay 200.
  RtpPacket packet;
  packet.SetSsrc(kIncomingUnsignalledSsrc);
  ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);

  recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
  EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
  delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
  EXPECT_EQ(200, delay_ms.value_or(0));

  // Check that now if we change delay for SSRC 0 it will change delay for the
  // default receiving stream as well.
  EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 300));
  EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
  delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
  EXPECT_EQ(300, delay_ms.value_or(0));
  recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
  EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 300);
}

void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket(
    uint8_t payload_type,
    bool expect_created_receive_stream) {
  // kRedRtxPayloadType must currently be unused.
  EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kRedRtxPayloadType));

  // Add a RED RTX codec.
  VideoCodec red_rtx_codec =
      VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
  recv_parameters_.codecs.push_back(red_rtx_codec);
  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));

  ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
  RtpPacket packet;
  packet.SetPayloadType(payload_type);
  packet.SetSsrc(kIncomingUnsignalledSsrc);
  ReceivePacketAndAdvanceTime(packet.Buffer(), /* packet_time_us */ -1);

  if (expect_created_receive_stream) {
    EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
        << "Should have created a receive stream for payload type: "
        << payload_type;
  } else {
    EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
        << "Shouldn't have created a receive stream for payload type: "
        << payload_type;
  }
}

class WebRtcVideoChannelDiscardUnknownSsrcTest : public WebRtcVideoChannelTest {
 public:
  WebRtcVideoChannelDiscardUnknownSsrcTest()
      : WebRtcVideoChannelTest(
            "WebRTC-Video-DiscardPacketsWithUnknownSsrc/Enabled/") {}
};

TEST_F(WebRtcVideoChannelDiscardUnknownSsrcTest, NoUnsignalledStreamCreated) {
  TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
                                  false /* expect_created_receive_stream */);
}

TEST_F(WebRtcVideoChannelTest, Vp8PacketCreatesUnsignalledStream) {
  TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
                                  true /* expect_created_receive_stream */);
}

TEST_F(WebRtcVideoChannelTest, Vp9PacketCreatesUnsignalledStream) {
  TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
                                  true /* expect_created_receive_stream */);
}

TEST_F(WebRtcVideoChannelTest, RtxPacketDoesntCreateUnsignalledStream) {
  AssignDefaultAptRtxTypes();
  const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
  const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
  TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
                                  false /* expect_created_receive_stream */);
}

TEST_F(WebRtcVideoChannelTest, UlpfecPacketDoesntCreateUnsignalledStream) {
  TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
                                  false /* expect_created_receive_stream */);
}

TEST_F(WebRtcVideoChannelFlexfecRecvTest,
       FlexfecPacketDoesntCreateUnsignalledStream) {
  TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
                                  false /* expect_created_receive_stream */);
}

TEST_F(WebRtcVideoChannelTest, RedRtxPacketDoesntCreateUnsignalledStream) {
  TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
                                  false /* expect_created_receive_stream */);
}

// Test that receiving any unsignalled SSRC works even if it changes.
// The first unsignalled SSRC received will create a default receive stream.
// Any different unsignalled SSRC received will replace the default.
TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) {
  // Allow receiving VP8, VP9, H264 (if enabled).
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP9"));

#if defined(WEBRTC_USE_H264)
  cricket::VideoCodec H264codec(126, "H264");
  parameters.codecs.push_back(H264codec);
#endif

  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
  // No receive streams yet.
  ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
  cricket::FakeVideoRenderer renderer;
  channel_->SetDefaultSink(&renderer);

  // Receive VP8 packet on first SSRC.
  RtpPacket rtp_packet;
  rtp_packet.SetPayloadType(GetEngineCodec("VP8").id);
  rtp_packet.SetSsrc(kIncomingUnsignalledSsrc + 1);
  ReceivePacketAndAdvanceTime(rtp_packet.Buffer(), /* packet_time_us */ -1);
  // VP8 packet should create default receive stream.
  ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
  FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_EQ(rtp_packet.Ssrc(), recv_stream->GetConfig().rtp.remote_ssrc);
  // Verify that the receive stream sinks to a renderer.
  webrtc::VideoFrame video_frame =
      webrtc::VideoFrame::Builder()
          .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
          .set_timestamp_rtp(100)
          .set_timestamp_us(0)
          .set_rotation(webrtc::kVideoRotation_0)
          .build();
  recv_stream->InjectFrame(video_frame);
  EXPECT_EQ(1, renderer.num_rendered_frames());

  // Receive VP9 packet on second SSRC.
  rtp_packet.SetPayloadType(GetEngineCodec("VP9").id);
  rtp_packet.SetSsrc(kIncomingUnsignalledSsrc + 2);
  ReceivePacketAndAdvanceTime(rtp_packet.Buffer(), /* packet_time_us */ -1);
  // VP9 packet should replace the default receive SSRC.
  ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
  recv_stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_EQ(rtp_packet.Ssrc(), recv_stream->GetConfig().rtp.remote_ssrc);
  // Verify that the receive stream sinks to a renderer.
  webrtc::VideoFrame video_frame2 =
      webrtc::VideoFrame::Builder()
          .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
          .set_timestamp_rtp(200)
          .set_timestamp_us(0)
          .set_rotation(webrtc::kVideoRotation_0)
          .build();
  recv_stream->InjectFrame(video_frame2);
  EXPECT_EQ(2, renderer.num_rendered_frames());

#if defined(WEBRTC_USE_H264)
  // Receive H264 packet on third SSRC.
  rtp_packet.SetPayloadType(126);
  rtp_packet.SetSsrc(kIncomingUnsignalledSsrc + 3);
  ReceivePacketAndAdvanceTime(rtp_packet.Buffer(), /* packet_time_us */ -1);
  // H264 packet should replace the default receive SSRC.
  ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
  recv_stream = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_EQ(rtp_packet.Ssrc(), recv_stream->GetConfig().rtp.remote_ssrc);
  // Verify that the receive stream sinks to a renderer.
  webrtc::VideoFrame video_frame3 =
      webrtc::VideoFrame::Builder()
          .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
          .set_timestamp_rtp(300)
          .set_timestamp_us(0)
          .set_rotation(webrtc::kVideoRotation_0)
          .build();
  recv_stream->InjectFrame(video_frame3);
  EXPECT_EQ(3, renderer.num_rendered_frames());
#endif
}

// This test verifies that when a new default stream is created for a new
// unsignaled SSRC, the new stream does not overwrite any old stream that had
// been the default receive stream before being properly signaled.
TEST_F(WebRtcVideoChannelTest,
       NewUnsignaledStreamDoesNotDestroyPreviouslyUnsignaledStream) {
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  ASSERT_TRUE(channel_->SetRecvParameters(parameters));

  // No streams signaled and no packets received, so we should not have any
  // stream objects created yet.
  EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());

  // Receive packet on an unsignaled SSRC.
  RtpPacket rtp_packet;
  rtp_packet.SetPayloadType(GetEngineCodec("VP8").id);
  rtp_packet.SetSsrc(kSsrcs3[0]);
  ReceivePacketAndAdvanceTime(rtp_packet.Buffer(), /* packet_time_us */ -1);
  // Default receive stream should be created.
  ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
  FakeVideoReceiveStream* recv_stream0 =
      fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);

  // Signal the SSRC.
  EXPECT_TRUE(
      channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs3[0])));
  ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
  recv_stream0 = fake_call_->GetVideoReceiveStreams()[0];
  EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);

  // Receive packet on a different unsignaled SSRC.
  rtp_packet.SetSsrc(kSsrcs3[1]);
  ReceivePacketAndAdvanceTime(rtp_packet.Buffer(), /* packet_time_us */ -1);
  // New default receive stream should be created, but old stream should remain.
  ASSERT_EQ(2u, fake_call_->GetVideoReceiveStreams().size());
  EXPECT_EQ(recv_stream0, fake_call_->GetVideoReceiveStreams()[0]);
  FakeVideoReceiveStream* recv_stream1 =
      fake_call_->GetVideoReceiveStreams()[1];
  EXPECT_EQ(kSsrcs3[1], recv_stream1->GetConfig().rtp.remote_ssrc);
}

TEST_F(WebRtcVideoChannelTest, CanSetMaxBitrateForExistingStream) {
  AddSendStream();

  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
  EXPECT_TRUE(channel_->SetSend(true));
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  int default_encoder_bitrate = GetMaxEncoderBitrate();
  EXPECT_GT(default_encoder_bitrate, 1000);

  // TODO(skvlad): Resolve the inconsistency between the interpretation
  // of the global bitrate limit for audio and video:
  // - Audio: max_bandwidth_bps = 0 - fail the operation,
  //          max_bandwidth_bps = -1 - remove the bandwidth limit
  // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
  //          max_bandwidth_bps = -1 - remove the bandwidth limit

  SetAndExpectMaxBitrate(1000, 0, 1000);
  SetAndExpectMaxBitrate(1000, 800, 800);
  SetAndExpectMaxBitrate(600, 800, 600);
  SetAndExpectMaxBitrate(0, 800, 800);
  SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest, CannotSetMaxBitrateForNonexistentStream) {
  webrtc::RtpParameters nonexistent_parameters =
      channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(0u, nonexistent_parameters.encodings.size());

  nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
  EXPECT_FALSE(
      channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters).ok());
}

TEST_F(WebRtcVideoChannelTest,
       SetLowMaxBitrateOverwritesVideoStreamMinBitrate) {
  FakeVideoSendStream* stream = AddSendStream();

  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1UL, parameters.encodings.size());
  EXPECT_FALSE(parameters.encodings[0].max_bitrate_bps.has_value());
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Note that this is testing the behavior of the FakeVideoSendStream, which
  // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
  // we are just testing the behavior of
  // EncoderStreamFactory::CreateEncoderStreams.
  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps,
            stream->GetVideoStreams()[0].min_bitrate_bps);

  // Set a low max bitrate & check that VideoStream.min_bitrate_bps is limited
  // by this amount.
  parameters = channel_->GetRtpSendParameters(last_ssrc_);
  int low_max_bitrate_bps = webrtc::kDefaultMinVideoBitrateBps - 1000;
  parameters.encodings[0].max_bitrate_bps = low_max_bitrate_bps;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
}

TEST_F(WebRtcVideoChannelTest,
       SetHighMinBitrateOverwritesVideoStreamMaxBitrate) {
  FakeVideoSendStream* stream = AddSendStream();

  // Note that this is testing the behavior of the FakeVideoSendStream, which
  // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
  // we are just testing the behavior of
  // EncoderStreamFactory::CreateEncoderStreams.
  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  int high_min_bitrate_bps = stream->GetVideoStreams()[0].max_bitrate_bps + 1;

  // Set a high min bitrate and check that max_bitrate_bps is adjusted up.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1UL, parameters.encodings.size());
  parameters.encodings[0].min_bitrate_bps = high_min_bitrate_bps;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
}

TEST_F(WebRtcVideoChannelTest,
       SetMinBitrateAboveMaxBitrateLimitAdjustsMinBitrateDown) {
  send_parameters_.max_bandwidth_bps = 99999;
  FakeVideoSendStream* stream = AddSendStream();
  ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps,
            stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_EQ(send_parameters_.max_bandwidth_bps,
            stream->GetVideoStreams()[0].max_bitrate_bps);

  // Set min bitrate above global max bitrate and check that min_bitrate_bps is
  // adjusted down.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1UL, parameters.encodings.size());
  parameters.encodings[0].min_bitrate_bps = 99999 + 1;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  EXPECT_EQ(send_parameters_.max_bandwidth_bps,
            stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_EQ(send_parameters_.max_bandwidth_bps,
            stream->GetVideoStreams()[0].max_bitrate_bps);
}

TEST_F(WebRtcVideoChannelTest, SetMaxFramerateOneStream) {
  FakeVideoSendStream* stream = AddSendStream();

  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1UL, parameters.encodings.size());
  EXPECT_FALSE(parameters.encodings[0].max_framerate.has_value());
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Note that this is testing the behavior of the FakeVideoSendStream, which
  // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
  // we are just testing the behavior of
  // EncoderStreamFactory::CreateEncoderStreams.
  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  EXPECT_EQ(kDefaultVideoMaxFramerate,
            stream->GetVideoStreams()[0].max_framerate);

  // Set max framerate and check that VideoStream.max_framerate is set.
  const int kNewMaxFramerate = kDefaultVideoMaxFramerate - 1;
  parameters = channel_->GetRtpSendParameters(last_ssrc_);
  parameters.encodings[0].max_framerate = kNewMaxFramerate;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  EXPECT_EQ(kNewMaxFramerate, stream->GetVideoStreams()[0].max_framerate);
}

TEST_F(WebRtcVideoChannelTest, SetNumTemporalLayersForSingleStream) {
  FakeVideoSendStream* stream = AddSendStream();

  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1UL, parameters.encodings.size());
  EXPECT_FALSE(parameters.encodings[0].num_temporal_layers.has_value());
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Note that this is testing the behavior of the FakeVideoSendStream, which
  // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
  // we are just testing the behavior of
  // EncoderStreamFactory::CreateEncoderStreams.
  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  EXPECT_FALSE(stream->GetVideoStreams()[0].num_temporal_layers.has_value());

  // Set temporal layers and check that VideoStream.num_temporal_layers is set.
  parameters = channel_->GetRtpSendParameters(last_ssrc_);
  parameters.encodings[0].num_temporal_layers = 2;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  ASSERT_EQ(1UL, stream->GetVideoStreams().size());
  EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
}

TEST_F(WebRtcVideoChannelTest,
       CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
  AddSendStream();
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  // Two or more encodings should result in failure.
  parameters.encodings.push_back(webrtc::RtpEncodingParameters());
  EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  // Zero encodings should also fail.
  parameters.encodings.clear();
  EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
}

TEST_F(WebRtcVideoChannelTest,
       CannotSetSimulcastRtpSendParametersWithIncorrectNumberOfEncodings) {
  std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
  StreamParams sp = CreateSimStreamParams("cname", ssrcs);
  AddSendStream(sp);

  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);

  // Additional encodings should result in failure.
  parameters.encodings.push_back(webrtc::RtpEncodingParameters());
  EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  // Zero encodings should also fail.
  parameters.encodings.clear();
  EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
}

// Changing the SSRC through RtpParameters is not allowed.
TEST_F(WebRtcVideoChannelTest, CannotSetSsrcInRtpSendParameters) {
  AddSendStream();
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  parameters.encodings[0].ssrc = 0xdeadbeef;
  EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
}

// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
// a value <= 0, setting the parameters returns false.
TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidBitratePriority) {
  AddSendStream();
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1UL, parameters.encodings.size());
  EXPECT_EQ(webrtc::kDefaultBitratePriority,
            parameters.encodings[0].bitrate_priority);

  parameters.encodings[0].bitrate_priority = 0;
  EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  parameters.encodings[0].bitrate_priority = -2;
  EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
}

// Tests when the the RTCRtpEncodingParameters.bitrate_priority gets set
// properly on the VideoChannel and propogates down to the video encoder.
TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPriorityOneStream) {
  AddSendStream();
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1UL, parameters.encodings.size());
  EXPECT_EQ(webrtc::kDefaultBitratePriority,
            parameters.encodings[0].bitrate_priority);

  // Change the value and set it on the VideoChannel.
  double new_bitrate_priority = 2.0;
  parameters.encodings[0].bitrate_priority = new_bitrate_priority;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that the encoding parameters bitrate_priority is set for the
  // VideoChannel.
  parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1UL, parameters.encodings.size());
  EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);

  // Verify that the new value propagated down to the encoder.
  std::vector<FakeVideoSendStream*> video_send_streams =
      fake_call_->GetVideoSendStreams();
  EXPECT_EQ(1UL, video_send_streams.size());
  FakeVideoSendStream* video_send_stream = video_send_streams.front();
  // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
  // appropriately.
  EXPECT_EQ(new_bitrate_priority,
            video_send_stream->GetEncoderConfig().bitrate_priority);
  // Check that the vector of VideoStreams also was propagated correctly. Note
  // that this is testing the behavior of the FakeVideoSendStream, which mimics
  // the calls to CreateEncoderStreams to get the VideoStreams.
  EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
            video_send_stream->GetVideoStreams()[0].bitrate_priority);
}

// Tests that the RTCRtpEncodingParameters.bitrate_priority is set for the
// VideoChannel and the value propogates to the video encoder with all simulcast
// streams.
TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPrioritySimulcastStreams) {
  // Create the stream params with multiple ssrcs for simulcast.
  const size_t kNumSimulcastStreams = 3;
  std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
  StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
  AddSendStream(stream_params);
  uint32_t primary_ssrc = stream_params.first_ssrc();

  // Using the FrameForwarder, we manually send a full size
  // frame. This creates multiple VideoStreams for all simulcast layers when
  // reconfiguring, and allows us to test this behavior.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
      1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
      rtc::kNumMicrosecsPerSec / 30));

  // Get and set the rtp encoding parameters.
  webrtc::RtpParameters parameters =
      channel_->GetRtpSendParameters(primary_ssrc);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  EXPECT_EQ(webrtc::kDefaultBitratePriority,
            parameters.encodings[0].bitrate_priority);
  // Change the value and set it on the VideoChannel.
  double new_bitrate_priority = 2.0;
  parameters.encodings[0].bitrate_priority = new_bitrate_priority;
  EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());

  // Verify that the encoding parameters priority is set on the VideoChannel.
  parameters = channel_->GetRtpSendParameters(primary_ssrc);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);

  // Verify that the new value propagated down to the encoder.
  std::vector<FakeVideoSendStream*> video_send_streams =
      fake_call_->GetVideoSendStreams();
  EXPECT_EQ(1UL, video_send_streams.size());
  FakeVideoSendStream* video_send_stream = video_send_streams.front();
  // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
  // appropriately.
  EXPECT_EQ(kNumSimulcastStreams,
            video_send_stream->GetEncoderConfig().number_of_streams);
  EXPECT_EQ(new_bitrate_priority,
            video_send_stream->GetEncoderConfig().bitrate_priority);
  // Check that the vector of VideoStreams also propagated correctly. The
  // FakeVideoSendStream calls CreateEncoderStreams, and we are testing that
  // these are created appropriately for the simulcast case.
  EXPECT_EQ(kNumSimulcastStreams, video_send_stream->GetVideoStreams().size());
  EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
            video_send_stream->GetVideoStreams()[0].bitrate_priority);
  // Since we are only setting bitrate priority per-sender, the other
  // VideoStreams should have a bitrate priority of 0.
  EXPECT_EQ(absl::nullopt,
            video_send_stream->GetVideoStreams()[1].bitrate_priority);
  EXPECT_EQ(absl::nullopt,
            video_send_stream->GetVideoStreams()[2].bitrate_priority);
  EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       GetAndSetRtpSendParametersScaleResolutionDownByVP8) {
  VideoSendParameters parameters;
  parameters.codecs.push_back(VideoCodec(kVp8CodecName));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  webrtc::test::FrameForwarder frame_forwarder;
  FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);

  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);

  // Try layers in natural order (smallest to largest).
  {
    auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
    ASSERT_EQ(3u, rtp_parameters.encodings.size());
    rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
    rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
    rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
    auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
    ASSERT_TRUE(result.ok());

    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
    ASSERT_EQ(3u, video_streams.size());
    EXPECT_EQ(320u, video_streams[0].width);
    EXPECT_EQ(180u, video_streams[0].height);
    EXPECT_EQ(640u, video_streams[1].width);
    EXPECT_EQ(360u, video_streams[1].height);
    EXPECT_EQ(1280u, video_streams[2].width);
    EXPECT_EQ(720u, video_streams[2].height);
  }

  // Try layers in reverse natural order (largest to smallest).
  {
    auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
    ASSERT_EQ(3u, rtp_parameters.encodings.size());
    rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
    rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
    rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
    auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
    ASSERT_TRUE(result.ok());

    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
    ASSERT_EQ(3u, video_streams.size());
    EXPECT_EQ(1280u, video_streams[0].width);
    EXPECT_EQ(720u, video_streams[0].height);
    EXPECT_EQ(640u, video_streams[1].width);
    EXPECT_EQ(360u, video_streams[1].height);
    EXPECT_EQ(320u, video_streams[2].width);
    EXPECT_EQ(180u, video_streams[2].height);
  }

  // Try layers in mixed order.
  {
    auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
    ASSERT_EQ(3u, rtp_parameters.encodings.size());
    rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
    rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
    rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
    auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
    ASSERT_TRUE(result.ok());

    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
    ASSERT_EQ(3u, video_streams.size());
    EXPECT_EQ(128u, video_streams[0].width);
    EXPECT_EQ(72u, video_streams[0].height);
    EXPECT_EQ(640u, video_streams[1].width);
    EXPECT_EQ(360u, video_streams[1].height);
    EXPECT_EQ(320u, video_streams[2].width);
    EXPECT_EQ(180u, video_streams[2].height);
  }

  // Try with a missing scale setting, defaults to 1.0 if any other is set.
  {
    auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
    ASSERT_EQ(3u, rtp_parameters.encodings.size());
    rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
    rtp_parameters.encodings[1].scale_resolution_down_by.reset();
    rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
    auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
    ASSERT_TRUE(result.ok());

    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
    ASSERT_EQ(3u, video_streams.size());
    EXPECT_EQ(1280u, video_streams[0].width);
    EXPECT_EQ(720u, video_streams[0].height);
    EXPECT_EQ(1280u, video_streams[1].width);
    EXPECT_EQ(720u, video_streams[1].height);
    EXPECT_EQ(320u, video_streams[2].width);
    EXPECT_EQ(180u, video_streams[2].height);
  }

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       GetAndSetRtpSendParametersScaleResolutionDownByVP8WithOddResolution) {
  // Ensure that the top layer has width and height divisible by 2^3,
  // so that the bottom layer has width and height divisible by 2.
  // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
  // the number of simulcast layers set by the app.
  webrtc::test::ScopedKeyValueConfig field_trial(
      field_trials_, "WebRTC-NormalizeSimulcastResolution/Enabled-3/");

  // Set up WebRtcVideoChannel for 3-layer VP8 simulcast.
  VideoSendParameters parameters;
  parameters.codecs.push_back(VideoCodec(kVp8CodecName));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);
  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
                                     &frame_forwarder));
  channel_->SetSend(true);

  // Set `scale_resolution_down_by`'s.
  auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
  ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
  rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
  rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
  rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
  const auto result =
      channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
  ASSERT_TRUE(result.ok());

  // Use a capture resolution whose width and height are not divisible by 2^3.
  // (See field trial set at the top of the test.)
  FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

  // Ensure the scaling is correct.
  const auto video_streams = stream->GetVideoStreams();
  ASSERT_EQ(video_streams.size(), 3u);
  // Ensure that we round the capture resolution down for the top layer...
  EXPECT_EQ(video_streams[0].width, 2000u);
  EXPECT_EQ(video_streams[0].height, 1200u);
  EXPECT_EQ(video_streams[1].width, 1000u);
  EXPECT_EQ(video_streams[1].height, 600u);
  // ...and that the bottom layer has a width/height divisible by 2.
  EXPECT_EQ(video_streams[2].width, 500u);
  EXPECT_EQ(video_streams[2].height, 300u);

  // Tear down.
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       GetAndSetRtpSendParametersScaleResolutionDownByH264) {
  encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
  VideoSendParameters parameters;
  parameters.codecs.push_back(VideoCodec(kH264CodecName));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  webrtc::test::FrameForwarder frame_forwarder;
  FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);

  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);

  // Try layers in natural order (smallest to largest).
  {
    auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
    ASSERT_EQ(3u, rtp_parameters.encodings.size());
    rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
    rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
    rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
    auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
    ASSERT_TRUE(result.ok());

    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
    ASSERT_EQ(3u, video_streams.size());
    EXPECT_EQ(320u, video_streams[0].width);
    EXPECT_EQ(180u, video_streams[0].height);
    EXPECT_EQ(640u, video_streams[1].width);
    EXPECT_EQ(360u, video_streams[1].height);
    EXPECT_EQ(1280u, video_streams[2].width);
    EXPECT_EQ(720u, video_streams[2].height);
  }

  // Try layers in reverse natural order (largest to smallest).
  {
    auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
    ASSERT_EQ(3u, rtp_parameters.encodings.size());
    rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
    rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
    rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
    auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
    ASSERT_TRUE(result.ok());

    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
    ASSERT_EQ(3u, video_streams.size());
    EXPECT_EQ(1280u, video_streams[0].width);
    EXPECT_EQ(720u, video_streams[0].height);
    EXPECT_EQ(640u, video_streams[1].width);
    EXPECT_EQ(360u, video_streams[1].height);
    EXPECT_EQ(320u, video_streams[2].width);
    EXPECT_EQ(180u, video_streams[2].height);
  }

  // Try layers in mixed order.
  {
    auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
    ASSERT_EQ(3u, rtp_parameters.encodings.size());
    rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
    rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
    rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
    auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
    ASSERT_TRUE(result.ok());

    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
    ASSERT_EQ(3u, video_streams.size());
    EXPECT_EQ(128u, video_streams[0].width);
    EXPECT_EQ(72u, video_streams[0].height);
    EXPECT_EQ(640u, video_streams[1].width);
    EXPECT_EQ(360u, video_streams[1].height);
    EXPECT_EQ(320u, video_streams[2].width);
    EXPECT_EQ(180u, video_streams[2].height);
  }

  // Try with a missing scale setting, defaults to 1.0 if any other is set.
  {
    auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
    ASSERT_EQ(3u, rtp_parameters.encodings.size());
    rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
    rtp_parameters.encodings[1].scale_resolution_down_by.reset();
    rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
    auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
    ASSERT_TRUE(result.ok());

    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
    ASSERT_EQ(3u, video_streams.size());
    EXPECT_EQ(1280u, video_streams[0].width);
    EXPECT_EQ(720u, video_streams[0].height);
    EXPECT_EQ(1280u, video_streams[1].width);
    EXPECT_EQ(720u, video_streams[1].height);
    EXPECT_EQ(320u, video_streams[2].width);
    EXPECT_EQ(180u, video_streams[2].height);
  }
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       GetAndSetRtpSendParametersScaleResolutionDownByH264WithOddResolution) {
  // Ensure that the top layer has width and height divisible by 2^3,
  // so that the bottom layer has width and height divisible by 2.
  // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
  // the number of simulcast layers set by the app.
  webrtc::test::ScopedKeyValueConfig field_trial(
      field_trials_, "WebRTC-NormalizeSimulcastResolution/Enabled-3/");

  // Set up WebRtcVideoChannel for 3-layer H264 simulcast.
  encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
  VideoSendParameters parameters;
  parameters.codecs.push_back(VideoCodec(kH264CodecName));
  ASSERT_TRUE(channel_->SetSendParameters(parameters));
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);
  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
                                     &frame_forwarder));
  channel_->SetSend(true);

  // Set `scale_resolution_down_by`'s.
  auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
  ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
  rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
  rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
  rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
  const auto result =
      channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
  ASSERT_TRUE(result.ok());

  // Use a capture resolution whose width and height are not divisible by 2^3.
  // (See field trial set at the top of the test.)
  FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
  frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

  // Ensure the scaling is correct.
  const auto video_streams = stream->GetVideoStreams();
  ASSERT_EQ(video_streams.size(), 3u);
  // Ensure that we round the capture resolution down for the top layer...
  EXPECT_EQ(video_streams[0].width, 2000u);
  EXPECT_EQ(video_streams[0].height, 1200u);
  EXPECT_EQ(video_streams[1].width, 1000u);
  EXPECT_EQ(video_streams[1].height, 600u);
  // ...and that the bottom layer has a width/height divisible by 2.
  EXPECT_EQ(video_streams[2].width, 500u);
  EXPECT_EQ(video_streams[2].height, 300u);

  // Tear down.
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMaxFramerate) {
  const size_t kNumSimulcastStreams = 3;
  SetUpSimulcast(true, false);

  // Get and set the rtp encoding parameters.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  for (const auto& encoding : parameters.encodings) {
    EXPECT_FALSE(encoding.max_framerate);
  }

  // Change the value and set it on the VideoChannel.
  parameters.encodings[0].max_framerate = 10;
  parameters.encodings[1].max_framerate = 20;
  parameters.encodings[2].max_framerate = 25;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that the bitrates are set on the VideoChannel.
  parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  EXPECT_EQ(10, parameters.encodings[0].max_framerate);
  EXPECT_EQ(20, parameters.encodings[1].max_framerate);
  EXPECT_EQ(25, parameters.encodings[2].max_framerate);
}

TEST_F(WebRtcVideoChannelTest,
       SetRtpSendParametersNumTemporalLayersFailsForInvalidRange) {
  const size_t kNumSimulcastStreams = 3;
  SetUpSimulcast(true, false);

  // Get and set the rtp encoding parameters.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());

  // Num temporal layers should be in the range [1, kMaxTemporalStreams].
  parameters.encodings[0].num_temporal_layers = 0;
  EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
            channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
  parameters.encodings[0].num_temporal_layers = webrtc::kMaxTemporalStreams + 1;
  EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
            channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
}

TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersNumTemporalLayers) {
  const size_t kNumSimulcastStreams = 3;
  SetUpSimulcast(true, false);

  // Get and set the rtp encoding parameters.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  for (const auto& encoding : parameters.encodings)
    EXPECT_FALSE(encoding.num_temporal_layers);

  // Change the value and set it on the VideoChannel.
  parameters.encodings[0].num_temporal_layers = 3;
  parameters.encodings[1].num_temporal_layers = 3;
  parameters.encodings[2].num_temporal_layers = 3;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that the number of temporal layers are set on the VideoChannel.
  parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  EXPECT_EQ(3, parameters.encodings[0].num_temporal_layers);
  EXPECT_EQ(3, parameters.encodings[1].num_temporal_layers);
  EXPECT_EQ(3, parameters.encodings[2].num_temporal_layers);
}

TEST_F(WebRtcVideoChannelTest, NumTemporalLayersPropagatedToEncoder) {
  const size_t kNumSimulcastStreams = 3;
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  // Send a full size frame so all simulcast layers are used when reconfiguring.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  // Get and set the rtp encoding parameters.
  // Change the value and set it on the VideoChannel.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  parameters.encodings[0].num_temporal_layers = 3;
  parameters.encodings[1].num_temporal_layers = 2;
  parameters.encodings[2].num_temporal_layers = 1;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that the new value is propagated down to the encoder.
  // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
  EXPECT_EQ(2, stream->num_encoder_reconfigurations());
  webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
  EXPECT_EQ(3UL, encoder_config.simulcast_layers[0].num_temporal_layers);
  EXPECT_EQ(2UL, encoder_config.simulcast_layers[1].num_temporal_layers);
  EXPECT_EQ(1UL, encoder_config.simulcast_layers[2].num_temporal_layers);

  // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
  // VideoStreams are created appropriately for the simulcast case.
  EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
  EXPECT_EQ(3UL, stream->GetVideoStreams()[0].num_temporal_layers);
  EXPECT_EQ(2UL, stream->GetVideoStreams()[1].num_temporal_layers);
  EXPECT_EQ(1UL, stream->GetVideoStreams()[2].num_temporal_layers);

  // No parameter changed, encoder should not be reconfigured.
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  EXPECT_EQ(2, stream->num_encoder_reconfigurations());

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       DefaultValuePropagatedToEncoderForUnsetNumTemporalLayers) {
  const size_t kDefaultNumTemporalLayers = 3;
  const size_t kNumSimulcastStreams = 3;
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  // Send a full size frame so all simulcast layers are used when reconfiguring.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  // Change rtp encoding parameters.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  parameters.encodings[0].num_temporal_layers = 2;
  parameters.encodings[2].num_temporal_layers = 1;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that no value is propagated down to the encoder.
  webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
  EXPECT_EQ(2UL, encoder_config.simulcast_layers[0].num_temporal_layers);
  EXPECT_FALSE(encoder_config.simulcast_layers[1].num_temporal_layers);
  EXPECT_EQ(1UL, encoder_config.simulcast_layers[2].num_temporal_layers);

  // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
  // VideoStreams are created appropriately for the simulcast case.
  EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
  EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
  EXPECT_EQ(kDefaultNumTemporalLayers,
            stream->GetVideoStreams()[1].num_temporal_layers);
  EXPECT_EQ(1UL, stream->GetVideoStreams()[2].num_temporal_layers);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       DefaultValuePropagatedToEncoderForUnsetFramerate) {
  const size_t kNumSimulcastStreams = 3;
  const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  // Send a full size frame so all simulcast layers are used when reconfiguring.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  // Get and set the rtp encoding parameters.
  // Change the value and set it on the VideoChannel.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  parameters.encodings[0].max_framerate = 15;
  parameters.encodings[2].max_framerate = 20;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that the new value propagated down to the encoder.
  // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
  webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
  EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
  EXPECT_EQ(-1, encoder_config.simulcast_layers[1].max_framerate);
  EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);

  // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
  // VideoStreams are created appropriately for the simulcast case.
  // The maximum `max_framerate` is used, kDefaultVideoMaxFramerate: 60.
  EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
  EXPECT_EQ(15, stream->GetVideoStreams()[0].max_framerate);
  EXPECT_EQ(kDefaultVideoMaxFramerate,
            stream->GetVideoStreams()[1].max_framerate);
  EXPECT_EQ(20, stream->GetVideoStreams()[2].max_framerate);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMinAndMaxBitrate) {
  const size_t kNumSimulcastStreams = 3;
  SetUpSimulcast(true, false);

  // Get and set the rtp encoding parameters.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  for (const auto& encoding : parameters.encodings) {
    EXPECT_FALSE(encoding.min_bitrate_bps);
    EXPECT_FALSE(encoding.max_bitrate_bps);
  }

  // Change the value and set it on the VideoChannel.
  parameters.encodings[0].min_bitrate_bps = 100000;
  parameters.encodings[0].max_bitrate_bps = 200000;
  parameters.encodings[1].min_bitrate_bps = 300000;
  parameters.encodings[1].max_bitrate_bps = 400000;
  parameters.encodings[2].min_bitrate_bps = 500000;
  parameters.encodings[2].max_bitrate_bps = 600000;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that the bitrates are set on the VideoChannel.
  parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  EXPECT_EQ(100000, parameters.encodings[0].min_bitrate_bps);
  EXPECT_EQ(200000, parameters.encodings[0].max_bitrate_bps);
  EXPECT_EQ(300000, parameters.encodings[1].min_bitrate_bps);
  EXPECT_EQ(400000, parameters.encodings[1].max_bitrate_bps);
  EXPECT_EQ(500000, parameters.encodings[2].min_bitrate_bps);
  EXPECT_EQ(600000, parameters.encodings[2].max_bitrate_bps);
}

TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersFailsWithIncorrectBitrate) {
  const size_t kNumSimulcastStreams = 3;
  SetUpSimulcast(true, false);

  // Get and set the rtp encoding parameters.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());

  // Max bitrate lower than min bitrate should fail.
  parameters.encodings[2].min_bitrate_bps = 100000;
  parameters.encodings[2].max_bitrate_bps = 100000 - 1;
  EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
            channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
}

// Test that min and max bitrate values set via RtpParameters are correctly
// propagated to the underlying encoder, and that the target is set to 3/4 of
// the maximum (3/4 was chosen because it's similar to the simulcast defaults
// that are used if no min/max are specified).
TEST_F(WebRtcVideoChannelTest, MinAndMaxSimulcastBitratePropagatedToEncoder) {
  const size_t kNumSimulcastStreams = 3;
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  // Send a full size frame so all simulcast layers are used when reconfiguring.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  // Get and set the rtp encoding parameters.
  // Change the value and set it on the VideoChannel.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  parameters.encodings[0].min_bitrate_bps = 100000;
  parameters.encodings[0].max_bitrate_bps = 200000;
  parameters.encodings[1].min_bitrate_bps = 300000;
  parameters.encodings[1].max_bitrate_bps = 400000;
  parameters.encodings[2].min_bitrate_bps = 500000;
  parameters.encodings[2].max_bitrate_bps = 600000;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that the new value propagated down to the encoder.
  // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
  EXPECT_EQ(2, stream->num_encoder_reconfigurations());
  webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
  EXPECT_EQ(100000, encoder_config.simulcast_layers[0].min_bitrate_bps);
  EXPECT_EQ(200000, encoder_config.simulcast_layers[0].max_bitrate_bps);
  EXPECT_EQ(300000, encoder_config.simulcast_layers[1].min_bitrate_bps);
  EXPECT_EQ(400000, encoder_config.simulcast_layers[1].max_bitrate_bps);
  EXPECT_EQ(500000, encoder_config.simulcast_layers[2].min_bitrate_bps);
  EXPECT_EQ(600000, encoder_config.simulcast_layers[2].max_bitrate_bps);

  // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
  // VideoStreams are created appropriately for the simulcast case.
  EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
  // Target bitrate: 200000 * 3 / 4 = 150000.
  EXPECT_EQ(100000, stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
  EXPECT_EQ(200000, stream->GetVideoStreams()[0].max_bitrate_bps);
  // Target bitrate: 400000 * 3 / 4 = 300000.
  EXPECT_EQ(300000, stream->GetVideoStreams()[1].min_bitrate_bps);
  EXPECT_EQ(300000, stream->GetVideoStreams()[1].target_bitrate_bps);
  EXPECT_EQ(400000, stream->GetVideoStreams()[1].max_bitrate_bps);
  // Target bitrate: 600000 * 3 / 4 = 450000, less than min -> max.
  EXPECT_EQ(500000, stream->GetVideoStreams()[2].min_bitrate_bps);
  EXPECT_EQ(600000, stream->GetVideoStreams()[2].target_bitrate_bps);
  EXPECT_EQ(600000, stream->GetVideoStreams()[2].max_bitrate_bps);

  // No parameter changed, encoder should not be reconfigured.
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  EXPECT_EQ(2, stream->num_encoder_reconfigurations());

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

// Test to only specify the min or max bitrate value for a layer via
// RtpParameters. The unspecified min/max and target value should be set to the
// simulcast default that is used if no min/max are specified.
TEST_F(WebRtcVideoChannelTest, MinOrMaxSimulcastBitratePropagatedToEncoder) {
  const size_t kNumSimulcastStreams = 3;
  const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  // Send a full size frame so all simulcast layers are used when reconfiguring.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  // Get and set the rtp encoding parameters.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());

  // Change the value and set it on the VideoChannel.
  // Layer 0: only configure min bitrate.
  const int kMinBpsLayer0 = kDefault[0].min_bitrate_bps + 1;
  parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
  // Layer 1: only configure max bitrate.
  const int kMaxBpsLayer1 = kDefault[1].max_bitrate_bps - 1;
  parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that the new value propagated down to the encoder.
  // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
  webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
  EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
  EXPECT_EQ(kMinBpsLayer0, encoder_config.simulcast_layers[0].min_bitrate_bps);
  EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
  EXPECT_EQ(-1, encoder_config.simulcast_layers[1].min_bitrate_bps);
  EXPECT_EQ(kMaxBpsLayer1, encoder_config.simulcast_layers[1].max_bitrate_bps);
  EXPECT_EQ(-1, encoder_config.simulcast_layers[2].min_bitrate_bps);
  EXPECT_EQ(-1, encoder_config.simulcast_layers[2].max_bitrate_bps);

  // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
  // VideoStreams are created appropriately for the simulcast case.
  EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
  // Layer 0: min configured bitrate should overwrite min default.
  EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_EQ(kDefault[0].target_bitrate_bps,
            stream->GetVideoStreams()[0].target_bitrate_bps);
  EXPECT_EQ(kDefault[0].max_bitrate_bps,
            stream->GetVideoStreams()[0].max_bitrate_bps);
  // Layer 1: max configured bitrate should overwrite max default.
  // And target bitrate should be 3/4 * max bitrate or default target
  // which is larger.
  EXPECT_EQ(kDefault[1].min_bitrate_bps,
            stream->GetVideoStreams()[1].min_bitrate_bps);
  const int kTargetBpsLayer1 =
      std::max(kDefault[1].target_bitrate_bps, kMaxBpsLayer1 * 3 / 4);
  EXPECT_EQ(kTargetBpsLayer1, stream->GetVideoStreams()[1].target_bitrate_bps);
  EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
  // Layer 2: min and max bitrate not configured, default expected.
  EXPECT_EQ(kDefault[2].min_bitrate_bps,
            stream->GetVideoStreams()[2].min_bitrate_bps);
  EXPECT_EQ(kDefault[2].target_bitrate_bps,
            stream->GetVideoStreams()[2].target_bitrate_bps);
  EXPECT_EQ(kDefault[2].max_bitrate_bps,
            stream->GetVideoStreams()[2].max_bitrate_bps);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

// Test that specifying the min (or max) bitrate value for a layer via
// RtpParameters above (or below) the simulcast default max (or min) adjusts the
// unspecified values accordingly.
TEST_F(WebRtcVideoChannelTest, SetMinAndMaxSimulcastBitrateAboveBelowDefault) {
  const size_t kNumSimulcastStreams = 3;
  const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  // Send a full size frame so all simulcast layers are used when reconfiguring.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  // Get and set the rtp encoding parameters.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());

  // Change the value and set it on the VideoChannel.
  // For layer 0, set the min bitrate above the default max.
  const int kMinBpsLayer0 = kDefault[0].max_bitrate_bps + 1;
  parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
  // For layer 1, set the max bitrate below the default min.
  const int kMaxBpsLayer1 = kDefault[1].min_bitrate_bps - 1;
  parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Verify that the new value propagated down to the encoder.
  // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
  // VideoStreams are created appropriately for the simulcast case.
  EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
  // Layer 0: Min bitrate above default max (target/max should be adjusted).
  EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].target_bitrate_bps);
  EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].max_bitrate_bps);
  // Layer 1: Max bitrate below default min (min/target should be adjusted).
  EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].min_bitrate_bps);
  EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].target_bitrate_bps);
  EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
  // Layer 2: min and max bitrate not configured, default expected.
  EXPECT_EQ(kDefault[2].min_bitrate_bps,
            stream->GetVideoStreams()[2].min_bitrate_bps);
  EXPECT_EQ(kDefault[2].target_bitrate_bps,
            stream->GetVideoStreams()[2].target_bitrate_bps);
  EXPECT_EQ(kDefault[2].max_bitrate_bps,
            stream->GetVideoStreams()[2].max_bitrate_bps);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest, BandwidthAboveTotalMaxBitrateGivenToMaxLayer) {
  const size_t kNumSimulcastStreams = 3;
  const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  // Send a full size frame so all simulcast layers are used when reconfiguring.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  // Set max bitrate for all but the highest layer.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  parameters.encodings[0].max_bitrate_bps = kDefault[0].max_bitrate_bps;
  parameters.encodings[1].max_bitrate_bps = kDefault[1].max_bitrate_bps;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Set max bandwidth equal to total max bitrate.
  send_parameters_.max_bandwidth_bps =
      GetTotalMaxBitrate(stream->GetVideoStreams()).bps();
  ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));

  // No bitrate above the total max to give to the highest layer.
  EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
  EXPECT_EQ(kDefault[2].max_bitrate_bps,
            stream->GetVideoStreams()[2].max_bitrate_bps);

  // Set max bandwidth above the total max bitrate.
  send_parameters_.max_bandwidth_bps =
      GetTotalMaxBitrate(stream->GetVideoStreams()).bps() + 1;
  ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));

  // The highest layer has no max bitrate set -> the bitrate above the total
  // max should be given to the highest layer.
  EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
  EXPECT_EQ(send_parameters_.max_bandwidth_bps,
            GetTotalMaxBitrate(stream->GetVideoStreams()).bps());
  EXPECT_EQ(kDefault[2].max_bitrate_bps + 1,
            stream->GetVideoStreams()[2].max_bitrate_bps);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       BandwidthAboveTotalMaxBitrateNotGivenToMaxLayerIfMaxBitrateSet) {
  const size_t kNumSimulcastStreams = 3;
  const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
  EXPECT_EQ(kNumSimulcastStreams, kDefault.size());
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  // Send a full size frame so all simulcast layers are used when reconfiguring.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());

  // Set max bitrate for the highest layer.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  parameters.encodings[2].max_bitrate_bps = kDefault[2].max_bitrate_bps;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Set max bandwidth above the total max bitrate.
  send_parameters_.max_bandwidth_bps =
      GetTotalMaxBitrate(stream->GetVideoStreams()).bps() + 1;
  ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
  ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));

  // The highest layer has the max bitrate set -> the bitrate above the total
  // max should not be given to the highest layer.
  EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
  EXPECT_EQ(*parameters.encodings[2].max_bitrate_bps,
            stream->GetVideoStreams()[2].max_bitrate_bps);

  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

// Test that min and max bitrate values set via RtpParameters are correctly
// propagated to the underlying encoder for a single stream.
TEST_F(WebRtcVideoChannelTest, MinAndMaxBitratePropagatedToEncoder) {
  FakeVideoSendStream* stream = AddSendStream();
  EXPECT_TRUE(channel_->SetSend(true));
  EXPECT_TRUE(stream->IsSending());

  // Set min and max bitrate.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(1u, parameters.encodings.size());
  parameters.encodings[0].min_bitrate_bps = 80000;
  parameters.encodings[0].max_bitrate_bps = 150000;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());

  // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
  webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
  EXPECT_EQ(1u, encoder_config.number_of_streams);
  EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
  EXPECT_EQ(80000, encoder_config.simulcast_layers[0].min_bitrate_bps);
  EXPECT_EQ(150000, encoder_config.simulcast_layers[0].max_bitrate_bps);

  // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
  // VideoStreams are created appropriately.
  EXPECT_EQ(1u, stream->GetVideoStreams().size());
  EXPECT_EQ(80000, stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
  EXPECT_EQ(150000, stream->GetVideoStreams()[0].max_bitrate_bps);
}

// Test the default min and max bitrate value are correctly propagated to the
// underlying encoder for a single stream (when the values are not set via
// RtpParameters).
TEST_F(WebRtcVideoChannelTest, DefaultMinAndMaxBitratePropagatedToEncoder) {
  FakeVideoSendStream* stream = AddSendStream();
  EXPECT_TRUE(channel_->SetSend(true));
  EXPECT_TRUE(stream->IsSending());

  // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
  webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
  EXPECT_EQ(1u, encoder_config.number_of_streams);
  EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
  EXPECT_EQ(-1, encoder_config.simulcast_layers[0].min_bitrate_bps);
  EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);

  // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
  // VideoStreams are created appropriately.
  EXPECT_EQ(1u, stream->GetVideoStreams().size());
  EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps,
            stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_GT(stream->GetVideoStreams()[0].max_bitrate_bps,
            stream->GetVideoStreams()[0].min_bitrate_bps);
  EXPECT_EQ(stream->GetVideoStreams()[0].max_bitrate_bps,
            stream->GetVideoStreams()[0].target_bitrate_bps);
}

// Test that a stream will not be sending if its encoding is made inactive
// through SetRtpSendParameters.
TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersOneEncodingActive) {
  FakeVideoSendStream* stream = AddSendStream();
  EXPECT_TRUE(channel_->SetSend(true));
  EXPECT_TRUE(stream->IsSending());

  // Get current parameters and change "active" to false.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  ASSERT_EQ(1u, parameters.encodings.size());
  ASSERT_TRUE(parameters.encodings[0].active);
  parameters.encodings[0].active = false;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  EXPECT_FALSE(stream->IsSending());

  // Now change it back to active and verify we resume sending.
  parameters.encodings[0].active = true;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  EXPECT_TRUE(stream->IsSending());
}

// Tests that when active is updated for any simulcast layer then the send
// stream's sending state will be updated and it will be reconfigured with the
// new appropriate active simulcast streams.
TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersMultipleEncodingsActive) {
  // Create the stream params with multiple ssrcs for simulcast.
  const size_t kNumSimulcastStreams = 3;
  std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
  StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
  FakeVideoSendStream* fake_video_send_stream = AddSendStream(stream_params);
  uint32_t primary_ssrc = stream_params.first_ssrc();

  // Using the FrameForwarder, we manually send a full size
  // frame. This allows us to test that ReconfigureEncoder is called
  // appropriately.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
      1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
      rtc::kNumMicrosecsPerSec / 30));

  // Check that all encodings are initially active.
  webrtc::RtpParameters parameters =
      channel_->GetRtpSendParameters(primary_ssrc);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  EXPECT_TRUE(parameters.encodings[0].active);
  EXPECT_TRUE(parameters.encodings[1].active);
  EXPECT_TRUE(parameters.encodings[2].active);
  EXPECT_TRUE(fake_video_send_stream->IsSending());

  // Only turn on only the middle stream.
  parameters.encodings[0].active = false;
  parameters.encodings[1].active = true;
  parameters.encodings[2].active = false;
  EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
  // Verify that the active fields are set on the VideoChannel.
  parameters = channel_->GetRtpSendParameters(primary_ssrc);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  EXPECT_FALSE(parameters.encodings[0].active);
  EXPECT_TRUE(parameters.encodings[1].active);
  EXPECT_FALSE(parameters.encodings[2].active);
  // Check that the VideoSendStream is updated appropriately. This means its
  // send state was updated and it was reconfigured.
  EXPECT_TRUE(fake_video_send_stream->IsSending());
  std::vector<webrtc::VideoStream> simulcast_streams =
      fake_video_send_stream->GetVideoStreams();
  EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
  EXPECT_FALSE(simulcast_streams[0].active);
  EXPECT_TRUE(simulcast_streams[1].active);
  EXPECT_FALSE(simulcast_streams[2].active);

  // Turn off all streams.
  parameters.encodings[0].active = false;
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = false;
  EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
  // Verify that the active fields are set on the VideoChannel.
  parameters = channel_->GetRtpSendParameters(primary_ssrc);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  EXPECT_FALSE(parameters.encodings[0].active);
  EXPECT_FALSE(parameters.encodings[1].active);
  EXPECT_FALSE(parameters.encodings[2].active);
  // Check that the VideoSendStream is off.
  EXPECT_FALSE(fake_video_send_stream->IsSending());
  simulcast_streams = fake_video_send_stream->GetVideoStreams();
  EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
  EXPECT_FALSE(simulcast_streams[0].active);
  EXPECT_FALSE(simulcast_streams[1].active);
  EXPECT_FALSE(simulcast_streams[2].active);

  EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
}

// Tests that when some streams are disactivated then the lowest
// stream min_bitrate would be reused for the first active stream.
TEST_F(WebRtcVideoChannelTest,
       SetRtpSendParametersSetsMinBitrateForFirstActiveStream) {
  // Create the stream params with multiple ssrcs for simulcast.
  const size_t kNumSimulcastStreams = 3;
  std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
  StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
  FakeVideoSendStream* fake_video_send_stream = AddSendStream(stream_params);
  uint32_t primary_ssrc = stream_params.first_ssrc();

  // Using the FrameForwarder, we manually send a full size
  // frame. This allows us to test that ReconfigureEncoder is called
  // appropriately.
  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
  channel_->SetSend(true);
  frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
      1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
      rtc::kNumMicrosecsPerSec / 30));

  // Check that all encodings are initially active.
  webrtc::RtpParameters parameters =
      channel_->GetRtpSendParameters(primary_ssrc);
  EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
  EXPECT_TRUE(parameters.encodings[0].active);
  EXPECT_TRUE(parameters.encodings[1].active);
  EXPECT_TRUE(parameters.encodings[2].active);
  EXPECT_TRUE(fake_video_send_stream->IsSending());

  // Only turn on the highest stream.
  parameters.encodings[0].active = false;
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = true;
  EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());

  // Check that the VideoSendStream is updated appropriately. This means its
  // send state was updated and it was reconfigured.
  EXPECT_TRUE(fake_video_send_stream->IsSending());
  std::vector<webrtc::VideoStream> simulcast_streams =
      fake_video_send_stream->GetVideoStreams();
  EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
  EXPECT_FALSE(simulcast_streams[0].active);
  EXPECT_FALSE(simulcast_streams[1].active);
  EXPECT_TRUE(simulcast_streams[2].active);

  EXPECT_EQ(simulcast_streams[2].min_bitrate_bps,
            simulcast_streams[0].min_bitrate_bps);

  EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
}

// Test that if a stream is reconfigured (due to a codec change or other
// change) while its encoding is still inactive, it doesn't start sending.
TEST_F(WebRtcVideoChannelTest,
       InactiveStreamDoesntStartSendingWhenReconfigured) {
  // Set an initial codec list, which will be modified later.
  cricket::VideoSendParameters parameters1;
  parameters1.codecs.push_back(GetEngineCodec("VP8"));
  parameters1.codecs.push_back(GetEngineCodec("VP9"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters1));

  FakeVideoSendStream* stream = AddSendStream();
  EXPECT_TRUE(channel_->SetSend(true));
  EXPECT_TRUE(stream->IsSending());

  // Get current parameters and change "active" to false.
  webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
  ASSERT_EQ(1u, parameters.encodings.size());
  ASSERT_TRUE(parameters.encodings[0].active);
  parameters.encodings[0].active = false;
  EXPECT_EQ(1u, GetFakeSendStreams().size());
  EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
  EXPECT_FALSE(stream->IsSending());

  // Reorder the codec list, causing the stream to be reconfigured.
  cricket::VideoSendParameters parameters2;
  parameters2.codecs.push_back(GetEngineCodec("VP9"));
  parameters2.codecs.push_back(GetEngineCodec("VP8"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters2));
  auto new_streams = GetFakeSendStreams();
  // Assert that a new underlying stream was created due to the codec change.
  // Otherwise, this test isn't testing what it set out to test.
  EXPECT_EQ(1u, GetFakeSendStreams().size());
  EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());

  // Verify that we still are not sending anything, due to the inactive
  // encoding.
  EXPECT_FALSE(new_streams[0]->IsSending());
}

// Test that GetRtpSendParameters returns the currently configured codecs.
TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersCodecs) {
  AddSendStream();
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpSendParameters(last_ssrc_);
  ASSERT_EQ(2u, rtp_parameters.codecs.size());
  EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
            rtp_parameters.codecs[0]);
  EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
            rtp_parameters.codecs[1]);
}

// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersRtcpCname) {
  StreamParams params = StreamParams::CreateLegacy(kSsrc);
  params.cname = "rtcpcname";
  AddSendStream(params);

  webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc);
  EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
}

// Test that RtpParameters for send stream has one encoding and it has
// the correct SSRC.
TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersSsrc) {
  AddSendStream();

  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpSendParameters(last_ssrc_);
  ASSERT_EQ(1u, rtp_parameters.encodings.size());
  EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
}

TEST_F(WebRtcVideoChannelTest, DetectRtpSendParameterHeaderExtensionsChange) {
  AddSendStream();

  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpSendParameters(last_ssrc_);
  rtp_parameters.header_extensions.emplace_back();

  EXPECT_NE(0u, rtp_parameters.header_extensions.size());

  webrtc::RTCError result =
      channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
  EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
}

TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersDegradationPreference) {
  AddSendStream();

  webrtc::test::FrameForwarder frame_forwarder;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));

  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_FALSE(rtp_parameters.degradation_preference.has_value());
  rtp_parameters.degradation_preference =
      webrtc::DegradationPreference::MAINTAIN_FRAMERATE;

  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());

  webrtc::RtpParameters updated_rtp_parameters =
      channel_->GetRtpSendParameters(last_ssrc_);
  EXPECT_EQ(updated_rtp_parameters.degradation_preference,
            webrtc::DegradationPreference::MAINTAIN_FRAMERATE);

  // Remove the source since it will be destroyed before the channel
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

// Test that if we set/get parameters multiple times, we get the same results.
TEST_F(WebRtcVideoChannelTest, SetAndGetRtpSendParameters) {
  AddSendStream();
  cricket::VideoSendParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  EXPECT_TRUE(channel_->SetSendParameters(parameters));

  webrtc::RtpParameters initial_params =
      channel_->GetRtpSendParameters(last_ssrc_);

  // We should be able to set the params we just got.
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params).ok());

  // ... And this shouldn't change the params returned by GetRtpSendParameters.
  EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
}

// Test that GetRtpReceiveParameters returns the currently configured codecs.
TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersCodecs) {
  AddRecvStream();
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpReceiveParameters(last_ssrc_);
  ASSERT_EQ(2u, rtp_parameters.codecs.size());
  EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
            rtp_parameters.codecs[0]);
  EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
            rtp_parameters.codecs[1]);
}

#if defined(WEBRTC_USE_H264)
TEST_F(WebRtcVideoChannelTest, GetRtpReceiveFmtpSprop) {
#else
TEST_F(WebRtcVideoChannelTest, DISABLED_GetRtpReceiveFmtpSprop) {
#endif
  cricket::VideoRecvParameters parameters;
  cricket::VideoCodec kH264sprop1(101, "H264");
  kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
  parameters.codecs.push_back(kH264sprop1);
  cricket::VideoCodec kH264sprop2(102, "H264");
  kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
  parameters.codecs.push_back(kH264sprop2);
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  FakeVideoReceiveStream* recv_stream = AddRecvStream();
  const webrtc::VideoReceiveStreamInterface::Config& cfg =
      recv_stream->GetConfig();
  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpReceiveParameters(last_ssrc_);
  ASSERT_EQ(2u, rtp_parameters.codecs.size());
  EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
  ASSERT_EQ(2u, cfg.decoders.size());
  EXPECT_EQ(101, cfg.decoders[0].payload_type);
  EXPECT_EQ("H264", cfg.decoders[0].video_format.name);
  const auto it0 =
      cfg.decoders[0].video_format.parameters.find(kH264FmtpSpropParameterSets);
  ASSERT_TRUE(it0 != cfg.decoders[0].video_format.parameters.end());
  EXPECT_EQ("uvw", it0->second);

  EXPECT_EQ(102, cfg.decoders[1].payload_type);
  EXPECT_EQ("H264", cfg.decoders[1].video_format.name);
  const auto it1 =
      cfg.decoders[1].video_format.parameters.find(kH264FmtpSpropParameterSets);
  ASSERT_TRUE(it1 != cfg.decoders[1].video_format.parameters.end());
  EXPECT_EQ("xyz", it1->second);
}

// Test that RtpParameters for receive stream has one encoding and it has
// the correct SSRC.
TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersSsrc) {
  AddRecvStream();

  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpReceiveParameters(last_ssrc_);
  ASSERT_EQ(1u, rtp_parameters.encodings.size());
  EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
}

// Test that if we set/get parameters multiple times, we get the same results.
TEST_F(WebRtcVideoChannelTest, SetAndGetRtpReceiveParameters) {
  AddRecvStream();
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  webrtc::RtpParameters initial_params =
      channel_->GetRtpReceiveParameters(last_ssrc_);

  // ... And this shouldn't change the params returned by
  // GetRtpReceiveParameters.
  EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
}

// Test that GetDefaultRtpReceiveParameters returns parameters correctly when
// SSRCs aren't signaled. It should always return an empty
// "RtpEncodingParameters", even after a packet is received and the unsignaled
// SSRC is known.
TEST_F(WebRtcVideoChannelTest,
       GetDefaultRtpReceiveParametersWithUnsignaledSsrc) {
  // Call necessary methods to configure receiving a default stream as
  // soon as it arrives.
  cricket::VideoRecvParameters parameters;
  parameters.codecs.push_back(GetEngineCodec("VP8"));
  parameters.codecs.push_back(GetEngineCodec("VP9"));
  EXPECT_TRUE(channel_->SetRecvParameters(parameters));

  // Call GetRtpReceiveParameters before configured to receive an unsignaled
  // stream. Should return nothing.
  EXPECT_EQ(webrtc::RtpParameters(),
            channel_->GetDefaultRtpReceiveParameters());

  // Set a sink for an unsignaled stream.
  cricket::FakeVideoRenderer renderer;
  channel_->SetDefaultSink(&renderer);

  // Call GetDefaultRtpReceiveParameters before the SSRC is known.
  webrtc::RtpParameters rtp_parameters =
      channel_->GetDefaultRtpReceiveParameters();
  ASSERT_EQ(1u, rtp_parameters.encodings.size());
  EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);

  // Receive VP8 packet.
  RtpPacket rtp_packet;
  rtp_packet.SetPayloadType(GetEngineCodec("VP8").id);
  rtp_packet.SetSsrc(kIncomingUnsignalledSsrc);
  ReceivePacketAndAdvanceTime(rtp_packet.Buffer(), /* packet_time_us */ -1);

  // The `ssrc` member should still be unset.
  rtp_parameters = channel_->GetDefaultRtpReceiveParameters();
  ASSERT_EQ(1u, rtp_parameters.encodings.size());
  EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
}

// Test that if a default stream is created for a non-primary stream (for
// example, RTX before we know it's RTX), we are still able to explicitly add
// the stream later.
TEST_F(WebRtcVideoChannelTest,
       AddReceiveStreamAfterReceivingNonPrimaryUnsignaledSsrc) {
  // Receive VP8 RTX packet.
  RtpPacket rtp_packet;
  const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
  rtp_packet.SetPayloadType(default_apt_rtx_types_[vp8.id]);
  rtp_packet.SetSsrc(2);
  ReceivePacketAndAdvanceTime(rtp_packet.Buffer(), /* packet_time_us */ -1);
  EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());

  cricket::StreamParams params = cricket::StreamParams::CreateLegacy(1);
  params.AddFidSsrc(1, 2);
  EXPECT_TRUE(channel_->AddRecvStream(params));
}

void WebRtcVideoChannelTest::TestReceiverLocalSsrcConfiguration(
    bool receiver_first) {
  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));

  const uint32_t kSenderSsrc = 0xC0FFEE;
  const uint32_t kSecondSenderSsrc = 0xBADCAFE;
  const uint32_t kReceiverSsrc = 0x4711;
  const uint32_t kExpectedDefaultReceiverSsrc = 1;

  if (receiver_first) {
    AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
    std::vector<FakeVideoReceiveStream*> receive_streams =
        fake_call_->GetVideoReceiveStreams();
    ASSERT_EQ(1u, receive_streams.size());
    // Default local SSRC when we have no sender.
    EXPECT_EQ(kExpectedDefaultReceiverSsrc,
              receive_streams[0]->GetConfig().rtp.local_ssrc);
  }
  AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
  if (!receiver_first)
    AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
  std::vector<FakeVideoReceiveStream*> receive_streams =
      fake_call_->GetVideoReceiveStreams();
  ASSERT_EQ(1u, receive_streams.size());
  EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);

  // Removing first sender should fall back to another (in this case the second)
  // local send stream's SSRC.
  AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
  ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
  receive_streams = fake_call_->GetVideoReceiveStreams();
  ASSERT_EQ(1u, receive_streams.size());
  EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);

  // Removing the last sender should fall back to default local SSRC.
  ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
  receive_streams = fake_call_->GetVideoReceiveStreams();
  ASSERT_EQ(1u, receive_streams.size());
  EXPECT_EQ(kExpectedDefaultReceiverSsrc,
            receive_streams[0]->GetConfig().rtp.local_ssrc);
}

TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrc) {
  TestReceiverLocalSsrcConfiguration(false);
}

TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrcOnExistingReceivers) {
  TestReceiverLocalSsrcConfiguration(true);
}

TEST_F(WebRtcVideoChannelTest, Simulcast_QualityScalingNotAllowed) {
  FakeVideoSendStream* stream = SetUpSimulcast(true, true);
  EXPECT_FALSE(stream->GetEncoderConfig().is_quality_scaling_allowed);
}

TEST_F(WebRtcVideoChannelTest, Singlecast_QualityScalingAllowed) {
  FakeVideoSendStream* stream = SetUpSimulcast(false, true);
  EXPECT_TRUE(stream->GetEncoderConfig().is_quality_scaling_allowed);
}

TEST_F(WebRtcVideoChannelTest,
       SinglecastScreenSharing_QualityScalingNotAllowed) {
  SetUpSimulcast(false, true);

  webrtc::test::FrameForwarder frame_forwarder;
  VideoOptions options;
  options.is_screencast = true;
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
  // Fetch the latest stream since SetVideoSend() may recreate it if the
  // screen content setting is changed.
  FakeVideoSendStream* stream = fake_call_->GetVideoSendStreams().front();

  EXPECT_FALSE(stream->GetEncoderConfig().is_quality_scaling_allowed);
  EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
}

TEST_F(WebRtcVideoChannelTest,
       SimulcastSingleActiveStream_QualityScalingAllowed) {
  FakeVideoSendStream* stream = SetUpSimulcast(true, false);

  webrtc::RtpParameters rtp_parameters =
      channel_->GetRtpSendParameters(last_ssrc_);
  ASSERT_EQ(3u, rtp_parameters.encodings.size());
  ASSERT_TRUE(rtp_parameters.encodings[0].active);
  ASSERT_TRUE(rtp_parameters.encodings[1].active);
  ASSERT_TRUE(rtp_parameters.encodings[2].active);
  rtp_parameters.encodings[0].active = false;
  rtp_parameters.encodings[1].active = false;
  EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
  EXPECT_TRUE(stream->GetEncoderConfig().is_quality_scaling_allowed);
}

class WebRtcVideoChannelSimulcastTest : public ::testing::Test {
 public:
  WebRtcVideoChannelSimulcastTest()
      : fake_call_(),
        encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
        decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
        mock_rate_allocator_factory_(
            std::make_unique<webrtc::MockVideoBitrateAllocatorFactory>()),
        engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
                    encoder_factory_),
                std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
                    decoder_factory_),
                field_trials_),
        last_ssrc_(0) {}

  void SetUp() override {
    encoder_factory_->AddSupportedVideoCodecType("VP8");
    decoder_factory_->AddSupportedVideoCodecType("VP8");
    channel_.reset(engine_.CreateMediaChannel(
        &fake_call_, GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
        mock_rate_allocator_factory_.get()));
    channel_->OnReadyToSend(true);
    last_ssrc_ = 123;
  }

 protected:
  void VerifySimulcastSettings(const VideoCodec& codec,
                               int capture_width,
                               int capture_height,
                               size_t num_configured_streams,
                               size_t expected_num_streams,
                               bool screenshare,
                               bool conference_mode) {
    cricket::VideoSendParameters parameters;
    parameters.codecs.push_back(codec);
    parameters.conference_mode = conference_mode;
    ASSERT_TRUE(channel_->SetSendParameters(parameters));

    std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
    RTC_DCHECK(num_configured_streams <= ssrcs.size());
    ssrcs.resize(num_configured_streams);

    AddSendStream(CreateSimStreamParams("cname", ssrcs));
    // Send a full-size frame to trigger a stream reconfiguration to use all
    // expected simulcast layers.
    webrtc::test::FrameForwarder frame_forwarder;
    cricket::FakeFrameSource frame_source(capture_width, capture_height,
                                          rtc::kNumMicrosecsPerSec / 30);

    VideoOptions options;
    if (screenshare)
      options.is_screencast = screenshare;
    EXPECT_TRUE(
        channel_->SetVideoSend(ssrcs.front(), &options, &frame_forwarder));
    // Fetch the latest stream since SetVideoSend() may recreate it if the
    // screen content setting is changed.
    FakeVideoSendStream* stream = fake_call_.GetVideoSendStreams().front();
    channel_->SetSend(true);
    frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());

    auto rtp_parameters = channel_->GetRtpSendParameters(kSsrcs3[0]);
    EXPECT_EQ(num_configured_streams, rtp_parameters.encodings.size());

    std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
    ASSERT_EQ(expected_num_streams, video_streams.size());
    EXPECT_LE(expected_num_streams, stream->GetConfig().rtp.ssrcs.size());

    std::vector<webrtc::VideoStream> expected_streams;
    if (num_configured_streams > 1 || conference_mode) {
      expected_streams = GetSimulcastConfig(
          /*min_layers=*/1, num_configured_streams, capture_width,
          capture_height, webrtc::kDefaultBitratePriority, kDefaultQpMax,
          screenshare && conference_mode, true, field_trials_);
      if (screenshare && conference_mode) {
        for (const webrtc::VideoStream& stream : expected_streams) {
          // Never scale screen content.
          EXPECT_EQ(stream.width, rtc::checked_cast<size_t>(capture_width));
          EXPECT_EQ(stream.height, rtc::checked_cast<size_t>(capture_height));
        }
      }
    } else {
      webrtc::VideoStream stream;
      stream.width = capture_width;
      stream.height = capture_height;
      stream.max_framerate = kDefaultVideoMaxFramerate;
      stream.min_bitrate_bps = webrtc::kDefaultMinVideoBitrateBps;
      stream.target_bitrate_bps = stream.max_bitrate_bps =
          GetMaxDefaultBitrateBps(capture_width, capture_height);
      stream.max_qp = kDefaultQpMax;
      expected_streams.push_back(stream);
    }

    ASSERT_EQ(expected_streams.size(), video_streams.size());

    size_t num_streams = video_streams.size();
    for (size_t i = 0; i < num_streams; ++i) {
      EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
      EXPECT_EQ(expected_streams[i].height, video_streams[i].height);

      EXPECT_GT(video_streams[i].max_framerate, 0);
      EXPECT_EQ(expected_streams[i].max_framerate,
                video_streams[i].max_framerate);

      EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
      EXPECT_EQ(expected_streams[i].min_bitrate_bps,
                video_streams[i].min_bitrate_bps);

      EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
      EXPECT_EQ(expected_streams[i].target_bitrate_bps,
                video_streams[i].target_bitrate_bps);

      EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
      EXPECT_EQ(expected_streams[i].max_bitrate_bps,
                video_streams[i].max_bitrate_bps);

      EXPECT_GT(video_streams[i].max_qp, 0);
      EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);

      EXPECT_EQ(num_configured_streams > 1 || conference_mode,
                expected_streams[i].num_temporal_layers.has_value());

      if (conference_mode) {
        EXPECT_EQ(expected_streams[i].num_temporal_layers,
                  video_streams[i].num_temporal_layers);
      }
    }

    EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), nullptr, nullptr));
  }

  FakeVideoSendStream* AddSendStream() {
    return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
  }

  FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
    size_t num_streams = fake_call_.GetVideoSendStreams().size();
    EXPECT_TRUE(channel_->AddSendStream(sp));
    std::vector<FakeVideoSendStream*> streams =
        fake_call_.GetVideoSendStreams();
    EXPECT_EQ(num_streams + 1, streams.size());
    return streams[streams.size() - 1];
  }

  std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
    return fake_call_.GetVideoSendStreams();
  }

  FakeVideoReceiveStream* AddRecvStream() {
    return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
  }

  FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
    size_t num_streams = fake_call_.GetVideoReceiveStreams().size();
    EXPECT_TRUE(channel_->AddRecvStream(sp));
    std::vector<FakeVideoReceiveStream*> streams =
        fake_call_.GetVideoReceiveStreams();
    EXPECT_EQ(num_streams + 1, streams.size());
    return streams[streams.size() - 1];
  }

  webrtc::test::ScopedKeyValueConfig field_trials_;
  webrtc::RtcEventLogNull event_log_;
  FakeCall fake_call_;
  cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
  cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
  std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
      mock_rate_allocator_factory_;
  WebRtcVideoEngine engine_;
  std::unique_ptr<VideoMediaChannel> channel_;
  uint32_t last_ssrc_;
};

TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith2SimulcastStreams) {
  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
                          true);
}

TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith3SimulcastStreams) {
  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
                          true);
}

// Test that we normalize send codec format size in simulcast.
TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
                          true);
}

TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForScreenshare) {
  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, true,
                          false);
}

TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForSimulcastScreenshare) {
  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
                          true);
}

TEST_F(WebRtcVideoChannelSimulcastTest, SimulcastScreenshareWithoutConference) {
  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, true,
                          false);
}

TEST_F(WebRtcVideoChannelBaseTest, GetSources) {
  EXPECT_THAT(channel_->GetSources(kSsrc), IsEmpty());

  channel_->SetDefaultSink(&renderer_);
  EXPECT_TRUE(SetDefaultCodec());
  EXPECT_TRUE(SetSend(true));
  EXPECT_EQ(renderer_.num_rendered_frames(), 0);

  // Send and receive one frame.
  SendFrame();
  EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);

  EXPECT_THAT(channel_->GetSources(kSsrc - 1), IsEmpty());
  EXPECT_THAT(channel_->GetSources(kSsrc), SizeIs(1));
  EXPECT_THAT(channel_->GetSources(kSsrc + 1), IsEmpty());

  webrtc::RtpSource source = channel_->GetSources(kSsrc)[0];
  EXPECT_EQ(source.source_id(), kSsrc);
  EXPECT_EQ(source.source_type(), webrtc::RtpSourceType::SSRC);
  int64_t rtp_timestamp_1 = source.rtp_timestamp();
  int64_t timestamp_ms_1 = source.timestamp_ms();

  // Send and receive another frame.
  SendFrame();
  EXPECT_FRAME_WAIT(2, kVideoWidth, kVideoHeight, kTimeout);

  EXPECT_THAT(channel_->GetSources(kSsrc - 1), IsEmpty());
  EXPECT_THAT(channel_->GetSources(kSsrc), SizeIs(1));
  EXPECT_THAT(channel_->GetSources(kSsrc + 1), IsEmpty());

  source = channel_->GetSources(kSsrc)[0];
  EXPECT_EQ(source.source_id(), kSsrc);
  EXPECT_EQ(source.source_type(), webrtc::RtpSourceType::SSRC);
  int64_t rtp_timestamp_2 = source.rtp_timestamp();
  int64_t timestamp_ms_2 = source.timestamp_ms();

  EXPECT_GT(rtp_timestamp_2, rtp_timestamp_1);
  EXPECT_GT(timestamp_ms_2, timestamp_ms_1);
}

TEST_F(WebRtcVideoChannelTest, SetsRidsOnSendStream) {
  StreamParams sp = CreateSimStreamParams("cname", {123, 456, 789});

  std::vector<std::string> rids = {"f", "h", "q"};
  std::vector<cricket::RidDescription> rid_descriptions;
  for (const auto& rid : rids) {
    rid_descriptions.emplace_back(rid, cricket::RidDirection::kSend);
  }
  sp.set_rids(rid_descriptions);

  ASSERT_TRUE(channel_->AddSendStream(sp));
  const auto& streams = fake_call_->GetVideoSendStreams();
  ASSERT_EQ(1u, streams.size());
  auto stream = streams[0];
  ASSERT_NE(stream, nullptr);
  const auto& config = stream->GetConfig();
  EXPECT_THAT(config.rtp.rids, ElementsAreArray(rids));
}

}  // namespace cricket
