/*
 *  Copyright 2023 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/audio_options.h"
#include "api/environment/environment.h"
#include "api/field_trials_view.h"
#include "api/jsep.h"
#include "api/make_ref_counted.h"
#include "api/media_stream_interface.h"
#include "api/media_types.h"
#include "api/rtc_error.h"
#include "api/rtp_parameters.h"
#include "api/rtp_sender_interface.h"
#include "api/rtp_transceiver_direction.h"
#include "api/rtp_transceiver_interface.h"
#include "api/scoped_refptr.h"
#include "api/stats/rtc_stats_report.h"
#include "api/stats/rtcstats_objects.h"
#include "api/test/rtc_error_matchers.h"
#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
#include "api/video_codecs/scalability_mode.h"
#include "api/video_codecs/sdp_video_format.h"
#include "media/base/codec.h"
#include "media/engine/fake_webrtc_video_engine.h"
#include "pc/sdp_utils.h"
#include "pc/session_description.h"
#include "pc/simulcast_description.h"
#include "pc/test/mock_peer_connection_observers.h"
#include "pc/test/peer_connection_test_wrapper.h"
#include "pc/test/simulcast_layer_util.h"
#include "rtc_base/checks.h"
#include "rtc_base/containers/flat_map.h"
#include "rtc_base/logging.h"
#include "rtc_base/physical_socket_server.h"
#include "rtc_base/thread.h"
#include "test/create_test_environment.h"
#include "test/create_test_field_trials.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/wait_until.h"

using ::testing::AllOf;
using ::testing::AnyOf;
using ::testing::Contains;
using ::testing::Each;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Gt;
using ::testing::HasSubstr;
using ::testing::IsSupersetOf;
using ::testing::IsTrue;
using ::testing::Key;
using ::testing::Le;
using ::testing::Matcher;
using ::testing::Ne;
using ::testing::NotNull;
using ::testing::Optional;
using ::testing::Pair;
using ::testing::Pointer;
using ::testing::ResultOf;
using ::testing::SizeIs;
using ::testing::StrCaseEq;
using ::testing::StrEq;
using ::testing::UnorderedElementsAre;

namespace webrtc {

namespace {

// Most tests pass in 20-30 seconds, but some tests take longer such as AV1
// requiring additional ramp-up time (https://crbug.com/webrtc/15006) or SVC
// (LxTx_KEY) being slower than simulcast to send top spatial layer.
// TODO(https://crbug.com/webrtc/15076): Remove need for long ramp-up timeouts
// by using simulated time.
constexpr TimeDelta kLongTimeoutForRampingUp = TimeDelta::Minutes(1);

// The max bitrate 1500 kbps may be subject to change in the future. What we're
// interested in here is that all code paths that result in L1T3 result in the
// same target bitrate which does not exceed this limit.
constexpr DataRate kVp9ExpectedMaxBitrateForL1T3 =
    DataRate::KilobitsPerSec(1500);

auto EncoderImplementationIs(absl::string_view impl) {
  return Field("encoder_implementation",
               &RTCOutboundRtpStreamStats::encoder_implementation,
               Optional(StrEq(impl)));
}

template <typename M>
auto ScalabilityModeIs(M matcher) {
  return Field("scalability_mode", &RTCOutboundRtpStreamStats::scalability_mode,
               matcher);
}

template <typename M>
auto CodecIs(M matcher) {
  return Field("codec_id", &RTCOutboundRtpStreamStats::codec_id, matcher);
}

template <typename M>
auto RidIs(M matcher) {
  return Field("rid", &RTCOutboundRtpStreamStats::rid, matcher);
}

template <typename WidthMatcher, typename HeightMatcher>
auto ResolutionIs(WidthMatcher width_matcher, HeightMatcher height_matcher) {
  return AllOf(Field("frame_width", &RTCOutboundRtpStreamStats::frame_width,
                     width_matcher),
               Field("frame_height", &RTCOutboundRtpStreamStats::frame_height,
                     height_matcher));
}

template <typename M>
auto HeightIs(M matcher) {
  return Field("frame_height", &RTCOutboundRtpStreamStats::frame_height,
               matcher);
}

template <typename M>
auto BytesSentIs(M matcher) {
  return Field("bytes_sent", &RTCOutboundRtpStreamStats::bytes_sent, matcher);
}

template <typename M>
auto FramesEncodedIs(M matcher) {
  return Field("frames_encoded", &RTCOutboundRtpStreamStats::frames_encoded,
               matcher);
}

auto Active() {
  return Field("active", &RTCOutboundRtpStreamStats::active, true);
}

Matcher<scoped_refptr<const RTCStatsReport>> OutboundRtpStatsAre(
    Matcher<std::vector<RTCOutboundRtpStreamStats>> matcher) {
  return Pointer(ResultOf(
      "outbound_rtp",
      [&](const RTCStatsReport* report) {
        std::vector<const RTCOutboundRtpStreamStats*> stats =
            report->GetStatsOfType<RTCOutboundRtpStreamStats>();

        // Copy to a new vector.
        std::vector<RTCOutboundRtpStreamStats> stats_copy;
        stats_copy.reserve(stats.size());
        for (const auto* stat : stats) {
          stats_copy.emplace_back(*stat);
        }
        return stats_copy;
      },
      matcher));
}

auto HasOutboundRtpBytesSent(size_t num_layers, size_t num_active_layers) {
  return OutboundRtpStatsAre(AllOf(
      SizeIs(num_layers),
      testing::Contains(
          Field("bytes_sent", &RTCOutboundRtpStreamStats::bytes_sent, Gt(0)))
          .Times(num_active_layers)));
}

auto HasOutboundRtpBytesSent(size_t num_layers) {
  return HasOutboundRtpBytesSent(num_layers, num_layers);
}

flat_map<std::string, RTCOutboundRtpStreamStats> GetOutboundRtpStreamStatsByRid(
    scoped_refptr<const RTCStatsReport> report) {
  flat_map<std::string, RTCOutboundRtpStreamStats> result;
  auto stats = report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  for (const auto* outbound_rtp : stats) {
    result.emplace(
        std::make_pair(outbound_rtp->rid.value_or(""), *outbound_rtp));
  }
  return result;
}

struct StringParamToString {
  std::string operator()(const ::testing::TestParamInfo<std::string>& info) {
    return info.param;
  }
};

std::string GetCurrentCodecMimeType(
    scoped_refptr<const RTCStatsReport> report,
    const RTCOutboundRtpStreamStats& outbound_rtp) {
  return outbound_rtp.codec_id.has_value()
             ? *report->GetAs<RTCCodecStats>(*outbound_rtp.codec_id)->mime_type
             : "";
}

const RTCOutboundRtpStreamStats* FindOutboundRtpByRid(
    const std::vector<const RTCOutboundRtpStreamStats*>& outbound_rtps,
    const absl::string_view& rid) {
  for (const auto* outbound_rtp : outbound_rtps) {
    if (outbound_rtp->rid.has_value() && *outbound_rtp->rid == rid) {
      return outbound_rtp;
    }
  }
  return nullptr;
}

}  // namespace

class PeerConnectionEncodingsIntegrationTest : public ::testing::Test {
 public:
  PeerConnectionEncodingsIntegrationTest()
      : env_(CreateTestEnvironment()),
        background_thread_(std::make_unique<Thread>(&pss_)) {
    RTC_CHECK(background_thread_->Start());
  }

  scoped_refptr<PeerConnectionTestWrapper> CreatePc(
      absl::string_view field_trials = "") {
    auto pc_wrapper = make_ref_counted<PeerConnectionTestWrapper>(
        "pc", env_, &pss_, background_thread_.get(), background_thread_.get());
    pc_wrapper->CreatePc({}, CreateBuiltinAudioEncoderFactory(),
                         CreateBuiltinAudioDecoderFactory(),
                         CreateTestFieldTrialsPtr(field_trials));
    return pc_wrapper;
  }

  scoped_refptr<RtpTransceiverInterface> AddTransceiverWithSimulcastLayers(
      scoped_refptr<PeerConnectionTestWrapper> local,
      scoped_refptr<PeerConnectionTestWrapper> remote,
      std::vector<SimulcastLayer> init_layers) {
    scoped_refptr<MediaStreamInterface> stream = local->GetUserMedia(
        /*audio=*/false, AudioOptions(), /*video=*/true,
        {.width = 1280, .height = 720});
    scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];

    RTCErrorOr<scoped_refptr<RtpTransceiverInterface>> transceiver_or_error =
        local->pc()->AddTransceiver(track, CreateTransceiverInit(init_layers));
    EXPECT_TRUE(transceiver_or_error.ok());
    return transceiver_or_error.value();
  }

  bool HasReceiverVideoCodecCapability(
      scoped_refptr<PeerConnectionTestWrapper> pc_wrapper,
      absl::string_view codec_name) {
    std::vector<RtpCodecCapability> codecs =
        pc_wrapper->pc_factory()
            ->GetRtpReceiverCapabilities(MediaType::VIDEO)
            .codecs;
    return std::find_if(codecs.begin(), codecs.end(),
                        [&codec_name](const RtpCodecCapability& codec) {
                          return absl::EqualsIgnoreCase(codec.name, codec_name);
                        }) != codecs.end();
  }

  std::vector<RtpCodecCapability> GetCapabilitiesAndRestrictToCodec(
      scoped_refptr<PeerConnectionTestWrapper> pc_wrapper,
      absl::string_view codec_name) {
    std::vector<RtpCodecCapability> codecs =
        pc_wrapper->pc_factory()
            ->GetRtpReceiverCapabilities(MediaType::VIDEO)
            .codecs;
    std::erase_if(codecs, [&codec_name](const RtpCodecCapability& codec) {
      return !codec.IsResiliencyCodec() &&
             !absl::EqualsIgnoreCase(codec.name, codec_name);
    });
    RTC_DCHECK(std::find_if(codecs.begin(), codecs.end(),
                            [&codec_name](const RtpCodecCapability& codec) {
                              return absl::EqualsIgnoreCase(codec.name,
                                                            codec_name);
                            }) != codecs.end());
    return codecs;
  }

  void ExchangeIceCandidates(
      scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper,
      scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper) {
    local_pc_wrapper->SignalOnIceCandidateReady.connect(
        remote_pc_wrapper.get(), &PeerConnectionTestWrapper::AddIceCandidate);
    remote_pc_wrapper->SignalOnIceCandidateReady.connect(
        local_pc_wrapper.get(), &PeerConnectionTestWrapper::AddIceCandidate);
  }

  // Negotiate without any tweaks (does not work for simulcast loopback).
  void Negotiate(scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper,
                 scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper) {
    std::unique_ptr<SessionDescriptionInterface> offer =
        CreateOffer(local_pc_wrapper);
    scoped_refptr<MockSetSessionDescriptionObserver> p1 =
        SetLocalDescription(local_pc_wrapper, offer.get());
    scoped_refptr<MockSetSessionDescriptionObserver> p2 =
        SetRemoteDescription(remote_pc_wrapper, offer.get());
    EXPECT_TRUE(Await({p1, p2}));
    std::unique_ptr<SessionDescriptionInterface> answer =
        CreateAnswer(remote_pc_wrapper);
    p1 = SetLocalDescription(remote_pc_wrapper, answer.get());
    p2 = SetRemoteDescription(local_pc_wrapper, answer.get());
    EXPECT_TRUE(Await({p1, p2}));
  }

  void NegotiateWithSimulcastTweaks(
      scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper,
      scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper) {
    // Create and set offer for `local_pc_wrapper`.
    std::unique_ptr<SessionDescriptionInterface> offer =
        CreateOffer(local_pc_wrapper);
    scoped_refptr<MockSetSessionDescriptionObserver> p1 =
        SetLocalDescription(local_pc_wrapper, offer.get());
    // Modify the offer before handoff because `remote_pc_wrapper` only supports
    // receiving singlecast.
    SimulcastDescription simulcast_description = RemoveSimulcast(offer.get());
    scoped_refptr<MockSetSessionDescriptionObserver> p2 =
        SetRemoteDescription(remote_pc_wrapper, offer.get());
    EXPECT_TRUE(Await({p1, p2}));

    // Create and set answer for `remote_pc_wrapper`.
    std::unique_ptr<SessionDescriptionInterface> answer =
        CreateAnswer(remote_pc_wrapper);
    EXPECT_TRUE(answer);
    p1 = SetLocalDescription(remote_pc_wrapper, answer.get());
    // Modify the answer before handoff because `local_pc_wrapper` should still
    // send simulcast.
    MediaContentDescription* mcd_answer =
        answer->description()->contents()[0].media_description();
    mcd_answer->mutable_streams().clear();
    std::vector<SimulcastLayer> simulcast_layers =
        simulcast_description.send_layers().GetAllLayers();
    SimulcastLayerList& receive_layers =
        mcd_answer->simulcast_description().receive_layers();
    for (const auto& layer : simulcast_layers) {
      receive_layers.AddLayer(layer);
    }
    p2 = SetRemoteDescription(local_pc_wrapper, answer.get());
    EXPECT_TRUE(Await({p1, p2}));
  }

  scoped_refptr<const RTCStatsReport> GetStats(
      scoped_refptr<PeerConnectionTestWrapper> pc_wrapper) {
    auto callback = make_ref_counted<MockRTCStatsCollectorCallback>();
    pc_wrapper->pc()->GetStats(callback.get());
    RTC_CHECK(WaitUntil([&]() { return callback->called(); }, testing::IsTrue())
                  .ok());
    return callback->report();
  }

  [[nodiscard]] RTCErrorOr<scoped_refptr<const RTCStatsReport>> GetStatsUntil(
      scoped_refptr<PeerConnectionTestWrapper> pc_wrapper,
      Matcher<scoped_refptr<const RTCStatsReport>> matcher,
      WaitUntilSettings settings = {}) {
    return WaitUntil([&]() { return GetStats(pc_wrapper); }, std::move(matcher),
                     settings);
  }

 protected:
  std::unique_ptr<SessionDescriptionInterface> CreateOffer(
      scoped_refptr<PeerConnectionTestWrapper> pc_wrapper) {
    auto observer = make_ref_counted<MockCreateSessionDescriptionObserver>();
    pc_wrapper->pc()->CreateOffer(observer.get(), {});
    EXPECT_THAT(WaitUntil([&] { return observer->called(); }, IsTrue()),
                IsRtcOk());
    return observer->MoveDescription();
  }

  std::unique_ptr<SessionDescriptionInterface> CreateAnswer(
      scoped_refptr<PeerConnectionTestWrapper> pc_wrapper) {
    auto observer = make_ref_counted<MockCreateSessionDescriptionObserver>();
    pc_wrapper->pc()->CreateAnswer(observer.get(), {});
    EXPECT_THAT(WaitUntil([&] { return observer->called(); }, IsTrue()),
                IsRtcOk());
    return observer->MoveDescription();
  }

  scoped_refptr<MockSetSessionDescriptionObserver> SetLocalDescription(
      scoped_refptr<PeerConnectionTestWrapper> pc_wrapper,
      SessionDescriptionInterface* sdp) {
    auto observer = make_ref_counted<MockSetSessionDescriptionObserver>();
    pc_wrapper->pc()->SetLocalDescription(
        observer.get(), CloneSessionDescription(sdp).release());
    return observer;
  }

  scoped_refptr<MockSetSessionDescriptionObserver> SetRemoteDescription(
      scoped_refptr<PeerConnectionTestWrapper> pc_wrapper,
      SessionDescriptionInterface* sdp) {
    auto observer = make_ref_counted<MockSetSessionDescriptionObserver>();
    pc_wrapper->pc()->SetRemoteDescription(
        observer.get(), CloneSessionDescription(sdp).release());
    return observer;
  }

  // To avoid ICE candidates arriving before the remote endpoint has received
  // the offer it is important to SetLocalDescription() and
  // SetRemoteDescription() are kicked off without awaiting in-between. This
  // helper is used to await multiple observers.
  bool Await(
      std::vector<scoped_refptr<MockSetSessionDescriptionObserver>> observers) {
    for (auto& observer : observers) {
      auto result = WaitUntil([&] { return observer->called(); }, IsTrue());

      if (!result.ok() || !observer->result()) {
        return false;
      }
    }
    return true;
  }

  const Environment env_;
  PhysicalSocketServer pss_;
  std::unique_ptr<Thread> background_thread_;
};

TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP8_SingleEncodingDefaultsToL1T1) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers = CreateLayers({"f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP8");
  transceiver->SetCodecPreferences(codecs);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait until media is flowing.
  auto stats_result =
      GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(1));
  ASSERT_THAT(stats_result, IsRtcOk());
  EXPECT_THAT(GetOutboundRtpStreamStatsByRid(stats_result.value()),
              ElementsAre(Pair("", ResolutionIs(1280, 720))));

  // Verify codec and scalability mode.
  scoped_refptr<const RTCStatsReport> report = stats_result.value();
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(1u));
  EXPECT_THAT(outbound_rtps, Contains(ResolutionIs(Le(1280), Le(720))));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]),
              StrCaseEq("video/VP8"));
  EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T1"));
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP8_RejectsSvcAndDefaultsToL1T1) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers = CreateLayers({"f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  // Restricting the local receive codecs will restrict what we offer and
  // hence the answer if it is a subset of our offer.
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8");
  transceiver->SetCodecPreferences(codecs);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);

  // Attempt SVC (L3T3_KEY). This is not possible because only VP8 is up for
  // negotiation and VP8 does not support it.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  parameters.encodings[0].scalability_mode = "L3T3_KEY";
  parameters.encodings[0].scale_resolution_down_by = 1;
  EXPECT_FALSE(sender->SetParameters(parameters).ok());
  // `scalability_mode` remains unset because SetParameters() failed.
  parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(std::nullopt));

  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait until media is flowing.
  ASSERT_THAT(GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(1)),
              IsRtcOk());
  // When `scalability_mode` is not set, VP8 defaults to L1T1.
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(1u));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]),
              StrCaseEq("video/VP8"));
  EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T1"));
  // GetParameters() confirms `scalability_mode` is still not set.
  parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(std::nullopt));
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       SetParametersWithScalabilityModeNotSupportedBySubsequentNegotiation) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers = CreateLayers({"f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  // Restricting the local receive codecs will restrict what we offer and
  // hence the answer if it is a subset of our offer.
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8");
  transceiver->SetCodecPreferences(codecs);

  // Attempt SVC (L3T3_KEY). This is still possible because VP9 might be
  // available from the remote end.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  parameters.encodings[0].scalability_mode = "L3T3_KEY";
  parameters.encodings[0].scale_resolution_down_by = 1;
  EXPECT_TRUE(sender->SetParameters(parameters).ok());

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);

  // `scalability_mode` is set to the VP8 default since that is what was
  // negotiated.
  parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq("L1T2"));

  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait until media is flowing.
  auto error_or_stats =
      GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(1));
  ASSERT_THAT(error_or_stats, IsRtcOk());
  // When `scalability_mode` is not set, VP8 defaults to L1T1.
  scoped_refptr<const RTCStatsReport> report = error_or_stats.value();
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(1u));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]),
              StrCaseEq("video/VP8"));
  EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T2"));
  // GetParameters() confirms `scalability_mode` is still not set.
  parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq("L1T2"));
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP8_FallbackFromSvcResultsInL1T2) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers = CreateLayers({"f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  // Verify test assumption that VP8 is first in the list, but don't modify the
  // codec preferences because we want the sender to think SVC is a possibility.
  std::vector<RtpCodecCapability> codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::VIDEO)
          .codecs;
  EXPECT_THAT(codecs[0].name, StrCaseEq("VP8"));
  // Attempt SVC (L3T3_KEY), which is not possible with VP8, but the sender does
  // not yet know which codec we'll use so the parameters will be accepted.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  parameters.encodings[0].scalability_mode = "L3T3_KEY";
  parameters.encodings[0].scale_resolution_down_by = 1;
  EXPECT_TRUE(sender->SetParameters(parameters).ok());
  // Verify fallback has not happened yet.
  parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  EXPECT_THAT(parameters.encodings[0].scalability_mode,
              Optional(std::string("L3T3_KEY")));

  // Negotiate, this results in VP8 being picked and fallback happening.
  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();
  // `scalaiblity_mode` is assigned the fallback value "L1T2" which is different
  // than the default of std::nullopt.
  parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  EXPECT_THAT(parameters.encodings[0].scalability_mode,
              Optional(std::string("L1T2")));

  // Wait until media is flowing, no significant time needed because we only
  // have one layer.
  ASSERT_THAT(GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(1u)),
              IsRtcOk());
  // GetStats() confirms "L1T2" is used which is different than the "L1T1"
  // default or the "L3T3_KEY" that was attempted.
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(1u));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]),
              StrCaseEq("video/VP8"));
  EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T2"));

  // Now that we know VP8 is used, try setting L3T3 which should fail.
  parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  parameters.encodings[0].scalability_mode = "L3T3_KEY";
  parameters.encodings[0].scale_resolution_down_by = 1;
  EXPECT_FALSE(sender->SetParameters(parameters).ok());
}

// The legacy SVC path is triggered when VP9 us used, but `scalability_mode` has
// not been specified.
// TODO(https://crbug.com/webrtc/14889): When legacy VP9 SVC path has been
// deprecated and removed, update this test to assert that simulcast is used
// (i.e. VP9 is not treated differently than VP8).
TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP9_LegacySvcWhenScalabilityModeNotSpecified) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait until media is flowing. We only expect a single RTP stream.
  // We expect to see bytes flowing almost immediately on the lowest layer.
  ASSERT_THAT(GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(1u)),
              IsRtcOk());
  // Wait until scalability mode is reported and expected resolution reached.
  // Ramp up time may be significant.
  ASSERT_THAT(
      GetStatsUntil(
          local_pc_wrapper,
          OutboundRtpStatsAre(Contains(
              AllOf(RidIs("f"), ScalabilityModeIs("L3T3_KEY"), HeightIs(720)))),
          {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());

  // Despite SVC being used on a single RTP stream, GetParameters() returns the
  // three encodings that we configured earlier (this is not spec-compliant but
  // it is how legacy SVC behaves).
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  std::vector<RtpEncodingParameters> encodings =
      sender->GetParameters().encodings;
  ASSERT_EQ(encodings.size(), 3u);
  // When legacy SVC is used, `scalability_mode` is not specified.
  EXPECT_FALSE(encodings[0].scalability_mode.has_value());
  EXPECT_FALSE(encodings[1].scalability_mode.has_value());
  EXPECT_FALSE(encodings[2].scalability_mode.has_value());
}

// The spec-compliant way to configure SVC for a single stream. The expected
// outcome is the same as for the legacy SVC case except that we only have one
// encoding in GetParameters().
TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP9_StandardSvcWithOnlyOneEncoding) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers = CreateLayers({"f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);
  // Configure SVC, a.k.a. "L3T3_KEY".
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  parameters.encodings[0].scalability_mode = "L3T3_KEY";
  parameters.encodings[0].scale_resolution_down_by = 1;
  EXPECT_TRUE(sender->SetParameters(parameters).ok());

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait until media is flowing. We only expect a single RTP stream.
  // We expect to see bytes flowing almost immediately on the lowest layer.

  auto error_or_stats =
      GetStatsUntil(local_pc_wrapper,
                    AllOf(HasOutboundRtpBytesSent(1u),
                          OutboundRtpStatsAre(Contains(HeightIs(720)))),
                    {.timeout = kLongTimeoutForRampingUp});
  ASSERT_THAT(error_or_stats, IsRtcOk());
  // Verify codec and scalability mode.
  scoped_refptr<const RTCStatsReport> report = error_or_stats.value();
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(1u));
  EXPECT_THAT(outbound_rtps[0], ResolutionIs(1280, 720));
  EXPECT_THAT(outbound_rtps[0], RidIs(std::nullopt));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]),
              StrCaseEq("video/VP9"));
  EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L3T3_KEY"));

  // GetParameters() is consistent with what we asked for and got.
  parameters = sender->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 1u);
  EXPECT_THAT(parameters.encodings[0].scalability_mode,
              Optional(std::string("L3T3_KEY")));
}

// The {active,inactive,inactive} case is technically simulcast but since we
// only have one active stream, we're able to do SVC (multiple spatial layers
// is not supported if multiple encodings are active). The expected outcome is
// the same as above except we end up with two inactive RTP streams which are
// observable in GetStats().
TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP9_StandardSvcWithSingleActiveEncoding) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);
  // Configure SVC, a.k.a. "L3T3_KEY".
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].scalability_mode = "L3T3_KEY";
  parameters.encodings[0].scale_resolution_down_by = 1;
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = false;
  EXPECT_TRUE(sender->SetParameters(parameters).ok());

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Since the standard API is configuring simulcast we get three outbound-rtps,
  // but only one is active.
  // Wait until scalability mode is reported and expected resolution reached.
  // Ramp up time is significant.
  ASSERT_THAT(GetStatsUntil(local_pc_wrapper,
                            AllOf(HasOutboundRtpBytesSent(3, 1),
                                  OutboundRtpStatsAre(Contains(AllOf(
                                      RidIs("f"), ScalabilityModeIs("L3T3_KEY"),
                                      HeightIs(720))))),
                            {.timeout = kLongTimeoutForRampingUp}),
              IsRtcOk());

  // GetParameters() is consistent with what we asked for and got.
  parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  EXPECT_THAT(parameters.encodings[0].scalability_mode,
              Optional(StrEq("L3T3_KEY")));
  EXPECT_FALSE(parameters.encodings[1].scalability_mode.has_value());
  EXPECT_FALSE(parameters.encodings[2].scalability_mode.has_value());
}

// Exercise common path where `scalability_mode` is not specified until after
// negotiation, requiring us to recreate the stream when the number of streams
// changes from 1 (legacy SVC) to 3 (standard simulcast).
TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP9_SwitchFromLegacySvcToStandardSingleActiveEncodingSvc) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);

  // The original negotiation triggers legacy SVC because we didn't specify
  // any scalability mode.
  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Switch to the standard mode. Despite only having a single active stream in
  // both cases, this internally reconfigures from 1 stream to 3 streams.
  // Test coverage for https://crbug.com/webrtc/15016.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].active = true;
  parameters.encodings[0].scalability_mode = "L2T2_KEY";
  parameters.encodings[0].scale_resolution_down_by = 2.0;
  parameters.encodings[1].active = false;
  parameters.encodings[1].scalability_mode = std::nullopt;
  parameters.encodings[2].active = false;
  parameters.encodings[2].scalability_mode = std::nullopt;
  sender->SetParameters(parameters);

  // Since the standard API is configuring simulcast we get three outbound-rtps,
  // but only one is active.
  // Wait until scalability mode is reported and expected resolution reached.
  // Ramp up time may be significant.
  ASSERT_THAT(GetStatsUntil(local_pc_wrapper,
                            AllOf(HasOutboundRtpBytesSent(3, 1),
                                  OutboundRtpStatsAre(Contains(AllOf(
                                      RidIs("f"), ScalabilityModeIs("L2T2_KEY"),
                                      HeightIs(720 / 2))))),
                            {.timeout = kLongTimeoutForRampingUp}),
              IsRtcOk());

  // GetParameters() does not report any fallback.
  parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  EXPECT_THAT(parameters.encodings[0].scalability_mode,
              Optional(std::string("L2T2_KEY")));
  EXPECT_FALSE(parameters.encodings[1].scalability_mode.has_value());
  EXPECT_FALSE(parameters.encodings[2].scalability_mode.has_value());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP9_SimulcastDeactiveActiveLayer_StandardSvc) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"q", "h", "f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  constexpr absl::string_view kCodec = "VP9";
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, kCodec);
  transceiver->SetCodecPreferences(codecs);

  // Switch to the standard mode. Despite only having a single active stream in
  // both cases, this internally reconfigures from 1 stream to 3 streams.
  // Test coverage for https://crbug.com/webrtc/15016.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].active = true;
  parameters.encodings[0].scalability_mode = "L1T3";
  parameters.encodings[0].scale_resolution_down_by = 4.0;
  parameters.encodings[1].active = true;
  parameters.encodings[1].scalability_mode = "L1T1";
  parameters.encodings[1].scale_resolution_down_by = 2.0;
  parameters.encodings[2].active = true;
  parameters.encodings[2].scalability_mode = "L1T1";
  parameters.encodings[2].scale_resolution_down_by = 1.0;
  EXPECT_TRUE(sender->SetParameters(parameters).ok());

  // The original negotiation triggers legacy SVC because we didn't specify
  // any scalability mode.
  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Since the standard API is configuring simulcast we get three outbound-rtps,
  // and two are active.
  ASSERT_THAT(
      WaitUntil(
          [&] {
            std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
                GetStats(local_pc_wrapper)
                    ->GetStatsOfType<RTCOutboundRtpStreamStats>();
            std::vector<size_t> bytes_sent;
            bytes_sent.reserve(outbound_rtps.size());
            for (const auto* outbound_rtp : outbound_rtps) {
              bytes_sent.push_back(outbound_rtp->bytes_sent.value_or(0));
            }
            return bytes_sent;
          },
          AllOf(SizeIs(3), Each(Gt(0))), {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  ASSERT_TRUE(report);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  EXPECT_THAT(outbound_rtps,
              Each(EncoderImplementationIs(
                  "SimulcastEncoderAdapter (libvpx, libvpx, libvpx)")));

  // GetParameters() does not report any fallback.
  parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  EXPECT_THAT(parameters.encodings[0].scalability_mode,
              Optional(StrEq("L1T3")));
  EXPECT_THAT(parameters.encodings[1].scalability_mode,
              Optional(StrEq("L1T1")));
  EXPECT_THAT(parameters.encodings[2].scalability_mode,
              Optional(StrEq("L1T1")));
  EXPECT_THAT(parameters.encodings[2].scale_resolution_down_by, Eq(1.0));
  EXPECT_THAT(parameters.encodings[1].scale_resolution_down_by, Eq(2.0));
  EXPECT_THAT(parameters.encodings[0].scale_resolution_down_by, Eq(4.0));

  // Deactivate the active layer.
  parameters.encodings[2].active = false;
  EXPECT_TRUE(sender->SetParameters(parameters).ok());
  ASSERT_THAT(WaitUntil(
                  [&]() {
                    return GetStats(local_pc_wrapper)
                        ->GetStatsOfType<RTCOutboundRtpStreamStats>();
                  },
                  AllOf(Each(EncoderImplementationIs(
                            "SimulcastEncoderAdapter (libvpx, libvpx)")),
                        UnorderedElementsAre(ScalabilityModeIs("L1T3"),
                                             ScalabilityModeIs("L1T1"),
                                             ScalabilityModeIs(std::nullopt)))),
              IsRtcOk());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP9_SimulcastMultiplLayersActive_StandardSvc) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"q", "h", "f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);

  // Switch to the standard mode. Despite only having a single active stream in
  // both cases, this internally reconfigures from 1 stream to 3 streams.
  // Test coverage for https://crbug.com/webrtc/15016.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].active = true;
  parameters.encodings[0].scalability_mode = "L1T3";
  parameters.encodings[0].scale_resolution_down_by = 4.0;
  parameters.encodings[1].active = true;
  parameters.encodings[1].scalability_mode = "L1T1";
  parameters.encodings[1].scale_resolution_down_by = 2.0;
  parameters.encodings[2].active = false;
  parameters.encodings[2].scalability_mode = std::nullopt;
  EXPECT_TRUE(sender->SetParameters(parameters).ok());

  // The original negotiation triggers legacy SVC because we didn't specify
  // any scalability mode.
  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Since the standard API is configuring simulcast we get three outbound-rtps,
  // and two are active.
  // Wait until scalability mode is reported and expected resolution reached.
  // Ramp up time may be significant.
  auto error_or_stats = GetStatsUntil(
      local_pc_wrapper,
      OutboundRtpStatsAre(
          IsSupersetOf({AllOf(RidIs("q"), ScalabilityModeIs("L1T3"),
                              HeightIs(720 / 4), BytesSentIs(Gt(0))),
                        AllOf(RidIs("h"), ScalabilityModeIs("L1T1"),
                              HeightIs(720 / 2), BytesSentIs(Gt(0)))})),
      {.timeout = kLongTimeoutForRampingUp});
  ASSERT_THAT(error_or_stats, IsRtcOk());
  scoped_refptr<const RTCStatsReport> report = error_or_stats.value();
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  EXPECT_THAT(outbound_rtps, Each(EncoderImplementationIs(
                                 "SimulcastEncoderAdapter (libvpx, libvpx)")));

  // GetParameters() does not report any fallback.
  parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  EXPECT_THAT(parameters.encodings[0].scalability_mode,
              Optional(StrEq("L1T3")));
  EXPECT_THAT(parameters.encodings[1].scalability_mode,
              Optional(StrEq("L1T1")));
  EXPECT_THAT(parameters.encodings[2].scalability_mode, Eq(std::nullopt));
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP9_Simulcast_SwitchToLegacySvc) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);

  // Switch to the standard mode. Despite only having a single active stream in
  // both cases, this internally reconfigures from 1 stream to 3 streams.
  // Test coverage for https://crbug.com/webrtc/15016.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].active = false;
  parameters.encodings[1].active = true;
  parameters.encodings[1].scalability_mode = "L1T1";
  parameters.encodings[1].scale_resolution_down_by = 2.0;
  parameters.encodings[2].active = true;
  parameters.encodings[2].scalability_mode = "L1T3";
  parameters.encodings[2].scale_resolution_down_by = 4.0;
  EXPECT_TRUE(sender->SetParameters(parameters).ok());

  // The original negotiation triggers legacy SVC because we didn't specify
  // any scalability mode.
  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Since the standard API is configuring simulcast we get three outbound-rtps,
  // and two are active.
  // Wait until scalability mode is reported and expected resolution reached.
  // Ramp up time may be significant.
  auto error_or_stats = GetStatsUntil(
      local_pc_wrapper,
      OutboundRtpStatsAre(UnorderedElementsAre(
          AllOf(RidIs("q"), ScalabilityModeIs("L1T3"), HeightIs(720 / 4)),
          AllOf(RidIs("h"), ScalabilityModeIs("L1T1"), HeightIs(720 / 2)),
          AllOf(RidIs("f"), BytesSentIs(AnyOf(0, std::nullopt))))),
      {.timeout = kLongTimeoutForRampingUp});
  ASSERT_THAT(error_or_stats, IsRtcOk());

  // GetParameters() does not report any fallback.
  parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(std::nullopt));
  EXPECT_THAT(parameters.encodings[1].scalability_mode,
              Optional(StrEq("L1T1")));
  EXPECT_THAT(parameters.encodings[2].scalability_mode,
              Optional(StrEq("L1T3")));

  // Switch to legacy SVC mode.
  parameters.encodings[0].active = true;
  parameters.encodings[0].scalability_mode = std::nullopt;
  parameters.encodings[0].scale_resolution_down_by = std::nullopt;
  parameters.encodings[1].active = true;
  parameters.encodings[1].scalability_mode = std::nullopt;
  parameters.encodings[1].scale_resolution_down_by = std::nullopt;
  parameters.encodings[2].active = false;
  parameters.encodings[2].scalability_mode = std::nullopt;
  parameters.encodings[2].scale_resolution_down_by = std::nullopt;

  EXPECT_TRUE(sender->SetParameters(parameters).ok());
  // Ensure that we are getting VGA at L1T3 from the "f" rid.
  EXPECT_THAT(
      GetStatsUntil(
          local_pc_wrapper,
          OutboundRtpStatsAre(Contains(AllOf(
              RidIs("f"), ScalabilityModeIs("L2T3_KEY"), HeightIs(720 / 2)))),
          {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());
}

TEST_F(PeerConnectionEncodingsIntegrationTest, VP9_OneLayerActive_LegacySvc) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);

  // Sending L1T3 with legacy SVC mode means setting 1 layer active.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].active = true;
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = false;
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Ensure that we are getting 180P at L1T3 from the "f" rid.
  EXPECT_THAT(
      GetStatsUntil(
          local_pc_wrapper,
          OutboundRtpStatsAre(Contains(
              AllOf(RidIs("f"), ScalabilityModeIs("L1T3"), HeightIs(720 / 4)))),
          {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP9_AllLayersInactive_LegacySvc) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);

  // Legacy SVC mode and all layers inactive.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].active = false;
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = false;
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Ensure no media is flowing (1 second should be enough).
  Thread::Current()->SleepMs(1000);
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(1u));
  EXPECT_EQ(*outbound_rtps[0]->bytes_sent, 0u);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       VP9_AllLayersInactive_StandardSvc) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);

  // Standard mode and all layers inactive.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].scalability_mode = "L3T3_KEY";
  parameters.encodings[0].scale_resolution_down_by = 1;
  parameters.encodings[0].active = false;
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = false;
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Ensure no media is flowing (1 second should be enough).
  Thread::Current()->SleepMs(1000);
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(3u));
  EXPECT_EQ(*outbound_rtps[0]->bytes_sent, 0u);
  EXPECT_EQ(*outbound_rtps[1]->bytes_sent, 0u);
  EXPECT_EQ(*outbound_rtps[2]->bytes_sent, 0u);
}

TEST_F(PeerConnectionEncodingsIntegrationTest, VP9_TargetBitrate_LegacyL1T3) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);

  // In legacy SVC, disabling the bottom two layers encodings is interpreted as
  // disabling the bottom two spatial layers resulting in L1T3.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  parameters.encodings[0].active = false;
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = true;
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait until 720p L1T3 has ramped up to 720p. It may take additional time
  // for the target bitrate to reach its maximum.
  ASSERT_THAT(
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(Contains(AllOf(
                        RidIs("f"), ScalabilityModeIs("L1T3"), HeightIs(720)))),
                    {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());

  // The target bitrate typically reaches `kVp9ExpectedMaxBitrateForL1T3`
  // in a short period of time. However to reduce risk of flakiness in bot
  // environments, this test only fails if we we exceed the expected target.
  Thread::Current()->SleepMs(1000);
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(1));
  DataRate target_bitrate =
      DataRate::BitsPerSec(*outbound_rtps[0]->target_bitrate);
  EXPECT_LE(target_bitrate.kbps(), kVp9ExpectedMaxBitrateForL1T3.kbps());
}

// Test coverage for https://crbug.com/1455039.
TEST_F(PeerConnectionEncodingsIntegrationTest, VP9_TargetBitrate_StandardL1T3) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9");
  transceiver->SetCodecPreferences(codecs);

  // With standard APIs, L1T3 is explicitly specified and the encodings refers
  // to the RTP streams, not the spatial layers. The end result should be
  // equivalent to the legacy L1T3 case.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  parameters.encodings[0].active = true;
  parameters.encodings[0].scale_resolution_down_by = 1.0;
  parameters.encodings[0].scalability_mode = "L1T3";
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = false;
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait until 720p L1T3 has ramped up to 720p. It may take additional time
  // for the target bitrate to reach its maximum.
  ASSERT_THAT(
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(Contains(AllOf(
                        RidIs("f"), ScalabilityModeIs("L1T3"), HeightIs(720)))),
                    {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());

  // The target bitrate typically reaches `kVp9ExpectedMaxBitrateForL1T3`
  // in a short period of time. However to reduce risk of flakiness in bot
  // environments, this test only fails if we we exceed the expected target.
  Thread::Current()->SleepMs(1000);
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(3));
  auto* outbound_rtp = FindOutboundRtpByRid(outbound_rtps, "f");
  ASSERT_TRUE(outbound_rtp);
  DataRate target_bitrate = DataRate::BitsPerSec(*outbound_rtp->target_bitrate);
  EXPECT_LE(target_bitrate.kbps(), kVp9ExpectedMaxBitrateForL1T3.kbps());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       SimulcastProducesUniqueSsrcAndRtxSsrcsWhenConnected) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP8");
  transceiver->SetCodecPreferences(codecs);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait until media is flowing on all three layers.
  // Ramp up time is needed before all three layers are sending.
  auto stats = GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(3u),
                             {.timeout = kLongTimeoutForRampingUp});
  ASSERT_THAT(stats, IsRtcOk());
  // Verify SSRCs and RTX SSRCs.
  scoped_refptr<const RTCStatsReport> report = stats.MoveValue();
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(3u));

  std::set<uint32_t> ssrcs;
  std::set<uint32_t> rtx_ssrcs;
  for (const auto& outbound_rtp : outbound_rtps) {
    ASSERT_TRUE(outbound_rtp->ssrc.has_value());
    ASSERT_TRUE(outbound_rtp->rtx_ssrc.has_value());
    ssrcs.insert(*outbound_rtp->ssrc);
    rtx_ssrcs.insert(*outbound_rtp->rtx_ssrc);
  }
  EXPECT_EQ(ssrcs.size(), 3u);
  EXPECT_EQ(rtx_ssrcs.size(), 3u);
}

// Similar to the above test, but we never exchange ICE candidates such that
// simulcast never has a chance to "ramp up". Despite this, we should see one
// outbound-rtp per encoding.
TEST_F(PeerConnectionEncodingsIntegrationTest,
       SimulcastProducesUniqueSsrcAndRtxSsrcsWhenDisconnected) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);

  // Inactive the middle layer.
  auto sender = transceiver->sender();
  auto parameters = sender->GetParameters();
  parameters.encodings[0].active = true;
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = true;
  EXPECT_TRUE(sender->SetParameters(parameters).ok());

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);

  // We have three outbound-rtps.
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_EQ(outbound_rtps.size(), 3u);
  // SSRC and RTX is unique.
  std::set<uint32_t> ssrcs;
  std::set<uint32_t> rtx_ssrcs;
  for (const auto& outbound_rtp : outbound_rtps) {
    ASSERT_TRUE(outbound_rtp->ssrc.has_value());
    ASSERT_TRUE(outbound_rtp->rtx_ssrc.has_value());
    ssrcs.insert(*outbound_rtp->ssrc);
    rtx_ssrcs.insert(*outbound_rtp->rtx_ssrc);
  }
  EXPECT_EQ(ssrcs.size(), 3u);
  EXPECT_EQ(rtx_ssrcs.size(), 3u);
  // RIDs and active are set.
  auto outbound_rtp_by_rid = GetOutboundRtpStreamStatsByRid(report);
  EXPECT_THAT(
      outbound_rtp_by_rid,
      UnorderedElementsAre(Pair("q", Active()), Pair("h", Not(Active())),
                           Pair("f", Active())));
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParameterCodecIsEmptyWhenCreatedAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::AUDIO);
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();
  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  EXPECT_FALSE(parameters.encodings[0].codec.has_value());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParameterCodecIsEmptyWhenCreatedVideo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO);
  scoped_refptr<RtpTransceiverInterface> video_transceiver =
      transceiver_or_error.MoveValue();
  RtpParameters parameters = video_transceiver->sender()->GetParameters();
  EXPECT_FALSE(parameters.encodings[0].codec.has_value());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParameterCodecIsSetByAddTransceiverAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  scoped_refptr<MediaStreamInterface> stream = local_pc_wrapper->GetUserMedia(
      /*audio=*/true, {}, /*video=*/false, {});
  scoped_refptr<AudioTrackInterface> track = stream->GetAudioTracks()[0];

  std::optional<RtpCodecCapability> pcmu =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::AUDIO, "pcmu");
  ASSERT_TRUE(pcmu);

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.codec = pcmu;
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(track, init);
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();
  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  EXPECT_EQ(*parameters.encodings[0].codec, *pcmu);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  ASSERT_TRUE(local_pc_wrapper->WaitForConnection());
  ASSERT_TRUE(remote_pc_wrapper->WaitForConnection());

  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_EQ(outbound_rtps.size(), 1u);
  std::string codec_name = GetCurrentCodecMimeType(report, *outbound_rtps[0]);
  EXPECT_STRCASEEQ(("audio/" + pcmu->name).c_str(), codec_name.c_str());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParameterCodecIsSetByAddTransceiverVideo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  scoped_refptr<MediaStreamInterface> stream = local_pc_wrapper->GetUserMedia(
      /*audio=*/false, {}, /*video=*/true, {.width = 1280, .height = 720});
  scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];

  std::optional<RtpCodecCapability> vp9 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp9");
  ASSERT_TRUE(vp9);

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.codec = vp9;
  encoding_parameters.scalability_mode = "L3T3";
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(track, init);
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();
  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  EXPECT_EQ(*parameters.encodings[0].codec, *vp9);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  auto error_or_stats =
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(Contains(ScalabilityModeIs("L3T3"))));
  ASSERT_THAT(error_or_stats, IsRtcOk());
  scoped_refptr<const RTCStatsReport> report = error_or_stats.MoveValue();
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_EQ(outbound_rtps.size(), 1u);
  std::string codec_name = GetCurrentCodecMimeType(report, *outbound_rtps[0]);
  EXPECT_STRCASEEQ(("video/" + vp9->name).c_str(), codec_name.c_str());
  EXPECT_EQ(outbound_rtps[0]->scalability_mode.value(), "L3T3");
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParameterCodecIsSetBySetParametersBeforeNegotiationAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  scoped_refptr<MediaStreamInterface> stream = local_pc_wrapper->GetUserMedia(
      /*audio=*/true, {}, /*video=*/false, {});
  scoped_refptr<AudioTrackInterface> track = stream->GetAudioTracks()[0];

  std::optional<RtpCodecCapability> pcmu =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::AUDIO, "pcmu");

  auto transceiver_or_error = local_pc_wrapper->pc()->AddTransceiver(track);
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();
  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = pcmu;
  EXPECT_TRUE(audio_transceiver->sender()->SetParameters(parameters).ok());

  parameters = audio_transceiver->sender()->GetParameters();
  EXPECT_EQ(parameters.encodings[0].codec, pcmu);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_EQ(outbound_rtps.size(), 1u);
  std::string codec_name = GetCurrentCodecMimeType(report, *outbound_rtps[0]);
  EXPECT_STRCASEEQ(("audio/" + pcmu->name).c_str(), codec_name.c_str());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParameterCodecIsSetBySetParametersAfterNegotiationAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  scoped_refptr<MediaStreamInterface> stream = local_pc_wrapper->GetUserMedia(
      /*audio=*/true, {}, /*video=*/false, {});
  scoped_refptr<AudioTrackInterface> track = stream->GetAudioTracks()[0];

  std::optional<RtpCodecCapability> pcmu =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::AUDIO, "pcmu");

  auto transceiver_or_error = local_pc_wrapper->pc()->AddTransceiver(track);
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_EQ(outbound_rtps.size(), 1u);
  std::string codec_name = GetCurrentCodecMimeType(report, *outbound_rtps[0]);
  EXPECT_STRCASENE(("audio/" + pcmu->name).c_str(), codec_name.c_str());
  std::string last_codec_id = outbound_rtps[0]->codec_id.value();

  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = pcmu;
  EXPECT_TRUE(audio_transceiver->sender()->SetParameters(parameters).ok());

  parameters = audio_transceiver->sender()->GetParameters();
  EXPECT_EQ(parameters.encodings[0].codec, pcmu);

  auto error_or_stats =
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(Contains(CodecIs(Ne(last_codec_id)))));
  ASSERT_THAT(error_or_stats, IsRtcOk());
  report = error_or_stats.MoveValue();
  outbound_rtps = report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_EQ(outbound_rtps.size(), 1u);
  codec_name = GetCurrentCodecMimeType(report, *outbound_rtps[0]);
  EXPECT_STRCASEEQ(("audio/" + pcmu->name).c_str(), codec_name.c_str());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParameterCodecIsSetBySetParametersBeforeNegotiationVideo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  scoped_refptr<MediaStreamInterface> stream = local_pc_wrapper->GetUserMedia(
      /*audio=*/false, {}, /*video=*/true, {.width = 1280, .height = 720});
  scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];

  std::optional<RtpCodecCapability> vp9 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp9");

  auto transceiver_or_error = local_pc_wrapper->pc()->AddTransceiver(track);
  scoped_refptr<RtpTransceiverInterface> video_transceiver =
      transceiver_or_error.MoveValue();
  RtpParameters parameters = video_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = vp9;
  parameters.encodings[0].scalability_mode = "L3T3";
  EXPECT_TRUE(video_transceiver->sender()->SetParameters(parameters).ok());

  parameters = video_transceiver->sender()->GetParameters();
  EXPECT_EQ(parameters.encodings[0].codec, vp9);
  EXPECT_EQ(parameters.encodings[0].scalability_mode, "L3T3");

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  auto error_or_stats = GetStatsUntil(
      local_pc_wrapper, OutboundRtpStatsAre(Contains(AllOf(
                            ScalabilityModeIs("L3T3"), CodecIs(Ne(""))))));
  ASSERT_THAT(error_or_stats, IsRtcOk());
  scoped_refptr<const RTCStatsReport> report = error_or_stats.MoveValue();
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_EQ(outbound_rtps.size(), 1u);
  std::string codec_name = GetCurrentCodecMimeType(report, *outbound_rtps[0]);
  EXPECT_STRCASEEQ(("video/" + vp9->name).c_str(), codec_name.c_str());
  EXPECT_EQ(outbound_rtps[0]->scalability_mode.value_or(""), "L3T3");
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParameterCodecIsSetBySetParametersAfterNegotiationVideo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  scoped_refptr<MediaStreamInterface> stream = local_pc_wrapper->GetUserMedia(
      /*audio=*/false, {}, /*video=*/true, {.width = 1280, .height = 720});
  scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];

  std::optional<RtpCodecCapability> vp9 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp9");

  auto transceiver_or_error = local_pc_wrapper->pc()->AddTransceiver(track);
  scoped_refptr<RtpTransceiverInterface> video_transceiver =
      transceiver_or_error.MoveValue();

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_EQ(outbound_rtps.size(), 1u);
  std::string codec_name = GetCurrentCodecMimeType(report, *outbound_rtps[0]);
  EXPECT_STRCASENE(("audio/" + vp9->name).c_str(), codec_name.c_str());
  std::string last_codec_id = outbound_rtps[0]->codec_id.value();

  RtpParameters parameters = video_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = vp9;
  parameters.encodings[0].scalability_mode = "L3T3";
  EXPECT_TRUE(video_transceiver->sender()->SetParameters(parameters).ok());

  parameters = video_transceiver->sender()->GetParameters();
  EXPECT_EQ(parameters.encodings[0].codec, vp9);
  EXPECT_EQ(parameters.encodings[0].scalability_mode, "L3T3");

  auto error_or_stats = GetStatsUntil(
      local_pc_wrapper,
      OutboundRtpStatsAre(Contains(
          AllOf(ScalabilityModeIs("L3T3"), CodecIs(Ne(last_codec_id))))));
  ASSERT_THAT(error_or_stats, IsRtcOk());
  report = error_or_stats.MoveValue();
  outbound_rtps = report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_EQ(outbound_rtps.size(), 1u);
  codec_name = GetCurrentCodecMimeType(report, *outbound_rtps[0]);
  EXPECT_STRCASEEQ(("video/" + vp9->name).c_str(), codec_name.c_str());
  EXPECT_EQ(outbound_rtps[0]->scalability_mode.value(), "L3T3");
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       AddTransceiverRejectsUnknownCodecParameterAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();

  RtpCodec dummy_codec;
  dummy_codec.kind = MediaType::AUDIO;
  dummy_codec.name = "FOOBAR";
  dummy_codec.clock_rate = 90000;
  dummy_codec.num_channels = 2;

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.codec = dummy_codec;
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::AUDIO, init);
  EXPECT_FALSE(transceiver_or_error.ok());
  EXPECT_EQ(transceiver_or_error.error().type(),
            RTCErrorType::UNSUPPORTED_OPERATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       AddTransceiverRejectsUnknownCodecParameterVideo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();

  RtpCodec dummy_codec;
  dummy_codec.kind = MediaType::VIDEO;
  dummy_codec.name = "FOOBAR";
  dummy_codec.clock_rate = 90000;

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.codec = dummy_codec;
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO, init);
  EXPECT_FALSE(transceiver_or_error.ok());
  EXPECT_EQ(transceiver_or_error.error().type(),
            RTCErrorType::UNSUPPORTED_OPERATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       SetParametersRejectsUnknownCodecParameterAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();

  RtpCodec dummy_codec;
  dummy_codec.kind = MediaType::AUDIO;
  dummy_codec.name = "FOOBAR";
  dummy_codec.clock_rate = 90000;
  dummy_codec.num_channels = 2;

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::AUDIO);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();

  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = dummy_codec;
  RTCError error = audio_transceiver->sender()->SetParameters(parameters);
  EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       SetParametersRejectsUnknownCodecParameterVideo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();

  RtpCodec dummy_codec;
  dummy_codec.kind = MediaType::VIDEO;
  dummy_codec.name = "FOOBAR";
  dummy_codec.clock_rate = 90000;

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> video_transceiver =
      transceiver_or_error.MoveValue();

  RtpParameters parameters = video_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = dummy_codec;
  RTCError error = video_transceiver->sender()->SetParameters(parameters);
  EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       SetParametersRejectsNonNegotiatedCodecParameterAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::optional<RtpCodecCapability> opus =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::AUDIO, "opus");
  ASSERT_TRUE(opus);

  std::vector<RtpCodecCapability> not_opus_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::AUDIO)
          .codecs;
  std::erase_if(not_opus_codecs, [&](const auto& codec) {
    return absl::EqualsIgnoreCase(codec.name, opus->name);
  });

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::AUDIO);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();
  ASSERT_TRUE(audio_transceiver->SetCodecPreferences(not_opus_codecs).ok());

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = opus;
  RTCError error = audio_transceiver->sender()->SetParameters(parameters);
  EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       SetParametersRejectsNonRemotelyNegotiatedCodecParameterAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::optional<RtpCodecCapability> opus =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::AUDIO, "opus");
  ASSERT_TRUE(opus);

  std::vector<RtpCodecCapability> not_opus_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::AUDIO)
          .codecs;
  std::erase_if(not_opus_codecs, [&](const auto& codec) {
    return absl::EqualsIgnoreCase(codec.name, opus->name);
  });

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::AUDIO);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();

  // Negotiation, create offer and apply it
  std::unique_ptr<SessionDescriptionInterface> offer =
      CreateOffer(local_pc_wrapper);
  scoped_refptr<MockSetSessionDescriptionObserver> p1 =
      SetLocalDescription(local_pc_wrapper, offer.get());
  scoped_refptr<MockSetSessionDescriptionObserver> p2 =
      SetRemoteDescription(remote_pc_wrapper, offer.get());
  EXPECT_TRUE(Await({p1, p2}));

  // Update the remote transceiver to reject Opus
  std::vector<scoped_refptr<RtpTransceiverInterface>> remote_transceivers =
      remote_pc_wrapper->pc()->GetTransceivers();
  ASSERT_TRUE(!remote_transceivers.empty());
  scoped_refptr<RtpTransceiverInterface> remote_audio_transceiver =
      remote_transceivers[0];
  ASSERT_TRUE(
      remote_audio_transceiver->SetCodecPreferences(not_opus_codecs).ok());

  // Create answer and apply it
  std::unique_ptr<SessionDescriptionInterface> answer =
      CreateAnswer(remote_pc_wrapper);
  p1 = SetLocalDescription(remote_pc_wrapper, answer.get());
  p2 = SetRemoteDescription(local_pc_wrapper, answer.get());
  EXPECT_TRUE(Await({p1, p2}));

  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = opus;
  RTCError error = audio_transceiver->sender()->SetParameters(parameters);
  EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

// Test coverage for https://crbug.com/webrtc/391340599.
// Some web apps add non-standard FMTP parameters to video codecs and because
// they get successfully negotiated due to being ignored by SDP rules, they show
// up in GetParameters().codecs. Using SetParameters() with such codecs should
// still work.
TEST_F(PeerConnectionEncodingsIntegrationTest,
       SetParametersAcceptsMungedCodecFromGetParameters) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> video_transceiver =
      transceiver_or_error.MoveValue();

  std::unique_ptr<SessionDescriptionInterface> offer =
      CreateOffer(local_pc_wrapper);
  // Munge a new parameter for VP8 in the offer.
  auto* mcd = offer->description()->contents()[0].media_description();
  ASSERT_THAT(mcd, NotNull());
  std::vector<Codec> codecs = mcd->codecs();
  ASSERT_THAT(codecs, Contains(Field(&Codec::name, "VP8")));
  auto vp8_codec = absl::c_find_if(
      codecs, [](const Codec& codec) { return codec.name == "VP8"; });
  vp8_codec->params.emplace("non-standard-param", "true");
  mcd->set_codecs(codecs);

  scoped_refptr<MockSetSessionDescriptionObserver> p1 =
      SetLocalDescription(local_pc_wrapper, offer.get());
  scoped_refptr<MockSetSessionDescriptionObserver> p2 =
      SetRemoteDescription(remote_pc_wrapper, offer.get());
  EXPECT_TRUE(Await({p1, p2}));

  // Create answer and apply it
  std::unique_ptr<SessionDescriptionInterface> answer =
      CreateAnswer(remote_pc_wrapper);
  mcd = answer->description()->contents()[0].media_description();
  ASSERT_THAT(mcd, NotNull());
  codecs = mcd->codecs();
  ASSERT_THAT(codecs, Contains(Field(&Codec::name, "VP8")));
  vp8_codec = absl::c_find_if(
      codecs, [](const Codec& codec) { return codec.name == "VP8"; });
  vp8_codec->params.emplace("non-standard-param", "true");
  mcd->set_codecs(codecs);
  p1 = SetLocalDescription(remote_pc_wrapper, answer.get());
  p2 = SetRemoteDescription(local_pc_wrapper, answer.get());
  EXPECT_TRUE(Await({p1, p2}));

  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  RtpParameters parameters = video_transceiver->sender()->GetParameters();
  auto it = absl::c_find_if(
      parameters.codecs, [](const auto& codec) { return codec.name == "VP8"; });
  ASSERT_NE(it, parameters.codecs.end());
  RtpCodecParameters& vp8_codec_from_parameters = *it;
  EXPECT_THAT(vp8_codec_from_parameters.parameters,
              Contains(Pair("non-standard-param", "true")));
  parameters.encodings[0].codec = vp8_codec_from_parameters;

  EXPECT_THAT(video_transceiver->sender()->SetParameters(parameters),
              IsRtcOk());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       SetParametersRejectsNonNegotiatedCodecParameterVideo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::optional<RtpCodecCapability> vp8 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp8");
  ASSERT_TRUE(vp8);

  std::vector<RtpCodecCapability> not_vp8_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::VIDEO)
          .codecs;
  std::erase_if(not_vp8_codecs, [&](const auto& codec) {
    return absl::EqualsIgnoreCase(codec.name, vp8->name);
  });

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> video_transceiver =
      transceiver_or_error.MoveValue();
  ASSERT_TRUE(video_transceiver->SetCodecPreferences(not_vp8_codecs).ok());

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  RtpParameters parameters = video_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = vp8;
  RTCError error = video_transceiver->sender()->SetParameters(parameters);
  EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       SetParametersRejectsNonRemotelyNegotiatedCodecParameterVideo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::optional<RtpCodecCapability> vp8 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp8");
  ASSERT_TRUE(vp8);

  std::vector<RtpCodecCapability> not_vp8_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::VIDEO)
          .codecs;
  std::erase_if(not_vp8_codecs, [&](const auto& codec) {
    return absl::EqualsIgnoreCase(codec.name, vp8->name);
  });

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> video_transceiver =
      transceiver_or_error.MoveValue();

  // Negotiation, create offer and apply it
  std::unique_ptr<SessionDescriptionInterface> offer =
      CreateOffer(local_pc_wrapper);
  scoped_refptr<MockSetSessionDescriptionObserver> p1 =
      SetLocalDescription(local_pc_wrapper, offer.get());
  scoped_refptr<MockSetSessionDescriptionObserver> p2 =
      SetRemoteDescription(remote_pc_wrapper, offer.get());
  EXPECT_TRUE(Await({p1, p2}));

  // Update the remote transceiver to reject VP8
  std::vector<scoped_refptr<RtpTransceiverInterface>> remote_transceivers =
      remote_pc_wrapper->pc()->GetTransceivers();
  ASSERT_TRUE(!remote_transceivers.empty());
  scoped_refptr<RtpTransceiverInterface> remote_video_transceiver =
      remote_transceivers[0];
  ASSERT_TRUE(
      remote_video_transceiver->SetCodecPreferences(not_vp8_codecs).ok());

  // Create answer and apply it
  std::unique_ptr<SessionDescriptionInterface> answer =
      CreateAnswer(remote_pc_wrapper);
  p1 = SetLocalDescription(remote_pc_wrapper, answer.get());
  p2 = SetRemoteDescription(local_pc_wrapper, answer.get());
  EXPECT_TRUE(Await({p1, p2}));

  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  RtpParameters parameters = video_transceiver->sender()->GetParameters();
  parameters.encodings[0].codec = vp8;
  RTCError error = video_transceiver->sender()->SetParameters(parameters);
  EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParametersCodecRemovedAfterNegotiationAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::optional<RtpCodecCapability> opus =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::AUDIO, "opus");
  ASSERT_TRUE(opus);

  std::vector<RtpCodecCapability> not_opus_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::AUDIO)
          .codecs;
  std::erase_if(not_opus_codecs, [&](const auto& codec) {
    return absl::EqualsIgnoreCase(codec.name, opus->name);
  });

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.codec = opus;
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::AUDIO, init);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  EXPECT_EQ(parameters.encodings[0].codec, opus);

  ASSERT_TRUE(audio_transceiver->SetCodecPreferences(not_opus_codecs).ok());
  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);

  parameters = audio_transceiver->sender()->GetParameters();
  EXPECT_FALSE(parameters.encodings[0].codec);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParametersRedEnabledBeforeNegotiationAudio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<RtpCodecCapability> send_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::AUDIO)
          .codecs;

  std::optional<RtpCodecCapability> opus =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::AUDIO, "opus");
  ASSERT_TRUE(opus);

  std::optional<RtpCodecCapability> red =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::AUDIO, "red");
  ASSERT_TRUE(red);

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.codec = opus;
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::AUDIO, init);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> audio_transceiver =
      transceiver_or_error.MoveValue();

  // Preferring RED over Opus should enable RED with Opus encoding.
  send_codecs[0] = red.value();
  send_codecs[1] = opus.value();

  ASSERT_TRUE(audio_transceiver->SetCodecPreferences(send_codecs).ok());
  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  RtpParameters parameters = audio_transceiver->sender()->GetParameters();
  EXPECT_EQ(parameters.encodings[0].codec, opus);
  EXPECT_EQ(parameters.codecs[0].name, red->name);

  // Check that it's possible to switch back to Opus without RED.
  send_codecs[0] = opus.value();
  send_codecs[1] = red.value();

  ASSERT_TRUE(audio_transceiver->SetCodecPreferences(send_codecs).ok());
  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);

  parameters = audio_transceiver->sender()->GetParameters();
  EXPECT_EQ(parameters.encodings[0].codec, opus);
  EXPECT_EQ(parameters.codecs[0].name, opus->name);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       SetParametersRejectsScalabilityModeForSelectedCodec) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();

  std::optional<RtpCodecCapability> vp8 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp8");
  ASSERT_TRUE(vp8);

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.codec = vp8;
  encoding_parameters.scalability_mode = "L1T3";
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO, init);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> video_transceiver =
      transceiver_or_error.MoveValue();

  RtpParameters parameters = video_transceiver->sender()->GetParameters();
  parameters.encodings[0].scalability_mode = "L3T3";
  RTCError error = video_transceiver->sender()->SetParameters(parameters);
  EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       EncodingParametersCodecRemovedByNegotiationVideo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::optional<RtpCodecCapability> vp8 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp8");
  ASSERT_TRUE(vp8);

  std::vector<RtpCodecCapability> not_vp8_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::VIDEO)
          .codecs;
  std::erase_if(not_vp8_codecs, [&](const auto& codec) {
    return absl::EqualsIgnoreCase(codec.name, vp8->name);
  });

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.rid = "h";
  encoding_parameters.codec = vp8;
  encoding_parameters.scale_resolution_down_by = 2;
  init.send_encodings.push_back(encoding_parameters);
  encoding_parameters.rid = "f";
  encoding_parameters.scale_resolution_down_by = 1;
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO, init);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> video_transceiver =
      transceiver_or_error.MoveValue();

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  RtpParameters parameters = video_transceiver->sender()->GetParameters();
  ASSERT_EQ(parameters.encodings.size(), 2u);
  EXPECT_EQ(parameters.encodings[0].codec, vp8);
  EXPECT_EQ(parameters.encodings[1].codec, vp8);

  ASSERT_TRUE(video_transceiver->SetCodecPreferences(not_vp8_codecs).ok());
  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);

  parameters = video_transceiver->sender()->GetParameters();
  EXPECT_FALSE(parameters.encodings[0].codec);
  EXPECT_FALSE(parameters.encodings[1].codec);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       AddTransceiverRejectsMixedCodecSimulcast) {
  // Mixed Codec Simulcast is not yet supported, so we ensure that we reject
  // such parameters.
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::optional<RtpCodecCapability> vp8 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp8");
  ASSERT_TRUE(vp8);
  std::optional<RtpCodecCapability> vp9 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp9");
  ASSERT_TRUE(vp9);

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.rid = "h";
  encoding_parameters.codec = vp8;
  encoding_parameters.scale_resolution_down_by = 2;
  init.send_encodings.push_back(encoding_parameters);
  encoding_parameters.rid = "f";
  encoding_parameters.codec = vp9;
  encoding_parameters.scale_resolution_down_by = 1;
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO, init);
  ASSERT_FALSE(transceiver_or_error.ok());
  EXPECT_EQ(transceiver_or_error.error().type(),
            RTCErrorType::UNSUPPORTED_OPERATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       AddTransceiverAcceptsMixedCodecSimulcast) {
  // Enable WIP mixed codec simulcast support
  std::string field_trials = "WebRTC-MixedCodecSimulcast/Enabled/";
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper =
      CreatePc(field_trials);
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper =
      CreatePc(field_trials);
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::optional<RtpCodecCapability> vp8 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp8");
  ASSERT_TRUE(vp8);
  std::optional<RtpCodecCapability> vp9 =
      local_pc_wrapper->FindFirstSendCodecWithName(MediaType::VIDEO, "vp9");
  ASSERT_TRUE(vp9);

  RtpTransceiverInit init;
  init.direction = RtpTransceiverDirection::kSendOnly;
  RtpEncodingParameters encoding_parameters;
  encoding_parameters.rid = "h";
  encoding_parameters.codec = vp8;
  encoding_parameters.scale_resolution_down_by = 2;
  init.send_encodings.push_back(encoding_parameters);
  encoding_parameters.rid = "f";
  encoding_parameters.codec = vp9;
  encoding_parameters.scale_resolution_down_by = 1;
  init.send_encodings.push_back(encoding_parameters);

  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO, init);
  ASSERT_TRUE(transceiver_or_error.ok());
}

TEST_F(PeerConnectionEncodingsIntegrationTest, ScaleToParameterChecking) {
  scoped_refptr<PeerConnectionTestWrapper> pc_wrapper = CreatePc();

  // AddTransceiver: If `scale_resolution_down_to` is specified on any encoding
  // it must be specified on all encodings.
  RtpTransceiverInit init;
  RtpEncodingParameters encoding;
  encoding.scale_resolution_down_to = std::nullopt;
  init.send_encodings.push_back(encoding);
  encoding.scale_resolution_down_to = {.width = 1280, .height = 720};
  init.send_encodings.push_back(encoding);
  auto transceiver_or_error =
      pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO, init);
  EXPECT_FALSE(transceiver_or_error.ok());
  EXPECT_EQ(transceiver_or_error.error().type(),
            RTCErrorType::UNSUPPORTED_OPERATION);

  // AddTransceiver: Width and height must not be zero.
  init.send_encodings[0].scale_resolution_down_to = {.width = 1280,
                                                     .height = 0};
  init.send_encodings[1].scale_resolution_down_to = {.width = 0, .height = 720};
  transceiver_or_error =
      pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO, init);
  EXPECT_FALSE(transceiver_or_error.ok());
  EXPECT_EQ(transceiver_or_error.error().type(),
            RTCErrorType::UNSUPPORTED_OPERATION);

  // AddTransceiver: Specifying both `scale_resolution_down_to` and
  // `scale_resolution_down_by` is allowed (the latter is ignored).
  init.send_encodings[0].scale_resolution_down_to = {.width = 640,
                                                     .height = 480};
  init.send_encodings[0].scale_resolution_down_by = 1.0;
  init.send_encodings[1].scale_resolution_down_to = {.width = 1280,
                                                     .height = 720};
  init.send_encodings[1].scale_resolution_down_by = 2.0;
  transceiver_or_error =
      pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO, init);
  ASSERT_TRUE(transceiver_or_error.ok());

  // SetParameters: If `scale_resolution_down_to` is specified on any active
  // encoding it must be specified on all active encodings.
  auto sender = transceiver_or_error.value()->sender();
  auto parameters = sender->GetParameters();
  parameters.encodings[0].scale_resolution_down_to = {.width = 640,
                                                      .height = 480};
  parameters.encodings[1].scale_resolution_down_to = std::nullopt;
  auto error = sender->SetParameters(parameters);
  EXPECT_FALSE(error.ok());
  EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
  // But it's OK not to specify `scale_resolution_down_to` on an inactive
  // encoding.
  parameters = sender->GetParameters();
  parameters.encodings[0].scale_resolution_down_to = {.width = 640,
                                                      .height = 480};
  parameters.encodings[1].active = false;
  parameters.encodings[1].scale_resolution_down_to = std::nullopt;
  error = sender->SetParameters(parameters);
  EXPECT_TRUE(error.ok());

  // SetParameters: Width and height must not be zero.
  sender = transceiver_or_error.value()->sender();
  parameters = sender->GetParameters();
  parameters.encodings[0].scale_resolution_down_to = {.width = 1280,
                                                      .height = 0};
  parameters.encodings[1].active = true;
  parameters.encodings[1].scale_resolution_down_to = {.width = 0,
                                                      .height = 720};
  error = sender->SetParameters(parameters);
  EXPECT_FALSE(error.ok());
  EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);

  // SetParameters: Specifying both `scale_resolution_down_to` and
  // `scale_resolution_down_by` is allowed (the latter is ignored).
  parameters = sender->GetParameters();
  parameters.encodings[0].scale_resolution_down_to = {.width = 640,
                                                      .height = 480};
  parameters.encodings[0].scale_resolution_down_by = 2.0;
  parameters.encodings[1].scale_resolution_down_to = {.width = 1280,
                                                      .height = 720};
  parameters.encodings[1].scale_resolution_down_by = 1.0;
  error = sender->SetParameters(parameters);
  EXPECT_TRUE(error.ok());
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
       ScaleResolutionDownByIsIgnoredWhenScaleToIsSpecified) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();

  scoped_refptr<MediaStreamInterface> stream = local_pc_wrapper->GetUserMedia(
      /*audio=*/false, {}, /*video=*/true, {.width = 640, .height = 360});
  scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];

  // Configure contradicting scaling factors (180p vs 360p).
  RtpTransceiverInit init;
  RtpEncodingParameters encoding;
  encoding.scale_resolution_down_by = 2.0;
  encoding.scale_resolution_down_to = {.width = 640, .height = 360};
  init.send_encodings.push_back(encoding);
  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(track, init);

  // Negotiate singlecast.
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);
  Negotiate(local_pc_wrapper, remote_pc_wrapper);

  // Confirm 640x360 is sent.
  // If `scale_resolution_down_by` was not ignored we would never ramp up to
  // full resolution.
  EXPECT_THAT(
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(ElementsAre(ResolutionIs(640, 360))),
                    {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());
}

// Tests that use the standard path (specifying both `scalability_mode` and
// `scale_resolution_down_by` or `scale_resolution_down_to`) should pass for all
// codecs.
class PeerConnectionEncodingsIntegrationParameterizedTest
    : public PeerConnectionEncodingsIntegrationTest,
      public ::testing::WithParamInterface<std::string> {
 public:
  PeerConnectionEncodingsIntegrationParameterizedTest()
      : codec_name_(GetParam()), mime_type_("video/" + codec_name_) {}

  // Work-around for the fact that whether or not AV1 is supported is not known
  // at compile-time so we have to skip tests early if missing.
  // TODO(https://crbug.com/webrtc/15011): Increase availability of AV1 or make
  // it possible to check support at compile-time.
  bool SkipTestDueToAv1Missing(
      scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper) {
    if (codec_name_ == "AV1" &&
        !HasReceiverVideoCodecCapability(local_pc_wrapper, "AV1")) {
      RTC_LOG(LS_WARNING) << "\n***\nAV1 is not available, skipping test.\n***";
      return true;
    }
    return false;
  }

 protected:
  const std::string codec_name_;  // E.g. "VP9"
  const std::string mime_type_;   // E.g. "video/VP9"
};

TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, AllLayersInactive) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "h", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);

  // Standard mode and all layers inactive.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].scalability_mode = "L1T3";
  parameters.encodings[0].scale_resolution_down_by = 1;
  parameters.encodings[0].active = false;
  parameters.encodings[1].active = false;
  parameters.encodings[2].active = false;
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Ensure no media is flowing (1 second should be enough).
  Thread::Current()->SleepMs(1000);
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(3u));
  EXPECT_EQ(*outbound_rtps[0]->bytes_sent, 0u);
  EXPECT_EQ(*outbound_rtps[1]->bytes_sent, 0u);
  EXPECT_EQ(*outbound_rtps[2]->bytes_sent, 0u);
}

// Configure 4:2:1 using `scale_resolution_down_by`.
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, Simulcast) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"q", "h", "f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);

  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].scalability_mode = "L1T3";
  parameters.encodings[0].scale_resolution_down_by = 4;
  parameters.encodings[1].scalability_mode = "L1T3";
  parameters.encodings[1].scale_resolution_down_by = 2;
  parameters.encodings[2].scalability_mode = "L1T3";
  parameters.encodings[2].scale_resolution_down_by = 1;
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // GetParameters() does not report any fallback.
  parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));

  EXPECT_TRUE(parameters.encodings[0].scalability_mode.has_value());
  EXPECT_THAT(parameters.encodings[0].scalability_mode,
              Optional(std::string("L1T3")));
  EXPECT_TRUE(parameters.encodings[1].scalability_mode.has_value());
  EXPECT_THAT(parameters.encodings[1].scalability_mode,
              Optional(std::string("L1T3")));
  EXPECT_TRUE(parameters.encodings[2].scalability_mode.has_value());
  EXPECT_THAT(parameters.encodings[2].scalability_mode,
              Optional(std::string("L1T3")));

  // Wait until media is flowing on all three layers.
  // Ramp up time is needed before all three layers are sending.
  auto error_or_report =
      GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(3u),
                    {.timeout = kLongTimeoutForRampingUp});
  ASSERT_THAT(error_or_report, IsRtcOk());
  // Verify codec and scalability mode.
  scoped_refptr<const RTCStatsReport> report = error_or_report.value();
  auto outbound_rtp_by_rid = GetOutboundRtpStreamStatsByRid(report);
  EXPECT_THAT(outbound_rtp_by_rid,
              UnorderedElementsAre(Pair("q", ResolutionIs(320, 180)),
                                   Pair("h", ResolutionIs(640, 360)),
                                   Pair("f", ResolutionIs(1280, 720))));
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(3u));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]),
              StrCaseEq(mime_type_));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[1]),
              StrCaseEq(mime_type_));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[2]),
              StrCaseEq(mime_type_));
  EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T3"));
  EXPECT_THAT(*outbound_rtps[1]->scalability_mode, StrEq("L1T3"));
  EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3"));
}

// Configure 4:2:1 using `scale_resolution_down_to`.
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
       SimulcastWithScaleTo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"q", "h", "f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);

  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].scalability_mode = "L1T3";
  parameters.encodings[0].scale_resolution_down_to = {.width = 320,
                                                      .height = 180};
  parameters.encodings[1].scalability_mode = "L1T3";
  parameters.encodings[1].scale_resolution_down_to = {.width = 640,
                                                      .height = 360};
  parameters.encodings[2].scalability_mode = "L1T3";
  parameters.encodings[2].scale_resolution_down_to = {.width = 1280,
                                                      .height = 720};
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // GetParameters() does not report any fallback.
  parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  EXPECT_THAT(parameters.encodings[0].scalability_mode,
              Optional(std::string("L1T3")));
  EXPECT_THAT(parameters.encodings[1].scalability_mode,
              Optional(std::string("L1T3")));
  EXPECT_THAT(parameters.encodings[2].scalability_mode,
              Optional(std::string("L1T3")));

  // Wait until media is flowing on all three layers.
  // Ramp up time is needed before all three layers are sending.
  auto error_or_report =
      GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(3u),
                    {.timeout = kLongTimeoutForRampingUp});
  ASSERT_THAT(error_or_report, IsRtcOk());
  // Verify codec and scalability mode.
  scoped_refptr<const RTCStatsReport> report = error_or_report.value();
  auto outbound_rtp_by_rid = GetOutboundRtpStreamStatsByRid(report);
  EXPECT_THAT(outbound_rtp_by_rid,
              UnorderedElementsAre(Pair("q", ResolutionIs(320, 180)),
                                   Pair("h", ResolutionIs(640, 360)),
                                   Pair("f", ResolutionIs(1280, 720))));
  // Verify codec and scalability mode.
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(3u));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]),
              StrCaseEq(mime_type_));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[1]),
              StrCaseEq(mime_type_));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[2]),
              StrCaseEq(mime_type_));
  EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T3"));
  EXPECT_THAT(*outbound_rtps[1]->scalability_mode, StrEq("L1T3"));
  EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3"));
}

// Simulcast starting in 720p 4:2:1 then changing to {180p, 360p, 540p} using
// the `scale_resolution_down_by` API.
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
       SimulcastScaleDownByNoLongerPowerOfTwo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"q", "h", "f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();

  // Configure {180p, 360p, 720p}.
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].scalability_mode = "L1T1";
  parameters.encodings[0].scale_resolution_down_by = 4.0;
  parameters.encodings[1].scalability_mode = "L1T1";
  parameters.encodings[1].scale_resolution_down_by = 2.0;
  parameters.encodings[2].scalability_mode = "L1T1";
  parameters.encodings[2].scale_resolution_down_by = 1.0;
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait for media to flow on all layers.
  // Needed repro step of https://crbug.com/webrtc/369654168: When the same
  // LibvpxVp9Encoder instance was used to first produce simulcast and later for
  // a single encoding, the previously used simulcast index (= 2) would still be
  // set when producing 180p since non-simulcast config does not reset this,
  // resulting in the 180p encoding freezing and the 540p encoding having double
  // frame rate and toggling between 180p and 540p in resolution.
  ASSERT_THAT(GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(3u),
                            {.timeout = kLongTimeoutForRampingUp}),
              IsRtcOk());

  // Configure {180p, 360p, 540p}.
  parameters = sender->GetParameters();
  parameters.encodings[0].scale_resolution_down_by = 4.0;
  parameters.encodings[1].scale_resolution_down_by = 2.0;
  parameters.encodings[2].scale_resolution_down_by = 1.333333;
  sender->SetParameters(parameters);

  // Wait for the new resolutions to be produced.
  auto encoding_resolutions_result =
      WaitUntil([&] { return GetStats(local_pc_wrapper); },
                OutboundRtpStatsAre(UnorderedElementsAre(
                    AllOf(RidIs("q"), ResolutionIs(320, 180)),
                    AllOf(RidIs("h"), ResolutionIs(640, 360)),
                    AllOf(RidIs("f"), ResolutionIs(960, 540)))),
                {.timeout = kLongTimeoutForRampingUp});
  ASSERT_THAT(encoding_resolutions_result, IsRtcOk());

  auto outbound_rtp_by_rid =
      GetOutboundRtpStreamStatsByRid(encoding_resolutions_result.value());
  ASSERT_THAT(outbound_rtp_by_rid,
              UnorderedElementsAre(Key("q"), Key("h"), Key("f")));

  // Ensure frames continue to be encoded post reconfiguration.
  uint64_t frames_encoded_q =
      outbound_rtp_by_rid.at("q").frames_encoded.value();
  uint64_t frames_encoded_h =
      outbound_rtp_by_rid.at("h").frames_encoded.value();
  uint64_t frames_encoded_f =
      outbound_rtp_by_rid.at("f").frames_encoded.value();
  EXPECT_THAT(
      GetStatsUntil(
          local_pc_wrapper,
          OutboundRtpStatsAre(UnorderedElementsAre(
              AllOf(RidIs("q"), FramesEncodedIs(Gt(frames_encoded_q))),
              AllOf(RidIs("h"), FramesEncodedIs(Gt(frames_encoded_h))),
              AllOf(RidIs("f"), FramesEncodedIs(Gt(frames_encoded_f))))),
          {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());
}

// Simulcast starting in 720p 4:2:1 then changing to {180p, 360p, 540p} using
// the `scale_resolution_down_to` API.
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
       SimulcastScaleToNoLongerPowerOfTwo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"q", "h", "f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();

  // Configure {180p, 360p, 720p}.
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[0].scalability_mode = "L1T1";
  parameters.encodings[0].scale_resolution_down_to = {.width = 320,
                                                      .height = 180};
  parameters.encodings[1].scalability_mode = "L1T1";
  parameters.encodings[1].scale_resolution_down_to = {.width = 640,
                                                      .height = 360};
  parameters.encodings[2].scalability_mode = "L1T1";
  parameters.encodings[2].scale_resolution_down_to = {.width = 1280,
                                                      .height = 720};
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait for media to flow on all layers.
  // Needed repro step of https://crbug.com/webrtc/369654168: When the same
  // LibvpxVp9Encoder instance was used to first produce simulcast and later for
  // a single encoding, the previously used simulcast index (= 2) would still be
  // set when producing 180p since non-simulcast config does not reset this,
  // resulting in the 180p encoding freezing and the 540p encoding having double
  // frame rate and toggling between 180p and 540p in resolution.
  ASSERT_THAT(GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(3u),
                            {.timeout = kLongTimeoutForRampingUp}),
              IsRtcOk());

  // Configure {180p, 360p, 540p}.
  parameters = sender->GetParameters();
  parameters.encodings[0].scale_resolution_down_to = {.width = 320,
                                                      .height = 180};
  parameters.encodings[1].scale_resolution_down_to = {.width = 640,
                                                      .height = 360};
  parameters.encodings[2].scale_resolution_down_to = {.width = 960,
                                                      .height = 540};
  sender->SetParameters(parameters);

  // Wait for the new resolutions to be produced.
  auto error_or_stats =
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(UnorderedElementsAre(
                        AllOf(RidIs("q"), ResolutionIs(320, 180)),
                        AllOf(RidIs("h"), ResolutionIs(640, 360)),
                        AllOf(RidIs("f"), ResolutionIs(960, 540)))),
                    {.timeout = kLongTimeoutForRampingUp});
  ASSERT_THAT(error_or_stats, IsRtcOk());

  auto outbound_rtp_by_rid =
      GetOutboundRtpStreamStatsByRid(error_or_stats.value());
  ASSERT_THAT(outbound_rtp_by_rid,
              UnorderedElementsAre(Pair("q", BytesSentIs(Ne(std::nullopt))),
                                   Pair("h", BytesSentIs(Ne(std::nullopt))),
                                   Pair("f", BytesSentIs(Ne(std::nullopt)))));

  // Ensure frames continue to be encoded post reconfiguration.
  EXPECT_THAT(
      GetStatsUntil(
          local_pc_wrapper,
          OutboundRtpStatsAre(UnorderedElementsAre(
              AllOf(RidIs("q"),
                    BytesSentIs(
                        Gt(outbound_rtp_by_rid.at("q").bytes_sent.value()))),
              AllOf(RidIs("h"),
                    BytesSentIs(
                        Gt(outbound_rtp_by_rid.at("h").bytes_sent.value()))),
              AllOf(RidIs("f"),
                    BytesSentIs(
                        Gt(outbound_rtp_by_rid.at("f").bytes_sent.value()))))),
          {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());
}

// The code path that disables layers based on resolution size should NOT run
// when `scale_resolution_down_to` is specified. (It shouldn't run in any case
// but that is an existing legacy code and non-compliance problem that we don't
// have to repeat here.)
TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
       LowResolutionSimulcastWithScaleTo) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"q", "h", "f"}, /*active=*/true);

  // Configure {20p,40p,80p} with 2:1 aspect ratio.
  RtpTransceiverInit init;
  RtpEncodingParameters encoding;
  encoding.scalability_mode = "L1T3";
  encoding.rid = "q";
  encoding.scale_resolution_down_to = {.width = 40, .height = 20};
  init.send_encodings.push_back(encoding);
  encoding.rid = "h";
  encoding.scale_resolution_down_to = {.width = 80, .height = 40};
  init.send_encodings.push_back(encoding);
  encoding.rid = "f";
  encoding.scale_resolution_down_to = {.width = 160, .height = 80};
  init.send_encodings.push_back(encoding);
  scoped_refptr<MediaStreamInterface> stream = local_pc_wrapper->GetUserMedia(
      /*audio=*/false, {}, /*video=*/true, {.width = 160, .height = 80});
  scoped_refptr<VideoTrackInterface> track = stream->GetVideoTracks()[0];
  auto transceiver_or_error =
      local_pc_wrapper->pc()->AddTransceiver(track, init);
  ASSERT_TRUE(transceiver_or_error.ok());
  scoped_refptr<RtpTransceiverInterface> transceiver =
      transceiver_or_error.value();

  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait for media to flow on all layers.
  ASSERT_THAT(GetStatsUntil(local_pc_wrapper, HasOutboundRtpBytesSent(3u)),
              IsRtcOk());
  // q=20p, h=40p, f=80p.
  EXPECT_THAT(GetStatsUntil(local_pc_wrapper,
                            OutboundRtpStatsAre(UnorderedElementsAre(
                                AllOf(RidIs("q"), ResolutionIs(40, 20)),
                                AllOf(RidIs("h"), ResolutionIs(80, 40)),
                                AllOf(RidIs("f"), ResolutionIs(160, 80)))),
                            {.timeout = kLongTimeoutForRampingUp}),
              IsRtcOk());
}

TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
       SimulcastEncodingStopWhenRtpEncodingChangeToInactive) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"q", "h", "f"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);

  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  ASSERT_EQ(parameters.encodings[0].rid, "q");
  parameters.encodings[0].scalability_mode = "L1T3";
  parameters.encodings[0].scale_resolution_down_by = 4;
  ASSERT_EQ(parameters.encodings[1].rid, "h");
  parameters.encodings[1].scalability_mode = "L1T3";
  parameters.encodings[1].scale_resolution_down_by = 2;
  ASSERT_EQ(parameters.encodings[2].rid, "f");
  parameters.encodings[2].scalability_mode = "L1T3";
  parameters.encodings[2].scale_resolution_down_by = 1;
  sender->SetParameters(parameters);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  ASSERT_THAT(GetStatsUntil(local_pc_wrapper,
                            OutboundRtpStatsAre(Contains(
                                AllOf(RidIs("f"), FramesEncodedIs(Gt(0))))),
                            {.timeout = kLongTimeoutForRampingUp}),
              IsRtcOk());

  // Switch higest layer to Inactive.
  parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(3));
  parameters.encodings[2].active = false;
  sender->SetParameters(parameters);
  auto error_or_stats = GetStatsUntil(
      local_pc_wrapper,
      OutboundRtpStatsAre(Contains(AllOf(RidIs("f"), Not(Active())))),
      {.timeout = kLongTimeoutForRampingUp});
  ASSERT_THAT(error_or_stats, IsRtcOk());

  auto outbound_rtp_by_rid =
      GetOutboundRtpStreamStatsByRid(error_or_stats.value());
  int encoded_frames_f = outbound_rtp_by_rid.at("f").frames_encoded.value();
  int encoded_frames_h = outbound_rtp_by_rid.at("h").frames_encoded.value();
  int encoded_frames_q = outbound_rtp_by_rid.at("q").frames_encoded.value();

  // Wait until the encoder has encoded another 10 frames on lower layers.
  ASSERT_THAT(
      GetStatsUntil(
          local_pc_wrapper,
          OutboundRtpStatsAre(UnorderedElementsAre(
              AllOf(RidIs("q"), FramesEncodedIs(Gt(encoded_frames_q + 10))),
              AllOf(RidIs("h"), FramesEncodedIs(Gt(encoded_frames_h + 10))),
              AllOf(RidIs("f"), FramesEncodedIs(Le(encoded_frames_f + 2))))),
          {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());
}

TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
       ScaleToDownscaleAndThenUpscale) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers = CreateLayers({"f"}, /*active=*/true);

  // This transceiver receives a 1280x720 source.
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Request 640x360, which is the same as scaling down by 2.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(1));
  parameters.encodings[0].scalability_mode = "L1T3";
  parameters.encodings[0].scale_resolution_down_to = {.width = 640,
                                                      .height = 360};
  sender->SetParameters(parameters);
  // Confirm 640x360 is sent.
  ASSERT_THAT(
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(ElementsAre(ResolutionIs(640, 360))),
                    {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());

  // Test coverage for https://crbug.com/webrtc/361477261:
  // Due initial frame dropping, OnFrameDroppedDueToSize() should have created
  // some resolution restrictions by now. With 720p input frame, restriction is
  // 540p which is not observable when sending 360p, but it prevents us from
  // immediately sending 720p. Restrictions will be lifted after a few seconds
  // (when good QP is reported by QualityScaler) and 720p should be sent. The
  // bug was not reconfiguring the encoder when restrictions were updated so the
  // restrictions at the time of the SetParameter() call were made indefinite.

  // Request the full 1280x720 resolution.
  parameters = sender->GetParameters();
  parameters.encodings[0].scale_resolution_down_to = {.width = 1280,
                                                      .height = 720};
  sender->SetParameters(parameters);
  // Confirm 1280x720 is sent.
  EXPECT_THAT(
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(ElementsAre(ResolutionIs(1280, 720))),
                    {.timeout = kLongTimeoutForRampingUp}),
      IsRtcOk());
}

TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
       ScaleToIsOrientationAgnostic) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers = CreateLayers({"f"}, /*active=*/true);

  // This transceiver receives a 1280x720 source.
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // 360x640 is the same as 640x360 due to orientation agnosticism.
  // The orientation is determined by the frame (1280x720): landscape.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(1));
  parameters.encodings[0].scale_resolution_down_to = {.width = 360,
                                                      .height = 640};
  sender->SetParameters(parameters);
  // Confirm 640x360 is sent.
  EXPECT_THAT(
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(ElementsAre(ResolutionIs(640, 360)))),
      IsRtcOk());
}

TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest,
       ScaleToMaintainsAspectRatio) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  if (SkipTestDueToAv1Missing(local_pc_wrapper)) {
    return;
  }
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers = CreateLayers({"f"}, /*active=*/true);

  // This transceiver receives a 1280x720 source.
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> codecs =
      GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_);
  transceiver->SetCodecPreferences(codecs);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Restrict height more than width, the scaling factor needed on height should
  // also be applied on the width in order to maintain the frame aspect ratio.
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();
  RtpParameters parameters = sender->GetParameters();
  ASSERT_THAT(parameters.encodings, SizeIs(1));
  parameters.encodings[0].scale_resolution_down_to = {.width = 1280,
                                                      .height = 360};
  sender->SetParameters(parameters);
  // Confirm 640x360 is sent.
  EXPECT_THAT(
      GetStatsUntil(local_pc_wrapper,
                    OutboundRtpStatsAre(ElementsAre(ResolutionIs(640, 360)))),
      IsRtcOk());
}

INSTANTIATE_TEST_SUITE_P(StandardPath,
                         PeerConnectionEncodingsIntegrationParameterizedTest,
                         ::testing::Values("VP8",
                                           "VP9",
#if defined(WEBRTC_USE_H264)
                                           "H264",
#endif  // defined(WEBRTC_USE_H264)
                                           "AV1"),
                         StringParamToString());

// These tests use fake encoders and decoders, allowing testing of codec
// preferences, SDP negotiation and get/setParamaters(). But because the codecs
// implementations are fake, these tests do not encode or decode any frames.
class PeerConnectionEncodingsFakeCodecsIntegrationTest
    : public PeerConnectionEncodingsIntegrationTest {
 public:
#ifdef RTC_ENABLE_H265
  scoped_refptr<PeerConnectionTestWrapper> CreatePcWithFakeH265(
      std::unique_ptr<FieldTrialsView> field_trials = nullptr) {
    std::unique_ptr<FakeWebRtcVideoEncoderFactory> video_encoder_factory =
        std::make_unique<FakeWebRtcVideoEncoderFactory>();
    video_encoder_factory->AddSupportedVideoCodec(
        SdpVideoFormat("H265",
                       {{"profile-id", "1"},
                        {"tier-flag", "0"},
                        {"level-id", "156"},
                        {"tx-mode", "SRST"}},
                       {ScalabilityMode::kL1T1}));
    std::unique_ptr<FakeWebRtcVideoDecoderFactory> video_decoder_factory =
        std::make_unique<FakeWebRtcVideoDecoderFactory>();
    video_decoder_factory->AddSupportedVideoCodecType("H265");
    auto pc_wrapper = make_ref_counted<PeerConnectionTestWrapper>(
        "pc", env_, &pss_, background_thread_.get(), background_thread_.get());
    pc_wrapper->CreatePc(
        {}, CreateBuiltinAudioEncoderFactory(),
        CreateBuiltinAudioDecoderFactory(), std::move(video_encoder_factory),
        std::move(video_decoder_factory), std::move(field_trials));
    return pc_wrapper;
  }
#endif  // RTC_ENABLE_H265

  // Creates a PC where we have H264 with one sendonly, one recvonly and one
  // sendrecv "profile-level-id". The sendrecv one is constrained baseline.
  scoped_refptr<PeerConnectionTestWrapper> CreatePcWithUnidirectionalH264(
      std::unique_ptr<FieldTrialsView> field_trials = nullptr) {
    std::unique_ptr<FakeWebRtcVideoEncoderFactory> video_encoder_factory =
        std::make_unique<FakeWebRtcVideoEncoderFactory>();
    SdpVideoFormat h264_constrained_baseline =
        SdpVideoFormat("H264",
                       {{"level-asymmetry-allowed", "1"},
                        {"packetization-mode", "1"},
                        {"profile-level-id", "42f00b"}},  // sendrecv
                       {ScalabilityMode::kL1T1});
    video_encoder_factory->AddSupportedVideoCodec(h264_constrained_baseline);
    video_encoder_factory->AddSupportedVideoCodec(
        SdpVideoFormat("H264",
                       {{"level-asymmetry-allowed", "1"},
                        {"packetization-mode", "1"},
                        {"profile-level-id", "640034"}},  // sendonly
                       {ScalabilityMode::kL1T1}));
    std::unique_ptr<FakeWebRtcVideoDecoderFactory> video_decoder_factory =
        std::make_unique<FakeWebRtcVideoDecoderFactory>();
    video_decoder_factory->AddSupportedVideoCodec(h264_constrained_baseline);
    video_decoder_factory->AddSupportedVideoCodec(
        SdpVideoFormat("H264",
                       {{"level-asymmetry-allowed", "1"},
                        {"packetization-mode", "1"},
                        {"profile-level-id", "f4001f"}},  // recvonly
                       {ScalabilityMode::kL1T1}));
    auto pc_wrapper = make_ref_counted<PeerConnectionTestWrapper>(
        "pc", env_, &pss_, background_thread_.get(), background_thread_.get());
    pc_wrapper->CreatePc(
        {}, CreateBuiltinAudioEncoderFactory(),
        CreateBuiltinAudioDecoderFactory(), std::move(video_encoder_factory),
        std::move(video_decoder_factory), std::move(field_trials));
    return pc_wrapper;
  }

  std::string LocalDescriptionStr(PeerConnectionTestWrapper* pc_wrapper) {
    const SessionDescriptionInterface* local_description =
        pc_wrapper->pc()->local_description();
    if (!local_description) {
      return "";
    }
    std::string str;
    if (!local_description->ToString(&str)) {
      return "";
    }
    return str;
  }
};

#ifdef RTC_ENABLE_H265
TEST_F(PeerConnectionEncodingsFakeCodecsIntegrationTest, H265Singlecast) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper =
      CreatePcWithFakeH265();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper =
      CreatePcWithFakeH265();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  scoped_refptr<RtpTransceiverInterface> transceiver =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO).MoveValue();
  std::vector<RtpCodecCapability> preferred_codecs =
      GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "H265");
  transceiver->SetCodecPreferences(preferred_codecs);

  Negotiate(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Verify codec.
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(1u));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]),
              StrCaseEq("video/H265"));
}

TEST_F(PeerConnectionEncodingsFakeCodecsIntegrationTest, H265Simulcast) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper =
      CreatePcWithFakeH265();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper =
      CreatePcWithFakeH265();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"q", "h", "f"}, /*active=*/true);

  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> preferred_codecs =
      GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "H265");
  transceiver->SetCodecPreferences(preferred_codecs);

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // Wait until all outbound RTPs exist.
  EXPECT_THAT(
      GetStatsUntil(local_pc_wrapper, OutboundRtpStatsAre(UnorderedElementsAre(
                                          AllOf(RidIs("q")), AllOf(RidIs("h")),
                                          AllOf(RidIs("f"))))),
      IsRtcOk());

  // Verify codec.
  scoped_refptr<const RTCStatsReport> report = GetStats(local_pc_wrapper);
  std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps =
      report->GetStatsOfType<RTCOutboundRtpStreamStats>();
  ASSERT_THAT(outbound_rtps, SizeIs(3u));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]),
              StrCaseEq("video/H265"));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[1]),
              StrCaseEq("video/H265"));
  EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[2]),
              StrCaseEq("video/H265"));
}

TEST_F(PeerConnectionEncodingsFakeCodecsIntegrationTest,
       H265SetParametersIgnoresLevelId) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper =
      CreatePcWithFakeH265();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper =
      CreatePcWithFakeH265();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers = CreateLayers({"f"}, /*active=*/true);

  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  std::vector<RtpCodecCapability> preferred_codecs =
      GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "H265");
  transceiver->SetCodecPreferences(preferred_codecs);
  scoped_refptr<RtpSenderInterface> sender = transceiver->sender();

  NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper);
  local_pc_wrapper->WaitForConnection();
  remote_pc_wrapper->WaitForConnection();

  // This includes non-codecs like rtx, red and flexfec too so we need to find
  // H265.
  std::vector<RtpCodecCapability> sender_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::VIDEO)
          .codecs;
  auto it = std::find_if(sender_codecs.begin(), sender_codecs.end(),
                         [](const RtpCodecCapability codec_capability) {
                           return codec_capability.name == "H265";
                         });
  ASSERT_NE(it, sender_codecs.end());
  RtpCodecCapability& h265_codec = *it;

  // SetParameters() without changing level-id.
  EXPECT_EQ(h265_codec.parameters["level-id"], "156");
  {
    RtpParameters parameters = sender->GetParameters();
    ASSERT_THAT(parameters.encodings, SizeIs(1));
    parameters.encodings[0].codec = h265_codec;
    ASSERT_THAT(sender->SetParameters(parameters), IsRtcOk());
  }
  // SetParameters() with a lower level-id.
  h265_codec.parameters["level-id"] = "30";
  {
    RtpParameters parameters = sender->GetParameters();
    ASSERT_THAT(parameters.encodings, SizeIs(1));
    parameters.encodings[0].codec = h265_codec;
    ASSERT_THAT(sender->SetParameters(parameters), IsRtcOk());
  }
  // SetParameters() with a higher level-id.
  h265_codec.parameters["level-id"] = "180";
  {
    RtpParameters parameters = sender->GetParameters();
    ASSERT_THAT(parameters.encodings, SizeIs(1));
    parameters.encodings[0].codec = h265_codec;
    ASSERT_THAT(sender->SetParameters(parameters), IsRtcOk());
  }
}
#endif  // RTC_ENABLE_H265

TEST_F(PeerConnectionEncodingsFakeCodecsIntegrationTest,
       H264UnidirectionalNegotiation) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper =
      CreatePcWithUnidirectionalH264();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper =
      CreatePcWithUnidirectionalH264();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  scoped_refptr<RtpTransceiverInterface> transceiver =
      local_pc_wrapper->pc()->AddTransceiver(MediaType::VIDEO).MoveValue();

  // Filter on codec name and assert that sender capabilities have codecs for
  // {sendrecv, sendonly} and the receiver capabilities have codecs for
  // {sendrecv, recvonly}.
  std::vector<RtpCodecCapability> send_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpSenderCapabilities(MediaType::VIDEO)
          .codecs;
  std::erase_if(send_codecs, [](const RtpCodecCapability& codec) {
    return codec.name != "H264";
  });
  std::vector<RtpCodecCapability> recv_codecs =
      local_pc_wrapper->pc_factory()
          ->GetRtpReceiverCapabilities(MediaType::VIDEO)
          .codecs;
  std::erase_if(recv_codecs, [](const RtpCodecCapability& codec) {
    RTC_LOG(LS_ERROR) << codec.name;
    return codec.name != "H264";
  });
  ASSERT_THAT(send_codecs, SizeIs(2u));
  ASSERT_THAT(recv_codecs, SizeIs(2u));
  EXPECT_EQ(send_codecs[0], recv_codecs[0]);
  EXPECT_NE(send_codecs[1], recv_codecs[1]);
  RtpCodecCapability& sendrecv_codec = send_codecs[0];
  RtpCodecCapability& sendonly_codec = send_codecs[1];
  RtpCodecCapability& recvonly_codec = recv_codecs[1];

  // Preferring sendonly + recvonly on a sendrecv transceiver is the same as
  // not having any preferences, meaning the sendrecv codec (not listed) is the
  // one being negotiated.
  std::vector<RtpCodecCapability> preferred_codecs = {sendonly_codec,
                                                      recvonly_codec};
  EXPECT_THAT(transceiver->SetCodecPreferences(preferred_codecs), IsRtcOk());
  EXPECT_THAT(
      transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendRecv),
      IsRtcOk());
  Negotiate(local_pc_wrapper, remote_pc_wrapper);
  std::string local_sdp = LocalDescriptionStr(local_pc_wrapper.get());
  EXPECT_THAT(local_sdp,
              HasSubstr(sendrecv_codec.parameters["profile-level-id"]));
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(sendonly_codec.parameters["profile-level-id"])));
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(recvonly_codec.parameters["profile-level-id"])));

  // Prefer all codecs and expect that the SDP offer contains the relevant
  // codecs after filtering. Complete O/A each time.
  preferred_codecs = {sendrecv_codec, sendonly_codec, recvonly_codec};
  EXPECT_THAT(transceiver->SetCodecPreferences(preferred_codecs), IsRtcOk());
  // Transceiver direction: sendrecv.
  EXPECT_THAT(
      transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendRecv),
      IsRtcOk());
  Negotiate(local_pc_wrapper, remote_pc_wrapper);
  local_sdp = LocalDescriptionStr(local_pc_wrapper.get());
  EXPECT_THAT(local_sdp,
              HasSubstr(sendrecv_codec.parameters["profile-level-id"]));
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(sendonly_codec.parameters["profile-level-id"])));
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(recvonly_codec.parameters["profile-level-id"])));
  // Transceiver direction: sendonly.
  EXPECT_THAT(
      transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendOnly),
      IsRtcOk());
  Negotiate(local_pc_wrapper, remote_pc_wrapper);
  local_sdp = LocalDescriptionStr(local_pc_wrapper.get());
  EXPECT_THAT(local_sdp,
              HasSubstr(sendrecv_codec.parameters["profile-level-id"]));
  EXPECT_THAT(local_sdp,
              HasSubstr(sendonly_codec.parameters["profile-level-id"]));
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(recvonly_codec.parameters["profile-level-id"])));
  // Transceiver direction: recvonly.
  EXPECT_THAT(
      transceiver->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly),
      IsRtcOk());
  Negotiate(local_pc_wrapper, remote_pc_wrapper);
  local_sdp = LocalDescriptionStr(local_pc_wrapper.get());
  EXPECT_THAT(local_sdp,
              HasSubstr(sendrecv_codec.parameters["profile-level-id"]));
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(sendonly_codec.parameters["profile-level-id"])));
  EXPECT_THAT(local_sdp,
              HasSubstr(recvonly_codec.parameters["profile-level-id"]));

  // Test that offering a sendonly codec on a sendonly transceiver is possible.
  // - Note that we don't complete the negotiation this time because we're not
  //   capable of receiving the codec.
  preferred_codecs = {sendonly_codec};
  EXPECT_THAT(transceiver->SetCodecPreferences(preferred_codecs), IsRtcOk());
  EXPECT_THAT(
      transceiver->SetDirectionWithError(RtpTransceiverDirection::kSendOnly),
      IsRtcOk());
  std::unique_ptr<SessionDescriptionInterface> offer =
      CreateOffer(local_pc_wrapper);
  EXPECT_TRUE(Await({SetLocalDescription(local_pc_wrapper, offer.get())}));
  local_sdp = LocalDescriptionStr(local_pc_wrapper.get());
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(sendrecv_codec.parameters["profile-level-id"])));
  EXPECT_THAT(local_sdp,
              HasSubstr(sendonly_codec.parameters["profile-level-id"]));
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(recvonly_codec.parameters["profile-level-id"])));
  // Test that offering recvonly codec on a recvonly transceiver is possible.
  // - Note that we don't complete the negotiation this time because we're not
  //   capable of sending the codec.
  preferred_codecs = {recvonly_codec};
  EXPECT_THAT(transceiver->SetCodecPreferences(preferred_codecs), IsRtcOk());
  EXPECT_THAT(
      transceiver->SetDirectionWithError(RtpTransceiverDirection::kRecvOnly),
      IsRtcOk());
  offer = CreateOffer(local_pc_wrapper);
  EXPECT_TRUE(Await({SetLocalDescription(local_pc_wrapper, offer.get())}));
  local_sdp = LocalDescriptionStr(local_pc_wrapper.get());
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(sendrecv_codec.parameters["profile-level-id"])));
  EXPECT_THAT(local_sdp,
              Not(HasSubstr(sendonly_codec.parameters["profile-level-id"])));
  EXPECT_THAT(local_sdp,
              HasSubstr(recvonly_codec.parameters["profile-level-id"]));
}

// Regression test for https://issues.chromium.org/issues/399667359
TEST_F(PeerConnectionEncodingsIntegrationTest,
       SimulcastNotSupportedGetParametersDoesNotCrash) {
  scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
  scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
  ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

  std::vector<SimulcastLayer> layers =
      CreateLayers({"f", "q"}, /*active=*/true);
  scoped_refptr<RtpTransceiverInterface> transceiver =
      AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper,
                                        layers);
  // Negotiate - receiver will reject simulcast, so the 2nd layer will be
  // disabled
  Negotiate(local_pc_wrapper, remote_pc_wrapper);
  // Negotiate again without simulcast.
  Negotiate(local_pc_wrapper, remote_pc_wrapper);

  RtpParameters parameters = transceiver->sender()->GetParameters();
  EXPECT_TRUE(transceiver->sender()->SetParameters(parameters).ok());
}

}  // namespace webrtc
