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

#include "api/video_codecs/video_encoder_software_fallback_wrapper.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "absl/types/optional.h"
#include "api/fec_controller_override.h"
#include "api/scoped_refptr.h"
#include "api/test/mock_video_encoder.h"
#include "api/video/encoded_image.h"
#include "api/video/i420_buffer.h"
#include "api/video/video_bitrate_allocation.h"
#include "api/video/video_frame.h"
#include "api/video/video_frame_buffer.h"
#include "api/video/video_rotation.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "modules/video_coding/utility/simulcast_rate_allocator.h"
#include "rtc_base/fake_clock.h"
#include "test/fake_texture_frame.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
using ::testing::_;
using ::testing::Return;

namespace {
const int kWidth = 320;
const int kHeight = 240;
const int kNumCores = 2;
const uint32_t kFramerate = 30;
const size_t kMaxPayloadSize = 800;
const int kLowThreshold = 10;
const int kHighThreshold = 20;

const VideoEncoder::Capabilities kCapabilities(false);
const VideoEncoder::Settings kSettings(kCapabilities,
                                       kNumCores,
                                       kMaxPayloadSize);

VideoEncoder::EncoderInfo GetEncoderInfoWithTrustedRateController(
    bool trusted_rate_controller) {
  VideoEncoder::EncoderInfo info;
  info.has_trusted_rate_controller = trusted_rate_controller;
  return info;
}

VideoEncoder::EncoderInfo GetEncoderInfoWithHardwareAccelerated(
    bool hardware_accelerated) {
  VideoEncoder::EncoderInfo info;
  info.is_hardware_accelerated = hardware_accelerated;
  return info;
}

VideoEncoder::EncoderInfo GetEncoderInfoWithInternalSource(
    bool internal_source) {
  VideoEncoder::EncoderInfo info;
  info.has_internal_source = internal_source;
  return info;
}

class FakeEncodedImageCallback : public EncodedImageCallback {
 public:
  Result OnEncodedImage(const EncodedImage& encoded_image,
                        const CodecSpecificInfo* codec_specific_info) override {
    ++callback_count_;
    return Result(Result::OK, callback_count_);
  }
  int callback_count_ = 0;
};
}  // namespace

class VideoEncoderSoftwareFallbackWrapperTestBase : public ::testing::Test {
 protected:
  VideoEncoderSoftwareFallbackWrapperTestBase(
      const std::string& field_trials,
      std::unique_ptr<VideoEncoder> sw_encoder)
      : override_field_trials_(field_trials),
        fake_encoder_(new CountingFakeEncoder()),
        wrapper_initialized_(false),
        fallback_wrapper_(CreateVideoEncoderSoftwareFallbackWrapper(
            std::move(sw_encoder),
            std::unique_ptr<VideoEncoder>(fake_encoder_),
            false)) {}

  class CountingFakeEncoder : public VideoEncoder {
   public:
    void SetFecControllerOverride(
        FecControllerOverride* fec_controller_override) override {
      // Ignored.
    }

    int32_t InitEncode(const VideoCodec* codec_settings,
                       const VideoEncoder::Settings& settings) override {
      ++init_encode_count_;
      return init_encode_return_code_;
    }

    int32_t Encode(const VideoFrame& frame,
                   const std::vector<VideoFrameType>* frame_types) override {
      ++encode_count_;
      last_video_frame_ = frame;
      if (encode_complete_callback_ &&
          encode_return_code_ == WEBRTC_VIDEO_CODEC_OK) {
        encode_complete_callback_->OnEncodedImage(EncodedImage(), nullptr);
      }
      return encode_return_code_;
    }

    int32_t RegisterEncodeCompleteCallback(
        EncodedImageCallback* callback) override {
      encode_complete_callback_ = callback;
      return WEBRTC_VIDEO_CODEC_OK;
    }

    int32_t Release() override {
      ++release_count_;
      return WEBRTC_VIDEO_CODEC_OK;
    }

    void SetRates(const RateControlParameters& parameters) override {}

    EncoderInfo GetEncoderInfo() const override {
      ++supports_native_handle_count_;
      EncoderInfo info;
      info.scaling_settings = ScalingSettings(kLowThreshold, kHighThreshold);
      info.supports_native_handle = supports_native_handle_;
      info.implementation_name = implementation_name_;
      return info;
    }

    int init_encode_count_ = 0;
    int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
    int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
    int encode_count_ = 0;
    EncodedImageCallback* encode_complete_callback_ = nullptr;
    int release_count_ = 0;
    mutable int supports_native_handle_count_ = 0;
    bool supports_native_handle_ = false;
    std::string implementation_name_ = "fake-encoder";
    absl::optional<VideoFrame> last_video_frame_;
  };

  void InitEncode();
  void UtilizeFallbackEncoder();
  void FallbackFromEncodeRequest();
  void EncodeFrame();
  void EncodeFrame(int expected_ret);
  void CheckLastEncoderName(const char* expected_name) {
    EXPECT_EQ(expected_name,
              fallback_wrapper_->GetEncoderInfo().implementation_name);
  }

  test::ScopedFieldTrials override_field_trials_;
  FakeEncodedImageCallback callback_;
  // |fake_encoder_| is owned and released by |fallback_wrapper_|.
  CountingFakeEncoder* fake_encoder_;
  CountingFakeEncoder* fake_sw_encoder_;
  bool wrapper_initialized_;
  std::unique_ptr<VideoEncoder> fallback_wrapper_;
  VideoCodec codec_ = {};
  std::unique_ptr<VideoFrame> frame_;
  std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
};

class VideoEncoderSoftwareFallbackWrapperTest
    : public VideoEncoderSoftwareFallbackWrapperTestBase {
 protected:
  VideoEncoderSoftwareFallbackWrapperTest()
      : VideoEncoderSoftwareFallbackWrapperTest(new CountingFakeEncoder()) {}
  explicit VideoEncoderSoftwareFallbackWrapperTest(
      CountingFakeEncoder* fake_sw_encoder)
      : VideoEncoderSoftwareFallbackWrapperTestBase(
            "",
            std::unique_ptr<VideoEncoder>(fake_sw_encoder)),
        fake_sw_encoder_(fake_sw_encoder) {
    fake_sw_encoder_->implementation_name_ = "fake_sw_encoder";
  }

  CountingFakeEncoder* fake_sw_encoder_;
};

void VideoEncoderSoftwareFallbackWrapperTestBase::EncodeFrame() {
  EncodeFrame(WEBRTC_VIDEO_CODEC_OK);
}

void VideoEncoderSoftwareFallbackWrapperTestBase::EncodeFrame(
    int expected_ret) {
  rtc::scoped_refptr<I420Buffer> buffer =
      I420Buffer::Create(codec_.width, codec_.height);
  I420Buffer::SetBlack(buffer);
  std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);

  frame_ =
      std::make_unique<VideoFrame>(VideoFrame::Builder()
                                       .set_video_frame_buffer(buffer)
                                       .set_rotation(webrtc::kVideoRotation_0)
                                       .set_timestamp_us(0)
                                       .build());
  EXPECT_EQ(expected_ret, fallback_wrapper_->Encode(*frame_, &types));
}

void VideoEncoderSoftwareFallbackWrapperTestBase::InitEncode() {
  if (!wrapper_initialized_) {
    fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
    EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
  }

  // Register fake encoder as main.
  codec_.codecType = kVideoCodecVP8;
  codec_.maxFramerate = kFramerate;
  codec_.width = kWidth;
  codec_.height = kHeight;
  codec_.VP8()->numberOfTemporalLayers = 1;
  rate_allocator_.reset(new SimulcastRateAllocator(codec_));

  if (wrapper_initialized_) {
    fallback_wrapper_->Release();
  }

  fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            fallback_wrapper_->InitEncode(&codec_, kSettings));

  if (!wrapper_initialized_) {
    fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
        rate_allocator_->Allocate(
            VideoBitrateAllocationParameters(300000, kFramerate)),
        kFramerate));
  }
  wrapper_initialized_ = true;
}

void VideoEncoderSoftwareFallbackWrapperTestBase::UtilizeFallbackEncoder() {
  if (!wrapper_initialized_) {
    fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
    EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
  }

  // Register with failing fake encoder. Should succeed with VP8 fallback.
  codec_.codecType = kVideoCodecVP8;
  codec_.maxFramerate = kFramerate;
  codec_.width = kWidth;
  codec_.height = kHeight;
  codec_.VP8()->numberOfTemporalLayers = 1;
  rate_allocator_.reset(new SimulcastRateAllocator(codec_));

  if (wrapper_initialized_) {
    fallback_wrapper_->Release();
  }

  fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            fallback_wrapper_->InitEncode(&codec_, kSettings));
  fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
      rate_allocator_->Allocate(
          VideoBitrateAllocationParameters(300000, kFramerate)),
      kFramerate));

  int callback_count = callback_.callback_count_;
  int encode_count = fake_encoder_->encode_count_;
  EncodeFrame();
  EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
  EXPECT_EQ(callback_count + 1, callback_.callback_count_);
}

void VideoEncoderSoftwareFallbackWrapperTestBase::FallbackFromEncodeRequest() {
  fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
  codec_.codecType = kVideoCodecVP8;
  codec_.maxFramerate = kFramerate;
  codec_.width = kWidth;
  codec_.height = kHeight;
  codec_.VP8()->numberOfTemporalLayers = 1;
  rate_allocator_.reset(new SimulcastRateAllocator(codec_));
  if (wrapper_initialized_) {
    fallback_wrapper_->Release();
  }
  fallback_wrapper_->InitEncode(&codec_, kSettings);
  fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
      rate_allocator_->Allocate(
          VideoBitrateAllocationParameters(300000, kFramerate)),
      kFramerate));
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);

  // Have the non-fallback encoder request a software fallback.
  fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
  int callback_count = callback_.callback_count_;
  int encode_count = fake_encoder_->encode_count_;
  EncodeFrame();
  // Single encode request, which returned failure.
  EXPECT_EQ(encode_count + 1, fake_encoder_->encode_count_);
  EXPECT_EQ(callback_count + 1, callback_.callback_count_);
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) {
  VideoCodec codec = {};
  fallback_wrapper_->InitEncode(&codec, kSettings);
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest, EncodeRequestsFallback) {
  FallbackFromEncodeRequest();
  // After fallback, further encodes shouldn't hit the fake encoder.
  int encode_count = fake_encoder_->encode_count_;
  EncodeFrame();
  EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) {
  UtilizeFallbackEncoder();
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
       InternalEncoderReleasedDuringFallback) {
  EXPECT_EQ(0, fake_encoder_->init_encode_count_);
  EXPECT_EQ(0, fake_encoder_->release_count_);

  InitEncode();

  EXPECT_EQ(1, fake_encoder_->init_encode_count_);
  EXPECT_EQ(0, fake_encoder_->release_count_);

  UtilizeFallbackEncoder();

  // One successful InitEncode(), one failed.
  EXPECT_EQ(2, fake_encoder_->init_encode_count_);
  EXPECT_EQ(1, fake_encoder_->release_count_);

  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());

  // No extra release when the fallback is released.
  EXPECT_EQ(2, fake_encoder_->init_encode_count_);
  EXPECT_EQ(1, fake_encoder_->release_count_);
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
       InternalEncoderNotEncodingDuringFallback) {
  UtilizeFallbackEncoder();
  int encode_count = fake_encoder_->encode_count_;
  EncodeFrame();
  EXPECT_EQ(encode_count, fake_encoder_->encode_count_);

  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
       CanRegisterCallbackWhileUsingFallbackEncoder) {
  InitEncode();
  EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);

  UtilizeFallbackEncoder();

  // Registering an encode-complete callback will now pass to the fallback
  // instead of the main encoder.
  FakeEncodedImageCallback callback2;
  fallback_wrapper_->RegisterEncodeCompleteCallback(&callback2);
  EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);

  // Encoding a frame using the fallback should arrive at the new callback.
  std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
  frame_->set_timestamp(frame_->timestamp() + 1000);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Encode(*frame_, &types));
  EXPECT_EQ(callback2.callback_count_, 1);

  // Re-initialize to use the main encoder, the new callback should be in use.
  InitEncode();
  EXPECT_EQ(&callback2, fake_encoder_->encode_complete_callback_);

  frame_->set_timestamp(frame_->timestamp() + 2000);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Encode(*frame_, &types));
  EXPECT_EQ(callback2.callback_count_, 2);
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
       SupportsNativeHandleForwardedWithoutFallback) {
  fallback_wrapper_->GetEncoderInfo();
  EXPECT_EQ(1, fake_encoder_->supports_native_handle_count_);
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
       SupportsNativeHandleNotForwardedDuringFallback) {
  // Fake encoder signals support for native handle, default (libvpx) does not.
  fake_encoder_->supports_native_handle_ = true;
  EXPECT_TRUE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
  UtilizeFallbackEncoder();
  EXPECT_FALSE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
  // Both times, both encoders are queried.
  EXPECT_EQ(2, fake_encoder_->supports_native_handle_count_);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) {
  codec_.width = kWidth;
  codec_.height = kHeight;
  fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
  fallback_wrapper_->InitEncode(&codec_, kSettings);
  EncodeFrame();
  CheckLastEncoderName("fake-encoder");
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
       ReportsFallbackImplementationName) {
  UtilizeFallbackEncoder();
  CheckLastEncoderName(fake_sw_encoder_->implementation_name_.c_str());
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
       OnEncodeFallbackNativeFrameScaledIfFallbackDoesNotSupportNativeFrames) {
  fake_encoder_->supports_native_handle_ = true;
  fake_sw_encoder_->supports_native_handle_ = false;
  InitEncode();
  int width = codec_.width * 2;
  int height = codec_.height * 2;
  VideoFrame native_frame = test::FakeNativeBuffer::CreateFrame(
      width, height, 0, 0, VideoRotation::kVideoRotation_0);
  std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
  fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;

  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            fallback_wrapper_->Encode(native_frame, &types));
  EXPECT_EQ(1, fake_sw_encoder_->encode_count_);
  ASSERT_TRUE(fake_sw_encoder_->last_video_frame_.has_value());
  EXPECT_NE(VideoFrameBuffer::Type::kNative,
            fake_sw_encoder_->last_video_frame_->video_frame_buffer()->type());
  EXPECT_EQ(codec_.width, fake_sw_encoder_->last_video_frame_->width());
  EXPECT_EQ(codec_.height, fake_sw_encoder_->last_video_frame_->height());
}

TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
       OnEncodeFallbackNativeFrameForwardedToFallbackIfItSupportsNativeFrames) {
  fake_encoder_->supports_native_handle_ = true;
  fake_sw_encoder_->supports_native_handle_ = true;
  InitEncode();
  int width = codec_.width * 2;
  int height = codec_.height * 2;
  VideoFrame native_frame = test::FakeNativeBuffer::CreateFrame(
      width, height, 0, 0, VideoRotation::kVideoRotation_0);
  std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
  fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;

  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            fallback_wrapper_->Encode(native_frame, &types));
  EXPECT_EQ(1, fake_sw_encoder_->encode_count_);
  ASSERT_TRUE(fake_sw_encoder_->last_video_frame_.has_value());
  EXPECT_EQ(VideoFrameBuffer::Type::kNative,
            fake_sw_encoder_->last_video_frame_->video_frame_buffer()->type());
  EXPECT_EQ(native_frame.width(), fake_sw_encoder_->last_video_frame_->width());
  EXPECT_EQ(native_frame.height(),
            fake_sw_encoder_->last_video_frame_->height());
}

namespace {
const int kBitrateKbps = 200;
const int kMinPixelsPerFrame = 1;
const char kFieldTrial[] = "WebRTC-VP8-Forced-Fallback-Encoder-v2";
}  // namespace

class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTestBase {
 public:
  explicit ForcedFallbackTest(const std::string& field_trials)
      : VideoEncoderSoftwareFallbackWrapperTestBase(field_trials,
                                                    VP8Encoder::Create()) {}

  ~ForcedFallbackTest() override {}

 protected:
  void SetUp() override {
    clock_.SetTime(Timestamp::Micros(1234));
    ConfigureVp8Codec();
  }

  void TearDown() override {
    if (wrapper_initialized_) {
      EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
    }
  }

  void ConfigureVp8Codec() {
    codec_.codecType = kVideoCodecVP8;
    codec_.maxFramerate = kFramerate;
    codec_.width = kWidth;
    codec_.height = kHeight;
    codec_.VP8()->numberOfTemporalLayers = 1;
    codec_.VP8()->automaticResizeOn = true;
    codec_.VP8()->frameDroppingOn = true;
    rate_allocator_.reset(new SimulcastRateAllocator(codec_));
  }

  void InitEncode(int width, int height) {
    codec_.width = width;
    codec_.height = height;
    if (wrapper_initialized_) {
      fallback_wrapper_->Release();
    }
    EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
              fallback_wrapper_->InitEncode(&codec_, kSettings));
    fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
    wrapper_initialized_ = true;
    SetRateAllocation(kBitrateKbps);
  }

  void SetRateAllocation(uint32_t bitrate_kbps) {
    fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
        rate_allocator_->Allocate(
            VideoBitrateAllocationParameters(bitrate_kbps * 1000, kFramerate)),
        kFramerate));
  }

  void EncodeFrameAndVerifyLastName(const char* expected_name) {
    EncodeFrameAndVerifyLastName(expected_name, WEBRTC_VIDEO_CODEC_OK);
  }

  void EncodeFrameAndVerifyLastName(const char* expected_name,
                                    int expected_ret) {
    EncodeFrame(expected_ret);
    CheckLastEncoderName(expected_name);
  }

  rtc::ScopedFakeClock clock_;
};

class ForcedFallbackTestEnabled : public ForcedFallbackTest {
 public:
  ForcedFallbackTestEnabled()
      : ForcedFallbackTest(std::string(kFieldTrial) + "/Enabled-" +
                           std::to_string(kMinPixelsPerFrame) + "," +
                           std::to_string(kWidth * kHeight) + ",30000/") {}
};

class ForcedFallbackTestDisabled : public ForcedFallbackTest {
 public:
  ForcedFallbackTestDisabled()
      : ForcedFallbackTest(std::string(kFieldTrial) + "/Disabled/") {}
};

TEST_F(ForcedFallbackTestDisabled, NoFallbackWithoutFieldTrial) {
  // Resolution above max threshold.
  InitEncode(kWidth + 1, kHeight);
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);
  EncodeFrameAndVerifyLastName("fake-encoder");

  // Resolution at max threshold.
  InitEncode(kWidth, kHeight);
  EncodeFrameAndVerifyLastName("fake-encoder");
}

TEST_F(ForcedFallbackTestEnabled, FallbackIfAtMaxResolutionLimit) {
  // Resolution above max threshold.
  InitEncode(kWidth + 1, kHeight);
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);
  EncodeFrameAndVerifyLastName("fake-encoder");

  // Resolution at max threshold.
  InitEncode(kWidth, kHeight);
  EncodeFrameAndVerifyLastName("libvpx");
}

TEST_F(ForcedFallbackTestEnabled, FallbackIsKeptWhenInitEncodeIsCalled) {
  // Resolution above max threshold.
  InitEncode(kWidth + 1, kHeight);
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);
  EncodeFrameAndVerifyLastName("fake-encoder");

  // Resolution at max threshold.
  InitEncode(kWidth, kHeight);
  EncodeFrameAndVerifyLastName("libvpx");

  // Re-initialize encoder, still expect fallback.
  InitEncode(kWidth / 2, kHeight / 2);
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);  // No change.
  EncodeFrameAndVerifyLastName("libvpx");
}

TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedWhenResolutionIsTooLarge) {
  // Resolution above max threshold.
  InitEncode(kWidth + 1, kHeight);
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);
  EncodeFrameAndVerifyLastName("fake-encoder");

  // Resolution at max threshold.
  InitEncode(kWidth, kHeight);
  EncodeFrameAndVerifyLastName("libvpx");

  // Re-initialize encoder with a larger resolution, expect no fallback.
  InitEncode(kWidth + 1, kHeight);
  EXPECT_EQ(2, fake_encoder_->init_encode_count_);
  EncodeFrameAndVerifyLastName("fake-encoder");
}

TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedForNonValidSettings) {
  // Resolution at max threshold.
  InitEncode(kWidth, kHeight);
  EncodeFrameAndVerifyLastName("libvpx");

  // Re-initialize encoder with invalid setting, expect no fallback.
  codec_.VP8()->numberOfTemporalLayers = 2;
  InitEncode(kWidth, kHeight);
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);
  EncodeFrameAndVerifyLastName("fake-encoder");

  // Re-initialize encoder with valid setting.
  codec_.VP8()->numberOfTemporalLayers = 1;
  InitEncode(kWidth, kHeight);
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);
  EncodeFrameAndVerifyLastName("libvpx");
}

TEST_F(ForcedFallbackTestEnabled, MultipleStartEndFallback) {
  const int kNumRuns = 5;
  for (int i = 1; i <= kNumRuns; ++i) {
    // Resolution at max threshold.
    InitEncode(kWidth, kHeight);
    EncodeFrameAndVerifyLastName("libvpx");
    // Resolution above max threshold.
    InitEncode(kWidth + 1, kHeight);
    EXPECT_EQ(i, fake_encoder_->init_encode_count_);
    EncodeFrameAndVerifyLastName("fake-encoder");
  }
}

TEST_F(ForcedFallbackTestDisabled, GetScaleSettings) {
  // Resolution above max threshold.
  InitEncode(kWidth + 1, kHeight);
  EXPECT_EQ(1, fake_encoder_->init_encode_count_);
  EncodeFrameAndVerifyLastName("fake-encoder");

  // Default min pixels per frame should be used.
  const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
  EXPECT_TRUE(settings.thresholds.has_value());
  EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame);
}

TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithNoFallback) {
  // Resolution above max threshold.
  InitEncode(kWidth + 1, kHeight);
  EncodeFrameAndVerifyLastName("fake-encoder");

  // Configured min pixels per frame should be used.
  const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
  EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
  ASSERT_TRUE(settings.thresholds);
  EXPECT_EQ(kLowThreshold, settings.thresholds->low);
  EXPECT_EQ(kHighThreshold, settings.thresholds->high);
}

TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithFallback) {
  // Resolution at max threshold.
  InitEncode(kWidth, kHeight);
  EncodeFrameAndVerifyLastName("libvpx");

  // Configured min pixels per frame should be used.
  const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
  EXPECT_TRUE(settings.thresholds.has_value());
  EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
}

TEST_F(ForcedFallbackTestEnabled, ScalingDisabledIfResizeOff) {
  // Resolution at max threshold.
  codec_.VP8()->automaticResizeOn = false;
  InitEncode(kWidth, kHeight);
  EncodeFrameAndVerifyLastName("libvpx");

  // Should be disabled for automatic resize off.
  const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
  EXPECT_FALSE(settings.thresholds.has_value());
}

TEST(SoftwareFallbackEncoderTest, BothRateControllersNotTrusted) {
  auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();

  EXPECT_CALL(*sw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
  EXPECT_CALL(*hw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));

  std::unique_ptr<VideoEncoder> wrapper =
      CreateVideoEncoderSoftwareFallbackWrapper(
          std::unique_ptr<VideoEncoder>(sw_encoder),
          std::unique_ptr<VideoEncoder>(hw_encoder));
  EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
}

TEST(SoftwareFallbackEncoderTest, SwRateControllerTrusted) {
  auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  EXPECT_CALL(*sw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
  EXPECT_CALL(*hw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));

  std::unique_ptr<VideoEncoder> wrapper =
      CreateVideoEncoderSoftwareFallbackWrapper(
          std::unique_ptr<VideoEncoder>(sw_encoder),
          std::unique_ptr<VideoEncoder>(hw_encoder));
  EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
}

TEST(SoftwareFallbackEncoderTest, HwRateControllerTrusted) {
  auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  EXPECT_CALL(*sw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
  EXPECT_CALL(*hw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));

  std::unique_ptr<VideoEncoder> wrapper =
      CreateVideoEncoderSoftwareFallbackWrapper(
          std::unique_ptr<VideoEncoder>(sw_encoder),
          std::unique_ptr<VideoEncoder>(hw_encoder));
  EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);

  VideoCodec codec_ = {};
  codec_.width = 100;
  codec_.height = 100;
  wrapper->InitEncode(&codec_, kSettings);

  // Trigger fallback to software.
  EXPECT_CALL(*hw_encoder, Encode)
      .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
  VideoFrame frame = VideoFrame::Builder()
                         .set_video_frame_buffer(I420Buffer::Create(100, 100))
                         .build();
  wrapper->Encode(frame, nullptr);

  EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
}

TEST(SoftwareFallbackEncoderTest, BothRateControllersTrusted) {
  auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  EXPECT_CALL(*sw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
  EXPECT_CALL(*hw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));

  std::unique_ptr<VideoEncoder> wrapper =
      CreateVideoEncoderSoftwareFallbackWrapper(
          std::unique_ptr<VideoEncoder>(sw_encoder),
          std::unique_ptr<VideoEncoder>(hw_encoder));
  EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
}

TEST(SoftwareFallbackEncoderTest, ReportsHardwareAccelerated) {
  auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  EXPECT_CALL(*sw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithHardwareAccelerated(false)));
  EXPECT_CALL(*hw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithHardwareAccelerated(true)));

  std::unique_ptr<VideoEncoder> wrapper =
      CreateVideoEncoderSoftwareFallbackWrapper(
          std::unique_ptr<VideoEncoder>(sw_encoder),
          std::unique_ptr<VideoEncoder>(hw_encoder));
  EXPECT_TRUE(wrapper->GetEncoderInfo().is_hardware_accelerated);

  VideoCodec codec_ = {};
  codec_.width = 100;
  codec_.height = 100;
  wrapper->InitEncode(&codec_, kSettings);

  // Trigger fallback to software.
  EXPECT_CALL(*hw_encoder, Encode)
      .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
  VideoFrame frame = VideoFrame::Builder()
                         .set_video_frame_buffer(I420Buffer::Create(100, 100))
                         .build();
  wrapper->Encode(frame, nullptr);
  EXPECT_FALSE(wrapper->GetEncoderInfo().is_hardware_accelerated);
}

TEST(SoftwareFallbackEncoderTest, ReportsInternalSource) {
  auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
  EXPECT_CALL(*sw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithInternalSource(false)));
  EXPECT_CALL(*hw_encoder, GetEncoderInfo())
      .WillRepeatedly(Return(GetEncoderInfoWithInternalSource(true)));

  std::unique_ptr<VideoEncoder> wrapper =
      CreateVideoEncoderSoftwareFallbackWrapper(
          std::unique_ptr<VideoEncoder>(sw_encoder),
          std::unique_ptr<VideoEncoder>(hw_encoder));
  EXPECT_TRUE(wrapper->GetEncoderInfo().has_internal_source);

  VideoCodec codec_ = {};
  codec_.width = 100;
  codec_.height = 100;
  wrapper->InitEncode(&codec_, kSettings);

  // Trigger fallback to software.
  EXPECT_CALL(*hw_encoder, Encode)
      .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
  VideoFrame frame = VideoFrame::Builder()
                         .set_video_frame_buffer(I420Buffer::Create(100, 100))
                         .build();
  wrapper->Encode(frame, nullptr);
  EXPECT_FALSE(wrapper->GetEncoderInfo().has_internal_source);
}

class PreferTemporalLayersFallbackTest : public ::testing::Test {
 public:
  PreferTemporalLayersFallbackTest() {}
  void SetUp() override {
    sw_ = new ::testing::NiceMock<MockVideoEncoder>();
    sw_info_.implementation_name = "sw";
    EXPECT_CALL(*sw_, GetEncoderInfo).WillRepeatedly([&]() {
      return sw_info_;
    });
    EXPECT_CALL(*sw_, InitEncode(_, _, _))
        .WillRepeatedly(Return(WEBRTC_VIDEO_CODEC_OK));

    hw_ = new ::testing::NiceMock<MockVideoEncoder>();
    hw_info_.implementation_name = "hw";
    EXPECT_CALL(*hw_, GetEncoderInfo()).WillRepeatedly([&]() {
      return hw_info_;
    });
    EXPECT_CALL(*hw_, InitEncode(_, _, _))
        .WillRepeatedly(Return(WEBRTC_VIDEO_CODEC_OK));

    wrapper_ = CreateVideoEncoderSoftwareFallbackWrapper(
        std::unique_ptr<VideoEncoder>(sw_), std::unique_ptr<VideoEncoder>(hw_),
        /*prefer_temporal_support=*/true);

    codec_settings.codecType = kVideoCodecVP8;
    codec_settings.maxFramerate = kFramerate;
    codec_settings.width = kWidth;
    codec_settings.height = kHeight;
    codec_settings.numberOfSimulcastStreams = 1;
    codec_settings.VP8()->numberOfTemporalLayers = 1;
  }

 protected:
  void SetSupportsLayers(VideoEncoder::EncoderInfo* info, bool tl_enabled) {
    int num_layers = 1;
    if (tl_enabled) {
      num_layers = codec_settings.VP8()->numberOfTemporalLayers;
    }
    SetNumLayers(info, num_layers);
  }

  void SetNumLayers(VideoEncoder::EncoderInfo* info, int num_layers) {
    info->fps_allocation[0].clear();
    for (int i = 0; i < num_layers; ++i) {
      info->fps_allocation[0].push_back(
          VideoEncoder::EncoderInfo::kMaxFramerateFraction >>
          (num_layers - i - 1));
    }
  }

  VideoCodec codec_settings;
  ::testing::NiceMock<MockVideoEncoder>* sw_;
  ::testing::NiceMock<MockVideoEncoder>* hw_;
  VideoEncoder::EncoderInfo sw_info_;
  VideoEncoder::EncoderInfo hw_info_;
  std::unique_ptr<VideoEncoder> wrapper_;
};

TEST_F(PreferTemporalLayersFallbackTest, UsesMainWhenLayersNotUsed) {
  codec_settings.VP8()->numberOfTemporalLayers = 1;
  SetSupportsLayers(&hw_info_, true);
  SetSupportsLayers(&sw_info_, true);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            wrapper_->InitEncode(&codec_settings, kSettings));
  EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
}

TEST_F(PreferTemporalLayersFallbackTest, UsesMainWhenLayersSupported) {
  codec_settings.VP8()->numberOfTemporalLayers = 2;
  SetSupportsLayers(&hw_info_, true);
  SetSupportsLayers(&sw_info_, true);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            wrapper_->InitEncode(&codec_settings, kSettings));
  EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
}

TEST_F(PreferTemporalLayersFallbackTest,
       UsesFallbackWhenLayersNotSupportedOnMain) {
  codec_settings.VP8()->numberOfTemporalLayers = 2;
  SetSupportsLayers(&hw_info_, false);
  SetSupportsLayers(&sw_info_, true);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            wrapper_->InitEncode(&codec_settings, kSettings));
  EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "sw");
}

TEST_F(PreferTemporalLayersFallbackTest, UsesMainWhenNeitherSupportsTemporal) {
  codec_settings.VP8()->numberOfTemporalLayers = 2;
  SetSupportsLayers(&hw_info_, false);
  SetSupportsLayers(&sw_info_, false);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            wrapper_->InitEncode(&codec_settings, kSettings));
  EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
}

TEST_F(PreferTemporalLayersFallbackTest, UsesFallbackWhenLayersAreUndefined) {
  codec_settings.VP8()->numberOfTemporalLayers = 2;
  SetNumLayers(&hw_info_, 1);
  SetNumLayers(&sw_info_, 0);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            wrapper_->InitEncode(&codec_settings, kSettings));
  EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "sw");
}

TEST_F(PreferTemporalLayersFallbackTest, PrimesEncoderOnSwitch) {
  codec_settings.VP8()->numberOfTemporalLayers = 2;
  // Both support temporal layers, will use main one.
  SetSupportsLayers(&hw_info_, true);
  SetSupportsLayers(&sw_info_, true);

  // On first InitEncode most params have no state and will not be
  // called to update.
  EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback).Times(0);
  EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback).Times(0);

  EXPECT_CALL(*hw_, SetFecControllerOverride).Times(0);
  EXPECT_CALL(*sw_, SetFecControllerOverride).Times(0);

  EXPECT_CALL(*hw_, SetRates).Times(0);
  EXPECT_CALL(*hw_, SetRates).Times(0);

  EXPECT_CALL(*hw_, OnPacketLossRateUpdate).Times(0);
  EXPECT_CALL(*sw_, OnPacketLossRateUpdate).Times(0);

  EXPECT_CALL(*hw_, OnRttUpdate).Times(0);
  EXPECT_CALL(*sw_, OnRttUpdate).Times(0);

  EXPECT_CALL(*hw_, OnLossNotification).Times(0);
  EXPECT_CALL(*sw_, OnLossNotification).Times(0);

  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            wrapper_->InitEncode(&codec_settings, kSettings));
  EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");

  FakeEncodedImageCallback callback1;
  class DummyFecControllerOverride : public FecControllerOverride {
   public:
    void SetFecAllowed(bool fec_allowed) override {}
  };
  DummyFecControllerOverride fec_controller_override1;
  VideoEncoder::RateControlParameters rate_params1;
  float packet_loss1 = 0.1;
  int64_t rtt1 = 1;
  VideoEncoder::LossNotification lntf1;

  EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback(&callback1));
  EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback).Times(0);
  wrapper_->RegisterEncodeCompleteCallback(&callback1);

  EXPECT_CALL(*hw_, SetFecControllerOverride(&fec_controller_override1));
  EXPECT_CALL(*sw_, SetFecControllerOverride).Times(0);
  wrapper_->SetFecControllerOverride(&fec_controller_override1);

  EXPECT_CALL(*hw_, SetRates(rate_params1));
  EXPECT_CALL(*sw_, SetRates).Times(0);
  wrapper_->SetRates(rate_params1);

  EXPECT_CALL(*hw_, OnPacketLossRateUpdate(packet_loss1));
  EXPECT_CALL(*sw_, OnPacketLossRateUpdate).Times(0);
  wrapper_->OnPacketLossRateUpdate(packet_loss1);

  EXPECT_CALL(*hw_, OnRttUpdate(rtt1));
  EXPECT_CALL(*sw_, OnRttUpdate).Times(0);
  wrapper_->OnRttUpdate(rtt1);

  EXPECT_CALL(*hw_, OnLossNotification).Times(1);
  EXPECT_CALL(*sw_, OnLossNotification).Times(0);
  wrapper_->OnLossNotification(lntf1);

  // Release and re-init, with fallback to software. This should trigger
  // the software encoder to be primed with the current state.
  wrapper_->Release();
  EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback(&callback1));
  EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback).Times(0);

  EXPECT_CALL(*sw_, SetFecControllerOverride(&fec_controller_override1));
  EXPECT_CALL(*hw_, SetFecControllerOverride).Times(0);

  // Rate control parameters are cleared on InitEncode.
  EXPECT_CALL(*sw_, SetRates).Times(0);
  EXPECT_CALL(*hw_, SetRates).Times(0);

  EXPECT_CALL(*sw_, OnPacketLossRateUpdate(packet_loss1));
  EXPECT_CALL(*hw_, OnPacketLossRateUpdate).Times(0);

  EXPECT_CALL(*sw_, OnRttUpdate(rtt1));
  EXPECT_CALL(*hw_, OnRttUpdate).Times(0);

  EXPECT_CALL(*sw_, OnLossNotification).Times(1);
  EXPECT_CALL(*hw_, OnLossNotification).Times(0);

  SetSupportsLayers(&hw_info_, false);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            wrapper_->InitEncode(&codec_settings, kSettings));
  EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "sw");

  // Update with all-new params for the software encoder.
  FakeEncodedImageCallback callback2;
  DummyFecControllerOverride fec_controller_override2;
  VideoEncoder::RateControlParameters rate_params2;
  float packet_loss2 = 0.2;
  int64_t rtt2 = 2;
  VideoEncoder::LossNotification lntf2;

  EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback(&callback2));
  EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback).Times(0);
  wrapper_->RegisterEncodeCompleteCallback(&callback2);

  EXPECT_CALL(*sw_, SetFecControllerOverride(&fec_controller_override2));
  EXPECT_CALL(*hw_, SetFecControllerOverride).Times(0);
  wrapper_->SetFecControllerOverride(&fec_controller_override2);

  EXPECT_CALL(*sw_, SetRates(rate_params2));
  EXPECT_CALL(*hw_, SetRates).Times(0);
  wrapper_->SetRates(rate_params2);

  EXPECT_CALL(*sw_, OnPacketLossRateUpdate(packet_loss2));
  EXPECT_CALL(*hw_, OnPacketLossRateUpdate).Times(0);
  wrapper_->OnPacketLossRateUpdate(packet_loss2);

  EXPECT_CALL(*sw_, OnRttUpdate(rtt2));
  EXPECT_CALL(*hw_, OnRttUpdate).Times(0);
  wrapper_->OnRttUpdate(rtt2);

  EXPECT_CALL(*sw_, OnLossNotification).Times(1);
  EXPECT_CALL(*hw_, OnLossNotification).Times(0);
  wrapper_->OnLossNotification(lntf2);

  // Release and re-init, back to main encoder. This should trigger
  // the main encoder to be primed with the current state.
  wrapper_->Release();
  EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback(&callback2));
  EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback).Times(0);

  EXPECT_CALL(*hw_, SetFecControllerOverride(&fec_controller_override2));
  EXPECT_CALL(*sw_, SetFecControllerOverride).Times(0);

  // Rate control parameters are cleared on InitEncode.
  EXPECT_CALL(*sw_, SetRates).Times(0);
  EXPECT_CALL(*hw_, SetRates).Times(0);

  EXPECT_CALL(*hw_, OnPacketLossRateUpdate(packet_loss2));
  EXPECT_CALL(*sw_, OnPacketLossRateUpdate).Times(0);

  EXPECT_CALL(*hw_, OnRttUpdate(rtt2));
  EXPECT_CALL(*sw_, OnRttUpdate).Times(0);

  EXPECT_CALL(*hw_, OnLossNotification).Times(1);
  EXPECT_CALL(*sw_, OnLossNotification).Times(0);

  SetSupportsLayers(&hw_info_, true);
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            wrapper_->InitEncode(&codec_settings, kSettings));
  EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
}

}  // namespace webrtc
