// Copyright 2015 The Chromium Authors
// 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;
  gfx::Size max_supported_size;
  ASSERT_TRUE(VaapiWrapper::GetSupportedResolutions(
      VAProfileJPEGBaseline, VaapiWrapper::CodecMode::kDecode,
      min_supported_size, 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;
  gfx::Size max_supported_size;
  ASSERT_TRUE(VaapiWrapper::GetSupportedResolutions(
      VAProfileJPEGBaseline, VaapiWrapper::CodecMode::kDecode,
      min_supported_size, 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;
  gfx::Size max_supported_size;
  ASSERT_TRUE(VaapiWrapper::GetSupportedResolutions(
      VAProfileJPEGBaseline, VaapiWrapper::CodecMode::kDecode,
      min_supported_size, 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
