// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/starboard/player/filter/video_decoder_internal.h"

#include <algorithm>
#include <deque>
#include <functional>
#include <map>
#include <set>

#include "starboard/common/condition_variable.h"
#include "starboard/common/mutex.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/common/string.h"
#include "starboard/drm.h"
#include "starboard/media.h"
#include "starboard/memory.h"
#include "starboard/shared/starboard/media/media_support_internal.h"
#include "starboard/shared/starboard/media/media_util.h"
#include "starboard/shared/starboard/player/filter/stub_player_components_impl.h"
#include "starboard/shared/starboard/player/job_queue.h"
#include "starboard/shared/starboard/player/video_dmp_reader.h"
#include "starboard/testing/fake_graphics_context_provider.h"
#include "starboard/thread.h"
#include "starboard/time.h"
#include "testing/gtest/include/gtest/gtest.h"

#if SB_HAS(PLAYER_FILTER_TESTS)
// This has to be defined in the global namespace as its instance will be used
// as SbPlayer.
struct SbPlayerPrivate {};

namespace starboard {
namespace shared {
namespace starboard {
namespace player {
namespace filter {
namespace testing {
namespace {

using ::starboard::testing::FakeGraphicsContextProvider;
using ::std::placeholders::_1;
using ::std::placeholders::_2;
using ::testing::AssertionFailure;
using ::testing::AssertionResult;
using ::testing::AssertionSuccess;
using ::testing::Bool;
using ::testing::Combine;
using ::testing::ValuesIn;
using video_dmp::VideoDmpReader;

struct TestParam {
  SbPlayerOutputMode output_mode;
  const char* filename;
};

const SbTimeMonotonic kDefaultWaitForNextEventTimeOut = 5 * kSbTimeSecond;

std::string GetTestInputDirectory() {
  const size_t kPathSize = SB_FILE_MAX_PATH + 1;

  char content_path[kPathSize];
  EXPECT_TRUE(
      SbSystemGetPath(kSbSystemPathContentDirectory, content_path, kPathSize));
  std::string directory_path =
      std::string(content_path) + SB_FILE_SEP_CHAR + "test" + SB_FILE_SEP_CHAR +
      "starboard" + SB_FILE_SEP_CHAR + "shared" + SB_FILE_SEP_CHAR +
      "starboard" + SB_FILE_SEP_CHAR + "player" + SB_FILE_SEP_CHAR + "testdata";

  SB_CHECK(SbDirectoryCanOpen(directory_path.c_str())) << directory_path;
  return directory_path;
}

void DeallocateSampleFunc(SbPlayer player,
                          void* context,
                          const void* sample_buffer) {
  SB_UNREFERENCED_PARAMETER(player);
  SB_UNREFERENCED_PARAMETER(context);
  SB_UNREFERENCED_PARAMETER(sample_buffer);
}

std::string ResolveTestFileName(const char* filename) {
  return GetTestInputDirectory() + SB_FILE_SEP_CHAR + filename;
}

AssertionResult AlmostEqualTime(SbTime time1, SbTime time2) {
  const SbTime kEpsilon = kSbTimeSecond / 1000;
  SbTime diff = time1 - time2;
  if (-kEpsilon <= diff && diff <= kEpsilon) {
    return AssertionSuccess();
  }
  return AssertionFailure()
         << "time " << time1 << " doesn't match with time " << time2;
}

class VideoDecoderTest
    : public ::testing::TestWithParam<std::tuple<TestParam, bool>> {
 public:
  VideoDecoderTest()
      : test_filename_(std::get<0>(GetParam()).filename),
        output_mode_(std::get<0>(GetParam()).output_mode),
        using_stub_decoder_(std::get<1>(GetParam())),
        dmp_reader_(ResolveTestFileName(test_filename_).c_str()) {
    SB_LOG(INFO) << "Testing " << test_filename_ << ", output mode "
                 << output_mode_
                 << (using_stub_decoder_ ? " with stub video decoder." : ".");
  }

  ~VideoDecoderTest() { video_decoder_->Reset(); }

  void SetUp() override {
    ASSERT_NE(dmp_reader_.video_codec(), kSbMediaVideoCodecNone);
    ASSERT_GT(dmp_reader_.number_of_video_buffers(), 0);
    ASSERT_TRUE(GetVideoInputBuffer(0)->video_sample_info().is_key_frame);

    SbPlayerOutputMode output_mode = output_mode_;
    ASSERT_TRUE(VideoDecoder::OutputModeSupported(
        output_mode, dmp_reader_.video_codec(), kSbDrmSystemInvalid));

    PlayerComponents::VideoParameters video_parameters = {
        &player_, dmp_reader_.video_codec(), kSbDrmSystemInvalid, output_mode,
        fake_graphics_context_provider_.decoder_target_provider()};

    scoped_ptr<PlayerComponents> components;
    if (using_stub_decoder_) {
      components = make_scoped_ptr<StubPlayerComponentsImpl>(
          new StubPlayerComponentsImpl);
    } else {
      components = PlayerComponents::Create();
    }
    components->CreateVideoComponents(video_parameters, &video_decoder_,
                                      &video_render_algorithm_,
                                      &video_renderer_sink_);
    ASSERT_TRUE(video_decoder_);

    if (video_renderer_sink_) {
      video_renderer_sink_->SetRenderCB(
          std::bind(&VideoDecoderTest::Render, this, _1));
    }

    video_decoder_->Initialize(
        std::bind(&VideoDecoderTest::OnDecoderStatusUpdate, this, _1, _2),
        std::bind(&VideoDecoderTest::OnError, this));
    if (HasPendingEvents()) {
      bool error_occurred = false;
      ASSERT_NO_FATAL_FAILURE(DrainOutputs(&error_occurred));
      ASSERT_FALSE(error_occurred);
    }
  }

  void Render(VideoRendererSink::DrawFrameCB draw_frame_cb) {
    SB_UNREFERENCED_PARAMETER(draw_frame_cb);
  }

  void OnDecoderStatusUpdate(VideoDecoder::Status status,
                             const scoped_refptr<VideoFrame>& frame) {
    ScopedLock scoped_lock(mutex_);
    // TODO: Ensure that this is only called during dtor or Reset().
    if (status == VideoDecoder::kReleaseAllFrames) {
      SB_DCHECK(!frame);
      event_queue_.clear();
      decoded_frames_.clear();
      return;
    } else if (status == VideoDecoder::kNeedMoreInput) {
      event_queue_.push_back(Event(kNeedMoreInput, frame));
    } else if (status == VideoDecoder::kBufferFull) {
      event_queue_.push_back(Event(kBufferFull, frame));
    } else {
      event_queue_.push_back(Event(kError, frame));
    }
  }

  void OnError() {
    ScopedLock scoped_lock(mutex_);
    event_queue_.push_back(Event(kError, NULL));
  }

#if SB_HAS(GLES2)
  void AssertInvalidDecodeTarget() {
    if (output_mode_ == kSbPlayerOutputModeDecodeToTexture &&
        !using_stub_decoder_) {
      volatile bool is_decode_target_valid = true;
      fake_graphics_context_provider_.RunOnGlesContextThread([&]() {
        SbDecodeTarget decode_target = video_decoder_->GetCurrentDecodeTarget();
        is_decode_target_valid = SbDecodeTargetIsValid(decode_target);
        SbDecodeTargetRelease(decode_target);
      });
      ASSERT_FALSE(is_decode_target_valid);
    }
  }
#endif  // SB_HAS(GLES2)

 protected:
  enum Status {
    kNeedMoreInput = VideoDecoder::kNeedMoreInput,
    kBufferFull = VideoDecoder::kBufferFull,
    kError,
    kTimeout
  };

  struct Event {
    Status status;
    scoped_refptr<VideoFrame> frame;

    Event() : status(kNeedMoreInput) {}
    Event(Status status, scoped_refptr<VideoFrame> frame)
        : status(status), frame(frame) {}
  };

  // This function is called inside WriteMultipleInputs() whenever an event has
  // been processed.
  // |continue_process| will always be a valid pointer and always contains
  // |true| when calling this callback.  The callback can set it to false to
  // stop further processing.
  typedef std::function<void(const Event&, bool* continue_process)> EventCB;

  void WaitForNextEvent(
      Event* event,
      SbTimeMonotonic timeout = kDefaultWaitForNextEventTimeOut) {
    ASSERT_TRUE(event);

    SbTimeMonotonic start = SbTimeGetMonotonicNow();
    while (SbTimeGetMonotonicNow() - start < timeout) {
      job_queue_.RunUntilIdle();
      GetDecodeTargetWhenSupported();
      {
        ScopedLock scoped_lock(mutex_);
        if (!event_queue_.empty()) {
          *event = event_queue_.front();
          event_queue_.pop_front();
          if (event->status == kNeedMoreInput) {
            need_more_input_ = true;
          } else if (event->status == kBufferFull) {
            if (!end_of_stream_written_) {
              ASSERT_FALSE(need_more_input_);
            }
          }
          return;
        }
      }
      SbThreadSleep(kSbTimeMillisecond);
    }
    event->status = kTimeout;
  }

  bool HasPendingEvents() {
    const SbTime kDelay = 5 * kSbTimeMillisecond;
    SbThreadSleep(kDelay);
    ScopedLock scoped_lock(mutex_);
    return !event_queue_.empty();
  }

  void GetDecodeTargetWhenSupported() {
#if SB_HAS(GLES2)
    if (output_mode_ == kSbPlayerOutputModeDecodeToTexture &&
        !using_stub_decoder_) {
      fake_graphics_context_provider_.RunOnGlesContextThread([&]() {
        SbDecodeTargetRelease(video_decoder_->GetCurrentDecodeTarget());
      });
    }
#endif  // SB_HAS(GLES2)
  }

  void AssertValidDecodeTargetWhenSupported() {
#if SB_HAS(GLES2)
    volatile bool is_decode_target_valid = false;
    if (output_mode_ == kSbPlayerOutputModeDecodeToTexture &&
        !using_stub_decoder_) {
      fake_graphics_context_provider_.RunOnGlesContextThread([&]() {
        SbDecodeTarget decode_target = video_decoder_->GetCurrentDecodeTarget();
        is_decode_target_valid = SbDecodeTargetIsValid(decode_target);
        SbDecodeTargetRelease(decode_target);
      });
      ASSERT_TRUE(is_decode_target_valid);
    }
#endif  // SB_HAS(GLES2)
  }

  // This has to be called when the decoder is just initialized/reseted or when
  // status is |kNeedMoreInput|.
  void WriteSingleInput(size_t index) {
    ASSERT_TRUE(need_more_input_);
    ASSERT_LT(index, dmp_reader_.number_of_video_buffers());

    auto input_buffer = GetVideoInputBuffer(index);
    {
      ScopedLock scoped_lock(mutex_);
      need_more_input_ = false;
      outstanding_inputs_.insert(input_buffer->timestamp());
    }

    video_decoder_->WriteInputBuffer(input_buffer);
  }

  void WriteEndOfStream() {
    {
      ScopedLock scoped_lock(mutex_);
      end_of_stream_written_ = true;
    }
    video_decoder_->WriteEndOfStream();
  }

  void WriteMultipleInputs(size_t start_index,
                           size_t number_of_inputs_to_write,
                           EventCB event_cb = EventCB()) {
    ASSERT_LE(start_index + number_of_inputs_to_write,
              dmp_reader_.number_of_video_buffers());

    ASSERT_NO_FATAL_FAILURE(WriteSingleInput(start_index));
    ++start_index;
    --number_of_inputs_to_write;

    while (number_of_inputs_to_write > 0) {
      Event event;
      ASSERT_NO_FATAL_FAILURE(WaitForNextEvent(&event));
      if (event.status == kNeedMoreInput) {
        ASSERT_NO_FATAL_FAILURE(WriteSingleInput(start_index));
        ++start_index;
        --number_of_inputs_to_write;
      } else if (event.status == kError || event.status == kTimeout) {
        // Assume that the caller does't expect an error when |event_cb| isn't
        // provided.
        ASSERT_TRUE(event_cb);
        bool continue_process = true;
        event_cb(event, &continue_process);
        ASSERT_FALSE(continue_process);
        return;
      } else {
        ASSERT_EQ(event.status, kBufferFull);
      }
      if (event.frame) {
        ASSERT_FALSE(event.frame->is_end_of_stream());
        if (!decoded_frames_.empty()) {
          ASSERT_LT(decoded_frames_.back()->timestamp(),
                    event.frame->timestamp());
        }
        decoded_frames_.push_back(event.frame);
        ASSERT_TRUE(AlmostEqualTime(*outstanding_inputs_.begin(),
                                    event.frame->timestamp()));
        outstanding_inputs_.erase(outstanding_inputs_.begin());
      }
      if (event_cb) {
        bool continue_process = true;
        event_cb(event, &continue_process);
        if (!continue_process) {
          return;
        }
      }
    }
  }

  void DrainOutputs(bool* error_occurred = NULL, EventCB event_cb = EventCB()) {
    if (error_occurred) {
      *error_occurred = false;
    }

    bool end_of_stream_decoded = false;

    while (!end_of_stream_decoded) {
      Event event;
      ASSERT_NO_FATAL_FAILURE(WaitForNextEvent(&event));
      if (event.status == kError || event.status == kTimeout) {
        if (error_occurred) {
          *error_occurred = true;
        } else {
          FAIL();
        }
        return;
      }
      if (event.frame) {
        if (event.frame->is_end_of_stream()) {
          end_of_stream_decoded = true;
          if (!outstanding_inputs_.empty()) {
            if (error_occurred) {
              *error_occurred = true;
            } else {
              // |error_occurred| is NULL indicates that the caller doesn't
              // expect an error, use the following redundant ASSERT to trigger
              // a failure.
              ASSERT_TRUE(outstanding_inputs_.empty());
            }
          }
        } else {
          if (!decoded_frames_.empty()) {
            ASSERT_LT(decoded_frames_.back()->timestamp(),
                      event.frame->timestamp());
          }
          decoded_frames_.push_back(event.frame);
          ASSERT_TRUE(AlmostEqualTime(*outstanding_inputs_.begin(),
                                      event.frame->timestamp()));
          outstanding_inputs_.erase(outstanding_inputs_.begin());
        }
      }
      if (event_cb) {
        bool continue_process = true;
        event_cb(event, &continue_process);
        if (!continue_process) {
          return;
        }
      }
    }
  }

  void ResetDecoderAndClearPendingEvents() {
    video_decoder_->Reset();
    ScopedLock scoped_lock(mutex_);
    event_queue_.clear();
    need_more_input_ = true;
    end_of_stream_written_ = false;
    outstanding_inputs_.clear();
    decoded_frames_.clear();
  }

  scoped_refptr<InputBuffer> GetVideoInputBuffer(size_t index) const {
    auto video_sample_info =
        dmp_reader_.GetPlayerSampleInfo(kSbMediaTypeVideo, index);
#if SB_API_VERSION >= 11
    auto input_buffer =
        new InputBuffer(DeallocateSampleFunc, NULL, NULL, video_sample_info);
#else   // SB_API_VERSION >= 11
    auto input_buffer = new InputBuffer(kSbMediaTypeVideo, DeallocateSampleFunc,
                                        NULL, NULL, video_sample_info, NULL);
#endif  // SB_API_VERSION >= 11
    auto iter = invalid_inputs_.find(index);
    if (iter != invalid_inputs_.end()) {
      std::vector<uint8_t> content(input_buffer->size(), iter->second);
      // Replace the content with invalid data.
      input_buffer->SetDecryptedContent(content.data(),
                                        static_cast<int>(content.size()));
    }
    return input_buffer;
  }

  void UseInvalidDataForInput(size_t index, uint8_t byte_to_fill) {
    invalid_inputs_[index] = byte_to_fill;
  }

  JobQueue job_queue_;

  Mutex mutex_;
  std::deque<Event> event_queue_;

  // Test parameter filename for the VideoDmpReader to load and test with.
  const char* test_filename_;

  // Test parameter for OutputMode.
  SbPlayerOutputMode output_mode_;

  // Test parameter for whether or not to use the StubVideoDecoder, or the
  // platform-specific VideoDecoderImpl.
  bool using_stub_decoder_;

  FakeGraphicsContextProvider fake_graphics_context_provider_;
  VideoDmpReader dmp_reader_;
  scoped_ptr<VideoDecoder> video_decoder_;

  bool need_more_input_ = true;
  std::set<SbTime> outstanding_inputs_;
  std::deque<scoped_refptr<VideoFrame>> decoded_frames_;

 private:
  SbPlayerPrivate player_;
  scoped_ptr<VideoRenderAlgorithm> video_render_algorithm_;
  scoped_refptr<VideoRendererSink> video_renderer_sink_;

  bool end_of_stream_written_ = false;

  std::map<size_t, uint8_t> invalid_inputs_;
};

TEST_P(VideoDecoderTest, PrerollFrameCount) {
  EXPECT_GT(video_decoder_->GetPrerollFrameCount(), 0);
}

TEST_P(VideoDecoderTest, MaxNumberOfCachedFrames) {
  EXPECT_GT(video_decoder_->GetMaxNumberOfCachedFrames(), 1);
}

TEST_P(VideoDecoderTest, PrerollTimeout) {
  EXPECT_GE(video_decoder_->GetPrerollTimeout(), 0);
}

// Ensure that OutputModeSupported() is callable on all combinations.
TEST_P(VideoDecoderTest, OutputModeSupported) {
  SbPlayerOutputMode kOutputModes[] = {kSbPlayerOutputModeDecodeToTexture,
                                       kSbPlayerOutputModePunchOut};
  SbMediaVideoCodec kVideoCodecs[] = {
    kSbMediaVideoCodecNone,
    kSbMediaVideoCodecH264,
    kSbMediaVideoCodecH265,
    kSbMediaVideoCodecMpeg2,
    kSbMediaVideoCodecTheora,
    kSbMediaVideoCodecVc1,
#if SB_API_VERSION < 11
    kSbMediaVideoCodecVp10,
#else   // SB_API_VERSION < 11
    kSbMediaVideoCodecAv1,
#endif  // SB_API_VERSION < 11
    kSbMediaVideoCodecVp8,
    kSbMediaVideoCodecVp9
  };
  for (auto output_mode : kOutputModes) {
    for (auto video_codec : kVideoCodecs) {
      VideoDecoder::OutputModeSupported(output_mode, video_codec,
                                        kSbDrmSystemInvalid);
    }
  }
}

#if SB_HAS(GLES2)
TEST_P(VideoDecoderTest, GetCurrentDecodeTargetBeforeWriteInputBuffer) {
  if (output_mode_ == kSbPlayerOutputModeDecodeToTexture) {
    AssertInvalidDecodeTarget();
  }
}
#endif  // SB_HAS(GLES2)

TEST_P(VideoDecoderTest, ThreeMoreDecoders) {
  // Create three more decoders for each supported combinations.
  const int kDecodersToCreate = 3;

  scoped_ptr<PlayerComponents> components = PlayerComponents::Create();

  SbPlayerOutputMode kOutputModes[] = {kSbPlayerOutputModeDecodeToTexture,
                                       kSbPlayerOutputModePunchOut};
  SbMediaVideoCodec kVideoCodecs[] = {
    kSbMediaVideoCodecNone,
    kSbMediaVideoCodecH264,
    kSbMediaVideoCodecH265,
    kSbMediaVideoCodecMpeg2,
    kSbMediaVideoCodecTheora,
    kSbMediaVideoCodecVc1,
#if SB_API_VERSION < 11
    kSbMediaVideoCodecVp10,
#else   // SB_API_VERSION < 11
    kSbMediaVideoCodecAv1,
#endif  // SB_API_VERSION < 11
    kSbMediaVideoCodecVp8,
    kSbMediaVideoCodecVp9
  };

  for (auto output_mode : kOutputModes) {
    for (auto video_codec : kVideoCodecs) {
      if (VideoDecoder::OutputModeSupported(output_mode, video_codec,
                                            kSbDrmSystemInvalid)) {
        SbPlayerPrivate players[kDecodersToCreate];
        scoped_ptr<VideoDecoder> video_decoders[kDecodersToCreate];
        scoped_ptr<VideoRenderAlgorithm>
            video_render_algorithms[kDecodersToCreate];
        scoped_refptr<VideoRendererSink>
            video_renderer_sinks[kDecodersToCreate];

        for (int i = 0; i < kDecodersToCreate; ++i) {
          PlayerComponents::VideoParameters video_parameters = {
              &players[i], dmp_reader_.video_codec(), kSbDrmSystemInvalid,
              output_mode,
              fake_graphics_context_provider_.decoder_target_provider()};

          components->CreateVideoComponents(
              video_parameters, &video_decoders[i], &video_render_algorithms[i],
              &video_renderer_sinks[i]);
          ASSERT_TRUE(video_decoders[i]);

          if (video_renderer_sinks[i]) {
            video_renderer_sinks[i]->SetRenderCB(
                std::bind(&VideoDecoderTest::Render, this, _1));
          }

          video_decoders[i]->Initialize(
              std::bind(&VideoDecoderTest::OnDecoderStatusUpdate, this, _1, _2),
              std::bind(&VideoDecoderTest::OnError, this));

#if SB_HAS(GLES2)
          if (output_mode == kSbPlayerOutputModeDecodeToTexture) {
            AssertInvalidDecodeTarget();
          }
#endif  // SB_HAS(GLES2)
        }
        if (HasPendingEvents()) {
          bool error_occurred = false;
          ASSERT_NO_FATAL_FAILURE(DrainOutputs(&error_occurred));
          ASSERT_FALSE(error_occurred);
        }
      }
    }
  }
}

TEST_P(VideoDecoderTest, SingleInput) {
  WriteSingleInput(0);
  WriteEndOfStream();

  bool error_occurred = false;
  ASSERT_NO_FATAL_FAILURE(DrainOutputs(
      &error_occurred, [=](const Event& event, bool* continue_process) {
        if (event.frame) {
          // TODO: On some platforms, decode texture will be ready only after
          // rendered by renderer, so decode target is not always available
          // at this point. We should provide a mock renderer and then check
          // the decode target here with AssertValidDecodeTargetWhenSupported().
        }
        *continue_process = true;
      }));
  ASSERT_FALSE(error_occurred);
}

TEST_P(VideoDecoderTest, SingleInvalidKeyFrame) {
  UseInvalidDataForInput(0, 0xab);

  WriteSingleInput(0);
  WriteEndOfStream();

  bool error_occurred = true;
  ASSERT_NO_FATAL_FAILURE(DrainOutputs(&error_occurred));
  // We don't expect the video decoder can always recover from a bad key frame
  // and to raise an error, but it shouldn't crash or hang.
  GetDecodeTargetWhenSupported();
}

TEST_P(VideoDecoderTest, MultipleValidInputsAfterInvalidKeyFrame) {
  const size_t kMaxNumberOfInputToWrite = 10;
  const size_t number_of_input_to_write =
      std::min(kMaxNumberOfInputToWrite, dmp_reader_.number_of_video_buffers());

  UseInvalidDataForInput(0, 0xab);

  bool error_occurred = false;
  bool timeout_occurred = false;
  // Write first few frames.  The first one is invalid and the rest are valid.
  WriteMultipleInputs(0, number_of_input_to_write,
                      [&](const Event& event, bool* continue_process) {
                        if (event.status == kTimeout) {
                          timeout_occurred = true;
                          *continue_process = false;
                          return;
                        }
                        if (event.status == kError) {
                          error_occurred = true;
                          *continue_process = false;
                          return;
                        }
                        *continue_process = event.status != kBufferFull;
                      });
  ASSERT_FALSE(timeout_occurred);
  if (!error_occurred) {
    GetDecodeTargetWhenSupported();
    WriteEndOfStream();
    ASSERT_NO_FATAL_FAILURE(DrainOutputs(&error_occurred));
  }
  // We don't expect the video decoder can always recover from a bad key frame
  // and to raise an error, but it shouldn't crash or hang.
  GetDecodeTargetWhenSupported();
}

TEST_P(VideoDecoderTest, MultipleInvalidInput) {
  const size_t kMaxNumberOfInputToWrite = 128;
  const size_t number_of_input_to_write =
      std::min(kMaxNumberOfInputToWrite, dmp_reader_.number_of_video_buffers());
  // Replace the content of the first few input buffers with invalid data.
  // Every test instance loads its own copy of data so this won't affect other
  // tests.
  for (size_t i = 0; i < number_of_input_to_write; ++i) {
    UseInvalidDataForInput(i, static_cast<uint8_t>(0xab + i));
  }

  bool error_occurred = false;
  bool timeout_occurred = false;
  WriteMultipleInputs(0, number_of_input_to_write,
                      [&](const Event& event, bool* continue_process) {
                        if (event.status == kTimeout) {
                          timeout_occurred = true;
                          *continue_process = false;
                          return;
                        }
                        if (event.status == kError) {
                          error_occurred = true;
                          *continue_process = false;
                          return;
                        }

                        *continue_process = event.status != kBufferFull;
                      });
  ASSERT_FALSE(timeout_occurred);
  if (!error_occurred) {
    GetDecodeTargetWhenSupported();
    WriteEndOfStream();
    ASSERT_NO_FATAL_FAILURE(DrainOutputs(&error_occurred));
  }
  // We don't expect the video decoder can always recover from a bad key frame
  // and to raise an error, but it shouldn't crash or hang.
  GetDecodeTargetWhenSupported();
}

TEST_P(VideoDecoderTest, EndOfStreamWithoutAnyInput) {
  WriteEndOfStream();
  ASSERT_NO_FATAL_FAILURE(DrainOutputs());
}

TEST_P(VideoDecoderTest, ResetBeforeInput) {
  EXPECT_FALSE(HasPendingEvents());
  ResetDecoderAndClearPendingEvents();
  EXPECT_FALSE(HasPendingEvents());

  WriteSingleInput(0);
  WriteEndOfStream();
  ASSERT_NO_FATAL_FAILURE(DrainOutputs());
}

TEST_P(VideoDecoderTest, ResetAfterInput) {
  const size_t kMaxInputToWrite = 10;
  bool error_occurred = false;
  WriteMultipleInputs(
      0, kMaxInputToWrite, [&](const Event& event, bool* continue_process) {
        if (event.status == kTimeout || event.status == kError) {
          error_occurred = true;
          *continue_process = false;
          return;
        }
        *continue_process = event.status != kBufferFull;
      });
  ASSERT_FALSE(error_occurred);
  ResetDecoderAndClearPendingEvents();
  EXPECT_FALSE(HasPendingEvents());
}

TEST_P(VideoDecoderTest, MultipleResets) {
  for (int max_inputs = 1; max_inputs < 10; ++max_inputs) {
    bool error_occurred = false;
    WriteMultipleInputs(
        0, max_inputs, [&](const Event& event, bool* continue_process) {
          if (event.status == kTimeout || event.status == kError) {
            error_occurred = true;
            *continue_process = false;
            return;
          }
          *continue_process = event.status != kBufferFull;
        });
    ASSERT_FALSE(error_occurred);
    ResetDecoderAndClearPendingEvents();
    EXPECT_FALSE(HasPendingEvents());
    WriteSingleInput(0);
    WriteEndOfStream();
    ASSERT_NO_FATAL_FAILURE(DrainOutputs());
    ResetDecoderAndClearPendingEvents();
    EXPECT_FALSE(HasPendingEvents());
  }
}

TEST_P(VideoDecoderTest, MultipleInputs) {
  const size_t kMaxNumberOfExpectedDecodedFrames = 5;
  const size_t number_of_expected_decoded_frames = std::min(
      kMaxNumberOfExpectedDecodedFrames, dmp_reader_.number_of_video_buffers());
  size_t frames_decoded = 0;
  bool error_occurred = false;
  ASSERT_NO_FATAL_FAILURE(WriteMultipleInputs(
      0, dmp_reader_.number_of_video_buffers(),
      [&](const Event& event, bool* continue_process) {
        if (event.status == kTimeout || event.status == kError) {
          error_occurred = true;
          *continue_process = false;
          return;
        }
        frames_decoded += decoded_frames_.size();
        decoded_frames_.clear();
        *continue_process = frames_decoded < number_of_expected_decoded_frames;
      }));
  ASSERT_FALSE(error_occurred);
  if (frames_decoded < number_of_expected_decoded_frames) {
    WriteEndOfStream();
    ASSERT_NO_FATAL_FAILURE(DrainOutputs());
  }
}

TEST_P(VideoDecoderTest, Preroll) {
  SbTimeMonotonic start = SbTimeGetMonotonicNow();
  SbTime preroll_timeout = video_decoder_->GetPrerollTimeout();
  bool error_occurred = false;
  ASSERT_NO_FATAL_FAILURE(WriteMultipleInputs(
      0, dmp_reader_.number_of_video_buffers(),
      [&](const Event& event, bool* continue_process) {
        if (event.status == kError) {
          error_occurred = true;
          *continue_process = false;
          return;
        }
        if (decoded_frames_.size() >= video_decoder_->GetPrerollFrameCount()) {
          *continue_process = false;
          return;
        }
        if (SbTimeGetMonotonicNow() - start >= preroll_timeout) {
          // After preroll timeout, we should get at least 1 decoded frame.
          ASSERT_GT(decoded_frames_.size(), 0);
          *continue_process = false;
          return;
        }
        *continue_process = true;
        return;
      }));
  ASSERT_FALSE(error_occurred);
}

TEST_P(VideoDecoderTest, HoldFramesUntilFull) {
  bool error_occurred = false;
  ASSERT_NO_FATAL_FAILURE(WriteMultipleInputs(
      0, dmp_reader_.number_of_video_buffers(),
      [&](const Event& event, bool* continue_process) {
        if (event.status == kTimeout || event.status == kError) {
          error_occurred = true;
          *continue_process = false;
          return;
        }
        *continue_process = decoded_frames_.size() <
                            video_decoder_->GetMaxNumberOfCachedFrames();
      }));
  ASSERT_FALSE(error_occurred);
  WriteEndOfStream();
  if (decoded_frames_.size() >= video_decoder_->GetMaxNumberOfCachedFrames()) {
    return;
  }
  ASSERT_NO_FATAL_FAILURE(DrainOutputs(
      &error_occurred, [=](const Event& event, bool* continue_process) {
        *continue_process = decoded_frames_.size() <
                            video_decoder_->GetMaxNumberOfCachedFrames();
      }));
  ASSERT_FALSE(error_occurred);
}

TEST_P(VideoDecoderTest, DecodeFullGOP) {
  int gop_size = 1;
  while (gop_size < dmp_reader_.number_of_video_buffers()) {
    if (GetVideoInputBuffer(gop_size)->video_sample_info().is_key_frame) {
      break;
    }
    ++gop_size;
  }
  bool error_occurred = false;
  ASSERT_NO_FATAL_FAILURE(WriteMultipleInputs(
      0, gop_size, [&](const Event& event, bool* continue_process) {
        if (event.status == kTimeout || event.status == kError) {
          error_occurred = true;
          *continue_process = false;
          return;
        }
        // Keep 1 decoded frame, assuming it's used by renderer.
        while (decoded_frames_.size() > 1) {
          decoded_frames_.pop_front();
        }
        *continue_process = true;
      }));
  ASSERT_FALSE(error_occurred);
  WriteEndOfStream();

  ASSERT_NO_FATAL_FAILURE(DrainOutputs(
      &error_occurred, [=](const Event& event, bool* continue_process) {
        // Keep 1 decoded frame, assuming it's used by renderer.
        while (decoded_frames_.size() > 1) {
          decoded_frames_.pop_front();
        }
        *continue_process = true;
      }));
  ASSERT_FALSE(error_occurred);
}

std::vector<TestParam> GetSupportedTests() {
  SbPlayerOutputMode kOutputModes[] = {kSbPlayerOutputModeDecodeToTexture,
                                       kSbPlayerOutputModePunchOut};

  const char* kFilenames[] = {"beneath_the_canopy_137_avc.dmp",
                              "beneath_the_canopy_248_vp9.dmp"};

  static std::vector<TestParam> test_params;

  if (!test_params.empty()) {
    return test_params;
  }

  for (auto filename : kFilenames) {
    VideoDmpReader dmp_reader(ResolveTestFileName(filename).c_str());
    SB_DCHECK(dmp_reader.number_of_video_buffers() > 0);

    for (auto output_mode : kOutputModes) {
      if (!VideoDecoder::OutputModeSupported(
              output_mode, dmp_reader.video_codec(), kSbDrmSystemInvalid)) {
        continue;
      }

      const auto& video_sample_info =
          dmp_reader.GetPlayerSampleInfo(kSbMediaTypeVideo, 0)
              .video_sample_info;

      if (SbMediaIsVideoSupported(
              dmp_reader.video_codec(),
#if SB_HAS(MEDIA_IS_VIDEO_SUPPORTED_REFINEMENT)
              -1, -1, 8, kSbMediaPrimaryIdUnspecified,
              kSbMediaTransferIdUnspecified, kSbMediaMatrixIdUnspecified,
#endif  // SB_HAS(MEDIA_IS_VIDEO_SUPPORTED_REFINEMENT)
#if SB_API_VERSION >= 11
              video_sample_info.frame_width, video_sample_info.frame_height,
#else   // SB_API_VERSION >= 11
              video_sample_info->frame_width, video_sample_info->frame_height,
#endif  // SB_API_VERSION >= 11
              dmp_reader.video_bitrate(), dmp_reader.video_fps()
#if SB_API_VERSION >= 10
                                              ,
              false
#endif  // SB_API_VERSION >= 10
              )) {
        test_params.push_back({output_mode, filename});
      }
    }
  }

  SB_DCHECK(!test_params.empty());
  return test_params;
}

INSTANTIATE_TEST_CASE_P(VideoDecoderTests,
                        VideoDecoderTest,
                        Combine(ValuesIn(GetSupportedTests()), Bool()));

}  // namespace
}  // namespace testing
}  // namespace filter
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
#endif  // SB_HAS(PLAYER_FILTER_TESTS)
