// 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_ == kCodecVP8 && 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(kCodecAV1)));
}

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(kCodecVP9, 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(kCodecVP9);
  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(kCodecH264);
#endif

  if (MediaCodecUtil::IsVp8DecoderAvailable())
    test_codecs.push_back(kCodecVP8);
  if (MediaCodecUtil::IsVp9DecoderAvailable())
    test_codecs.push_back(kCodecVP9);
  if (MediaCodecUtil::IsAv1DecoderAvailable())
    test_codecs.push_back(kCodecAV1);
  return test_codecs;
}

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

static std::vector<VideoCodec> GetVp8IfAvailable() {
  return MediaCodecUtil::IsVp8DecoderAvailable()
             ? std::vector<VideoCodec>(1, kCodecVP8)
             : 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, kCodecVP9)
//              : std::vector<VideoCodec>();
// }

static std::vector<VideoCodec> GetAv1IfAvailable() {
  return MediaCodecUtil::IsAv1DecoderAvailable()
             ? std::vector<VideoCodec>(1, kCodecAV1)
             : 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
