// 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/cxx17_backports.h"
#include "base/files/memory_mapped_file.h"
#include "base/logging.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::RepeatingCallback<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 = base::size(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;
  ASSERT_TRUE(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::BindRepeating(&AVStreamToAudioDecoderConfig));
    } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
      if (found_video)
        continue;
      found_video = true;
      VideoDecoderConfig video_config;
      TestConfigConvertExtraData(
          stream, &video_config,
          base::BindRepeating(&AVStreamToVideoDecoderConfig));
    } else {
      // Only process audio/video.
      continue;
    }
  }

  ASSERT_TRUE(found_audio);
  ASSERT_TRUE(found_video);
}

TEST_F(FFmpegCommonTest, AVStreamToAudioDecoderConfig_OpusAmbisonics_4ch) {
  base::MemoryMappedFile file;
  ASSERT_TRUE(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(AudioCodec::kOpus, 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;
  ASSERT_TRUE(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(AudioCodec::kOpus, 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;
  ASSERT_TRUE(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(AudioCodec::kPCM, 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 < base::size(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},

          {"mpegvideo_xvmc_deprecated", 1550758811},
          {"voxware_deprecated", 1656834662}
      };

  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
}
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
TEST_F(FFmpegCommonTest, VerifyH264Profile) {
  // Open a file to get a real AVStreams from FFmpeg.
  base::MemoryMappedFile file;
  ASSERT_TRUE(file.Initialize(GetTestDataFilePath("bear-1280x720.mp4")));
  InMemoryUrlProtocol protocol(file.data(), file.length(), false);
  FFmpegGlue glue(&protocol);
  ASSERT_TRUE(glue.OpenContext());
  AVFormatContext* format_context = glue.format_context();

  for (size_t i = 0; i < format_context->nb_streams; ++i) {
    AVStream* stream = format_context->streams[i];
    AVCodecParameters* codec_parameters = stream->codecpar;
    AVMediaType codec_type = codec_parameters->codec_type;

    if (codec_type == AVMEDIA_TYPE_VIDEO) {
      VideoDecoderConfig video_config;
      EXPECT_TRUE(AVStreamToVideoDecoderConfig(stream, &video_config));
      EXPECT_EQ(H264PROFILE_HIGH, video_config.profile());
    } else {
      // Only process video.
      continue;
    }
  }
}
#endif

// Verifies that the HDR Metadata and VideoColorSpace are correctly parsed.
TEST_F(FFmpegCommonTest, VerifyHDRMetadataAndColorSpaceInfo) {
  // Open a file to get a real AVStreams from FFmpeg.
  base::MemoryMappedFile file;
  ASSERT_TRUE(file.Initialize(GetTestDataFilePath("colour.webm")));
  InMemoryUrlProtocol protocol(file.data(), file.length(), false);
  FFmpegGlue glue(&protocol);
  ASSERT_TRUE(glue.OpenContext());
  AVFormatContext* format_context = glue.format_context();
  ASSERT_EQ(format_context->nb_streams, 1u);

  AVStream* stream = format_context->streams[0];
  AVCodecParameters* codec_parameters = stream->codecpar;
  AVMediaType codec_type = codec_parameters->codec_type;
  ASSERT_EQ(codec_type, AVMEDIA_TYPE_VIDEO);

  VideoDecoderConfig video_config;
  EXPECT_TRUE(AVStreamToVideoDecoderConfig(stream, &video_config));
  ASSERT_TRUE(video_config.hdr_metadata().has_value());
  EXPECT_EQ(30.0,
            video_config.hdr_metadata()->color_volume_metadata.luminance_min);
  EXPECT_EQ(40.0,
            video_config.hdr_metadata()->color_volume_metadata.luminance_max);
  EXPECT_EQ(gfx::PointF(0.1, 0.2),
            video_config.hdr_metadata()->color_volume_metadata.primary_r);
  EXPECT_EQ(gfx::PointF(0.1, 0.2),
            video_config.hdr_metadata()->color_volume_metadata.primary_g);
  EXPECT_EQ(gfx::PointF(0.1, 0.2),
            video_config.hdr_metadata()->color_volume_metadata.primary_b);
  EXPECT_EQ(gfx::PointF(0.1, 0.2),
            video_config.hdr_metadata()->color_volume_metadata.white_point);

  EXPECT_EQ(VideoColorSpace(VideoColorSpace::PrimaryID::SMPTEST428_1,
                            VideoColorSpace::TransferID::LOG,
                            VideoColorSpace::MatrixID::RGB,
                            gfx::ColorSpace::RangeID::FULL),
            video_config.color_space_info());
}
}  // namespace media
