// Copyright 2023 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 "cobalt/media/base/decoder_buffer_cache.h"

#include <algorithm>

#include "base/time/time.h"
#include "cobalt/media/decoder_buffer_allocator.h"
#include "starboard/media.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/chromium//media/base/decoder_buffer.h"

namespace cobalt {
namespace media {
namespace {

using ::media::DecoderBuffer;
using ::media::DemuxerStream;

constexpr size_t kMaxSamplesPerRead = 8;
constexpr size_t kBufferArraySize = 8;
constexpr size_t kBufferSize = 8;
constexpr uint8_t kBufferDataArray[kBufferArraySize][kBufferSize] = {
    {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01},
    {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02},
    {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03},
    {0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04},
    {0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05},
    {0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06},
    {0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07},
    {0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08},
};

const size_t kVideoKeyFrameFrequency = 4;
const size_t kDurationPerFrame = 16;

bool operator==(const SbMediaAudioStreamInfo& left,
                const SbMediaAudioStreamInfo& right) {
  return !(left != right);
}

bool operator==(const SbMediaVideoStreamInfo& left,
                const SbMediaVideoStreamInfo& right) {
  return !(left != right);
}

SbMediaAudioStreamInfo GetAudioStreamInfo() {
  SbMediaAudioStreamInfo stream_info;
  stream_info.codec = kSbMediaAudioCodecAac;
  stream_info.mime = "";
  stream_info.number_of_channels = 2;
  stream_info.samples_per_second = 44100;
  stream_info.audio_specific_config_size = 0;
  return stream_info;
}

SbMediaVideoStreamInfo GetVideoStreamInfo() {
  SbMediaVideoStreamInfo stream_info;
  stream_info.codec = kSbMediaVideoCodecH264;
  stream_info.mime = "";
  stream_info.max_video_capabilities = "";
  stream_info.frame_width = 1920;
  stream_info.frame_height = 1080;
  return stream_info;
}

DecoderBufferCache::DecoderBuffers GetAudioSourceBuffers() {
  DecoderBufferCache::DecoderBuffers source_buffers;
  for (size_t i = 0; i < kBufferArraySize; i++) {
    auto decoder_buffer =
        media::DecoderBuffer::CopyFrom(kBufferDataArray[i], kBufferSize);
    decoder_buffer->set_is_key_frame(true);
    decoder_buffer->set_timestamp(
        base::TimeDelta::FromMilliseconds(kDurationPerFrame * i));
    source_buffers.push_back(decoder_buffer);
  }
  return source_buffers;
}

DecoderBufferCache::DecoderBuffers GetVideoSourceBuffers() {
  DecoderBufferCache::DecoderBuffers source_buffers;
  for (size_t i = 0; i < kBufferArraySize; i++) {
    auto decoder_buffer =
        media::DecoderBuffer::CopyFrom(kBufferDataArray[i], kBufferSize);
    if (i % kVideoKeyFrameFrequency == 0) {
      decoder_buffer->set_is_key_frame(true);
      decoder_buffer->set_timestamp(
          base::TimeDelta::FromMilliseconds(kDurationPerFrame * i));
    } else {
      // Intended to reverse the timestamp orders.
      decoder_buffer->set_timestamp(base::TimeDelta::FromMilliseconds(
          kDurationPerFrame *
          (i + kVideoKeyFrameFrequency - 2 * (i % kVideoKeyFrameFrequency))));
    }
    source_buffers.push_back(decoder_buffer);
  }
  return source_buffers;
}

bool CompareOutputBuffers(const DecoderBufferCache::DecoderBuffers& source,
                          size_t start_index,
                          const DecoderBufferCache::DecoderBuffers& output) {
  if (start_index + output.size() > source.size()) {
    return false;
  }
  for (size_t i = 0; i < output.size(); i++) {
    if (source[start_index + i] != output[i]) {
      return false;
    }
  }
  return true;
}

template <typename StreamInfo>
void ReadAndCompareOutputs(DecoderBufferCache* cache, size_t buffers_to_read,
                           const DecoderBufferCache::DecoderBuffers& source,
                           size_t start_index,
                           const StreamInfo& source_stream_info) {
  StreamInfo output_stream_info;
  DecoderBufferCache::DecoderBuffers output_buffers;
  while (buffers_to_read > 0) {
    output_buffers.clear();
    cache->ReadBuffers(&output_buffers,
                       std::min(kMaxSamplesPerRead, buffers_to_read),
                       &output_stream_info);
    ASSERT_TRUE(source_stream_info == output_stream_info);
    ASSERT_GT(output_buffers.size(), 0);
    ASSERT_TRUE(CompareOutputBuffers(source, start_index, output_buffers));
    start_index += output_buffers.size();
    buffers_to_read -= output_buffers.size();
  }
}

size_t FindKeyFrameIndexBeforeTime(
    const DecoderBufferCache::DecoderBuffers& source,
    const base::TimeDelta& time) {
  SB_DCHECK(!source.empty());
  SB_DCHECK(source[0]->is_key_frame());

  size_t previous_key_frame_index = 0;
  for (size_t i = 1; i < source.size(); i++) {
    if (source[i]->is_key_frame()) {
      if (source[i]->timestamp() <= time) {
        previous_key_frame_index = i;
      } else {
        return previous_key_frame_index;
      }
    }
  }
  return previous_key_frame_index;
}

}  // namespace

TEST(DecoderBufferCacheTest, SunnyDay) {
  DecoderBufferAllocator allocator;
  DecoderBufferCache cache;

  SbMediaAudioStreamInfo source_audio_stream_info = GetAudioStreamInfo();
  SbMediaVideoStreamInfo source_video_stream_info = GetVideoStreamInfo();
  DecoderBufferCache::DecoderBuffers source_audio_buffers =
      GetAudioSourceBuffers();
  DecoderBufferCache::DecoderBuffers source_video_buffers =
      GetVideoSourceBuffers();
  cache.AddBuffers(source_audio_buffers, source_audio_stream_info);
  cache.AddBuffers(source_video_buffers, source_video_stream_info);

  ASSERT_NO_FATAL_FAILURE(
      ReadAndCompareOutputs(&cache, source_audio_buffers.size(),
                            source_audio_buffers, 0, source_audio_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));

  ASSERT_NO_FATAL_FAILURE(
      ReadAndCompareOutputs(&cache, source_video_buffers.size(),
                            source_video_buffers, 0, source_video_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));

  cache.ClearAll();
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));
}

TEST(DecoderBufferCacheTest, EmptyCache) {
  DecoderBufferCache cache;

  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));

  DecoderBufferCache::DecoderBuffers buffers;
  SbMediaAudioStreamInfo audio_stream_info;
  SbMediaVideoStreamInfo video_stream_info;

  cache.ReadBuffers(&buffers, kMaxSamplesPerRead, &audio_stream_info);
  ASSERT_TRUE(buffers.empty());
  cache.ReadBuffers(&buffers, kMaxSamplesPerRead, &video_stream_info);
  ASSERT_TRUE(buffers.empty());

  cache.ClearSegmentsBeforeMediaTime(base::TimeDelta());

  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));

  cache.ReadBuffers(&buffers, kMaxSamplesPerRead, &audio_stream_info);
  ASSERT_TRUE(buffers.empty());

  cache.ReadBuffers(&buffers, kMaxSamplesPerRead, &video_stream_info);
  ASSERT_TRUE(buffers.empty());
}

TEST(DecoderBufferCacheTest, ClearSegmentsWithZero) {
  DecoderBufferAllocator allocator;
  DecoderBufferCache cache;

  SbMediaAudioStreamInfo source_audio_stream_info = GetAudioStreamInfo();
  SbMediaVideoStreamInfo source_video_stream_info = GetVideoStreamInfo();
  DecoderBufferCache::DecoderBuffers source_audio_buffers =
      GetAudioSourceBuffers();
  DecoderBufferCache::DecoderBuffers source_video_buffers =
      GetVideoSourceBuffers();
  cache.AddBuffers(source_audio_buffers, source_audio_stream_info);
  cache.AddBuffers(source_video_buffers, source_video_stream_info);

  // Cache should not clear anything.
  cache.ClearSegmentsBeforeMediaTime(base::TimeDelta::FromMilliseconds(0));

  ASSERT_NO_FATAL_FAILURE(
      ReadAndCompareOutputs(&cache, source_audio_buffers.size(),
                            source_audio_buffers, 0, source_audio_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));

  ASSERT_NO_FATAL_FAILURE(
      ReadAndCompareOutputs(&cache, source_video_buffers.size(),
                            source_video_buffers, 0, source_video_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));
}

TEST(DecoderBufferCacheTest, ClearSegmentsAndResume) {
  DecoderBufferAllocator allocator;
  DecoderBufferCache cache;

  SbMediaAudioStreamInfo source_audio_stream_info = GetAudioStreamInfo();
  SbMediaVideoStreamInfo source_video_stream_info = GetVideoStreamInfo();
  DecoderBufferCache::DecoderBuffers source_audio_buffers =
      GetAudioSourceBuffers();
  DecoderBufferCache::DecoderBuffers source_video_buffers =
      GetVideoSourceBuffers();
  cache.AddBuffers(source_audio_buffers, source_audio_stream_info);
  cache.AddBuffers(source_video_buffers, source_video_stream_info);

  base::TimeDelta clear_time =
      base::TimeDelta::FromMilliseconds(kDurationPerFrame);
  cache.ClearSegmentsBeforeMediaTime(clear_time);

  size_t start_index =
      FindKeyFrameIndexBeforeTime(source_audio_buffers, clear_time);
  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_audio_buffers.size() - start_index, source_audio_buffers,
      start_index, source_audio_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));

  start_index = FindKeyFrameIndexBeforeTime(source_video_buffers, clear_time);
  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_video_buffers.size() - start_index, source_video_buffers,
      start_index, source_video_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));

  cache.StartResuming();

  start_index = FindKeyFrameIndexBeforeTime(source_audio_buffers, clear_time);
  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_audio_buffers.size() - start_index, source_audio_buffers,
      start_index, source_audio_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));

  start_index = FindKeyFrameIndexBeforeTime(source_video_buffers, clear_time);
  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_video_buffers.size() - start_index, source_video_buffers,
      start_index, source_video_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));

  clear_time = base::TimeDelta::FromMilliseconds(kDurationPerFrame *
                                                 (kVideoKeyFrameFrequency + 1));
  cache.ClearSegmentsBeforeMediaTime(clear_time);
  cache.StartResuming();

  start_index = FindKeyFrameIndexBeforeTime(source_audio_buffers, clear_time);
  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_audio_buffers.size() - start_index, source_audio_buffers,
      start_index, source_audio_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));

  start_index = FindKeyFrameIndexBeforeTime(source_video_buffers, clear_time);
  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_video_buffers.size() - start_index, source_video_buffers,
      start_index, source_video_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));
}

TEST(DecoderBufferCacheTest, MultipleStreamInfos) {
  DecoderBufferAllocator allocator;
  DecoderBufferCache cache;

  SbMediaAudioStreamInfo source_audio_stream_info_1 = GetAudioStreamInfo();
  SbMediaVideoStreamInfo source_video_stream_info_1 = GetVideoStreamInfo();

  SbMediaAudioStreamInfo source_audio_stream_info_2 = GetAudioStreamInfo();
  source_audio_stream_info_2.samples_per_second *= 2;
  SbMediaVideoStreamInfo source_video_stream_info_2 = GetVideoStreamInfo();
  source_video_stream_info_2.frame_width *= 2;
  source_video_stream_info_2.frame_height *= 2;

  DecoderBufferCache::DecoderBuffers source_audio_buffers =
      GetAudioSourceBuffers();
  DecoderBufferCache::DecoderBuffers source_video_buffers =
      GetVideoSourceBuffers();

  DecoderBufferCache::DecoderBuffers source_audio_buffers_1(
      source_audio_buffers.begin(),
      source_audio_buffers.begin() + kVideoKeyFrameFrequency);
  DecoderBufferCache::DecoderBuffers source_video_buffers_1(
      source_video_buffers.begin(),
      source_video_buffers.begin() + kVideoKeyFrameFrequency);

  DecoderBufferCache::DecoderBuffers source_audio_buffers_2(
      source_audio_buffers.begin() + kVideoKeyFrameFrequency,
      source_audio_buffers.end());
  DecoderBufferCache::DecoderBuffers source_video_buffers_2(
      source_video_buffers.begin() + kVideoKeyFrameFrequency,
      source_video_buffers.end());

  cache.AddBuffers(source_audio_buffers_1, source_audio_stream_info_1);
  cache.AddBuffers(source_video_buffers_1, source_video_stream_info_1);
  cache.AddBuffers(source_audio_buffers_2, source_audio_stream_info_2);
  cache.AddBuffers(source_video_buffers_2, source_video_stream_info_2);

  DecoderBufferCache::DecoderBuffers output_buffers;
  SbMediaAudioStreamInfo output_audio_stream_info;
  SbMediaVideoStreamInfo output_video_stream_info;

  // The output buffers in one read call should have same configuration.
  cache.ReadBuffers(&output_buffers, kMaxSamplesPerRead,
                    &output_audio_stream_info);
  ASSERT_TRUE(source_audio_stream_info_1 == output_audio_stream_info);
  ASSERT_EQ(output_buffers.size(), source_audio_buffers_1.size());

  output_buffers.clear();
  cache.ReadBuffers(&output_buffers, kMaxSamplesPerRead,
                    &output_video_stream_info);
  ASSERT_TRUE(source_video_stream_info_1 == output_video_stream_info);
  ASSERT_EQ(output_buffers.size(), source_video_buffers_1.size());

  cache.StartResuming();
  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_audio_buffers_1.size(), source_audio_buffers_1, 0,
      source_audio_stream_info_1));

  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_video_buffers_1.size(), source_video_buffers_1, 0,
      source_video_stream_info_1));

  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_audio_buffers_2.size(), source_audio_buffers_2, 0,
      source_audio_stream_info_2));

  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_video_buffers_2.size(), source_video_buffers_2, 0,
      source_video_stream_info_2));

  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));

  base::TimeDelta clear_time = base::TimeDelta::FromMilliseconds(
      kDurationPerFrame * (kVideoKeyFrameFrequency));
  cache.ClearSegmentsBeforeMediaTime(clear_time);
  cache.StartResuming();

  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_audio_buffers_2.size(), source_audio_buffers_2, 0,
      source_audio_stream_info_2));

  ASSERT_NO_FATAL_FAILURE(ReadAndCompareOutputs(
      &cache, source_video_buffers_2.size(), source_video_buffers_2, 0,
      source_video_stream_info_2));

  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));
}

TEST(DecoderBufferCacheTest, AudioOnly) {
  DecoderBufferAllocator allocator;
  DecoderBufferCache cache;

  SbMediaAudioStreamInfo source_audio_stream_info = GetAudioStreamInfo();
  DecoderBufferCache::DecoderBuffers source_audio_buffers =
      GetAudioSourceBuffers();
  cache.AddBuffers(source_audio_buffers, source_audio_stream_info);

  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));

  ASSERT_NO_FATAL_FAILURE(
      ReadAndCompareOutputs(&cache, source_audio_buffers.size(),
                            source_audio_buffers, 0, source_audio_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));
}

TEST(DecoderBufferCacheTest, VideoOnly) {
  DecoderBufferAllocator allocator;
  DecoderBufferCache cache;

  SbMediaVideoStreamInfo source_video_stream_info = GetVideoStreamInfo();
  DecoderBufferCache::DecoderBuffers source_video_buffers =
      GetVideoSourceBuffers();
  cache.AddBuffers(source_video_buffers, source_video_stream_info);

  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::AUDIO));

  ASSERT_NO_FATAL_FAILURE(
      ReadAndCompareOutputs(&cache, source_video_buffers.size(),
                            source_video_buffers, 0, source_video_stream_info));
  ASSERT_FALSE(cache.HasMoreBuffers(DemuxerStream::VIDEO));
}

TEST(DecoderBufferCacheTest, StreamInfosDeepCopied) {
  const char* kAudioMime = "audio/mp4; codecs=\"mp4a.40.2\"";
  const char* kAudioSpecificConfig = "0000";
  const char* kVideoMime = "video/mp4; codecs=\"avc1.42001E\"";
  const char* kMaxVideoCapabilities = "width=1920; height=1080; framerate=15";

  DecoderBufferAllocator allocator;
  DecoderBufferCache cache;

  SbMediaAudioStreamInfo source_audio_stream_info = GetAudioStreamInfo();
  source_audio_stream_info.mime = kAudioMime;
  source_audio_stream_info.audio_specific_config_size =
      strlen(kAudioSpecificConfig);
  source_audio_stream_info.audio_specific_config = kAudioSpecificConfig;

  SbMediaVideoStreamInfo source_video_stream_info = GetVideoStreamInfo();
  source_video_stream_info.mime = kVideoMime;
  source_video_stream_info.max_video_capabilities = kMaxVideoCapabilities;

  DecoderBufferCache::DecoderBuffers source_audio_buffers =
      GetAudioSourceBuffers();
  DecoderBufferCache::DecoderBuffers source_video_buffers =
      GetVideoSourceBuffers();
  cache.AddBuffers(source_audio_buffers, source_audio_stream_info);
  cache.AddBuffers(source_video_buffers, source_video_stream_info);

  DecoderBufferCache::DecoderBuffers output_buffers;
  SbMediaAudioStreamInfo output_audio_stream_info;
  SbMediaVideoStreamInfo output_video_stream_info;

  output_buffers.clear();
  cache.ReadBuffers(&output_buffers, kMaxSamplesPerRead,
                    &output_audio_stream_info);
  ASSERT_TRUE(source_audio_stream_info == output_audio_stream_info);
  ASSERT_NE(source_audio_stream_info.mime, output_audio_stream_info.mime);
  ASSERT_NE(source_audio_stream_info.audio_specific_config,
            output_audio_stream_info.audio_specific_config);

  output_buffers.clear();
  cache.ReadBuffers(&output_buffers, kMaxSamplesPerRead,
                    &output_video_stream_info);
  ASSERT_TRUE(source_video_stream_info == output_video_stream_info);
  ASSERT_NE(source_video_stream_info.mime, output_video_stream_info.mime);
  ASSERT_NE(source_video_stream_info.max_video_capabilities,
            output_video_stream_info.max_video_capabilities);
}


}  // namespace media
}  // namespace cobalt
