// 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 "media/mojo/common/mojo_decoder_buffer_converter.h"

#include <stdint.h>

#include <memory>

#include "base/macros.h"
#include "media/base/decoder_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

namespace {

scoped_refptr<DecoderBuffer> ConvertDecoderBufferAndBack(
    scoped_refptr<DecoderBuffer> buffer) {
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  std::unique_ptr<MojoDecoderBufferWriter> writer =
      MojoDecoderBufferWriter::Create(DemuxerStream::AUDIO, &consumer_handle);
  MojoDecoderBufferReader reader(std::move(consumer_handle));

  // Convert from and back.
  mojom::DecoderBufferPtr mojo_buffer = writer->WriteDecoderBuffer(buffer);
  return reader.ReadDecoderBuffer(mojo_buffer);
}

void CompareDecoderBuffer(scoped_refptr<DecoderBuffer> a,
                          scoped_refptr<DecoderBuffer> b) {
  EXPECT_EQ(a->end_of_stream(), b->end_of_stream());
  // According to DecoderBuffer API, it is illegal to call any method when
  // end_of_stream() is true.
  if (a->end_of_stream())
    return;

  EXPECT_EQ(a->timestamp(), b->timestamp());
  EXPECT_EQ(a->duration(), b->duration());
  EXPECT_EQ(a->is_key_frame(), b->is_key_frame());
  EXPECT_EQ(a->splice_timestamp(), b->splice_timestamp());
  EXPECT_EQ(a->discard_padding(), b->discard_padding());

  EXPECT_EQ(a->data_size(), b->data_size());
  if (a->data_size() > 0)
    EXPECT_EQ(0, memcmp(a->data(), b->data(), a->data_size()));

  EXPECT_EQ(a->side_data_size(), b->side_data_size());
  if (a->side_data_size() > 0)
    EXPECT_EQ(0, memcmp(a->side_data(), b->side_data(), a->side_data_size()));

  EXPECT_EQ(a->decrypt_config() == nullptr, b->decrypt_config() == nullptr);
  if (a->decrypt_config())
    EXPECT_TRUE(a->decrypt_config()->Matches(*b->decrypt_config()));
}

}  // namespace

TEST(MojoDecoderBufferConverterTest, ConvertDecoderBuffer_Normal) {
  const uint8_t kData[] = "hello, world";
  const uint8_t kSideData[] = "sideshow bob";
  const size_t kDataSize = arraysize(kData);
  const size_t kSideDataSize = arraysize(kSideData);

  // Original.
  scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CopyFrom(
      reinterpret_cast<const uint8_t*>(&kData), kDataSize,
      reinterpret_cast<const uint8_t*>(&kSideData), kSideDataSize));
  buffer->set_timestamp(base::TimeDelta::FromMilliseconds(123));
  buffer->set_duration(base::TimeDelta::FromMilliseconds(456));
  buffer->set_splice_timestamp(base::TimeDelta::FromMilliseconds(200));
  buffer->set_discard_padding(
      DecoderBuffer::DiscardPadding(base::TimeDelta::FromMilliseconds(5),
                                    base::TimeDelta::FromMilliseconds(6)));

  scoped_refptr<DecoderBuffer> result = ConvertDecoderBufferAndBack(buffer);
  CompareDecoderBuffer(buffer, result);
}

TEST(MojoDecoderBufferConverterTest, ConvertDecoderBuffer_EOS) {
  scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CreateEOSBuffer());
  scoped_refptr<DecoderBuffer> result = ConvertDecoderBufferAndBack(buffer);
  CompareDecoderBuffer(buffer, result);
}

TEST(MojoDecoderBufferConverterTest, ConvertDecoderBuffer_KeyFrame) {
  const uint8_t kData[] = "hello, world";
  const size_t kDataSize = arraysize(kData);

  scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CopyFrom(
      reinterpret_cast<const uint8_t*>(&kData), kDataSize));
  buffer->set_is_key_frame(true);
  EXPECT_TRUE(buffer->is_key_frame());

  scoped_refptr<DecoderBuffer> result = ConvertDecoderBufferAndBack(buffer);
  CompareDecoderBuffer(buffer, result);
}

TEST(MojoDecoderBufferConverterTest, ConvertDecoderBuffer_EncryptedBuffer) {
  const uint8_t kData[] = "hello, world";
  const size_t kDataSize = arraysize(kData);
  const char kKeyId[] = "00112233445566778899aabbccddeeff";
  const char kIv[] = "0123456789abcdef";

  std::vector<SubsampleEntry> subsamples;
  subsamples.push_back(SubsampleEntry(10, 20));
  subsamples.push_back(SubsampleEntry(30, 40));
  subsamples.push_back(SubsampleEntry(50, 60));

  scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CopyFrom(
      reinterpret_cast<const uint8_t*>(&kData), kDataSize));
  buffer->set_decrypt_config(
      base::MakeUnique<DecryptConfig>(kKeyId, kIv, subsamples));

  scoped_refptr<DecoderBuffer> result = ConvertDecoderBufferAndBack(buffer);
  CompareDecoderBuffer(buffer, result);

  // Test empty IV. This is used for clear buffer in an encrypted stream.
  buffer->set_decrypt_config(base::MakeUnique<DecryptConfig>(
      kKeyId, "", std::vector<SubsampleEntry>()));
  result = ConvertDecoderBufferAndBack(buffer);
  CompareDecoderBuffer(buffer, result);
}

}  // namespace media
