// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/gpu/android/media_codec_video_decoder.h"

#include "base/android/jni_android.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/run_loop.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "gpu/command_buffer/service/mock_texture_owner.h"
#include "gpu/config/gpu_preferences.h"
#include "media/base/android/media_codec_util.h"
#include "media/base/android/mock_android_overlay.h"
#include "media/base/android/mock_media_crypto_context.h"
#include "media/base/async_destroy_video_decoder.h"
#include "media/base/decoder_buffer.h"
#include "media/base/media_util.h"
#include "media/base/supported_video_decoder_config.h"
#include "media/base/test_helpers.h"
#include "media/base/video_codecs.h"
#include "media/base/video_frame.h"
#include "media/gpu/android/android_video_surface_chooser_impl.h"
#include "media/gpu/android/fake_codec_allocator.h"
#include "media/gpu/android/mock_android_video_surface_chooser.h"
#include "media/gpu/android/mock_device_info.h"
#include "media/gpu/android/video_frame_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::test::RunCallback;
using testing::_;
using testing::InvokeWithoutArgs;
using testing::NiceMock;
using testing::NotNull;
using testing::Return;
using testing::ReturnRef;
using testing::SaveArg;

namespace media {
namespace {

void OutputCb(scoped_refptr<VideoFrame>* output,
              scoped_refptr<VideoFrame> frame) {
  *output = std::move(frame);
}

std::unique_ptr<AndroidOverlay> CreateAndroidOverlayCb(
    const base::UnguessableToken&,
    AndroidOverlayConfig) {
  return nullptr;
}

}  // namespace

class MockVideoFrameFactory : public VideoFrameFactory {
 public:
  MOCK_METHOD2(Initialize, void(OverlayMode overlay_mode, InitCB init_cb));
  MOCK_METHOD1(MockSetSurfaceBundle, void(scoped_refptr<CodecSurfaceBundle>));
  MOCK_METHOD5(
      MockCreateVideoFrame,
      void(CodecOutputBuffer* raw_output_buffer,
           scoped_refptr<gpu::TextureOwner> texture_owner,
           base::TimeDelta timestamp,
           gfx::Size natural_size,
           PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb));
  MOCK_METHOD1(MockRunAfterPendingVideoFrames,
               void(base::OnceClosure* closure));
  MOCK_METHOD0(CancelPendingCallbacks, void());

  void SetSurfaceBundle(
      scoped_refptr<CodecSurfaceBundle> surface_bundle) override {
    MockSetSurfaceBundle(surface_bundle);
    if (!surface_bundle) {
      texture_owner_ = nullptr;
    } else {
      texture_owner_ = surface_bundle->overlay()
                           ? nullptr
                           : surface_bundle->codec_buffer_wait_coordinator()
                                 ->texture_owner();
    }
  }

  void CreateVideoFrame(
      std::unique_ptr<CodecOutputBuffer> output_buffer,
      base::TimeDelta timestamp,
      gfx::Size natural_size,
      PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb,
      VideoFrameFactory::OnceOutputCB output_cb) override {
    MockCreateVideoFrame(output_buffer.get(), texture_owner_, timestamp,
                         natural_size, promotion_hint_cb);
    last_output_buffer_ = std::move(output_buffer);
    std::move(output_cb).Run(VideoFrame::CreateBlackFrame(gfx::Size(10, 10)));
  }

  void RunAfterPendingVideoFrames(base::OnceClosure closure) override {
    last_closure_ = std::move(closure);
    MockRunAfterPendingVideoFrames(&last_closure_);
  }

  std::unique_ptr<CodecOutputBuffer> last_output_buffer_;
  scoped_refptr<gpu::TextureOwner> texture_owner_;
  base::OnceClosure last_closure_;
};

class MediaCodecVideoDecoderTest : public testing::TestWithParam<VideoCodec> {
 public:
  MediaCodecVideoDecoderTest() : codec_(GetParam()) {}

  void SetUp() override {
    uint8_t data = 0;
    fake_decoder_buffer_ = DecoderBuffer::CopyFrom(&data, 1);
    codec_allocator_ = std::make_unique<FakeCodecAllocator>(
        base::ThreadTaskRunnerHandle::Get());
    device_info_ = std::make_unique<NiceMock<MockDeviceInfo>>();
  }

  void TearDown() override {
    // For VP8, make MCVD skip the drain by resetting it.  Otherwise, it's hard
    // to finish the drain.
    if (mcvd_ && codec_ == VideoCodec::kVP8 &&
        codec_allocator_->most_recent_codec)
      DoReset();

    // MCVD calls DeleteSoon() on itself, so we have to run a RunLoop.
    mcvd_.reset();
    base::RunLoop().RunUntilIdle();
  }

  void CreateMcvd() {
    auto surface_chooser =
        std::make_unique<NiceMock<MockAndroidVideoSurfaceChooser>>();
    surface_chooser_ = surface_chooser.get();

    auto texture_owner = base::MakeRefCounted<NiceMock<gpu::MockTextureOwner>>(
        0, nullptr, nullptr);
    texture_owner_ = texture_owner.get();

    auto video_frame_factory =
        std::make_unique<NiceMock<MockVideoFrameFactory>>();
    video_frame_factory_ = video_frame_factory.get();
    // Set up VFF to pass |texture_owner_| via its InitCB.
    ON_CALL(*video_frame_factory_, Initialize(ExpectedOverlayMode(), _))
        .WillByDefault(RunCallback<1>(texture_owner));

    auto* mcvd = new MediaCodecVideoDecoder(
        gpu_preferences_, gpu_feature_info_, std::make_unique<NullMediaLog>(),
        device_info_.get(), codec_allocator_.get(), std::move(surface_chooser),
        base::BindRepeating(&CreateAndroidOverlayCb),
        base::BindRepeating(&MediaCodecVideoDecoderTest::RequestOverlayInfoCb,
                            base::Unretained(this)),
        std::move(video_frame_factory), /*lock=*/nullptr);
    mcvd_ = std::make_unique<AsyncDestroyVideoDecoder<MediaCodecVideoDecoder>>(
        base::WrapUnique(mcvd));
    mcvd_raw_ = mcvd;
  }

  VideoFrameFactory::OverlayMode ExpectedOverlayMode() const {
    const bool want_promotion_hint =
        device_info_->IsSetOutputSurfaceSupported();
    return want_promotion_hint
               ? VideoFrameFactory::OverlayMode::kRequestPromotionHints
               : VideoFrameFactory::OverlayMode::kDontRequestPromotionHints;
  }

  void CreateCdm(bool has_media_crypto_context,
                 bool require_secure_video_decoder) {
    cdm_ = std::make_unique<MockMediaCryptoContext>(has_media_crypto_context);
    require_secure_video_decoder_ = require_secure_video_decoder;

    // We need to send an object as the media crypto, but MCVD shouldn't
    // use it for anything.  Just send in some random java object, so that
    // it's not null.
    media_crypto_ = base::android::ScopedJavaGlobalRef<jobject>(
        gl::SurfaceTexture::Create(0)->j_surface_texture());
  }

  // Just call Initialize(). MCVD will be waiting for a call to Decode() before
  // continuining initialization.
  bool Initialize(VideoDecoderConfig config) {
    if (!mcvd_)
      CreateMcvd();
    bool result = false;
    auto init_cb = [](bool* result_out, Status result) {
      *result_out = result.is_ok();
    };
    mcvd_->Initialize(
        config, false, cdm_.get(), base::BindOnce(init_cb, &result),
        base::BindRepeating(&OutputCb, &most_recent_frame_), base::DoNothing());
    base::RunLoop().RunUntilIdle();

    // If there is a CDM available, then we expect that MCVD will be waiting
    // for the media crypto object.
    // TODO(liberato): why does CreateJavaObjectPtr() not link?
    if (cdm_ && cdm_->media_crypto_ready_cb) {
      std::move(cdm_->media_crypto_ready_cb)
          .Run(std::make_unique<base::android::ScopedJavaGlobalRef<jobject>>(
                   media_crypto_),
               require_secure_video_decoder_);
      // The callback is consumed, mark that we ran it so tests can verify.
      cdm_->ran_media_crypto_ready_cb = true;
      base::RunLoop().RunUntilIdle();
    }

    return result;
  }

  // Call Initialize() and Decode() to start lazy init. MCVD will be waiting for
  // a codec and have one decode pending.
  MockAndroidOverlay* InitializeWithOverlay_OneDecodePending(
      VideoDecoderConfig config) {
    Initialize(config);
    mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
    OverlayInfo info;
    info.routing_token = base::UnguessableToken::Deserialize(1, 2);
    provide_overlay_info_cb_.Run(info);
    auto overlay_ptr = std::make_unique<MockAndroidOverlay>();
    auto* overlay = overlay_ptr.get();

    if (!java_surface_) {
      java_surface_ = base::android::ScopedJavaGlobalRef<jobject>(
          gl::SurfaceTexture::Create(0)->j_surface_texture());
    }
    EXPECT_CALL(*overlay, GetJavaSurface())
        .WillRepeatedly(ReturnRef(java_surface_));

    surface_chooser_->ProvideOverlay(std::move(overlay_ptr));
    return overlay;
  }

  // Call Initialize() and Decode() to start lazy init. MCVD will be waiting for
  // a codec and have one decode pending.
  void InitializeWithTextureOwner_OneDecodePending(VideoDecoderConfig config) {
    Initialize(config);
    mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
    provide_overlay_info_cb_.Run(OverlayInfo());
    surface_chooser_->ProvideTextureOwner();
  }

  // Fully initializes MCVD and returns the codec it's configured with. MCVD
  // will have one decode pending.
  MockMediaCodecBridge* InitializeFully_OneDecodePending(
      VideoDecoderConfig config) {
    InitializeWithTextureOwner_OneDecodePending(config);
    return codec_allocator_->ProvideMockCodecAsync();
  }

  // Provide access to MCVD's private PumpCodec() to drive the state transitions
  // that depend on queueing and dequeueing buffers. It uses |mcvd_raw_| so that
  // it can be called after |mcvd_| is reset.
  void PumpCodec() { mcvd_raw_->PumpCodec(false); }

  // Start and finish a reset.
  void DoReset() {
    bool reset_complete = false;
    mcvd_->Reset(base::BindOnce(
        [](bool* reset_complete) { *reset_complete = true; }, &reset_complete));
    base::RunLoop().RunUntilIdle();
    if (!reset_complete) {
      // Note that there might be more pending decodes, and this will arrive
      // out of order.  We assume that MCVD doesn't care.
      codec_allocator_->most_recent_codec->ProduceOneOutput(
          MockMediaCodecBridge::kEos);
      PumpCodec();
      EXPECT_TRUE(reset_complete);
    }
  }

  void RequestOverlayInfoCb(bool restart_for_transitions,
                            ProvideOverlayInfoCB provide_overlay_info_cb) {
    restart_for_transitions_ = restart_for_transitions;
    provide_overlay_info_cb_ = std::move(provide_overlay_info_cb);
  }

 protected:
  const VideoCodec codec_;
  base::test::SingleThreadTaskEnvironment task_environment_;
  base::android::ScopedJavaGlobalRef<jobject> java_surface_;
  scoped_refptr<DecoderBuffer> fake_decoder_buffer_;
  std::unique_ptr<MockDeviceInfo> device_info_;
  std::unique_ptr<FakeCodecAllocator> codec_allocator_;
  MockAndroidVideoSurfaceChooser* surface_chooser_;
  gpu::MockTextureOwner* texture_owner_;
  MockVideoFrameFactory* video_frame_factory_;
  NiceMock<base::MockCallback<VideoDecoder::DecodeCB>> decode_cb_;
  ProvideOverlayInfoCB provide_overlay_info_cb_;
  bool restart_for_transitions_;
  gpu::GpuPreferences gpu_preferences_;
  gpu::GpuFeatureInfo gpu_feature_info_;
  scoped_refptr<VideoFrame> most_recent_frame_;

  // This is not an actual media crypto object.
  base::android::ScopedJavaGlobalRef<jobject> media_crypto_;
  bool require_secure_video_decoder_ = false;

  // This must outlive |mcvd_| .
  std::unique_ptr<MockMediaCryptoContext> cdm_;

  // |mcvd_raw_| lets us call PumpCodec() even after |mcvd_| is dropped, for
  // testing the teardown path.
  MediaCodecVideoDecoder* mcvd_raw_;
  std::unique_ptr<VideoDecoder> mcvd_;
};

// Tests which only work for a single codec.
class MediaCodecVideoDecoderAV1Test : public MediaCodecVideoDecoderTest {};
class MediaCodecVideoDecoderH264Test : public MediaCodecVideoDecoderTest {};
class MediaCodecVideoDecoderVp8Test : public MediaCodecVideoDecoderTest {};
class MediaCodecVideoDecoderVp9Test : public MediaCodecVideoDecoderTest {};

TEST_P(MediaCodecVideoDecoderTest, UnknownCodecIsRejected) {
  ASSERT_FALSE(Initialize(TestVideoConfig::Invalid()));
}

TEST_P(MediaCodecVideoDecoderH264Test, H264IsSupported) {
  ASSERT_TRUE(Initialize(TestVideoConfig::NormalH264()));
}

TEST_P(MediaCodecVideoDecoderVp8Test, SmallVp8IsRejected) {
  auto configs = MediaCodecVideoDecoder::GetSupportedConfigs();
  auto small_vp8_config = TestVideoConfig::Normal();
  for (const auto& c : configs)
    ASSERT_FALSE(c.Matches(small_vp8_config));
}

TEST_P(MediaCodecVideoDecoderAV1Test, Av1IsSupported) {
  EXPECT_CALL(*device_info_, IsAv1DecoderAvailable()).WillOnce(Return(true));
  ASSERT_TRUE(Initialize(TestVideoConfig::Normal(VideoCodec::kAV1)));
}

TEST_P(MediaCodecVideoDecoderTest, InitializeDoesntInitSurfaceOrCodec) {
  CreateMcvd();
  EXPECT_CALL(*video_frame_factory_, Initialize(ExpectedOverlayMode(), _))
      .Times(0);
  EXPECT_CALL(*surface_chooser_, MockUpdateState()).Times(0);
  EXPECT_CALL(*codec_allocator_, MockCreateMediaCodecAsync()).Times(0);
  Initialize(TestVideoConfig::Large(codec_));
}

TEST_P(MediaCodecVideoDecoderTest, FirstDecodeTriggersFrameFactoryInit) {
  Initialize(TestVideoConfig::Large(codec_));
  EXPECT_CALL(*video_frame_factory_, Initialize(ExpectedOverlayMode(), _));
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
}

TEST_P(MediaCodecVideoDecoderTest,
       FirstDecodeTriggersOverlayInfoRequestIfSupported) {
  Initialize(TestVideoConfig::Large(codec_));
  // Requesting overlay info sets this cb.
  ASSERT_FALSE(provide_overlay_info_cb_);
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
  ASSERT_TRUE(provide_overlay_info_cb_);
}

TEST_P(MediaCodecVideoDecoderTest,
       OverlayInfoIsNotRequestedIfOverlaysNotSupported) {
  Initialize(TestVideoConfig::Large(codec_));
  ON_CALL(*device_info_, SupportsOverlaySurfaces())
      .WillByDefault(Return(false));
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
  ASSERT_FALSE(provide_overlay_info_cb_);
}

TEST_P(MediaCodecVideoDecoderTest, RestartForOverlayTransitionsFlagIsCorrect) {
  ON_CALL(*device_info_, IsSetOutputSurfaceSupported())
      .WillByDefault(Return(true));
  Initialize(TestVideoConfig::Large(codec_));
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
  ASSERT_FALSE(restart_for_transitions_);
}

TEST_P(MediaCodecVideoDecoderTest,
       OverlayInfoIsNotRequestedIfThreadedTextureMailboxesEnabled) {
  gpu_preferences_.enable_threaded_texture_mailboxes = true;
  Initialize(TestVideoConfig::Large(codec_));
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
  ASSERT_FALSE(provide_overlay_info_cb_);
}

TEST_P(MediaCodecVideoDecoderTest, OverlayInfoDuringInitUpdatesSurfaceChooser) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));
  EXPECT_CALL(*surface_chooser_, MockUpdateState());
  provide_overlay_info_cb_.Run(OverlayInfo());
}

TEST_P(MediaCodecVideoDecoderTest, CodecIsCreatedAfterSurfaceChosen) {
  Initialize(TestVideoConfig::Large(codec_));
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
  provide_overlay_info_cb_.Run(OverlayInfo());
  EXPECT_CALL(*codec_allocator_, MockCreateMediaCodecAsync());
  surface_chooser_->ProvideTextureOwner();
}

TEST_P(MediaCodecVideoDecoderTest, FrameFactoryInitFailureIsAnError) {
  Initialize(TestVideoConfig::Large(codec_));
  ON_CALL(*video_frame_factory_, Initialize(ExpectedOverlayMode(), _))
      .WillByDefault(RunCallback<1>(nullptr));
  EXPECT_CALL(decode_cb_, Run(IsDecodeErrorStatus())).Times(1);
  EXPECT_CALL(*surface_chooser_, MockUpdateState()).Times(0);
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
}

TEST_P(MediaCodecVideoDecoderTest, CodecCreationFailureIsAnError) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
  EXPECT_CALL(decode_cb_, Run(IsDecodeErrorStatus())).Times(2);
  // Failing to create a codec should put MCVD into an error state.
  codec_allocator_->ProvideNullCodecAsync();
}

TEST_P(MediaCodecVideoDecoderTest, CodecFailuresAreAnError) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  EXPECT_CALL(*codec, DequeueInputBuffer(_, _))
      .WillOnce(Return(MEDIA_CODEC_ERROR));
  EXPECT_CALL(decode_cb_, Run(IsDecodeErrorStatus()));
  PumpCodec();
}

TEST_P(MediaCodecVideoDecoderTest, AfterInitCompletesTheCodecIsPolled) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  // Run a RunLoop until the first time the codec is polled for an available
  // input buffer.
  base::RunLoop loop;
  EXPECT_CALL(*codec, DequeueInputBuffer(_, _))
      .WillOnce(InvokeWithoutArgs([&loop]() {
        loop.Quit();
        return MEDIA_CODEC_TRY_AGAIN_LATER;
      }));
  loop.Run();
}

TEST_P(MediaCodecVideoDecoderTest, CodecIsReleasedOnDestruction) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  EXPECT_CALL(*codec_allocator_, MockReleaseMediaCodec(codec));
}

TEST_P(MediaCodecVideoDecoderTest, SurfaceChooserIsUpdatedOnOverlayChanges) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));

  EXPECT_CALL(*surface_chooser_, MockReplaceOverlayFactory(_)).Times(2);
  OverlayInfo info;
  info.routing_token = base::UnguessableToken::Deserialize(1, 2);
  provide_overlay_info_cb_.Run(info);
  ASSERT_TRUE(surface_chooser_->factory_);
  info.routing_token = base::UnguessableToken::Deserialize(3, 4);
  provide_overlay_info_cb_.Run(info);
  ASSERT_TRUE(surface_chooser_->factory_);
}

TEST_P(MediaCodecVideoDecoderTest, OverlayInfoUpdatesAreIgnoredInStateError) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));
  // Enter the error state.
  codec_allocator_->ProvideNullCodecAsync();

  EXPECT_CALL(*surface_chooser_, MockUpdateState()).Times(0);
  OverlayInfo info;
  info.routing_token = base::UnguessableToken::Deserialize(1, 2);
  provide_overlay_info_cb_.Run(info);
}

TEST_P(MediaCodecVideoDecoderTest, DuplicateOverlayInfoUpdatesAreIgnored) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));

  // The second overlay info update should be ignored.
  EXPECT_CALL(*surface_chooser_, MockReplaceOverlayFactory(_)).Times(1);
  OverlayInfo info;
  info.routing_token = base::UnguessableToken::Deserialize(1, 2);
  provide_overlay_info_cb_.Run(info);
  provide_overlay_info_cb_.Run(info);
}

TEST_P(MediaCodecVideoDecoderTest, CodecIsCreatedWithChosenOverlay) {
  EXPECT_CALL(*codec_allocator_, MockCreateMediaCodecAsync());
  InitializeWithOverlay_OneDecodePending(TestVideoConfig::Large(codec_));
  EXPECT_TRUE(base::android::AttachCurrentThread()->IsSameObject(
      java_surface_.obj(),
      codec_allocator_->most_recent_config->surface.obj()));
}

TEST_P(MediaCodecVideoDecoderTest,
       CodecCreationWeakPtrIsInvalidatedBySurfaceDestroyed) {
  ON_CALL(*device_info_, IsSetOutputSurfaceSupported())
      .WillByDefault(Return(false));
  auto* overlay =
      InitializeWithOverlay_OneDecodePending(TestVideoConfig::Large(codec_));
  overlay->OnSurfaceDestroyed();

  // MCVD handles release of the MediaCodec after WeakPtr invalidation.
  EXPECT_CALL(*codec_allocator_, MockReleaseMediaCodec(NotNull()));
  auto* codec = codec_allocator_->ProvideMockCodecAsync();
  ASSERT_TRUE(!!codec);
}

TEST_P(MediaCodecVideoDecoderTest, SurfaceChangedWhileCodecCreationPending) {
  auto* overlay =
      InitializeWithOverlay_OneDecodePending(TestVideoConfig::Large(codec_));
  overlay->OnSurfaceDestroyed();
  auto codec = std::make_unique<NiceMock<MockMediaCodecBridge>>();

  // SetSurface() is called as soon as the codec is created to switch away from
  // the destroyed surface.
  EXPECT_CALL(*codec, SetSurface(_)).WillOnce(Return(true));
  codec_allocator_->ProvideMockCodecAsync(std::move(codec));
}

TEST_P(MediaCodecVideoDecoderTest, SurfaceDestroyedDoesSyncSurfaceTransition) {
  auto* overlay =
      InitializeWithOverlay_OneDecodePending(TestVideoConfig::Large(codec_));
  auto* codec = codec_allocator_->ProvideMockCodecAsync();

  // MCVD must synchronously switch the codec's surface (to surface
  // texture), and delete the overlay.
  EXPECT_CALL(*codec, SetSurface(_)).WillOnce(Return(true));
  auto observer = overlay->CreateDestructionObserver();
  observer->ExpectDestruction();
  overlay->OnSurfaceDestroyed();
}

TEST_P(MediaCodecVideoDecoderTest,
       SurfaceDestroyedReleasesCodecIfSetSurfaceIsNotSupported) {
  ON_CALL(*device_info_, IsSetOutputSurfaceSupported())
      .WillByDefault(Return(false));
  auto* overlay =
      InitializeWithOverlay_OneDecodePending(TestVideoConfig::Large(codec_));
  auto* codec = codec_allocator_->ProvideMockCodecAsync();

  // MCVD must synchronously release the codec.
  EXPECT_CALL(*codec, SetSurface(_)).Times(0);
  EXPECT_CALL(*codec_allocator_, MockReleaseMediaCodec(codec));
  overlay->OnSurfaceDestroyed();
  // Verify expectations before we delete the MCVD.
  testing::Mock::VerifyAndClearExpectations(codec_allocator_.get());
}

TEST_P(MediaCodecVideoDecoderTest, PumpCodecPerformsPendingSurfaceTransitions) {
  InitializeWithOverlay_OneDecodePending(TestVideoConfig::Large(codec_));
  auto* codec = codec_allocator_->ProvideMockCodecAsync();

  // Set a pending surface transition and then call PumpCodec().
  surface_chooser_->ProvideTextureOwner();
  EXPECT_CALL(*codec, SetSurface(_)).WillOnce(Return(true));
  PumpCodec();
}

TEST_P(MediaCodecVideoDecoderTest,
       SetSurfaceFailureReleasesTheCodecAndSignalsError) {
  InitializeWithOverlay_OneDecodePending(TestVideoConfig::Large(codec_));
  auto* codec = codec_allocator_->ProvideMockCodecAsync();

  surface_chooser_->ProvideTextureOwner();
  EXPECT_CALL(*codec, SetSurface(_)).WillOnce(Return(false));
  EXPECT_CALL(decode_cb_, Run(IsDecodeErrorStatus())).Times(2);
  EXPECT_CALL(*codec_allocator_, MockReleaseMediaCodec(codec));
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
  // Verify expectations before we delete the MCVD.
  testing::Mock::VerifyAndClearExpectations(codec_allocator_.get());
}

TEST_P(MediaCodecVideoDecoderTest, SurfaceTransitionsCanBeCanceled) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));
  auto* codec = codec_allocator_->ProvideMockCodecAsync();

  // Set a pending transition to an overlay, and then back to a texture owner.
  // They should cancel each other out and leave the codec as-is.
  EXPECT_CALL(*codec, SetSurface(_)).Times(0);
  auto overlay = std::make_unique<MockAndroidOverlay>();
  auto observer = overlay->CreateDestructionObserver();
  surface_chooser_->ProvideOverlay(std::move(overlay));

  // Switching back to texture owner should delete the pending overlay.
  observer->ExpectDestruction();
  surface_chooser_->ProvideTextureOwner();
  observer.reset();

  // Verify that Decode() does not transition the surface
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
}

TEST_P(MediaCodecVideoDecoderTest, TransitionToSameSurfaceIsIgnored) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));
  auto* codec = codec_allocator_->ProvideMockCodecAsync();
  EXPECT_CALL(*codec, SetSurface(_)).Times(0);
  surface_chooser_->ProvideTextureOwner();
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
}

TEST_P(MediaCodecVideoDecoderTest,
       ResetBeforeCodecInitializedSucceedsImmediately) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));
  base::MockCallback<base::OnceClosure> reset_cb;
  EXPECT_CALL(reset_cb, Run());
  mcvd_->Reset(reset_cb.Get());
  testing::Mock::VerifyAndClearExpectations(&reset_cb);
}

TEST_P(MediaCodecVideoDecoderTest, ResetAbortsPendingDecodes) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));
  EXPECT_CALL(decode_cb_, Run(HasStatusCode(StatusCode::kAborted)));
  DoReset();
  testing::Mock::VerifyAndClearExpectations(&decode_cb_);
}

TEST_P(MediaCodecVideoDecoderTest, ResetAbortsPendingEosDecode) {
  // EOS is treated differently by MCVD. This verifies that it's also aborted.
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  base::MockCallback<VideoDecoder::DecodeCB> eos_decode_cb;
  mcvd_->Decode(DecoderBuffer::CreateEOSBuffer(), eos_decode_cb.Get());

  // Accept the two pending decodes.
  codec->AcceptOneInput();
  PumpCodec();
  codec->AcceptOneInput(MockMediaCodecBridge::kEos);
  PumpCodec();

  EXPECT_CALL(eos_decode_cb, Run(HasStatusCode(StatusCode::kAborted)));
  DoReset();
  // Should be run before |mcvd_| is destroyed.
  testing::Mock::VerifyAndClearExpectations(&eos_decode_cb);
}

TEST_P(MediaCodecVideoDecoderTest, ResetDoesNotFlushAnAlreadyFlushedCodec) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));

  // The codec is still in the flushed state so Reset() doesn't need to flush.
  EXPECT_CALL(*codec, Flush()).Times(0);
  base::MockCallback<base::OnceClosure> reset_cb;
  EXPECT_CALL(reset_cb, Run());
  mcvd_->Reset(reset_cb.Get());
  testing::Mock::VerifyAndClearExpectations(&decode_cb_);
}

TEST_P(MediaCodecVideoDecoderVp8Test, ResetDrainsVP8CodecsBeforeFlushing) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  // Accept the first decode to transition out of the flushed state.
  codec->AcceptOneInput();
  PumpCodec();

  // The reset should not complete immediately because the codec needs to be
  // drained.
  EXPECT_CALL(*codec, Flush()).Times(0);
  base::MockCallback<base::OnceClosure> reset_cb;
  EXPECT_CALL(reset_cb, Run()).Times(0);
  mcvd_->Reset(reset_cb.Get());

  // The next input should be an EOS.
  codec->AcceptOneInput(MockMediaCodecBridge::kEos);
  PumpCodec();
  testing::Mock::VerifyAndClearExpectations(codec);

  // After the EOS is dequeued, the reset should complete.
  EXPECT_CALL(reset_cb, Run());
  codec->ProduceOneOutput(MockMediaCodecBridge::kEos);
  PumpCodec();
  testing::Mock::VerifyAndClearExpectations(&reset_cb);
}

TEST_P(MediaCodecVideoDecoderVp8Test, ResetDoesNotDrainVp8WithAsyncApi) {
  EXPECT_CALL(*device_info_, IsAsyncApiSupported())
      .WillRepeatedly(Return(true));

  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  // Accept the first decode to transition out of the flushed state.
  codec->AcceptOneInput();
  PumpCodec();

  // The reset should complete immediately because the codec is not VP8 so
  // it doesn't need draining.  We don't expect a call to Flush on the codec
  // since it will be deferred until the first decode after the reset.
  base::MockCallback<base::OnceClosure> reset_cb;
  EXPECT_CALL(reset_cb, Run());
  mcvd_->Reset(reset_cb.Get());
  // The reset should complete before destroying the codec, since TearDown will
  // complete the drain for VP8.  It still might not call reset since a drain
  // for destroy probably doesn't, but either way we expect it before the drain.
  testing::Mock::VerifyAndClearExpectations(&reset_cb);
}

TEST_P(MediaCodecVideoDecoderH264Test, ResetDoesNotDrainNonVp8Codecs) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  // Accept the first decode to transition out of the flushed state.
  codec->AcceptOneInput();
  PumpCodec();

  // The reset should complete immediately because the codec is not VP8 so
  // it doesn't need draining.  We don't expect a call to Flush on the codec
  // since it will be deferred until the first decode after the reset.
  base::MockCallback<base::OnceClosure> reset_cb;
  EXPECT_CALL(reset_cb, Run());
  mcvd_->Reset(reset_cb.Get());
  // The reset should complete before destroying the codec, since TearDown will
  // complete the drain for VP8.  It still might not call reset since a drain
  // for destroy probably doesn't, but either way we expect it before the drain.
  testing::Mock::VerifyAndClearExpectations(&reset_cb);
}

TEST_P(MediaCodecVideoDecoderVp8Test, TeardownCompletesPendingReset) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));

  // Accept the first decode to transition out of the flushed state.
  codec->AcceptOneInput();
  PumpCodec();

  base::MockCallback<base::OnceClosure> reset_cb;
  EXPECT_CALL(reset_cb, Run()).Times(0);
  mcvd_->Reset(reset_cb.Get());
  EXPECT_CALL(reset_cb, Run());
  mcvd_.reset();

  // VP8 codecs requiring draining for teardown to complete (tested below).
  codec->ProduceOneOutput(MockMediaCodecBridge::kEos);
  PumpCodec();
}

TEST_P(MediaCodecVideoDecoderTest, CodecFlushIsDeferredAfterDraining) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  mcvd_->Decode(DecoderBuffer::CreateEOSBuffer(), decode_cb_.Get());

  // Produce one output that VFF will hold onto.
  codec->AcceptOneInput();
  codec->ProduceOneOutput();
  PumpCodec();

  // Drain the codec.
  EXPECT_CALL(*codec, Flush()).Times(0);
  codec->AcceptOneInput(MockMediaCodecBridge::kEos);
  codec->ProduceOneOutput(MockMediaCodecBridge::kEos);
  PumpCodec();

  // Create a pending decode. The codec should still not be flushed because
  // there is an unrendered output buffer.
  mcvd_->Decode(fake_decoder_buffer_, decode_cb_.Get());
  PumpCodec();

  // Releasing the output buffer should now trigger a flush.
  video_frame_factory_->last_output_buffer_.reset();
  EXPECT_CALL(*codec, Flush());
  PumpCodec();
}

TEST_P(MediaCodecVideoDecoderTest, EosDecodeCbIsRunAfterEosIsDequeued) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  codec->AcceptOneInput();
  PumpCodec();

  base::MockCallback<VideoDecoder::DecodeCB> eos_decode_cb;
  EXPECT_CALL(eos_decode_cb, Run(_)).Times(0);
  mcvd_->Decode(DecoderBuffer::CreateEOSBuffer(), eos_decode_cb.Get());
  codec->AcceptOneInput(MockMediaCodecBridge::kEos);
  PumpCodec();

  // On dequeueing EOS, MCVD will post a closure to run eos_decode_cb after
  // pending video frames.
  EXPECT_CALL(*video_frame_factory_, MockRunAfterPendingVideoFrames(_));
  codec->ProduceOneOutput(MockMediaCodecBridge::kEos);
  PumpCodec();

  EXPECT_CALL(eos_decode_cb, Run(IsOkStatus()));
  std::move(video_frame_factory_->last_closure_).Run();
}

TEST_P(MediaCodecVideoDecoderTest, TeardownInvalidatesCodecCreationWeakPtr) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));
  mcvd_.reset();
  EXPECT_CALL(*codec_allocator_, MockReleaseMediaCodec(NotNull()));
  ASSERT_TRUE(codec_allocator_->ProvideMockCodecAsync());
}

TEST_P(MediaCodecVideoDecoderTest,
       TeardownInvalidatesCodecCreationWeakPtrButDoesNotCallReleaseMediaCodec) {
  InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_));
  mcvd_.reset();

  // A null codec should not be released via ReleaseMediaCodec().
  EXPECT_CALL(*codec_allocator_, MockReleaseMediaCodec(_)).Times(0);
  codec_allocator_->ProvideNullCodecAsync();
}

TEST_P(MediaCodecVideoDecoderTest, TeardownDoesNotDrainFlushedCodecs) {
  InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  // Since we assert that MCVD is destructed by default, this test verifies that
  // MCVD is destructed without requiring the codec to output an EOS buffer.

  // We assert this since, otherwise, we'll complete the drain for VP8 codecs in
  // TearDown.  This guarantees that we won't, so any drain started by MCVD
  // won't complete.  Otherwise, this tests nothing.  Note that 'Drained' here
  // is a bit of a misnomer; the mock codec doesn't track flushed.
  ASSERT_TRUE(codec_allocator_->most_recent_codec->IsDrained());
}

TEST_P(MediaCodecVideoDecoderH264Test, TeardownDoesNotDrainNonVp8Codecs) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  // Accept the first decode to transition out of the flushed state.
  codec->AcceptOneInput();
  PumpCodec();
  // Since we assert that MCVD is destructed by default, this test verifies that
  // MCVD is destructed without requiring the codec to output an EOS buffer.
  // Remember that we do not complete the drain for non-VP8 codecs in TearDown.
}

TEST_P(MediaCodecVideoDecoderVp8Test,
       TeardownDrainsVp8CodecsBeforeDestruction) {
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));
  // Accept the first decode to transition out of the flushed state.
  codec->AcceptOneInput();
  PumpCodec();

  // MCVD should not be destructed immediately.
  mcvd_.reset();
  base::RunLoop().RunUntilIdle();

  // It should be destructed after draining completes.
  codec->AcceptOneInput(MockMediaCodecBridge::kEos);
  codec->ProduceOneOutput(MockMediaCodecBridge::kEos);
  EXPECT_CALL(*codec, Flush()).Times(0);
  PumpCodec();
  base::RunLoop().RunUntilIdle();
}

TEST_P(MediaCodecVideoDecoderTest, CdmInitializationWorksForL3) {
  // Make sure that MCVD uses the cdm, and sends it along to the codec.
  CreateCdm(true, false);
  InitializeWithOverlay_OneDecodePending(
      TestVideoConfig::NormalEncrypted(codec_));
  ASSERT_TRUE(!!cdm_->ran_media_crypto_ready_cb);
  ASSERT_EQ(surface_chooser_->current_state_.is_secure, true);
  ASSERT_EQ(surface_chooser_->current_state_.is_required, false);
  ASSERT_EQ(codec_allocator_->most_recent_config->codec_type, CodecType::kAny);
  // We can't check for equality safely, but verify that something was provided.
  ASSERT_TRUE(codec_allocator_->most_recent_config->media_crypto);
}

TEST_P(MediaCodecVideoDecoderTest, CdmInitializationWorksForL1) {
  // Make sure that MCVD uses the cdm, and sends it along to the codec.
  CreateCdm(true, true);
  InitializeWithOverlay_OneDecodePending(
      TestVideoConfig::NormalEncrypted(codec_));
  ASSERT_TRUE(!!cdm_->ran_media_crypto_ready_cb);
  ASSERT_EQ(surface_chooser_->current_state_.is_secure, true);
  ASSERT_EQ(surface_chooser_->current_state_.is_required, true);
  ASSERT_EQ(codec_allocator_->most_recent_config->codec_type,
            CodecType::kSecure);
  ASSERT_TRUE(codec_allocator_->most_recent_config->media_crypto);
}

TEST_P(MediaCodecVideoDecoderTest, CdmIsSetEvenForClearStream) {
  // Make sure that MCVD uses the cdm, and sends it along to the codec.
  CreateCdm(true, false);
  // We use the Large config, since VPx can be rejected if it's too small, in
  // favor of software decode, since this is unencrypted.
  InitializeWithOverlay_OneDecodePending(TestVideoConfig::Large(codec_));
  ASSERT_TRUE(!!cdm_->ran_media_crypto_ready_cb);
  ASSERT_EQ(surface_chooser_->current_state_.is_secure, true);
  ASSERT_EQ(surface_chooser_->current_state_.is_required, false);
  ASSERT_NE(codec_allocator_->most_recent_config->codec_type,
            CodecType::kSecure);
  // We can't check for equality safely, but verify that something was provided.
  ASSERT_TRUE(codec_allocator_->most_recent_config->media_crypto);
}

TEST_P(MediaCodecVideoDecoderTest, NoMediaCryptoContext_ClearStream) {
  // Make sure that MCVD initializes for clear stream when MediaCryptoContext
  // is not available.
  CreateCdm(false, false);
  InitializeWithOverlay_OneDecodePending(TestVideoConfig::Normal(codec_));
  ASSERT_FALSE(!!cdm_->media_crypto_ready_cb);
  ASSERT_FALSE(!!cdm_->ran_media_crypto_ready_cb);
  ASSERT_EQ(surface_chooser_->current_state_.is_secure, false);
  ASSERT_EQ(surface_chooser_->current_state_.is_required, false);
  ASSERT_NE(codec_allocator_->most_recent_config->codec_type,
            CodecType::kSecure);
  ASSERT_FALSE(codec_allocator_->most_recent_config->media_crypto);
}

TEST_P(MediaCodecVideoDecoderTest, NoMediaCryptoContext_EncryptedStream) {
  // Make sure that MCVD fails to initialize for encrypted stream when
  // MediaCryptoContext is not available.
  CreateCdm(false, false);
  ASSERT_FALSE(Initialize(TestVideoConfig::NormalEncrypted(codec_)));
}

TEST_P(MediaCodecVideoDecoderTest, MissingMediaCryptoFailsInit) {
  // Encrypted media that doesn't get a mediacrypto should fail to init.
  CreateCdm(true, true);
  media_crypto_ = nullptr;
  ASSERT_FALSE(Initialize(TestVideoConfig::NormalEncrypted(codec_)));
}

TEST_P(MediaCodecVideoDecoderTest, MissingCdmFailsInit) {
  // MCVD should fail init if we don't provide a cdm with an encrypted config.
  ASSERT_FALSE(Initialize(TestVideoConfig::NormalEncrypted(codec_)));
}

TEST_P(MediaCodecVideoDecoderTest, VideoFramesArePowerEfficient) {
  // MCVD should mark video frames as POWER_EFFICIENT.
  auto* codec =
      InitializeFully_OneDecodePending(TestVideoConfig::Large(codec_));

  // Produce one output.
  codec->AcceptOneInput();
  codec->ProduceOneOutput();
  EXPECT_CALL(*video_frame_factory_, MockCreateVideoFrame(_, _, _, _, _));
  PumpCodec();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(!!most_recent_frame_);
  EXPECT_TRUE(most_recent_frame_->metadata().power_efficient);
}

TEST_P(MediaCodecVideoDecoderH264Test, CsdIsIncludedInCodecConfig) {
  // Make sure that any CSD is included in the CodecConfig that MCVD uses to
  // allocate the codec.
  VideoDecoderConfig config = TestVideoConfig::NormalH264();

  // Csd, excluding '0 0 0 1'.
  std::vector<uint8_t> csd0 = {103, 77,  64, 30,  232, 128, 80, 23,
                               252, 184, 8,  128, 0,   0,   3,  0,
                               128, 0,   0,  30,  7,   139, 22, 137};
  std::vector<uint8_t> csd1 = {104, 235, 239, 32};
  std::vector<uint8_t> extra_data_separator = {1, 0, 4};
  std::vector<uint8_t> extra_data = {1, 77, 64, 30, 255, 225, 0, 24};
  extra_data.insert(extra_data.end(), csd0.begin(), csd0.end());
  extra_data.insert(extra_data.end(), extra_data_separator.begin(),
                    extra_data_separator.end());
  extra_data.insert(extra_data.end(), csd1.begin(), csd1.end());
  config.SetExtraData(extra_data);

  EXPECT_TRUE(InitializeFully_OneDecodePending(config));

  // Prepend the headers and check for equality.
  std::vector<uint8_t> csd_header = {0, 0, 0, 1};
  csd0.insert(csd0.begin(), csd_header.begin(), csd_header.end());
  EXPECT_EQ(csd0, codec_allocator_->most_recent_config->csd0);
  csd1.insert(csd1.begin(), csd_header.begin(), csd_header.end());
  EXPECT_EQ(csd1, codec_allocator_->most_recent_config->csd1);
}

TEST_P(MediaCodecVideoDecoderVp9Test, ColorSpaceIsIncludedInCodecConfig) {
  VideoColorSpace color_space(VideoColorSpace::PrimaryID::BT2020,
                              VideoColorSpace::TransferID::SMPTEST2084,
                              VideoColorSpace::MatrixID::BT2020_CL,
                              gfx::ColorSpace::RangeID::LIMITED);
  VideoDecoderConfig config =
      TestVideoConfig::NormalWithColorSpace(VideoCodec::kVP9, color_space);
  EXPECT_TRUE(InitializeFully_OneDecodePending(config));

  EXPECT_EQ(color_space,
            codec_allocator_->most_recent_config->container_color_space);
}

TEST_P(MediaCodecVideoDecoderVp9Test, HdrMetadataIsIncludedInCodecConfig) {
  VideoDecoderConfig config = TestVideoConfig::Normal(VideoCodec::kVP9);
  gfx::HDRMetadata hdr_metadata;
  hdr_metadata.max_frame_average_light_level = 123;
  hdr_metadata.max_content_light_level = 456;
  hdr_metadata.color_volume_metadata.primary_r.set_x(0.1f);
  hdr_metadata.color_volume_metadata.primary_r.set_y(0.2f);
  hdr_metadata.color_volume_metadata.primary_g.set_x(0.3f);
  hdr_metadata.color_volume_metadata.primary_g.set_y(0.4f);
  hdr_metadata.color_volume_metadata.primary_b.set_x(0.5f);
  hdr_metadata.color_volume_metadata.primary_b.set_y(0.6f);
  hdr_metadata.color_volume_metadata.white_point.set_x(0.7f);
  hdr_metadata.color_volume_metadata.white_point.set_y(0.8f);
  hdr_metadata.color_volume_metadata.luminance_max = 1000;
  hdr_metadata.color_volume_metadata.luminance_min = 0;

  config.set_hdr_metadata(hdr_metadata);

  EXPECT_TRUE(InitializeFully_OneDecodePending(config));

  EXPECT_EQ(hdr_metadata, codec_allocator_->most_recent_config->hdr_metadata);
}

static std::vector<VideoCodec> GetTestList() {
  std::vector<VideoCodec> test_codecs;

#if BUILDFLAG(USE_PROPRIETARY_CODECS)
  if (MediaCodecUtil::IsMediaCodecAvailable())
    test_codecs.push_back(VideoCodec::kH264);
#endif

  if (MediaCodecUtil::IsVp8DecoderAvailable())
    test_codecs.push_back(VideoCodec::kVP8);
  if (MediaCodecUtil::IsVp9DecoderAvailable())
    test_codecs.push_back(VideoCodec::kVP9);
  if (MediaCodecUtil::IsAv1DecoderAvailable())
    test_codecs.push_back(VideoCodec::kAV1);
  return test_codecs;
}

#if BUILDFLAG(USE_PROPRIETARY_CODECS)
static std::vector<VideoCodec> GetH264IfAvailable() {
  return MediaCodecUtil::IsMediaCodecAvailable()
             ? std::vector<VideoCodec>(1, VideoCodec::kH264)
             : std::vector<VideoCodec>();
}
#endif

static std::vector<VideoCodec> GetVp8IfAvailable() {
  return MediaCodecUtil::IsVp8DecoderAvailable()
             ? std::vector<VideoCodec>(1, VideoCodec::kVP8)
             : std::vector<VideoCodec>();
}

// TODO(https://crbug.com/1179801): Uncomment once MediaCodecVideoDecoderVp9Test
// is fixed.
// static std::vector<VideoCodec> GetVp9IfAvailable() {
//   return MediaCodecUtil::IsVp9DecoderAvailable()
//              ? std::vector<VideoCodec>(1, VideoCodec::kVP9)
//              : std::vector<VideoCodec>();
// }

static std::vector<VideoCodec> GetAv1IfAvailable() {
  return MediaCodecUtil::IsAv1DecoderAvailable()
             ? std::vector<VideoCodec>(1, VideoCodec::kAV1)
             : std::vector<VideoCodec>();
}

INSTANTIATE_TEST_SUITE_P(MediaCodecVideoDecoderTest,
                         MediaCodecVideoDecoderTest,
                         testing::ValuesIn(GetTestList()));

#if BUILDFLAG(USE_PROPRIETARY_CODECS)
INSTANTIATE_TEST_SUITE_P(MediaCodecVideoDecoderH264Test,
                         MediaCodecVideoDecoderH264Test,
                         testing::ValuesIn(GetH264IfAvailable()));
#endif

INSTANTIATE_TEST_SUITE_P(MediaCodecVideoDecoderVp8Test,
                         MediaCodecVideoDecoderVp8Test,
                         testing::ValuesIn(GetVp8IfAvailable()));

// TODO(https://crbug.com/1179801): Uncomment once MediaCodecVideoDecoderVp9Test
// is fixed.
// INSTANTIATE_TEST_SUITE_P(MediaCodecVideoDecoderVp9Test,
//                          MediaCodecVideoDecoderVp9Test,
//                          testing::ValuesIn(GetVp9IfAvailable()));

INSTANTIATE_TEST_SUITE_P(MediaCodecVideoDecoderAV1Test,
                         MediaCodecVideoDecoderAV1Test,
                         testing::ValuesIn(GetAv1IfAvailable()));

// TODO(https://crbug.com/1179801): Remove this annotation once
// MediaCodecVideoDecoderVp9Test is fixed.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaCodecVideoDecoderVp9Test);
// This test suite is empty on some OSes.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaCodecVideoDecoderAV1Test);
// For builds without proprietary codecs
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaCodecVideoDecoderH264Test);

}  // namespace media
