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

#include "media/gpu/chromeos/video_decoder_pipeline.h"

#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "media/base/cdm_context.h"
#include "media/base/media_util.h"
#include "media/base/mock_filters.h"
#include "media/base/mock_media_log.h"
#include "media/base/status.h"
#include "media/base/video_decoder_config.h"
#include "media/gpu/chromeos/dmabuf_video_frame_pool.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/libdrm/src/include/drm/drm_fourcc.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
// gn check does not account for BUILDFLAG(), so including this header will
// make gn check fail for builds other than ash-chrome. See gn help nogncheck
// for more information.
#include "chromeos/components/cdm_factory_daemon/chromeos_cdm_context.h"  // nogncheck
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

using base::test::RunClosure;
using ::testing::_;
using ::testing::ByMove;
using ::testing::InSequence;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::TestWithParam;

namespace media {

using PixelLayoutCandidate = ImageProcessor::PixelLayoutCandidate;

MATCHER_P(MatchesStatusCode, status_code, "") {
  // media::Status doesn't provide an operator==(...), we add here a simple one.
  return arg.code() == status_code;
}

class MockVideoFramePool : public DmabufVideoFramePool {
 public:
  MockVideoFramePool() = default;
  ~MockVideoFramePool() override = default;

  // DmabufVideoFramePool implementation.
  MOCK_METHOD7(Initialize,
               CroStatus::Or<GpuBufferLayout>(const Fourcc&,
                                              const gfx::Size&,
                                              const gfx::Rect&,
                                              const gfx::Size&,
                                              size_t,
                                              bool,
                                              bool));
  MOCK_METHOD0(GetFrame, scoped_refptr<VideoFrame>());
  MOCK_METHOD0(IsExhausted, bool());
  MOCK_METHOD1(NotifyWhenFrameAvailable, void(base::OnceClosure));
  MOCK_METHOD0(ReleaseAllFrames, void());
  MOCK_METHOD0(GetGpuBufferLayout, absl::optional<GpuBufferLayout>());

  bool IsFakeVideoFramePool() override { return true; }
};

class MockDecoder : public VideoDecoderMixin {
 public:
  MockDecoder()
      : VideoDecoderMixin(std::make_unique<MockMediaLog>(),
                          base::SingleThreadTaskRunner::GetCurrentDefault(),
                          base::WeakPtr<VideoDecoderMixin::Client>(nullptr)) {}
  ~MockDecoder() override = default;

  MOCK_METHOD6(Initialize,
               void(const VideoDecoderConfig&,
                    bool,
                    CdmContext*,
                    InitCB,
                    const OutputCB&,
                    const WaitingCB&));
  MOCK_METHOD2(Decode, void(scoped_refptr<DecoderBuffer>, DecodeCB));
  MOCK_METHOD1(Reset, void(base::OnceClosure));
  MOCK_METHOD0(ApplyResolutionChange, void());
  MOCK_METHOD0(NeedsTranscryption, bool());
  MOCK_CONST_METHOD0(GetDecoderType, VideoDecoderType());
};

#if BUILDFLAG(IS_CHROMEOS_ASH)
constexpr uint8_t kEncryptedData[] = {1, 8, 9};
constexpr uint8_t kTranscryptedData[] = {9, 2, 4};
class MockChromeOsCdmContext : public chromeos::ChromeOsCdmContext {
 public:
  MockChromeOsCdmContext() : chromeos::ChromeOsCdmContext() {}
  ~MockChromeOsCdmContext() override = default;

  MOCK_METHOD3(GetHwKeyData,
               void(const DecryptConfig*,
                    const std::vector<uint8_t>&,
                    chromeos::ChromeOsCdmContext::GetHwKeyDataCB));
  MOCK_METHOD1(GetHwConfigData,
               void(chromeos::ChromeOsCdmContext::GetHwConfigDataCB));
  MOCK_METHOD1(GetScreenResolutions,
               void(chromeos::ChromeOsCdmContext::GetScreenResolutionsCB));
  MOCK_METHOD0(GetCdmContextRef, std::unique_ptr<CdmContextRef>());
  MOCK_CONST_METHOD0(UsingArcCdm, bool());
  MOCK_CONST_METHOD0(IsRemoteCdm, bool());
};
// A real implementation of this class would actually hold onto a reference of
// the owner of the CdmContext to ensure it is not destructed before the
// CdmContextRef is destructed. For the tests here, we don't need to bother with
// that because the CdmContext is a class member declared before the
// VideoDecoderPipeline so the CdmContext will get destructed after what uses
// it.
class FakeCdmContextRef : public CdmContextRef {
 public:
  FakeCdmContextRef(CdmContext* cdm_context) : cdm_context_(cdm_context) {}
  ~FakeCdmContextRef() override = default;

  CdmContext* GetCdmContext() override { return cdm_context_; }

 private:
  CdmContext* cdm_context_;
};
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

class MockImageProcessor : public ImageProcessor {
 public:
  explicit MockImageProcessor(
      scoped_refptr<base::SequencedTaskRunner> client_task_runner)
      : ImageProcessor(nullptr,
                       client_task_runner,
                       /*backend_task_runner=*/
                       base::ThreadPool::CreateSequencedTaskRunner({})) {}

  MOCK_CONST_METHOD0(input_config, const ImageProcessorBackend::PortConfig&());
  MOCK_CONST_METHOD0(output_config, const ImageProcessorBackend::PortConfig&());
};

struct DecoderPipelineTestParams {
  // GTest params need to be copyable; hence we need here a RepeatingCallback
  // version of VideoDecoderPipeline::CreateDecoderFunctionCB.
  using RepeatingCreateDecoderFunctionCB = base::RepeatingCallback<
      VideoDecoderPipeline::CreateDecoderFunctionCB::RunType>;
  RepeatingCreateDecoderFunctionCB create_decoder_function_cb;
  DecoderStatus::Codes status_code;
};

constexpr gfx::Size kMinSupportedResolution(64, 64);
constexpr gfx::Size kMaxSupportedResolution(2048, 1088);
constexpr gfx::Size kCodedSize(128, 128);

static_assert(kMinSupportedResolution.width() <= kCodedSize.width() &&
                  kMinSupportedResolution.height() <= kCodedSize.height() &&
                  kCodedSize.width() <= kMaxSupportedResolution.width() &&
                  kCodedSize.height() <= kMaxSupportedResolution.height(),
              "kCodedSize must be within the supported resolutions.");

class VideoDecoderPipelineTest
    : public testing::TestWithParam<DecoderPipelineTestParams> {
 public:
  VideoDecoderPipelineTest()
      : config_(VideoCodec::kVP8,
                VP8PROFILE_ANY,
                VideoDecoderConfig::AlphaMode::kIsOpaque,
                VideoColorSpace(),
                kNoTransformation,
                kCodedSize,
                gfx::Rect(kCodedSize),
                kCodedSize,
                EmptyExtraData(),
                EncryptionScheme::kUnencrypted) {
    auto pool = std::make_unique<MockVideoFramePool>();
    pool_ = pool.get();
    decoder_ = base::WrapUnique(new VideoDecoderPipeline(
        gpu::GpuDriverBugWorkarounds(),
        base::SingleThreadTaskRunner::GetCurrentDefault(), std::move(pool),
        /*frame_converter=*/nullptr,
        VideoDecoderPipeline::DefaultPreferredRenderableFourccs(),
        std::make_unique<MockMediaLog>(),
        // This callback needs to be configured in the individual tests.
        base::BindOnce(&VideoDecoderPipelineTest::CreateNullMockDecoder),
        /*uses_oop_video_decoder=*/false));

    SetSupportedVideoDecoderConfigs({SupportedVideoDecoderConfig(
        /*profile_min,=*/VP8PROFILE_ANY,
        /*profile_max=*/VP8PROFILE_ANY, kMinSupportedResolution,
        kMaxSupportedResolution,
        /*allow_encrypted=*/true,
        /*require_encrypted=*/false)});
  }
  ~VideoDecoderPipelineTest() override = default;

  void TearDown() override {
    VideoDecoderPipeline::DestroyAsync(std::move(decoder_));
    task_environment_.RunUntilIdle();
  }
  MOCK_METHOD1(OnInit, void(DecoderStatus));
  MOCK_METHOD1(OnOutput, void(scoped_refptr<VideoFrame>));
  MOCK_METHOD0(OnResetDone, void());
  MOCK_METHOD1(OnDecodeDone, void(DecoderStatus));
  MOCK_METHOD1(OnWaiting, void(WaitingReason));

  void SetCreateDecoderFunctionCB(VideoDecoderPipeline::CreateDecoderFunctionCB
                                      function) NO_THREAD_SAFETY_ANALYSIS {
    decoder_->create_decoder_function_cb_ = std::move(function);
  }

  void SetCreateImageProcessorCBForTesting(
      VideoDecoderPipeline::CreateImageProcessorCBForTesting function)
      NO_THREAD_SAFETY_ANALYSIS {
    decoder_->create_image_processor_cb_for_testing_ = std::move(function);
  }

  // Constructs |decoder_| with a given |create_decoder_function_cb| and
  // verifying |status_code| is received back in OnInit().
  void InitializeDecoder(
      VideoDecoderPipeline::CreateDecoderFunctionCB create_decoder_function_cb,
      DecoderStatus::Codes status_code,
      CdmContext* cdm_context = nullptr) {
    SetCreateDecoderFunctionCB(std::move(create_decoder_function_cb));

    base::RunLoop run_loop;
    EXPECT_CALL(*this, OnInit(MatchesStatusCode(status_code)))
        .WillOnce(RunClosure(run_loop.QuitClosure()));

    decoder_->Initialize(
        config_, false /* low_delay */, cdm_context,
        base::BindOnce(&VideoDecoderPipelineTest::OnInit,
                       base::Unretained(this)),
        base::BindRepeating(&VideoDecoderPipelineTest::OnOutput,
                            base::Unretained(this)),
        base::BindRepeating(&VideoDecoderPipelineTest::OnWaiting,
                            base::Unretained(this)));
    run_loop.Run();
    testing::Mock::VerifyAndClearExpectations(this);
  }

#if BUILDFLAG(IS_CHROMEOS_ASH)
  void InitializeForTranscrypt() {
    decoder_->allow_encrypted_content_for_testing_ = true;
    EXPECT_CALL(cdm_context_, GetChromeOsCdmContext())
        .WillRepeatedly(Return(&chromeos_cdm_context_));
    EXPECT_CALL(cdm_context_, RegisterEventCB(_))
        .WillOnce([this](CdmContext::EventCB event_cb) {
          return event_callbacks_.Register(std::move(event_cb));
        });
    EXPECT_CALL(cdm_context_, GetDecryptor())
        .WillRepeatedly(Return(&decryptor_));
    EXPECT_CALL(chromeos_cdm_context_, GetCdmContextRef())
        .WillOnce(
            Return(ByMove(std::make_unique<FakeCdmContextRef>(&cdm_context_))));
    InitializeDecoder(
        base::BindOnce(
            &VideoDecoderPipelineTest::CreateGoodMockTranscryptDecoder),
        DecoderStatus::Codes::kOk, &cdm_context_);
    testing::Mock::VerifyAndClearExpectations(&chromeos_cdm_context_);
    testing::Mock::VerifyAndClearExpectations(&cdm_context_);
    // GetDecryptor() will be called again, so set that expectation.
    EXPECT_CALL(cdm_context_, GetDecryptor())
        .WillRepeatedly(Return(&decryptor_));
    encrypted_buffer_ =
        DecoderBuffer::CopyFrom(kEncryptedData, std::size(kEncryptedData));
    transcrypted_buffer_ = DecoderBuffer::CopyFrom(
        kTranscryptedData, std::size(kTranscryptedData));
  }
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

  static std::unique_ptr<VideoDecoderMixin> CreateNullMockDecoder(
      std::unique_ptr<MediaLog> /* media_log */,
      scoped_refptr<base::SequencedTaskRunner> /* decoder_task_runner */,
      base::WeakPtr<VideoDecoderMixin::Client> /* client */) {
    return nullptr;
  }

  // Creates a MockDecoder with an EXPECT_CALL on Initialize that returns ok.
  static std::unique_ptr<VideoDecoderMixin> CreateGoodMockDecoder(
      std::unique_ptr<MediaLog> /* media_log */,
      scoped_refptr<base::SequencedTaskRunner> /* decoder_task_runner */,
      base::WeakPtr<VideoDecoderMixin::Client> /* client */) {
    std::unique_ptr<MockDecoder> decoder(new MockDecoder());
    EXPECT_CALL(*decoder, Initialize(_, _, _, _, _, _))
        .WillOnce(::testing::WithArgs<3>([](VideoDecoder::InitCB init_cb) {
          std::move(init_cb).Run(DecoderStatus::Codes::kOk);
        }));
    EXPECT_CALL(*decoder, NeedsTranscryption()).WillRepeatedly(Return(false));
    return std::move(decoder);
  }

  // Creates a MockDecoder with an EXPECT_CALL on Initialize that returns ok and
  // also indicates that it requires transcryption.
  static std::unique_ptr<VideoDecoderMixin> CreateGoodMockTranscryptDecoder(
      std::unique_ptr<MediaLog> /* media_log */,
      scoped_refptr<base::SequencedTaskRunner> /* decoder_task_runner */,
      base::WeakPtr<VideoDecoderMixin::Client> /* client */) {
    std::unique_ptr<MockDecoder> decoder(new MockDecoder());
    EXPECT_CALL(*decoder, Initialize(_, _, _, _, _, _))
        .WillOnce(::testing::WithArgs<3>([](VideoDecoder::InitCB init_cb) {
          std::move(init_cb).Run(DecoderStatus::Codes::kOk);
        }));
    EXPECT_CALL(*decoder, NeedsTranscryption()).WillRepeatedly(Return(true));
    return std::move(decoder);
  }

  // Creates a MockDecoder with an EXPECT_CALL on Initialize that returns error.
  static std::unique_ptr<VideoDecoderMixin> CreateBadMockDecoder(
      std::unique_ptr<MediaLog> /* media_log */,
      scoped_refptr<base::SequencedTaskRunner> /* decoder_task_runner */,
      base::WeakPtr<VideoDecoderMixin::Client> /* client */) {
    std::unique_ptr<MockDecoder> decoder(new MockDecoder());
    EXPECT_CALL(*decoder, Initialize(_, _, _, _, _, _))
        .WillOnce(::testing::WithArgs<3>([](VideoDecoder::InitCB init_cb) {
          std::move(init_cb).Run(DecoderStatus::Codes::kFailed);
        }));
    EXPECT_CALL(*decoder, NeedsTranscryption()).WillRepeatedly(Return(false));
    return std::move(decoder);
  }

  VideoDecoderMixin* GetUnderlyingDecoder() NO_THREAD_SAFETY_ANALYSIS {
    return decoder_->decoder_.get();
  }

  void SetSupportedVideoDecoderConfigs(
      const SupportedVideoDecoderConfigs& configs) {
    decoder_->supported_configs_for_testing_ = configs;
  }

  void DetachDecoderSequenceChecker() NO_THREAD_SAFETY_ANALYSIS {
    // |decoder_| will be destroyed on its |decoder_task_runner| via
    // DestroyAsync(). This will trip its |decoder_sequence_checker_| if it has
    // been pegged to the test task runner, e.g. in PickDecoderOutputFormat().
    // Since in that case we don't care about threading, just detach it.
    DETACH_FROM_SEQUENCE(decoder_->decoder_sequence_checker_);

    if (decoder_->image_processor_) {
      // |decoder_->image_processor_->sequence_checker_| is pegged to the test
      // task runner because |decoder_->image_processor_| is created when we
      // call PickDecoderOutputFormat() from test code.
      // |decoder_->image_processor_| is then destroyed on the decoder task
      // runner because of VideoDecoderPipeline::DestroyAsync(). Thus the need
      // for this detachment.
      DETACH_FROM_SEQUENCE(decoder_->image_processor_->sequence_checker_);
    }
  }

  void InvokeWaitingCB(WaitingReason reason) {
    decoder_->decoder_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&VideoDecoderPipeline::OnDecoderWaiting,
                                  base::Unretained(decoder_.get()), reason));
  }

  bool DecoderHasImageProcessor() NO_THREAD_SAFETY_ANALYSIS {
    return !!decoder_->image_processor_;
  }

  scoped_refptr<base::SequencedTaskRunner> GetDecoderTaskRunner()
      NO_THREAD_SAFETY_ANALYSIS {
    return decoder_->decoder_task_runner_;
  }

  base::test::TaskEnvironment task_environment_;
  const VideoDecoderConfig config_;

#if BUILDFLAG(IS_CHROMEOS_ASH)
  MockCdmContext cdm_context_;  // Keep this before |decoder_|.
  MockChromeOsCdmContext chromeos_cdm_context_;
  StrictMock<MockDecryptor> decryptor_;
  scoped_refptr<DecoderBuffer> encrypted_buffer_;
  scoped_refptr<DecoderBuffer> transcrypted_buffer_;
  media::CallbackRegistry<CdmContext::EventCB::RunType> event_callbacks_;
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
  std::unique_ptr<VideoDecoderPipeline> decoder_;
  raw_ptr<MockVideoFramePool> pool_;
};

// Verifies the status code for several typical CreateDecoderFunctionCB cases.
TEST_P(VideoDecoderPipelineTest, Initialize) {
  InitializeDecoder(base::BindOnce(GetParam().create_decoder_function_cb),
                    GetParam().status_code);

  EXPECT_EQ(GetParam().status_code == DecoderStatus::Codes::kOk,
            !!GetUnderlyingDecoder());
}

const struct DecoderPipelineTestParams kDecoderPipelineTestParams[] = {
    // A CreateDecoderFunctionCB that fails to Create() (i.e. returns a
    // null Decoder)
    {base::BindRepeating(&VideoDecoderPipelineTest::CreateNullMockDecoder),
     DecoderStatus::Codes::kFailedToCreateDecoder},

    // A CreateDecoderFunctionCB that works fine, i.e. Create()s and
    // Initialize()s correctly.
    {base::BindRepeating(&VideoDecoderPipelineTest::CreateGoodMockDecoder),
     DecoderStatus::Codes::kOk},

#if BUILDFLAG(IS_CHROMEOS_ASH)
    // A CreateDecoderFunctionCB for transcryption, where Create() is ok, and
    // the decoder will Initialize OK, but then the pipeline will not create the
    // transcryptor due to a missing CdmContext. This will succeed if called
    // through InitializeForTranscrypt where a CdmContext is set.
    {base::BindRepeating(
         &VideoDecoderPipelineTest::CreateGoodMockTranscryptDecoder),
     DecoderStatus::Codes::kUnsupportedEncryptionMode},
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

    // A CreateDecoderFunctionCB that Create()s ok but fails to Initialize()
    // correctly.
    {base::BindRepeating(&VideoDecoderPipelineTest::CreateBadMockDecoder),
     DecoderStatus::Codes::kFailed},
};

INSTANTIATE_TEST_SUITE_P(All,
                         VideoDecoderPipelineTest,
                         testing::ValuesIn(kDecoderPipelineTestParams));

// Verifies that trying to Initialize() with a non-supported config fails.
TEST_F(VideoDecoderPipelineTest, InitializeFailsDueToNotSupportedConfig) {
  // Configure the supported configs to something that we know is not supported,
  // e.g. making the smallest supported resolution larger than the |config_|
  // we'll be requesting.
  SetSupportedVideoDecoderConfigs({SupportedVideoDecoderConfig(
      /*profile_min=*/config_.profile(),
      /*profile_max=*/config_.profile(),
      /*coded_size_min=*/config_.coded_size() + gfx::Size(1, 1),
      kMaxSupportedResolution,
      /*allow_encrypted=*/true,
      /*require_encrypted=*/false)});

  InitializeDecoder(
      base::BindOnce(&VideoDecoderPipelineTest::CreateGoodMockDecoder),
      DecoderStatus::Codes::kUnsupportedConfig);
}

// Verifies the Reset sequence.
TEST_F(VideoDecoderPipelineTest, Reset) {
  InitializeDecoder(
      base::BindOnce(&VideoDecoderPipelineTest::CreateGoodMockDecoder),
      DecoderStatus::Codes::kOk);

  // When we call Reset(), we expect GetUnderlyingDecoder()'s Reset() method to
  // be called, and when that method Run()s its argument closure, then
  // OnResetDone() is expected to be called.

  base::RunLoop run_loop;
  EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()), Reset(_))
      .WillOnce(::testing::WithArgs<0>(
          [](base::OnceClosure closure) { std::move(closure).Run(); }));

  EXPECT_CALL(*this, OnResetDone())
      .WillOnce(RunClosure(run_loop.QuitClosure()));

  decoder_->Reset(base::BindOnce(&VideoDecoderPipelineTest::OnResetDone,
                                 base::Unretained(this)));
}

#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(VideoDecoderPipelineTest, TranscryptThenEos) {
  InitializeForTranscrypt();

  // First send in a DecoderBuffer.
  {
    InSequence sequence;
    EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
        .WillOnce([this](Decryptor::StreamType stream_type,
                         scoped_refptr<DecoderBuffer> encrypted,
                         Decryptor::DecryptCB decrypt_cb) {
          std::move(decrypt_cb).Run(Decryptor::kSuccess, transcrypted_buffer_);
        });
    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
                Decode(transcrypted_buffer_, _))
        .WillOnce([](scoped_refptr<DecoderBuffer> transcrypted,
                     VideoDecoderMixin::DecodeCB decode_cb) {
          std::move(decode_cb).Run(DecoderStatus::Codes::kOk);
        });
    EXPECT_CALL(*this,
                OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kOk)));
  }
  decoder_->Decode(encrypted_buffer_,
                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                  base::Unretained(this)));
  task_environment_.RunUntilIdle();

  testing::Mock::VerifyAndClearExpectations(&decryptor_);
  testing::Mock::VerifyAndClearExpectations(
      reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()));
  testing::Mock::VerifyAndClearExpectations(this);

  // Now send in the EOS, this should not invoke Decrypt.
  scoped_refptr<DecoderBuffer> eos_buffer = DecoderBuffer::CreateEOSBuffer();
  {
    InSequence sequence;
    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
                Decode(eos_buffer, _))
        .WillOnce([](scoped_refptr<DecoderBuffer> transcrypted,
                     VideoDecoderMixin::DecodeCB decode_cb) {
          std::move(decode_cb).Run(DecoderStatus::Codes::kOk);
        });
    EXPECT_CALL(*this,
                OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kOk)));
  }
  decoder_->Decode(eos_buffer,
                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                  base::Unretained(this)));
  task_environment_.RunUntilIdle();
}

TEST_F(VideoDecoderPipelineTest, TranscryptReset) {
  InitializeForTranscrypt();
  scoped_refptr<DecoderBuffer> encrypted_buffer2 = DecoderBuffer::CopyFrom(
      &kEncryptedData[1], std::size(kEncryptedData) - 1);
  // Send in a buffer, but don't invoke the Decrypt callback so it stays as
  // pending. Then send in 2 more buffers so they are in the queue.
  EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
      .Times(1);
  decoder_->Decode(encrypted_buffer_,
                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                  base::Unretained(this)));
  decoder_->Decode(encrypted_buffer2,
                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                  base::Unretained(this)));
  decoder_->Decode(encrypted_buffer2,
                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                  base::Unretained(this)));
  task_environment_.RunUntilIdle();
  testing::Mock::VerifyAndClearExpectations(&decryptor_);

  // Now when we reset, we should see 3 decode callbacks occur as well as the
  // reset callback.
  {
    InSequence sequence;
    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
                Reset(_))
        .WillOnce([](base::OnceClosure closure) { std::move(closure).Run(); });
    EXPECT_CALL(*this,
                OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kAborted)))
        .Times(3);
    EXPECT_CALL(*this, OnResetDone()).Times(1);
  }
  decoder_->Reset(base::BindOnce(&VideoDecoderPipelineTest::OnResetDone,
                                 base::Unretained(this)));
  task_environment_.RunUntilIdle();
}

// Verifies that if we get notified about a new decrypt key while we are
// performing a transcrypt that fails w/out a key, we immediately retry again.
TEST_F(VideoDecoderPipelineTest, TranscryptKeyAddedDuringTranscrypt) {
  InitializeForTranscrypt();
  // First send in a buffer, which will go to the decryptor and hold on to that
  // callback.
  Decryptor::DecryptCB saved_decrypt_cb;
  EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
      .WillOnce([&saved_decrypt_cb](Decryptor::StreamType stream_type,
                                    scoped_refptr<DecoderBuffer> encrypted,
                                    Decryptor::DecryptCB decrypt_cb) {
        saved_decrypt_cb =
            base::BindPostTaskToCurrentDefault(std::move(decrypt_cb));
      });
  decoder_->Decode(encrypted_buffer_,
                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                  base::Unretained(this)));
  task_environment_.RunUntilIdle();
  testing::Mock::VerifyAndClearExpectations(&decryptor_);

  // Now we invoke the CDM callback to indicate there is a new key available.
  event_callbacks_.Notify(CdmContext::Event::kHasAdditionalUsableKey);
  task_environment_.RunUntilIdle();

  // Now we have the decryptor callback return with kNoKey which should then
  // cause another call into the decryptor which we will have succeed and then
  // that should go through decoding. This should not invoke the waiting CB.
  {
    InSequence sequence;
    EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
        .WillOnce([this](Decryptor::StreamType stream_type,
                         scoped_refptr<DecoderBuffer> encrypted,
                         Decryptor::DecryptCB decrypt_cb) {
          std::move(decrypt_cb).Run(Decryptor::kSuccess, transcrypted_buffer_);
        });
    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
                Decode(transcrypted_buffer_, _))
        .WillOnce([](scoped_refptr<DecoderBuffer> transcrypted,
                     VideoDecoderMixin::DecodeCB decode_cb) {
          std::move(decode_cb).Run(DecoderStatus::Codes::kOk);
        });
    EXPECT_CALL(*this,
                OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kOk)));
  }
  EXPECT_CALL(*this, OnWaiting(_)).Times(0);
  std::move(saved_decrypt_cb).Run(Decryptor::kNoKey, nullptr);
  task_environment_.RunUntilIdle();
}

// Verifies that if we don't have the key during transcrypt, the WaitingCB is
// invoked and then it retries again when we notify it of the new key.
TEST_F(VideoDecoderPipelineTest, TranscryptNoKeyWaitRetry) {
  InitializeForTranscrypt();
  // First send in a buffer, which will go to the decryptor and indicate there
  // is no key. This should also invoke the WaitingCB.
  {
    InSequence sequence;
    EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
        .WillOnce([](Decryptor::StreamType stream_type,
                     scoped_refptr<DecoderBuffer> encrypted,
                     Decryptor::DecryptCB decrypt_cb) {
          std::move(decrypt_cb).Run(Decryptor::kNoKey, nullptr);
        });
    EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey)).Times(1);
  }
  decoder_->Decode(encrypted_buffer_,
                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                  base::Unretained(this)));
  task_environment_.RunUntilIdle();
  testing::Mock::VerifyAndClearExpectations(&decryptor_);
  testing::Mock::VerifyAndClearExpectations(this);

  // Now we invoke the CDM callback to indicate there is a new key available.
  // This should invoke the decryptor again which we will have succeed and
  // complete the decode operation.
  {
    InSequence sequence;
    EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
        .WillOnce([this](Decryptor::StreamType stream_type,
                         scoped_refptr<DecoderBuffer> encrypted,
                         Decryptor::DecryptCB decrypt_cb) {
          std::move(decrypt_cb).Run(Decryptor::kSuccess, transcrypted_buffer_);
        });
    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
                Decode(transcrypted_buffer_, _))
        .WillOnce([](scoped_refptr<DecoderBuffer> transcrypted,
                     VideoDecoderMixin::DecodeCB decode_cb) {
          std::move(decode_cb).Run(DecoderStatus::Codes::kOk);
        });
    EXPECT_CALL(*this,
                OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kOk)));
  }
  event_callbacks_.Notify(CdmContext::Event::kHasAdditionalUsableKey);
  task_environment_.RunUntilIdle();
}

TEST_F(VideoDecoderPipelineTest, TranscryptError) {
  InitializeForTranscrypt();
  {
    InSequence sequence;
    EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
        .WillOnce([](Decryptor::StreamType stream_type,
                     scoped_refptr<DecoderBuffer> encrypted,
                     Decryptor::DecryptCB decrypt_cb) {
          std::move(decrypt_cb).Run(Decryptor::kError, nullptr);
        });
    EXPECT_CALL(*this,
                OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kFailed)));
  }
  decoder_->Decode(encrypted_buffer_,
                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                  base::Unretained(this)));
  task_environment_.RunUntilIdle();
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

// Verifies the algorithm for choosing formats in PickDecoderOutputFormat works
// as expected.
TEST_F(VideoDecoderPipelineTest, PickDecoderOutputFormat) {
  constexpr gfx::Size kSize(320, 240);
  constexpr gfx::Rect kVisibleRect(320, 240);
  constexpr size_t kNumCodecReferenceFrames = 4u;
  constexpr uint64_t kModifier = ~DRM_FORMAT_MOD_LINEAR;

  const struct {
    std::vector<PixelLayoutCandidate> input_candidates;
    PixelLayoutCandidate expected_chosen_candidate;
  } test_vectors[] = {
      // Easy cases: one candidate that is supported, should be chosen.
      {{PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier}},
       PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier}},
      {{PixelLayoutCandidate{Fourcc(Fourcc::YV12), kSize, kModifier}},
       PixelLayoutCandidate{Fourcc(Fourcc::YV12), kSize, kModifier}},
      {{PixelLayoutCandidate{Fourcc(Fourcc::P010), kSize, kModifier}},
       PixelLayoutCandidate{Fourcc(Fourcc::P010), kSize, kModifier}},
      // Two candidates, both supported: pick as per implementation.
      {{PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier},
        PixelLayoutCandidate{Fourcc(Fourcc::YV12), kSize, kModifier}},
       PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier}},
      {{PixelLayoutCandidate{Fourcc(Fourcc::YV12), kSize, kModifier},
        PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier}},
       PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier}},
      {{PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier},
        PixelLayoutCandidate{Fourcc(Fourcc::P010), kSize, kModifier}},
       PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier}},
      // Two candidates, only one supported, the supported one should be picked.
      {{PixelLayoutCandidate{Fourcc(Fourcc::YU16), kSize, kModifier},
        PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier}},
       PixelLayoutCandidate{Fourcc(Fourcc::NV12), kSize, kModifier}},
      {{PixelLayoutCandidate{Fourcc(Fourcc::YU16), kSize, kModifier},
        PixelLayoutCandidate{Fourcc(Fourcc::YV12), kSize, kModifier}},
       PixelLayoutCandidate{Fourcc(Fourcc::YV12), kSize, kModifier}},
      {{PixelLayoutCandidate{Fourcc(Fourcc::YU16), kSize, kModifier},
        PixelLayoutCandidate{Fourcc(Fourcc::P010), kSize, kModifier}},
       PixelLayoutCandidate{Fourcc(Fourcc::P010), kSize, kModifier}}};

  for (const auto& test_vector : test_vectors) {
    const Fourcc& expected_fourcc =
        test_vector.expected_chosen_candidate.fourcc;
    const gfx::Size& expected_coded_size =
        test_vector.expected_chosen_candidate.size;
    std::vector<ColorPlaneLayout> planes(
        VideoFrame::NumPlanes(expected_fourcc.ToVideoPixelFormat()));
    EXPECT_CALL(
        *pool_,
        Initialize(expected_fourcc, expected_coded_size, kVisibleRect,
                   /*natural_size=*/kVisibleRect.size(),
                   /*max_num_frames=*/::testing::Gt(kNumCodecReferenceFrames),
                   /*use_protected=*/false,
                   /*use_linear_buffers=*/false))
        .WillOnce(Return(*GpuBufferLayout::Create(
            expected_fourcc, expected_coded_size, std::move(planes),
            /*modifier=*/kModifier)));
    auto status_or_chosen_candidate = decoder_->PickDecoderOutputFormat(
        test_vector.input_candidates, kVisibleRect,
        /*decoder_natural_size=*/kVisibleRect.size(),
        /*output_size=*/absl::nullopt,
        /*num_codec_reference_frames=*/kNumCodecReferenceFrames,
        /*use_protected=*/false, /*need_aux_frame_pool=*/false, absl::nullopt);
    ASSERT_TRUE(status_or_chosen_candidate.has_value());
    const PixelLayoutCandidate chosen_candidate =
        std::move(status_or_chosen_candidate).value();
    EXPECT_EQ(test_vector.expected_chosen_candidate, chosen_candidate)
        << " expected: "
        << test_vector.expected_chosen_candidate.fourcc.ToString()
        << ", actual: " << chosen_candidate.fourcc.ToString();
    EXPECT_FALSE(DecoderHasImageProcessor());
    testing::Mock::VerifyAndClearExpectations(pool_);
  }
  DetachDecoderSequenceChecker();
}

// These tests only work on non-linux and non-lacros vaapi systems, since on
// linux and lacros there is no support for different modifiers.
#if BUILDFLAG(USE_VAAPI) && !BUILDFLAG(IS_LINUX) && \
    !BUILDFLAG(IS_CHROMEOS_LACROS)

// Verifies the algorithm for choosing formats in PickDecoderOutputFormat works
// as expected when the pool returns linear buffers. It should allocate an image
// processor in those cases.
TEST_F(VideoDecoderPipelineTest, PickDecoderOutputFormatLinearModifier) {
  constexpr gfx::Size kSize(320, 240);
  constexpr gfx::Rect kVisibleRect(320, 240);
  constexpr size_t kNumCodecReferenceFrames = 4u;
  const Fourcc kFourcc(Fourcc::NV12);

  auto image_processor =
      std::make_unique<MockImageProcessor>(GetDecoderTaskRunner());
  ImageProcessorBackend::PortConfig port_config(
      Fourcc(Fourcc::NV12), gfx::Size(320, 240), {}, gfx::Rect(320, 240), {});
  EXPECT_CALL(*image_processor, input_config())
      .WillRepeatedly(testing::ReturnRef(port_config));
  EXPECT_CALL(*image_processor, output_config())
      .WillRepeatedly(testing::ReturnRef(port_config));

  base::MockCallback<VideoDecoderPipeline::CreateImageProcessorCBForTesting>
      image_processor_cb;
  EXPECT_CALL(image_processor_cb, Run(_, _, kSize, _))
      .WillOnce(Return(testing::ByMove(std::move(image_processor))));
  SetCreateImageProcessorCBForTesting(image_processor_cb.Get());

  // Modifier should be the linear format.
  GpuBufferLayout gpu_buffer_layout = *GpuBufferLayout::Create(
      kFourcc, kSize,
      std::vector<ColorPlaneLayout>(
          VideoFrame::NumPlanes(kFourcc.ToVideoPixelFormat())),
      /*modifier=*/DRM_FORMAT_MOD_LINEAR);
  EXPECT_CALL(*pool_, Initialize(_, _, _, _, _, _, _))
      .WillRepeatedly(Return(gpu_buffer_layout));

  PixelLayoutCandidate candidate{Fourcc(Fourcc::NV12), kSize,
                                 /*modifier=*/~DRM_FORMAT_MOD_LINEAR};
  auto status_or_chosen_candidate = decoder_->PickDecoderOutputFormat(
      {candidate}, kVisibleRect,
      /*decoder_natural_size=*/kVisibleRect.size(),
      /*output_size=*/absl::nullopt,
      /*num_codec_reference_frames=*/kNumCodecReferenceFrames,
      /*use_protected=*/false, /*need_aux_frame_pool=*/false, absl::nullopt);

  EXPECT_TRUE(status_or_chosen_candidate.has_value());
  // Main concern is that the image processor was set.
  EXPECT_TRUE(DecoderHasImageProcessor());
  DetachDecoderSequenceChecker();
}

// Verifies the algorithm for choosing formats in PickDecoderOutputFormat works
// as expected when the frame pool returns buffers that have an unsupported
// modifier.
TEST_F(VideoDecoderPipelineTest, PickDecoderOutputFormatUnsupportedModifier) {
  constexpr gfx::Size kSize(320, 240);
  constexpr gfx::Rect kVisibleRect(320, 240);
  constexpr size_t kNumCodecReferenceFrames = 4u;
  const Fourcc kFourcc(Fourcc::NV12);

  // Modifier is *not* the linear format.
  GpuBufferLayout gpu_buffer_layout = *GpuBufferLayout::Create(
      kFourcc, kSize,
      std::vector<ColorPlaneLayout>(
          VideoFrame::NumPlanes(kFourcc.ToVideoPixelFormat())),
      /*modifier=*/~DRM_FORMAT_MOD_LINEAR);
  EXPECT_CALL(*pool_, Initialize(_, _, _, _, _, _, _))
      .WillRepeatedly(Return(gpu_buffer_layout));

  // Make sure the modifier mismatches the |gpu_buffer_layout|'s
  constexpr uint64_t modifier = ~DRM_FORMAT_MOD_LINEAR + 1;
  PixelLayoutCandidate candidate{Fourcc(Fourcc::NV12), kSize, modifier};
  auto status_or_chosen_candidate = decoder_->PickDecoderOutputFormat(
      {candidate}, kVisibleRect,
      /*decoder_natural_size=*/kVisibleRect.size(),
      /*output_size=*/absl::nullopt,
      /*num_codec_reference_frames=*/kNumCodecReferenceFrames,
      /*use_protected=*/false, /*need_aux_frame_pool=*/false, absl::nullopt);

  EXPECT_FALSE(status_or_chosen_candidate.has_value());
  EXPECT_FALSE(DecoderHasImageProcessor());
  DetachDecoderSequenceChecker();
}

#endif  // BUILDFLAG(USE_VAAPI) && !BUILDFLAG(IS_LINUX) &&
        // !BUILDFLAG(IS_CHROMEOS_LACROS)

// Verifies that ReleaseAllFrames is called on the frame pool when we receive
// the kDecoderStateLost event through the waiting callback. This can occur
// during protected content playback on Intel.
TEST_F(VideoDecoderPipelineTest, RebuildFramePoolsOnStateLost) {
  InitializeDecoder(
      base::BindOnce(&VideoDecoderPipelineTest::CreateGoodMockDecoder),
      DecoderStatus::Codes::kOk);

  // Simulate the waiting callback from the decoder for kDecoderStateLost.
  EXPECT_CALL(*this, OnWaiting(media::WaitingReason::kDecoderStateLost));
  InvokeWaitingCB(media::WaitingReason::kDecoderStateLost);
  task_environment_.RunUntilIdle();

  // Invoke Reset() as a client would do, and we then expect that to invoke the
  // method to rebuild the frame pool.
  EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()), Reset(_))
      .WillOnce(::testing::WithArgs<0>(
          [](base::OnceClosure closure) { std::move(closure).Run(); }));
  EXPECT_CALL(*this, OnResetDone());
  EXPECT_CALL(*pool_, ReleaseAllFrames());

  decoder_->Reset(base::BindOnce(&VideoDecoderPipelineTest::OnResetDone,
                                 base::Unretained(this)));
  task_environment_.RunUntilIdle();
}
}  // namespace media
