// 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 <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "media/base/fake_demuxer_stream.h"
#include "media/base/gmock_callback_support.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"

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 {

const int kNumConfigs = 4;
const int kNumBuffersInOneConfig = 5;

static std::string GetDecoderName(int i) {
  return std::string("VideoDecoder") + base::IntToString(i);
}

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

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

class VideoFrameStreamTest
    : public testing::Test,
      public testing::WithParamInterface<VideoFrameStreamTestParams> {
 public:
  VideoFrameStreamTest()
      : demuxer_stream_(new FakeDemuxerStream(kNumConfigs,
                                              kNumBuffersInOneConfig,
                                              GetParam().is_encrypted)),
        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_frame_stream_.reset(new VideoFrameStream(
        message_loop_.task_runner(),
        base::Bind(&VideoFrameStreamTest::CreateVideoDecodersForTest,
                   base::Unretained(this)),
        &media_log_));
    video_frame_stream_->set_decoder_change_observer_for_testing(base::Bind(
        &VideoFrameStreamTest::OnDecoderChanged, base::Unretained(this)));

    if (GetParam().is_encrypted && GetParam().has_decryptor) {
      decryptor_.reset(new NiceMock<MockDecryptor>());

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

    if (GetParam().is_encrypted) {
      cdm_context_.reset(new StrictMock<MockCdmContext>());

      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("decryptor")).Times(AnyNumber());
  }

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

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

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

  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;
    for (int i = 0; i < 3; ++i) {
      auto decoder = std::make_unique<FakeVideoDecoder>(
          GetDecoderName(i), GetParam().decoding_delay,
          GetParam().parallel_decoding,
          base::Bind(&VideoFrameStreamTest::OnBytesDecoded,
                     base::Unretained(this)));

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

      // Keep a copy of the raw pointers so we can change the behavior of each
      // decoder.
      decoders_.push_back(decoder.get());

      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();

    decoder_indices_to_fail_init_.clear();
    decoder_indices_to_hold_init_.clear();
    decoder_indices_to_hold_decode_.clear();

    return decoders;
  }

  // On next decoder selection, fail initialization on decoders specified by
  // |decoder_indices|.
  void FailDecoderInitOnSelection(const std::vector<int>& decoder_indices) {
    decoder_indices_to_fail_init_ = decoder_indices;
  }

  // On next decoder selection, hold initialization on decoders specified by
  // |decoder_indices|.
  void HoldDecoderInitOnSelection(const std::vector<int>& decoder_indices) {
    decoder_indices_to_hold_init_ = decoder_indices;
  }

  // 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(const std::vector<int>& decoder_indices) {
    decoder_indices_to_hold_decode_ = decoder_indices;
  }

  // Updates the |decoder_| currently being used by VideoFrameStream.
  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"));

    std::string name = decoder->GetDisplayName();
    ASSERT_TRUE(GetDecoderName(0) == name || GetDecoderName(1) == name ||
                GetDecoderName(2) == name);
    decoder_ = static_cast<FakeVideoDecoder*>(decoder);
  }

  MOCK_METHOD0(OnWaitingForDecryptionKey, void(void));

  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() {
    pending_initialize_ = true;
    video_frame_stream_->Initialize(
        demuxer_stream_.get(), base::Bind(&VideoFrameStreamTest::OnInitialized,
                                          base::Unretained(this)),
        cdm_context_.get(),
        base::Bind(&VideoFrameStreamTest::OnStatistics, base::Unretained(this)),
        base::Bind(&VideoFrameStreamTest::OnWaitingForDecryptionKey,
                   base::Unretained(this)));
    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,
               const scoped_refptr<DecoderBuffer>& encrypted,
               const Decryptor::DecryptCB& decrypt_cb) {
    DCHECK(encrypted->decrypt_config());
    if (has_no_key_) {
      decrypt_cb.Run(Decryptor::kNoKey, NULL);
      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());
    decrypt_cb.Run(Decryptor::kSuccess, decrypted);
  }

  // Callback for VideoFrameStream::Read().
  void FrameReady(VideoFrameStream::Status status,
                  const scoped_refptr<VideoFrame>& frame) {
    DCHECK(pending_read_);
    frame_read_ = frame;
    last_read_status_ = status;
    if (frame.get() &&
        !frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) {
      num_decoded_frames_++;
    }
    pending_read_ = false;
  }

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

  void ReadOneFrame() {
    frame_read_ = NULL;
    pending_read_ = true;
    video_frame_stream_->Read(base::Bind(
        &VideoFrameStreamTest::FrameReady, base::Unretained(this)));
    base::RunLoop().RunUntilIdle();
  }

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

  void ReadAllFrames(int expected_decoded_frames) {
    do {
      ReadOneFrame();
    } while (frame_read_.get() &&
             !frame_read_->metadata()->IsTrue(
                 VideoFrameMetadata::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, OnWaitingForDecryptionKey());
          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_frame_stream_->Reset(base::Bind(&VideoFrameStreamTest::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));
      case DEMUXER_READ_NORMAL:
        demuxer_stream_->SatisfyRead();
        break;

      // This is only interesting to test during VideoFrameStream 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::MessageLoop message_loop_;

  StrictMock<MockMediaLog> media_log_;
  std::unique_ptr<VideoFrameStream> video_frame_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,
  // e.g. RegisterNewKeyCB().
  std::unique_ptr<NiceMock<MockDecryptor>> decryptor_;

  // Raw pointers 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_frame_stream_|.
  std::vector<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_;

  // The current decoder used by |video_frame_stream_|.
  FakeVideoDecoder* decoder_;

  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_;
  VideoFrameStream::Status last_read_status_;

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

 private:
  DISALLOW_COPY_AND_ASSIGN(VideoFrameStreamTest);
};

INSTANTIATE_TEST_CASE_P(
    Clear,
    VideoFrameStreamTest,
    ::testing::Values(VideoFrameStreamTestParams(false, false, 0, 1),
                      VideoFrameStreamTestParams(false, false, 3, 1),
                      VideoFrameStreamTestParams(false, false, 7, 1)));

INSTANTIATE_TEST_CASE_P(
    EncryptedWithDecryptor,
    VideoFrameStreamTest,
    ::testing::Values(VideoFrameStreamTestParams(true, true, 7, 1)));

INSTANTIATE_TEST_CASE_P(
    EncryptedWithoutDecryptor,
    VideoFrameStreamTest,
    ::testing::Values(VideoFrameStreamTestParams(true, false, 7, 1)));

INSTANTIATE_TEST_CASE_P(
    Clear_Parallel,
    VideoFrameStreamTest,
    ::testing::Values(VideoFrameStreamTestParams(false, false, 0, 3),
                      VideoFrameStreamTestParams(false, false, 2, 3)));

TEST_P(VideoFrameStreamTest, CanReadWithoutStallingAtAnyTime) {
  ASSERT_FALSE(video_frame_stream_->CanReadWithoutStalling());
}

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

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

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

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

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

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

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

  int demuxed_buffers = 0;

  // Pass frames from the demuxer to the VideoFrameStream 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(VideoFrameStreamTest, 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 VideoFrameStream 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(VideoFrameStreamTest, 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_, VideoFrameStream::OK);

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

TEST_P(VideoFrameStreamTest, 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_EQ(last_read_status_, VideoFrameStream::DECODE_ERROR);
}

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

TEST_P(VideoFrameStreamTest, Reset_DuringReinitialization) {
  Initialize();
  EnterPendingState(DECODER_REINIT);
  // VideoDecoder::Reset() is not called when we reset during reinitialization.
  pending_reset_ = true;
  video_frame_stream_->Reset(
      base::Bind(&VideoFrameStreamTest::OnReset, base::Unretained(this)));
  SatisfyPendingCallback(DECODER_REINIT);
  Read();
}

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

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

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

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

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

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

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

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

// In the following Destroy_* tests, |video_frame_stream_| is destroyed in
// VideoFrameStreamTest dtor.

TEST_P(VideoFrameStreamTest, Destroy_BeforeInitialization) {
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

TEST_P(VideoFrameStreamTest, 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(VideoFrameStreamTest, FallbackDecoder_DecodeError) {
  Initialize();
  decoder_->SimulateError();
  ReadOneFrame();

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

  ASSERT_FALSE(pending_read_);
  ASSERT_EQ(VideoFrameStream::OK, last_read_status_);

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

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

TEST_P(VideoFrameStreamTest, 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_frame_stream_| should not have emited a frame.
  EXPECT_TRUE(pending_read_);

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

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

  ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());

  // A frame should have been emitted.
  EXPECT_FALSE(pending_read_);
  EXPECT_EQ(last_read_status_, VideoFrameStream::OK);
  EXPECT_FALSE(
      frame_read_->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
  EXPECT_GT(decoder_->total_bytes_decoded(), 0);

  ReadOneFrame();

  EXPECT_FALSE(pending_read_);
  EXPECT_EQ(0, video_frame_stream_->get_fallback_buffers_size_for_testing());
  EXPECT_TRUE(
      frame_read_->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
}

TEST_P(VideoFrameStreamTest, 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_frame_stream_->Read(
      base::Bind(&VideoFrameStreamTest::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(GetDecoderName(1), decoder_->GetDisplayName());

  // 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(VideoFrameStreamTest, FallbackDecoder_DecodeErrorTwice) {
  Initialize();

  // Simulate decode error to trigger the fallback path.
  decoder_->SimulateError();

  // Decoder 0 should be blacklisted and never tried. Hold decode on decoder 1
  // and simulate decode error again.
  HoldDecodeAfterSelection({1});
  ReadOneFrame();
  ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
  decoder_->SimulateError();
  decoder_->SatisfyDecode();
  base::RunLoop().RunUntilIdle();

  // Only one fallback is allowed so we are not falling back to other decoders.
  ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
  EXPECT_FALSE(pending_read_);
  ASSERT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_);
}

// This tests verifies that we properly fallback to a new decoder if the first
// decode after a config change fails.
TEST_P(VideoFrameStreamTest,
       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(VideoFrameStream::OK, last_read_status_);

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

  // Hold decodes to prevent a frame from being outputed 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 outputed.
  decoder_->SimulateError();
  base::RunLoop().RunUntilIdle();

  ReadOneFrame();

  // Verify that fallback happened.
  EXPECT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
  EXPECT_FALSE(pending_read_);
  EXPECT_EQ(VideoFrameStream::OK, last_read_status_);
  EXPECT_GT(decoder_->total_bytes_decoded(), 0);
}

TEST_P(VideoFrameStreamTest,
       FallbackDecoder_DecodeErrorTwice_AfterReinitialization) {
  Initialize();

  // Simulate decode error to trigger the fallback path.
  decoder_->SimulateError();
  ReadOneFrame();
  ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());

  // Simulate reinitialize error of decoder 1.
  decoder_->SimulateFailureToInit();

  // Decoder 0 should be selected again. Simulate immediate decode error after
  // reinitialization.
  HoldDecodeAfterSelection({0});
  ReadUntilDecoderReinitialized();
  ASSERT_EQ(GetDecoderName(0), decoder_->GetDisplayName());
  decoder_->SimulateError();
  decoder_->SatisfyDecode();
  base::RunLoop().RunUntilIdle();

  // VideoDecoderStream has produced video frames, so we are not trying fallback
  // again.
  // TODO(xhwang): Revisit this behavior, e.g. always try to fallback if a newly
  // selected decoder has not produced any video frames before.
  ASSERT_EQ(GetDecoderName(0), decoder_->GetDisplayName());
  EXPECT_FALSE(pending_read_);
  ASSERT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_);
}

TEST_P(VideoFrameStreamTest, 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_frame_stream_->get_pending_buffers_size_for_testing(), 0);

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

  ReadAllFrames();
}

TEST_P(VideoFrameStreamTest, 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_frame_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_frame_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(VideoFrameStreamTest, FallbackDecoder_PendingBuffersIsFilledAndCleared) {
  // Test applies only when there is a decoder delay, and the decoder will not
  // receive a config change before outputing 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_frame_stream_->get_pending_buffers_size_for_testing());
    // No fallback buffers should be queued up yet.
    EXPECT_EQ(0, video_frame_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_frame_stream_->get_pending_buffers_size_for_testing());

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

  ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());

  // Make sure the pending buffers have been transfered 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_frame_stream_->get_fallback_buffers_size_for_testing());
  EXPECT_EQ(demuxer_reads_satisfied,
            video_frame_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_frame_stream_->get_fallback_buffers_size_for_testing());
  EXPECT_EQ(demuxer_reads_satisfied,
            video_frame_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_frame_stream_->get_pending_buffers_size_for_testing(), 0);
  EXPECT_FALSE(pending_read_);

  demuxer_stream_->SatisfyRead();

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

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

  // Decoder 0 should be blacklisted, and decoder 1 fails to initialize, so
  // |video_frame_stream_| should have fallen back to decoder 2.
  ASSERT_EQ(GetDecoderName(2), decoder_->GetDisplayName());

  ASSERT_FALSE(pending_read_);
  ASSERT_EQ(VideoFrameStream::OK, last_read_status_);

  // 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(VideoFrameStreamTest, FallbackDecoder_SelectedOnInitThenDecodeErrors) {
  FailDecoderInitOnSelection({0});
  Initialize();
  ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());

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

  // |video_frame_stream_| should have fallen back to decoder 0.
  ASSERT_EQ(GetDecoderName(0), decoder_->GetDisplayName());

  ASSERT_FALSE(pending_read_);
  ASSERT_EQ(VideoFrameStream::OK, last_read_status_);

  // 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(VideoFrameStreamTest,
       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_ == VideoFrameStream::OK) {
    ReadOneFrame();
    base::RunLoop().RunUntilIdle();
    EXPECT_FALSE(pending_read_);
  }

  // Verify the error was surfaced, rather than falling back to other decoders.
  ASSERT_EQ(GetDecoderName(0), decoder_->GetDisplayName());
  EXPECT_FALSE(pending_read_);
  ASSERT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_);
}

TEST_P(VideoFrameStreamTest, 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_ == VideoFrameStream::OK) {
    ReadOneFrame();
    base::RunLoop().RunUntilIdle();
    EXPECT_FALSE(pending_read_);
  }
  EXPECT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_);
}

TEST_P(VideoFrameStreamTest, ReinitializeFailure_Once) {
  Initialize();
  decoder_->SimulateFailureToInit();
  ReadUntilDecoderReinitialized();
  ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());
  ReadAllFrames();
  ASSERT_GT(decoder_->total_bytes_decoded(), 0);
}

TEST_P(VideoFrameStreamTest, ReinitializeFailure_Twice) {
  Initialize();

  // Trigger reinitialization error, and fallback to decoder 1.
  decoder_->SimulateFailureToInit();
  ReadUntilDecoderReinitialized();
  ASSERT_EQ(GetDecoderName(1), decoder_->GetDisplayName());

  ReadOneFrame();

  // Trigger reinitialization error again, and fallback back to decoder 0.
  decoder_->SimulateFailureToInit();
  ReadUntilDecoderReinitialized();
  ASSERT_EQ(GetDecoderName(0), decoder_->GetDisplayName());
  ReadAllFrames();
}

TEST_P(VideoFrameStreamTest, ReinitializeFailure_OneUnsupportedDecoder) {
  Initialize();

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

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

  ReadUntilDecoderReinitialized();

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

  ReadAllFrames();
}

TEST_P(VideoFrameStreamTest, ReinitializeFailure_NoSupportedDecoder) {
  Initialize();

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

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

  ReadUntilDecoderReinitialized();

  // The error will surface from Read() as DECODE_ERROR.
  while (last_read_status_ == VideoFrameStream::OK) {
    ReadOneFrame();
    base::RunLoop().RunUntilIdle();
    EXPECT_FALSE(pending_read_);
  }
  EXPECT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_);
}

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

}  // namespace media
