Bug 1907121 - Modify YCbCrUtils APIs to return yuv_convert execution results r=gfx-reviewers,nical

Previously, the YCbCrUtils APIs internally asserted the success of the
underlying yuv_convert API calls. This patch modifies the YCbCrUtils
APIs to return the results of these calls instead of silently asserting
them. While the assertions are temporarily removed, they will be
reintroduced in appropriate locations in subsequent patches.

Differential Revision: https://phabricator.services.mozilla.com/D216189
This commit is contained in:
Chun-Min Chang 2024-07-18 21:02:32 +00:00
parent 778413a663
commit 64939f2f56
2 changed files with 105 additions and 96 deletions

View File

@ -15,8 +15,6 @@
namespace mozilla {
namespace gfx {
// clang-format off
static YUVType GetYUVType(const layers::PlanarYCbCrData& aData) {
switch (aData.mChromaSubsampling) {
case ChromaSubsampling::FULL:
@ -192,12 +190,12 @@ struct YUV8BitData {
UniquePtr<uint8_t[]> mAlphaChannel;
};
static void ScaleYCbCrToRGB(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
const IntSize& aDestSize,
unsigned char* aDestBuffer,
int32_t aStride,
YUVType aYUVType) {
static nsresult ScaleYCbCrToRGB(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
const IntSize& aDestSize,
unsigned char* aDestBuffer,
int32_t aStride,
YUVType aYUVType) {
#if defined(HAVE_YCBCR_TO_RGB565)
if (aDestFormat == SurfaceFormat::R5G6B5_UINT16) {
ScaleYCbCrToRGB565(aData.mYChannel,
@ -215,31 +213,31 @@ static void ScaleYCbCrToRGB(const layers::PlanarYCbCrData& aData,
aStride,
aYUVType,
FILTER_BILINEAR);
return;
return NS_OK;
}
#endif
ScaleYCbCrToRGB32(aData.mYChannel,
aData.mCbChannel,
aData.mCrChannel,
aDestBuffer,
aData.mPictureRect.width,
aData.mPictureRect.height,
aDestSize.width,
aDestSize.height,
aData.mYStride,
aData.mCbCrStride,
aStride,
aYUVType,
aData.mYUVColorSpace,
FILTER_BILINEAR);
return ScaleYCbCrToRGB32(aData.mYChannel,
aData.mCbChannel,
aData.mCrChannel,
aDestBuffer,
aData.mPictureRect.width,
aData.mPictureRect.height,
aDestSize.width,
aDestSize.height,
aData.mYStride,
aData.mCbCrStride,
aStride,
aYUVType,
aData.mYUVColorSpace,
FILTER_BILINEAR);
}
static void ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
unsigned char* aDestBuffer,
int32_t aStride,
YUVType aYUVType,
RGB32Type aRGB32Type) {
static nsresult ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
unsigned char* aDestBuffer,
int32_t aStride,
YUVType aYUVType,
RGB32Type aRGB32Type) {
#if defined(HAVE_YCBCR_TO_RGB565)
if (aDestFormat == SurfaceFormat::R5G6B5_UINT16) {
ConvertYCbCrToRGB565(aData.mYChannel,
@ -254,30 +252,30 @@ static void ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
aData.mCbCrStride,
aStride,
aYUVType);
return;
return NS_OK;
}
#endif
ConvertYCbCrToRGB32(aData.mYChannel,
aData.mCbChannel,
aData.mCrChannel,
aDestBuffer,
aData.mPictureRect.x,
aData.mPictureRect.y,
aData.mPictureRect.width,
aData.mPictureRect.height,
aData.mYStride,
aData.mCbCrStride,
aStride,
aYUVType,
aData.mYUVColorSpace,
aData.mColorRange,
aRGB32Type);
return ConvertYCbCrToRGB32(aData.mYChannel,
aData.mCbChannel,
aData.mCrChannel,
aDestBuffer,
aData.mPictureRect.x,
aData.mPictureRect.y,
aData.mPictureRect.width,
aData.mPictureRect.height,
aData.mYStride,
aData.mCbCrStride,
aStride,
aYUVType,
aData.mYUVColorSpace,
aData.mColorRange,
aRGB32Type);
}
void ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
const IntSize& aDestSize, unsigned char* aDestBuffer,
int32_t aStride) {
nsresult ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
const IntSize& aDestSize, unsigned char* aDestBuffer,
int32_t aStride) {
// ConvertYCbCrToRGB et al. assume the chroma planes are rounded up if the
// luma plane is odd sized. Monochrome images have 0-sized CbCr planes
YUVType yuvtype = GetYUVType(aData);
@ -286,22 +284,29 @@ void ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
const layers::PlanarYCbCrData& srcData = data.Get8BitData();
// Convert from YCbCr to RGB now, scaling the image if needed.
nsresult result = NS_OK;
if (aDestSize != srcData.mPictureRect.Size()) {
ScaleYCbCrToRGB(srcData, aDestFormat, aDestSize, aDestBuffer, aStride,
yuvtype);
result = ScaleYCbCrToRGB(srcData, aDestFormat, aDestSize, aDestBuffer,
aStride, yuvtype);
} else { // no prescale
ConvertYCbCrToRGB(srcData, aDestFormat, aDestBuffer, aStride, yuvtype,
RGB32Type::ARGB);
result = ConvertYCbCrToRGB(srcData, aDestFormat, aDestBuffer, aStride,
yuvtype, RGB32Type::ARGB);
}
if (NS_FAILED(result)) {
return result;
}
#if MOZ_BIG_ENDIAN()
// libyuv makes endian-correct result, which needs to be swapped to BGRX
if (aDestFormat != SurfaceFormat::R5G6B5_UINT16) {
gfx::SwizzleData(aDestBuffer, aStride, gfx::SurfaceFormat::X8R8G8B8,
aDestBuffer, aStride, gfx::SurfaceFormat::B8G8R8X8,
aDestSize);
if (!gfx::SwizzleData(aDestBuffer, aStride, gfx::SurfaceFormat::X8R8G8B8,
aDestBuffer, aStride, gfx::SurfaceFormat::B8G8R8X8,
aDestSize)) {
return NS_ERROR_UNEXPECTED;
}
}
#endif
return NS_OK;
}
void FillAlphaToRGBA(const uint8_t* aAlpha, const int32_t aAlphaStride,
@ -326,10 +331,10 @@ void FillAlphaToRGBA(const uint8_t* aAlpha, const int32_t aAlphaStride,
}
}
void ConvertYCbCrToRGB32(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
unsigned char* aDestBuffer, int32_t aStride,
PremultFunc premultiplyAlphaOp) {
nsresult ConvertYCbCrToRGB32(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
unsigned char* aDestBuffer, int32_t aStride,
PremultFunc premultiplyAlphaOp) {
MOZ_ASSERT(aDestFormat == SurfaceFormat::B8G8R8A8 ||
aDestFormat == SurfaceFormat::B8G8R8X8 ||
aDestFormat == SurfaceFormat::R8G8B8A8 ||
@ -347,8 +352,11 @@ void ConvertYCbCrToRGB32(const layers::PlanarYCbCrData& aData,
? RGB32Type::ARGB
: RGB32Type::ABGR;
ConvertYCbCrToRGB(data, aDestFormat, aDestBuffer, aStride, yuvtype,
rgb32Type);
nsresult result = ConvertYCbCrToRGB(data, aDestFormat, aDestBuffer, aStride,
yuvtype, rgb32Type);
if (NS_FAILED(result)) {
return result;
}
bool needAlpha = aDestFormat == SurfaceFormat::B8G8R8A8 ||
aDestFormat == SurfaceFormat::R8G8B8A8;
@ -359,48 +367,48 @@ void ConvertYCbCrToRGB32(const layers::PlanarYCbCrData& aData,
aDestFormat);
if (premultiplyAlphaOp) {
DebugOnly<int> err = premultiplyAlphaOp(aDestBuffer, aStride, aDestBuffer,
aStride, aData.mPictureRect.width,
aData.mPictureRect.height);
MOZ_ASSERT(!err);
result = ToNSResult(premultiplyAlphaOp(aDestBuffer, aStride, aDestBuffer,
aStride, aData.mPictureRect.width,
aData.mPictureRect.height));
if (NS_FAILED(result)) {
return result;
}
}
}
#if MOZ_BIG_ENDIAN()
// libyuv makes endian-correct result, which needs to be reversed to BGR* or
// RGB*.
gfx::SwizzleData(aDestBuffer, aStride, gfx::SurfaceFormat::X8R8G8B8,
aDestBuffer, aStride, gfx::SurfaceFormat::B8G8R8X8,
aData.mPictureRect.Size());
if (!gfx::SwizzleData(aDestBuffer, aStride, gfx::SurfaceFormat::X8R8G8B8,
aDestBuffer, aStride, gfx::SurfaceFormat::B8G8R8X8,
aData.mPictureRect.Size())) {
return NS_ERROR_UNEXPECTED;
}
#endif
return NS_OK;
}
void
ConvertI420AlphaToARGB(const uint8_t* aSrcY,
const uint8_t* aSrcU,
const uint8_t* aSrcV,
const uint8_t* aSrcA,
int aSrcStrideYA, int aSrcStrideUV,
uint8_t* aDstARGB, int aDstStrideARGB,
int aWidth, int aHeight) {
ConvertI420AlphaToARGB32(aSrcY,
aSrcU,
aSrcV,
aSrcA,
aDstARGB,
aWidth,
aHeight,
aSrcStrideYA,
aSrcStrideUV,
aDstStrideARGB);
nsresult ConvertI420AlphaToARGB(const uint8_t* aSrcY, const uint8_t* aSrcU,
const uint8_t* aSrcV, const uint8_t* aSrcA,
int aSrcStrideYA, int aSrcStrideUV,
uint8_t* aDstARGB, int aDstStrideARGB,
int aWidth, int aHeight) {
nsresult result = ConvertI420AlphaToARGB32(
aSrcY, aSrcU, aSrcV, aSrcA, aDstARGB, aWidth, aHeight, aSrcStrideYA,
aSrcStrideUV, aDstStrideARGB);
if (NS_FAILED(result)) {
return result;
}
#if MOZ_BIG_ENDIAN()
// libyuv makes endian-correct result, which needs to be swapped to BGRA
gfx::SwizzleData(aDstARGB, aDstStrideARGB, gfx::SurfaceFormat::A8R8G8B8,
aDstARGB, aDstStrideARGB, gfx::SurfaceFormat::B8G8R8A8,
IntSize(aWidth, aHeight));
if (!gfx::SwizzleData(aDstARGB, aDstStrideARGB, gfx::SurfaceFormat::A8R8G8B8,
aDstARGB, aDstStrideARGB, gfx::SurfaceFormat::B8G8R8A8,
IntSize(aWidth, aHeight))) {
return NS_ERROR_UNEXPECTED;
}
#endif
return NS_OK;
}
} // namespace gfx
} // namespace mozilla
} // namespace gfx
} // namespace mozilla

View File

@ -6,6 +6,7 @@
#ifndef Y_CB_CR_UTILS_H_
#define Y_CB_CR_UTILS_H_
#include "ErrorList.h"
#include "ImageContainer.h"
#include "mozilla/gfx/Types.h"
@ -17,7 +18,7 @@ GetYCbCrToRGBDestFormatAndSize(const layers::PlanarYCbCrData& aData,
SurfaceFormat& aSuggestedFormat,
IntSize& aSuggestedSize);
void
nsresult
ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
const IntSize& aDestSize,
@ -29,14 +30,14 @@ using PremultFunc = int (*)(const uint8_t* src_argb, int src_stride_argb,
int height);
// Convert given YUV data w/ or w/out alpha into BGRA or BGRX data.
void
nsresult
ConvertYCbCrToRGB32(const layers::PlanarYCbCrData& aData,
const SurfaceFormat& aDestFormat,
unsigned char* aDestBuffer,
int32_t aStride,
PremultFunc premultiplyAlphaOp);
void
nsresult
ConvertI420AlphaToARGB(const uint8_t* aSrcY,
const uint8_t* aSrcU,
const uint8_t* aSrcV,