// 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 "base/macros.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/ffmpeg_aac_bitstream_converter.h"
#include "media/filters/ffmpeg_demuxer.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

namespace {
const int kAacMainProfile = 0;
const int kAacLowComplexityProfile = 1;
} // namespace

// Class for testing the FFmpegAACBitstreamConverter.
class FFmpegAACBitstreamConverterTest : public testing::Test {
 protected:
  FFmpegAACBitstreamConverterTest() {
    // Minimal extra data header
    memset(extradata_header_, 0, sizeof(extradata_header_));

    // Set up reasonable aac parameters
    memset(&test_parameters_, 0, sizeof(AVCodecParameters));
    test_parameters_.codec_id = AV_CODEC_ID_AAC;
    test_parameters_.profile = FF_PROFILE_AAC_MAIN;
    test_parameters_.channels = 2;
    test_parameters_.extradata = extradata_header_;
    test_parameters_.extradata_size = sizeof(extradata_header_);
  }

  void CreatePacket(AVPacket* packet, const uint8_t* data, uint32_t data_size) {
    // Create new packet sized of |data_size| from |data|.
    EXPECT_EQ(av_new_packet(packet, data_size), 0);
    memcpy(packet->data, data, data_size);
  }

  // Variable to hold valid dummy parameters for testing.
  AVCodecParameters test_parameters_;

 private:
  uint8_t extradata_header_[2];

  DISALLOW_COPY_AND_ASSIGN(FFmpegAACBitstreamConverterTest);
};

TEST_F(FFmpegAACBitstreamConverterTest, Conversion_Success) {
  FFmpegAACBitstreamConverter converter(&test_parameters_);

  uint8_t dummy_packet[1000];
  // Fill dummy packet with junk data. aac converter doesn't look into packet
  // data, just header, so can fill with whatever we want for test.
  for(size_t i = 0; i < sizeof(dummy_packet); i++) {
    dummy_packet[i] = i & 0xFF; // Repeated sequences of 0-255
  }

  ScopedAVPacket test_packet = MakeScopedAVPacket();
  CreatePacket(test_packet.get(), dummy_packet,
               sizeof(dummy_packet));

  // Try out the actual conversion (should be successful and allocate new
  // packet and destroy the old one).
  EXPECT_TRUE(converter.ConvertPacket(test_packet.get()));

  // Check that a header was added and that packet data was preserved
  EXPECT_EQ(static_cast<long>(test_packet->size),
            static_cast<long>(sizeof(dummy_packet) +
                              FFmpegAACBitstreamConverter::kAdtsHeaderSize));
  EXPECT_EQ(memcmp(
      reinterpret_cast<void*>(test_packet->data +
                              FFmpegAACBitstreamConverter::kAdtsHeaderSize),
      reinterpret_cast<void*>(dummy_packet),
      sizeof(dummy_packet)), 0);
}

TEST_F(FFmpegAACBitstreamConverterTest, Conversion_FailureNullParams) {
  // Set up AVCConfigurationRecord to represent NULL data.
  AVCodecParameters dummy_parameters;
  dummy_parameters.extradata = nullptr;
  dummy_parameters.extradata_size = 0;
  FFmpegAACBitstreamConverter converter(&dummy_parameters);

  uint8_t dummy_packet[1000] = {0};

  // Try out the actual conversion with NULL parameter.
  EXPECT_FALSE(converter.ConvertPacket(NULL));

  // Create new packet to test actual conversion.
  ScopedAVPacket test_packet = MakeScopedAVPacket();
  CreatePacket(test_packet.get(), dummy_packet, sizeof(dummy_packet));

  // Try out the actual conversion. This should fail due to missing extradata.
  EXPECT_FALSE(converter.ConvertPacket(test_packet.get()));
}

TEST_F(FFmpegAACBitstreamConverterTest, Conversion_AudioProfileType) {
  FFmpegAACBitstreamConverter converter(&test_parameters_);

  uint8_t dummy_packet[1000] = {0};

  ScopedAVPacket test_packet = MakeScopedAVPacket();
  CreatePacket(test_packet.get(), dummy_packet,
               sizeof(dummy_packet));

  EXPECT_TRUE(converter.ConvertPacket(test_packet.get()));

  // Check that the ADTS header profile matches the parameters
  int profile = ((test_packet->data[2] & 0xC0) >> 6);

  EXPECT_EQ(profile, kAacMainProfile);

  test_parameters_.profile = FF_PROFILE_AAC_HE;
  FFmpegAACBitstreamConverter converter_he(&test_parameters_);

  test_packet.reset(av_packet_alloc());
  CreatePacket(test_packet.get(), dummy_packet,
               sizeof(dummy_packet));

  EXPECT_TRUE(converter_he.ConvertPacket(test_packet.get()));

  profile = ((test_packet->data[2] & 0xC0) >> 6);

  EXPECT_EQ(profile, kAacLowComplexityProfile);

  test_parameters_.profile = FF_PROFILE_AAC_ELD;
  FFmpegAACBitstreamConverter converter_eld(&test_parameters_);

  test_packet.reset(av_packet_alloc());
  CreatePacket(test_packet.get(), dummy_packet,
               sizeof(dummy_packet));

  EXPECT_FALSE(converter_eld.ConvertPacket(test_packet.get()));
}

TEST_F(FFmpegAACBitstreamConverterTest, Conversion_MultipleLength) {
  FFmpegAACBitstreamConverter converter(&test_parameters_);

  uint8_t dummy_packet[1000];

  ScopedAVPacket test_packet = MakeScopedAVPacket();
  CreatePacket(test_packet.get(), dummy_packet,
               sizeof(dummy_packet));

  // Try out the actual conversion (should be successful and allocate new
  // packet and destroy the old one).
  EXPECT_TRUE(converter.ConvertPacket(test_packet.get()));

  // Check that the ADTS header frame length matches the packet size
  int frame_length = ((test_packet->data[3] & 0x03) << 11) |
                     ((test_packet->data[4] & 0xFF) << 3) |
                     ((test_packet->data[5] & 0xE0) >> 5);

  EXPECT_EQ(frame_length, test_packet->size);

  // Create a second packet that is 1 byte smaller than the first one
  ScopedAVPacket second_test_packet = MakeScopedAVPacket();
  CreatePacket(second_test_packet.get(), dummy_packet,
               sizeof(dummy_packet) - 1);

  // Try out the actual conversion (should be successful and allocate new
  // packet and destroy the old one).
  EXPECT_TRUE(converter.ConvertPacket(second_test_packet.get()));

  // Check that the ADTS header frame length matches the packet size
  frame_length = ((second_test_packet->data[3] & 0x03) << 11) |
                 ((second_test_packet->data[4] & 0xFF) << 3) |
                 ((second_test_packet->data[5] & 0xE0) >> 5);

  EXPECT_EQ(frame_length, second_test_packet->size);
}

}  // namespace media
