// Copyright 2020 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/player_components.h"

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "starboard/common/scoped_ptr.h"
#include "starboard/media.h"
#include "starboard/player.h"
#include "starboard/shared/starboard/player/filter/testing/test_util.h"
#include "starboard/shared/starboard/player/filter/video_decoder_internal.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 "testing/gtest/include/gtest/gtest.h"

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

using ::starboard::testing::FakeGraphicsContextProvider;
using std::string;
using std::unique_ptr;
using std::vector;
using ::testing::ValuesIn;
using video_dmp::VideoDmpReader;

typedef VideoDmpReader::AudioAccessUnit AudioAccessUnit;
typedef VideoDmpReader::VideoAccessUnit VideoAccessUnit;
typedef PlayerComponents::Factory::CreationParameters CreationParameters;
typedef std::tuple<const char*, const char*, SbPlayerOutputMode>
    PlayerComponentsTestParam;

const SbTimeMonotonic kDefaultPrerollTimeOut = 5 * kSbTimeSecond;
const SbTimeMonotonic kDefaultEndTimeOut = 5 * kSbTimeSecond;
const SbTimeMonotonic kDefaultWriteTimeOut = 5 * kSbTimeSecond;

const SbPlayer kDummyPlayer = reinterpret_cast<SbPlayer>(1);

class PlayerComponentsTest
    : public ::testing::TestWithParam<PlayerComponentsTestParam> {
 protected:
  PlayerComponentsTest()
      : audio_filename_(std::get<0>(GetParam())),
        video_filename_(std::get<1>(GetParam())),
        output_mode_(std::get<2>(GetParam())) {
    SB_LOG(INFO) << "Testing: \"" << audio_filename_ << "\", \""
                 << video_filename_
                 << (output_mode_ == kSbPlayerOutputModeDecodeToTexture
                         ? "\", kSbPlayerOutputModeDecodeToTexture."
                         : "\", kSbPlayerOutputModePunchOut.");
  }

  void SetUp() override {
    if (audio_filename_.length() > 0) {
      audio_reader_.reset(new VideoDmpReader(
          ResolveTestFileName(audio_filename_.c_str()).c_str(),
          VideoDmpReader::kEnableReadOnDemand));
    }
    if (video_filename_.length() > 0) {
      video_reader_.reset(new VideoDmpReader(
          ResolveTestFileName(video_filename_.c_str()).c_str(),
          VideoDmpReader::kEnableReadOnDemand));
    }

    scoped_ptr<PlayerComponents::Factory> factory =
        PlayerComponents::Factory::Create();
    string error_message;
    if (audio_reader_ && video_reader_) {
      CreationParameters creation_parameters(
          audio_reader_->audio_codec(), audio_reader_->audio_sample_info(),
          video_reader_->video_codec(),
#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
          video_reader_->GetPlayerSampleInfo(kSbMediaTypeVideo, 0)
              .video_sample_info,
#endif  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
          kDummyPlayer, output_mode_,
          fake_graphics_context_provider_.decoder_target_provider());
      player_components_ =
          factory->CreateComponents(creation_parameters, &error_message);
    } else if (audio_reader_) {
      // Audio only
      CreationParameters creation_parameters(
          audio_reader_->audio_codec(), audio_reader_->audio_sample_info());
      player_components_ =
          factory->CreateComponents(creation_parameters, &error_message);
    } else {
      // Video only
      ASSERT_TRUE(video_reader_);
      CreationParameters creation_parameters(
          video_reader_->video_codec(),
#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
          video_reader_->GetPlayerSampleInfo(kSbMediaTypeVideo, 0)
              .video_sample_info,
#endif  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
          kDummyPlayer, output_mode_,
          fake_graphics_context_provider_.decoder_target_provider());
      player_components_ =
          factory->CreateComponents(creation_parameters, &error_message);
    }
    ASSERT_TRUE(player_components_);

    if (GetAudioRenderer()) {
      GetAudioRenderer()->Initialize(
          std::bind(&PlayerComponentsTest::OnError, this),
          std::bind(&PlayerComponentsTest::OnPrerolled, this,
                    kSbMediaTypeAudio),
          std::bind(&PlayerComponentsTest::OnEnded, this, kSbMediaTypeAudio));
    }
    SetPlaybackRate(playback_rate_);
    if (GetVideoRenderer()) {
      GetVideoRenderer()->Initialize(
          std::bind(&PlayerComponentsTest::OnError, this),
          std::bind(&PlayerComponentsTest::OnPrerolled, this,
                    kSbMediaTypeVideo),
          std::bind(&PlayerComponentsTest::OnEnded, this, kSbMediaTypeVideo));
    }
  }

  MediaTimeProvider* GetMediaTimeProvider() const {
    return player_components_->GetMediaTimeProvider();
  }
  AudioRenderer* GetAudioRenderer() const {
    return player_components_->GetAudioRenderer();
  }
  VideoRenderer* GetVideoRenderer() const {
    return player_components_->GetVideoRenderer();
  }

  bool IsPlaybackPrerolled() {
    if (GetAudioRenderer() && !audio_prerolled_) {
      return false;
    }
    if (GetVideoRenderer() && !video_prerolled_) {
      return false;
    }
    return true;
  }

  bool IsPlaybackEnded() {
    if (GetAudioRenderer() && !audio_ended_) {
      return false;
    }
    if (GetVideoRenderer() && !video_ended_) {
      return false;
    }
    return true;
  }

  void Seek(SbTime seek_to_time) {
    has_error_ = false;
    audio_prerolled_ = false;
    video_prerolled_ = false;
    audio_ended_ = false;
    video_ended_ = false;
    audio_index_ = 0;
    video_index_ = 0;
    // Find the closest key frame prior to |seek_to_time|.
    if (GetAudioRenderer()) {
      for (int index = 1; index < audio_reader_->number_of_audio_buffers();
           index++) {
        SbPlayerSampleInfo sample_info =
            audio_reader_->GetPlayerSampleInfo(kSbMediaTypeAudio, index);
        if (sample_info.timestamp > seek_to_time) {
          break;
        }
        audio_index_ = index;
      }
    }
    if (GetVideoRenderer()) {
      for (int index = 1; index < video_reader_->number_of_video_buffers();
           index++) {
        SbPlayerSampleInfo sample_info =
            video_reader_->GetPlayerSampleInfo(kSbMediaTypeVideo, index);
        if (sample_info.timestamp > seek_to_time) {
          break;
        }
        if (sample_info.video_sample_info.is_key_frame) {
          video_index_ = index;
        }
      }
    }
    GetMediaTimeProvider()->Pause();
    if (GetVideoRenderer()) {
      GetVideoRenderer()->Seek(seek_to_time);
    }
    GetMediaTimeProvider()->Seek(seek_to_time);
  }

  void Play() { GetMediaTimeProvider()->Play(); }

  void Pause() { GetMediaTimeProvider()->Pause(); }

  void SetPlaybackRate(double playback_rate) {
    playback_rate_ = playback_rate;
    GetMediaTimeProvider()->SetPlaybackRate(playback_rate_);
  }

  SbTime GetMediaTime() {
    bool is_playing, is_eos_played, is_underflow;
    double playback_rate;
    return GetMediaTimeProvider()->GetCurrentMediaTime(
        &is_playing, &is_eos_played, &is_underflow, &playback_rate);
  }

  bool IsPlaying() {
    bool is_playing, is_eos_played, is_underflow;
    double playback_rate;
    GetMediaTimeProvider()->GetCurrentMediaTime(&is_playing, &is_eos_played,
                                                &is_underflow, &playback_rate);
    return is_playing;
  }

  SbTime GetCurrentAudioBufferTimestamp() const {
    if (!GetAudioRenderer()) {
      return 0;
    }
    if (audio_index_ >= audio_reader_->number_of_audio_buffers()) {
      return audio_reader_->audio_duration();
    }
    return audio_reader_->GetPlayerSampleInfo(kSbMediaTypeAudio, audio_index_)
        .timestamp;
  }

  SbTime GetCurrentVideoBufferTimestamp() const {
    if (!GetVideoRenderer()) {
      return 0;
    }
    if (video_index_ >= video_reader_->number_of_video_buffers()) {
      return video_reader_->video_duration();
    }
    if (video_index_ >= video_reader_->number_of_video_buffers() - 1) {
      return video_reader_->GetPlayerSampleInfo(kSbMediaTypeVideo, video_index_)
          .timestamp;
    }
    // The buffers are ordered by decoding order. We need to find the
    // presentation timestamp of next frame.
    SbTime next_timestamps[2] = {
        video_reader_->GetPlayerSampleInfo(kSbMediaTypeVideo, video_index_)
            .timestamp,
        video_reader_->GetPlayerSampleInfo(kSbMediaTypeVideo, video_index_ + 1)
            .timestamp};
    return std::min(next_timestamps[0], next_timestamps[1]);
  }

  void WriteDataUntilPrerolled(SbTime timeout = kDefaultPrerollTimeOut) {
    SbTimeMonotonic start_time = SbTimeGetMonotonicNow();
    while (!IsPlaybackPrerolled()) {
      ASSERT_LE(SbTimeGetMonotonicNow() - start_time, timeout);
      bool written =
          TryToWriteOneInputBuffer(GetMediaTime() + kMaxWriteAheadDuration);
      if (!written) {
        ASSERT_NO_FATAL_FAILURE(RenderAndProcessPendingJobs());
        SbThreadSleep(5 * kSbTimeMillisecond);
      }
    }
  }

  void WriteDataUntil(SbTime timestamp, SbTime timeout = kDefaultWriteTimeOut) {
    SB_CHECK(playback_rate_ != 0);

    SbTimeMonotonic last_input_filled_time = SbTimeGetMonotonicNow();
    while (
        (GetAudioRenderer() && GetCurrentAudioBufferTimestamp() < timestamp) ||
        (GetVideoRenderer() && GetCurrentVideoBufferTimestamp() < timestamp)) {
      if (last_input_filled_time != -1) {
        ASSERT_LE(SbTimeGetMonotonicNow() - last_input_filled_time, timeout);
      }
      bool written = TryToWriteOneInputBuffer(timestamp);
      if (written) {
        last_input_filled_time = SbTimeGetMonotonicNow();
      } else {
        ASSERT_NO_FATAL_FAILURE(RenderAndProcessPendingJobs());
        SbThreadSleep(5 * kSbTimeMillisecond);
      }
    }
  }

  void WriteEOS() {
    if (GetAudioRenderer()) {
      GetAudioRenderer()->WriteEndOfStream();
    }
    if (GetVideoRenderer()) {
      GetVideoRenderer()->WriteEndOfStream();
    }
  }

  void WaitUntilPlaybackEnded() {
    SB_CHECK(playback_rate_ != 0);

    SbTime duration = std::max(GetCurrentAudioBufferTimestamp(),
                               GetCurrentVideoBufferTimestamp());
    SbTime current_time = GetMediaTime();
    SbTime expected_end_time =
        SbTimeGetMonotonicNow() +
        static_cast<SbTime>((duration - current_time) / playback_rate_) +
        kDefaultEndTimeOut;
    while (!IsPlaybackEnded()) {
      // If this fails, timeout must have been reached.
      ASSERT_LE(SbTimeGetMonotonicNow(), expected_end_time);
      ASSERT_NO_FATAL_FAILURE(RenderAndProcessPendingJobs());
      SbThreadSleep(5 * kSbTimeMillisecond);
    }
    current_time = GetMediaTime();
    // TODO: investigate and reduce the tolerance.
    ASSERT_LE(std::abs(current_time - duration), 500 * kSbTimeMillisecond);
  }

  // This function needs to be called periodically to keep player components
  // working.
  void RenderAndProcessPendingJobs() {
    // Call GetCurrentDecodeTarget() periodically for decode to texture mode.
    if (output_mode_ == kSbPlayerOutputModeDecodeToTexture &&
        GetVideoRenderer()) {
#if SB_HAS(GLES2)
      fake_graphics_context_provider_.RunOnGlesContextThread(
          std::bind(&PlayerComponentsTest::RenderOnGlesContextThread, this));
#endif  // SB_HAS(GLES2)
    }
    // Process jobs in the job queue.
    job_queue_.RunUntilIdle();
    ASSERT_FALSE(has_error_);
  }

 private:
  // We won't write audio data more than 1s ahead of current media time in
  // cobalt. So, to test with the same condition, we limit max inputs ahead to
  // 1s in the tests.
  const SbTime kMaxWriteAheadDuration = kSbTimeSecond;

  void OnError() { has_error_ = true; }
  void OnPrerolled(SbMediaType media_type) {
    if (media_type == kSbMediaTypeAudio) {
      audio_prerolled_ = true;
    } else {
      EXPECT_EQ(media_type, kSbMediaTypeVideo);
      video_prerolled_ = true;
    }
  }
  void OnEnded(SbMediaType media_type) {
    if (media_type == kSbMediaTypeAudio) {
      audio_ended_ = true;
    } else {
      EXPECT_EQ(media_type, kSbMediaTypeVideo);
      video_ended_ = true;
    }
  }

  scoped_refptr<InputBuffer> GetAudioInputBuffer(size_t index) const {
    auto player_sample_info =
        audio_reader_->GetPlayerSampleInfo(kSbMediaTypeAudio, index);
#if SB_API_VERSION >= 11
    auto input_buffer = new InputBuffer(StubDeallocateSampleFunc, nullptr,
                                        nullptr, player_sample_info);
#else   // SB_API_VERSION >= 11
    SbMediaAudioSampleInfo audio_sample_info =
        audio_reader_->GetAudioSampleInfo(index);
    auto input_buffer =
        new InputBuffer(kSbMediaTypeAudio, StubDeallocateSampleFunc, nullptr,
                        nullptr, player_sample_info, &audio_sample_info);
#endif  // SB_API_VERSION >= 11
    return input_buffer;
  }

  scoped_refptr<InputBuffer> GetVideoInputBuffer(size_t index) const {
    auto video_sample_info =
        video_reader_->GetPlayerSampleInfo(kSbMediaTypeVideo, index);
#if SB_API_VERSION >= 11
    auto input_buffer = new InputBuffer(StubDeallocateSampleFunc, NULL, NULL,
                                        video_sample_info);
#else   // SB_API_VERSION >= 11
    auto input_buffer =
        new InputBuffer(kSbMediaTypeVideo, StubDeallocateSampleFunc, NULL, NULL,
                        video_sample_info, NULL);
#endif  // SB_API_VERSION >= 11
    return input_buffer;
  }

  void RenderOnGlesContextThread() {
    SbDecodeTargetRelease(GetVideoRenderer()->GetCurrentDecodeTarget());
  }

  bool TryToWriteOneInputBuffer(SbTime max_timestamp) {
    bool input_buffer_written = false;
    if (GetAudioRenderer() && GetAudioRenderer()->CanAcceptMoreData() &&
        audio_index_ < audio_reader_->number_of_audio_buffers() &&
        GetCurrentAudioBufferTimestamp() < max_timestamp) {
      GetAudioRenderer()->WriteSample(GetAudioInputBuffer(audio_index_++));
      input_buffer_written = true;
    }
    if (GetVideoRenderer() && GetVideoRenderer()->CanAcceptMoreData() &&
        video_index_ < video_reader_->number_of_video_buffers() &&
        GetCurrentVideoBufferTimestamp() < max_timestamp) {
      GetVideoRenderer()->WriteSample(GetVideoInputBuffer(video_index_++));
      input_buffer_written = true;
    }
    if (input_buffer_written) {
      job_queue_.RunUntilIdle();
    }
    return input_buffer_written;
  }

  const std::string audio_filename_;
  const std::string video_filename_;
  const SbPlayerOutputMode output_mode_;
  JobQueue job_queue_;
  FakeGraphicsContextProvider fake_graphics_context_provider_;
  unique_ptr<VideoDmpReader> audio_reader_;
  unique_ptr<VideoDmpReader> video_reader_;
  scoped_ptr<PlayerComponents> player_components_;
  double playback_rate_ = 1.0;
  int audio_index_ = 0;
  int video_index_ = 0;
  bool has_error_ = false;
  bool audio_prerolled_ = false;
  bool video_prerolled_ = false;
  bool audio_ended_ = false;
  bool video_ended_ = false;
};

TEST_P(PlayerComponentsTest, Preroll) {
  Seek(0);
  ASSERT_NO_FATAL_FAILURE(WriteDataUntilPrerolled());
}

TEST_P(PlayerComponentsTest, SunnyDay) {
  Seek(0);
  ASSERT_NO_FATAL_FAILURE(WriteDataUntilPrerolled());
  ASSERT_EQ(GetMediaTime(), 0);
  ASSERT_FALSE(IsPlaying());

  SbTimeMonotonic play_requested_at = SbTimeGetMonotonicNow();
  Play();
  SbTime media_duration = std::max(GetCurrentVideoBufferTimestamp(),
                                   GetCurrentAudioBufferTimestamp());
  media_duration = std::max(kSbTimeSecond, media_duration);

  ASSERT_NO_FATAL_FAILURE(WriteDataUntil(media_duration));
  ASSERT_NO_FATAL_FAILURE(WriteEOS());
  ASSERT_NO_FATAL_FAILURE(WaitUntilPlaybackEnded());

  // TODO: investigate and reduce the tolerance.
  // ASSERT_LE(
  //     std::abs(SbTimeGetMonotonicNow() - (play_requested_at +
  //     media_duration)), 300 * kSbTimeMillisecond);
}

TEST_P(PlayerComponentsTest, ShortPlayback) {
  Seek(0);
  ASSERT_NO_FATAL_FAILURE(WriteDataUntil(50 * kSbTimeMillisecond));
  ASSERT_NO_FATAL_FAILURE(WriteEOS());
  Play();
  ASSERT_NO_FATAL_FAILURE(WaitUntilPlaybackEnded());
}

TEST_P(PlayerComponentsTest, EOSWithoutInput) {
  Seek(0);
  ASSERT_NO_FATAL_FAILURE(WriteEOS());
  Play();
  ASSERT_NO_FATAL_FAILURE(WaitUntilPlaybackEnded());
  // TODO: investigate and reduce the tolerance.
  // ASSERT_LE(std::abs(GetMediaTime()), 100 * kSbTimeMillisecond);
}

TEST_P(PlayerComponentsTest, Pause) {
  Seek(0);
  ASSERT_NO_FATAL_FAILURE(WriteDataUntilPrerolled());
  Play();
  ASSERT_NO_FATAL_FAILURE(WriteDataUntil(kSbTimeSecond));
  Pause();
  ASSERT_FALSE(IsPlaying());

  SbTimeMonotonic start_time = SbTimeGetMonotonicNow();
  while (SbTimeGetMonotonicNow() < start_time + 200 * kSbTimeMillisecond) {
    ASSERT_NO_FATAL_FAILURE(RenderAndProcessPendingJobs());
    SbThreadSleep(5 * kSbTimeMillisecond);
  }
  SbTime media_time = GetMediaTime();
  start_time = SbTimeGetMonotonicNow();
  while (SbTimeGetMonotonicNow() < start_time + 200 * kSbTimeMillisecond) {
    ASSERT_NO_FATAL_FAILURE(RenderAndProcessPendingJobs());
    SbThreadSleep(5 * kSbTimeMillisecond);
  }
  ASSERT_EQ(media_time, GetMediaTime());

  Play();
  ASSERT_NO_FATAL_FAILURE(WriteDataUntil(std::max(
      GetCurrentAudioBufferTimestamp(), GetCurrentVideoBufferTimestamp())));
  ASSERT_NO_FATAL_FAILURE(WriteEOS());
  ASSERT_NO_FATAL_FAILURE(WaitUntilPlaybackEnded());
}

// TODO: Enable variable playback rate tests
// TEST_P(PlayerComponentsTest, PlaybackRateHalf) {
//   const double kPlaybackRate = 0.5;

//   Seek(0);
//   SetPlaybackRate(kPlaybackRate);
//   ASSERT_NO_FATAL_FAILURE(WriteDataUntilPrerolled());
//   ASSERT_EQ(GetMediaTime(), 0);
//   ASSERT_FALSE(IsPlaying());

//   SbTime media_duration_to_write = std::max(GetCurrentVideoBufferTimestamp(),
//                                             GetCurrentAudioBufferTimestamp());
//   media_duration_to_write = std::max(kSbTimeSecond, media_duration_to_write);
//   SbTime media_duration_to_play =
//       static_cast<SbTime>(media_duration_to_write / kPlaybackRate);

//   SbTimeMonotonic play_requested_at = SbTimeGetMonotonicNow();
//   Play();

//   ASSERT_NO_FATAL_FAILURE(WriteDataUntil(media_duration_to_write));
//   ASSERT_NO_FATAL_FAILURE(WriteEOS());
//   ASSERT_NO_FATAL_FAILURE(WaitUntilPlaybackEnded());

//   TODO: Enable the below check after we improve the accuracy of varied
//   playback rate time reporting.
//   ASSERT_GE(SbTimeGetMonotonicNow(),
//             play_requested_at + media_duration_to_play - 200 *
//             kSbTimeMillisecond);
// }

// TEST_P(PlayerComponentsTest, PlaybackRateDouble) {
//   const double kPlaybackRate = 2.0;

//   Seek(0);
//   SetPlaybackRate(kPlaybackRate);
//   ASSERT_NO_FATAL_FAILURE(WriteDataUntilPrerolled());
//   ASSERT_EQ(GetMediaTime(), 0);
//   ASSERT_FALSE(IsPlaying());

//   SbTime media_duration_to_write = std::max(GetCurrentVideoBufferTimestamp(),
//                                             GetCurrentAudioBufferTimestamp());
//   media_duration_to_write =
//       std::max(kSbTimeSecond * 2, media_duration_to_write);
//   SbTime media_duration_to_play =
//       static_cast<SbTime>(media_duration_to_write / kPlaybackRate);

//   SbTimeMonotonic play_requested_at = SbTimeGetMonotonicNow();
//   Play();

//   ASSERT_NO_FATAL_FAILURE(WriteDataUntil(media_duration_to_write));
//   ASSERT_NO_FATAL_FAILURE(WriteEOS());
//   ASSERT_NO_FATAL_FAILURE(WaitUntilPlaybackEnded());

//   playback rate time reporting.
//   ASSERT_LE(SbTimeGetMonotonicNow(),
//             play_requested_at + media_duration_to_play + 200 *
//             kSbTimeMillisecond);
// }

TEST_P(PlayerComponentsTest, SeekForward) {
  SbTime seek_to_time = 0;
  Seek(seek_to_time);
  ASSERT_NO_FATAL_FAILURE(WriteDataUntilPrerolled());
  ASSERT_EQ(GetMediaTime(), seek_to_time);
  ASSERT_FALSE(IsPlaying());

  Play();
  ASSERT_NO_FATAL_FAILURE(WriteDataUntil(kSbTimeSecond));

  Pause();
  seek_to_time = 2 * kSbTimeSecond;
  Seek(seek_to_time);
  ASSERT_NO_FATAL_FAILURE(WriteDataUntilPrerolled());
  ASSERT_EQ(GetMediaTime(), seek_to_time);
  ASSERT_FALSE(IsPlaying());

  Play();
  ASSERT_NO_FATAL_FAILURE(WriteDataUntil(seek_to_time + kSbTimeSecond));
  ASSERT_NO_FATAL_FAILURE(WriteEOS());
  ASSERT_NO_FATAL_FAILURE(WaitUntilPlaybackEnded());
}

TEST_P(PlayerComponentsTest, SeekBackward) {
  SbTime seek_to_time = 3 * kSbTimeSecond;
  Seek(seek_to_time);
  ASSERT_NO_FATAL_FAILURE(WriteDataUntilPrerolled());
  ASSERT_EQ(GetMediaTime(), seek_to_time);
  ASSERT_FALSE(IsPlaying());

  Play();
  ASSERT_NO_FATAL_FAILURE(WriteDataUntil(seek_to_time + kSbTimeSecond));

  Pause();
  seek_to_time = 1 * kSbTimeSecond;
  Seek(seek_to_time);
  ASSERT_NO_FATAL_FAILURE(WriteDataUntilPrerolled());
  ASSERT_EQ(GetMediaTime(), seek_to_time);
  ASSERT_FALSE(IsPlaying());

  Play();
  ASSERT_NO_FATAL_FAILURE(WriteDataUntil(seek_to_time + kSbTimeSecond));
  ASSERT_NO_FATAL_FAILURE(WriteEOS());
  ASSERT_NO_FATAL_FAILURE(WaitUntilPlaybackEnded());
}

PlayerComponentsTestParam CreateParam(const char* audio_file,
                                      const VideoTestParam& video_param) {
  return std::make_tuple(audio_file, std::get<0>(video_param),
                         std::get<1>(video_param));
}

vector<PlayerComponentsTestParam> GetSupportedCreationParameters() {
  vector<PlayerComponentsTestParam> supported_parameters;

  // TODO: Enable tests of "heaac.dmp".
  vector<const char*> audio_files = GetSupportedAudioTestFiles(false, false);
  vector<VideoTestParam> video_params = GetSupportedVideoTests();

  // Filter too short dmp files, as the tests need at least 4s of data.
  for (auto iter = audio_files.begin(); iter != audio_files.end();) {
    VideoDmpReader audio_dmp_reader(ResolveTestFileName(*iter).c_str(),
                                    VideoDmpReader::kEnableReadOnDemand);
    if (audio_dmp_reader.audio_duration() < 5 * kSbTimeSecond) {
      iter = audio_files.erase(iter);
    } else {
      iter++;
    }
  }
  for (auto iter = video_params.begin(); iter != video_params.end();) {
    VideoDmpReader video_dmp_reader(
        ResolveTestFileName(std::get<0>(*iter)).c_str(),
        VideoDmpReader::kEnableReadOnDemand);
    if (video_dmp_reader.video_duration() < 5 * kSbTimeSecond) {
      iter = video_params.erase(iter);
    } else {
      iter++;
    }
  }

  for (size_t i = 0; i < video_params.size(); i++) {
    supported_parameters.push_back(CreateParam("", video_params[i]));
    for (size_t j = 0; j < audio_files.size(); j++) {
      supported_parameters.push_back(
          CreateParam(audio_files[j], video_params[i]));
    }
  }
  SB_DCHECK(supported_parameters.size() < 50)
      << "There're " << supported_parameters.size()
      << " tests added. It may take too long time to run and result in timeout";

  for (size_t i = 0; i < audio_files.size(); i++) {
    if (VideoDecoder::OutputModeSupported(kSbPlayerOutputModeDecodeToTexture,
                                          kSbMediaVideoCodecNone,
                                          kSbDrmSystemInvalid)) {
      supported_parameters.push_back(std::make_tuple(
          audio_files[i], "", kSbPlayerOutputModeDecodeToTexture));
    }
    if (VideoDecoder::OutputModeSupported(kSbPlayerOutputModePunchOut,
                                          kSbMediaVideoCodecNone,
                                          kSbDrmSystemInvalid)) {
      supported_parameters.push_back(
          std::make_tuple(audio_files[i], "", kSbPlayerOutputModePunchOut));
    }
  }

  return supported_parameters;
}

INSTANTIATE_TEST_CASE_P(PlayerComponentsTests,
                        PlayerComponentsTest,
                        ValuesIn(GetSupportedCreationParameters()));

}  // namespace
}  // namespace testing
}  // namespace filter
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
