// Copyright 2019 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/gpu/windows/supported_profile_helpers.h"

#include <d3d11.h>
#include <d3d11_1.h>
#include <initguid.h>
#include <map>
#include <utility>

#include "base/test/scoped_feature_list.h"
#include "base/win/windows_version.h"
#include "media/base/media_switches.h"
#include "media/base/test_helpers.h"
#include "media/base/win/d3d11_mocks.h"
#include "media/gpu/windows/av1_guids.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::WithArgs;

#define DONT_RUN_ON_WIN_7()                                  \
  do {                                                       \
    if (base::win::GetVersion() <= base::win::Version::WIN7) \
      return;                                                \
  } while (0)

namespace {

using PciId = std::pair<uint16_t, uint16_t>;
constexpr PciId kLegacyIntelGpu = {0x8086, 0x102};
constexpr PciId kRecentIntelGpu = {0x8086, 0x100};
constexpr PciId kLegacyAmdGpu = {0x1022, 0x130f};
constexpr PciId kRecentAmdGpu = {0x1022, 0x130e};

constexpr gfx::Size kMinResolution(64, 64);
constexpr gfx::Size kFullHd(1920, 1088);
constexpr gfx::Size kSquare4k(4096, 4096);
constexpr gfx::Size kSquare8k(8192, 8192);

}  // namespace

namespace media {

constexpr VideoCodecProfile kSupportedH264Profiles[] = {
    H264PROFILE_BASELINE, H264PROFILE_MAIN, H264PROFILE_HIGH};

class SupportedResolutionResolverTest : public ::testing::Test {
 public:
  void SetUp() override {
    gpu_workarounds_.disable_dxgi_zero_copy_video = false;
    mock_d3d11_device_ = MakeComPtr<NiceMock<D3D11DeviceMock>>();

    mock_dxgi_device_ = MakeComPtr<NiceMock<DXGIDeviceMock>>();
    ON_CALL(*mock_d3d11_device_.Get(), QueryInterface(IID_IDXGIDevice, _))
        .WillByDefault(SetComPointeeAndReturnOk<1>(mock_dxgi_device_.Get()));

    mock_d3d11_video_device_ = MakeComPtr<NiceMock<D3D11VideoDeviceMock>>();
    ON_CALL(*mock_d3d11_device_.Get(), QueryInterface(IID_ID3D11VideoDevice, _))
        .WillByDefault(
            SetComPointeeAndReturnOk<1>(mock_d3d11_video_device_.Get()));

    mock_dxgi_adapter_ = MakeComPtr<NiceMock<DXGIAdapterMock>>();
    ON_CALL(*mock_dxgi_device_.Get(), GetAdapter(_))
        .WillByDefault(SetComPointeeAndReturnOk<0>(mock_dxgi_adapter_.Get()));

    SetGpuProfile(kRecentIntelGpu);
    SetMaxResolution(D3D11_DECODER_PROFILE_H264_VLD_NOFGT, kSquare4k);
  }

  void SetMaxResolution(const GUID& g, const gfx::Size& max_res) {
    max_size_for_guids_[g] = max_res;
    ON_CALL(*mock_d3d11_video_device_.Get(), GetVideoDecoderConfigCount(_, _))
        .WillByDefault(
            WithArgs<0, 1>(Invoke([this](const D3D11_VIDEO_DECODER_DESC* desc,
                                         UINT* count) -> HRESULT {
              *count = 0;
              const auto& itr = this->max_size_for_guids_.find(desc->Guid);
              if (itr == this->max_size_for_guids_.end())
                return E_FAIL;
              const gfx::Size max = itr->second;
              if (max.height() < 0 || max.width() < 0)
                return E_FAIL;
              if (static_cast<UINT>(max.height()) < desc->SampleHeight)
                return E_FAIL;
              if (static_cast<UINT>(max.width()) < desc->SampleWidth)
                return S_OK;
              *count = 1;
              return S_OK;
            })));
  }

  void EnableDecoders(const std::vector<GUID>& decoder_guids) {
    ON_CALL(*mock_d3d11_video_device_.Get(), GetVideoDecoderProfileCount())
        .WillByDefault(Return(decoder_guids.size()));

    // Note that we don't check if the guid in the config actually matches
    // |decoder_profile|.  Perhaps we should.
    ON_CALL(*mock_d3d11_video_device_.Get(), GetVideoDecoderProfile(_, _))
        .WillByDefault(WithArgs<0, 1>(
            Invoke([decoder_guids](UINT p_idx, GUID* guid) -> HRESULT {
              if (p_idx >= decoder_guids.size())
                return E_FAIL;
              *guid = decoder_guids.at(p_idx);
              return S_OK;
            })));
  }

  void SetGpuProfile(std::pair<uint16_t, uint16_t> vendor_and_gpu) {
    mock_adapter_desc_.DeviceId = static_cast<UINT>(vendor_and_gpu.second);
    mock_adapter_desc_.VendorId = static_cast<UINT>(vendor_and_gpu.first);

    ON_CALL(*mock_dxgi_adapter_.Get(), GetDesc(_))
        .WillByDefault(
            DoAll(SetArgPointee<0>(mock_adapter_desc_), Return(S_OK)));
  }

  void AssertDefaultSupport(
      const SupportedResolutionRangeMap& supported_resolutions,
      size_t expected_size = 3u) {
    ASSERT_EQ(expected_size, supported_resolutions.size());
    for (const auto profile : kSupportedH264Profiles) {
      auto it = supported_resolutions.find(profile);
      ASSERT_NE(it, supported_resolutions.end());
      EXPECT_EQ(kMinResolution, it->second.min_resolution);
      EXPECT_EQ(kFullHd, it->second.max_landscape_resolution);
      EXPECT_EQ(gfx::Size(), it->second.max_portrait_resolution);
    }
  }

  void TestDecoderSupport(const GUID& decoder,
                          VideoCodecProfile profile,
                          const gfx::Size& max_res = kSquare4k,
                          const gfx::Size& max_landscape_res = kSquare4k,
                          const gfx::Size& max_portrait_res = kSquare4k) {
    EnableDecoders({decoder});
    SetMaxResolution(decoder, max_res);

    const auto supported_resolutions = GetSupportedD3D11VideoDecoderResolutions(
        mock_d3d11_device_, gpu_workarounds_);
    AssertDefaultSupport(supported_resolutions,
                         base::size(kSupportedH264Profiles) + 1);

    auto it = supported_resolutions.find(profile);
    ASSERT_NE(it, supported_resolutions.end());
    EXPECT_EQ(kMinResolution, it->second.min_resolution);
    EXPECT_EQ(max_landscape_res, it->second.max_landscape_resolution);
    EXPECT_EQ(max_portrait_res, it->second.max_portrait_resolution);
  }

  Microsoft::WRL::ComPtr<D3D11DeviceMock> mock_d3d11_device_;
  Microsoft::WRL::ComPtr<DXGIAdapterMock> mock_dxgi_adapter_;
  Microsoft::WRL::ComPtr<DXGIDeviceMock> mock_dxgi_device_;
  Microsoft::WRL::ComPtr<D3D11VideoDeviceMock> mock_d3d11_video_device_;
  DXGI_ADAPTER_DESC mock_adapter_desc_;
  gpu::GpuDriverBugWorkarounds gpu_workarounds_;

  struct GUIDComparison {
    bool operator()(const GUID& a, const GUID& b) const {
      return memcmp(&a, &b, sizeof(GUID)) < 0;
    }
  };
  base::flat_map<GUID, gfx::Size, GUIDComparison> max_size_for_guids_;
};

TEST_F(SupportedResolutionResolverTest, CanDisableAV1) {
  DONT_RUN_ON_WIN_7();

  // Do all the things to normally enable AV1:
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(kMediaFoundationAV1Decoding);

  // Enable the av1 decoder.
  EnableDecoders({DXVA_ModeAV1_VLD_Profile0});
  SetMaxResolution(DXVA_ModeAV1_VLD_Profile0, kSquare8k);

  const auto supported_resolutions = GetSupportedD3D11VideoDecoderResolutions(
      mock_d3d11_device_, gpu_workarounds_, false);
  auto av1_supported_res = supported_resolutions.find(AV1PROFILE_PROFILE_MAIN);

  // There should be no supported av1 resolutions.
  ASSERT_EQ(av1_supported_res, supported_resolutions.end());
}

TEST_F(SupportedResolutionResolverTest, HasH264SupportByDefault) {
  DONT_RUN_ON_WIN_7();
  AssertDefaultSupport(
      GetSupportedD3D11VideoDecoderResolutions(nullptr, gpu_workarounds_));

  SetGpuProfile(kLegacyIntelGpu);
  AssertDefaultSupport(GetSupportedD3D11VideoDecoderResolutions(
      mock_d3d11_device_, gpu_workarounds_));

  SetGpuProfile(kLegacyAmdGpu);
  AssertDefaultSupport(GetSupportedD3D11VideoDecoderResolutions(
      mock_d3d11_device_, gpu_workarounds_));
}

TEST_F(SupportedResolutionResolverTest, WorkaroundsDisableVpx) {
  DONT_RUN_ON_WIN_7();

  gpu_workarounds_.disable_accelerated_vp8_decode = true;
  gpu_workarounds_.disable_accelerated_vp9_decode = true;
  EnableDecoders({D3D11_DECODER_PROFILE_VP8_VLD,
                  D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0,
                  D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2});

  AssertDefaultSupport(GetSupportedD3D11VideoDecoderResolutions(
      mock_d3d11_device_, gpu_workarounds_));
}

TEST_F(SupportedResolutionResolverTest, H264Supports4k) {
  DONT_RUN_ON_WIN_7();

  EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT});
  const auto supported_resolutions = GetSupportedD3D11VideoDecoderResolutions(
      mock_d3d11_device_, gpu_workarounds_);

  ASSERT_EQ(3u, supported_resolutions.size());
  for (const auto profile : kSupportedH264Profiles) {
    auto it = supported_resolutions.find(profile);
    ASSERT_NE(it, supported_resolutions.end());
    EXPECT_EQ(kMinResolution, it->second.min_resolution);
    EXPECT_EQ(kSquare4k, it->second.max_landscape_resolution);
    EXPECT_EQ(kSquare4k, it->second.max_portrait_resolution);
  }
}

TEST_F(SupportedResolutionResolverTest, VP8Supports4k) {
  DONT_RUN_ON_WIN_7();

  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(kMediaFoundationVP8Decoding);

  EnableDecoders({D3D11_DECODER_PROFILE_VP8_VLD});
  SetMaxResolution(D3D11_DECODER_PROFILE_VP8_VLD, kSquare4k);

  const auto supported_resolutions = GetSupportedD3D11VideoDecoderResolutions(
      mock_d3d11_device_, gpu_workarounds_);
  auto it = supported_resolutions.find(VP8PROFILE_ANY);
  ASSERT_NE(it, supported_resolutions.end());
  EXPECT_EQ(kSquare4k, it->second.max_landscape_resolution);
  EXPECT_EQ(kSquare4k, it->second.max_portrait_resolution);

  constexpr gfx::Size kMinVp8Resolution = gfx::Size(640, 480);
  EXPECT_EQ(kMinVp8Resolution, it->second.min_resolution);
}

TEST_F(SupportedResolutionResolverTest, VP9Profile0Supports8k) {
  DONT_RUN_ON_WIN_7();
  TestDecoderSupport(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0,
                     VP9PROFILE_PROFILE0, kSquare8k, kSquare8k, kSquare8k);
}

TEST_F(SupportedResolutionResolverTest, VP9Profile2Supports8k) {
  DONT_RUN_ON_WIN_7();
  TestDecoderSupport(D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2,
                     VP9PROFILE_PROFILE2, kSquare8k, kSquare8k, kSquare8k);
}

TEST_F(SupportedResolutionResolverTest, MultipleCodecs) {
  DONT_RUN_ON_WIN_7();

  SetGpuProfile(kRecentAmdGpu);

  // H.264 and VP9.0 are the most common supported codecs.
  EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT,
                  D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0});
  SetMaxResolution(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, kSquare8k);

  const auto supported_resolutions = GetSupportedD3D11VideoDecoderResolutions(
      mock_d3d11_device_, gpu_workarounds_);

  ASSERT_EQ(base::size(kSupportedH264Profiles) + 1,
            supported_resolutions.size());
  for (const auto profile : kSupportedH264Profiles) {
    auto it = supported_resolutions.find(profile);
    ASSERT_NE(it, supported_resolutions.end());
    EXPECT_EQ(kMinResolution, it->second.min_resolution);
    EXPECT_EQ(kSquare4k, it->second.max_landscape_resolution);
    EXPECT_EQ(kSquare4k, it->second.max_portrait_resolution);
  }

  auto it = supported_resolutions.find(VP9PROFILE_PROFILE0);
  ASSERT_NE(it, supported_resolutions.end());
  EXPECT_EQ(kMinResolution, it->second.min_resolution);
  EXPECT_EQ(kSquare8k, it->second.max_landscape_resolution);
  EXPECT_EQ(kSquare8k, it->second.max_portrait_resolution);
}

TEST_F(SupportedResolutionResolverTest, AV1ProfileMainSupports8k) {
  DONT_RUN_ON_WIN_7();

  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(kMediaFoundationAV1Decoding);
  TestDecoderSupport(DXVA_ModeAV1_VLD_Profile0, AV1PROFILE_PROFILE_MAIN,
                     kSquare8k, kSquare8k, kSquare8k);
}

TEST_F(SupportedResolutionResolverTest, AV1ProfileHighSupports8k) {
  DONT_RUN_ON_WIN_7();

  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(kMediaFoundationAV1Decoding);
  TestDecoderSupport(DXVA_ModeAV1_VLD_Profile1, AV1PROFILE_PROFILE_HIGH,
                     kSquare8k, kSquare8k, kSquare8k);
}

TEST_F(SupportedResolutionResolverTest, AV1ProfileProSupports8k) {
  DONT_RUN_ON_WIN_7();

  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(kMediaFoundationAV1Decoding);
  TestDecoderSupport(DXVA_ModeAV1_VLD_Profile2, AV1PROFILE_PROFILE_PRO,
                     kSquare8k, kSquare8k, kSquare8k);
}

}  // namespace media
