// Copyright (c) 2011 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 <cstring>

#include "base/bind.h"
#include "base/files/memory_mapped_file.h"
#include "base/logging.h"
#include "base/macros.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/media.h"
#include "media/base/media_util.h"
#include "media/base/test_data_util.h"
#include "media/base/video_decoder_config.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/ffmpeg_glue.h"
#include "media/filters/in_memory_url_protocol.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

class FFmpegCommonTest : public testing::Test {
 public:
  FFmpegCommonTest() {}
  ~FFmpegCommonTest() override = default;
};

uint8_t kExtraData[5] = {0x00, 0x01, 0x02, 0x03, 0x04};

template <typename T>
void TestConfigConvertExtraData(
    AVStream* stream,
    T* decoder_config,
    const base::Callback<bool(const AVStream*, T*)>& converter_fn) {
  // Should initially convert.
  EXPECT_TRUE(converter_fn.Run(stream, decoder_config));

  // Store orig to let FFmpeg free whatever it allocated.
  AVCodecParameters* codec_parameters = stream->codecpar;
  uint8_t* orig_extradata = codec_parameters->extradata;
  int orig_extradata_size = codec_parameters->extradata_size;

  // Valid combination: extra_data = nullptr && size = 0.
  codec_parameters->extradata = nullptr;
  codec_parameters->extradata_size = 0;
  EXPECT_TRUE(converter_fn.Run(stream, decoder_config));
  EXPECT_EQ(static_cast<size_t>(codec_parameters->extradata_size),
            decoder_config->extra_data().size());

  // Valid combination: extra_data = non-nullptr && size > 0.
  codec_parameters->extradata = &kExtraData[0];
  codec_parameters->extradata_size = arraysize(kExtraData);
  EXPECT_TRUE(converter_fn.Run(stream, decoder_config));
  EXPECT_EQ(static_cast<size_t>(codec_parameters->extradata_size),
            decoder_config->extra_data().size());
  EXPECT_EQ(
      0, memcmp(codec_parameters->extradata, &decoder_config->extra_data()[0],
                decoder_config->extra_data().size()));

  // Possible combination: extra_data = nullptr && size != 0, but the converter
  // function considers this valid and having no extra_data, due to behavior of
  // avcodec_parameters_to_context().
  codec_parameters->extradata = nullptr;
  codec_parameters->extradata_size = 10;
  EXPECT_TRUE(converter_fn.Run(stream, decoder_config));
  EXPECT_EQ(0UL, decoder_config->extra_data().size());

  // Invalid combination: extra_data = non-nullptr && size = 0.
  codec_parameters->extradata = &kExtraData[0];
  codec_parameters->extradata_size = 0;
  EXPECT_FALSE(converter_fn.Run(stream, decoder_config));

  // Restore orig values for sane cleanup.
  codec_parameters->extradata = orig_extradata;
  codec_parameters->extradata_size = orig_extradata_size;
}

TEST_F(FFmpegCommonTest, AVStreamToDecoderConfig) {
  // Open a file to get a real AVStreams from FFmpeg.
  base::MemoryMappedFile file;
  file.Initialize(GetTestDataFilePath("bear-320x240.webm"));
  InMemoryUrlProtocol protocol(file.data(), file.length(), false);
  FFmpegGlue glue(&protocol);
  ASSERT_TRUE(glue.OpenContext());
  AVFormatContext* format_context = glue.format_context();

  // Find the audio and video streams and test valid and invalid combinations
  // for extradata and extradata_size.
  bool found_audio = false;
  bool found_video = false;
  for (size_t i = 0;
       i < format_context->nb_streams && (!found_audio || !found_video);
       ++i) {
    AVStream* stream = format_context->streams[i];
    AVCodecParameters* codec_parameters = stream->codecpar;
    AVMediaType codec_type = codec_parameters->codec_type;

    if (codec_type == AVMEDIA_TYPE_AUDIO) {
      if (found_audio)
        continue;
      found_audio = true;
      AudioDecoderConfig audio_config;
      TestConfigConvertExtraData(stream, &audio_config,
                                 base::Bind(&AVStreamToAudioDecoderConfig));
    } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
      if (found_video)
        continue;
      found_video = true;
      VideoDecoderConfig video_config;
      TestConfigConvertExtraData(stream, &video_config,
                                 base::Bind(&AVStreamToVideoDecoderConfig));
    } else {
      // Only process audio/video.
      continue;
    }
  }

  ASSERT_TRUE(found_audio);
  ASSERT_TRUE(found_video);
}

TEST_F(FFmpegCommonTest, AVStreamToAudioDecoderConfig_OpusAmbisonics_4ch) {
  base::MemoryMappedFile file;
  file.Initialize(
      GetTestDataFilePath("bear-opus-end-trimming-4ch-channelmapping2.webm"));
  InMemoryUrlProtocol protocol(file.data(), file.length(), false);
  FFmpegGlue glue(&protocol);
  ASSERT_TRUE(glue.OpenContext());

  AVFormatContext* format_context = glue.format_context();
  EXPECT_EQ(static_cast<unsigned int>(1), format_context->nb_streams);
  AVStream* stream = format_context->streams[0];

  AVCodecParameters* codec_parameters = stream->codecpar;
  EXPECT_EQ(AVMEDIA_TYPE_AUDIO, codec_parameters->codec_type);

  AudioDecoderConfig audio_config;
  ASSERT_TRUE(AVStreamToAudioDecoderConfig(stream, &audio_config));

  EXPECT_EQ(kCodecOpus, audio_config.codec());
  EXPECT_EQ(CHANNEL_LAYOUT_QUAD, audio_config.channel_layout());
  EXPECT_EQ(4, audio_config.channels());
}

TEST_F(FFmpegCommonTest, AVStreamToAudioDecoderConfig_OpusAmbisonics_11ch) {
  base::MemoryMappedFile file;
  file.Initialize(
      GetTestDataFilePath("bear-opus-end-trimming-11ch-channelmapping2.webm"));
  InMemoryUrlProtocol protocol(file.data(), file.length(), false);
  FFmpegGlue glue(&protocol);
  ASSERT_TRUE(glue.OpenContext());

  AVFormatContext* format_context = glue.format_context();
  EXPECT_EQ(static_cast<unsigned int>(1), format_context->nb_streams);
  AVStream* stream = format_context->streams[0];

  AVCodecParameters* codec_parameters = stream->codecpar;
  EXPECT_EQ(AVMEDIA_TYPE_AUDIO, codec_parameters->codec_type);

  AudioDecoderConfig audio_config;
  ASSERT_TRUE(AVStreamToAudioDecoderConfig(stream, &audio_config));

  EXPECT_EQ(kCodecOpus, audio_config.codec());
  EXPECT_EQ(CHANNEL_LAYOUT_DISCRETE, audio_config.channel_layout());
  EXPECT_EQ(11, audio_config.channels());
}

TEST_F(FFmpegCommonTest, AVStreamToAudioDecoderConfig_9ch_wav) {
  base::MemoryMappedFile file;
  file.Initialize(GetTestDataFilePath("9ch.wav"));
  InMemoryUrlProtocol protocol(file.data(), file.length(), false);
  FFmpegGlue glue(&protocol);
  ASSERT_TRUE(glue.OpenContext());

  AVFormatContext* format_context = glue.format_context();
  EXPECT_EQ(static_cast<unsigned int>(1), format_context->nb_streams);
  AVStream* stream = format_context->streams[0];

  AVCodecParameters* codec_parameters = stream->codecpar;
  EXPECT_EQ(AVMEDIA_TYPE_AUDIO, codec_parameters->codec_type);

  AudioDecoderConfig audio_config;
  ASSERT_TRUE(AVStreamToAudioDecoderConfig(stream, &audio_config));

  EXPECT_EQ(kCodecPCM, audio_config.codec());
  EXPECT_EQ(CHANNEL_LAYOUT_DISCRETE, audio_config.channel_layout());
  EXPECT_EQ(9, audio_config.channels());
}

TEST_F(FFmpegCommonTest, TimeBaseConversions) {
  const int64_t test_data[][5] = {
      {1, 2, 1, 500000, 1}, {1, 3, 1, 333333, 1}, {1, 3, 2, 666667, 2},
  };

  for (size_t i = 0; i < arraysize(test_data); ++i) {
    SCOPED_TRACE(i);

    AVRational time_base;
    time_base.num = static_cast<int>(test_data[i][0]);
    time_base.den = static_cast<int>(test_data[i][1]);

    base::TimeDelta time_delta =
        ConvertFromTimeBase(time_base, test_data[i][2]);

    EXPECT_EQ(time_delta.InMicroseconds(), test_data[i][3]);
    EXPECT_EQ(ConvertToTimeBase(time_base, time_delta), test_data[i][4]);
  }
}

TEST_F(FFmpegCommonTest, VerifyFormatSizes) {
  for (AVSampleFormat format = AV_SAMPLE_FMT_NONE;
       format < AV_SAMPLE_FMT_NB;
       format = static_cast<AVSampleFormat>(format + 1)) {
    std::vector<AVCodecID> codec_ids(1, AV_CODEC_ID_NONE);
    if (format == AV_SAMPLE_FMT_S32)
      codec_ids.push_back(AV_CODEC_ID_PCM_S24LE);
    for (const auto& codec_id : codec_ids) {
      SampleFormat sample_format =
          AVSampleFormatToSampleFormat(format, codec_id);
      if (sample_format == kUnknownSampleFormat) {
        // This format not supported, so skip it.
        continue;
      }

      // Have FFMpeg compute the size of a buffer of 1 channel / 1 frame
      // with 1 byte alignment to make sure the sizes match.
      int single_buffer_size =
          av_samples_get_buffer_size(NULL, 1, 1, format, 1);
      int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
      EXPECT_EQ(bytes_per_channel, single_buffer_size);
    }
  }
}

// Verifies there are no collisions of the codec name hashes used for UMA.  Also
// includes code for updating the histograms XML.
TEST_F(FFmpegCommonTest, VerifyUmaCodecHashes) {
  const AVCodecDescriptor* desc = avcodec_descriptor_next(nullptr);

  std::map<int32_t, const char*> sorted_hashes;
  while (desc) {
    const int32_t hash = HashCodecName(desc->name);
    // Ensure there are no collisions.
    ASSERT_TRUE(sorted_hashes.find(hash) == sorted_hashes.end());
    sorted_hashes[hash] = desc->name;

    desc = avcodec_descriptor_next(desc);
  }

  // Add a none entry for when no codec is detected.
  static const char kUnknownCodec[] = "none";
  const int32_t hash = HashCodecName(kUnknownCodec);
  ASSERT_TRUE(sorted_hashes.find(hash) == sorted_hashes.end());
  sorted_hashes[hash] = kUnknownCodec;

  // Uncomment the following lines to generate the "FFmpegCodecHashes" enum for
  // usage in the histogram metrics file.  While it regenerates *ALL* values, it
  // should only be used to *ADD* values to histograms file.  Never delete any
  // values; diff should verify.
#if 0
  static const std::vector<std::pair<std::string, int32_t>> kDeprecatedHashes =
      {
          {"brender_pix_deprecated", -1866047250},
          {"adpcm_vima_deprecated", -1782518388},
          {"pcm_s32le_planar_deprecated", -1328796639},
          {"webp_deprecated", -993429906},
          {"paf_video_deprecated", -881893142},
          {"vima_deprecated", -816209197},
          {"iff_byterun1", -777478450},
          {"paf_audio_deprecated", -630356729},

          {"exr_deprecated", -418117523},
          {"hevc_deprecated", -414733739},
          {"vp7_deprecated", -197551526},
          {"escape130_deprecated", 73149662},
          {"tak_deprecated", 1041617024},
          {"opus_deprecated", 1165132763},
          {"g2m_deprecated", 1194572884},

          {"pcm_s24le_planar_deprecated", 1535518292},
          {"sanm_deprecated", 2047102762},
      };

  for (auto& kv : kDeprecatedHashes)
    sorted_hashes[kv.second] = kv.first.c_str();
  printf("<enum name=\"FFmpegCodecHashes\">\n");
  for (const auto& kv : sorted_hashes)
    printf("  <int value=\"%d\" label=\"%s\"/>\n", kv.first, kv.second);
  printf("</enum>\n");
#endif
}

}  // namespace media
