mirror of
https://github.com/roytam1/basilisk55.git
synced 2026-05-26 15:02:46 +00:00
ported from UXP: Issue #2118 - Part 2: Add support for Identity YUVColorSpace (3e62b1fc)
This commit is contained in:
@@ -232,6 +232,21 @@ AOMDecoder::DoDecode(MediaRawData* aSample)
|
||||
RESULT_DETAIL("AOM Unknown image format"));
|
||||
}
|
||||
|
||||
switch (img->mc) {
|
||||
case AOM_CICP_MC_BT_601:
|
||||
b.mYUVColorSpace = YUVColorSpace::BT601;
|
||||
break;
|
||||
case AOM_CICP_MC_BT_709:
|
||||
b.mYUVColorSpace = YUVColorSpace::BT709;
|
||||
break;
|
||||
case AOM_CICP_MC_IDENTITY:
|
||||
b.mYUVColorSpace = YUVColorSpace::IDENTITY;
|
||||
break;
|
||||
default:
|
||||
LOG("Unhandled colorspace %d", img->mc);
|
||||
break;
|
||||
}
|
||||
|
||||
RefPtr<VideoData> v =
|
||||
VideoData::CreateAndCopyData(mInfo,
|
||||
mImageContainer,
|
||||
|
||||
@@ -194,6 +194,22 @@ VPXDecoder::DoDecode(MediaRawData* aSample)
|
||||
RESULT_DETAIL("VPX Unknown image format"));
|
||||
}
|
||||
|
||||
b.mYUVColorSpace = [&]() {
|
||||
switch (img->cs) {
|
||||
case VPX_CS_BT_601:
|
||||
case VPX_CS_SMPTE_170:
|
||||
case VPX_CS_SMPTE_240:
|
||||
return YUVColorSpace::BT601;
|
||||
case VPX_CS_BT_709:
|
||||
return YUVColorSpace::BT709;
|
||||
case VPX_CS_SRGB:
|
||||
return YUVColorSpace::IDENTITY;
|
||||
default:
|
||||
LOG("Unhandled colorspace %d", img->cs);
|
||||
return YUVColorSpace::BT601;
|
||||
}
|
||||
}();
|
||||
|
||||
RefPtr<VideoData> v;
|
||||
if (!img_alpha) {
|
||||
v = VideoData::CreateAndCopyData(mInfo,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
|
||||
#define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P
|
||||
#define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P
|
||||
#define AV_PIX_FMT_GBRP PIX_FMT_GBRP
|
||||
#define AV_PIX_FMT_NONE PIX_FMT_NONE
|
||||
#endif
|
||||
|
||||
@@ -53,6 +54,9 @@ ChoosePixelFormat(AVCodecContext* aCodecContext, const AVPixelFormat* aFormats)
|
||||
case AV_PIX_FMT_YUVJ420P:
|
||||
FFMPEG_LOG("Requesting pixel format YUVJ420P.");
|
||||
return AV_PIX_FMT_YUVJ420P;
|
||||
case AV_PIX_FMT_GBRP:
|
||||
FFMPEG_LOG("Requesting pixel format GBRP.");
|
||||
return AV_PIX_FMT_GBRP;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -294,7 +298,8 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
|
||||
|
||||
b.mPlanes[0].mWidth = mFrame->width;
|
||||
b.mPlanes[0].mHeight = mFrame->height;
|
||||
if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P) {
|
||||
if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P ||
|
||||
mCodecContext->pix_fmt == AV_PIX_FMT_GBRP) {
|
||||
b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = mFrame->width;
|
||||
b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = mFrame->height;
|
||||
} else {
|
||||
@@ -310,6 +315,9 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
|
||||
case AVCOL_SPC_BT470BG:
|
||||
b.mYUVColorSpace = YUVColorSpace::BT601;
|
||||
break;
|
||||
case AVCOL_SPC_RGB:
|
||||
b.mYUVColorSpace = YUVColorSpace::IDENTITY;
|
||||
break;
|
||||
case AVCOL_SPC_UNSPECIFIED:
|
||||
#if LIBAVCODEC_VERSION_MAJOR >= 55
|
||||
if (mCodecContext->codec_id == AV_CODEC_ID_VP9) {
|
||||
|
||||
@@ -101,6 +101,7 @@ enum class StereoMode {
|
||||
enum class YUVColorSpace {
|
||||
BT601,
|
||||
BT709,
|
||||
IDENTITY,
|
||||
// This represents the unknown format.
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
@@ -1157,6 +1157,10 @@ const float kBT709NarrowYCbCrToRGB_RowMajor[16] = {
|
||||
1.16438f, 0.00000f, 1.79274f, -0.97295f, 1.16438f, -0.21325f,
|
||||
-0.53291f, 0.30148f, 1.16438f, 2.11240f, 0.00000f, -1.13340f,
|
||||
0.00000f, 0.00000f, 0.00000f, 1.00000f};
|
||||
const float kIdentityNarrowYCbCrToRGB_RowMajor[16] = {
|
||||
0.00000f, 0.00000f, 1.00000f, 0.00000f, 1.00000f, 0.00000f,
|
||||
0.00000f, 0.00000f, 0.00000f, 1.00000f, 0.00000f, 0.00000f,
|
||||
0.00000f, 0.00000f, 0.00000f, 1.00000f};
|
||||
|
||||
/* static */ const float*
|
||||
gfxUtils::Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace)
|
||||
@@ -1166,6 +1170,7 @@ gfxUtils::Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace)
|
||||
|
||||
static const float rec601[12] = X(kBT601NarrowYCbCrToRGB_RowMajor);
|
||||
static const float rec709[12] = X(kBT709NarrowYCbCrToRGB_RowMajor);
|
||||
static const float identity[12] = X(kIdentityNarrowYCbCrToRGB_RowMajor);
|
||||
|
||||
#undef X
|
||||
|
||||
@@ -1174,6 +1179,8 @@ gfxUtils::Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace)
|
||||
return rec601;
|
||||
case YUVColorSpace::BT709:
|
||||
return rec709;
|
||||
case YUVColorSpace::IDENTITY:
|
||||
return identity;
|
||||
default:
|
||||
MOZ_CRASH("Bad YUVColorSpace");
|
||||
}
|
||||
@@ -1187,6 +1194,7 @@ gfxUtils::Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace)
|
||||
|
||||
static const float rec601[9] = X(kBT601NarrowYCbCrToRGB_RowMajor);
|
||||
static const float rec709[9] = X(kBT709NarrowYCbCrToRGB_RowMajor);
|
||||
static const float identity[9] = X(kIdentityNarrowYCbCrToRGB_RowMajor);
|
||||
|
||||
#undef X
|
||||
|
||||
@@ -1195,6 +1203,8 @@ gfxUtils::Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace)
|
||||
return rec601;
|
||||
case YUVColorSpace::BT709:
|
||||
return rec709;
|
||||
case YUVColorSpace::IDENTITY:
|
||||
return identity;
|
||||
default:
|
||||
MOZ_CRASH("Bad YUVColorSpace");
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
// Header for low level row functions.
|
||||
#include "yuv_row.h"
|
||||
#include "mozilla/SSE.h"
|
||||
#include "mozilla/IntegerRange.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -63,6 +64,23 @@ libyuv::FourCC FourCCFromYUVType(YUVType aYUVType)
|
||||
}
|
||||
}
|
||||
|
||||
void GBRPlanarToARGB(const uint8_t* src_y, int y_pitch,
|
||||
const uint8_t* src_u, int u_pitch,
|
||||
const uint8_t* src_v, int v_pitch,
|
||||
uint8_t* rgb_buf, int rgb_pitch,
|
||||
int pic_width, int pic_height) {
|
||||
// libyuv has no native conversion function for this
|
||||
// fixme: replace with something less awful
|
||||
for (const auto row : IntegerRange(pic_height)) {
|
||||
for (const auto col : IntegerRange(pic_width)) {
|
||||
rgb_buf[rgb_pitch * row + col * 4 + 0] = src_u[u_pitch * row + col];
|
||||
rgb_buf[rgb_pitch * row + col * 4 + 1] = src_y[y_pitch * row + col];
|
||||
rgb_buf[rgb_pitch * row + col * 4 + 2] = src_v[v_pitch * row + col];
|
||||
rgb_buf[rgb_pitch * row + col * 4 + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a frame of YUV to 32 bit ARGB.
|
||||
void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
@@ -113,13 +131,20 @@ void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||
const uint8* src_y = y_buf + y_pitch * pic_y + pic_x;
|
||||
const uint8* src_u = u_buf + uv_pitch * pic_y + pic_x;
|
||||
const uint8* src_v = v_buf + uv_pitch * pic_y + pic_x;
|
||||
DebugOnly<int> err = libyuv::I444ToARGBMatrix(src_y, y_pitch,
|
||||
src_u, uv_pitch,
|
||||
src_v, uv_pitch,
|
||||
rgb_buf, rgb_pitch,
|
||||
yuvconstants,
|
||||
pic_width, pic_height);
|
||||
MOZ_ASSERT(!err);
|
||||
if (yuv_color_space == YUVColorSpace::IDENTITY) {
|
||||
// Special case for RGB image
|
||||
GBRPlanarToARGB(src_y, y_pitch, src_u, uv_pitch, src_v, uv_pitch,
|
||||
rgb_buf, rgb_pitch, pic_width, pic_height);
|
||||
return;
|
||||
} else {
|
||||
DebugOnly<int> err = libyuv::I444ToARGBMatrix(src_y, y_pitch,
|
||||
src_u, uv_pitch,
|
||||
src_v, uv_pitch,
|
||||
rgb_buf, rgb_pitch,
|
||||
yuvconstants,
|
||||
pic_width, pic_height);
|
||||
MOZ_ASSERT(!err);
|
||||
}
|
||||
} else if (yuv_type == YV16) {
|
||||
const uint8* src_y = y_buf + y_pitch * pic_y + pic_x;
|
||||
const uint8* src_u = u_buf + uv_pitch * pic_y + pic_x / 2;
|
||||
@@ -301,6 +326,21 @@ void ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||
return;
|
||||
}
|
||||
|
||||
if (yuv_type == YV24 && yuv_color_space == YUVColorSpace::IDENTITY) {
|
||||
auto buffer = MakeUnique<uint8[]>(source_width * source_height * 4);
|
||||
auto buffer_pitch = source_width * 4;
|
||||
GBRPlanarToARGB(y_buf, y_pitch, u_buf, uv_pitch, v_buf, uv_pitch,
|
||||
buffer.get(), buffer_pitch, source_width, source_height);
|
||||
DebugOnly<int> err =
|
||||
libyuv::ARGBScale(buffer.get(), buffer_pitch,
|
||||
source_width, source_height,
|
||||
rgb_buf, rgb_pitch,
|
||||
width, height,
|
||||
libyuv::kFilterBilinear);
|
||||
MOZ_ASSERT(!err);
|
||||
return;
|
||||
}
|
||||
|
||||
DebugOnly<int> err =
|
||||
libyuv::YUVToARGBScale(y_buf, y_pitch,
|
||||
u_buf, uv_pitch,
|
||||
|
||||
Reference in New Issue
Block a user