// 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/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 "testing/gtest/include/gtest/gtest.h"

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
