// Copyright 2019 The Chromium Authors
// 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 <algorithm>
#include <limits>
#include <memory>
#include <utility>

#include <d3d9.h>
#include <dxva2api.h>

#include "base/feature_list.h"
#include "base/trace_event/trace_event.h"
#include "base/win/windows_version.h"
#include "media/base/media_switches.h"
#include "media/gpu/windows/av1_guids.h"

namespace {

// Windows Media Foundation H.264 decoding does not support decoding videos
// with any dimension smaller than 48 pixels:
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815
//
// TODO(dalecurtis): These values are too low. We should only be using
// hardware decode for videos above ~360p, see http://crbug.com/684792.
constexpr gfx::Size kMinResolution(64, 64);

bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test,
                                    const GUID& decoder_guid,
                                    ID3D11VideoDevice* video_device,
                                    DXGI_FORMAT format) {
  D3D11_VIDEO_DECODER_DESC desc = {
      decoder_guid,                                    // Guid
      static_cast<UINT>(resolution_to_test.width()),   // SampleWidth
      static_cast<UINT>(resolution_to_test.height()),  // SampleHeight
      format                                           // OutputFormat
  };

  // We've chosen the least expensive test for identifying if a given resolution
  // is supported. Actually creating the VideoDecoder instance only fails ~0.4%
  // of the time and the outcome is that we will offer support and then
  // immediately fall back to software; e.g., playback still works. Since these
  // calls can take hundreds of milliseconds to complete and are often executed
  // during startup, this seems a reasonably trade off.
  //
  // See the deprecated histograms Media.DXVAVDA.GetDecoderConfigStatus which
  // succeeds 100% of the time and Media.DXVAVDA.CreateDecoderStatus which
  // only succeeds 99.6% of the time (in a 28 day aggregation).
  UINT config_count;
  return SUCCEEDED(
             video_device->GetVideoDecoderConfigCount(&desc, &config_count)) &&
         config_count > 0;
}

media::SupportedResolutionRange GetResolutionsForGUID(
    ID3D11VideoDevice* video_device,
    const GUID& decoder_guid,
    const std::vector<gfx::Size>& resolutions_to_test,
    DXGI_FORMAT format = DXGI_FORMAT_NV12,
    const gfx::Size& min_resolution = kMinResolution) {
  media::SupportedResolutionRange result;

  // Verify input is in ascending order by height.
  DCHECK(std::is_sorted(resolutions_to_test.begin(), resolutions_to_test.end(),
                        [](const gfx::Size& a, const gfx::Size& b) {
                          return a.height() < b.height();
                        }));

  for (const auto& res : resolutions_to_test) {
    if (!IsResolutionSupportedForDevice(res, decoder_guid, video_device,
                                        format)) {
      break;
    }
    result.max_landscape_resolution = res;
  }

  // The max supported portrait resolution should be just be a w/h flip of the
  // max supported landscape resolution.
  const gfx::Size flipped(result.max_landscape_resolution.height(),
                          result.max_landscape_resolution.width());
  if (flipped == result.max_landscape_resolution ||
      IsResolutionSupportedForDevice(flipped, decoder_guid, video_device,
                                     format)) {
    result.max_portrait_resolution = flipped;
  }

  if (!result.max_landscape_resolution.IsEmpty())
    result.min_resolution = min_resolution;

  return result;
}

}  // namespace

namespace media {

SupportedResolutionRangeMap GetSupportedD3D11VideoDecoderResolutions(
    ComD3D11Device device,
    const gpu::GpuDriverBugWorkarounds& workarounds) {
  TRACE_EVENT0("gpu,startup", "GetSupportedD3D11VideoDecoderResolutions");
  SupportedResolutionRangeMap supported_resolutions;

  // We always insert support for H.264 regardless of the tests below. It's old
  // enough to be ubiquitous.
  //
  // On Windows 7 the maximum resolution supported by media foundation is
  // 1920 x 1088. We use 1088 to account for 16x16 macro-blocks.
  constexpr gfx::Size kDefaultMaxH264Resolution(1920, 1088);
  SupportedResolutionRange h264_profile;
  h264_profile.min_resolution = kMinResolution;
  h264_profile.max_landscape_resolution = kDefaultMaxH264Resolution;

  // We don't have a way to map DXVA support to specific H.264 profiles, so just
  // mark all the common ones with the same level of support.
  constexpr VideoCodecProfile kSupportedH264Profiles[] = {
      H264PROFILE_BASELINE, H264PROFILE_MAIN, H264PROFILE_HIGH};
  for (const auto profile : kSupportedH264Profiles)
    supported_resolutions[profile] = h264_profile;

  if (!device)
    return supported_resolutions;

  // To detect if a driver supports the desired resolutions, we try and create
  // a DXVA decoder instance for that resolution and profile. If that succeeds
  // we assume that the driver supports decoding for that resolution.
  // Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while
  // creating surfaces larger than 1920 x 1088.
  ComD3D11VideoDevice video_device;
  if (FAILED(device.As(&video_device)))
    return supported_resolutions;

  const std::vector<gfx::Size> kModernResolutions = {
      gfx::Size(4096, 2160), gfx::Size(4096, 2304), gfx::Size(7680, 4320),
      gfx::Size(8192, 4320), gfx::Size(8192, 8192)};

  // Enumerate supported video profiles and look for the known profile for each
  // codec. We first look through the the decoder profiles so we don't run N
  // resolution tests for a profile that's unsupported.
  UINT profile_count = video_device->GetVideoDecoderProfileCount();
  for (UINT i = 0; i < profile_count; i++) {
    GUID profile_id;
    if (FAILED(video_device->GetVideoDecoderProfile(i, &profile_id)))
      continue;

    if (profile_id == D3D11_DECODER_PROFILE_H264_VLD_NOFGT) {
      const auto result = GetResolutionsForGUID(
          video_device.Get(), profile_id,
          {gfx::Size(2560, 1440), gfx::Size(3840, 2160), gfx::Size(4096, 2160),
           gfx::Size(4096, 2304), gfx::Size(4096, 4096)});

      // Unlike the other codecs, H.264 support is assumed up to 1080p, even if
      // our initial queries fail. If they fail, we use the defaults set above.
      if (!result.max_landscape_resolution.IsEmpty()) {
        for (const auto profile : kSupportedH264Profiles)
          supported_resolutions[profile] = result;
      }
      continue;
    }

    // Note: Each bit depth of AV1 uses a different DXGI_FORMAT, here we only
    // test for the 8-bit one (NV12).
    if (!workarounds.disable_accelerated_av1_decode) {
      if (profile_id == DXVA_ModeAV1_VLD_Profile0) {
        supported_resolutions[AV1PROFILE_PROFILE_MAIN] = GetResolutionsForGUID(
            video_device.Get(), profile_id, kModernResolutions);
        continue;
      }
      if (profile_id == DXVA_ModeAV1_VLD_Profile1) {
        supported_resolutions[AV1PROFILE_PROFILE_HIGH] = GetResolutionsForGUID(
            video_device.Get(), profile_id, kModernResolutions);
        continue;
      }
      if (profile_id == DXVA_ModeAV1_VLD_Profile2) {
        // TODO(dalecurtis): 12-bit profile 2 support is complicated. Ideally,
        // we should test DXVA_ModeAV1_VLD_12bit_Profile2 and
        // DXVA_ModeAV1_VLD_12bit_Profile2_420 when the bit depth of the content
        // is 12-bit. However we don't know the bit depth or pixel format until
        // too late. In these cases we'll end up initializing the decoder and
        // failing on the first decode (which will trigger software fallback).
        supported_resolutions[AV1PROFILE_PROFILE_PRO] = GetResolutionsForGUID(
            video_device.Get(), profile_id, kModernResolutions);
        continue;
      }
    }

    if (!workarounds.disable_accelerated_vp9_decode) {
      if (profile_id == D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0) {
        supported_resolutions[VP9PROFILE_PROFILE0] = GetResolutionsForGUID(
            video_device.Get(), profile_id, kModernResolutions);
        continue;
      }

      // RS3 has issues with VP9.2 decoding. See https://crbug.com/937108.
      if (!workarounds.disable_accelerated_vp9_profile2_decode &&
          profile_id == D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2 &&
          base::win::GetVersion() != base::win::Version::WIN10_RS3) {
        supported_resolutions[VP9PROFILE_PROFILE2] =
            GetResolutionsForGUID(video_device.Get(), profile_id,
                                  kModernResolutions, DXGI_FORMAT_P010);
        continue;
      }
    }

    if (!workarounds.disable_accelerated_vp8_decode &&
        profile_id == D3D11_DECODER_PROFILE_VP8_VLD &&
        base::FeatureList::IsEnabled(kMediaFoundationVP8Decoding)) {
      // VP8 decoding is cheap on modern devices compared to other codecs, so
      // much so that hardware decoding performance is actually worse at low
      // resolutions than software decoding. See https://crbug.com/1136495.
      constexpr gfx::Size kMinVp8Resolution = gfx::Size(640, 480);

      supported_resolutions[VP8PROFILE_ANY] = GetResolutionsForGUID(
          video_device.Get(), profile_id,
          {gfx::Size(4096, 2160), gfx::Size(4096, 2304), gfx::Size(4096, 4096)},
          DXGI_FORMAT_NV12, kMinVp8Resolution);
      continue;
    }

#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
    if (!workarounds.disable_accelerated_hevc_decode &&
        base::FeatureList::IsEnabled(kPlatformHEVCDecoderSupport)) {
      if (profile_id == D3D11_DECODER_PROFILE_HEVC_VLD_MAIN) {
        supported_resolutions[HEVCPROFILE_MAIN] = GetResolutionsForGUID(
            video_device.Get(), profile_id, kModernResolutions);
        continue;
      }
      // For range extensions only test main10_422 with P010, and apply
      // the same resolution range to main420 & main10_YUV420. Ideally we
      // should be also testing against NV12 & Y210 for YUV422, and Y410 for
      // YUV444 8/10/12 bit.
      if (profile_id == DXVA_ModeHEVC_VLD_Main422_10_Intel) {
        supported_resolutions[HEVCPROFILE_REXT] =
            GetResolutionsForGUID(video_device.Get(), profile_id,
                                  kModernResolutions, DXGI_FORMAT_P010);
        continue;
      }
      if (profile_id == D3D11_DECODER_PROFILE_HEVC_VLD_MAIN10) {
        supported_resolutions[HEVCPROFILE_MAIN10] =
            GetResolutionsForGUID(video_device.Get(), profile_id,
                                  kModernResolutions, DXGI_FORMAT_P010);
        continue;
      }
    }
#endif  // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
  }

  return supported_resolutions;
}

}  // namespace media
