// Copyright 2014 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 <sstream>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "media/base/media_util.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_decoder_config.h"
#include "media/formats/mp2t/es_adapter_video.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace media {
namespace mp2t {

namespace {

VideoDecoderConfig CreateFakeVideoConfig() {
  gfx::Size coded_size(320, 240);
  gfx::Rect visible_rect(0, 0, 320, 240);
  gfx::Size natural_size(320, 240);
  return VideoDecoderConfig(kCodecH264, H264PROFILE_MAIN, PIXEL_FORMAT_I420,
                            COLOR_SPACE_UNSPECIFIED, coded_size, visible_rect,
                            natural_size, EmptyExtraData(), Unencrypted());
}

StreamParserBuffer::BufferQueue GenerateFakeBuffers(const int* frame_pts_ms,
                                                    const bool* is_key_frame,
                                                    size_t frame_count) {
  uint8_t dummy_buffer[] = {0, 0, 0, 0};

  StreamParserBuffer::BufferQueue buffers(frame_count);
  for (size_t k = 0; k < frame_count; k++) {
    buffers[k] =
        StreamParserBuffer::CopyFrom(dummy_buffer, arraysize(dummy_buffer),
                                     is_key_frame[k], DemuxerStream::VIDEO, 0);
    if (frame_pts_ms[k] < 0) {
      buffers[k]->set_timestamp(kNoTimestamp);
    } else {
      buffers[k]->set_timestamp(
          base::TimeDelta::FromMilliseconds(frame_pts_ms[k]));
    }
  }
  return buffers;
}

}  // namespace

class EsAdapterVideoTest : public testing::Test {
 public:
  EsAdapterVideoTest();

 protected:
  // Feed the ES adapter with the buffers from |buffer_queue|.
  // Return the durations computed by the ES adapter as well as
  // whether each frame emitted by the adapter is a key frame.
  std::string RunAdapterTest(const StreamParser::BufferQueue& buffer_queue);

 private:
  void OnNewConfig(const VideoDecoderConfig& video_config);
  void OnNewBuffer(scoped_refptr<StreamParserBuffer> buffer);

  EsAdapterVideo es_adapter_;

  std::stringstream buffer_descriptors_;

  DISALLOW_COPY_AND_ASSIGN(EsAdapterVideoTest);
};

EsAdapterVideoTest::EsAdapterVideoTest()
    : es_adapter_(
          base::Bind(&EsAdapterVideoTest::OnNewConfig, base::Unretained(this)),
          base::Bind(&EsAdapterVideoTest::OnNewBuffer,
                     base::Unretained(this))) {}

void EsAdapterVideoTest::OnNewConfig(const VideoDecoderConfig& video_config) {}

void EsAdapterVideoTest::OnNewBuffer(scoped_refptr<StreamParserBuffer> buffer) {
  buffer_descriptors_ << "(" << buffer->duration().InMilliseconds() << ","
                      << (buffer->is_key_frame() ? "Y" : "N") << ") ";
}

std::string EsAdapterVideoTest::RunAdapterTest(
    const StreamParserBuffer::BufferQueue& buffer_queue) {
  buffer_descriptors_.clear();

  es_adapter_.OnConfigChanged(CreateFakeVideoConfig());
  for (StreamParserBuffer::BufferQueue::const_iterator it =
           buffer_queue.begin();
       it != buffer_queue.end(); ++it) {
    es_adapter_.OnNewBuffer(*it);
  }
  es_adapter_.Flush();

  std::string s = buffer_descriptors_.str();
  base::TrimWhitespaceASCII(s, base::TRIM_ALL, &s);
  return s;
}

TEST_F(EsAdapterVideoTest, FrameDurationSimpleGop) {
  // PTS for a GOP without B frames - strictly increasing.
  int pts_ms[] = {30, 31, 33, 36, 40, 45, 51, 58};
  bool is_key_frame[] = {true, false, false, false, false, false, false, false};
  StreamParserBuffer::BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms));

  EXPECT_EQ("(1,Y) (2,N) (3,N) (4,N) (5,N) (6,N) (7,N) (7,N)",
            RunAdapterTest(buffer_queue));
}

TEST_F(EsAdapterVideoTest, FrameDurationComplexGop) {
  // PTS for a GOP with B frames.
  int pts_ms[] = {30, 120, 60, 90, 210, 150, 180, 300, 240, 270};
  bool is_key_frame[] = {true,  false, false, false, false,
                         false, false, false, false, false};
  StreamParserBuffer::BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms));

  EXPECT_EQ(
      "(30,Y) (30,N) (30,N) (30,N) (30,N) "
      "(30,N) (30,N) (30,N) (30,N) (30,N)",
      RunAdapterTest(buffer_queue));
}

TEST_F(EsAdapterVideoTest, LeadingNonKeyFrames) {
  int pts_ms[] = {30, 40, 50, 120, 150, 180};
  bool is_key_frame[] = {false, false, false, true, false, false};
  StreamParserBuffer::BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms));

  EXPECT_EQ("(30,Y) (30,Y) (30,Y) (30,Y) (30,N) (30,N)",
            RunAdapterTest(buffer_queue));
}

TEST_F(EsAdapterVideoTest, LeadingKeyFrameWithNoTimestamp) {
  int pts_ms[] = {-1, 40, 50, 120, 150, 180};
  bool is_key_frame[] = {true, false, false, true, false, false};
  StreamParserBuffer::BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms));

  EXPECT_EQ("(40,Y) (40,Y) (30,Y) (30,N) (30,N)", RunAdapterTest(buffer_queue));
}

TEST_F(EsAdapterVideoTest, LeadingFramesWithNoTimestamp) {
  int pts_ms[] = {-1, -1, 50, 120, 150, 180};
  bool is_key_frame[] = {false, false, false, true, false, false};
  StreamParserBuffer::BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms));

  EXPECT_EQ("(70,Y) (30,Y) (30,N) (30,N)", RunAdapterTest(buffer_queue));
}

}  // namespace mp2t
}  // namespace media
}  // namespace cobalt
