// Copyright 2013 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/vaapi/vaapi_wrapper.h"

#include <dlfcn.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <va/va.h>
#include <va/va_drm.h>
#include <va/va_drmcommon.h>
#include <va/va_str.h>
#include <va/va_version.h>
#include <xf86drm.h>

#include <algorithm>
#include <string>
#include <type_traits>
#include <utility>

#include "base/bind.h"
#include "base/bits.h"
#include "base/callback_helpers.h"
#include "base/containers/contains.h"
#include "base/containers/cxx20_erase.h"
#include "base/cpu.h"
#include "base/cxx17_backports.h"
#include "base/environment.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/pattern.h"
#include "base/strings/string_util.h"
#include "base/system/sys_info.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "ui/base/ui_base_features.h"

#include "media/base/media_switches.h"
#include "media/base/video_frame.h"
#include "media/base/video_types.h"
#include "media/gpu/macros.h"
#include "media/media_buildflags.h"

// Auto-generated for dlopen libva libraries
#include "media/gpu/vaapi/va_stubs.h"

#include "third_party/libva_protected_content/va_protected_content.h"
#include "third_party/libyuv/include/libyuv.h"
#include "third_party/minigbm/src/external/i915_drm.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/linux/native_pixmap_dmabuf.h"
#include "ui/gfx/native_pixmap.h"
#include "ui/gfx/native_pixmap_handle.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_implementation.h"

#if BUILDFLAG(USE_VAAPI_X11)
typedef XID Drawable;

extern "C" {
#include "media/gpu/vaapi/va_x11.sigs"
}

#include "ui/gfx/x/connection.h"  // nogncheck
#endif                            // BUILDFLAG(USE_VAAPI_X11)

#if defined(USE_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/surface_factory_ozone.h"
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include <va/va_prot.h>
using media_gpu_vaapi::kModuleVa_prot;
#endif

using media_gpu_vaapi::kModuleVa;
using media_gpu_vaapi::kModuleVa_drm;
#if BUILDFLAG(USE_VAAPI_X11)
using media_gpu_vaapi::kModuleVa_x11;
#endif  // BUILDFLAG(USE_VAAPI_X11)
using media_gpu_vaapi::InitializeStubs;
using media_gpu_vaapi::IsVaInitialized;
#if BUILDFLAG(USE_VAAPI_X11)
using media_gpu_vaapi::IsVa_x11Initialized;
#endif  // BUILDFLAG(USE_VAAPI_X11)
using media_gpu_vaapi::IsVa_drmInitialized;
using media_gpu_vaapi::StubPathMap;

namespace media {

// These values are logged to UMA. Entries should not be renumbered and numeric
// values should never be reused. Please keep in sync with
// "VaapiFunctions" in src/tools/metrics/histograms/enums.xml.
enum class VaapiFunctions {
  kVABeginPicture = 0,
  kVACreateBuffer = 1,
  kVACreateConfig = 2,
  kVACreateContext = 3,
  kVACreateImage = 4,
  kVACreateSurfaces_Allocating = 5,
  kVACreateSurfaces_Importing = 6,
  kVADestroyBuffer = 7,
  kVADestroyConfig = 8,
  kVADestroyContext = 9,
  kVADestroySurfaces = 10,
  kVAEndPicture = 11,
  kVAExportSurfaceHandle = 12,
  kVAGetConfigAttributes = 13,
  kVAPutImage = 14,
  kVAPutSurface = 15,
  kVAQueryConfigAttributes = 16,
  kVAQueryImageFormats = 17,
  kVAQuerySurfaceAttributes = 18,
  kVAQueryVideoProcPipelineCaps = 19,
  kVARenderPicture_VABuffers = 20,
  kVARenderPicture_Vpp = 21,
  kVASyncSurface = 22,
  kVATerminate = 23,
  kVAUnmapBuffer = 24,
  // Protected mode functions below.
  kVACreateProtectedSession = 25,
  kVADestroyProtectedSession = 26,
  kVAAttachProtectedSession = 27,
  kVADetachProtectedSession = 28,
  kVAProtectedSessionHwUpdate_Deprecated = 29,
  kVAProtectedSessionExecute = 30,
  // Anything else is captured in this last entry.
  kOtherVAFunction = 31,
  kMaxValue = kOtherVAFunction,
};

void ReportVaapiErrorToUMA(const std::string& histogram_name,
                           VaapiFunctions value) {
  UMA_HISTOGRAM_ENUMERATION(histogram_name, value);
}

constexpr std::array<const char*,
                     static_cast<size_t>(VaapiFunctions::kMaxValue) + 1>
    kVaapiFunctionNames = {"vaBeginPicture",
                           "vaCreateBuffer",
                           "vaCreateConfig",
                           "vaCreateContext",
                           "vaCreateImage",
                           "vaCreateSurfaces (allocate mode)",
                           "vaCreateSurfaces (import mode)",
                           "vaDestroyBuffer",
                           "vaDestroyConfig",
                           "vaDestroyContext",
                           "vaDestroySurfaces",
                           "vaEndPicture",
                           "vaExportSurfaceHandle",
                           "vaGetConfigAttributes",
                           "vaPutImage",
                           "vaPutSurface",
                           "vaQueryConfigAttributes",
                           "vaQueryImageFormats",
                           "vaQuerySurfaceAttributes",
                           "vaQueryVideoProcPipelineCaps",
                           "vaRenderPicture (|pending_va_buffers_|)",
                           "vaRenderPicture using Vpp",
                           "vaSyncSurface",
                           "vaTerminate",
                           "vaUnmapBuffer",
                           "vaCreateProtectedSession",
                           "vaDestroyProtectedSession",
                           "vaAttachProtectedSession",
                           "vaDetachProtectedSession",
                           "vaProtectedSessionHwUpdate (Deprecated)",
                           "vaProtectedSessionExecute",
                           "Other VA function"};

// Translates |function| into a human readable string for logging.
const char* VaapiFunctionName(VaapiFunctions function) {
  DCHECK(function <= VaapiFunctions::kMaxValue);
  return kVaapiFunctionNames[static_cast<size_t>(function)];
}

}  // namespace media

#define LOG_VA_ERROR_AND_REPORT(va_error, function)              \
  do {                                                           \
    LOG(ERROR) << VaapiFunctionName(function)                    \
               << " failed, VA error: " << vaErrorStr(va_error); \
    report_error_to_uma_cb_.Run(function);                       \
  } while (0)

#define VA_LOG_ON_ERROR(va_res, function)                        \
  do {                                                           \
    const VAStatus va_res_va_log_on_error = (va_res);            \
    if (va_res_va_log_on_error != VA_STATUS_SUCCESS)             \
      LOG_VA_ERROR_AND_REPORT(va_res_va_log_on_error, function); \
  } while (0)

#define VA_SUCCESS_OR_RETURN(va_res, function, ret)                  \
  do {                                                               \
    const VAStatus va_res_va_sucess_or_return = (va_res);            \
    if (va_res_va_sucess_or_return != VA_STATUS_SUCCESS) {           \
      LOG_VA_ERROR_AND_REPORT(va_res_va_sucess_or_return, function); \
      return (ret);                                                  \
    }                                                                \
    DVLOG(3) << VaapiFunctionName(function);                         \
  } while (0)

namespace {

uint32_t BufferFormatToVAFourCC(gfx::BufferFormat fmt) {
  switch (fmt) {
    case gfx::BufferFormat::BGRX_8888:
      return VA_FOURCC_BGRX;
    case gfx::BufferFormat::BGRA_8888:
      return VA_FOURCC_BGRA;
    case gfx::BufferFormat::RGBX_8888:
      return VA_FOURCC_RGBX;
    case gfx::BufferFormat::RGBA_8888:
      return VA_FOURCC_RGBA;
    case gfx::BufferFormat::YVU_420:
      return VA_FOURCC_YV12;
    case gfx::BufferFormat::YUV_420_BIPLANAR:
      return VA_FOURCC_NV12;
    case gfx::BufferFormat::P010:
      return VA_FOURCC_P010;
    default:
      NOTREACHED() << gfx::BufferFormatToString(fmt);
      return 0;
  }
}

media::VAImplementation VendorStringToImplementationType(
    const std::string& va_vendor_string) {
  if (base::StartsWith(va_vendor_string, "Mesa Gallium driver",
                       base::CompareCase::SENSITIVE)) {
    return media::VAImplementation::kMesaGallium;
  } else if (base::StartsWith(va_vendor_string, "Intel i965 driver",
                              base::CompareCase::SENSITIVE)) {
    return media::VAImplementation::kIntelI965;
  } else if (base::StartsWith(va_vendor_string, "Intel iHD driver",
                              base::CompareCase::SENSITIVE)) {
    return media::VAImplementation::kIntelIHD;
  }
  return media::VAImplementation::kOther;
}

}  // namespace

namespace media {

namespace {
// VAEntrypoint is an enumeration starting from 1, but has no "invalid" value.
constexpr VAEntrypoint kVAEntrypointInvalid = static_cast<VAEntrypoint>(0);

// Returns true if the SoC has a Gen8 GPU. CPU model ID's are referenced from
// the following file in the kernel source: arch/x86/include/asm/intel-family.h.
bool IsGen8Gpu() {
  constexpr int kPentiumAndLaterFamily = 0x06;
  constexpr int kBroadwellCoreModelId = 0x3D;
  constexpr int kBroadwellGT3EModelId = 0x47;
  constexpr int kBroadwellXModelId = 0x4F;
  constexpr int kBroadwellXeonDModelId = 0x56;
  constexpr int kBraswellModelId = 0x4C;
  static const base::NoDestructor<base::CPU> cpuid;
  static const bool is_gen8_gpu = cpuid->family() == kPentiumAndLaterFamily &&
                                  (cpuid->model() == kBroadwellCoreModelId ||
                                   cpuid->model() == kBroadwellGT3EModelId ||
                                   cpuid->model() == kBroadwellXModelId ||
                                   cpuid->model() == kBroadwellXeonDModelId ||
                                   cpuid->model() == kBraswellModelId);
  return is_gen8_gpu;
}

// Returns true if the SoC has a Gen9 GPU. CPU model ID's are referenced from
// the following file in the kernel source: arch/x86/include/asm/intel-family.h.
bool IsGen9Gpu() {
  constexpr int kPentiumAndLaterFamily = 0x06;
  constexpr int kSkyLakeModelId = 0x5E;
  constexpr int kSkyLake_LModelId = 0x4E;
  constexpr int kApolloLakeModelId = 0x5c;
  static const base::NoDestructor<base::CPU> cpuid;
  static const bool is_gen9_gpu = cpuid->family() == kPentiumAndLaterFamily &&
                                  (cpuid->model() == kSkyLakeModelId ||
                                   cpuid->model() == kSkyLake_LModelId ||
                                   cpuid->model() == kApolloLakeModelId);
  return is_gen9_gpu;
}

// Returns true if the SoC has a 9.5 GPU. CPU model IDs are referenced from the
// following file in the kernel source:  arch/x86/include/asm/intel-family.h.
bool IsGen95Gpu() {
  constexpr int kPentiumAndLaterFamily = 0x06;
  constexpr int kKabyLakeModelId = 0x9E;
  // Amber Lake, Whiskey Lake and some Comet Lake CPU IDs are the same as KBL L.
  constexpr int kKabyLake_LModelId = 0x8E;
  constexpr int kGeminiLakeModelId = 0x7A;
  constexpr int kCometLakeModelId = 0xA5;
  constexpr int kCometLake_LModelId = 0xA6;
  static const base::NoDestructor<base::CPU> cpuid;
  static const bool is_gen95_gpu = cpuid->family() == kPentiumAndLaterFamily &&
                                   (cpuid->model() == kKabyLakeModelId ||
                                    cpuid->model() == kKabyLake_LModelId ||
                                    cpuid->model() == kGeminiLakeModelId ||
                                    cpuid->model() == kCometLakeModelId ||
                                    cpuid->model() == kCometLake_LModelId);
  return is_gen95_gpu;
}

// Returns true if the intel hybrid driver is used for decoding |va_profile|.
// https://github.com/intel/intel-hybrid-driver
// Note that since the hybrid driver runs as a part of the i965 driver,
// vaQueryVendorString() returns "Intel i965 driver".
bool IsUsingHybridDriverForDecoding(VAProfile va_profile) {
  // Note that Skylake (not gen8) also needs the hybrid decoder for VP9
  // decoding. However, it is disabled today on ChromeOS
  // (see crrev.com/c/390511).
  return va_profile == VAProfileVP9Profile0 && IsGen8Gpu();
}

// Returns true if the SoC is considered a low power one, i.e. it's an Intel
// Pentium, Celeron, or a Core Y-series. See go/intel-socs-101 or
// https://www.intel.com/content/www/us/en/processors/processor-numbers.html.
bool IsLowPowerIntelProcessor() {
  constexpr int kPentiumAndLaterFamily = 0x06;
  static const base::NoDestructor<base::CPU> cpuid;
  static const bool is_core_y_processor =
      base::MatchPattern(cpuid->cpu_brand(), "Intel(R) Core(TM) *Y CPU*");

  static const bool is_low_power_intel =
      cpuid->family() == kPentiumAndLaterFamily &&
      (base::Contains(cpuid->cpu_brand(), "Pentium") ||
       base::Contains(cpuid->cpu_brand(), "Celeron") || is_core_y_processor);
  return is_low_power_intel;
}

bool IsModeEncoding(VaapiWrapper::CodecMode mode) {
  return mode == VaapiWrapper::CodecMode::kEncodeConstantBitrate ||
         mode == VaapiWrapper::CodecMode::kEncodeConstantQuantizationParameter;
}

bool GetNV12VisibleWidthBytes(int visible_width,
                              uint32_t plane,
                              size_t* bytes) {
  if (plane == 0) {
    *bytes = base::checked_cast<size_t>(visible_width);
    return true;
  }

  *bytes = base::checked_cast<size_t>(visible_width);
  return visible_width % 2 == 0 ||
         base::CheckAdd<int>(visible_width, 1).AssignIfValid(bytes);
}

// Fill 0 on VAImage's non visible area.
bool ClearNV12Padding(const VAImage& image,
                      const gfx::Size& visible_size,
                      uint8_t* data) {
  DCHECK_EQ(2u, image.num_planes);
  DCHECK_EQ(image.format.fourcc, static_cast<uint32_t>(VA_FOURCC_NV12));

  size_t visible_width_bytes[2] = {};
  if (!GetNV12VisibleWidthBytes(visible_size.width(), 0u,
                                &visible_width_bytes[0]) ||
      !GetNV12VisibleWidthBytes(visible_size.width(), 1u,
                                &visible_width_bytes[1])) {
    return false;
  }

  for (uint32_t plane = 0; plane < image.num_planes; plane++) {
    size_t row_bytes = base::strict_cast<size_t>(image.pitches[plane]);
    if (row_bytes == visible_width_bytes[plane])
      continue;

    CHECK_GT(row_bytes, visible_width_bytes[plane]);
    int visible_height = visible_size.height();
    if (plane == 1 && !(base::CheckAdd<int>(visible_size.height(), 1) / 2)
                           .AssignIfValid(&visible_height)) {
      return false;
    }

    const size_t padding_bytes = row_bytes - visible_width_bytes[plane];
    uint8_t* plane_data = data + image.offsets[plane];
    for (int row = 0; row < visible_height; row++, plane_data += row_bytes)
      memset(plane_data + visible_width_bytes[plane], 0, padding_bytes);

    CHECK_GE(base::strict_cast<int>(image.height), visible_height);
    size_t image_height = base::strict_cast<size_t>(image.height);
    if (plane == 1 && !(base::CheckAdd<size_t>(image.height, 1) / 2)
                           .AssignIfValid(&image_height)) {
      return false;
    }

    base::CheckedNumeric<size_t> remaining_area(image_height);
    remaining_area -= base::checked_cast<size_t>(visible_height);
    remaining_area *= row_bytes;
    if (!remaining_area.IsValid())
      return false;
    memset(plane_data, 0, remaining_area.ValueOrDie());
  }

  return true;
}

// Can't statically initialize the profile map:
// https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
using ProfileCodecMap = std::map<VideoCodecProfile, VAProfile>;
const ProfileCodecMap& GetProfileCodecMap() {
  static const base::NoDestructor<ProfileCodecMap> kMediaToVAProfileMap({
      // VAProfileH264Baseline is deprecated in <va/va.h> since libva 2.0.0.
      {H264PROFILE_BASELINE, VAProfileH264ConstrainedBaseline},
          {H264PROFILE_MAIN, VAProfileH264Main},
          // TODO(posciak): See if we can/want to support other variants of
          // H264PROFILE_HIGH*.
          {H264PROFILE_HIGH, VAProfileH264High},
          {VP8PROFILE_ANY, VAProfileVP8Version0_3},
          {VP9PROFILE_PROFILE0, VAProfileVP9Profile0},
          // VaapiWrapper does not support VP9 Profile 1, see b/153680337.
          // {VP9PROFILE_PROFILE1, VAProfileVP9Profile1},
          {VP9PROFILE_PROFILE2, VAProfileVP9Profile2},
      // VaapiWrapper does not support Profile 3.
      //{VP9PROFILE_PROFILE3, VAProfileVP9Profile3},
          {AV1PROFILE_PROFILE_MAIN, VAProfileAV1Profile0},
        // VaapiWrapper does not support AV1 Profile 1.
        // {AV1PROFILE_PROFILE_HIGH, VAProfileAV1Profile1},
#if BUILDFLAG(ENABLE_PLATFORM_HEVC_DECODING)
          {HEVCPROFILE_MAIN, VAProfileHEVCMain},
          {HEVCPROFILE_MAIN10, VAProfileHEVCMain10},
#endif
  });
  return *kMediaToVAProfileMap;
}

// Maps a VideoCodecProfile |profile| to a VAProfile, or VAProfileNone.
VAProfile ProfileToVAProfile(VideoCodecProfile profile,
                             VaapiWrapper::CodecMode mode) {
  const auto& profiles = GetProfileCodecMap();
  const auto& maybe_profile = profiles.find(profile);
  if (maybe_profile == profiles.end())
    return VAProfileNone;
  return maybe_profile->second;
}

bool IsVAProfileSupported(VAProfile va_profile) {
  const auto& profiles = GetProfileCodecMap();
  // VAProfileJPEGBaseline and VAProfileProtected are always recognized but are
  // not video codecs per se.
  return va_profile == VAProfileJPEGBaseline ||
#if BUILDFLAG(IS_CHROMEOS_ASH)
         va_profile == VAProfileProtected ||
#endif
         std::find_if(profiles.begin(), profiles.end(),
                      [va_profile](const auto& entry) {
                        return entry.second == va_profile;
                      }) != profiles.end();
}

bool IsBlockedDriver(VaapiWrapper::CodecMode mode, VAProfile va_profile) {
  if (!IsModeEncoding(mode)) {
    return va_profile == VAProfileAV1Profile0 &&
           !base::FeatureList::IsEnabled(kVaapiAV1Decoder);
  }

  // TODO(posciak): Remove once VP8 encoding is to be enabled by default.
  if (va_profile == VAProfileVP8Version0_3 &&
      !base::FeatureList::IsEnabled(kVaapiVP8Encoder)) {
    return true;
  }

  // TODO(crbug.com/811912): Remove once VP9 encoding is enabled by default.
  if (va_profile == VAProfileVP9Profile0 &&
      !base::FeatureList::IsEnabled(kVaapiVP9Encoder)) {
    return true;
  }

  return false;
}

// This class is a wrapper around its |va_display_| (and its associated
// |va_lock_|) to guarantee mutual exclusion and singleton behaviour.
class VADisplayState {
 public:
  static VADisplayState* Get();

  // Initialize static data before sandbox is enabled.
  static void PreSandboxInitialization();

  bool Initialize();
  VAStatus Deinitialize();

  base::Lock* va_lock() { return &va_lock_; }
  VADisplay va_display() const { return va_display_; }
  VAImplementation implementation_type() const { return implementation_type_; }

  void SetDrmFd(base::PlatformFile fd) { drm_fd_.reset(HANDLE_EINTR(dup(fd))); }
  base::ScopedFD GetDrmFd() {
    return base::ScopedFD(HANDLE_EINTR(dup(drm_fd_.get())));
  }

 private:
  friend class base::NoDestructor<VADisplayState>;

  VADisplayState();
  ~VADisplayState() = default;

  // Implementation of Initialize() called only once.
  bool InitializeOnce() EXCLUSIVE_LOCKS_REQUIRED(va_lock_);
  bool InitializeVaDisplay_Locked() EXCLUSIVE_LOCKS_REQUIRED(va_lock_);
  bool InitializeVaDriver_Locked() EXCLUSIVE_LOCKS_REQUIRED(va_lock_);

  int refcount_ GUARDED_BY(va_lock_);

  // Libva is not thread safe, so we have to do locking for it ourselves.
  // This lock is to be taken for the duration of all VA-API calls and for
  // the entire job submission sequence in ExecuteAndDestroyPendingBuffers().
  base::Lock va_lock_;

  // Drm fd used to obtain access to the driver interface by VA.
  base::ScopedFD drm_fd_;

  // The VADisplay handle. Valid between Initialize() and Deinitialize().
  VADisplay va_display_;

  // True if vaInitialize() has been called successfully, until Deinitialize().
  bool va_initialized_;

  // Enumerated version of vaQueryVendorString(). Valid after Initialize().
  VAImplementation implementation_type_ = VAImplementation::kInvalid;

  DISALLOW_COPY_AND_ASSIGN(VADisplayState);
};

// static
VADisplayState* VADisplayState::Get() {
  static base::NoDestructor<VADisplayState> display_state;
  return display_state.get();
}

// static
void VADisplayState::PreSandboxInitialization() {
  const char kDriRenderNode0Path[] = "/dev/dri/renderD128";
  base::File drm_file = base::File(
      base::FilePath::FromUTF8Unsafe(kDriRenderNode0Path),
      base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE);
  if (drm_file.IsValid())
    VADisplayState::Get()->SetDrmFd(drm_file.GetPlatformFile());
}

VADisplayState::VADisplayState()
    : refcount_(0), va_display_(nullptr), va_initialized_(false) {}

bool VADisplayState::Initialize() {
  base::AutoLock auto_lock(va_lock_);

#if defined(USE_OZONE) && defined(OS_LINUX)
  // TODO(crbug.com/1116701): add vaapi support for other Ozone platforms on
  // Linux. See comment in OzonePlatform::PlatformProperties::supports_vaapi
  // for more details. This will also require revisiting everything that's
  // guarded by USE_VAAPI_X11. For example, if USE_VAAPI_X11 is true, but the
  // user chooses the Wayland backend for Ozone at runtime, then many things (if
  // not all) that we do for X11 won't apply.
  if (!ui::OzonePlatform::GetInstance()->GetPlatformProperties().supports_vaapi)
    return false;
#endif

  bool libraries_initialized = IsVaInitialized() && IsVa_drmInitialized();
#if BUILDFLAG(USE_VAAPI_X11)
  libraries_initialized = libraries_initialized && IsVa_x11Initialized();
#endif
  if (!libraries_initialized)
    return false;

  // Manual refcounting to ensure the rest of the method is called only once.
  if (refcount_++ > 0)
    return true;

  const bool success = InitializeOnce();
  UMA_HISTOGRAM_BOOLEAN("Media.VaapiWrapper.VADisplayStateInitializeSuccess",
                        success);
  return success;
}

#if BUILDFLAG(USE_VAAPI_X11)

absl::optional<VADisplay> GetVADisplayStateX11(const base::ScopedFD& drm_fd) {
  switch (gl::GetGLImplementation()) {
    case gl::kGLImplementationEGLGLES2:
      return vaGetDisplayDRM(drm_fd.get());

    case gl::kGLImplementationNone:

    case gl::kGLImplementationDesktopGL: {
      VADisplay display =
          vaGetDisplay(x11::Connection::Get()->GetXlibDisplay());
      if (vaDisplayIsValid(display))
        return display;
      return vaGetDisplayDRM(drm_fd.get());
    }

    case gl::kGLImplementationEGLANGLE:
      return vaGetDisplay(x11::Connection::Get()->GetXlibDisplay());

    default:
      LOG(WARNING) << "VAAPI video acceleration not available for "
                   << gl::GetGLImplementationGLName(
                          gl::GetGLImplementationParts());
      return absl::nullopt;
  }
}

#else

absl::optional<VADisplay> GetVADisplayState(const base::ScopedFD& drm_fd) {
  switch (gl::GetGLImplementation()) {
    case gl::kGLImplementationEGLGLES2:
    case gl::kGLImplementationNone:
      return vaGetDisplayDRM(drm_fd.get());
    default:
      LOG(WARNING) << "VAAPI video acceleration not available for "
                   << gl::GetGLImplementationGLName(
                          gl::GetGLImplementationParts());
      return absl::nullopt;
  }
}

#endif  // BUILDFLAG(USE_VAAPI_X11)

bool VADisplayState::InitializeVaDisplay_Locked() {
  absl::optional<VADisplay> display =
#if BUILDFLAG(USE_VAAPI_X11)
      GetVADisplayStateX11(drm_fd_);
#else
      GetVADisplayState(drm_fd_);
#endif

  if (!display)
    return false;

  va_display_ = *display;
  if (!vaDisplayIsValid(va_display_)) {
    LOG(ERROR) << "Could not get a valid VA display";
    return false;
  }

  return true;
}

bool VADisplayState::InitializeVaDriver_Locked() {
  // The VAAPI version.
  int major_version, minor_version;
  VAStatus va_res = vaInitialize(va_display_, &major_version, &minor_version);
  if (va_res != VA_STATUS_SUCCESS) {
    VLOGF(1) << "vaInitialize failed: " << vaErrorStr(va_res);
    return false;
  }
  const std::string va_vendor_string = vaQueryVendorString(va_display_);
  DLOG_IF(WARNING, va_vendor_string.empty())
      << "Vendor string empty or error reading.";
  DVLOG(1) << "VAAPI version: " << major_version << "." << minor_version << " "
           << va_vendor_string;
  implementation_type_ = VendorStringToImplementationType(va_vendor_string);

  va_initialized_ = true;

  // The VAAPI version is determined from what is loaded on the system by
  // calling vaInitialize(). Since the libva is now ABI-compatible, relax the
  // version check which helps in upgrading the libva, without breaking any
  // existing functionality. Make sure the system version is not older than
  // the version with which the chromium is built since libva is only
  // guaranteed to be backward (and not forward) compatible.
  if (VA_MAJOR_VERSION > major_version ||
      (VA_MAJOR_VERSION == major_version && VA_MINOR_VERSION > minor_version)) {
    VLOGF(1) << "The system version " << major_version << "." << minor_version
             << " should be greater than or equal to " << VA_MAJOR_VERSION
             << "." << VA_MINOR_VERSION;
    return false;
  }
  return true;
}

bool VADisplayState::InitializeOnce() {
  static_assert(
      VA_MAJOR_VERSION >= 2 || (VA_MAJOR_VERSION == 1 && VA_MINOR_VERSION >= 1),
      "Requires VA-API >= 1.1.0");

  // Set VA logging level, unless already set.
  constexpr char libva_log_level_env[] = "LIBVA_MESSAGING_LEVEL";
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  if (!env->HasVar(libva_log_level_env))
    env->SetVar(libva_log_level_env, "1");

  if (!InitializeVaDisplay_Locked() || !InitializeVaDriver_Locked())
    return false;

#if BUILDFLAG(USE_VAAPI_X11)
  if (gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE &&
      implementation_type_ == VAImplementation::kIntelIHD) {
    constexpr char libva_driver_impl_env[] = "LIBVA_DRIVER_NAME";
    // TODO(crbug/1116703) The libva intel-media driver has a known segfault in
    // vaPutSurface, so until this is fixed, fall back to the i965 driver. There
    // is discussion of the issue here:
    // https://github.com/intel/media-driver/issues/818
    if (!env->HasVar(libva_driver_impl_env))
      env->SetVar(libva_driver_impl_env, "i965");

    // Re-initialize with the new driver.
    va_display_ = nullptr;
    va_initialized_ = false;
    implementation_type_ = VAImplementation::kInvalid;

    if (!InitializeVaDisplay_Locked() || !InitializeVaDriver_Locked())
      return false;
  }
#endif  // BUILDFLAG(USE_VAAPI_X11)

  return true;
}

VAStatus VADisplayState::Deinitialize() {
  base::AutoLock auto_lock(va_lock_);
  VAStatus va_res = VA_STATUS_SUCCESS;

  if (--refcount_ > 0)
    return va_res;

  // Must check if vaInitialize completed successfully, to work around a bug in
  // libva. The bug was fixed upstream:
  // http://lists.freedesktop.org/archives/libva/2013-July/001807.html
  // TODO(mgiuca): Remove this check, and the |va_initialized_| variable, once
  // the fix has rolled out sufficiently.
  if (va_initialized_ && va_display_)
    va_res = vaTerminate(va_display_);
  va_initialized_ = false;
  va_display_ = nullptr;
  return va_res;
}

// Returns all the VAProfiles that the driver lists as supported, regardless of
// what Chrome supports or not.
std::vector<VAProfile> GetSupportedVAProfiles(const base::Lock* va_lock,
                                              VADisplay va_display) {
  va_lock->AssertAcquired();

  // Query the driver for supported profiles.
  const int max_va_profiles = vaMaxNumProfiles(va_display);
  std::vector<VAProfile> va_profiles(
      base::checked_cast<size_t>(max_va_profiles));

  int num_va_profiles;
  const VAStatus va_res =
      vaQueryConfigProfiles(va_display, &va_profiles[0], &num_va_profiles);
  if (va_res != VA_STATUS_SUCCESS) {
    LOG(ERROR) << "vaQueryConfigProfiles failed: " << vaErrorStr(va_res);
    return {};
  }
  if (num_va_profiles < 0 || num_va_profiles > max_va_profiles) {
    LOG(ERROR) << "vaQueryConfigProfiles returned: " << num_va_profiles
               << " profiles";
    return {};
  }

  va_profiles.resize(base::checked_cast<size_t>(num_va_profiles));
  return va_profiles;
}

// Queries the driver for the supported entrypoints for |va_profile|, then
// returns those allowed for |mode|.
std::vector<VAEntrypoint> GetEntryPointsForProfile(const base::Lock* va_lock,
                                                   VADisplay va_display,
                                                   VaapiWrapper::CodecMode mode,
                                                   VAProfile va_profile) {
  va_lock->AssertAcquired();

  const int max_entrypoints = vaMaxNumEntrypoints(va_display);
  std::vector<VAEntrypoint> va_entrypoints(
      base::checked_cast<size_t>(max_entrypoints));

  int num_va_entrypoints;
  const VAStatus va_res = vaQueryConfigEntrypoints(
      va_display, va_profile, &va_entrypoints[0], &num_va_entrypoints);
  if (va_res != VA_STATUS_SUCCESS) {
    LOG(ERROR) << "vaQueryConfigEntrypoints failed, VA error: "
               << vaErrorStr(va_res);
    return {};
  }
  if (num_va_entrypoints < 0 || num_va_entrypoints > max_entrypoints) {
    LOG(ERROR) << "vaQueryConfigEntrypoints returned: " << num_va_entrypoints
               << " entry points, when the max is: " << max_entrypoints;
    return {};
  }
  va_entrypoints.resize(num_va_entrypoints);

  const std::vector<VAEntrypoint> kAllowedEntryPoints[] = {
    {VAEntrypointVLD},  // kDecode.
#if BUILDFLAG(IS_CHROMEOS_ASH)
    {VAEntrypointVLD, VAEntrypointProtectedContent},  // kDecodeProtected.
#endif
    {VAEntrypointEncSlice, VAEntrypointEncPicture,
     VAEntrypointEncSliceLP},  // kEncodeConstantBitrate.
    {VAEntrypointEncSlice,
     VAEntrypointEncSliceLP},  // kEncodeConstantQuantizationParameter.
    {VAEntrypointVideoProc}    // kVideoProcess.
  };
  static_assert(base::size(kAllowedEntryPoints) == VaapiWrapper::kCodecModeMax,
                "");

  std::vector<VAEntrypoint> entrypoints;
  std::copy_if(va_entrypoints.begin(), va_entrypoints.end(),
               std::back_inserter(entrypoints),
               [&kAllowedEntryPoints, mode](VAEntrypoint entry_point) {
                 return base::Contains(kAllowedEntryPoints[mode], entry_point);
               });
  return entrypoints;
}

bool GetRequiredAttribs(const base::Lock* va_lock,
                        VADisplay va_display,
                        VaapiWrapper::CodecMode mode,
                        VAProfile profile,
                        VAEntrypoint entrypoint,
                        std::vector<VAConfigAttrib>* required_attribs) {
  va_lock->AssertAcquired();

  // Choose a suitable VAConfigAttribRTFormat for every |mode|. For video
  // processing, the supported surface attribs may vary according to which RT
  // format is set.
  if (profile == VAProfileVP9Profile2 || profile == VAProfileVP9Profile3) {
    required_attribs->push_back(
        {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420_10BPP});
#if BUILDFLAG(IS_CHROMEOS_ASH)
  } else if (profile == VAProfileProtected) {
    DCHECK_EQ(mode, VaapiWrapper::kDecodeProtected);
    constexpr int kWidevineUsage = 0x1;
    required_attribs->push_back(
        {VAConfigAttribProtectedContentUsage, kWidevineUsage});
    required_attribs->push_back(
        {VAConfigAttribProtectedContentCipherAlgorithm, VA_PC_CIPHER_AES});
    required_attribs->push_back(
        {VAConfigAttribProtectedContentCipherBlockSize, VA_PC_BLOCK_SIZE_128});
    required_attribs->push_back(
        {VAConfigAttribProtectedContentCipherMode, VA_PC_CIPHER_MODE_CTR});
#endif
  } else {
    required_attribs->push_back({VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420});
  }

#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (mode == VaapiWrapper::kDecodeProtected && profile != VAProfileProtected) {
    required_attribs->push_back(
        {VAConfigAttribEncryption, VA_ENCRYPTION_TYPE_SUBSAMPLE_CTR});
  }
#endif

  if (!IsModeEncoding(mode))
    return true;

  if (profile == VAProfileJPEGBaseline)
    return true;

  if (mode == VaapiWrapper::kEncodeConstantBitrate)
    required_attribs->push_back({VAConfigAttribRateControl, VA_RC_CBR});
  if (mode == VaapiWrapper::kEncodeConstantQuantizationParameter)
    required_attribs->push_back({VAConfigAttribRateControl, VA_RC_CQP});

  constexpr VAProfile kSupportedH264VaProfilesForEncoding[] = {
      VAProfileH264ConstrainedBaseline, VAProfileH264Main, VAProfileH264High};
  // VAConfigAttribEncPackedHeaders is H.264 specific.
  if (base::Contains(kSupportedH264VaProfilesForEncoding, profile)) {
    // Encode with Packed header if the driver supports.
    VAConfigAttrib attrib{};
    attrib.type = VAConfigAttribEncPackedHeaders;
    const VAStatus va_res =
        vaGetConfigAttributes(va_display, profile, entrypoint, &attrib, 1);
    if (va_res != VA_STATUS_SUCCESS) {
      LOG(ERROR) << "vaGetConfigAttributes failed: " << vaProfileStr(profile);
      return false;
    }

    const uint32_t packed_header_attributes =
        (VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE |
         VA_ENC_PACKED_HEADER_SLICE);
    if ((packed_header_attributes & attrib.value) == packed_header_attributes) {
      required_attribs->push_back(
          {VAConfigAttribEncPackedHeaders, packed_header_attributes});
    } else {
      required_attribs->push_back(
          {VAConfigAttribEncPackedHeaders, VA_ENC_PACKED_HEADER_NONE});
    }
  }
  return true;
}

// Returns true if |va_profile| for |entrypoint| with |required_attribs| is
// supported.
bool AreAttribsSupported(const base::Lock* va_lock,
                         VADisplay va_display,
                         VAProfile va_profile,
                         VAEntrypoint entrypoint,
                         const std::vector<VAConfigAttrib>& required_attribs) {
  va_lock->AssertAcquired();
  // Query the driver for required attributes.
  std::vector<VAConfigAttrib> attribs = required_attribs;
  for (size_t i = 0; i < required_attribs.size(); ++i)
    attribs[i].value = 0;

  VAStatus va_res = vaGetConfigAttributes(va_display, va_profile, entrypoint,
                                          &attribs[0], attribs.size());
  if (va_res != VA_STATUS_SUCCESS) {
    LOG(ERROR) << "vaGetConfigAttributes failed error: " << vaErrorStr(va_res);
    return false;
  }
  for (size_t i = 0; i < required_attribs.size(); ++i) {
    if (attribs[i].type != required_attribs[i].type ||
        (attribs[i].value & required_attribs[i].value) !=
            required_attribs[i].value) {
      DVLOG(1) << "Unsupported value " << required_attribs[i].value << " for "
               << vaConfigAttribTypeStr(required_attribs[i].type);
      return false;
    }
  }
  return true;
}

// This class encapsulates reading and giving access to the list of supported
// ProfileInfo entries, in a singleton way.
class VASupportedProfiles {
 public:
  struct ProfileInfo {
    VAProfile va_profile;
    VAEntrypoint va_entrypoint;
    gfx::Size min_resolution;
    gfx::Size max_resolution;
    std::vector<uint32_t> pixel_formats;
    VaapiWrapper::InternalFormats supported_internal_formats;
  };
  static const VASupportedProfiles& Get();

  // Determines if |mode| supports |va_profile| (and |va_entrypoint| if defined
  // and valid). If so, returns a const pointer to its ProfileInfo, otherwise
  // returns nullptr.
  const ProfileInfo* IsProfileSupported(
      VaapiWrapper::CodecMode mode,
      VAProfile va_profile,
      VAEntrypoint va_entrypoint = kVAEntrypointInvalid) const;

 private:
  friend class base::NoDestructor<VASupportedProfiles>;

  friend std::map<VAProfile, std::vector<VAEntrypoint>>
  VaapiWrapper::GetSupportedConfigurationsForCodecModeForTesting(
      CodecMode mode);

  VASupportedProfiles();
  ~VASupportedProfiles() = default;

  // Fills in |supported_profiles_|.
  void FillSupportedProfileInfos(base::Lock* va_lock, VADisplay va_display);

  // Fills |profile_info| for |va_profile| and |entrypoint| with
  // |required_attribs|. If the return value is true, the operation was
  // successful. Otherwise, the information in *|profile_info| shouldn't be
  // relied upon.
  bool FillProfileInfo_Locked(const base::Lock* va_lock,
                              VADisplay va_display,
                              VAProfile va_profile,
                              VAEntrypoint entrypoint,
                              std::vector<VAConfigAttrib>& required_attribs,
                              ProfileInfo* profile_info) const;

  std::vector<ProfileInfo> supported_profiles_[VaapiWrapper::kCodecModeMax];
  static_assert(std::extent<decltype(supported_profiles_)>() ==
                    VaapiWrapper::kCodecModeMax,
                "|supported_profiles_| size is incorrect.");

  const ReportErrorToUMACB report_error_to_uma_cb_;

  DISALLOW_COPY_AND_ASSIGN(VASupportedProfiles);
};

// static
const VASupportedProfiles& VASupportedProfiles::Get() {
  static const base::NoDestructor<VASupportedProfiles> profile_infos;
  return *profile_infos;
}

const VASupportedProfiles::ProfileInfo* VASupportedProfiles::IsProfileSupported(
    VaapiWrapper::CodecMode mode,
    VAProfile va_profile,
    VAEntrypoint va_entrypoint) const {
  auto iter = std::find_if(
      supported_profiles_[mode].begin(), supported_profiles_[mode].end(),
      [va_profile, va_entrypoint](const ProfileInfo& profile) {
        return profile.va_profile == va_profile &&
               (va_entrypoint == kVAEntrypointInvalid ||
                profile.va_entrypoint == va_entrypoint);
      });
  if (iter != supported_profiles_[mode].end())
    return &*iter;
  return nullptr;
}

VASupportedProfiles::VASupportedProfiles()
    : report_error_to_uma_cb_(base::DoNothing()) {
  VADisplayState* display_state = VADisplayState::Get();
  if (!display_state->Initialize())
    return;

  VADisplay va_display = display_state->va_display();
  DCHECK(va_display) << "VADisplayState hasn't been properly Initialize()d";

  FillSupportedProfileInfos(VADisplayState::Get()->va_lock(), va_display);

  const VAStatus va_res = display_state->Deinitialize();
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVATerminate);
}

void VASupportedProfiles::FillSupportedProfileInfos(base::Lock* va_lock,
                                                    VADisplay va_display) {
  base::AutoLock auto_lock(*va_lock);

  const std::vector<VAProfile> va_profiles =
      GetSupportedVAProfiles(va_lock, va_display);

  constexpr VaapiWrapper::CodecMode kWrapperModes[] = {
    VaapiWrapper::kDecode,
#if BUILDFLAG(IS_CHROMEOS_ASH)
    VaapiWrapper::kDecodeProtected,
#endif
    VaapiWrapper::kEncodeConstantBitrate,
    VaapiWrapper::kEncodeConstantQuantizationParameter,
    VaapiWrapper::kVideoProcess
  };
  static_assert(base::size(kWrapperModes) == VaapiWrapper::kCodecModeMax, "");

  for (VaapiWrapper::CodecMode mode : kWrapperModes) {
    std::vector<ProfileInfo> supported_profile_infos;

    for (const auto& va_profile : va_profiles) {
      if (IsBlockedDriver(mode, va_profile))
        continue;

      if ((mode != VaapiWrapper::kVideoProcess) &&
          !IsVAProfileSupported(va_profile)) {
        continue;
      }

      const std::vector<VAEntrypoint> supported_entrypoints =
          GetEntryPointsForProfile(va_lock, va_display, mode, va_profile);

      for (const auto& entrypoint : supported_entrypoints) {
        std::vector<VAConfigAttrib> required_attribs;
        if (!GetRequiredAttribs(va_lock, va_display, mode, va_profile,
                                entrypoint, &required_attribs)) {
          continue;
        }
        if (!AreAttribsSupported(va_lock, va_display, va_profile, entrypoint,
                                 required_attribs)) {
          continue;
        }
        ProfileInfo profile_info{};
        if (!FillProfileInfo_Locked(va_lock, va_display, va_profile, entrypoint,
                                    required_attribs, &profile_info)) {
          LOG(ERROR) << "FillProfileInfo_Locked failed for va_profile "
                     << vaProfileStr(va_profile) << " and entrypoint "
                     << vaEntrypointStr(entrypoint);
          continue;
        }

        supported_profile_infos.push_back(profile_info);
      }
    }
    supported_profiles_[static_cast<int>(mode)] = supported_profile_infos;
  }
}

bool VASupportedProfiles::FillProfileInfo_Locked(
    const base::Lock* va_lock,
    VADisplay va_display,
    VAProfile va_profile,
    VAEntrypoint entrypoint,
    std::vector<VAConfigAttrib>& required_attribs,
    ProfileInfo* profile_info) const {
  va_lock->AssertAcquired();
  VAConfigID va_config_id;
  VAStatus va_res =
      vaCreateConfig(va_display, va_profile, entrypoint, &required_attribs[0],
                     required_attribs.size(), &va_config_id);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateConfig, false);
  base::ScopedClosureRunner vaconfig_destroyer(base::BindOnce(
      [](VADisplay display, VAConfigID id) {
        if (id != VA_INVALID_ID) {
          VAStatus va_res = vaDestroyConfig(display, id);
          if (va_res != VA_STATUS_SUCCESS)
            LOG(ERROR) << "vaDestroyConfig failed. VA error: "
                       << vaErrorStr(va_res);
        }
      },
      va_display, va_config_id));

#if BUILDFLAG(IS_CHROMEOS_ASH)
  // Nothing further to query for protected profile.
  if (va_profile == VAProfileProtected) {
    profile_info->va_profile = va_profile;
    profile_info->va_entrypoint = entrypoint;
    return true;
  }
#endif

  // Calls vaQuerySurfaceAttributes twice. The first time is to get the number
  // of attributes to prepare the space and the second time is to get all
  // attributes.
  unsigned int num_attribs;
  va_res =
      vaQuerySurfaceAttributes(va_display, va_config_id, nullptr, &num_attribs);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAQuerySurfaceAttributes,
                       false);
  if (!num_attribs)
    return false;

  std::vector<VASurfaceAttrib> attrib_list(
      base::checked_cast<size_t>(num_attribs));

  va_res = vaQuerySurfaceAttributes(va_display, va_config_id, &attrib_list[0],
                                    &num_attribs);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAQuerySurfaceAttributes,
                       false);

  profile_info->va_profile = va_profile;
  profile_info->va_entrypoint  = entrypoint;
  profile_info->min_resolution = gfx::Size();
  profile_info->max_resolution = gfx::Size();
  for (const auto& attrib : attrib_list) {
    if (attrib.type == VASurfaceAttribMaxWidth) {
      profile_info->max_resolution.set_width(
          base::strict_cast<int>(attrib.value.value.i));
    } else if (attrib.type == VASurfaceAttribMaxHeight) {
      profile_info->max_resolution.set_height(
          base::strict_cast<int>(attrib.value.value.i));
    } else if (attrib.type == VASurfaceAttribMinWidth) {
      profile_info->min_resolution.set_width(
          base::strict_cast<int>(attrib.value.value.i));
    } else if (attrib.type == VASurfaceAttribMinHeight) {
      profile_info->min_resolution.set_height(
          base::strict_cast<int>(attrib.value.value.i));
    } else if (attrib.type == VASurfaceAttribPixelFormat) {
      // According to va.h, VASurfaceAttribPixelFormat is meaningful as input to
      // vaQuerySurfaceAttributes(). However, per the implementation of
      // i965_QuerySurfaceAttributes(), our usage here should enumerate all the
      // formats.
      profile_info->pixel_formats.push_back(attrib.value.value.i);
    }
  }
  if (profile_info->max_resolution.IsEmpty()) {
    LOG(ERROR) << "Empty codec maximum resolution";
    return false;
  }

  if (va_profile != VAProfileJPEGBaseline) {
    // Set a reasonable minimum value for both encoding and decoding.
    profile_info->min_resolution.SetToMax(gfx::Size(16, 16));

    const bool is_encoding = entrypoint == VAEntrypointEncSliceLP ||
                             entrypoint == VAEntrypointEncSlice;
    const bool is_hybrid_decoding = entrypoint == VAEntrypointVLD &&
                                    IsUsingHybridDriverForDecoding(va_profile);

    // Using HW encoding for small resolutions is less efficient than using a SW
    // encoder. Similarly, using the intel-hybrid-driver for decoding is less
    // efficient than using a SW decoder. In both cases, increase
    // |min_resolution| to QVGA + 1 which is an experimental lower threshold.
    // This can be turned off with kVaapiVideoMinResolutionForPerformance for
    // testing.
    if ((is_encoding || is_hybrid_decoding) &&
        base::FeatureList::IsEnabled(kVaapiVideoMinResolutionForPerformance)) {
      constexpr gfx::Size kMinVideoResolution(320 + 1, 240 + 1);
      profile_info->min_resolution.SetToMax(kMinVideoResolution);
      DVLOG(2) << "Setting the minimum supported resolution for "
               << vaProfileStr(va_profile)
               << (is_encoding ? " encoding" : " decoding") << " to "
               << profile_info->min_resolution.ToString();
    }
  }

  // Create a new configuration to find the supported RT formats. We don't pass
  // required attributes here because we want the driver to tell us all the
  // supported RT formats.
  va_res = vaCreateConfig(va_display, va_profile, entrypoint, nullptr, 0,
                          &va_config_id);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateConfig, false);
  base::ScopedClosureRunner vaconfig_no_attribs_destroyer(base::BindOnce(
      [](VADisplay display, VAConfigID id) {
        if (id != VA_INVALID_ID) {
          VAStatus va_res = vaDestroyConfig(display, id);
          if (va_res != VA_STATUS_SUCCESS)
            LOG(ERROR) << "vaDestroyConfig failed. VA error: "
                       << vaErrorStr(va_res);
        }
      },
      va_display, va_config_id));
  profile_info->supported_internal_formats = {};
  size_t max_num_config_attributes;
  if (!base::CheckedNumeric<int>(vaMaxNumConfigAttributes(va_display))
           .AssignIfValid(&max_num_config_attributes)) {
    LOG(ERROR) << "Can't get the maximum number of config attributes";
    return false;
  }
  std::vector<VAConfigAttrib> config_attributes(max_num_config_attributes);
  int num_config_attributes;
  va_res = vaQueryConfigAttributes(va_display, va_config_id, &va_profile,
                                   &entrypoint, config_attributes.data(),
                                   &num_config_attributes);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAQueryConfigAttributes, false);
  for (int i = 0; i < num_config_attributes; i++) {
    const VAConfigAttrib& attrib = config_attributes[i];
    if (attrib.type != VAConfigAttribRTFormat)
      continue;
    if (attrib.value & VA_RT_FORMAT_YUV420)
      profile_info->supported_internal_formats.yuv420 = true;
    if (attrib.value & VA_RT_FORMAT_YUV420_10)
      profile_info->supported_internal_formats.yuv420_10 = true;
    if (attrib.value & VA_RT_FORMAT_YUV422)
      profile_info->supported_internal_formats.yuv422 = true;
    if (attrib.value & VA_RT_FORMAT_YUV444)
      profile_info->supported_internal_formats.yuv444 = true;
    break;
  }

  // Now work around some driver misreporting for JPEG decoding.
  if (va_profile == VAProfileJPEGBaseline && entrypoint == VAEntrypointVLD) {
    if (VADisplayState::Get()->implementation_type() ==
        VAImplementation::kMesaGallium) {
      // TODO(andrescj): the VAAPI state tracker in mesa does not report
      // VA_RT_FORMAT_YUV422 as being supported for JPEG decoding. However, it
      // is happy to allocate YUYV surfaces
      // (https://gitlab.freedesktop.org/mesa/mesa/commit/5608f442). Remove this
      // workaround once b/128337341 is resolved.
      profile_info->supported_internal_formats.yuv422 = true;
    }
  }
  const bool is_any_profile_supported =
      profile_info->supported_internal_formats.yuv420 ||
      profile_info->supported_internal_formats.yuv420_10 ||
      profile_info->supported_internal_formats.yuv422 ||
      profile_info->supported_internal_formats.yuv444;
  DLOG_IF(ERROR, !is_any_profile_supported)
      << "No cool internal formats supported";
  return is_any_profile_supported;
}

void DestroyVAImage(VADisplay va_display, VAImage image) {
  if (image.image_id != VA_INVALID_ID)
    vaDestroyImage(va_display, image.image_id);
}

// This class encapsulates fetching the list of supported output image formats
// from the VAAPI driver, in a singleton way.
class VASupportedImageFormats {
 public:
  static const VASupportedImageFormats& Get();

  bool IsImageFormatSupported(const VAImageFormat& va_format) const;

  const std::vector<VAImageFormat>& GetSupportedImageFormats() const;

 private:
  friend class base::NoDestructor<VASupportedImageFormats>;

  VASupportedImageFormats();
  ~VASupportedImageFormats() = default;

  // Initialize the list of supported image formats.
  bool InitSupportedImageFormats_Locked() EXCLUSIVE_LOCKS_REQUIRED(va_lock_);

  // Pointer to VADisplayState's members |va_lock_| and its |va_display_|.
  base::Lock* va_lock_;
  VADisplay va_display_ GUARDED_BY(va_lock_);

  std::vector<VAImageFormat> supported_formats_;
  const ReportErrorToUMACB report_error_to_uma_cb_;

  DISALLOW_COPY_AND_ASSIGN(VASupportedImageFormats);
};

// static
const VASupportedImageFormats& VASupportedImageFormats::Get() {
  static const base::NoDestructor<VASupportedImageFormats> image_formats;
  return *image_formats;
}

bool VASupportedImageFormats::IsImageFormatSupported(
    const VAImageFormat& va_image_format) const {
  auto it = std::find_if(supported_formats_.begin(), supported_formats_.end(),
                         [&va_image_format](const VAImageFormat& format) {
                           return format.fourcc == va_image_format.fourcc;
                         });
  return it != supported_formats_.end();
}

const std::vector<VAImageFormat>&
VASupportedImageFormats::GetSupportedImageFormats() const {
#if DCHECK_IS_ON()
  std::string formats_str;
  for (size_t i = 0; i < supported_formats_.size(); i++) {
    if (i > 0)
      formats_str += ", ";
    formats_str += FourccToString(supported_formats_[i].fourcc);
  }
  DVLOG(1) << "Supported image formats: " << formats_str;
#endif
  return supported_formats_;
}

VASupportedImageFormats::VASupportedImageFormats()
    : va_lock_(VADisplayState::Get()->va_lock()),
      report_error_to_uma_cb_(base::DoNothing()) {
  VADisplayState* display_state = VADisplayState::Get();
  if (!display_state->Initialize())
    return;

  {
    base::AutoLock auto_lock(*va_lock_);
    va_display_ = display_state->va_display();
    DCHECK(va_display_) << "VADisplayState hasn't been properly initialized";

    if (!InitSupportedImageFormats_Locked())
      LOG(ERROR) << "Failed to get supported image formats";
  }

  const VAStatus va_res = display_state->Deinitialize();
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVATerminate);
}

bool VASupportedImageFormats::InitSupportedImageFormats_Locked() {
  va_lock_->AssertAcquired();

  // Query the driver for the max number of image formats and allocate space.
  const int max_image_formats = vaMaxNumImageFormats(va_display_);
  if (max_image_formats < 0) {
    LOG(ERROR) << "vaMaxNumImageFormats returned: " << max_image_formats;
    return false;
  }
  supported_formats_.resize(static_cast<size_t>(max_image_formats));

  // Query the driver for the list of supported image formats.
  int num_image_formats;
  const VAStatus va_res = vaQueryImageFormats(
      va_display_, supported_formats_.data(), &num_image_formats);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAQueryImageFormats, false);
  if (num_image_formats < 0 || num_image_formats > max_image_formats) {
    LOG(ERROR) << "vaQueryImageFormats returned: " << num_image_formats;
    supported_formats_.clear();
    return false;
  }

  // Resize the list to the actual number of formats returned by the driver.
  supported_formats_.resize(static_cast<size_t>(num_image_formats));

  // Now work around some driver misreporting.
  if (VADisplayState::Get()->implementation_type() ==
      VAImplementation::kMesaGallium) {
    // TODO(andrescj): considering that the VAAPI state tracker in mesa can
    // convert from NV12 to IYUV when doing vaGetImage(), it's reasonable to
    // assume that IYUV/I420 is supported. However, it's not currently being
    // reported. See https://gitlab.freedesktop.org/mesa/mesa/commit/b0a44f10.
    // Remove this workaround once b/128340287 is resolved.
    if (std::find_if(supported_formats_.cbegin(), supported_formats_.cend(),
                     [](const VAImageFormat& format) {
                       return format.fourcc == VA_FOURCC_I420;
                     }) == supported_formats_.cend()) {
      VAImageFormat i420_format{};
      i420_format.fourcc = VA_FOURCC_I420;
      supported_formats_.push_back(i420_format);
    }
  }
  return true;
}

bool IsLowPowerEncSupported(VAProfile va_profile) {
  constexpr VAProfile kSupportedLowPowerEncodeProfiles[] = {
      VAProfileH264ConstrainedBaseline,
      VAProfileH264Main,
      VAProfileH264High,
      VAProfileVP9Profile0,
      VAProfileVP9Profile2};
  if (!base::Contains(kSupportedLowPowerEncodeProfiles, va_profile))
    return false;

  if ((IsGen95Gpu() || IsGen9Gpu()) &&
      !base::FeatureList::IsEnabled(kVaapiLowPowerEncoderGen9x)) {
    return false;
  }

  if (VASupportedProfiles::Get().IsProfileSupported(
          VaapiWrapper::kEncodeConstantBitrate, va_profile,
          VAEntrypointEncSliceLP)) {
    return true;
  }
  return false;
}

}  // namespace

NativePixmapAndSizeInfo::NativePixmapAndSizeInfo() = default;

NativePixmapAndSizeInfo::~NativePixmapAndSizeInfo() = default;

// static
VAImplementation VaapiWrapper::GetImplementationType() {
  return VADisplayState::Get()->implementation_type();
}

// static
scoped_refptr<VaapiWrapper> VaapiWrapper::Create(
    CodecMode mode,
    VAProfile va_profile,
    EncryptionScheme encryption_scheme,
    const ReportErrorToUMACB& report_error_to_uma_cb) {
  if (!VASupportedProfiles::Get().IsProfileSupported(mode, va_profile)) {
    DVLOG(1) << "Unsupported va_profile: " << vaProfileStr(va_profile);
    return nullptr;
  }
#if BUILDFLAG(IS_CHROMEOS_ASH)
  // In protected decode |mode| we need to ensure that |va_profile| is supported
  // (which we verified above) and that VAProfileProtected is supported, which
  // we check here.
  if (mode == kDecodeProtected &&
      !VASupportedProfiles::Get().IsProfileSupported(mode,
                                                     VAProfileProtected)) {
    LOG(ERROR) << "Protected content profile not supported";
    return nullptr;
  }
#endif

  scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper(mode));
  if (vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) {
    if (vaapi_wrapper->Initialize(va_profile, encryption_scheme))
      return vaapi_wrapper;
  }
  LOG(ERROR) << "Failed to create VaapiWrapper for va_profile: "
             << vaProfileStr(va_profile);
  return nullptr;
}

// static
scoped_refptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec(
    CodecMode mode,
    VideoCodecProfile profile,
    EncryptionScheme encryption_scheme,
    const ReportErrorToUMACB& report_error_to_uma_cb) {
  const VAProfile va_profile = ProfileToVAProfile(profile, mode);
  return Create(mode, va_profile, encryption_scheme, report_error_to_uma_cb);
}

// static
std::vector<SVCScalabilityMode> VaapiWrapper::GetSupportedScalabilityModes(
    VideoCodecProfile media_profile,
    VAProfile va_profile) {
  std::vector<SVCScalabilityMode> scalability_modes;
#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (media_profile == VP9PROFILE_PROFILE0) {
    scalability_modes.push_back(SVCScalabilityMode::kL1T2);
    scalability_modes.push_back(SVCScalabilityMode::kL1T3);
    if (base::FeatureList::IsEnabled(kVaapiVp9kSVCHWEncoding) &&
        GetDefaultVaEntryPoint(
            VaapiWrapper::kEncodeConstantQuantizationParameter, va_profile) ==
            VAEntrypointEncSliceLP) {
      scalability_modes.push_back(SVCScalabilityMode::kL2T2Key);
      scalability_modes.push_back(SVCScalabilityMode::kL2T3Key);
      scalability_modes.push_back(SVCScalabilityMode::kL3T2Key);
      scalability_modes.push_back(SVCScalabilityMode::kL3T3Key);
    }
  }

  if (media_profile >= H264PROFILE_MIN && media_profile <= H264PROFILE_MAX) {
    // TODO(b/199487660): Enable H.264 temporal layer encoding on AMD once their
    // drivers support them.
    VAImplementation implementation = VaapiWrapper::GetImplementationType();
    if (base::FeatureList::IsEnabled(kVaapiH264TemporalLayerHWEncoding) &&
        (implementation == VAImplementation::kIntelI965 ||
         implementation == VAImplementation::kIntelIHD)) {
      scalability_modes.push_back(SVCScalabilityMode::kL1T2);
      scalability_modes.push_back(SVCScalabilityMode::kL1T3);
    }
  }
#endif
  return scalability_modes;
}

// static
VideoEncodeAccelerator::SupportedProfiles
VaapiWrapper::GetSupportedEncodeProfiles() {
  VideoEncodeAccelerator::SupportedProfiles profiles;

  for (const auto& media_to_va_profile_map_entry : GetProfileCodecMap()) {
    const VideoCodecProfile media_profile = media_to_va_profile_map_entry.first;
    const VAProfile va_profile = media_to_va_profile_map_entry.second;
    DCHECK(va_profile != VAProfileNone);

    const VASupportedProfiles::ProfileInfo* profile_info =
        VASupportedProfiles::Get().IsProfileSupported(kEncodeConstantBitrate,
                                                      va_profile);
    if (!profile_info)
      continue;

    VideoEncodeAccelerator::SupportedProfile profile;
    profile.profile = media_profile;
    profile.min_resolution = profile_info->min_resolution;
    profile.max_resolution = profile_info->max_resolution;
    // Maximum framerate of encoded profile. This value is an arbitrary
    // limit and not taken from HW documentation.
    constexpr int kMaxEncoderFramerate = 30;
    profile.max_framerate_numerator = kMaxEncoderFramerate;
    profile.max_framerate_denominator = 1;
    profile.scalability_modes =
        GetSupportedScalabilityModes(media_profile, va_profile);
    profiles.push_back(profile);
  }
  return profiles;
}

// static
VideoDecodeAccelerator::SupportedProfiles
VaapiWrapper::GetSupportedDecodeProfiles() {
  VideoDecodeAccelerator::SupportedProfiles profiles;

  for (const auto& media_to_va_profile_map_entry : GetProfileCodecMap()) {
    const VideoCodecProfile media_profile = media_to_va_profile_map_entry.first;
    const VAProfile va_profile = media_to_va_profile_map_entry.second;
    DCHECK(va_profile != VAProfileNone);

    const VASupportedProfiles::ProfileInfo* profile_info =
        VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile);
    if (!profile_info)
      continue;

    VideoDecodeAccelerator::SupportedProfile profile;
    profile.profile = media_profile;
    profile.max_resolution = profile_info->max_resolution;
    profile.min_resolution = profile_info->min_resolution;
    profiles.push_back(profile);
  }
  return profiles;
}

// static
bool VaapiWrapper::IsDecodeSupported(VAProfile va_profile) {
  return VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile);
}

// static
VaapiWrapper::InternalFormats VaapiWrapper::GetDecodeSupportedInternalFormats(
    VAProfile va_profile) {
  const VASupportedProfiles::ProfileInfo* profile_info =
      VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile);
  if (!profile_info)
    return InternalFormats{};
  return profile_info->supported_internal_formats;
}

// static
bool VaapiWrapper::IsDecodingSupportedForInternalFormat(
    VAProfile va_profile,
    unsigned int rt_format) {
  static const VaapiWrapper::InternalFormats supported_internal_formats(
      VaapiWrapper::GetDecodeSupportedInternalFormats(va_profile));
  switch (rt_format) {
    case VA_RT_FORMAT_YUV420:
      return supported_internal_formats.yuv420;
    case VA_RT_FORMAT_YUV420_10:
      return supported_internal_formats.yuv420_10;
    case VA_RT_FORMAT_YUV422:
      return supported_internal_formats.yuv422;
    case VA_RT_FORMAT_YUV444:
      return supported_internal_formats.yuv444;
  }
  return false;
}

// static
bool VaapiWrapper::GetDecodeMinResolution(VAProfile va_profile,
                                          gfx::Size* min_size) {
  const VASupportedProfiles::ProfileInfo* profile_info =
      VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile);
  if (!profile_info)
    return false;
  *min_size = gfx::Size(std::max(1, profile_info->min_resolution.width()),
                        std::max(1, profile_info->min_resolution.height()));
  return true;
}

// static
bool VaapiWrapper::GetDecodeMaxResolution(VAProfile va_profile,
                                          gfx::Size* max_size) {
  const VASupportedProfiles::ProfileInfo* profile_info =
      VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile);
  if (!profile_info)
    return false;

  *max_size = profile_info->max_resolution;
  return true;
}

// static
bool VaapiWrapper::GetJpegDecodeSuitableImageFourCC(unsigned int rt_format,
                                                    uint32_t preferred_fourcc,
                                                    uint32_t* suitable_fourcc) {
  if (!IsDecodingSupportedForInternalFormat(VAProfileJPEGBaseline, rt_format))
    return false;

  // Work around some driver-specific conversion issues. If you add a workaround
  // here, please update the VaapiJpegDecoderTest.MinimalImageFormatSupport
  // test.
  DCHECK_NE(VAImplementation::kInvalid, GetImplementationType());
  if (GetImplementationType() == VAImplementation::kMesaGallium) {
    // The VAAPI mesa state tracker only supports conversion from NV12 to YV12
    // and IYUV (synonym of I420).
    if (rt_format == VA_RT_FORMAT_YUV420) {
      if (preferred_fourcc != VA_FOURCC_I420 &&
          preferred_fourcc != VA_FOURCC_YV12) {
        preferred_fourcc = VA_FOURCC_NV12;
      }
    } else if (rt_format == VA_RT_FORMAT_YUV422) {
      preferred_fourcc = VA_FOURCC('Y', 'U', 'Y', 'V');
    } else {
      // Out of the three internal formats we care about (4:2:0, 4:2:2, and
      // 4:4:4), this driver should only support the first two. Since we check
      // for supported internal formats at the beginning of this function, we
      // shouldn't get here.
      NOTREACHED();
      return false;
    }
  } else if (GetImplementationType() == VAImplementation::kIntelI965) {
    // Workaround deduced from observations in samus and nocturne: we found that
    //
    // - For a 4:2:2 image, the internal format is 422H.
    // - For a 4:2:0 image, the internal format is IMC3.
    // - For a 4:4:4 image, the internal format is 444P.
    //
    // For these internal formats and an image format of either 422H or P010, an
    // intermediate NV12 surface is allocated. Then, a conversion is made from
    // {422H, IMC3, 444P} -> NV12 -> {422H, P010}. Unfortunately, the
    // NV12 -> {422H, P010} conversion is unimplemented in
    // i965_image_pl2_processing(). So, when |preferred_fourcc| is either 422H
    // or P010, we can just fallback to I420.
    //
    if (preferred_fourcc == VA_FOURCC_422H ||
        preferred_fourcc == VA_FOURCC_P010) {
      preferred_fourcc = VA_FOURCC_I420;
    }
  } else if (GetImplementationType() == VAImplementation::kIntelIHD) {
    // TODO(b/155939640): iHD v19.4 fails to allocate AYUV surfaces for the VPP
    // on gen 9.5.
    // (b/159896972): iHD v20.1.1 cannot create Y216 and Y416 images from a
    // decoded JPEG on gen 12. It is also failing to support Y800 format.
    if (preferred_fourcc == VA_FOURCC_AYUV ||
        preferred_fourcc == VA_FOURCC_Y216 ||
        preferred_fourcc == VA_FOURCC_Y416 ||
        preferred_fourcc == VA_FOURCC_Y800) {
      preferred_fourcc = VA_FOURCC_I420;
    }
  }

  if (!VASupportedImageFormats::Get().IsImageFormatSupported(
          VAImageFormat{.fourcc = preferred_fourcc})) {
    preferred_fourcc = VA_FOURCC_I420;
  }

  // After workarounds, assume the conversion is supported.
  *suitable_fourcc = preferred_fourcc;
  return true;
}

// static
bool VaapiWrapper::IsVppResolutionAllowed(const gfx::Size& size) {
  const VASupportedProfiles::ProfileInfo* profile_info =
      VASupportedProfiles::Get().IsProfileSupported(kVideoProcess,
                                                    VAProfileNone);
  if (!profile_info)
    return false;

  return size.width() >= profile_info->min_resolution.width() &&
         size.width() <= profile_info->max_resolution.width() &&
         size.height() >= profile_info->min_resolution.height() &&
         size.height() <= profile_info->max_resolution.height();
}

// static
bool VaapiWrapper::IsVppFormatSupported(uint32_t va_fourcc) {
  const VASupportedProfiles::ProfileInfo* profile_info =
      VASupportedProfiles::Get().IsProfileSupported(kVideoProcess,
                                                    VAProfileNone);
  if (!profile_info)
    return false;

  return base::Contains(profile_info->pixel_formats, va_fourcc);
}

// static
std::vector<Fourcc> VaapiWrapper::GetVppSupportedFormats() {
  const VASupportedProfiles::ProfileInfo* profile_info =
      VASupportedProfiles::Get().IsProfileSupported(kVideoProcess,
                                                    VAProfileNone);
  if (!profile_info)
    return {};

  std::vector<Fourcc> supported_fourccs;
  for (uint32_t pixel_format : profile_info->pixel_formats) {
    auto fourcc = Fourcc::FromVAFourCC(pixel_format);
    if (!fourcc)
      continue;
    supported_fourccs.push_back(*fourcc);
  }
  return supported_fourccs;
}

// static
bool VaapiWrapper::IsVppSupportedForJpegDecodedSurfaceToFourCC(
    unsigned int rt_format,
    uint32_t fourcc) {
  if (!IsDecodingSupportedForInternalFormat(VAProfileJPEGBaseline, rt_format))
    return false;

  // Workaround: for Mesa VAAPI driver, VPP only supports internal surface
  // format for 4:2:0 JPEG image.
  DCHECK_NE(VAImplementation::kInvalid, GetImplementationType());
  if (GetImplementationType() == VAImplementation::kMesaGallium &&
      rt_format != VA_RT_FORMAT_YUV420) {
    return false;
  }

  return IsVppFormatSupported(fourcc);
}

// static
bool VaapiWrapper::IsJpegEncodeSupported() {
  return VASupportedProfiles::Get().IsProfileSupported(kEncodeConstantBitrate,
                                                       VAProfileJPEGBaseline);
}

// static
bool VaapiWrapper::IsImageFormatSupported(const VAImageFormat& format) {
  return VASupportedImageFormats::Get().IsImageFormatSupported(format);
}

// static
const std::vector<VAImageFormat>&
VaapiWrapper::GetSupportedImageFormatsForTesting() {
  return VASupportedImageFormats::Get().GetSupportedImageFormats();
}

// static
std::map<VAProfile, std::vector<VAEntrypoint>>
VaapiWrapper::GetSupportedConfigurationsForCodecModeForTesting(CodecMode mode) {
  std::map<VAProfile, std::vector<VAEntrypoint>> configurations;
  for (const auto& supported_profile :
       VASupportedProfiles::Get().supported_profiles_[mode]) {
    configurations[supported_profile.va_profile].push_back(
        supported_profile.va_entrypoint);
  }
  return configurations;
}

// static
VAEntrypoint VaapiWrapper::GetDefaultVaEntryPoint(CodecMode mode,
                                                  VAProfile profile) {
  switch (mode) {
    case VaapiWrapper::kDecode:
      return VAEntrypointVLD;
#if BUILDFLAG(IS_CHROMEOS_ASH)
    case VaapiWrapper::kDecodeProtected:
      if (profile == VAProfileProtected)
        return VAEntrypointProtectedContent;
      return VAEntrypointVLD;
#endif
    case VaapiWrapper::kEncodeConstantBitrate:
    case VaapiWrapper::kEncodeConstantQuantizationParameter:
      if (profile == VAProfileJPEGBaseline)
        return VAEntrypointEncPicture;
      DCHECK(IsModeEncoding(mode));
      if (IsLowPowerEncSupported(profile))
        return VAEntrypointEncSliceLP;
      return VAEntrypointEncSlice;
    case VaapiWrapper::kVideoProcess:
      return VAEntrypointVideoProc;
    case VaapiWrapper::kCodecModeMax:
      NOTREACHED();
      return VAEntrypointVLD;
  }
}

// static
uint32_t VaapiWrapper::BufferFormatToVARTFormat(gfx::BufferFormat fmt) {
  switch (fmt) {
    case gfx::BufferFormat::BGRX_8888:
    case gfx::BufferFormat::BGRA_8888:
    case gfx::BufferFormat::RGBX_8888:
    case gfx::BufferFormat::RGBA_8888:
      return VA_RT_FORMAT_RGB32;
    case gfx::BufferFormat::YVU_420:
    case gfx::BufferFormat::YUV_420_BIPLANAR:
      return VA_RT_FORMAT_YUV420;
    case gfx::BufferFormat::P010:
      return VA_RT_FORMAT_YUV420_10BPP;
    default:
      NOTREACHED() << gfx::BufferFormatToString(fmt);
      return 0;
  }
}

bool VaapiWrapper::CreateContextAndSurfaces(
    unsigned int va_format,
    const gfx::Size& size,
    const std::vector<SurfaceUsageHint>& surface_usage_hints,
    size_t num_surfaces,
    std::vector<VASurfaceID>* va_surfaces) {
  DVLOG(2) << "Creating " << num_surfaces << " surfaces";
  DCHECK(va_surfaces->empty());

  if (va_context_id_ != VA_INVALID_ID) {
    LOG(ERROR)
        << "The current context should be destroyed before creating a new one";
    return false;
  }

  if (!CreateSurfaces(va_format, size, surface_usage_hints, num_surfaces,
                      va_surfaces)) {
    return false;
  }

  const bool success = CreateContext(size);
  if (!success)
    DestroyContextAndSurfaces(*va_surfaces);
  return success;
}

std::vector<std::unique_ptr<ScopedVASurface>>
VaapiWrapper::CreateContextAndScopedVASurfaces(
    unsigned int va_format,
    const gfx::Size& size,
    const std::vector<SurfaceUsageHint>& usage_hints,
    size_t num_surfaces,
    const absl::optional<gfx::Size>& visible_size) {
  if (va_context_id_ != VA_INVALID_ID) {
    LOG(ERROR) << "The current context should be destroyed before creating a "
                  "new one";
    return {};
  }

  std::vector<std::unique_ptr<ScopedVASurface>> scoped_va_surfaces =
      CreateScopedVASurfaces(va_format, size, usage_hints, num_surfaces,
                             visible_size, /*va_fourcc=*/absl::nullopt);
  if (scoped_va_surfaces.empty())
    return {};

  if (CreateContext(size))
    return scoped_va_surfaces;

  DestroyContext();
  return {};
}

bool VaapiWrapper::CreateProtectedSession(
    EncryptionScheme encryption,
    const std::vector<uint8_t>& hw_config,
    std::vector<uint8_t>* hw_identifier_out) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  DCHECK_EQ(va_protected_config_id_, VA_INVALID_ID);
  DCHECK_EQ(va_protected_session_id_, VA_INVALID_ID);
  DCHECK(hw_identifier_out);
  if (mode_ != kDecodeProtected) {
    LOG(ERROR) << "Cannot attached protected context if not in protected mode";
    return false;
  }
  if (encryption == EncryptionScheme::kUnencrypted) {
    LOG(ERROR) << "Must specify encryption scheme for protected mode";
    return false;
  }
  const VAProfile va_profile = VAProfileProtected;
  const VAEntrypoint entrypoint = GetDefaultVaEntryPoint(mode_, va_profile);
  {
    base::AutoLock auto_lock(*va_lock_);
    std::vector<VAConfigAttrib> required_attribs;
    if (!GetRequiredAttribs(va_lock_, va_display_, mode_, va_profile,
                            entrypoint, &required_attribs)) {
      LOG(ERROR) << "Failed getting required attributes for protected mode";
      return false;
    }
    DCHECK(!required_attribs.empty());

    // We need to adjust the attribute for encryption scheme.
    for (auto& attrib : required_attribs) {
      if (attrib.type == VAConfigAttribProtectedContentCipherMode) {
        attrib.value = (encryption == EncryptionScheme::kCbcs)
                           ? VA_PC_CIPHER_MODE_CBC
                           : VA_PC_CIPHER_MODE_CTR;
      }
    }

    VAStatus va_res = vaCreateConfig(
        va_display_, va_profile, entrypoint, &required_attribs[0],
        required_attribs.size(), &va_protected_config_id_);
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateConfig, false);

    va_res = vaCreateProtectedSession(va_display_, va_protected_config_id_,
                                      &va_protected_session_id_);
    DCHECK(va_res == VA_STATUS_SUCCESS ||
           va_protected_session_id_ == VA_INVALID_ID);
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateProtectedSession,
                         false);
  }
  // We have to hold the VABuffer outside of the lock because its destructor
  // will acquire the lock when it goes out of scope. We also must do this after
  // we create the protected session.
  VAProtectedSessionExecuteBuffer hw_update_buf;
  std::unique_ptr<ScopedVABuffer> hw_update = CreateVABuffer(
      VAProtectedSessionExecuteBufferType, sizeof(hw_update_buf));
  {
    base::AutoLock auto_lock(*va_lock_);
    constexpr size_t kHwIdentifierMaxSize = 64;
    memset(&hw_update_buf, 0, sizeof(hw_update_buf));
    hw_update_buf.function_id = VA_TEE_EXEC_TEE_FUNCID_HW_UPDATE;
    hw_update_buf.input.data_size = hw_config.size();
    hw_update_buf.input.data =
        static_cast<void*>(const_cast<uint8_t*>(hw_config.data()));
    hw_update_buf.output.max_data_size = kHwIdentifierMaxSize;
    hw_identifier_out->resize(kHwIdentifierMaxSize);
    hw_update_buf.output.data = hw_identifier_out->data();
    if (!MapAndCopy_Locked(
            hw_update->id(),
            {hw_update->type(), hw_update->size(), &hw_update_buf})) {
      LOG(ERROR) << "Failed mapping Execute buf";
      return false;
    }

    VAStatus va_res = vaProtectedSessionExecute(
        va_display_, va_protected_session_id_, hw_update->id());
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAProtectedSessionExecute,
                         false);

    ScopedVABufferMapping mapping(va_lock_, va_display_, hw_update->id());
    if (!mapping.IsValid()) {
      LOG(ERROR) << "Failed mapping returned Execute buf";
      return false;
    }
    auto* hw_update_buf_out =
        reinterpret_cast<VAProtectedSessionExecuteBuffer*>(mapping.data());
    if (!hw_update_buf_out->output.data_size) {
      LOG(ERROR) << "Received empty HW identifier";
      return false;
    }
    hw_identifier_out->resize(hw_update_buf_out->output.data_size);
    memcpy(hw_identifier_out->data(), hw_update_buf_out->output.data,
           hw_update_buf_out->output.data_size);

    // If the decoding context is created, attach the protected session.
    // Otherwise this is done in CreateContext when the decoding context is
    // created.
    return MaybeAttachProtectedSession_Locked();
  }
#else
  NOTIMPLEMENTED() << "Protected content mode not supported";
  return false;
#endif
}

// static
uint32_t VaapiWrapper::GetProtectedInstanceID() {
  // This sends an ioctl to query for the current instance ID of the protected
  // system. This allows us to track if it was torn down and rebuilt which
  // invalidates everything from prior instances.

  // This is the struct/union used to setup the bitfields properly.
  struct pxp_tag {
    union {
      uint32_t value;
      struct {
        uint32_t session_id : 8;
        uint32_t instance_id : 8;
        uint32_t enable : 1;
        uint32_t hm : 1;
        uint32_t reserved_1 : 1;
        uint32_t sm : 1;
        uint32_t reserved_2 : 12;
      };
    };
  };
  pxp_tag query_tag;
  query_tag.value = 0;
  query_tag.session_id = 0xf;
  query_tag.instance_id = 1;
  query_tag.enable = 1;
  query_tag.hm = 1;

  // Setup the structure for the ioctl.
  struct pxp_info pxp_info;
  pxp_info.action = 0;  // PXP_ACTION_QUERY_PXP_TAG
  pxp_info.query_pxp_tag.session_is_alive = 1;
  pxp_info.query_pxp_tag.pxp_tag = query_tag.value;
  struct drm_i915_pxp_ops pxp_ops = {.info_ptr = &pxp_info,
                                     .info_size = sizeof(pxp_info)};

  base::ScopedFD drm_fd = VADisplayState::Get()->GetDrmFd();
  if (drmIoctl(drm_fd.get(), DRM_IOCTL_I915_PXP_OPS, &pxp_ops)) {
    PLOG(ERROR) << "Error issuing ioctl to get protected instance ID";
    // Zero indicates no protected instance, if we can't query it, then we
    // should behave like we don't have it.
    return 0;
  }

  if (!pxp_info.query_pxp_tag.session_is_alive) {
    // This means that the instance is not alive, return as if there is no
    // instance.
    return 0;
  }

  // Put the result back in the bitfield so we can extract the instance ID.
  query_tag.value = pxp_info.query_pxp_tag.pxp_tag;
  DCHECK_NE(query_tag.instance_id, 0u);
  return query_tag.instance_id;
}

bool VaapiWrapper::IsProtectedSessionDead() {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  return IsProtectedSessionDead(va_protected_session_id_);
#else
  return false;
#endif
}

#if BUILDFLAG(IS_CHROMEOS_ASH)
bool VaapiWrapper::IsProtectedSessionDead(
    VAProtectedSessionID va_protected_session_id) {
  if (va_protected_session_id == VA_INVALID_ID)
    return false;

  uint8_t alive;
  VAProtectedSessionExecuteBuffer tee_exec_buf = {};
  tee_exec_buf.function_id = VA_TEE_EXEC_TEE_FUNCID_IS_SESSION_ALIVE;
  tee_exec_buf.input.data_size = 0;
  tee_exec_buf.input.data = nullptr;
  tee_exec_buf.output.data_size = sizeof(alive);
  tee_exec_buf.output.data = &alive;

  base::AutoLock auto_lock(*va_lock_);
  VABufferID buf_id;
  VAStatus va_res = vaCreateBuffer(
      va_display_, va_protected_session_id, VAProtectedSessionExecuteBufferType,
      sizeof(tee_exec_buf), 1, &tee_exec_buf, &buf_id);
  // Failure here is valid if the protected session has been closed.
  if (va_res != VA_STATUS_SUCCESS)
    return true;

  va_res =
      vaProtectedSessionExecute(va_display_, va_protected_session_id, buf_id);
  vaDestroyBuffer(va_display_, buf_id);
  if (va_res != VA_STATUS_SUCCESS)
    return true;

  return !alive;
}
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
VAProtectedSessionID VaapiWrapper::GetProtectedSessionID() const {
  return va_protected_session_id_;
}
#endif

void VaapiWrapper::DestroyProtectedSession() {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (va_protected_session_id_ == VA_INVALID_ID)
    return;
  base::AutoLock auto_lock(*va_lock_);
  VAStatus va_res =
      vaDestroyProtectedSession(va_display_, va_protected_session_id_);
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyProtectedSession);
  va_res = vaDestroyConfig(va_display_, va_protected_config_id_);
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyConfig);
  va_protected_session_id_ = VA_INVALID_ID;
  va_protected_config_id_ = VA_INVALID_ID;
#endif
}

void VaapiWrapper::DestroyContextAndSurfaces(
    std::vector<VASurfaceID> va_surfaces) {
  DestroyContext();
  DestroySurfaces(va_surfaces);
}

bool VaapiWrapper::CreateContext(const gfx::Size& size) {
  DVLOG(2) << "Creating context";
  base::AutoLock auto_lock(*va_lock_);

  // vaCreateContext() doesn't really need an array of VASurfaceIDs (see
  // https://lists.01.org/pipermail/intel-vaapi-media/2017-July/000052.html and
  // https://github.com/intel/libva/issues/251); pass a dummy list of valid
  // (non-null) IDs until the signature gets updated.
  constexpr VASurfaceID* empty_va_surfaces_ids_pointer = nullptr;
  constexpr size_t empty_va_surfaces_ids_size = 0u;

  // No flag must be set and passing picture size is irrelevant in the case of
  // vpp, just passing 0x0.
  const int flag = mode_ != kVideoProcess ? VA_PROGRESSIVE : 0x0;
  const gfx::Size picture_size = mode_ != kVideoProcess ? size : gfx::Size();
  if (base::FeatureList::IsEnabled(kVaapiEnforceVideoMinMaxResolution) &&
      mode_ != kVideoProcess) {
    const VASupportedProfiles::ProfileInfo* profile_info =
        VASupportedProfiles::Get().IsProfileSupported(mode_, va_profile_,
                                                      va_entrypoint_);
    DCHECK(profile_info);
    const bool is_picture_within_bounds =
        gfx::Rect(picture_size)
            .Contains(gfx::Rect(profile_info->min_resolution)) &&
        gfx::Rect(profile_info->max_resolution)
            .Contains(gfx::Rect(picture_size));
    if (!is_picture_within_bounds) {
      VLOG(2) << "Requested resolution=" << picture_size.ToString()
              << " is not within bounds ["
              << profile_info->min_resolution.ToString() << ", "
              << profile_info->max_resolution.ToString() << "]";
      return false;
    }
  }

  VAStatus va_res = vaCreateContext(
      va_display_, va_config_id_, picture_size.width(), picture_size.height(),
      flag, empty_va_surfaces_ids_pointer, empty_va_surfaces_ids_size,
      &va_context_id_);
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVACreateContext);
  if (va_res != VA_STATUS_SUCCESS)
    return false;

  if (IsModeEncoding(mode_) && IsLowPowerIntelProcessor())
    MaybeSetLowQualityEncoding_Locked();

  // If we have a protected session already, attach it to this new context.
  return MaybeAttachProtectedSession_Locked();
}

scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForPixmap(
    scoped_refptr<gfx::NativePixmap> pixmap,
    bool protected_content) {
  const gfx::BufferFormat buffer_format = pixmap->GetBufferFormat();

  // Create a VASurface for a NativePixmap by importing the underlying dmabufs.
  const gfx::Size size = pixmap->GetBufferSize();
  VASurfaceAttribExternalBuffers va_attrib_extbuf{};
  va_attrib_extbuf.pixel_format = BufferFormatToVAFourCC(buffer_format);
  va_attrib_extbuf.width = size.width();
  va_attrib_extbuf.height = size.height();

  const size_t num_planes = pixmap->GetNumberOfPlanes();
  for (size_t i = 0; i < num_planes; ++i) {
    va_attrib_extbuf.pitches[i] = pixmap->GetDmaBufPitch(i);
    va_attrib_extbuf.offsets[i] = pixmap->GetDmaBufOffset(i);
    DVLOG(4) << "plane " << i << ": pitch: " << va_attrib_extbuf.pitches[i]
             << " offset: " << va_attrib_extbuf.offsets[i];
  }
  va_attrib_extbuf.num_planes = num_planes;

  const int dma_buf_fd = pixmap->GetDmaBufFd(0);
  if (dma_buf_fd < 0) {
    LOG(ERROR) << "Failed to get dmabuf from an Ozone NativePixmap";
    return nullptr;
  }
  const off_t data_size = lseek(dma_buf_fd, /*offset=*/0, SEEK_END);
  if (data_size == static_cast<off_t>(-1)) {
    PLOG(ERROR) << "Failed to get the size of the dma-buf";
    return nullptr;
  }
  if (lseek(dma_buf_fd, /*offset=*/0, SEEK_SET) == static_cast<off_t>(-1)) {
    PLOG(ERROR) << "Failed to reset the file offset of the dma-buf";
    return nullptr;
  }
  // If the data size doesn't fit in a uint32_t, we probably have bigger
  // problems.
  va_attrib_extbuf.data_size = base::checked_cast<uint32_t>(data_size);

  // We only have to pass the first file descriptor to a driver. A VA-API driver
  // shall create a VASurface from the single fd correctly.
  uintptr_t fd = base::checked_cast<uintptr_t>(dma_buf_fd);
  va_attrib_extbuf.buffers = &fd;
  va_attrib_extbuf.num_buffers = 1u;

  DCHECK_EQ(va_attrib_extbuf.flags, 0u);
  DCHECK_EQ(va_attrib_extbuf.private_data, nullptr);

  uint32_t va_format = BufferFormatToVARTFormat(buffer_format);

  if (protected_content) {
    if (GetImplementationType() == VAImplementation::kMesaGallium)
      va_format |= VA_RT_FORMAT_PROTECTED;
    else
      va_attrib_extbuf.flags = VA_SURFACE_EXTBUF_DESC_PROTECTED;
  }

  std::vector<VASurfaceAttrib> va_attribs(2);

  va_attribs[0].type = VASurfaceAttribMemoryType;
  va_attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
  va_attribs[0].value.type = VAGenericValueTypeInteger;
  va_attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;

  va_attribs[1].type = VASurfaceAttribExternalBufferDescriptor;
  va_attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
  va_attribs[1].value.type = VAGenericValueTypePointer;
  va_attribs[1].value.value.p = &va_attrib_extbuf;

  VASurfaceID va_surface_id = VA_INVALID_ID;
  {
    base::AutoLock auto_lock(*va_lock_);
    VAStatus va_res = vaCreateSurfaces(
        va_display_, va_format, base::checked_cast<unsigned int>(size.width()),
        base::checked_cast<unsigned int>(size.height()), &va_surface_id, 1,
        &va_attribs[0], va_attribs.size());
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateSurfaces_Importing,
                         nullptr);
  }
  DVLOG(2) << __func__ << " " << va_surface_id;
  // VASurface shares an ownership of the buffer referred by the passed file
  // descriptor. We can release |pixmap| here.
  return new VASurface(va_surface_id, size, va_format,
                       base::BindOnce(&VaapiWrapper::DestroySurface, this));
}

scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForUserPtr(
    const gfx::Size& size,
    uintptr_t* buffers,
    size_t buffer_size) {
  VASurfaceAttribExternalBuffers va_attrib_extbuf{};
  va_attrib_extbuf.num_planes = 3;
  va_attrib_extbuf.buffers = buffers;
  va_attrib_extbuf.data_size = base::checked_cast<uint32_t>(buffer_size);
  va_attrib_extbuf.num_buffers = 1u;
  va_attrib_extbuf.width = base::checked_cast<uint32_t>(size.width());
  va_attrib_extbuf.height = base::checked_cast<uint32_t>(size.height());
  va_attrib_extbuf.offsets[0] = 0;
  va_attrib_extbuf.offsets[1] = size.GetCheckedArea().ValueOrDie<uint32_t>();
  va_attrib_extbuf.offsets[2] =
      (size.GetCheckedArea() * 2).ValueOrDie<uint32_t>();
  std::fill(va_attrib_extbuf.pitches, va_attrib_extbuf.pitches + 3,
            base::checked_cast<uint32_t>(size.width()));
  va_attrib_extbuf.pixel_format = VA_FOURCC_RGBP;

  std::vector<VASurfaceAttrib> va_attribs(2);
  va_attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
  va_attribs[0].type = VASurfaceAttribMemoryType;
  va_attribs[0].value.type = VAGenericValueTypeInteger;
  va_attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR;

  va_attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
  va_attribs[1].type = VASurfaceAttribExternalBufferDescriptor;
  va_attribs[1].value.type = VAGenericValueTypePointer;
  va_attribs[1].value.value.p = &va_attrib_extbuf;

  VASurfaceID va_surface_id = VA_INVALID_ID;
  const unsigned int va_format = VA_RT_FORMAT_RGBP;
  {
    base::AutoLock auto_lock(*va_lock_);
    VAStatus va_res = vaCreateSurfaces(
        va_display_, va_format, base::checked_cast<unsigned int>(size.width()),
        base::checked_cast<unsigned int>(size.height()), &va_surface_id, 1,
        &va_attribs[0], va_attribs.size());
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateSurfaces_Importing,
                         nullptr);
  }
  DVLOG(2) << __func__ << " " << va_surface_id;
  return new VASurface(va_surface_id, size, va_format,
                       base::BindOnce(&VaapiWrapper::DestroySurface, this));
}

std::unique_ptr<NativePixmapAndSizeInfo>
VaapiWrapper::ExportVASurfaceAsNativePixmapDmaBuf(
    const ScopedVASurface& scoped_va_surface) {
  if (!scoped_va_surface.IsValid()) {
    LOG(ERROR) << "Cannot export an invalid surface";
    return nullptr;
  }

  VADRMPRIMESurfaceDescriptor descriptor;
  {
    base::AutoLock auto_lock(*va_lock_);
    VAStatus va_res = vaSyncSurface(va_display_, scoped_va_surface.id());
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, nullptr);
    va_res = vaExportSurfaceHandle(
        va_display_, scoped_va_surface.id(),
        VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
        VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS,
        &descriptor);
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAExportSurfaceHandle,
                         nullptr);
  }

  // We only support one bo containing all the planes. The fd should be owned by
  // us: per va/va.h, "the exported handles are owned by the caller."
  //
  // TODO(crbug.com/974438): support multiple buffer objects so that this can
  // work in AMD.
  if (descriptor.num_objects != 1u) {
    DVLOG(1) << "Only surface descriptors with one bo are supported";
    NOTREACHED();
    return nullptr;
  }
  base::ScopedFD bo_fd(descriptor.objects[0].fd);
  const uint64_t bo_modifier = descriptor.objects[0].drm_format_modifier;

  // Translate the pixel format to a gfx::BufferFormat.
  gfx::BufferFormat buffer_format;
  switch (descriptor.fourcc) {
    case VA_FOURCC_IMC3:
      // IMC3 is like I420 but all the planes have the same stride. This is used
      // for decoding 4:2:0 JPEGs in the Intel i965 driver. We don't currently
      // have a gfx::BufferFormat for YUV420. Instead, we reuse YVU_420 and
      // later swap the U and V planes.
      //
      // TODO(andrescj): revisit this once crrev.com/c/1573718 lands.
      buffer_format = gfx::BufferFormat::YVU_420;
      break;
    case VA_FOURCC_NV12:
      buffer_format = gfx::BufferFormat::YUV_420_BIPLANAR;
      break;
    default:
      LOG(ERROR) << "Cannot export a surface with FOURCC "
                 << FourccToString(descriptor.fourcc);
      return nullptr;
  }

  gfx::NativePixmapHandle handle{};
  handle.modifier = bo_modifier;
  for (uint32_t layer = 0; layer < descriptor.num_layers; layer++) {
    // According to va/va_drmcommon.h, if VA_EXPORT_SURFACE_SEPARATE_LAYERS is
    // specified, each layer should contain one plane.
    DCHECK_EQ(1u, descriptor.layers[layer].num_planes);

    // Strictly speaking, we only have to dup() the fd for the planes after the
    // first one since we already own the first one, but we dup() regardless for
    // simplicity: |bo_fd| will be closed at the end of this method anyway.
    base::ScopedFD plane_fd(HANDLE_EINTR(dup(bo_fd.get())));
    PCHECK(plane_fd.is_valid());
    constexpr uint64_t kZeroSizeToPreventMapping = 0u;
    handle.planes.emplace_back(
        base::checked_cast<int>(descriptor.layers[layer].pitch[0]),
        base::checked_cast<int>(descriptor.layers[layer].offset[0]),
        kZeroSizeToPreventMapping,
        base::ScopedFD(HANDLE_EINTR(dup(bo_fd.get()))));
  }

  if (descriptor.fourcc == VA_FOURCC_IMC3) {
    // Recall that for VA_FOURCC_IMC3, we will return a format of
    // gfx::BufferFormat::YVU_420, so we need to swap the U and V planes to keep
    // the semantics.
    DCHECK_EQ(3u, handle.planes.size());
    std::swap(handle.planes[1], handle.planes[2]);
  }

  auto exported_pixmap = std::make_unique<NativePixmapAndSizeInfo>();
  exported_pixmap->va_surface_resolution =
      gfx::Size(base::checked_cast<int>(descriptor.width),
                base::checked_cast<int>(descriptor.height));
  exported_pixmap->byte_size =
      base::strict_cast<size_t>(descriptor.objects[0].size);
  if (!gfx::Rect(exported_pixmap->va_surface_resolution)
           .Contains(gfx::Rect(scoped_va_surface.size()))) {
    LOG(ERROR) << "A " << scoped_va_surface.size().ToString()
               << " ScopedVASurface cannot be contained by a "
               << exported_pixmap->va_surface_resolution.ToString()
               << " buffer";
    return nullptr;
  }
  exported_pixmap->pixmap = base::MakeRefCounted<gfx::NativePixmapDmaBuf>(
      scoped_va_surface.size(), buffer_format, std::move(handle));
  return exported_pixmap;
}

bool VaapiWrapper::SyncSurface(VASurfaceID va_surface_id) {
  DCHECK_NE(va_surface_id, VA_INVALID_ID);

  base::AutoLock auto_lock(*va_lock_);

  VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, false);
  return true;
}

bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type,
                                size_t size,
                                const void* data) {
  TRACE_EVENT0("media,gpu", "VaapiWrapper::SubmitBuffer");
  base::AutoLock auto_lock(*va_lock_);
  return SubmitBuffer_Locked({va_buffer_type, size, data});
}

bool VaapiWrapper::SubmitBuffers(
    const std::vector<VABufferDescriptor>& va_buffers) {
  TRACE_EVENT0("media,gpu", "VaapiWrapper::SubmitBuffers");
  base::AutoLock auto_lock(*va_lock_);
  for (const VABufferDescriptor& va_buffer : va_buffers) {
    if (!SubmitBuffer_Locked(va_buffer))
      return false;
  }
  return true;
}

void VaapiWrapper::DestroyPendingBuffers() {
  TRACE_EVENT0("media,gpu", "VaapiWrapper::DestroyPendingBuffers");
  base::AutoLock auto_lock(*va_lock_);
  DestroyPendingBuffers_Locked();
}

void VaapiWrapper::DestroyPendingBuffers_Locked() {
  TRACE_EVENT0("media,gpu", "VaapiWrapper::DestroyPendingBuffers_Locked");
  va_lock_->AssertAcquired();
  for (const auto& pending_va_buf : pending_va_buffers_) {
    VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_buf);
    VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyBuffer);
  }
  pending_va_buffers_.clear();
}

bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
  base::AutoLock auto_lock(*va_lock_);
  bool result = Execute_Locked(va_surface_id, pending_va_buffers_);
  DestroyPendingBuffers_Locked();
  return result;
}

bool VaapiWrapper::MapAndCopyAndExecute(
    VASurfaceID va_surface_id,
    const std::vector<std::pair<VABufferID, VABufferDescriptor>>& va_buffers) {
  DCHECK_NE(va_surface_id, VA_INVALID_SURFACE);

  TRACE_EVENT0("media,gpu", "VaapiWrapper::MapAndCopyAndExecute");
  base::AutoLock auto_lock(*va_lock_);
  std::vector<VABufferID> va_buffer_ids;

  for (const auto& va_buffer : va_buffers) {
    const VABufferID va_buffer_id = va_buffer.first;
    const VABufferDescriptor& descriptor = va_buffer.second;
    DCHECK_NE(va_buffer_id, VA_INVALID_ID);

    if (!MapAndCopy_Locked(va_buffer_id, descriptor))
      return false;

    va_buffer_ids.push_back(va_buffer_id);
  }

  return Execute_Locked(va_surface_id, va_buffer_ids);
}

#if BUILDFLAG(USE_VAAPI_X11)
bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
                                        x11::Pixmap x_pixmap,
                                        gfx::Size dest_size) {
  base::AutoLock auto_lock(*va_lock_);

  VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, false);

  // Put the data into an X Pixmap.
  va_res =
      vaPutSurface(va_display_, va_surface_id, static_cast<uint32_t>(x_pixmap),
                   0, 0, dest_size.width(), dest_size.height(), 0, 0,
                   dest_size.width(), dest_size.height(), nullptr, 0, 0);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAPutSurface, false);
  return true;
}
#endif  // BUILDFLAG(USE_VAAPI_X11)

std::unique_ptr<ScopedVAImage> VaapiWrapper::CreateVaImage(
    VASurfaceID va_surface_id,
    VAImageFormat* format,
    const gfx::Size& size) {
  std::unique_ptr<ScopedVAImage> scoped_image;
  {
    base::AutoLock auto_lock(*va_lock_);

    VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, nullptr);

    scoped_image = std::make_unique<ScopedVAImage>(va_lock_, va_display_,
                                                   va_surface_id, format, size);
  }
  return scoped_image->IsValid() ? std::move(scoped_image) : nullptr;
}

bool VaapiWrapper::UploadVideoFrameToSurface(const VideoFrame& frame,
                                             VASurfaceID va_surface_id,
                                             const gfx::Size& va_surface_size) {
  TRACE_EVENT0("media,gpu", "VaapiWrapper::UploadVideoFrameToSurface");
  base::AutoLock auto_lock(*va_lock_);
  TRACE_EVENT0("media,gpu", "VaapiWrapper::UploadVideoFrameToSurfaceLocked");

  if (frame.visible_rect().origin() != gfx::Point(0, 0)) {
    LOG(ERROR) << "The origin of the frame's visible rectangle is not (0, 0), "
               << "frame.visible_rect().origin()="
               << frame.visible_rect().origin().ToString();
    return false;
  }

  const gfx::Size visible_size = frame.visible_rect().size();
  bool needs_va_put_image = false;
  VAImage image;
  VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image);
  if (va_res == VA_STATUS_ERROR_OPERATION_FAILED) {
    DVLOG(4) << "vaDeriveImage failed and fallback to Create_PutImage";
    constexpr VAImageFormat kImageFormatNV12{.fourcc = VA_FOURCC_NV12,
                                             .byte_order = VA_LSB_FIRST,
                                             .bits_per_pixel = 12};
    VAImageFormat image_format = kImageFormatNV12;

    va_res = vaCreateImage(va_display_, &image_format, va_surface_size.width(),
                           va_surface_size.height(), &image);
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateImage, false);
    needs_va_put_image = true;
  }
  base::ScopedClosureRunner vaimage_deleter(
      base::BindOnce(&DestroyVAImage, va_display_, image));

  if (image.format.fourcc != VA_FOURCC_NV12) {
    LOG(ERROR) << "Unsupported image format: " << image.format.fourcc;
    return false;
  }

  if (image.width % 2 != 0 || image.height % 2 != 0) {
    LOG(ERROR) << "Buffer's width and height are not even, "
               << "width=" << image.width << ", height=" << image.height;
    return false;
  }

  if (!gfx::Rect(image.width, image.height).Contains(gfx::Rect(visible_size))) {
    LOG(ERROR) << "Buffer too small to fit the frame.";
    return false;
  }

  ScopedVABufferMapping mapping(va_lock_, va_display_, image.buf);
  if (!mapping.IsValid())
    return false;
  uint8_t* image_ptr = static_cast<uint8_t*>(mapping.data());

  if (!ClearNV12Padding(image, visible_size, image_ptr)) {
    LOG(ERROR) << "Failed to clear non visible area of VAImage";
    return false;
  }

  int ret = 0;
  {
    TRACE_EVENT0("media,gpu", "VaapiWrapper::UploadVideoFrameToSurface_copy");

    base::AutoUnlock auto_unlock(*va_lock_);
    switch (frame.format()) {
      case PIXEL_FORMAT_I420:
        ret = libyuv::I420ToNV12(
            frame.data(VideoFrame::kYPlane), frame.stride(VideoFrame::kYPlane),
            frame.data(VideoFrame::kUPlane), frame.stride(VideoFrame::kUPlane),
            frame.data(VideoFrame::kVPlane), frame.stride(VideoFrame::kVPlane),
            image_ptr + image.offsets[0], image.pitches[0],
            image_ptr + image.offsets[1], image.pitches[1],
            visible_size.width(), visible_size.height());
        break;
      case PIXEL_FORMAT_NV12: {
        int uv_width = visible_size.width();
        if (visible_size.width() % 2 != 0 &&
            !base::CheckAdd<int>(visible_size.width(), 1)
                 .AssignIfValid(&uv_width)) {
          return false;
        }

        int uv_height = 0;
        if (!(base::CheckAdd<int>(visible_size.height(), 1) / 2)
                 .AssignIfValid(&uv_height)) {
          return false;
        }

        libyuv::CopyPlane(frame.data(VideoFrame::kYPlane),
                          frame.stride(VideoFrame::kYPlane),
                          image_ptr + image.offsets[0], image.pitches[0],
                          visible_size.width(), visible_size.height());
        libyuv::CopyPlane(frame.data(VideoFrame::kUVPlane),
                          frame.stride(VideoFrame::kUVPlane),
                          image_ptr + image.offsets[1], image.pitches[1],
                          uv_width, uv_height);
      } break;
      default:
        LOG(ERROR) << "Unsupported pixel format: " << frame.format();
        return false;
    }
  }
  if (needs_va_put_image) {
    const VAStatus va_res =
        vaPutImage(va_display_, va_surface_id, image.image_id, 0, 0,
                   visible_size.width(), visible_size.height(), 0, 0,
                   visible_size.width(), visible_size.height());
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAPutImage, false);
  }
  return ret == 0;
}

std::unique_ptr<ScopedVABuffer> VaapiWrapper::CreateVABuffer(VABufferType type,
                                                             size_t size) {
  TRACE_EVENT0("media,gpu", "VaapiWrapper::CreateVABuffer");
  base::AutoLock auto_lock(*va_lock_);
  TRACE_EVENT0("media,gpu", "VaapiWrapper::CreateVABufferLocked");
#if BUILDFLAG(IS_CHROMEOS_ASH)
  VAContextID context_id = type == VAProtectedSessionExecuteBufferType
                               ? va_protected_session_id_
                               : va_context_id_;
#else
  VAContextID context_id = va_context_id_;
#endif

  if (context_id == VA_INVALID_ID)
    return nullptr;
  return ScopedVABuffer::Create(va_lock_, va_display_, context_id, type, size);
}

uint64_t VaapiWrapper::GetEncodedChunkSize(VABufferID buffer_id,
                                           VASurfaceID sync_surface_id) {
  TRACE_EVENT0("media,gpu", "VaapiWrapper::GetEncodedChunkSize");
  base::AutoLock auto_lock(*va_lock_);
  TRACE_EVENT0("media,gpu", "VaapiWrapper::GetEncodedChunkSizeLocked");
  VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, 0u);

  ScopedVABufferMapping mapping(va_lock_, va_display_, buffer_id);
  if (!mapping.IsValid())
    return 0u;

  uint64_t coded_data_size = 0;
  for (auto* buffer_segment =
           reinterpret_cast<VACodedBufferSegment*>(mapping.data());
       buffer_segment; buffer_segment = reinterpret_cast<VACodedBufferSegment*>(
                           buffer_segment->next)) {
    coded_data_size += buffer_segment->size;
  }
  return coded_data_size;
}

bool VaapiWrapper::DownloadFromVABuffer(VABufferID buffer_id,
                                        VASurfaceID sync_surface_id,
                                        uint8_t* target_ptr,
                                        size_t target_size,
                                        size_t* coded_data_size) {
  DCHECK(target_ptr);
  TRACE_EVENT0("media,gpu", "VaapiWrapper::DownloadFromVABuffer");
  base::AutoLock auto_lock(*va_lock_);
  TRACE_EVENT0("media,gpu", "VaapiWrapper::DownloadFromVABufferLocked");

  // vaSyncSurface() is not necessary on Intel platforms as long as there is a
  // vaMapBuffer() like in ScopedVABufferMapping below, see b/184312032.
  if (GetImplementationType() != VAImplementation::kIntelI965 &&
      GetImplementationType() != VAImplementation::kIntelIHD) {
    TRACE_EVENT0("media,gpu", "VaapiWrapper::DownloadFromVABuffer_SyncSurface");
    const VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id);
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, false);
  }

  ScopedVABufferMapping mapping(va_lock_, va_display_, buffer_id);
  if (!mapping.IsValid())
    return false;
  auto* buffer_segment =
      reinterpret_cast<VACodedBufferSegment*>(mapping.data());

  // memcpy calls should be fast, unlocking and relocking for unmapping might
  // cause another thread to acquire the lock and we'd have to wait delaying the
  // notification that the encode is done.
  {
    TRACE_EVENT0("media,gpu", "VaapiWrapper::DownloadFromVABuffer_copy");
    *coded_data_size = 0;

    while (buffer_segment) {
      DCHECK(buffer_segment->buf);

      if (buffer_segment->size > target_size) {
        LOG(ERROR) << "Insufficient output buffer size: " << target_size
                   << ", the buffer segment size: " << buffer_segment->size;
        break;
      }
      memcpy(target_ptr, buffer_segment->buf, buffer_segment->size);

      target_ptr += buffer_segment->size;
      target_size -= buffer_segment->size;
      *coded_data_size += buffer_segment->size;
      buffer_segment =
          reinterpret_cast<VACodedBufferSegment*>(buffer_segment->next);
    }
  }

  return buffer_segment == nullptr;
}

bool VaapiWrapper::GetVAEncMaxNumOfRefFrames(VideoCodecProfile profile,
                                             size_t* max_ref_frames) {
  const VAProfile va_profile =
      ProfileToVAProfile(profile, CodecMode::kEncodeConstantBitrate);
  VAConfigAttrib attrib;
  attrib.type = VAConfigAttribEncMaxRefFrames;

  base::AutoLock auto_lock(*va_lock_);
  VAStatus va_res = vaGetConfigAttributes(va_display_, va_profile,
                                          va_entrypoint_, &attrib, 1);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAGetConfigAttributes, false);

  *max_ref_frames = attrib.value;
  return true;
}

bool VaapiWrapper::GetSupportedPackedHeaders(VideoCodecProfile profile,
                                             bool& packed_sps,
                                             bool& packed_pps,
                                             bool& packed_slice) {
  const VAProfile va_profile =
      ProfileToVAProfile(profile, CodecMode::kEncodeConstantBitrate);
  VAConfigAttrib attrib{};
  attrib.type = VAConfigAttribEncPackedHeaders;
  base::AutoLock auto_lock(*va_lock_);
  const VAStatus va_res = vaGetConfigAttributes(va_display_, va_profile,
                                                va_entrypoint_, &attrib, 1);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAGetConfigAttributes, false);
  packed_sps = attrib.value & VA_ENC_PACKED_HEADER_SEQUENCE;
  packed_pps = attrib.value & VA_ENC_PACKED_HEADER_PICTURE;
  packed_slice = attrib.value & VA_ENC_PACKED_HEADER_SLICE;

  return true;
}

bool VaapiWrapper::IsRotationSupported() {
  base::AutoLock auto_lock(*va_lock_);
  VAProcPipelineCaps pipeline_caps;
  memset(&pipeline_caps, 0, sizeof(pipeline_caps));
  VAStatus va_res = vaQueryVideoProcPipelineCaps(va_display_, va_context_id_,
                                                 nullptr, 0, &pipeline_caps);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAQueryVideoProcPipelineCaps,
                       false);

  if (!pipeline_caps.rotation_flags) {
    DVLOG(2) << "VA-API driver doesn't support any rotation";
    return false;
  }
  return true;
}

bool VaapiWrapper::BlitSurface(const VASurface& va_surface_src,
                               const VASurface& va_surface_dest,
                               absl::optional<gfx::Rect> src_rect,
                               absl::optional<gfx::Rect> dest_rect,
                               VideoRotation rotation
#if BUILDFLAG(IS_CHROMEOS_ASH)
                               ,
                               VAProtectedSessionID va_protected_session_id
#endif
) {
  DCHECK_EQ(mode_, kVideoProcess);
  base::AutoLock auto_lock(*va_lock_);

  // Create a buffer for VPP if it has not been created.
  if (!va_buffer_for_vpp_) {
    DCHECK_NE(VA_INVALID_ID, va_context_id_);
    va_buffer_for_vpp_ =
        ScopedVABuffer::Create(va_lock_, va_display_, va_context_id_,
                               VAProcPipelineParameterBufferType,
                               sizeof(VAProcPipelineParameterBuffer));
    if (!va_buffer_for_vpp_)
      return false;
  }

  // Note that since we store pointers to these regions in our mapping below,
  // these may be accessed after the Unmap() below. These must therefore live
  // until the end of the function.
  VARectangle input_region;
  VARectangle output_region;
  {
    ScopedVABufferMapping mapping(va_lock_, va_display_,
                                  va_buffer_for_vpp_->id());
    if (!mapping.IsValid())
      return false;
    auto* pipeline_param =
        reinterpret_cast<VAProcPipelineParameterBuffer*>(mapping.data());

    memset(pipeline_param, 0, sizeof *pipeline_param);
    if (!src_rect)
      src_rect.emplace(gfx::Rect(va_surface_src.size()));
    if (!dest_rect)
      dest_rect.emplace(gfx::Rect(va_surface_dest.size()));

    input_region.x = src_rect->x();
    input_region.y = src_rect->y();
    input_region.width = src_rect->width();
    input_region.height = src_rect->height();
    pipeline_param->surface_region = &input_region;
    pipeline_param->surface = va_surface_src.id();
    pipeline_param->surface_color_standard = VAProcColorStandardNone;

    output_region.x = dest_rect->x();
    output_region.y = dest_rect->y();
    output_region.width = dest_rect->width();
    output_region.height = dest_rect->height();
    pipeline_param->output_region = &output_region;
    pipeline_param->output_background_color = 0xff000000;
    pipeline_param->output_color_standard = VAProcColorStandardNone;
    pipeline_param->filter_flags = VA_FILTER_SCALING_DEFAULT;

    switch (rotation) {
      case VIDEO_ROTATION_0:
        pipeline_param->rotation_state = VA_ROTATION_NONE;
        break;
      case VIDEO_ROTATION_90:
        pipeline_param->rotation_state = VA_ROTATION_90;
        break;
      case VIDEO_ROTATION_180:
        pipeline_param->rotation_state = VA_ROTATION_180;
        break;
      case VIDEO_ROTATION_270:
        pipeline_param->rotation_state = VA_ROTATION_270;
        break;
    }

    const VAStatus va_res = mapping.Unmap();
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAUnmapBuffer, false);
  }

#if BUILDFLAG(IS_CHROMEOS_ASH)
  base::ScopedClosureRunner protected_session_detacher;
  if (va_protected_session_id != VA_INVALID_ID) {
    const VAStatus va_res = vaAttachProtectedSession(
        va_display_, va_context_id_, va_protected_session_id);
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAAttachProtectedSession,
                         false);
    // Note that we use a lambda expression to wrap vaDetachProtectedSession()
    // because the function in |protected_session_detacher| must return void.
    protected_session_detacher.ReplaceClosure(base::BindOnce(
        [](VADisplay va_display, VAContextID va_context_id) {
          vaDetachProtectedSession(va_display, va_context_id);
        },
        va_display_, va_context_id_));
  }
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

  TRACE_EVENT2("media,gpu", "VaapiWrapper::BlitSurface", "src_rect",
               src_rect->ToString(), "dest_rect", dest_rect->ToString());

  VAStatus va_res =
      vaBeginPicture(va_display_, va_context_id_, va_surface_dest.id());
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVABeginPicture, false);

  VABufferID va_buffer_id = va_buffer_for_vpp_->id();
  va_res = vaRenderPicture(va_display_, va_context_id_, &va_buffer_id, 1);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVARenderPicture_Vpp, false);
  va_res = vaEndPicture(va_display_, va_context_id_);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAEndPicture, false);

  return true;
}

// static
void VaapiWrapper::PreSandboxInitialization() {
  VADisplayState::PreSandboxInitialization();

  const std::string va_suffix(std::to_string(VA_MAJOR_VERSION + 1));
  StubPathMap paths;

  paths[kModuleVa].push_back(std::string("libva.so.") + va_suffix);
  paths[kModuleVa_drm].push_back(std::string("libva-drm.so.") + va_suffix);
#if BUILDFLAG(USE_VAAPI_X11)
  paths[kModuleVa_x11].push_back(std::string("libva-x11.so.") + va_suffix);
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
  paths[kModuleVa_prot].push_back(std::string("libva.so.") + va_suffix);
#endif

  // InitializeStubs dlopen() VA-API libraries
  // libva.so
  // libva-x11.so (X11)
  // libva-drm.so (X11 and Ozone).
  static bool result = InitializeStubs(paths);
  if (!result) {
    static const char kErrorMsg[] = "Failed to initialize VAAPI libs";
#if defined(OS_CHROMEOS)
    // When Chrome runs on Linux with target_os="chromeos", do not log error
    // message without VAAPI libraries.
    LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS()) << kErrorMsg;
#else
    DVLOG(1) << kErrorMsg;
#endif
  }

  // VASupportedProfiles::Get creates VADisplayState and in so doing
  // driver associated libraries are dlopen(), to know:
  // i965_drv_video.so
  // hybrid_drv_video.so (platforms that support it)
  // libcmrt.so (platforms that support it)
  VASupportedProfiles::Get();
}

VaapiWrapper::VaapiWrapper(CodecMode mode)
    : mode_(mode),
      va_lock_(VADisplayState::Get()->va_lock()),
      va_display_(NULL),
      va_profile_(VAProfileNone),
      va_entrypoint_(kVAEntrypointInvalid) {}

VaapiWrapper::~VaapiWrapper() {
  // Destroy ScopedVABuffer before VaapiWrappers are destroyed to ensure
  // VADisplay is valid on ScopedVABuffer's destruction.
  va_buffer_for_vpp_.reset();
  DestroyPendingBuffers();
  DestroyContext();
  Deinitialize();
}

bool VaapiWrapper::Initialize(VAProfile va_profile,
                              EncryptionScheme encryption_scheme) {
#if DCHECK_IS_ON()
  if (mode_ == kEncodeConstantQuantizationParameter) {
    DCHECK_NE(va_profile, VAProfileJPEGBaseline)
        << "JPEG Encoding doesn't support CQP bitrate control";
  }
#endif  // DCHECK_IS_ON()

#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (encryption_scheme != EncryptionScheme::kUnencrypted &&
      mode_ != kDecodeProtected) {
    return false;
  }
#endif

  const VAEntrypoint entrypoint = GetDefaultVaEntryPoint(mode_, va_profile);

  base::AutoLock auto_lock(*va_lock_);
  std::vector<VAConfigAttrib> required_attribs;
  if (!GetRequiredAttribs(va_lock_, va_display_, mode_, va_profile, entrypoint,
                          &required_attribs)) {
    return false;
  }

#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (encryption_scheme != EncryptionScheme::kUnencrypted) {
    DCHECK(!required_attribs.empty());
    // We need to adjust the attribute for encryption scheme.
    for (auto& attrib : required_attribs) {
      if (attrib.type == VAConfigAttribEncryption) {
        attrib.value = (encryption_scheme == EncryptionScheme::kCbcs)
                           ? VA_ENCRYPTION_TYPE_SUBSAMPLE_CBC
                           : VA_ENCRYPTION_TYPE_SUBSAMPLE_CTR;
      }
    }
  }
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

  const VAStatus va_res =
      vaCreateConfig(va_display_, va_profile, entrypoint,
                     required_attribs.empty() ? nullptr : &required_attribs[0],
                     required_attribs.size(), &va_config_id_);
  va_profile_ = va_profile;
  va_entrypoint_ = entrypoint;

  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateConfig, false);
  return true;
}

void VaapiWrapper::Deinitialize() {
  {
    base::AutoLock auto_lock(*va_lock_);
#if BUILDFLAG(IS_CHROMEOS_ASH)
    if (va_protected_session_id_ != VA_INVALID_ID) {
      VAStatus va_res =
          vaDestroyProtectedSession(va_display_, va_protected_session_id_);
      VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyProtectedSession);
      va_res = vaDestroyConfig(va_display_, va_protected_config_id_);
      VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyConfig);
    }
#endif
    if (va_config_id_ != VA_INVALID_ID) {
      const VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_);
      VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyConfig);
    }
#if BUILDFLAG(IS_CHROMEOS_ASH)
    va_protected_session_id_ = VA_INVALID_ID;
    va_protected_config_id_ = VA_INVALID_ID;
#endif
    va_config_id_ = VA_INVALID_ID;
    va_display_ = nullptr;
  }

  const VAStatus va_res = VADisplayState::Get()->Deinitialize();
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVATerminate);
}

bool VaapiWrapper::VaInitialize(
    const ReportErrorToUMACB& report_error_to_uma_cb) {
  report_error_to_uma_cb_ = report_error_to_uma_cb;
  if (!VADisplayState::Get()->Initialize())
    return false;

  {
    base::AutoLock auto_lock(*va_lock_);
    va_display_ = VADisplayState::Get()->va_display();
    DCHECK(va_display_) << "VADisplayState hasn't been properly Initialize()d";
  }
  return true;
}

void VaapiWrapper::DestroyContext() {
  base::AutoLock auto_lock(*va_lock_);
  DVLOG(2) << "Destroying context";

  if (va_context_id_ != VA_INVALID_ID) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
    if (va_protected_session_id_ != VA_INVALID_ID) {
      const VAStatus va_res =
          vaDetachProtectedSession(va_display_, va_context_id_);
      VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADetachProtectedSession);
    }
#endif
    const VAStatus va_res = vaDestroyContext(va_display_, va_context_id_);
    VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyContext);
  }

  va_context_id_ = VA_INVALID_ID;
}

bool VaapiWrapper::CreateSurfaces(
    unsigned int va_format,
    const gfx::Size& size,
    const std::vector<SurfaceUsageHint>& usage_hints,
    size_t num_surfaces,
    std::vector<VASurfaceID>* va_surfaces) {
  DVLOG(2) << "Creating " << num_surfaces << " " << size.ToString()
           << " surfaces";
  DCHECK_NE(va_format, kInvalidVaRtFormat);
  DCHECK(va_surfaces->empty());

  va_surfaces->resize(num_surfaces);
  VASurfaceAttrib attribute;
  memset(&attribute, 0, sizeof(attribute));
  attribute.type = VASurfaceAttribUsageHint;
  attribute.flags = VA_SURFACE_ATTRIB_SETTABLE;
  attribute.value.type = VAGenericValueTypeInteger;
  attribute.value.value.i = 0;
  for (SurfaceUsageHint usage_hint : usage_hints)
    attribute.value.value.i |= static_cast<int32_t>(usage_hint);
  static_assert(std::is_same<decltype(attribute.value.value.i), int32_t>::value,
                "attribute.value.value.i is not int32_t");
  static_assert(std::is_same<std::underlying_type<SurfaceUsageHint>::type,
                             int32_t>::value,
                "The underlying type of SurfaceUsageHint is not int32_t");

  VAStatus va_res;
  {
    base::AutoLock auto_lock(*va_lock_);
    va_res = vaCreateSurfaces(
        va_display_, va_format, base::checked_cast<unsigned int>(size.width()),
        base::checked_cast<unsigned int>(size.height()), va_surfaces->data(),
        num_surfaces, &attribute, 1u);
  }
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVACreateSurfaces_Allocating);
  return va_res == VA_STATUS_SUCCESS;
}

std::vector<std::unique_ptr<ScopedVASurface>>
VaapiWrapper::CreateScopedVASurfaces(
    unsigned int va_rt_format,
    const gfx::Size& size,
    const std::vector<SurfaceUsageHint>& usage_hints,
    size_t num_surfaces,
    const absl::optional<gfx::Size>& visible_size,
    const absl::optional<uint32_t>& va_fourcc) {
  if (kInvalidVaRtFormat == va_rt_format) {
    LOG(ERROR) << "Invalid VA RT format to CreateScopedVASurface";
    return {};
  }

  if (size.IsEmpty()) {
    LOG(ERROR) << "Invalid visible size input to CreateScopedVASurface";
    return {};
  }

  VASurfaceAttrib attribs[2];
  unsigned int num_attribs = 1;
  memset(attribs, 0, sizeof(attribs));
  attribs[0].type = VASurfaceAttribUsageHint;
  attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
  attribs[0].value.type = VAGenericValueTypeInteger;
  attribs[0].value.value.i = 0;
  for (SurfaceUsageHint usage_hint : usage_hints)
    attribs[0].value.value.i |= static_cast<int32_t>(usage_hint);

  if (va_fourcc) {
    num_attribs += 1;
    attribs[1].type = VASurfaceAttribPixelFormat;
    attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
    attribs[1].value.type = VAGenericValueTypeInteger;
    attribs[1].value.value.i = base::checked_cast<int32_t>(*va_fourcc);
  }
  base::AutoLock auto_lock(*va_lock_);
  std::vector<VASurfaceID> va_surface_ids(num_surfaces, VA_INVALID_ID);
  const VAStatus va_res = vaCreateSurfaces(
      va_display_, va_rt_format, base::checked_cast<unsigned int>(size.width()),
      base::checked_cast<unsigned int>(size.height()), va_surface_ids.data(),
      num_surfaces, attribs, num_attribs);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateSurfaces_Allocating,
                       std::vector<std::unique_ptr<ScopedVASurface>>{});

  DCHECK(!base::Contains(va_surface_ids, VA_INVALID_ID))
      << "Invalid VA surface id after vaCreateSurfaces";

  DCHECK(!visible_size.has_value() || !visible_size->IsEmpty());
  std::vector<std::unique_ptr<ScopedVASurface>> scoped_va_surfaces;
  scoped_va_surfaces.reserve(num_surfaces);
  for (const VASurfaceID va_surface_id : va_surface_ids) {
    auto scoped_va_surface = std::make_unique<ScopedVASurface>(
        this, va_surface_id, visible_size.has_value() ? *visible_size : size,
        va_rt_format);
    DCHECK(scoped_va_surface->IsValid());
    scoped_va_surfaces.push_back(std::move(scoped_va_surface));
  }

  return scoped_va_surfaces;
}

void VaapiWrapper::DestroySurfaces(std::vector<VASurfaceID> va_surfaces) {
  DVLOG(2) << "Destroying " << va_surfaces.size() << " surfaces";

  // vaDestroySurfaces() makes no guarantees about VA_INVALID_SURFACE.
  base::Erase(va_surfaces, VA_INVALID_SURFACE);
  if (va_surfaces.empty())
    return;

  base::AutoLock auto_lock(*va_lock_);
  const VAStatus va_res =
      vaDestroySurfaces(va_display_, va_surfaces.data(), va_surfaces.size());
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroySurfaces);
}

void VaapiWrapper::DestroySurface(VASurfaceID va_surface_id) {
  if (va_surface_id == VA_INVALID_SURFACE)
    return;
  DVLOG(2) << __func__ << " " << va_surface_id;
  base::AutoLock auto_lock(*va_lock_);
  const VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1);
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroySurfaces);
}

bool VaapiWrapper::Execute_Locked(VASurfaceID va_surface_id,
                                  const std::vector<VABufferID>& va_buffers) {
  TRACE_EVENT0("media,gpu", "VaapiWrapper::Execute_Locked");
  va_lock_->AssertAcquired();

  DVLOG(4) << "Pending VA bufs to commit: " << pending_va_buffers_.size();
  DVLOG(4) << "Target VA surface " << va_surface_id;
  const auto decode_start_time = base::TimeTicks::Now();

  // Get ready to execute for given surface.
  VAStatus va_res = vaBeginPicture(va_display_, va_context_id_, va_surface_id);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVABeginPicture, false);

  if (!va_buffers.empty()) {
    // vaRenderPicture() needs a non-const pointer, possibly unnecessarily.
    VABufferID* va_buffers_data = const_cast<VABufferID*>(va_buffers.data());
    va_res = vaRenderPicture(va_display_, va_context_id_, va_buffers_data,
                             base::checked_cast<int>(va_buffers.size()));
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVARenderPicture_VABuffers,
                         false);
  }

  // Instruct HW codec to start processing the submitted commands. In theory,
  // this shouldn't be blocking, relying on vaSyncSurface() instead, however
  // evidence points to it actually waiting for the job to be done.
  va_res = vaEndPicture(va_display_, va_context_id_);
  VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAEndPicture, false);

  UMA_HISTOGRAM_TIMES("Media.PlatformVideoDecoding.Decode",
                      base::TimeTicks::Now() - decode_start_time);

  return true;
}

bool VaapiWrapper::SubmitBuffer_Locked(const VABufferDescriptor& va_buffer) {
  TRACE_EVENT0("media,gpu", "VaapiWrapper::SubmitBuffer_Locked");
  va_lock_->AssertAcquired();

  DCHECK(IsValidVABufferType(va_buffer.type));
  base::ScopedClosureRunner pending_buffers_destroyer_on_failure(base::BindOnce(
      &VaapiWrapper::DestroyPendingBuffers_Locked, base::Unretained(this)));
  unsigned int va_buffer_size;
  // We use a null |va_buffer|.data for testing: it signals that we want this
  // SubmitBuffer_Locked() call to fail.
  if (!va_buffer.data || !base::CheckedNumeric<size_t>(va_buffer.size)
                              .AssignIfValid(&va_buffer_size)) {
    return false;
  }

  VABufferID buffer_id;
  {
    TRACE_EVENT0("media,gpu",
                 "VaapiWrapper::SubmitBuffer_Locked_vaCreateBuffer");
    const VAStatus va_res =
        vaCreateBuffer(va_display_, va_context_id_, va_buffer.type,
                       va_buffer_size, 1, nullptr, &buffer_id);
    VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateBuffer, false);
  }

  if (!MapAndCopy_Locked(buffer_id, va_buffer))
    return false;

  pending_va_buffers_.push_back(buffer_id);
  pending_buffers_destroyer_on_failure.ReplaceClosure(base::DoNothing());
  return true;
}

bool VaapiWrapper::MapAndCopy_Locked(VABufferID va_buffer_id,
                                     const VABufferDescriptor& va_buffer) {
  va_lock_->AssertAcquired();

  DCHECK_NE(va_buffer_id, VA_INVALID_ID);
  DCHECK(IsValidVABufferType(va_buffer.type));
  DCHECK(va_buffer.data);

  ScopedVABufferMapping mapping(
      va_lock_, va_display_, va_buffer_id,
      base::BindOnce(base::IgnoreResult(&vaDestroyBuffer), va_display_));
  if (!mapping.IsValid())
    return false;

  return memcpy(mapping.data(), va_buffer.data, va_buffer.size);
}

void VaapiWrapper::MaybeSetLowQualityEncoding_Locked() {
  DCHECK(IsModeEncoding(mode_));
  va_lock_->AssertAcquired();

  // Query if encoding quality (VAConfigAttribEncQualityRange) is supported, and
  // if so, use the associated value for lowest quality and power consumption.
  VAConfigAttrib attrib{};
  attrib.type = VAConfigAttribEncQualityRange;
  const VAStatus va_res = vaGetConfigAttributes(va_display_, va_profile_,
                                                va_entrypoint_, &attrib, 1);
  if (va_res != VA_STATUS_SUCCESS) {
    LOG(ERROR) << "vaGetConfigAttributes failed: " << vaProfileStr(va_profile_);
    return;
  }
  // From libva's va.h: 'A value less than or equal to 1 means that the
  // encoder only has a single "quality setting,"'.
  if (attrib.value == VA_ATTRIB_NOT_SUPPORTED || attrib.value <= 1u)
    return;

  const size_t temp_size = sizeof(VAEncMiscParameterBuffer) +
                           sizeof(VAEncMiscParameterBufferQualityLevel);
  std::vector<char> temp(temp_size);

  auto* const va_buffer =
      reinterpret_cast<VAEncMiscParameterBuffer*>(temp.data());
  va_buffer->type = VAEncMiscParameterTypeQualityLevel;
  auto* const enc_quality =
      reinterpret_cast<VAEncMiscParameterBufferQualityLevel*>(va_buffer->data);
  enc_quality->quality_level = attrib.value;

  const bool success =
      SubmitBuffer_Locked({VAEncMiscParameterBufferType, temp_size, va_buffer});
  LOG_IF(ERROR, !success) << "Error setting encoding quality to "
                          << enc_quality->quality_level;
}

bool VaapiWrapper::MaybeAttachProtectedSession_Locked() {
  va_lock_->AssertAcquired();
  if (va_context_id_ == VA_INVALID_ID)
    return true;
#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (va_protected_session_id_ == VA_INVALID_ID)
    return true;

  VAStatus va_res = vaAttachProtectedSession(va_display_, va_context_id_,
                                             va_protected_session_id_);
  VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVAAttachProtectedSession);
  return va_res == VA_STATUS_SUCCESS;
#else
  return true;
#endif
}

}  // namespace media
