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 @@ ...@@ -17,6 +17,7 @@
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "media/gpu/macros.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_jpeg_decoder.h"
#include "media/gpu/vaapi/vaapi_utils.h" #include "media/gpu/vaapi/vaapi_utils.h"
#include "mojo/public/cpp/bindings/callback_helpers.h" #include "mojo/public/cpp/bindings/callback_helpers.h"
...@@ -52,11 +53,17 @@ void DecodeTask( ...@@ -52,11 +53,17 @@ void DecodeTask(
mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(decode_cb), mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(decode_cb),
nullptr); nullptr);
VaapiJpegDecodeStatus status; VaapiJpegDecodeStatus status;
std::unique_ptr<ScopedVAImage> scoped_image = decoder->DoDecode( decoder->Decode(
base::make_span<const uint8_t>(encoded_data.data(), encoded_data.size()), base::make_span<const uint8_t>(encoded_data.data(), encoded_data.size()),
VA_FOURCC_RGBX /* preferred_image_fourcc */, &status); &status);
if (status != VaapiJpegDecodeStatus::kSuccess) { 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); << static_cast<uint32_t>(status);
return; return;
} }
......
...@@ -12,12 +12,14 @@ ...@@ -12,12 +12,14 @@
#include <va/va.h> #include <va/va.h>
#include "base/bind_helpers.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "media/base/video_types.h" #include "media/base/video_types.h"
#include "media/filters/jpeg_parser.h" #include "media/filters/jpeg_parser.h"
#include "media/gpu/macros.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_utils.h"
#include "media/gpu/vaapi/vaapi_wrapper.h" #include "media/gpu/vaapi/vaapi_wrapper.h"
...@@ -223,9 +225,8 @@ bool VaapiJpegDecoder::Initialize(const base::RepeatingClosure& error_uma_cb) { ...@@ -223,9 +225,8 @@ bool VaapiJpegDecoder::Initialize(const base::RepeatingClosure& error_uma_cb) {
return true; return true;
} }
std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::DoDecode( scoped_refptr<VASurface> VaapiJpegDecoder::Decode(
base::span<const uint8_t> encoded_image, base::span<const uint8_t> encoded_image,
uint32_t preferred_image_fourcc,
VaapiJpegDecodeStatus* status) { VaapiJpegDecodeStatus* status) {
if (!vaapi_wrapper_) { if (!vaapi_wrapper_) {
VLOGF(1) << "VaapiJpegDecoder has not been initialized"; VLOGF(1) << "VaapiJpegDecoder has not been initialized";
...@@ -332,7 +333,21 @@ std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::DoDecode( ...@@ -332,7 +333,21 @@ std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::DoDecode(
return nullptr; 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; uint32_t image_fourcc;
if (!VaapiWrapper::GetJpegDecodeSuitableImageFourCC( if (!VaapiWrapper::GetJpegDecodeSuitableImageFourCC(
va_rt_format_, preferred_image_fourcc, &image_fourcc)) { va_rt_format_, preferred_image_fourcc, &image_fourcc)) {
...@@ -354,11 +369,4 @@ std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::DoDecode( ...@@ -354,11 +369,4 @@ std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::DoDecode(
return scoped_image; 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 } // namespace media
...@@ -22,6 +22,7 @@ namespace media { ...@@ -22,6 +22,7 @@ namespace media {
struct JpegFrameHeader; struct JpegFrameHeader;
class ScopedVAImage; class ScopedVAImage;
class VASurface;
class VaapiWrapper; class VaapiWrapper;
enum class VaapiJpegDecodeStatus : uint32_t { enum class VaapiJpegDecodeStatus : uint32_t {
...@@ -63,20 +64,20 @@ class VaapiJpegDecoder final { ...@@ -63,20 +64,20 @@ class VaapiJpegDecoder final {
// Decodes a JPEG picture. It will fill VA-API parameters and call the // Decodes a JPEG picture. It will fill VA-API parameters and call the
// corresponding VA-API methods according to the JPEG in |encoded_image|. // corresponding VA-API methods according to the JPEG in |encoded_image|.
// Decoded data will be returned as a ScopedVAImage. The VAImage's format will // The image will be decoded into an internally allocated VA surface. It
// be either |preferred_image_fourcc| if the conversion from the internal // will be returned as an unowned VASurface, which remains valid until the
// format is supported or a fallback FOURCC (see // 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);
// 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 // VaapiWrapper::GetJpegDecodeSuitableImageFourCC() for details). Returns
// nullptr on failure and sets *|status| to the reason for failure. // nullptr on failure and sets *|status| to the reason for failure.
std::unique_ptr<ScopedVAImage> DoDecode( std::unique_ptr<ScopedVAImage> GetImage(uint32_t preferred_image_fourcc,
base::span<const uint8_t> encoded_image, VaapiJpegDecodeStatus* status);
uint32_t preferred_image_fourcc,
VaapiJpegDecodeStatus* status);
// Calls DoDecode() above with |preferred_image_fourcc| = VA_FOURCC_I420.
std::unique_ptr<ScopedVAImage> DoDecode(
base::span<const uint8_t> encoded_image,
VaapiJpegDecodeStatus* status);
private: private:
scoped_refptr<VaapiWrapper> vaapi_wrapper_; scoped_refptr<VaapiWrapper> vaapi_wrapper_;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "media/base/test_data_util.h" #include "media/base/test_data_util.h"
...@@ -333,6 +334,8 @@ int GetMaxSupportedDimension(int max_surface_supported) { ...@@ -333,6 +334,8 @@ int GetMaxSupportedDimension(int max_surface_supported) {
} // namespace } // namespace
class VASurface;
class VaapiJpegDecoderTest : public testing::TestWithParam<TestParam> { class VaapiJpegDecoderTest : public testing::TestWithParam<TestParam> {
protected: protected:
VaapiJpegDecoderTest() { VaapiJpegDecoderTest() {
...@@ -380,12 +383,22 @@ std::unique_ptr<ScopedVAImage> VaapiJpegDecoderTest::Decode( ...@@ -380,12 +383,22 @@ std::unique_ptr<ScopedVAImage> VaapiJpegDecoderTest::Decode(
base::span<const uint8_t> encoded_image, base::span<const uint8_t> encoded_image,
uint32_t preferred_fourcc, uint32_t preferred_fourcc,
VaapiJpegDecodeStatus* status) { VaapiJpegDecodeStatus* status) {
VaapiJpegDecodeStatus tmp_status; VaapiJpegDecodeStatus decode_status;
std::unique_ptr<ScopedVAImage> scoped_image = scoped_refptr<VASurface> surface =
decoder_.DoDecode(encoded_image, preferred_fourcc, &tmp_status); decoder_.Decode(encoded_image, &decode_status);
EXPECT_EQ(!!scoped_image, tmp_status == VaapiJpegDecodeStatus::kSuccess); EXPECT_EQ(!!surface, decode_status == VaapiJpegDecodeStatus::kSuccess);
if (status)
*status = tmp_status; // 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; return scoped_image;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/base/video_types.h" #include "media/base/video_types.h"
#include "media/gpu/macros.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_utils.h"
#include "media/gpu/vaapi/vaapi_wrapper.h" #include "media/gpu/vaapi/vaapi_wrapper.h"
#include "third_party/libyuv/include/libyuv.h" #include "third_party/libyuv/include/libyuv.h"
...@@ -226,14 +227,19 @@ void VaapiMjpegDecodeAccelerator::DecodeTask( ...@@ -226,14 +227,19 @@ void VaapiMjpegDecodeAccelerator::DecodeTask(
TRACE_EVENT0("jpeg", "DecodeTask"); TRACE_EVENT0("jpeg", "DecodeTask");
VaapiJpegDecodeStatus status; VaapiJpegDecodeStatus status;
std::unique_ptr<ScopedVAImage> image = decoder_.DoDecode( decoder_.Decode(
base::make_span<const uint8_t>(static_cast<const uint8_t*>(shm->memory()), base::make_span(static_cast<const uint8_t*>(shm->memory()), shm->size()),
shm->size()),
&status); &status);
if (status != VaapiJpegDecodeStatus::kSuccess) { if (status != VaapiJpegDecodeStatus::kSuccess) {
NotifyError(bitstream_buffer_id, VaapiJpegDecodeStatusToError(status)); NotifyError(bitstream_buffer_id, VaapiJpegDecodeStatusToError(status));
return; 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, if (!OutputPictureOnTaskRunner(std::move(image), bitstream_buffer_id,
std::move(video_frame))) { 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