Commit 900c2b4d authored by David Staessens's avatar David Staessens Committed by Commit Bot

media/gpu/VAAPI: Add JPEG decode test using different sampling formats.

The VAAPI JPEG decoder on some platforms won't convert the decoded images to the
I420 format, but will return the decoded images in their original pixel format.
This means a conversion must be done in the VAAPI wrapper to the expected I420
output format. This change adds a SamplingFormatChange test that will test
whether the conversion is successful for JPEGS with different sampling formats.

Additional cleanup:
* Added some comments for clarification

TEST=ran JDA tests on eve and grunt

Bug: 828119
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: Ibade43422590268d774b8d330097e46a8a33bca1
Reviewed-on: https://chromium-review.googlesource.com/1218386Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarPawel Osciak <posciak@chromium.org>
Reviewed-by: default avatarLeon Scroggins <scroggo@chromium.org>
Commit-Queue: David Staessens <dstaessens@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592683}
parent 7205a856
......@@ -87,25 +87,30 @@ struct ParsedJpegImage {
return image;
}
static std::unique_ptr<ParsedJpegImage> CreateBlackImage(int width,
int height) {
base::FilePath filename;
LOG_ASSERT(base::GetTempDir(&filename));
filename =
filename.Append(base::StringPrintf("black-%dx%d.jpg", width, height));
auto image = std::make_unique<ParsedJpegImage>(filename);
static std::unique_ptr<ParsedJpegImage> CreateBlackImage(
int width,
int height,
SkJpegEncoder::Downsample downsample = SkJpegEncoder::Downsample::k420) {
// Generate a black image with the specified resolution.
constexpr size_t kBytesPerPixel = 4;
constexpr int kJpegQuality = 100;
const std::vector<unsigned char> input_buffer(width * height *
kBytesPerPixel);
std::vector<unsigned char> encoded;
const SkImageInfo info = SkImageInfo::Make(
width, height, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
const SkPixmap src(info, input_buffer.data(), width * kBytesPerPixel);
LOG_ASSERT(gfx::JPEGCodec::Encode(src, kJpegQuality, &encoded));
// Encode the generated image in the JPEG format, the output buffer will be
// automatically resized while encoding.
constexpr int kJpegQuality = 100;
std::vector<unsigned char> encoded;
LOG_ASSERT(gfx::JPEGCodec::Encode(src, kJpegQuality, downsample, &encoded));
base::FilePath filename;
LOG_ASSERT(base::GetTempDir(&filename));
filename =
filename.Append(base::StringPrintf("black-%dx%d.jpg", width, height));
auto image = std::make_unique<ParsedJpegImage>(filename);
image->data_str.append(encoded.begin(), encoded.end());
image->InitializeSizes(width, height);
return image;
......@@ -125,6 +130,7 @@ struct ParsedJpegImage {
// least one odd dimension.
coded_size.SetSize((visible_size.width() + 1) & ~1,
(visible_size.height() + 1) & ~1);
// The JPEG decoder will always return the decoded frame in I420 format.
output_size = VideoFrame::AllocationSize(PIXEL_FORMAT_I420, coded_size);
}
......@@ -172,6 +178,9 @@ class JpegDecodeAcceleratorTestEnvironment : public ::testing::Environment {
// Used for testing some drivers which will align the output resolution to a
// multiple of 16. 640x360 will be aligned to 640x368.
std::unique_ptr<ParsedJpegImage> image_data_640x360_black_;
// Generated black images used to test different JPEG sampling formats.
std::unique_ptr<ParsedJpegImage> image_data_640x368_422_black_;
std::unique_ptr<ParsedJpegImage> image_data_640x368_444_black_;
// Parsed data of "peach_pi-1280x720.jpg".
std::unique_ptr<ParsedJpegImage> image_data_1280x720_default_;
// Parsed data of failure image.
......@@ -191,6 +200,10 @@ void JpegDecodeAcceleratorTestEnvironment::SetUp() {
image_data_1280x720_black_ = ParsedJpegImage::CreateBlackImage(1280, 720);
image_data_640x368_black_ = ParsedJpegImage::CreateBlackImage(640, 368);
image_data_640x360_black_ = ParsedJpegImage::CreateBlackImage(640, 360);
image_data_640x368_422_black_ = ParsedJpegImage::CreateBlackImage(
640, 368, SkJpegEncoder::Downsample::k422);
image_data_640x368_444_black_ = ParsedJpegImage::CreateBlackImage(
640, 368, SkJpegEncoder::Downsample::k444);
image_data_1280x720_default_ = ParsedJpegImage::CreateFromFile(
GetOriginalOrTestDataFilePath(kDefaultJpegFilename));
......@@ -483,12 +496,14 @@ void JpegClient::StartDecode(int32_t bitstream_buffer_id,
dup_handle = base::SharedMemory::DuplicateHandle(in_shm_->handle());
BitstreamBuffer bitstream_buffer(bitstream_buffer_id, dup_handle,
image_file->data_str.size());
hw_out_frame_ = VideoFrame::WrapExternalSharedMemory(
PIXEL_FORMAT_I420, image_file->coded_size,
gfx::Rect(image_file->visible_size), image_file->visible_size,
static_cast<uint8_t*>(hw_out_shm_->memory()), image_file->output_size,
hw_out_shm_->handle(), 0, base::TimeDelta());
LOG_ASSERT(hw_out_frame_.get());
decoder_->Decode(bitstream_buffer, hw_out_frame_);
}
......@@ -772,6 +787,16 @@ TEST_F(JpegDecodeAcceleratorTest, CodedSizeAlignment) {
TestDecode(images, expected_status);
}
// Tests whether different JPEG sampling formats will be decoded correctly.
TEST_F(JpegDecodeAcceleratorTest, SamplingFormatChange) {
const std::vector<ParsedJpegImage*> images = {
g_env->image_data_640x368_black_.get(),
g_env->image_data_640x368_422_black_.get(),
g_env->image_data_640x368_444_black_.get()};
const std::vector<ClientState> expected_status(images.size(), CS_DECODE_PASS);
TestDecode(images, expected_status);
}
TEST_F(JpegDecodeAcceleratorTest, FailureJpeg) {
const std::vector<ParsedJpegImage*> images = {
g_env->image_data_invalid_.get()};
......
......@@ -11,7 +11,6 @@
#include "base/logging.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColorPriv.h"
#include "third_party/skia/include/encode/SkJpegEncoder.h"
#include "ui/gfx/codec/vector_wstream.h"
extern "C" {
......@@ -47,15 +46,23 @@ void ErrorExit(jpeg_common_struct* cinfo) {
// Encoder ---------------------------------------------------------------------
bool JPEGCodec::Encode(const SkPixmap& src,
bool JPEGCodec::Encode(const SkPixmap& input,
int quality,
SkJpegEncoder::Downsample downsample,
std::vector<unsigned char>* output) {
output->clear();
VectorWStream dst(output);
SkJpegEncoder::Options options;
options.fQuality = quality;
return SkJpegEncoder::Encode(&dst, src, options);
options.fDownsample = downsample;
return SkJpegEncoder::Encode(&dst, input, options);
}
bool JPEGCodec::Encode(const SkPixmap& input,
int quality,
std::vector<unsigned char>* output) {
return Encode(input, quality, SkJpegEncoder::Downsample::k420, output);
}
bool JPEGCodec::Encode(const SkBitmap& src,
......
......@@ -12,6 +12,7 @@
#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/codec/codec_export.h"
class SkBitmap;
......@@ -37,6 +38,20 @@ class CODEC_EXPORT JPEGCodec {
FORMAT_SkBitmap
};
// Encodes the given raw 'input' pixmap, which includes a pointer to pixels
// as well as information describing the pixel format. The encoded JPEG data
// will be written into the supplied vector and true will be returned on
// success. On failure (false), the contents of the output buffer are
// undefined.
//
// downsample: specifies how pixels will be sampled in the encoded JPEG image,
// can be either k420, k422 or k444.
// quality: an integer in the range 0-100, where 100 is the highest quality.
static bool Encode(const SkPixmap& input,
int quality,
SkJpegEncoder::Downsample downsample,
std::vector<unsigned char>* output);
// Encodes the given raw 'input' pixmap, which includes a pointer to pixels
// as well as information describing the pixel format. The encoded JPEG data
// will be written into the supplied vector and true will be returned on
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment