Commit 68c804d2 authored by Ren-Pei Zeng's avatar Ren-Pei Zeng Committed by Commit Bot

media/gpu: Refactor VaapiJpegDecoder to export VA surface

This CL decouples JPEG decoding and surface-to-image conversion in
VaapiJpegDecoder interface. Caller can obtain the decoded VA surface
from decoder, and get a VA image zero or multiple times.

Bug: b:120057531
Test: Pass jpeg_decode_accelerator_unittest.
Change-Id: I8bde2ec508394b05cf8058432efdb1b598535bf9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1609751
Commit-Queue: Ren-Pei Zeng <kamesan@chromium.org>
Reviewed-by: default avatarAndres Calderon Jaramillo <andrescj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#660761}
parent ddac2d1a
......@@ -17,6 +17,7 @@
#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "media/gpu/macros.h"
#include "media/gpu/vaapi/va_surface.h"
#include "media/gpu/vaapi/vaapi_jpeg_decoder.h"
#include "media/gpu/vaapi/vaapi_utils.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
......@@ -52,11 +53,17 @@ void DecodeTask(
mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(decode_cb),
nullptr);
VaapiJpegDecodeStatus status;
std::unique_ptr<ScopedVAImage> scoped_image = decoder->DoDecode(
decoder->Decode(
base::make_span<const uint8_t>(encoded_data.data(), encoded_data.size()),
VA_FOURCC_RGBX /* preferred_image_fourcc */, &status);
&status);
if (status != VaapiJpegDecodeStatus::kSuccess) {
VLOGF(1) << "Failed to decode image - status = "
VLOGF(1) << "Failed to decode - status = " << static_cast<uint32_t>(status);
return;
}
std::unique_ptr<ScopedVAImage> scoped_image =
decoder->GetImage(VA_FOURCC_RGBX /* preferred_image_fourcc */, &status);
if (status != VaapiJpegDecodeStatus::kSuccess) {
VLOGF(1) << "Failed to get image - status = "
<< static_cast<uint32_t>(status);
return;
}
......
......@@ -12,12 +12,14 @@
#include <va/va.h>
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "media/base/video_types.h"
#include "media/filters/jpeg_parser.h"
#include "media/gpu/macros.h"
#include "media/gpu/vaapi/va_surface.h"
#include "media/gpu/vaapi/vaapi_utils.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
......@@ -223,9 +225,8 @@ bool VaapiJpegDecoder::Initialize(const base::RepeatingClosure& error_uma_cb) {
return true;
}
std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::DoDecode(
scoped_refptr<VASurface> VaapiJpegDecoder::Decode(
base::span<const uint8_t> encoded_image,
uint32_t preferred_image_fourcc,
VaapiJpegDecodeStatus* status) {
if (!vaapi_wrapper_) {
VLOGF(1) << "VaapiJpegDecoder has not been initialized";
......@@ -332,7 +333,21 @@ std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::DoDecode(
return nullptr;
}
// Get the decode output as a ScopedVAImage.
*status = VaapiJpegDecodeStatus::kSuccess;
return base::MakeRefCounted<VASurface>(va_surface_id_, coded_size_,
va_rt_format_,
base::DoNothing() /* release_cb */);
}
std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::GetImage(
uint32_t preferred_image_fourcc,
VaapiJpegDecodeStatus* status) {
if (va_surface_id_ == VA_INVALID_ID) {
VLOGF(1) << "No decoded JPEG available";
*status = VaapiJpegDecodeStatus::kInvalidState;
return nullptr;
}
uint32_t image_fourcc;
if (!VaapiWrapper::GetJpegDecodeSuitableImageFourCC(
va_rt_format_, preferred_image_fourcc, &image_fourcc)) {
......@@ -354,11 +369,4 @@ std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::DoDecode(
return scoped_image;
}
std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::DoDecode(
base::span<const uint8_t> encoded_image,
VaapiJpegDecodeStatus* status) {
return DoDecode(encoded_image, VA_FOURCC_I420 /* preferred_image_fourcc */,
status);
}
} // namespace media
......@@ -22,6 +22,7 @@ namespace media {
struct JpegFrameHeader;
class ScopedVAImage;
class VASurface;
class VaapiWrapper;
enum class VaapiJpegDecodeStatus : uint32_t {
......@@ -63,19 +64,19 @@ class VaapiJpegDecoder final {
// Decodes a JPEG picture. It will fill VA-API parameters and call the
// corresponding VA-API methods according to the JPEG in |encoded_image|.
// Decoded data will be returned as a ScopedVAImage. The VAImage's format will
// be either |preferred_image_fourcc| if the conversion from the internal
// format is supported or a fallback FOURCC (see
// VaapiWrapper::GetJpegDecodeSuitableImageFourCC() for details). Returns
// nullptr on failure and sets *|status| to the reason for failure.
std::unique_ptr<ScopedVAImage> DoDecode(
base::span<const uint8_t> encoded_image,
uint32_t preferred_image_fourcc,
// The image will be decoded into an internally allocated VA surface. It
// will be returned as an unowned VASurface, which remains valid until the
// next Decode() call or destruction of this class. Returns nullptr on
// failure and sets *|status| to the reason for failure.
scoped_refptr<VASurface> Decode(base::span<const uint8_t> encoded_image,
VaapiJpegDecodeStatus* status);
// Calls DoDecode() above with |preferred_image_fourcc| = VA_FOURCC_I420.
std::unique_ptr<ScopedVAImage> DoDecode(
base::span<const uint8_t> encoded_image,
// Get the decoded data from the last Decode() call as a ScopedVAImage. The
// VAImage's format will be either |preferred_image_fourcc| if the conversion
// from the internal format is supported or a fallback FOURCC (see
// VaapiWrapper::GetJpegDecodeSuitableImageFourCC() for details). Returns
// nullptr on failure and sets *|status| to the reason for failure.
std::unique_ptr<ScopedVAImage> GetImage(uint32_t preferred_image_fourcc,
VaapiJpegDecodeStatus* status);
private:
......
......@@ -21,6 +21,7 @@
#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/test_data_util.h"
......@@ -333,6 +334,8 @@ int GetMaxSupportedDimension(int max_surface_supported) {
} // namespace
class VASurface;
class VaapiJpegDecoderTest : public testing::TestWithParam<TestParam> {
protected:
VaapiJpegDecoderTest() {
......@@ -380,12 +383,22 @@ std::unique_ptr<ScopedVAImage> VaapiJpegDecoderTest::Decode(
base::span<const uint8_t> encoded_image,
uint32_t preferred_fourcc,
VaapiJpegDecodeStatus* status) {
VaapiJpegDecodeStatus tmp_status;
std::unique_ptr<ScopedVAImage> scoped_image =
decoder_.DoDecode(encoded_image, preferred_fourcc, &tmp_status);
EXPECT_EQ(!!scoped_image, tmp_status == VaapiJpegDecodeStatus::kSuccess);
if (status)
*status = tmp_status;
VaapiJpegDecodeStatus decode_status;
scoped_refptr<VASurface> surface =
decoder_.Decode(encoded_image, &decode_status);
EXPECT_EQ(!!surface, decode_status == VaapiJpegDecodeStatus::kSuccess);
// Still try to get image when decode fails.
VaapiJpegDecodeStatus image_status;
std::unique_ptr<ScopedVAImage> scoped_image;
scoped_image = decoder_.GetImage(preferred_fourcc, &image_status);
EXPECT_EQ(!!scoped_image, image_status == VaapiJpegDecodeStatus::kSuccess);
// Record the first fail status.
if (status) {
*status = decode_status != VaapiJpegDecodeStatus::kSuccess ? decode_status
: image_status;
}
return scoped_image;
}
......
......@@ -24,6 +24,7 @@
#include "media/base/video_frame.h"
#include "media/base/video_types.h"
#include "media/gpu/macros.h"
#include "media/gpu/vaapi/va_surface.h"
#include "media/gpu/vaapi/vaapi_utils.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "third_party/libyuv/include/libyuv.h"
......@@ -226,14 +227,19 @@ void VaapiMjpegDecodeAccelerator::DecodeTask(
TRACE_EVENT0("jpeg", "DecodeTask");
VaapiJpegDecodeStatus status;
std::unique_ptr<ScopedVAImage> image = decoder_.DoDecode(
base::make_span<const uint8_t>(static_cast<const uint8_t*>(shm->memory()),
shm->size()),
decoder_.Decode(
base::make_span(static_cast<const uint8_t*>(shm->memory()), shm->size()),
&status);
if (status != VaapiJpegDecodeStatus::kSuccess) {
NotifyError(bitstream_buffer_id, VaapiJpegDecodeStatusToError(status));
return;
}
std::unique_ptr<ScopedVAImage> image =
decoder_.GetImage(VA_FOURCC_I420 /* preferred_image_fourcc */, &status);
if (status != VaapiJpegDecodeStatus::kSuccess) {
NotifyError(bitstream_buffer_id, VaapiJpegDecodeStatusToError(status));
return;
}
if (!OutputPictureOnTaskRunner(std::move(image), bitstream_buffer_id,
std::move(video_frame))) {
......
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