// 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/d3d11_decoder_configurator.h"

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

#include "base/feature_list.h"
#include "media/base/media_log.h"
#include "media/base/media_switches.h"
#include "media/base/status_codes.h"
#include "media/base/win/hresult_status_helper.h"
#include "media/base/win/mf_helpers.h"
#include "media/gpu/windows/av1_guids.h"
#include "media/gpu/windows/d3d11_copying_texture_wrapper.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gl/direct_composition_surface_win.h"

namespace media {

D3D11DecoderConfigurator::D3D11DecoderConfigurator(
    DXGI_FORMAT decoder_output_dxgifmt,
    GUID decoder_guid,
    gfx::Size coded_size,
    bool is_encrypted,
    bool supports_swap_chain)
    : dxgi_format_(decoder_output_dxgifmt),
      decoder_guid_(decoder_guid),
      supports_swap_chain_(supports_swap_chain),
      is_encrypted_(is_encrypted) {
  SetUpDecoderDescriptor(coded_size);
  SetUpTextureDescriptor();
}

// static
std::unique_ptr<D3D11DecoderConfigurator> D3D11DecoderConfigurator::Create(
    const gpu::GpuPreferences& gpu_preferences,
    const gpu::GpuDriverBugWorkarounds& workarounds,
    const VideoDecoderConfig& config,
    uint8_t bit_depth,
    MediaLog* media_log,
    bool use_shared_handle) {
  // Decoder swap chains do not support shared resources. More info in
  // https://crbug.com/911847. To enable Kaby Lake+ systems for using shared
  // handle, we disable decode swap chain support if shared handle is enabled.
  const bool supports_nv12_decode_swap_chain =
      gl::DirectCompositionSurfaceWin::IsDecodeSwapChainSupported() &&
      !use_shared_handle;
  const auto decoder_dxgi_format =
      bit_depth == 8 ? DXGI_FORMAT_NV12 : DXGI_FORMAT_P010;
  GUID decoder_guid = {};
  if (config.codec() == VideoCodec::kH264) {
    decoder_guid = D3D11_DECODER_PROFILE_H264_VLD_NOFGT;
  } else if (config.profile() == VP9PROFILE_PROFILE0) {
    decoder_guid = D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0;
  } else if (config.profile() == VP9PROFILE_PROFILE2) {
    decoder_guid = D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2;
  } else if (config.profile() == AV1PROFILE_PROFILE_MAIN) {
    decoder_guid = DXVA_ModeAV1_VLD_Profile0;
  } else if (config.profile() == AV1PROFILE_PROFILE_HIGH) {
    decoder_guid = DXVA_ModeAV1_VLD_Profile1;
  } else if (config.profile() == AV1PROFILE_PROFILE_PRO) {
    decoder_guid = DXVA_ModeAV1_VLD_Profile2;
  } else {
    MEDIA_LOG(INFO, media_log)
        << "D3D11VideoDecoder does not support codec " << config.codec();
    return nullptr;
  }

  MEDIA_LOG(INFO, media_log)
      << "D3D11VideoDecoder is using " << GetProfileName(config.profile())
      << " / " << (decoder_dxgi_format == DXGI_FORMAT_NV12 ? "NV12" : "P010");

  return std::make_unique<D3D11DecoderConfigurator>(
      decoder_dxgi_format, decoder_guid, config.coded_size(),
      config.is_encrypted(), supports_nv12_decode_swap_chain);
}

bool D3D11DecoderConfigurator::SupportsDevice(
    ComD3D11VideoDevice video_device) {
  for (UINT i = video_device->GetVideoDecoderProfileCount(); i--;) {
    GUID profile = {};
    if (SUCCEEDED(video_device->GetVideoDecoderProfile(i, &profile))) {
      if (profile == decoder_guid_)
        return true;
    }
  }
  return false;
}

StatusOr<ComD3D11Texture2D> D3D11DecoderConfigurator::CreateOutputTexture(
    ComD3D11Device device,
    gfx::Size size,
    uint32_t array_size,
    bool use_shared_handle) {
  output_texture_desc_.Width = size.width();
  output_texture_desc_.Height = size.height();
  output_texture_desc_.ArraySize = array_size;

  if (use_shared_handle) {
    // Update the decoder output texture usage to support shared handle and
    // keyed_mutex if required. SwapChain should be disabled and the frame
    // shouldn't be encrypted.
    DCHECK(!supports_swap_chain_);
    DCHECK(!is_encrypted_);
    output_texture_desc_.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE |
                                     D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
  } else if (supports_swap_chain_) {
    // Decode swap chains do not support shared resources.
    // TODO(sunnyps): Find a workaround for when the decoder moves to its own
    // thread and D3D device.  See https://crbug.com/911847
    // TODO(liberato): This depends on the configuration of the TextureSelector,
    // to some degree. We should unset the flag only if it's binding and the
    // decode swap chain is supported, as Intel driver is buggy on Gen9 and
    // older devices without the flag. See https://crbug.com/1107403
    output_texture_desc_.MiscFlags = 0;
  } else {
    // Create non-shareable texture for d3d11 video decoder.
    output_texture_desc_.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
  }

  if (is_encrypted_)
    output_texture_desc_.MiscFlags |= D3D11_RESOURCE_MISC_HW_PROTECTED;

  ComD3D11Texture2D texture;
  HRESULT hr =
      device->CreateTexture2D(&output_texture_desc_, nullptr, &texture);
  if (FAILED(hr)) {
    return Status(StatusCode::kCreateDecoderOutputTextureFailed)
        .AddCause(HresultToStatus(hr));
  }
  hr = SetDebugName(texture.Get(), "D3D11Decoder_ConfiguratorOutput");
  if (FAILED(hr)) {
    return Status(StatusCode::kCreateDecoderOutputTextureFailed)
        .AddCause(HresultToStatus(hr));
  }
  return texture;
}

// private
void D3D11DecoderConfigurator::SetUpDecoderDescriptor(
    const gfx::Size& coded_size) {
  decoder_desc_ = {};
  decoder_desc_.Guid = decoder_guid_;
  decoder_desc_.SampleWidth = coded_size.width();
  decoder_desc_.SampleHeight = coded_size.height();
  decoder_desc_.OutputFormat = dxgi_format_;
}

// private
void D3D11DecoderConfigurator::SetUpTextureDescriptor() {
  output_texture_desc_ = {};
  output_texture_desc_.MipLevels = 1;
  output_texture_desc_.Format = dxgi_format_;
  output_texture_desc_.SampleDesc.Count = 1;
  output_texture_desc_.Usage = D3D11_USAGE_DEFAULT;
  output_texture_desc_.BindFlags =
      D3D11_BIND_DECODER | D3D11_BIND_SHADER_RESOURCE;
}

}  // namespace media
