// Copyright 2017 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/vaapi/vaapi_video_decode_accelerator.h"

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/task_environment.h"
#include "media/gpu/accelerated_video_decoder.h"
#include "media/gpu/vaapi/vaapi_picture.h"
#include "media/gpu/vaapi/vaapi_picture_factory.h"
#include "media/gpu/vaapi/vaapi_video_decoder_delegate.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::test::RunClosure;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::TestWithParam;
using ::testing::ValuesIn;
using ::testing::WithArg;

namespace media {

namespace {

struct TestParams {
  VideoCodecProfile video_codec;
  bool decode_using_client_picture_buffers;
};

constexpr int32_t kBitstreamId = 123;
constexpr size_t kInputSize = 256;

constexpr size_t kNumPictures = 14;
const gfx::Size kPictureSize(64, 48);

constexpr size_t kNewNumPictures = 13;
const gfx::Size kNewPictureSize(64, 48);

MATCHER_P2(IsExpectedDecoderBuffer, data_size, decrypt_config, "") {
  return arg.data_size() == data_size && arg.decrypt_config() == decrypt_config;
}
}  // namespace

class MockAcceleratedVideoDecoder : public AcceleratedVideoDecoder {
 public:
  MockAcceleratedVideoDecoder() = default;
  ~MockAcceleratedVideoDecoder() override = default;

  MOCK_METHOD2(SetStream, void(int32_t id, const DecoderBuffer&));
  MOCK_METHOD0(Flush, bool());
  MOCK_METHOD0(Reset, void());
  MOCK_METHOD0(Decode, DecodeResult());
  MOCK_CONST_METHOD0(GetPicSize, gfx::Size());
  MOCK_CONST_METHOD0(GetProfile, VideoCodecProfile());
  MOCK_CONST_METHOD0(GetBitDepth, uint8_t());
  MOCK_CONST_METHOD0(GetVisibleRect, gfx::Rect());
  MOCK_CONST_METHOD0(GetRequiredNumOfPictures, size_t());
  MOCK_CONST_METHOD0(GetNumReferenceFrames, size_t());
};

class MockVaapiWrapper : public VaapiWrapper {
 public:
  MockVaapiWrapper(CodecMode mode) : VaapiWrapper(mode) {}
  MOCK_METHOD5(CreateContextAndSurfaces,
               bool(unsigned int,
                    const gfx::Size&,
                    const std::vector<SurfaceUsageHint>&,
                    size_t,
                    std::vector<VASurfaceID>*));
  MOCK_METHOD1(CreateContext, bool(const gfx::Size&));
  MOCK_METHOD0(DestroyContext, void());
  MOCK_METHOD1(DestroySurface, void(VASurfaceID));

 private:
  ~MockVaapiWrapper() override = default;
};

class MockVaapiPicture : public VaapiPicture {
 public:
  MockVaapiPicture(scoped_refptr<VaapiWrapper> vaapi_wrapper,
                   const MakeGLContextCurrentCallback& make_context_current_cb,
                   const BindGLImageCallback& bind_image_cb,
                   int32_t picture_buffer_id,
                   const gfx::Size& size,
                   const gfx::Size& visible_size,
                   uint32_t texture_id,
                   uint32_t client_texture_id,
                   uint32_t texture_target)
      : VaapiPicture(std::move(vaapi_wrapper),
                     make_context_current_cb,
                     bind_image_cb,
                     picture_buffer_id,
                     size,
                     visible_size,
                     texture_id,
                     client_texture_id,
                     texture_target) {}
  ~MockVaapiPicture() override = default;

  // VaapiPicture implementation.
  Status Allocate(gfx::BufferFormat format) override { return OkStatus(); }
  bool ImportGpuMemoryBufferHandle(
      gfx::BufferFormat format,
      gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) override {
    return true;
  }
  bool DownloadFromSurface(scoped_refptr<VASurface> va_surface) override {
    return true;
  }
  bool AllowOverlay() const override { return false; }
  VASurfaceID va_surface_id() const override {
    // Return any number different from VA_INVALID_ID and VaapiPicture specific.
    return static_cast<VASurfaceID>(texture_id_);
  }
};

class MockVaapiPictureFactory : public VaapiPictureFactory {
 public:
  MockVaapiPictureFactory() = default;
  ~MockVaapiPictureFactory() override = default;

  MOCK_METHOD3(MockCreateVaapiPicture,
               void(VaapiWrapper*, const gfx::Size&, const gfx::Size&));
  std::unique_ptr<VaapiPicture> Create(
      scoped_refptr<VaapiWrapper> vaapi_wrapper,
      const MakeGLContextCurrentCallback& make_context_current_cb,
      const BindGLImageCallback& bind_image_cb,
      const PictureBuffer& picture_buffer,
      const gfx::Size& visible_size) override {
    const uint32_t service_texture_id = picture_buffer.service_texture_ids()[0];
    const uint32_t client_texture_id = picture_buffer.client_texture_ids()[0];
    MockCreateVaapiPicture(vaapi_wrapper.get(), picture_buffer.size(),
                           visible_size);
    return std::make_unique<MockVaapiPicture>(
        std::move(vaapi_wrapper), make_context_current_cb, bind_image_cb,
        picture_buffer.id(), picture_buffer.size(), visible_size,
        service_texture_id, client_texture_id, picture_buffer.texture_target());
  }
};

class VaapiVideoDecodeAcceleratorTest : public TestWithParam<TestParams>,
                                        public VideoDecodeAccelerator::Client {
 public:
  VaapiVideoDecodeAcceleratorTest()
      : vda_(
            base::BindRepeating([] { return true; }),
            base::BindRepeating([](uint32_t client_texture_id,
                                   uint32_t texture_target,
                                   const scoped_refptr<gl::GLImage>& image,
                                   bool can_bind_to_sampler) { return true; })),
        decoder_thread_("VaapiVideoDecodeAcceleratorTestThread"),
        mock_decoder_(new ::testing::StrictMock<MockAcceleratedVideoDecoder>),
        mock_vaapi_picture_factory_(new MockVaapiPictureFactory()),
        mock_vaapi_wrapper_(new MockVaapiWrapper(VaapiWrapper::kDecode)),
        mock_vpp_vaapi_wrapper_(new MockVaapiWrapper(VaapiWrapper::kDecode)),
        weak_ptr_factory_(this) {
    decoder_thread_.Start();

    // Don't want to go through a vda_->Initialize() because it binds too many
    // items of the environment. Instead, do all the necessary steps here.

    vda_.decoder_thread_task_runner_ = decoder_thread_.task_runner();

    decoder_delegate_ = std::make_unique<VaapiVideoDecoderDelegate>(
        &vda_, mock_vaapi_wrapper_, base::DoNothing(), nullptr);

    // Plug in all the mocks and ourselves as the |client_|.
    vda_.decoder_.reset(mock_decoder_);
    vda_.decoder_delegate_ = decoder_delegate_.get();
    vda_.client_ = weak_ptr_factory_.GetWeakPtr();
    vda_.vaapi_wrapper_ = mock_vaapi_wrapper_;
    vda_.vpp_vaapi_wrapper_ = mock_vpp_vaapi_wrapper_;
    vda_.vaapi_picture_factory_.reset(mock_vaapi_picture_factory_);

    // TODO(crbug.com/917999): add IMPORT mode to test variations.
    vda_.output_mode_ = VideoDecodeAccelerator::Config::OutputMode::ALLOCATE;
    vda_.profile_ = GetParam().video_codec;
    vda_.buffer_allocation_mode_ =
        GetParam().decode_using_client_picture_buffers
            ? VaapiVideoDecodeAccelerator::BufferAllocationMode::kNone
            : VaapiVideoDecodeAccelerator::BufferAllocationMode::kSuperReduced;

    vda_.state_ = VaapiVideoDecodeAccelerator::kIdle;
  }

  VaapiVideoDecodeAcceleratorTest(const VaapiVideoDecodeAcceleratorTest&) =
      delete;
  VaapiVideoDecodeAcceleratorTest& operator=(
      const VaapiVideoDecodeAcceleratorTest&) = delete;

  ~VaapiVideoDecodeAcceleratorTest() {}

  void SetUp() override {
    in_shm_ = base::UnsafeSharedMemoryRegion::Create(kInputSize);
  }

  void SetVdaStateToUnitialized() {
    base::AutoLock auto_lock(vda_.lock_);
    vda_.state_ = VaapiVideoDecodeAccelerator::kUninitialized;
  }

  void QueueInputBuffer(BitstreamBuffer bitstream_buffer) {
    auto id = bitstream_buffer.id();
    vda_.QueueInputBuffer(bitstream_buffer.ToDecoderBuffer(), id);
  }

  void AssignPictureBuffers(const std::vector<PictureBuffer>& picture_buffers) {
    vda_.AssignPictureBuffers(picture_buffers);
  }

  // Reset epilogue, needed to get |vda_| worker thread out of its Wait().
  void ResetSequence() {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_decoder_, Reset());
    EXPECT_CALL(*this, NotifyResetDone())
        .WillOnce(RunClosure(run_loop.QuitClosure()));
    vda_.Reset();
    run_loop.Run();
  }

  // Try and QueueInputBuffer()s, where we pretend that |mock_decoder_| requests
  // to kConfigChange: |vda_| will ping us to ProvidePictureBuffers().
  // If |expect_dismiss_picture_buffers| is signalled, then we expect as well
  // that |vda_| will emit |num_picture_buffers_to_dismiss| DismissPictureBuffer
  // calls.
  void QueueInputBufferSequence(size_t num_pictures,
                                const gfx::Size& picture_size,
                                int32_t bitstream_id,
                                bool expect_dismiss_picture_buffers = false,
                                size_t num_picture_buffers_to_dismiss = 0) {
    ::testing::InSequence s;
    EXPECT_CALL(*mock_decoder_,
                SetStream(_, IsExpectedDecoderBuffer(kInputSize, nullptr)))
        .WillOnce(Return());
    EXPECT_CALL(*mock_decoder_, Decode())
        .WillOnce(Return(AcceleratedVideoDecoder::kConfigChange));

    EXPECT_CALL(*mock_decoder_, GetBitDepth()).WillOnce(Return(8u));
    EXPECT_CALL(*mock_decoder_, GetPicSize()).WillOnce(Return(picture_size));
    EXPECT_CALL(*mock_decoder_, GetVisibleRect())
        .WillOnce(Return(gfx::Rect(picture_size)));
    EXPECT_CALL(*mock_decoder_, GetRequiredNumOfPictures())
        .WillOnce(Return(num_pictures));
    const size_t kNumReferenceFrames = num_pictures / 2;
    EXPECT_CALL(*mock_decoder_, GetNumReferenceFrames())
        .WillOnce(Return(kNumReferenceFrames));
    EXPECT_CALL(*mock_decoder_, GetProfile())
        .WillOnce(Return(GetParam().video_codec));
    EXPECT_CALL(*mock_vaapi_wrapper_, DestroyContext());

    if (expect_dismiss_picture_buffers) {
      EXPECT_CALL(*this, DismissPictureBuffer(_))
          .Times(num_picture_buffers_to_dismiss);
    }

    const size_t expected_num_picture_buffers_requested =
        vda_.buffer_allocation_mode_ ==
                VaapiVideoDecodeAccelerator::BufferAllocationMode::kSuperReduced
            ? num_pictures - kNumReferenceFrames
            : num_pictures;

    base::RunLoop run_loop;

    EXPECT_CALL(*this,
                ProvidePictureBuffers(expected_num_picture_buffers_requested, _,
                                      1, picture_size, _))
        .WillOnce(RunClosure(run_loop.QuitClosure()));

    auto region = base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
        in_shm_.Duplicate());
    BitstreamBuffer bitstream_buffer(bitstream_id, std::move(region),
                                     kInputSize);

    QueueInputBuffer(std::move(bitstream_buffer));
    run_loop.Run();
  }

  // Calls AssignPictureBuffers(), expecting the corresponding mock calls; we
  // pretend |mock_decoder_| has kRanOutOfStreamData (i.e. it's finished
  // decoding) and expect |vda_| to emit a NotifyEndOfBitstreamBuffer().
  // QueueInputBufferSequence() must have been called beforehand.
  void AssignPictureBuffersSequence(size_t num_pictures,
                                    const gfx::Size& picture_size,
                                    int32_t bitstream_id) {
    ASSERT_TRUE(vda_.curr_input_buffer_)
        << "QueueInputBuffer() should have been called";

    // |decode_using_client_picture_buffers| determines the concrete method for
    // creation of context, surfaces and VaapiPictures.
    if (GetParam().decode_using_client_picture_buffers) {
      EXPECT_CALL(*mock_vaapi_wrapper_, CreateContext(picture_size))
          .WillOnce(Return(true));
      EXPECT_CALL(*mock_decoder_, GetVisibleRect())
          .WillRepeatedly(Return(gfx::Rect(picture_size)));
      EXPECT_CALL(*mock_vaapi_picture_factory_,
                  MockCreateVaapiPicture(mock_vaapi_wrapper_.get(),
                                         picture_size, picture_size))
          .Times(num_pictures);
    } else {
      EXPECT_EQ(
          vda_.buffer_allocation_mode_,
          VaapiVideoDecodeAccelerator::BufferAllocationMode::kSuperReduced);
      const size_t kNumReferenceFrames = 1 + num_pictures / 2;
      EXPECT_CALL(*mock_vaapi_wrapper_,
                  CreateContextAndSurfaces(
                      _, picture_size,
                      std::vector<VaapiWrapper::SurfaceUsageHint>{
                          VaapiWrapper::SurfaceUsageHint::kVideoDecoder},
                      kNumReferenceFrames, _))
          .WillOnce(DoAll(
              WithArg<4>(Invoke([kNumReferenceFrames](
                                    std::vector<VASurfaceID>* va_surface_ids) {
                va_surface_ids->resize(kNumReferenceFrames);
              })),
              Return(true)));
      EXPECT_CALL(*mock_vaapi_wrapper_, DestroySurface(_))
          .Times(kNumReferenceFrames);
      EXPECT_CALL(*mock_decoder_, GetVisibleRect())
          .WillRepeatedly(Return(gfx::Rect(picture_size)));
      EXPECT_CALL(*mock_vaapi_picture_factory_,
                  MockCreateVaapiPicture(_, picture_size, picture_size))
          .Times(num_pictures);
    }

    ::testing::InSequence s;
    base::RunLoop run_loop;

    EXPECT_CALL(*mock_decoder_, Decode())
        .WillOnce(Return(AcceleratedVideoDecoder::kRanOutOfStreamData));
    EXPECT_CALL(*this, NotifyEndOfBitstreamBuffer(bitstream_id))
        .WillOnce(RunClosure(run_loop.QuitClosure()));

    const auto tex_target = mock_vaapi_picture_factory_->GetGLTextureTarget();
    int32_t irrelevant_id = 2;
    std::vector<PictureBuffer> picture_buffers;
    for (size_t picture = 0; picture < num_pictures; ++picture) {
      // The picture buffer id, client id and service texture ids are
      // arbitrarily chosen.
      picture_buffers.push_back(
          {irrelevant_id++, picture_size,
           PictureBuffer::TextureIds{static_cast<uint32_t>(irrelevant_id++)},
           PictureBuffer::TextureIds{static_cast<uint32_t>(irrelevant_id++)},
           tex_target, PIXEL_FORMAT_XRGB});
    }

    AssignPictureBuffers(picture_buffers);
    run_loop.Run();
  }

  // Calls QueueInputBuffer(); we instruct from |mock_decoder_| that it has
  // kRanOutOfStreamData (i.e. it's finished decoding). This is a fast method
  // because the Decode() is (almost) immediate.
  void DecodeOneFrameFast(int32_t bitstream_id) {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_decoder_,
                SetStream(_, IsExpectedDecoderBuffer(kInputSize, nullptr)))
        .WillOnce(Return());
    EXPECT_CALL(*mock_decoder_, Decode())
        .WillOnce(Return(AcceleratedVideoDecoder::kRanOutOfStreamData));
    EXPECT_CALL(*this, NotifyEndOfBitstreamBuffer(bitstream_id))
        .WillOnce(RunClosure(run_loop.QuitClosure()));

    auto region = base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
        in_shm_.Duplicate());
    QueueInputBuffer(
        BitstreamBuffer(bitstream_id, std::move(region), kInputSize));

    run_loop.Run();
  }

  // VideoDecodeAccelerator::Client methods.
  MOCK_METHOD1(NotifyInitializationComplete, void(Status));
  MOCK_METHOD5(
      ProvidePictureBuffers,
      void(uint32_t, VideoPixelFormat, uint32_t, const gfx::Size&, uint32_t));
  MOCK_METHOD1(DismissPictureBuffer, void(int32_t));
  MOCK_METHOD1(PictureReady, void(const Picture&));
  MOCK_METHOD1(NotifyEndOfBitstreamBuffer, void(int32_t));
  MOCK_METHOD0(NotifyFlushDone, void());
  MOCK_METHOD0(NotifyResetDone, void());
  MOCK_METHOD1(NotifyError, void(VideoDecodeAccelerator::Error));

  base::test::TaskEnvironment task_environment_;

  std::unique_ptr<VaapiVideoDecoderDelegate> decoder_delegate_;

  // The class under test and a worker thread for it.
  VaapiVideoDecodeAccelerator vda_;
  base::Thread decoder_thread_;

  // Ownership passed to |vda_|, but we retain a pointer to it for MOCK checks.
  MockAcceleratedVideoDecoder* mock_decoder_;
  MockVaapiPictureFactory* mock_vaapi_picture_factory_;

  scoped_refptr<MockVaapiWrapper> mock_vaapi_wrapper_;
  scoped_refptr<MockVaapiWrapper> mock_vpp_vaapi_wrapper_;

  base::UnsafeSharedMemoryRegion in_shm_;

 private:
  base::WeakPtrFactory<VaapiVideoDecodeAcceleratorTest> weak_ptr_factory_;
};

// Verify that it is possible to select DRM(egl) and TFP(glx) at runtime.
TEST_P(VaapiVideoDecodeAcceleratorTest, SupportedPlatforms) {
  EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationNone,
            mock_vaapi_picture_factory_->GetVaapiImplementation(
                gl::kGLImplementationNone));
  EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationDrm,
            mock_vaapi_picture_factory_->GetVaapiImplementation(
                gl::kGLImplementationEGLGLES2));

#if BUILDFLAG(USE_VAAPI_X11)
  EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationX11,
            mock_vaapi_picture_factory_->GetVaapiImplementation(
                gl::kGLImplementationDesktopGL));
#endif
}

// This test checks that QueueInputBuffer() fails when state is kUnitialized.
TEST_P(VaapiVideoDecodeAcceleratorTest,
       QueueInputBufferAndErrorWhenVDAUninitialized) {
  SetVdaStateToUnitialized();

  auto region = base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
      in_shm_.Duplicate());
  BitstreamBuffer bitstream_buffer(kBitstreamId, std::move(region), kInputSize);

  EXPECT_CALL(*this,
              NotifyError(VaapiVideoDecodeAccelerator::PLATFORM_FAILURE));
  QueueInputBuffer(std::move(bitstream_buffer));
}

// Verifies that Decode() returning kDecodeError ends up pinging NotifyError().
TEST_P(VaapiVideoDecodeAcceleratorTest, QueueInputBufferAndDecodeError) {
  auto region = base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
      in_shm_.Duplicate());
  BitstreamBuffer bitstream_buffer(kBitstreamId, std::move(region), kInputSize);

  base::RunLoop run_loop;
  EXPECT_CALL(*mock_decoder_,
              SetStream(_, IsExpectedDecoderBuffer(kInputSize, nullptr)))
      .WillOnce(Return());
  EXPECT_CALL(*mock_decoder_, Decode())
      .WillOnce(Return(AcceleratedVideoDecoder::kDecodeError));
  EXPECT_CALL(*this, NotifyError(VaapiVideoDecodeAccelerator::PLATFORM_FAILURE))
      .WillOnce(RunClosure(run_loop.QuitClosure()));

  QueueInputBuffer(std::move(bitstream_buffer));
  run_loop.Run();
}

TEST_P(VaapiVideoDecodeAcceleratorTest, QueueVP9Profile2AndError) {
  if (GetParam().video_codec != VP9PROFILE_PROFILE2)
    GTEST_SKIP() << "The test parameter is not vp9 profile 2";

  auto region = base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
      in_shm_.Duplicate());
  BitstreamBuffer bitstream_buffer(kBitstreamId, std::move(region), kInputSize);
  base::RunLoop run_loop;
  EXPECT_CALL(*mock_decoder_,
              SetStream(_, IsExpectedDecoderBuffer(kInputSize, nullptr)))
      .WillOnce(Return());
  EXPECT_CALL(*mock_decoder_, Decode())
      .WillOnce(Return(AcceleratedVideoDecoder::kConfigChange));
  EXPECT_CALL(*mock_decoder_, GetBitDepth()).WillOnce(Return(10u));
  EXPECT_CALL(*this, NotifyError(VaapiVideoDecodeAccelerator::PLATFORM_FAILURE))
      .WillOnce(RunClosure(run_loop.QuitClosure()));

  QueueInputBuffer(std::move(bitstream_buffer));
  run_loop.Run();
}

// Verifies a single fast frame decoding..
TEST_P(VaapiVideoDecodeAcceleratorTest, DecodeOneFrame) {
  if (GetParam().video_codec == VP9PROFILE_PROFILE2)
    GTEST_SKIP() << "Decoding profile 2 is not supported";
  DecodeOneFrameFast(kBitstreamId);

  ResetSequence();
}

// Tests usual startup sequence: a BitstreamBuffer is enqueued for decode;
// |vda_| asks for PictureBuffers, that we provide via AssignPictureBuffers().
TEST_P(VaapiVideoDecodeAcceleratorTest,
       QueueInputBuffersAndAssignPictureBuffers) {
  if (GetParam().video_codec == VP9PROFILE_PROFILE2)
    GTEST_SKIP() << "Decoding profile 2 is not supported";
  QueueInputBufferSequence(kNumPictures, kPictureSize, kBitstreamId);

  AssignPictureBuffersSequence(kNumPictures, kPictureSize, kBitstreamId);

  ResetSequence();
}

// Tests a typical resolution change sequence: a BitstreamBuffer is enqueued;
// |vda_| asks for PictureBuffers, we them provide via AssignPictureBuffers().
// We then try to enqueue a few BitstreamBuffers of a different resolution: we
// then expect the old ones to be dismissed and new ones provided.This sequence
// is purely ingress-wise, i.e. there's no decoded output checks.
TEST_P(VaapiVideoDecodeAcceleratorTest,
       QueueInputBuffersAndAssignPictureBuffersAndReallocate) {
  if (GetParam().video_codec == VP9PROFILE_PROFILE2)
    GTEST_SKIP() << "Decoding profile 2 is not supported";
  QueueInputBufferSequence(kNumPictures, kPictureSize, kBitstreamId);

  AssignPictureBuffersSequence(kNumPictures, kPictureSize, kBitstreamId);

  // Decode a few frames. This step is not necessary.
  for (int i = 0; i < 5; ++i)
    DecodeOneFrameFast(kBitstreamId + i);

  QueueInputBufferSequence(kNewNumPictures, kNewPictureSize, kBitstreamId,
                           true /* expect_dismiss_picture_buffers */,
                           kNumPictures /* num_picture_buffers_to_dismiss */);

  AssignPictureBuffersSequence(kNewNumPictures, kNewPictureSize, kBitstreamId);

  ResetSequence();
}

constexpr TestParams kTestCases[] = {
    {H264PROFILE_MIN, false /* decode_using_client_picture_buffers */},
    {H264PROFILE_MIN, true /* decode_using_client_picture_buffers */},
    {VP8PROFILE_MIN, false /* decode_using_client_picture_buffers */},
    {VP9PROFILE_MIN, false /* decode_using_client_picture_buffers */},
    {VP9PROFILE_MIN, true /* decode_using_client_picture_buffers */},
    {VP9PROFILE_PROFILE2, false /* decode_using_client_picture_buffers */},
};

INSTANTIATE_TEST_SUITE_P(All,
                         VaapiVideoDecodeAcceleratorTest,
                         ValuesIn(kTestCases));

}  // namespace media
