// Copyright (c) 2012 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 <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.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 "media/base/fake_demuxer_stream.h"
#include "media/base/mock_filters.h"
#include "media/base/mock_media_log.h"
#include "media/base/test_helpers.h"
#include "media/base/timestamp_constants.h"
#include "media/filters/decoder_stream.h"
#include "media/filters/fake_video_decoder.h"
#include "testing/gtest/include/gtest/gtest.h"

#if !defined(OS_ANDROID)
#include "media/filters/decrypting_video_decoder.h"
#endif

#include <iostream>

using ::base::test::RunCallback;
using ::base::test::RunOnceCallback;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Assign;
using ::testing::HasSubstr;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::StrictMock;

namespace media {

namespace {
const int kNumConfigs = 4;
const int kNumBuffersInOneConfig = 5;
constexpr base::TimeDelta kPrepareDelay = base::Milliseconds(5);

static int GetDecoderId(int i) {
  return i;
}

DecoderPriority MockDecoderPriority(const VideoDecoderConfig& config,
                                    const VideoDecoder& decoder) {
  auto const at_or_above_cutoff = config.visible_rect().height() >=
                                  TestVideoConfig::LargeCodedSize().height();
  return at_or_above_cutoff == decoder.IsPlatformDecoder()
             ? DecoderPriority::kNormal
             : DecoderPriority::kDeprioritized;
}

}  // namespace

struct VideoDecoderStreamTestParams {
  VideoDecoderStreamTestParams(bool is_encrypted,
                               bool has_decryptor,
                               bool has_prepare,
                               int decoding_delay,
                               int parallel_decoding)
      : is_encrypted(is_encrypted),
        has_decryptor(has_decryptor),
        has_prepare(has_prepare),
        decoding_delay(decoding_delay),
        parallel_decoding(parallel_decoding) {}

  bool is_encrypted;
  bool has_decryptor;
  bool has_prepare;
  int decoding_delay;
  int parallel_decoding;
};

class VideoDecoderStreamTest
    : public testing::Test,
      public testing::WithParamInterface<VideoDecoderStreamTestParams> {
 public:
  VideoDecoderStreamTest()
      : is_initialized_(false),
        num_decoded_frames_(0),
        pending_initialize_(false),
        pending_read_(false),
        pending_reset_(false),
        pending_stop_(false),
        num_decoded_bytes_unreported_(0),
        has_no_key_(false) {
    video_decoder_stream_ = std::make_unique<VideoDecoderStream>(
        std::make_unique<VideoDecoderStream::StreamTraits>(&media_log_),
        task_environment_.GetMainThreadTaskRunner(),
        base::BindRepeating(&VideoDecoderStreamTest::CreateVideoDecodersForTest,
                            base::Unretained(this)),
        &media_log_);
    video_decoder_stream_->set_decoder_change_observer(base::BindRepeating(
        &VideoDecoderStreamTest::OnDecoderChanged, base::Unretained(this)));
    video_decoder_stream_
        ->GetDecoderSelectorForTesting(base::PassKey<VideoDecoderStreamTest>())
        .OverrideDecoderPriorityCBForTesting(
            base::BindRepeating(MockDecoderPriority));
    if (GetParam().has_prepare) {
      video_decoder_stream_->SetPrepareCB(base::BindRepeating(
          &VideoDecoderStreamTest::PrepareFrame, base::Unretained(this)));
    }

    if (GetParam().is_encrypted && GetParam().has_decryptor) {
      decryptor_ = std::make_unique<NiceMock<MockDecryptor>>();

      // Decryptor can only decrypt (not decrypt-and-decode) so that
      // DecryptingDemuxerStream will be used.
      EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
          .WillRepeatedly(RunOnceCallback<1>(false));
      EXPECT_CALL(*decryptor_, Decrypt(_, _, _))
          .WillRepeatedly(Invoke(this, &VideoDecoderStreamTest::Decrypt));
    }

    if (GetParam().is_encrypted) {
      cdm_context_ = std::make_unique<StrictMock<MockCdmContext>>();

      EXPECT_CALL(*cdm_context_, RegisterEventCB(_)).Times(AnyNumber());
      EXPECT_CALL(*cdm_context_, GetDecryptor())
          .WillRepeatedly(Return(decryptor_.get()));
    }

    // Covering most MediaLog messages for now.
    // TODO(wolenetz/xhwang): Fix tests to have better MediaLog checking.
    EXPECT_MEDIA_LOG(HasSubstr("video")).Times(AnyNumber());
    EXPECT_MEDIA_LOG(HasSubstr("Video")).Times(AnyNumber());
    EXPECT_MEDIA_LOG(HasSubstr("audio")).Times(AnyNumber());
    EXPECT_MEDIA_LOG(HasSubstr("Audio")).Times(AnyNumber());
    EXPECT_MEDIA_LOG(HasSubstr("decryptor")).Times(AnyNumber());
  }

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

  ~VideoDecoderStreamTest() {
    // Check that the pipeline statistics callback was fired correctly.
    EXPECT_EQ(num_decoded_bytes_unreported_, 0);

    is_initialized_ = false;
    decoders_.clear();
    video_decoder_stream_.reset();
    base::RunLoop().RunUntilIdle();

    DCHECK(!pending_initialize_);
    DCHECK(!pending_read_);
    DCHECK(!pending_reset_);
    DCHECK(!pending_stop_);
  }

  void CreateDemuxerStream(gfx::Size start_size, gfx::Vector2dF size_delta) {
    DCHECK(!demuxer_stream_);
    demuxer_stream_ = std::make_unique<FakeDemuxerStream>(
        kNumConfigs, kNumBuffersInOneConfig, GetParam().is_encrypted,
        start_size, size_delta);
  }

  void PrepareFrame(scoped_refptr<VideoFrame> frame,
                    VideoDecoderStream::OutputReadyCB output_ready_cb) {
    // Simulate some delay in return of the output.
    task_environment_.GetMainThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(output_ready_cb), std::move(frame)));
  }

  void PrepareFrameWithDelay(
      scoped_refptr<VideoFrame> frame,
      VideoDecoderStream::OutputReadyCB output_ready_cb) {
    task_environment_.FastForwardBy(kPrepareDelay);
    task_environment_.GetMainThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(output_ready_cb), std::move(frame)));
  }

  void OnBytesDecoded(int count) { num_decoded_bytes_unreported_ += count; }

  // Callback to create a list of decoders for the DecoderSelector to select
  // from. Decoder selection happens
  // - on the initial selection in Initialize(),
  // - on decoder reinitialization failure, which can be simulated by calling
  //   decoder_->SimulateFailureToInit(), and
  // - on decode error of the first buffer, which can be simulated by calling
  //   decoder_->SimulateError() before reading the first frame.
  std::vector<std::unique_ptr<VideoDecoder>> CreateVideoDecodersForTest() {
    // Previously decoders could have been destroyed on decoder reselection.
    decoders_.clear();

    // Provide 3 decoders to test fallback cases.
    // TODO(xhwang): We should test the case where only certain decoder
    // supports encrypted streams. Currently this is hard to test because we use
    // parameterized tests which need to pass in all combinations.
    std::vector<std::unique_ptr<VideoDecoder>> decoders;

#if !defined(OS_ANDROID)
    // Note this is _not_ inserted into |decoders_| below, so we don't need to
    // adjust the indices used below to compensate.
    decoders.push_back(std::make_unique<DecryptingVideoDecoder>(
        task_environment_.GetMainThreadTaskRunner(), &media_log_));
#endif

    for (int i = 0; i < 3; ++i) {
      auto decoder = std::make_unique<FakeVideoDecoder>(
          GetDecoderId(i), GetParam().decoding_delay,
          GetParam().parallel_decoding,
          base::BindRepeating(&VideoDecoderStreamTest::OnBytesDecoded,
                              base::Unretained(this)));

      if (GetParam().is_encrypted && !GetParam().has_decryptor)
        decoder->EnableEncryptedConfigSupport();

      // Keep a reference so we can change the behavior of each decoder.
      decoders_.push_back(decoder->GetWeakPtr());

      decoders.push_back(std::move(decoder));
    }

    for (const auto i : decoder_indices_to_fail_init_)
      decoders_[i]->SimulateFailureToInit();

    for (const auto i : decoder_indices_to_hold_init_)
      decoders_[i]->HoldNextInit();

    for (const auto i : decoder_indices_to_hold_decode_)
      decoders_[i]->HoldDecode();

    for (const auto i : platform_decoder_indices_)
      decoders_[i]->SetIsPlatformDecoder(true);

    return decoders;
  }

  void ClearDecoderInitExpectations() {
    decoder_indices_to_fail_init_.clear();
    decoder_indices_to_hold_init_.clear();
    decoder_indices_to_hold_decode_.clear();
    platform_decoder_indices_.clear();
  }

  // On next decoder selection, fail initialization on decoders specified by
  // |decoder_indices|.
  void FailDecoderInitOnSelection(std::vector<int> decoder_indices) {
    decoder_indices_to_fail_init_ = std::move(decoder_indices);
    for (int i : decoder_indices_to_fail_init_) {
      if (!decoders_.empty() && decoders_[i] && decoders_[i].get() != decoder_)
        decoders_[i]->SimulateFailureToInit();
    }
  }

  // On next decoder selection, hold initialization on decoders specified by
  // |decoder_indices|.
  void HoldDecoderInitOnSelection(std::vector<int> decoder_indices) {
    decoder_indices_to_hold_init_ = std::move(decoder_indices);
    for (int i : decoder_indices_to_hold_init_) {
      if (!decoders_.empty() && decoders_[i] && decoders_[i].get() != decoder_)
        decoders_[i]->HoldNextInit();
    }
  }

  // After next decoder selection, hold decode on decoders specified by
  // |decoder_indices|. This is needed because after decoder selection decode
  // may be resumed immediately and it'll be too late to hold decode then.
  void HoldDecodeAfterSelection(std::vector<int> decoder_indices) {
    decoder_indices_to_hold_decode_ = std::move(decoder_indices);
    for (int i : decoder_indices_to_hold_decode_) {
      if (!decoders_.empty() && decoders_[i] && decoders_[i].get() != decoder_)
        decoders_[i]->HoldDecode();
    }
  }

  void EnablePlatformDecoders(std::vector<int> decoder_indices) {
    platform_decoder_indices_ = std::move(decoder_indices);
    for (int i : platform_decoder_indices_) {
      if (!decoders_.empty() && decoders_[i] && decoders_[i].get() != decoder_)
        decoders_[i]->SetIsPlatformDecoder(true);
    }
  }

  // Updates the |decoder_| currently being used by VideoDecoderStream.
  void OnDecoderChanged(VideoDecoder* decoder) {
    if (!decoder) {
      decoder_ = nullptr;
      return;
    }

    // Ensure there's a media log created whenever selecting a decoder.
    EXPECT_MEDIA_LOG(HasSubstr("for video decoding, config"));
    decoder_ = static_cast<FakeVideoDecoder*>(decoder);
    ASSERT_TRUE(decoder_->GetDecoderId() == GetDecoderId(0) ||
                decoder_->GetDecoderId() == GetDecoderId(1) ||
                decoder_->GetDecoderId() == GetDecoderId(2));
  }

  MOCK_METHOD1(OnWaiting, void(WaitingReason));

  void OnStatistics(const PipelineStatistics& statistics) {
    num_decoded_bytes_unreported_ -= statistics.video_bytes_decoded;
  }

  void OnInitialized(bool success) {
    DCHECK(!pending_read_);
    DCHECK(!pending_reset_);
    DCHECK(pending_initialize_);
    pending_initialize_ = false;

    is_initialized_ = success;
    if (!success)
      decoders_.clear();
  }

  void Initialize() {
    if (!demuxer_stream_) {
      demuxer_stream_ = std::make_unique<FakeDemuxerStream>(
          kNumConfigs, kNumBuffersInOneConfig, GetParam().is_encrypted);
    }

    pending_initialize_ = true;
    video_decoder_stream_->Initialize(
        demuxer_stream_.get(),
        base::BindOnce(&VideoDecoderStreamTest::OnInitialized,
                       base::Unretained(this)),
        cdm_context_.get(),
        base::BindRepeating(&VideoDecoderStreamTest::OnStatistics,
                            base::Unretained(this)),
        base::BindRepeating(&VideoDecoderStreamTest::OnWaiting,
                            base::Unretained(this)));

    EXPECT_MEDIA_LOG(HasSubstr("video")).Times(AnyNumber());
    EXPECT_MEDIA_LOG(HasSubstr("Video")).Times(AnyNumber());
    EXPECT_MEDIA_LOG(HasSubstr("audio")).Times(AnyNumber());
    EXPECT_MEDIA_LOG(HasSubstr("Audio")).Times(AnyNumber());
    base::RunLoop().RunUntilIdle();
  }

  // Fake Decrypt() function used by DecryptingDemuxerStream. It does nothing
  // but removes the DecryptConfig to make the buffer unencrypted.
  void Decrypt(Decryptor::StreamType stream_type,
               scoped_refptr<DecoderBuffer> encrypted,
               Decryptor::DecryptCB decrypt_cb) {
    DCHECK(encrypted->decrypt_config());
    if (has_no_key_) {
      std::move(decrypt_cb).Run(Decryptor::kNoKey, nullptr);
      return;
    }

    DCHECK_EQ(stream_type, Decryptor::kVideo);
    scoped_refptr<DecoderBuffer> decrypted =
        DecoderBuffer::CopyFrom(encrypted->data(), encrypted->data_size());
    if (encrypted->is_key_frame())
      decrypted->set_is_key_frame(true);
    decrypted->set_timestamp(encrypted->timestamp());
    decrypted->set_duration(encrypted->duration());
    std::move(decrypt_cb).Run(Decryptor::kSuccess, decrypted);
  }

  // Callback for VideoDecoderStream::Read().
  void FrameReady(VideoDecoderStream::ReadResult result) {
    DCHECK(pending_read_);
    last_read_status_code_ = result.code();
    scoped_refptr<VideoFrame> frame = last_read_status_code_ == StatusCode::kOk
                                          ? std::move(result).value()
                                          : nullptr;
    frame_read_ = frame;
    if (frame && !frame->metadata().end_of_stream) {
      EXPECT_EQ(*frame->metadata().frame_duration, demuxer_stream_->duration());

      num_decoded_frames_++;
    }
    pending_read_ = false;
  }

  void OnReset() {
    DCHECK(!pending_read_);
    DCHECK(pending_reset_);
    pending_reset_ = false;
  }

  void ReadOneFrame() {
    frame_read_ = nullptr;
    pending_read_ = true;
    video_decoder_stream_->Read(base::BindOnce(
        &VideoDecoderStreamTest::FrameReady, base::Unretained(this)));
    base::RunLoop().RunUntilIdle();
  }

  void ReadUntilPending() {
    do {
      ReadOneFrame();
    } while (!pending_read_);
  }

  void ReadAllFrames(int expected_decoded_frames) {
    // Reading all frames reinitializes the demuxer.
    do {
      ReadOneFrame();
    } while (frame_read_.get() && !frame_read_->metadata().end_of_stream);

    DCHECK_EQ(expected_decoded_frames, num_decoded_frames_);
  }

  void ReadAllFrames() {
    // No frames should have been dropped.
    ReadAllFrames(kNumConfigs * kNumBuffersInOneConfig);
  }

  enum PendingState {
    NOT_PENDING,
    DEMUXER_READ_NORMAL,
    DEMUXER_READ_CONFIG_CHANGE,
    DECRYPTOR_NO_KEY,
    DECODER_REINIT,
    DECODER_DECODE,
    DECODER_RESET
  };

  void EnterPendingState(PendingState state) {
    DCHECK_NE(state, NOT_PENDING);
    switch (state) {
      case DEMUXER_READ_NORMAL:
        demuxer_stream_->HoldNextRead();
        ReadUntilPending();
        break;

      case DEMUXER_READ_CONFIG_CHANGE:
        demuxer_stream_->HoldNextConfigChangeRead();
        ReadUntilPending();
        break;

      case DECRYPTOR_NO_KEY:
        if (GetParam().is_encrypted && GetParam().has_decryptor) {
          EXPECT_MEDIA_LOG(HasSubstr("no key for key ID"));
          EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey));
          has_no_key_ = true;
        }
        ReadOneFrame();
        break;

      case DECODER_REINIT:
        decoder_->HoldNextInit();
        ReadUntilPending();
        break;

      case DECODER_DECODE:
        decoder_->HoldDecode();
        ReadUntilPending();
        break;

      case DECODER_RESET:
        decoder_->HoldNextReset();
        pending_reset_ = true;
        video_decoder_stream_->Reset(base::BindOnce(
            &VideoDecoderStreamTest::OnReset, base::Unretained(this)));
        base::RunLoop().RunUntilIdle();
        break;

      case NOT_PENDING:
        NOTREACHED();
        break;
    }
  }

  void SatisfyPendingCallback(PendingState state) {
    DCHECK_NE(state, NOT_PENDING);
    switch (state) {
      case DEMUXER_READ_CONFIG_CHANGE:
        EXPECT_MEDIA_LOG(HasSubstr("decoder config changed"))
            .Times(testing::AtLeast(1));
        FALLTHROUGH;
      case DEMUXER_READ_NORMAL:
        demuxer_stream_->SatisfyRead();
        break;

      // This is only interesting to test during VideoDecoderStream destruction.
      // There's no need to satisfy a callback.
      case DECRYPTOR_NO_KEY:
        NOTREACHED();
        break;

      case DECODER_REINIT:
        decoder_->SatisfyInit();
        break;

      case DECODER_DECODE:
        decoder_->SatisfyDecode();
        break;

      case DECODER_RESET:
        decoder_->SatisfyReset();
        break;

      case NOT_PENDING:
        NOTREACHED();
        break;
    }

    base::RunLoop().RunUntilIdle();
  }

  void Read() {
    EnterPendingState(DECODER_DECODE);
    SatisfyPendingCallback(DECODER_DECODE);
  }

  void Reset() {
    EnterPendingState(DECODER_RESET);
    SatisfyPendingCallback(DECODER_RESET);
  }

  void ReadUntilDecoderReinitialized() {
    EnterPendingState(DECODER_REINIT);
    SatisfyPendingCallback(DECODER_REINIT);
  }

  base::test::SingleThreadTaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};

  StrictMock<MockMediaLog> media_log_;
  std::unique_ptr<VideoDecoderStream> video_decoder_stream_;
  std::unique_ptr<FakeDemuxerStream> demuxer_stream_;
  std::unique_ptr<StrictMock<MockCdmContext>> cdm_context_;

  // Use NiceMock since we don't care about most of calls on the decryptor.
  std::unique_ptr<NiceMock<MockDecryptor>> decryptor_;

  // References to the list of decoders to be select from by DecoderSelector.
  // Three decoders are needed to test that decoder fallback can occur more than
  // once on a config change. They are owned by |video_decoder_stream_|.
  std::vector<base::WeakPtr<FakeVideoDecoder>> decoders_;

  std::vector<int> decoder_indices_to_fail_init_;
  std::vector<int> decoder_indices_to_hold_init_;
  std::vector<int> decoder_indices_to_hold_decode_;
  std::vector<int> platform_decoder_indices_;

  // The current decoder used by |video_decoder_stream_|.
  FakeVideoDecoder* decoder_ = nullptr;

  bool is_initialized_;
  int num_decoded_frames_;
  bool pending_initialize_;
  bool pending_read_;
  bool pending_reset_;
  bool pending_stop_;
  int num_decoded_bytes_unreported_;
  scoped_refptr<VideoFrame> frame_read_;
  StatusCode last_read_status_code_;

  // Decryptor has no key to decrypt a frame.
  bool has_no_key_;
};

INSTANTIATE_TEST_SUITE_P(
    Clear,
    VideoDecoderStreamTest,
    ::testing::Values(VideoDecoderStreamTestParams(false, false, false, 0, 1),
                      VideoDecoderStreamTestParams(false, false, false, 3, 1),
                      VideoDecoderStreamTestParams(false, false, false, 7, 1),
                      VideoDecoderStreamTestParams(false, false, true, 0, 1),
                      VideoDecoderStreamTestParams(false, false, true, 3, 1)));

INSTANTIATE_TEST_SUITE_P(
    EncryptedWithDecryptor,
    VideoDecoderStreamTest,
    ::testing::Values(VideoDecoderStreamTestParams(true, true, false, 7, 1),
                      VideoDecoderStreamTestParams(true, true, true, 7, 1)));

INSTANTIATE_TEST_SUITE_P(
    EncryptedWithoutDecryptor,
    VideoDecoderStreamTest,
    ::testing::Values(VideoDecoderStreamTestParams(true, false, false, 7, 1),
                      VideoDecoderStreamTestParams(true, false, true, 7, 1)));

INSTANTIATE_TEST_SUITE_P(
    Clear_Parallel,
    VideoDecoderStreamTest,
    ::testing::Values(VideoDecoderStreamTestParams(false, false, false, 0, 3),
                      VideoDecoderStreamTestParams(false, false, false, 2, 3),
                      VideoDecoderStreamTestParams(false, false, true, 0, 3),
                      VideoDecoderStreamTestParams(false, false, true, 2, 3)));

TEST_P(VideoDecoderStreamTest, CanReadWithoutStallingAtAnyTime) {
  ASSERT_FALSE(video_decoder_stream_->CanReadWithoutStalling());
}

TEST_P(VideoDecoderStreamTest, Initialization) {
  Initialize();
  EXPECT_TRUE(is_initialized_);
}

TEST_P(VideoDecoderStreamTest, AllDecoderInitializationFails) {
  FailDecoderInitOnSelection({0, 1, 2});
  Initialize();
  EXPECT_FALSE(is_initialized_);
}

TEST_P(VideoDecoderStreamTest, PartialDecoderInitializationFails) {
  FailDecoderInitOnSelection({0, 1});
  Initialize();
  EXPECT_TRUE(is_initialized_);
}

TEST_P(VideoDecoderStreamTest, ReadOneFrame) {
  Initialize();
  Read();
}

TEST_P(VideoDecoderStreamTest, ReadAllFrames) {
  Initialize();
  ReadAllFrames();
}

TEST_P(VideoDecoderStreamTest, Read_AfterReset) {
  Initialize();
  Reset();
  Read();
  Reset();
  Read();
}

// Tests that the decoder stream will switch from a software decoder to a
// hardware decoder if the config size increases
TEST_P(VideoDecoderStreamTest, ConfigChangeSwToHw) {
  EnablePlatformDecoders({1});

  // Create a demuxer stream with a config that increases in size
  auto const size_delta =
      TestVideoConfig::LargeCodedSize() - TestVideoConfig::NormalCodedSize();
  auto const width_delta = size_delta.width() / (kNumConfigs - 1);
  auto const height_delta = size_delta.height() / (kNumConfigs - 1);
  CreateDemuxerStream(TestVideoConfig::NormalCodedSize(),
                      gfx::Vector2dF(width_delta, height_delta));
  Initialize();

  // Initially we should be using a software decoder
  EXPECT_TRUE(decoder_);
  EXPECT_FALSE(decoder_->IsPlatformDecoder());

  ReadAllFrames();

  // We should end up on a hardware decoder
  EXPECT_TRUE(decoder_->IsPlatformDecoder());
}

// Tests that the decoder stream will switch from a hardware decoder to a
// software decoder if the config size decreases
TEST_P(VideoDecoderStreamTest, ConfigChangeHwToSw) {
  EnablePlatformDecoders({1});

  // Create a demuxer stream with a config that progressively decreases in size
  auto const size_delta =
      TestVideoConfig::LargeCodedSize() - TestVideoConfig::NormalCodedSize();
  auto const width_delta = size_delta.width() / kNumConfigs;
  auto const height_delta = size_delta.height() / kNumConfigs;
  CreateDemuxerStream(TestVideoConfig::LargeCodedSize(),
                      gfx::Vector2dF(-width_delta, -height_delta));
  Initialize();

  // We should initially be using a hardware decoder
  EXPECT_TRUE(decoder_);
  EXPECT_TRUE(decoder_->IsPlatformDecoder());
  ReadAllFrames();

  // We should end up on a software decoder
  EXPECT_FALSE(decoder_->IsPlatformDecoder());
}

TEST_P(VideoDecoderStreamTest, Read_ProperMetadata) {
  // For testing simplicity, omit parallel decode tests with a delay in frames.
  if (GetParam().parallel_decoding > 1 && GetParam().decoding_delay > 0)
    return;

  if (GetParam().has_prepare) {
    // Override the basic PrepareFrame() for a version that moves the MockTime
    // by kPrepareDelay. This simulates real work done (e.g. YUV conversion).
    video_decoder_stream_->SetPrepareCB(
        base::BindRepeating(&VideoDecoderStreamTest::PrepareFrameWithDelay,
                            base::Unretained(this)));
  }

  constexpr base::TimeDelta kDecodeDelay = base::Milliseconds(10);

  Initialize();

  // Simulate time elapsed by the decoder.
  EnterPendingState(DECODER_DECODE);
  task_environment_.FastForwardBy(kDecodeDelay);

  SatisfyPendingCallback(DECODER_DECODE);

  EXPECT_TRUE(frame_read_);

  const VideoFrameMetadata& metadata = frame_read_->metadata();

  // Verify the decoding metadata is accurate.
  EXPECT_EQ(*metadata.decode_end_time - *metadata.decode_begin_time,
            kDecodeDelay);

  // Verify the processing metadata is accurate.
  const base::TimeDelta expected_processing_time =
      GetParam().has_prepare ? (kDecodeDelay + kPrepareDelay) : kDecodeDelay;

  EXPECT_EQ(*metadata.processing_time, expected_processing_time);
}

TEST_P(VideoDecoderStreamTest, Read_BlockedDemuxer) {
  Initialize();
  demuxer_stream_->HoldNextRead();
  ReadOneFrame();
  EXPECT_TRUE(pending_read_);

  int demuxed_buffers = 0;

  // Pass frames from the demuxer to the VideoDecoderStream until the first read
  // request is satisfied.
  while (pending_read_) {
    ++demuxed_buffers;
    demuxer_stream_->SatisfyReadAndHoldNext();
    base::RunLoop().RunUntilIdle();
  }

  EXPECT_EQ(std::min(GetParam().decoding_delay + 1, kNumBuffersInOneConfig + 1),
            demuxed_buffers);

  // At this point the stream is waiting on read from the demuxer, but there is
  // no pending read from the stream. The stream should be blocked if we try
  // reading from it again.
  ReadUntilPending();

  demuxer_stream_->SatisfyRead();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(pending_read_);
}

TEST_P(VideoDecoderStreamTest, Read_BlockedDemuxerAndDecoder) {
  // Test applies only when the decoder allows multiple parallel requests.
  if (GetParam().parallel_decoding == 1)
    return;

  Initialize();
  demuxer_stream_->HoldNextRead();
  decoder_->HoldDecode();
  ReadOneFrame();
  EXPECT_TRUE(pending_read_);

  int demuxed_buffers = 0;

  // Pass frames from the demuxer to the VideoDecoderStream until the first read
  // request is satisfied, while always keeping one decode request pending.
  while (pending_read_) {
    ++demuxed_buffers;
    demuxer_stream_->SatisfyReadAndHoldNext();
    base::RunLoop().RunUntilIdle();

    // Always keep one decode request pending.
    if (demuxed_buffers > 1) {
      decoder_->SatisfySingleDecode();
      base::RunLoop().RunUntilIdle();
    }
  }

  ReadUntilPending();
  EXPECT_TRUE(pending_read_);

  // Unblocking one decode request should unblock read even when demuxer is
  // still blocked.
  decoder_->SatisfySingleDecode();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(pending_read_);

  // Stream should still be blocked on the demuxer after unblocking the decoder.
  decoder_->SatisfyDecode();
  ReadUntilPending();
  EXPECT_TRUE(pending_read_);

  // Verify that the stream has returned all frames that have been demuxed,
  // accounting for the decoder delay.
  EXPECT_EQ(demuxed_buffers - GetParam().decoding_delay, num_decoded_frames_);

  // Unblocking the demuxer will unblock the stream.
  demuxer_stream_->SatisfyRead();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(pending_read_);
}

TEST_P(VideoDecoderStreamTest, Read_DuringEndOfStreamDecode) {
  // Test applies only when the decoder allows multiple parallel requests, and
  // they are not satisfied in a single batch.
  if (GetParam().parallel_decoding == 1 || GetParam().decoding_delay != 0)
    return;

  Initialize();
  decoder_->HoldDecode();

  // Read all of the frames up to end of stream. Since parallel decoding is
  // enabled, the end of stream buffer will be sent to the decoder immediately,
  // but we don't satisfy it yet.
  for (int configuration = 0; configuration < kNumConfigs; configuration++) {
    for (int frame = 0; frame < kNumBuffersInOneConfig; frame++) {
      ReadOneFrame();
      while (pending_read_) {
        decoder_->SatisfySingleDecode();
        base::RunLoop().RunUntilIdle();
      }
    }
  }

  // Read() again. The callback must be delayed until the decode completes.
  ReadOneFrame();
  ASSERT_TRUE(pending_read_);

  // Satisfy decoding of the end of stream buffer. The read should complete.
  decoder_->SatisfySingleDecode();
  base::RunLoop().RunUntilIdle();
  ASSERT_FALSE(pending_read_);
  EXPECT_EQ(last_read_status_code_, StatusCode::kOk);

  // The read output should indicate end of stream.
  ASSERT_TRUE(frame_read_.get());
  EXPECT_TRUE(frame_read_->metadata().end_of_stream);
}

TEST_P(VideoDecoderStreamTest, Read_DemuxerStreamReadError) {
  Initialize();
  EnterPendingState(DEMUXER_READ_NORMAL);

  InSequence s;

  if (GetParam().is_encrypted && GetParam().has_decryptor) {
    EXPECT_MEDIA_LOG(
        HasSubstr("DecryptingDemuxerStream: demuxer stream read error"));
  }
  EXPECT_MEDIA_LOG(HasSubstr("video demuxer stream read error"));

  demuxer_stream_->Error();
  base::RunLoop().RunUntilIdle();

  ASSERT_FALSE(pending_read_);
  EXPECT_NE(last_read_status_code_, StatusCode::kOk);
  EXPECT_NE(last_read_status_code_, StatusCode::kAborted);
}

// No Reset() before initialization is successfully completed.
TEST_P(VideoDecoderStreamTest, Reset_AfterInitialization) {
  Initialize();
  Reset();
  Read();
}

TEST_P(VideoDecoderStreamTest, Reset_DuringReinitialization) {
  Initialize();

  EnterPendingState(DECODER_REINIT);
  // VideoDecoder::Reset() is not called when we reset during reinitialization.
  pending_reset_ = true;
  video_decoder_stream_->Reset(
      base::BindOnce(&VideoDecoderStreamTest::OnReset, base::Unretained(this)));
  SatisfyPendingCallback(DECODER_REINIT);
  Read();
}

TEST_P(VideoDecoderStreamTest, Reset_AfterReinitialization) {
  Initialize();
  EnterPendingState(DECODER_REINIT);
  SatisfyPendingCallback(DECODER_REINIT);
  Reset();
  Read();
}

TEST_P(VideoDecoderStreamTest, Reset_DuringDemuxerRead_Normal) {
  Initialize();
  EnterPendingState(DEMUXER_READ_NORMAL);
  EnterPendingState(DECODER_RESET);
  SatisfyPendingCallback(DEMUXER_READ_NORMAL);
  SatisfyPendingCallback(DECODER_RESET);
  Read();
}

TEST_P(VideoDecoderStreamTest, Reset_DuringDemuxerRead_ConfigChange) {
  Initialize();
  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
  EnterPendingState(DECODER_RESET);
  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
  SatisfyPendingCallback(DECODER_RESET);
  Read();
}

TEST_P(VideoDecoderStreamTest, Reset_DuringNormalDecoderDecode) {
  Initialize();
  EnterPendingState(DECODER_DECODE);
  EnterPendingState(DECODER_RESET);
  SatisfyPendingCallback(DECODER_DECODE);
  SatisfyPendingCallback(DECODER_RESET);
  Read();
}

TEST_P(VideoDecoderStreamTest, Reset_AfterNormalRead) {
  Initialize();
  Read();
  Reset();
  Read();
}

TEST_P(VideoDecoderStreamTest, Reset_AfterDemuxerRead_ConfigChange) {
  Initialize();
  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
  Reset();
  Read();
}

TEST_P(VideoDecoderStreamTest, Reset_AfterEndOfStream) {
  Initialize();
  ReadAllFrames();
  Reset();
  num_decoded_frames_ = 0;
  demuxer_stream_->SeekToStart();
  ReadAllFrames();
}

TEST_P(VideoDecoderStreamTest, Reset_DuringNoKeyRead) {
  Initialize();
  EnterPendingState(DECRYPTOR_NO_KEY);
  Reset();
}

// In the following Destroy_* tests, |video_decoder_stream_| is destroyed in
// VideoDecoderStreamTest destructor.

TEST_P(VideoDecoderStreamTest, Destroy_BeforeInitialization) {}

TEST_P(VideoDecoderStreamTest, Destroy_DuringInitialization) {
  HoldDecoderInitOnSelection({0});
  Initialize();
}

TEST_P(VideoDecoderStreamTest, Destroy_AfterInitialization) {
  Initialize();
}

TEST_P(VideoDecoderStreamTest, Destroy_DuringReinitialization) {
  Initialize();
  EnterPendingState(DECODER_REINIT);
}

TEST_P(VideoDecoderStreamTest, Destroy_AfterReinitialization) {
  Initialize();
  EnterPendingState(DECODER_REINIT);
  SatisfyPendingCallback(DECODER_REINIT);
}

TEST_P(VideoDecoderStreamTest, Destroy_DuringDemuxerRead_Normal) {
  Initialize();
  EnterPendingState(DEMUXER_READ_NORMAL);
}

TEST_P(VideoDecoderStreamTest, Destroy_DuringDemuxerRead_ConfigChange) {
  Initialize();
  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
}

TEST_P(VideoDecoderStreamTest, Destroy_DuringNormalDecoderDecode) {
  Initialize();
  EnterPendingState(DECODER_DECODE);
}

TEST_P(VideoDecoderStreamTest, Destroy_AfterNormalRead) {
  Initialize();
  Read();
}

TEST_P(VideoDecoderStreamTest, Destroy_AfterConfigChangeRead) {
  Initialize();
  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
}

TEST_P(VideoDecoderStreamTest, Destroy_DuringDecoderReinitialization) {
  Initialize();
  EnterPendingState(DECODER_REINIT);
}

TEST_P(VideoDecoderStreamTest, Destroy_DuringNoKeyRead) {
  Initialize();
  EnterPendingState(DECRYPTOR_NO_KEY);
}

TEST_P(VideoDecoderStreamTest, Destroy_DuringReset) {
  Initialize();
  EnterPendingState(DECODER_RESET);
}

TEST_P(VideoDecoderStreamTest, Destroy_AfterReset) {
  Initialize();
  Reset();
}

TEST_P(VideoDecoderStreamTest, Destroy_DuringRead_DuringReset) {
  Initialize();
  EnterPendingState(DECODER_DECODE);
  EnterPendingState(DECODER_RESET);
}

TEST_P(VideoDecoderStreamTest, Destroy_AfterRead_DuringReset) {
  Initialize();
  EnterPendingState(DECODER_DECODE);
  EnterPendingState(DECODER_RESET);
  SatisfyPendingCallback(DECODER_DECODE);
}

TEST_P(VideoDecoderStreamTest, Destroy_AfterRead_AfterReset) {
  Initialize();
  Read();
  Reset();
}

// The following tests cover the fallback logic after reinitialization error or
// decode error of the first buffer after initialization.

TEST_P(VideoDecoderStreamTest, FallbackDecoder_DecodeError) {
  Initialize();
  decoder_->SimulateError();
  ReadOneFrame();

  // |video_decoder_stream_| should have fallen back to a new decoder.
  ASSERT_EQ(GetDecoderId(1), decoder_->GetDecoderId());

  ASSERT_FALSE(pending_read_);
  ASSERT_EQ(last_read_status_code_, StatusCode::kOk);

  // Check that we fell back to Decoder2.
  ASSERT_GT(decoder_->total_bytes_decoded(), 0);

  // Verify no frame was dropped.
  ReadAllFrames();
}

TEST_P(VideoDecoderStreamTest,
       FallbackDecoder_EndOfStreamReachedBeforeFallback) {
  // Only consider cases where there is a decoder delay. For test simplicity,
  // omit the parallel case.
  if (GetParam().decoding_delay == 0 || GetParam().parallel_decoding > 1)
    return;

  Initialize();
  decoder_->HoldDecode();
  ReadOneFrame();

  // One buffer should have already pulled from the demuxer stream. Set the next
  // one to be an EOS.
  demuxer_stream_->SeekToEndOfStream();

  decoder_->SatisfySingleDecode();
  base::RunLoop().RunUntilIdle();

  // |video_decoder_stream_| should not have emitted a frame.
  EXPECT_TRUE(pending_read_);

  // Pending buffers should contain a regular buffer and an EOS buffer.
  EXPECT_EQ(video_decoder_stream_->get_pending_buffers_size_for_testing(), 2);

  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(GetDecoderId(1), decoder_->GetDecoderId());

  // A frame should have been emitted.
  EXPECT_FALSE(pending_read_);
  EXPECT_EQ(last_read_status_code_, StatusCode::kOk);
  EXPECT_FALSE(frame_read_->metadata().end_of_stream);
  EXPECT_GT(decoder_->total_bytes_decoded(), 0);

  ReadOneFrame();

  EXPECT_FALSE(pending_read_);
  EXPECT_EQ(0, video_decoder_stream_->get_fallback_buffers_size_for_testing());
  EXPECT_TRUE(frame_read_->metadata().end_of_stream);
}

TEST_P(VideoDecoderStreamTest,
       FallbackDecoder_DoesReinitializeStompPendingRead) {
  // Test only the case where there is no decoding delay and parallel decoding.
  if (GetParam().decoding_delay != 0 || GetParam().parallel_decoding <= 1)
    return;

  Initialize();
  decoder_->HoldDecode();

  // Queue one read, defer the second.
  frame_read_ = nullptr;
  pending_read_ = true;
  video_decoder_stream_->Read(base::BindOnce(
      &VideoDecoderStreamTest::FrameReady, base::Unretained(this)));
  demuxer_stream_->HoldNextRead();

  // Force an error to occur on the first decode, but ensure it isn't propagated
  // until after the next read has been started.
  decoder_->SimulateError();
  HoldDecodeAfterSelection({1});

  // Complete the fallback to the second decoder with the read still pending.
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(GetDecoderId(1), decoder_->GetDecoderId());

  // Can't check the original decoder right now, it might have been destroyed
  // already. Verify that there was nothing decoded until we kicked the decoder.
  EXPECT_EQ(decoder_->total_bytes_decoded(), 0);
  decoder_->SatisfyDecode();
  const int first_decoded_bytes = decoder_->total_bytes_decoded();
  ASSERT_GT(first_decoded_bytes, 0);

  // Satisfy the previously pending read and ensure it is decoded.
  demuxer_stream_->SatisfyRead();
  base::RunLoop().RunUntilIdle();
  ASSERT_GT(decoder_->total_bytes_decoded(), first_decoded_bytes);
}

TEST_P(VideoDecoderStreamTest, FallbackDecoder_DecodeErrorRepeated) {
  Initialize();

  // Hold other decoders to simulate errors.
  HoldDecodeAfterSelection({1, 2});

  // Simulate decode error to trigger the fallback path.
  decoder_->SimulateError();
  ReadOneFrame();
  base::RunLoop().RunUntilIdle();

  // Expect decoder 1 to be tried.
  ASSERT_EQ(GetDecoderId(1), decoder_->GetDecoderId());
  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  // Then decoder 2.
  ASSERT_EQ(GetDecoderId(2), decoder_->GetDecoderId());
  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  // No decoders left, expect failure.
  EXPECT_EQ(decoder_, nullptr);
  EXPECT_FALSE(pending_read_);
  EXPECT_NE(last_read_status_code_, StatusCode::kOk);
  EXPECT_NE(last_read_status_code_, StatusCode::kAborted);
}

// This tests verifies that we properly fallback to a new decoder if the first
// decode after a config change fails.
TEST_P(VideoDecoderStreamTest,
       FallbackDecoder_SelectedOnMidstreamDecodeErrorAfterReinitialization) {
  // For simplicity of testing, this test applies only when there is no decoder
  // delay and parallel decoding is disabled.
  if (GetParam().decoding_delay != 0 || GetParam().parallel_decoding > 1)
    return;

  Initialize();

  // Note: Completes decoding one frame, results in Decode() being called with
  // second frame that is not completed.
  ReadOneFrame();

  // Verify that the first frame was decoded successfully.
  EXPECT_FALSE(pending_read_);
  EXPECT_GT(decoder_->total_bytes_decoded(), 0);
  EXPECT_EQ(last_read_status_code_, StatusCode::kOk);

  // Continue up to the point of reinitialization.
  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);

  // Hold decodes to prevent a frame from being outputted upon reinitialization.
  decoder_->HoldDecode();
  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);

  // DecoderStream sends an EOS to flush the decoder during config changes.
  // Let the EOS decode be satisfied to properly complete the decoder reinit.
  decoder_->SatisfySingleDecode();
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(pending_read_);

  // Fail the first decode, before a frame can be outputted.
  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  ReadOneFrame();

  // Verify that fallback happened.
  EXPECT_EQ(GetDecoderId(0), decoder_->GetDecoderId());
  EXPECT_FALSE(pending_read_);
  EXPECT_EQ(last_read_status_code_, StatusCode::kOk);
  EXPECT_GT(decoder_->total_bytes_decoded(), 0);
}

TEST_P(VideoDecoderStreamTest,
       FallbackDecoder_DecodeErrorRepeated_AfterReinitialization) {
  Initialize();

  // Simulate decode error to trigger fallback.
  decoder_->SimulateError();
  ReadOneFrame();
  base::RunLoop().RunUntilIdle();

  // Simulate reinitialize error of decoder 1.
  ASSERT_EQ(GetDecoderId(1), decoder_->GetDecoderId());
  decoder_->SimulateFailureToInit();
  HoldDecodeAfterSelection({0, 1, 2});
  ReadUntilDecoderReinitialized();

  // Decoder 0 should be selected again.
  ASSERT_EQ(GetDecoderId(0), decoder_->GetDecoderId());
  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  // Decoder 1.
  ASSERT_EQ(GetDecoderId(1), decoder_->GetDecoderId());
  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  // Decoder 2.
  ASSERT_EQ(GetDecoderId(2), decoder_->GetDecoderId());
  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  // No decoders left.
  EXPECT_EQ(decoder_, nullptr);
  EXPECT_FALSE(pending_read_);
  EXPECT_NE(last_read_status_code_, StatusCode::kOk);
  EXPECT_NE(last_read_status_code_, StatusCode::kAborted);
}

TEST_P(VideoDecoderStreamTest,
       FallbackDecoder_ConfigChangeClearsPendingBuffers) {
  // Test case is only interesting if the decoder can receive a config change
  // before returning its first frame.
  if (GetParam().decoding_delay < kNumBuffersInOneConfig)
    return;

  Initialize();
  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
  ASSERT_GT(video_decoder_stream_->get_pending_buffers_size_for_testing(), 0);

  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
  ASSERT_EQ(video_decoder_stream_->get_pending_buffers_size_for_testing(), 0);
  EXPECT_FALSE(pending_read_);

  ReadAllFrames();
}

TEST_P(VideoDecoderStreamTest,
       FallbackDecoder_ErrorDuringConfigChangeFlushing) {
  // Test case is only interesting if the decoder can receive a config change
  // before returning its first frame.
  if (GetParam().decoding_delay < kNumBuffersInOneConfig)
    return;

  Initialize();
  EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
  EXPECT_GT(video_decoder_stream_->get_pending_buffers_size_for_testing(), 0);

  decoder_->HoldDecode();
  SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);

  // The flush request should have been sent and held.
  EXPECT_EQ(video_decoder_stream_->get_pending_buffers_size_for_testing(), 0);
  EXPECT_TRUE(pending_read_);

  // Triggering an error here will cause the frames in selected decoder to be
  // lost. There are no pending buffers to give to |decoders_[1]| due to
  // http://crbug.com/603713
  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  // We want to make sure the fallback decoder can decode the rest of the frames
  // in the demuxer stream.
  ReadAllFrames(kNumBuffersInOneConfig * (kNumConfigs - 1));
}

TEST_P(VideoDecoderStreamTest,
       FallbackDecoder_PendingBuffersIsFilledAndCleared) {
  // Test applies only when there is a decoder delay, and the decoder will not
  // receive a config change before outputting its first frame. Parallel
  // decoding is also disabled in this test case, for readability and simplicity
  // of the unit test.
  if (GetParam().decoding_delay == 0 ||
      GetParam().decoding_delay > kNumBuffersInOneConfig ||
      GetParam().parallel_decoding > 1) {
    return;
  }

  Initialize();

  // Block on demuxer read and decoder decode so we can step through.
  demuxer_stream_->HoldNextRead();
  decoder_->HoldDecode();
  ReadOneFrame();

  int demuxer_reads_satisfied = 0;
  // Send back and requests buffers until the next one would fill the decoder
  // delay.
  while (demuxer_reads_satisfied < GetParam().decoding_delay - 1) {
    // Send a buffer back.
    demuxer_stream_->SatisfyReadAndHoldNext();
    base::RunLoop().RunUntilIdle();
    ++demuxer_reads_satisfied;

    // Decode one buffer.
    decoder_->SatisfySingleDecode();
    base::RunLoop().RunUntilIdle();
    EXPECT_TRUE(pending_read_);
    EXPECT_EQ(demuxer_reads_satisfied,
              video_decoder_stream_->get_pending_buffers_size_for_testing());
    // No fallback buffers should be queued up yet.
    EXPECT_EQ(0,
              video_decoder_stream_->get_fallback_buffers_size_for_testing());
  }

  // Hold the init before triggering the error, to verify internal state.
  demuxer_stream_->SatisfyReadAndHoldNext();
  ++demuxer_reads_satisfied;

  decoder_->SimulateError();

  HoldDecoderInitOnSelection({1});
  HoldDecodeAfterSelection({1});

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(pending_read_);
  EXPECT_EQ(demuxer_reads_satisfied,
            video_decoder_stream_->get_pending_buffers_size_for_testing());

  decoders_[1]->SatisfyInit();
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(GetDecoderId(1), decoder_->GetDecoderId());

  // Make sure the pending buffers have been transferred to fallback buffers.
  // One call to Decode() during the initialization process, so we expect one
  // buffer to already have been consumed from the fallback buffers.
  // Pending buffers should never go down (unless we encounter a config change)
  EXPECT_EQ(demuxer_reads_satisfied - 1,
            video_decoder_stream_->get_fallback_buffers_size_for_testing());
  EXPECT_EQ(demuxer_reads_satisfied,
            video_decoder_stream_->get_pending_buffers_size_for_testing());

  decoder_->SatisfyDecode();
  base::RunLoop().RunUntilIdle();

  // Make sure all buffers consumed by |decoders_| have come from the fallback.
  // Pending buffers should not have been cleared yet.
  EXPECT_EQ(0, video_decoder_stream_->get_fallback_buffers_size_for_testing());
  EXPECT_EQ(demuxer_reads_satisfied,
            video_decoder_stream_->get_pending_buffers_size_for_testing());
  EXPECT_TRUE(pending_read_);

  // Give the decoder one more buffer, enough to release a frame.
  demuxer_stream_->SatisfyReadAndHoldNext();
  base::RunLoop().RunUntilIdle();

  // New buffers should not have been added after the frame was released.
  EXPECT_EQ(video_decoder_stream_->get_pending_buffers_size_for_testing(), 0);
  EXPECT_FALSE(pending_read_);

  demuxer_stream_->SatisfyRead();

  // Confirm no frames were dropped.
  ReadAllFrames();
}

TEST_P(VideoDecoderStreamTest, FallbackDecoder_SelectedOnDecodeThenInitErrors) {
  Initialize();
  decoder_->SimulateError();
  FailDecoderInitOnSelection({1});
  ReadOneFrame();

  // Decoder 0 should be blocked, and decoder 1 fails to initialize, so
  // |video_decoder_stream_| should have fallen back to decoder 2.
  ASSERT_EQ(GetDecoderId(2), decoder_->GetDecoderId());

  ASSERT_FALSE(pending_read_);
  ASSERT_EQ(last_read_status_code_, StatusCode::kOk);

  // Can't check previously selected decoder(s) right now, they might have been
  // destroyed already.
  ASSERT_GT(decoder_->total_bytes_decoded(), 0);

  // Verify no frame was dropped.
  ReadAllFrames();
}

TEST_P(VideoDecoderStreamTest, FallbackDecoder_SelectedOnInitThenDecodeErrors) {
  FailDecoderInitOnSelection({0});
  Initialize();
  ASSERT_EQ(GetDecoderId(1), decoder_->GetDecoderId());
  ClearDecoderInitExpectations();

  decoder_->HoldDecode();
  ReadOneFrame();
  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  // |video_decoder_stream_| should have fallen back to decoder 2.
  ASSERT_EQ(GetDecoderId(2), decoder_->GetDecoderId());

  ASSERT_FALSE(pending_read_);
  ASSERT_EQ(last_read_status_code_, StatusCode::kOk);

  // Can't check previously selected decoder(s) right now, they might have been
  // destroyed already.
  ASSERT_GT(decoder_->total_bytes_decoded(), 0);

  // Verify no frame was dropped.
  ReadAllFrames();
}

TEST_P(VideoDecoderStreamTest,
       FallbackDecoder_NotSelectedOnMidstreamDecodeError) {
  Initialize();
  ReadOneFrame();

  // Successfully received a frame.
  EXPECT_FALSE(pending_read_);
  ASSERT_GT(decoder_->total_bytes_decoded(), 0);

  decoder_->SimulateError();

  // The error must surface from Read() as DECODE_ERROR.
  while (last_read_status_code_ == StatusCode::kOk) {
    ReadOneFrame();
    base::RunLoop().RunUntilIdle();
    EXPECT_FALSE(pending_read_);
  }

  // Verify the error was surfaced, rather than falling back to other decoders.
  ASSERT_EQ(GetDecoderId(0), decoder_->GetDecoderId());
  EXPECT_FALSE(pending_read_);
  EXPECT_NE(last_read_status_code_, StatusCode::kOk);
  EXPECT_NE(last_read_status_code_, StatusCode::kAborted);
}

TEST_P(VideoDecoderStreamTest, DecoderErrorWhenNotReading) {
  Initialize();
  decoder_->HoldDecode();
  ReadOneFrame();
  EXPECT_TRUE(pending_read_);

  // Satisfy decode requests until we get the first frame out.
  while (pending_read_) {
    decoder_->SatisfySingleDecode();
    base::RunLoop().RunUntilIdle();
  }

  // Trigger an error in the decoding.
  decoder_->SimulateError();

  // The error must surface from Read() as DECODE_ERROR.
  while (last_read_status_code_ == StatusCode::kOk) {
    ReadOneFrame();
    base::RunLoop().RunUntilIdle();
    EXPECT_FALSE(pending_read_);
  }
  EXPECT_NE(last_read_status_code_, StatusCode::kOk);
  EXPECT_NE(last_read_status_code_, StatusCode::kAborted);
}

TEST_P(VideoDecoderStreamTest, ReinitializeFailure_Once) {
  Initialize();
  decoder_->SimulateFailureToInit();
  ReadUntilDecoderReinitialized();
  // Should have fallen back to a new instance of decoder 0.
  ASSERT_EQ(GetDecoderId(0), decoder_->GetDecoderId());
  ReadAllFrames();
  ASSERT_GT(decoder_->total_bytes_decoded(), 0);
}

TEST_P(VideoDecoderStreamTest, ReinitializeFailure_Twice) {
  Initialize();

  // Trigger reinitialization error, and fallback to a new instance.
  decoder_->SimulateFailureToInit();
  ReadUntilDecoderReinitialized();
  ASSERT_EQ(GetDecoderId(0), decoder_->GetDecoderId());

  ReadOneFrame();

  // Trigger reinitialization error again. Since a frame was output, this will
  // be a new instance of decoder 0 again.
  decoder_->SimulateFailureToInit();
  ReadUntilDecoderReinitialized();
  ASSERT_EQ(GetDecoderId(0), decoder_->GetDecoderId());
  ReadAllFrames();
}

TEST_P(VideoDecoderStreamTest, ReinitializeFailure_OneUnsupportedDecoder) {
  Initialize();

  // The current decoder will fail to reinitialize.
  decoder_->SimulateFailureToInit();

  // Decoder 1 will also fail to initialize on decoder selection.
  FailDecoderInitOnSelection({0, 1});

  ReadUntilDecoderReinitialized();

  // As a result, decoder 2 will be selected.
  ASSERT_EQ(GetDecoderId(2), decoder_->GetDecoderId());

  ReadAllFrames();
}

TEST_P(VideoDecoderStreamTest, ReinitializeFailure_NoSupportedDecoder) {
  Initialize();

  // The current decoder will fail to reinitialize, triggering decoder
  // selection.
  decoder_->SimulateFailureToInit();

  // All of the decoders will fail in decoder selection.
  FailDecoderInitOnSelection({0, 1, 2});

  ReadUntilDecoderReinitialized();

  // The error will surface from Read() as DECODE_ERROR.
  while (last_read_status_code_ == StatusCode::kOk) {
    ReadOneFrame();
    base::RunLoop().RunUntilIdle();
    EXPECT_FALSE(pending_read_);
  }
  EXPECT_NE(last_read_status_code_, StatusCode::kOk);
  EXPECT_NE(last_read_status_code_, StatusCode::kAborted);
}

TEST_P(VideoDecoderStreamTest, Destroy_DuringFallbackDecoderSelection) {
  Initialize();
  decoder_->SimulateFailureToInit();
  EnterPendingState(DECODER_REINIT);
  HoldDecoderInitOnSelection({1});
  SatisfyPendingCallback(DECODER_REINIT);
}

}  // namespace media
