// 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 <stddef.h>
#include <stdint.h>

#include <sstream>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/cxx17_backports.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 "testing/gtest/include/gtest/gtest.h"

namespace media {
namespace mp2t {

typedef StreamParser::BufferQueue BufferQueue;

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(VideoCodec::kH264, H264PROFILE_MAIN,
                            VideoDecoderConfig::AlphaMode::kIsOpaque,
                            VideoColorSpace(), kNoTransformation, coded_size,
                            visible_rect, natural_size, EmptyExtraData(),
                            EncryptionScheme::kUnencrypted);
}

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

  BufferQueue buffers(frame_count);
  for (size_t k = 0; k < frame_count; k++) {
    buffers[k] =
        StreamParserBuffer::CopyFrom(dummy_buffer, base::size(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::Milliseconds(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 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::BindRepeating(&EsAdapterVideoTest::OnNewConfig,
                                      base::Unretained(this)),
                  base::BindRepeating(&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 BufferQueue& buffer_queue) {
  buffer_descriptors_.clear();

  es_adapter_.OnConfigChanged(CreateFakeVideoConfig());
  for (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 };
  BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, base::size(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 };
  BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, base::size(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};
  BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, base::size(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};
  BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, base::size(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};
  BufferQueue buffer_queue =
      GenerateFakeBuffers(pts_ms, is_key_frame, base::size(pts_ms));

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

}  // namespace mp2t
}  // namespace media
