// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>
#include <va/va.h>

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

// This has to be included first.
// See http://code.google.com/p/googletest/issues/detail?id=371
#include "testing/gtest/include/gtest/gtest.h"

#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_util.h"
#include "media/base/video_types.h"
#include "media/gpu/test/local_gpu_memory_buffer_manager.h"
#include "media/gpu/vaapi/test_utils.h"
#include "media/gpu/vaapi/va_surface.h"
#include "media/gpu/vaapi/vaapi_image_decoder.h"
#include "media/gpu/vaapi/vaapi_image_decoder_test_common.h"
#include "media/gpu/vaapi/vaapi_jpeg_decoder.h"
#include "media/gpu/vaapi/vaapi_utils.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "media/parsers/jpeg_parser.h"
#include "third_party/libyuv/include/libyuv.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkPixmap.h"
#include "third_party/skia/include/encode/SkJpegEncoder.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/linux/native_pixmap_dmabuf.h"
#include "ui/gfx/native_pixmap_handle.h"

namespace media {
namespace {

using DecodedImagePtr = std::unique_ptr<vaapi_test_utils::DecodedImage>;

constexpr const char* kYuv422Filename = "pixel-1280x720.jpg";
constexpr const char* kYuv420Filename = "pixel-1280x720-yuv420.jpg";
constexpr const char* kYuv444Filename = "pixel-1280x720-yuv444.jpg";
constexpr const char* kOddHeightImageFilename = "pixel-40x23-yuv420.jpg";
constexpr const char* kOddWidthImageFilename = "pixel-41x22-yuv420.jpg";
constexpr const char* kOddDimensionsImageFilename = "pixel-41x23-yuv420.jpg";

const vaapi_test_utils::TestParam kVAImageTestCases[] = {
    {"YUV422", kYuv422Filename},
    {"YUV420", kYuv420Filename},
    {"YUV444", kYuv444Filename},
};

const vaapi_test_utils::TestParam kDmaBufTestCases[] = {
    {"YUV420", kYuv420Filename},
    {"OddHeightImage40x23", kOddHeightImageFilename},
    {"OddWidthImage41x22", kOddWidthImageFilename},
    {"OddDimensionsImage41x23", kOddDimensionsImageFilename},
};

constexpr double kMinSsim = 0.995;

// This file is not supported by the VAAPI, so we don't define expectations on
// the decode result.
constexpr const char* kUnsupportedFilename = "pixel-1280x720-grayscale.jpg";

// The size of the minimum coded unit for a YUV 4:2:0 image (both the width and
// the height of the MCU are the same for 4:2:0).
constexpr int k420MCUSize = 16;

// The largest maximum supported surface size we expect a driver to report for
// JPEG decoding.
constexpr gfx::Size kLargestSupportedSize(16 * 1024, 16 * 1024);

// Decodes the given |encoded_image| using libyuv and returns the result as a
// DecodedImage object. The decoded planes will be stored in |dest_*|.
// Note however, that this function does not takes ownership of |dest_*| or
// manage their memory.
DecodedImagePtr GetSwDecode(base::span<const uint8_t> encoded_image,
                            std::vector<uint8_t>* dest_y,
                            std::vector<uint8_t>* dest_u,
                            std::vector<uint8_t>* dest_v) {
  DCHECK(dest_y && dest_u && dest_v);
  JpegParseResult parse_result;
  const bool result = ParseJpegPicture(encoded_image.data(),
                                       encoded_image.size(), &parse_result);
  if (!result)
    return nullptr;

  const gfx::Size jpeg_size(
      base::strict_cast<int>(parse_result.frame_header.visible_width),
      base::strict_cast<int>(parse_result.frame_header.visible_height));
  if (jpeg_size.IsEmpty())
    return nullptr;

  const gfx::Size half_jpeg_size((jpeg_size.width() + 1) / 2,
                                 (jpeg_size.height() + 1) / 2);

  dest_y->resize(jpeg_size.GetArea());
  dest_u->resize(half_jpeg_size.GetArea());
  dest_v->resize(half_jpeg_size.GetArea());

  if (libyuv::ConvertToI420(
          encoded_image.data(), encoded_image.size(), dest_y->data(),
          jpeg_size.width(), dest_u->data(), half_jpeg_size.width(),
          dest_v->data(), half_jpeg_size.width(), 0, 0, jpeg_size.width(),
          jpeg_size.height(), jpeg_size.width(), jpeg_size.height(),
          libyuv::kRotate0, libyuv::FOURCC_MJPG) != 0) {
    return nullptr;
  }

  auto sw_decoded_jpeg = std::make_unique<vaapi_test_utils::DecodedImage>();
  sw_decoded_jpeg->fourcc = VA_FOURCC_I420;
  sw_decoded_jpeg->number_of_planes = 3u;
  sw_decoded_jpeg->size = jpeg_size;
  sw_decoded_jpeg->planes[0].data = dest_y->data();
  sw_decoded_jpeg->planes[0].stride = jpeg_size.width();
  sw_decoded_jpeg->planes[1].data = dest_u->data();
  sw_decoded_jpeg->planes[1].stride = half_jpeg_size.width();
  sw_decoded_jpeg->planes[2].data = dest_v->data();
  sw_decoded_jpeg->planes[2].stride = half_jpeg_size.width();

  return sw_decoded_jpeg;
}

// Generates a checkerboard pattern as a JPEG image of a specified |size| and
// |subsampling| format. Returns an empty vector on failure.
std::vector<unsigned char> GenerateJpegImage(
    const gfx::Size& size,
    SkJpegEncoder::Downsample subsampling = SkJpegEncoder::Downsample::k420) {
  DCHECK(!size.IsEmpty());

  // First build a raw RGBA image of the given size with a checkerboard pattern.
  const SkImageInfo image_info = SkImageInfo::Make(
      size.width(), size.height(), SkColorType::kRGBA_8888_SkColorType,
      SkAlphaType::kOpaque_SkAlphaType);
  const size_t byte_size = image_info.computeMinByteSize();
  if (byte_size == SIZE_MAX)
    return {};
  const size_t stride = image_info.minRowBytes();
  DCHECK_EQ(4, SkColorTypeBytesPerPixel(image_info.colorType()));
  DCHECK_EQ(4 * size.width(), base::checked_cast<int>(stride));
  constexpr gfx::Size kCheckerRectSize(3, 5);
  std::vector<uint8_t> rgba_data(byte_size);
  uint8_t* data = rgba_data.data();
  for (int y = 0; y < size.height(); y++) {
    const bool y_bit = (((y / kCheckerRectSize.height()) & 0x1) == 0);
    for (int x = 0; x < base::checked_cast<int>(stride); x += 4) {
      const bool x_bit = (((x / kCheckerRectSize.width()) & 0x1) == 0);
      const SkColor color = (x_bit != y_bit) ? SK_ColorBLUE : SK_ColorMAGENTA;
      data[x + 0] = SkColorGetR(color);
      data[x + 1] = SkColorGetG(color);
      data[x + 2] = SkColorGetB(color);
      data[x + 3] = SkColorGetA(color);
    }
    data += stride;
  }

  // Now, encode it as a JPEG.
  //
  // TODO(andrescj): if this generates a large enough image (in terms of byte
  // size), it will be decoded incorrectly in AMD Stoney Ridge (see
  // b/127874877). When that's resolved, change the quality here to 100 so that
  // the generated JPEG is large.
  std::vector<unsigned char> jpeg_data;
  if (gfx::JPEGCodec::Encode(
          SkPixmap(image_info, rgba_data.data(), stride) /* input */,
          95 /* quality */, subsampling /* downsample */,
          &jpeg_data /* output */)) {
    return jpeg_data;
  }
  return {};
}

// Rounds |n| to the greatest multiple of |m| that is less than or equal to |n|.
int RoundDownToMultiple(int n, int m) {
  DCHECK_GE(n, 0);
  DCHECK_GT(m, 0);
  return (n / m) * m;
}

// Rounds |n| to the smallest multiple of |m| that is greater than or equal to
// |n|.
int RoundUpToMultiple(int n, int m) {
  DCHECK_GE(n, 0);
  DCHECK_GT(m, 0);
  if (n % m == 0)
    return n;
  base::CheckedNumeric<int> safe_n(n);
  safe_n += m;
  return RoundDownToMultiple(safe_n.ValueOrDie(), m);
}

// Given a minimum supported surface dimension (width or height) value
// |min_surface_supported|, this function returns a non-zero coded dimension of
// a 4:2:0 JPEG image that would not be supported because the dimension is right
// below the supported value. For example, if |min_surface_supported| is 19,
// this function should return 16 because for a 4:2:0 image, both coded
// dimensions should be multiples of 16. If an unsupported dimension was found
// (i.e., |min_surface_supported| > 16), this function returns true, false
// otherwise.
bool GetMinUnsupportedDimension(int min_surface_supported,
                                int* min_unsupported) {
  if (min_surface_supported <= k420MCUSize)
    return false;
  *min_unsupported =
      RoundDownToMultiple(min_surface_supported - 1, k420MCUSize);
  return true;
}

// Given a minimum supported surface dimension (width or height) value
// |min_surface_supported|, this function returns a non-zero coded dimension of
// a 4:2:0 JPEG image that would be supported because the dimension is at least
// the minimum. For example, if |min_surface_supported| is 35, this function
// should return 48 because for a 4:2:0 image, both coded dimensions should be
// multiples of 16.
int GetMinSupportedDimension(int min_surface_supported) {
  LOG_ASSERT(min_surface_supported > 0);
  return RoundUpToMultiple(min_surface_supported, k420MCUSize);
}

// Given a maximum supported surface dimension (width or height) value
// |max_surface_supported|, this function returns the coded dimension of a 4:2:0
// JPEG image that would be supported because the dimension is at most the
// maximum. For example, if |max_surface_supported| is 65, this function
// should return 64 because for a 4:2:0 image, both coded dimensions should be
// multiples of 16.
int GetMaxSupportedDimension(int max_surface_supported) {
  return RoundDownToMultiple(max_surface_supported, k420MCUSize);
}

}  // namespace

class VaapiJpegDecoderTest : public VaapiImageDecoderTestCommon {
 protected:
  VaapiJpegDecoderTest()
      : VaapiImageDecoderTestCommon(std::make_unique<VaapiJpegDecoder>()) {}

  std::unique_ptr<ScopedVAImage> Decode(
      base::span<const uint8_t> encoded_image,
      uint32_t preferred_fourcc,
      VaapiImageDecodeStatus* status = nullptr);

  std::unique_ptr<ScopedVAImage> Decode(
      base::span<const uint8_t> encoded_image,
      VaapiImageDecodeStatus* status = nullptr);
};

std::unique_ptr<ScopedVAImage> VaapiJpegDecoderTest::Decode(
    base::span<const uint8_t> encoded_image,
    uint32_t preferred_fourcc,
    VaapiImageDecodeStatus* status) {
  const VaapiImageDecodeStatus decode_status = Decoder()->Decode(encoded_image);
  EXPECT_EQ(!!Decoder()->GetScopedVASurface(),
            decode_status == VaapiImageDecodeStatus::kSuccess);

  // Still try to get image when decode fails.
  VaapiImageDecodeStatus image_status;
  std::unique_ptr<ScopedVAImage> scoped_image;
  scoped_image = static_cast<VaapiJpegDecoder*>(Decoder())->GetImage(
      preferred_fourcc, &image_status);
  EXPECT_EQ(!!scoped_image, image_status == VaapiImageDecodeStatus::kSuccess);

  // Return the first fail status.
  if (status) {
    *status = decode_status != VaapiImageDecodeStatus::kSuccess ? decode_status
                                                                : image_status;
  }
  return scoped_image;
}

std::unique_ptr<ScopedVAImage> VaapiJpegDecoderTest::Decode(
    base::span<const uint8_t> encoded_image,
    VaapiImageDecodeStatus* status) {
  return Decode(encoded_image, VA_FOURCC_I420, status);
}

// The intention of this test is to ensure that the workarounds added in
// VaapiWrapper::GetJpegDecodeSuitableImageFourCC() don't result in an
// unsupported image format.
TEST_F(VaapiJpegDecoderTest, MinimalImageFormatSupport) {
  // All drivers should support at least I420.
  VAImageFormat i420_format{};
  i420_format.fourcc = VA_FOURCC_I420;
  ASSERT_TRUE(VaapiWrapper::IsImageFormatSupported(i420_format));

  // Additionally, the mesa VAAPI driver should support YV12, NV12 and YUYV.
  ASSERT_NE(VAImplementation::kInvalid, VaapiWrapper::GetImplementationType());
  if (VaapiWrapper::GetImplementationType() == VAImplementation::kMesaGallium) {
    VAImageFormat yv12_format{};
    yv12_format.fourcc = VA_FOURCC_YV12;
    ASSERT_TRUE(VaapiWrapper::IsImageFormatSupported(yv12_format));

    VAImageFormat nv12_format{};
    nv12_format.fourcc = VA_FOURCC_NV12;
    ASSERT_TRUE(VaapiWrapper::IsImageFormatSupported(nv12_format));

    VAImageFormat yuyv_format{};
    yuyv_format.fourcc = VA_FOURCC('Y', 'U', 'Y', 'V');
    ASSERT_TRUE(VaapiWrapper::IsImageFormatSupported(yuyv_format));
  }
}

TEST_P(VaapiJpegDecoderTest, DecodeSucceeds) {
  base::FilePath input_file = FindTestDataFilePath(GetParam().filename);
  std::string jpeg_data;
  ASSERT_TRUE(base::ReadFileToString(input_file, &jpeg_data))
      << "failed to read input data from " << input_file.value();
  const auto encoded_image = base::as_bytes(base::make_span(jpeg_data));

  // Skip the image if the VAAPI driver doesn't claim to support its chroma
  // subsampling format. However, we expect at least 4:2:0 and 4:2:2 support.
  const VaapiWrapper::InternalFormats supported_internal_formats =
      VaapiWrapper::GetDecodeSupportedInternalFormats(VAProfileJPEGBaseline);
  ASSERT_TRUE(supported_internal_formats.yuv420);
  ASSERT_TRUE(supported_internal_formats.yuv422);
  JpegParseResult parse_result;
  ASSERT_TRUE(ParseJpegPicture(encoded_image.data(), encoded_image.size(),
                               &parse_result));
  const unsigned int rt_format =
      VaSurfaceFormatForJpeg(parse_result.frame_header);
  ASSERT_NE(kInvalidVaRtFormat, rt_format);
  if (!VaapiWrapper::IsDecodingSupportedForInternalFormat(VAProfileJPEGBaseline,
                                                          rt_format)) {
    GTEST_SKIP();
  }

  // Note that this test together with
  // VaapiJpegDecoderTest.MinimalImageFormatSupport gives us two guarantees:
  //
  // 1) Every combination of supported internal format (returned by
  //    GetJpegDecodeSupportedInternalFormats()) and supported image format
  //    works with vaGetImage() (for JPEG decoding).
  //
  // 2) The FOURCC returned by VaapiWrapper::GetJpegDecodeSuitableImageFourCC()
  //    corresponds to a supported image format.
  //
  // Note that we expect VA_FOURCC_I420 and VA_FOURCC_NV12 support in all
  // drivers.
  const std::vector<VAImageFormat>& supported_image_formats =
      VaapiWrapper::GetSupportedImageFormatsForTesting();
  EXPECT_GE(supported_image_formats.size(), 2u);

  VAImageFormat i420_format{};
  i420_format.fourcc = VA_FOURCC_I420;
  EXPECT_TRUE(VaapiWrapper::IsImageFormatSupported(i420_format));

  VAImageFormat nv12_format{};
  nv12_format.fourcc = VA_FOURCC_NV12;
  EXPECT_TRUE(VaapiWrapper::IsImageFormatSupported(nv12_format));

  // Decode the image using libyuv. Using |temp_*| for resource management.
  std::vector<uint8_t> temp_y;
  std::vector<uint8_t> temp_u;
  std::vector<uint8_t> temp_v;
  DecodedImagePtr sw_decoded_jpeg =
      GetSwDecode(encoded_image, &temp_y, &temp_u, &temp_v);
  ASSERT_TRUE(sw_decoded_jpeg);

  // Now run the comparison between the sw and hw image decodes for the
  // supported formats.
  for (const auto& image_format : supported_image_formats) {
    std::unique_ptr<ScopedVAImage> scoped_image =
        Decode(encoded_image, image_format.fourcc);
    ASSERT_TRUE(scoped_image);
    ASSERT_TRUE(Decoder()->GetScopedVASurface());
    EXPECT_TRUE(Decoder()->GetScopedVASurface()->IsValid());
    EXPECT_EQ(Decoder()->GetScopedVASurface()->size().width(),
              base::strict_cast<int>(parse_result.frame_header.visible_width));
    EXPECT_EQ(Decoder()->GetScopedVASurface()->size().height(),
              base::strict_cast<int>(parse_result.frame_header.visible_height));
    EXPECT_EQ(rt_format, Decoder()->GetScopedVASurface()->format());
    const uint32_t actual_fourcc = scoped_image->image()->format.fourcc;
    // TODO(andrescj): CompareImages() only supports I420, NV12, YUY2, and YUYV.
    // Make it support all the image formats we expect and call it
    // unconditionally.
    if (actual_fourcc == VA_FOURCC_I420 || actual_fourcc == VA_FOURCC_NV12 ||
        actual_fourcc == VA_FOURCC_YUY2 ||
        actual_fourcc == VA_FOURCC('Y', 'U', 'Y', 'V')) {
      ASSERT_TRUE(vaapi_test_utils::CompareImages(
          *sw_decoded_jpeg,
          vaapi_test_utils::ScopedVAImageToDecodedImage(scoped_image.get()),
          kMinSsim));
    }
    DVLOG(1) << "Got a " << FourccToString(scoped_image->image()->format.fourcc)
             << " VAImage (preferred " << FourccToString(image_format.fourcc)
             << ")";
  }
}

// Make sure that JPEGs whose size is in the supported size range are decoded
// successfully.
//
// TODO(andrescj): for now, this assumes 4:2:0. Handle other formats.
// TODO(andrescj): consider recreating the decoder for every size so that no
// state is retained.
TEST_F(VaapiJpegDecoderTest, DecodeSucceedsForSupportedSizes) {
  gfx::Size min_supported_size;
  ASSERT_TRUE(VaapiWrapper::GetDecodeMinResolution(VAProfileJPEGBaseline,
                                                   &min_supported_size));
  gfx::Size max_supported_size;
  ASSERT_TRUE(VaapiWrapper::GetDecodeMaxResolution(VAProfileJPEGBaseline,
                                                   &max_supported_size));

  // Ensure the maximum supported size is reasonable.
  ASSERT_GE(max_supported_size.width(), min_supported_size.width());
  ASSERT_GE(max_supported_size.height(), min_supported_size.height());
  ASSERT_LE(max_supported_size.width(), kLargestSupportedSize.width());
  ASSERT_LE(max_supported_size.height(), kLargestSupportedSize.height());

  // The actual image min/max coded size depends on the subsampling format. For
  // example, for 4:2:0, the coded dimensions must be multiples of 16. So, if
  // the minimum surface size is, e.g., 18x18, the minimum image coded size is
  // 32x32. Get those actual min/max coded sizes now.
  const int min_width = GetMinSupportedDimension(min_supported_size.width());
  const int min_height = GetMinSupportedDimension(min_supported_size.height());
  const int max_width = GetMaxSupportedDimension(max_supported_size.width());
  const int max_height = GetMaxSupportedDimension(max_supported_size.height());
  ASSERT_GT(max_width, 0);
  ASSERT_GT(max_height, 0);
  const std::vector<gfx::Size> test_sizes = {{min_width, min_height},
                                             {min_width, max_height},
                                             {max_width, min_height},
                                             {max_width, max_height}};
  for (const auto& test_size : test_sizes) {
    const std::vector<unsigned char> jpeg_data = GenerateJpegImage(test_size);
    auto jpeg_data_span = base::as_bytes(base::make_span(jpeg_data));
    ASSERT_FALSE(jpeg_data.empty());
    std::unique_ptr<ScopedVAImage> scoped_image = Decode(jpeg_data_span);
    ASSERT_TRUE(scoped_image)
        << "Decode unexpectedly failed for size = " << test_size.ToString();
    ASSERT_TRUE(Decoder()->GetScopedVASurface());
    EXPECT_TRUE(Decoder()->GetScopedVASurface()->IsValid());

    // Decode the image using libyuv. Using |temp_*| for resource management.
    std::vector<uint8_t> temp_y;
    std::vector<uint8_t> temp_u;
    std::vector<uint8_t> temp_v;
    DecodedImagePtr sw_decoded_jpeg =
        GetSwDecode(jpeg_data_span, &temp_y, &temp_u, &temp_v);
    ASSERT_TRUE(sw_decoded_jpeg);

    EXPECT_TRUE(vaapi_test_utils::CompareImages(
        *sw_decoded_jpeg,
        vaapi_test_utils::ScopedVAImageToDecodedImage(scoped_image.get()),
        kMinSsim))
        << "The SSIM check unexpectedly failed for size = "
        << test_size.ToString();
  }
}

class VaapiJpegDecoderWithDmaBufsTest : public VaapiJpegDecoderTest {
 public:
  VaapiJpegDecoderWithDmaBufsTest() = default;
  ~VaapiJpegDecoderWithDmaBufsTest() override = default;
};

// TODO(andrescj): test other JPEG formats besides YUV 4:2:0.
TEST_P(VaapiJpegDecoderWithDmaBufsTest, DecodeSucceeds) {
  ASSERT_NE(VAImplementation::kInvalid, VaapiWrapper::GetImplementationType());
  if (VaapiWrapper::GetImplementationType() == VAImplementation::kMesaGallium) {
    // TODO(crbug.com/974438): until we support surfaces with multiple buffer
    // objects, the AMD driver fails this test.
    GTEST_SKIP();
  }

  base::FilePath input_file = FindTestDataFilePath(GetParam().filename);
  std::string jpeg_data;
  ASSERT_TRUE(base::ReadFileToString(input_file, &jpeg_data))
      << "failed to read input data from " << input_file.value();
  const auto encoded_image = base::as_bytes(base::make_span(jpeg_data));

  // Decode into a VAAPI-allocated surface.
  const VaapiImageDecodeStatus decode_status = Decoder()->Decode(encoded_image);
  EXPECT_EQ(VaapiImageDecodeStatus::kSuccess, decode_status);
  ASSERT_TRUE(Decoder()->GetScopedVASurface());
  const gfx::Size va_surface_visible_size =
      Decoder()->GetScopedVASurface()->size();

  // The size stored in the ScopedVASurface should be the visible size of the
  // JPEG.
  JpegParseResult parse_result;
  ASSERT_TRUE(ParseJpegPicture(encoded_image.data(), encoded_image.size(),
                               &parse_result));
  EXPECT_EQ(gfx::Size(parse_result.frame_header.visible_width,
                      parse_result.frame_header.visible_height),
            va_surface_visible_size);

  // Export the surface.
  VaapiImageDecodeStatus export_status = VaapiImageDecodeStatus::kInvalidState;
  std::unique_ptr<NativePixmapAndSizeInfo> exported_pixmap =
      Decoder()->ExportAsNativePixmapDmaBuf(&export_status);
  EXPECT_EQ(VaapiImageDecodeStatus::kSuccess, export_status);
  ASSERT_TRUE(exported_pixmap);
  ASSERT_TRUE(exported_pixmap->pixmap);
  EXPECT_FALSE(Decoder()->GetScopedVASurface());

  // For JPEG decoding, the size of the surface we request is the coded size of
  // the JPEG. Make sure the surface contains that coded area.
  EXPECT_TRUE(gfx::Rect(exported_pixmap->va_surface_resolution)
                  .Contains(gfx::Rect(parse_result.frame_header.coded_width,
                                      parse_result.frame_header.coded_height)));

  // Make sure the visible area is contained by the surface.
  EXPECT_EQ(va_surface_visible_size, exported_pixmap->pixmap->GetBufferSize());
  EXPECT_FALSE(exported_pixmap->va_surface_resolution.IsEmpty());
  EXPECT_FALSE(exported_pixmap->pixmap->GetBufferSize().IsEmpty());
  ASSERT_TRUE(
      gfx::Rect(exported_pixmap->va_surface_resolution)
          .Contains(gfx::Rect(exported_pixmap->pixmap->GetBufferSize())));

  // TODO(andrescj): we could get a better lower bound based on the dimensions
  // and the format.
  ASSERT_GT(exported_pixmap->byte_size, 0u);

  // After exporting the surface, we should not be able to obtain a VAImage with
  // the decoded data.
  VAImageFormat i420_format{};
  i420_format.fourcc = VA_FOURCC_I420;
  EXPECT_TRUE(VaapiWrapper::IsImageFormatSupported(i420_format));
  VaapiImageDecodeStatus image_status = VaapiImageDecodeStatus::kSuccess;
  EXPECT_FALSE(static_cast<VaapiJpegDecoder*>(Decoder())->GetImage(
      i420_format.fourcc, &image_status));
  EXPECT_EQ(VaapiImageDecodeStatus::kInvalidState, image_status);

  // Workaround: in order to import and map the pixmap using minigbm when the
  // format is gfx::BufferFormat::YVU_420, we need to reorder the planes so that
  // the offsets are in increasing order as assumed in https://bit.ly/2NLubNN.
  // Otherwise, we get a validation error. In essence, we're making minigbm
  // think that it is mapping a YVU_420, but it's actually mapping a YUV_420.
  //
  // TODO(andrescj): revisit this once crrev.com/c/1573718 lands.
  gfx::NativePixmapHandle handle = exported_pixmap->pixmap->ExportHandle();
  ASSERT_EQ(gfx::NumberOfPlanesForLinearBufferFormat(
                exported_pixmap->pixmap->GetBufferFormat()),
            handle.planes.size());
  if (exported_pixmap->pixmap->GetBufferFormat() == gfx::BufferFormat::YVU_420)
    std::swap(handle.planes[1], handle.planes[2]);

  LocalGpuMemoryBufferManager gpu_memory_buffer_manager;
  std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer =
      gpu_memory_buffer_manager.ImportDmaBuf(
          handle, exported_pixmap->pixmap->GetBufferSize(),
          exported_pixmap->pixmap->GetBufferFormat());
  ASSERT_TRUE(gpu_memory_buffer);
  ASSERT_TRUE(gpu_memory_buffer->Map());
  vaapi_test_utils::DecodedImage decoded_image{};
  const gfx::BufferFormat format = gpu_memory_buffer->GetFormat();
  if (format == gfx::BufferFormat::YVU_420) {
    decoded_image.fourcc = VA_FOURCC_I420;
    decoded_image.number_of_planes = 3u;
  } else if (format == gfx::BufferFormat::YUV_420_BIPLANAR) {
    decoded_image.fourcc = VA_FOURCC_NV12;
    decoded_image.number_of_planes = 2u;
  } else {
    ASSERT_TRUE(false) << "Unsupported format "
                       << gfx::BufferFormatToString(format);
  }
  decoded_image.size = gpu_memory_buffer->GetSize();
  for (size_t plane = 0u;
       plane < base::strict_cast<size_t>(decoded_image.number_of_planes);
       plane++) {
    decoded_image.planes[plane].data =
        static_cast<uint8_t*>(gpu_memory_buffer->memory(plane));
    decoded_image.planes[plane].stride = gpu_memory_buffer->stride(plane);
  }

  // Decode the image using libyuv. Using |temp_*| for resource management.
  std::vector<uint8_t> temp_y;
  std::vector<uint8_t> temp_u;
  std::vector<uint8_t> temp_v;
  DecodedImagePtr sw_decoded_jpeg =
      GetSwDecode(encoded_image, &temp_y, &temp_u, &temp_v);
  ASSERT_TRUE(sw_decoded_jpeg);

  EXPECT_TRUE(vaapi_test_utils::CompareImages(*sw_decoded_jpeg, decoded_image,
                                              kMinSsim));
  gpu_memory_buffer->Unmap();
}

// Make sure that JPEGs whose size is below the supported size range are
// rejected.
//
// TODO(andrescj): for now, this assumes 4:2:0. Handle other formats.
TEST_F(VaapiJpegDecoderTest, DecodeFailsForBelowMinSize) {
  gfx::Size min_supported_size;
  ASSERT_TRUE(VaapiWrapper::GetDecodeMinResolution(VAProfileJPEGBaseline,
                                                   &min_supported_size));
  gfx::Size max_supported_size;
  ASSERT_TRUE(VaapiWrapper::GetDecodeMaxResolution(VAProfileJPEGBaseline,
                                                   &max_supported_size));

  // Ensure the maximum supported size is reasonable.
  ASSERT_GE(max_supported_size.width(), min_supported_size.width());
  ASSERT_GE(max_supported_size.height(), min_supported_size.height());
  ASSERT_LE(max_supported_size.width(), kLargestSupportedSize.width());
  ASSERT_LE(max_supported_size.height(), kLargestSupportedSize.height());

  // Get good (supported) minimum dimensions.
  const int good_width = GetMinSupportedDimension(min_supported_size.width());
  ASSERT_LE(good_width, max_supported_size.width());
  const int good_height = GetMinSupportedDimension(min_supported_size.height());
  ASSERT_LE(good_height, max_supported_size.height());

  // Get bad (unsupported) dimensions.
  int bad_width;
  const bool got_bad_width =
      GetMinUnsupportedDimension(min_supported_size.width(), &bad_width);
  int bad_height;
  const bool got_bad_height =
      GetMinUnsupportedDimension(min_supported_size.height(), &bad_height);

  // Now build and test the good/bad combinations that we expect will fail.
  std::vector<gfx::Size> test_sizes;
  if (got_bad_width)
    test_sizes.push_back({bad_width, good_height});
  if (got_bad_height)
    test_sizes.push_back({good_width, bad_height});
  if (got_bad_width && got_bad_height)
    test_sizes.push_back({bad_width, bad_height});
  for (const auto& test_size : test_sizes) {
    const std::vector<unsigned char> jpeg_data = GenerateJpegImage(test_size);
    ASSERT_FALSE(jpeg_data.empty());
    VaapiImageDecodeStatus status = VaapiImageDecodeStatus::kSuccess;
    ASSERT_FALSE(Decode(base::as_bytes(base::make_span(jpeg_data)), &status))
        << "Decode unexpectedly succeeded for size = " << test_size.ToString();
    EXPECT_EQ(VaapiImageDecodeStatus::kUnsupportedImage, status);
    EXPECT_FALSE(Decoder()->GetScopedVASurface());
  }
}

// Make sure that JPEGs whose size is above the supported size range are
// rejected.
//
// TODO(andrescj): for now, this assumes 4:2:0. Handle other formats.
TEST_F(VaapiJpegDecoderTest, DecodeFailsForAboveMaxSize) {
  gfx::Size min_supported_size;
  ASSERT_TRUE(VaapiWrapper::GetDecodeMinResolution(VAProfileJPEGBaseline,
                                                   &min_supported_size));
  gfx::Size max_supported_size;
  ASSERT_TRUE(VaapiWrapper::GetDecodeMaxResolution(VAProfileJPEGBaseline,
                                                   &max_supported_size));

  // Ensure the maximum supported size is reasonable.
  ASSERT_GE(max_supported_size.width(), min_supported_size.width());
  ASSERT_GE(max_supported_size.height(), min_supported_size.height());
  ASSERT_LE(max_supported_size.width(), kLargestSupportedSize.width());
  ASSERT_LE(max_supported_size.height(), kLargestSupportedSize.height());

  // Get good (supported) maximum dimensions.
  const int good_width = GetMaxSupportedDimension(max_supported_size.width());
  ASSERT_GE(good_width, min_supported_size.width());
  ASSERT_GT(good_width, 0);
  const int good_height = GetMaxSupportedDimension(max_supported_size.height());
  ASSERT_GE(good_height, min_supported_size.height());
  ASSERT_GT(good_height, 0);

  // Get bad (unsupported) dimensions.
  const int bad_width =
      RoundUpToMultiple(max_supported_size.width() + 1, k420MCUSize);
  const int bad_height =
      RoundUpToMultiple(max_supported_size.height() + 1, k420MCUSize);

  // Now build and test the good/bad combinations that we expect will fail.
  const std::vector<gfx::Size> test_sizes = {{bad_width, good_height},
                                             {good_width, bad_height},
                                             {bad_width, bad_height}};
  for (const auto& test_size : test_sizes) {
    const std::vector<unsigned char> jpeg_data = GenerateJpegImage(test_size);
    ASSERT_FALSE(jpeg_data.empty());
    VaapiImageDecodeStatus status = VaapiImageDecodeStatus::kSuccess;
    ASSERT_FALSE(Decode(base::as_bytes(base::make_span(jpeg_data)), &status))
        << "Decode unexpectedly succeeded for size = " << test_size.ToString();
    EXPECT_EQ(VaapiImageDecodeStatus::kUnsupportedImage, status);
    EXPECT_FALSE(Decoder()->GetScopedVASurface());
  }
}

TEST_F(VaapiJpegDecoderTest, DecodeFails) {
  // A grayscale image (4:0:0) should be rejected.
  base::FilePath input_file = FindTestDataFilePath(kUnsupportedFilename);
  std::string jpeg_data;
  ASSERT_TRUE(base::ReadFileToString(input_file, &jpeg_data))
      << "failed to read input data from " << input_file.value();
  VaapiImageDecodeStatus status = VaapiImageDecodeStatus::kSuccess;
  ASSERT_FALSE(Decode(base::as_bytes(base::make_span(jpeg_data)), &status));
  EXPECT_EQ(VaapiImageDecodeStatus::kUnsupportedSubsampling, status);
  EXPECT_FALSE(Decoder()->GetScopedVASurface());
}

INSTANTIATE_TEST_SUITE_P(All,
                         VaapiJpegDecoderTest,
                         testing::ValuesIn(kVAImageTestCases),
                         vaapi_test_utils::TestParamToString);

INSTANTIATE_TEST_SUITE_P(All,
                         VaapiJpegDecoderWithDmaBufsTest,
                         testing::ValuesIn(kDmaBufTestCases),
                         vaapi_test_utils::TestParamToString);

}  // namespace media
