mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2026-02-07 18:26:43 +08:00
10 bit YUV to 10 bit BGR
BGR variation of 10 bit conversion using swapped U and V and mirrored matrix to produce AB30 format instead of AR30. Bug: libyuv:777 Test: LibYUVConvertTest.H010ToAB30_Opt Change-Id: I96d115a5d1e12138f40cb548871e03aa3ab210eb Reviewed-on: https://chromium-review.googlesource.com/922284 Commit-Queue: Frank Barchard <fbarchard@chromium.org> Reviewed-by: Miguel Casas <mcasas@chromium.org>
This commit is contained in:
parent
439fc3ce3d
commit
6630558875
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 1697
|
||||
Version: 1698
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -50,11 +50,12 @@ The following is extracted from video_common.h as a complete list of formats sup
|
||||
// 1 Secondary YUV format: row biplanar.
|
||||
FOURCC_M420 = FOURCC('M', '4', '2', '0'),
|
||||
|
||||
// 10 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc
|
||||
// 11 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc
|
||||
FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'),
|
||||
FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'),
|
||||
FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'),
|
||||
FOURCC_AR30 = FOURCC('A', 'R', '3', '0'), // 10 bit per channel. 2101010.
|
||||
FOURCC_AB30 = FOURCC('A', 'B', '3', '0'), // ABGR version of 10 bit
|
||||
FOURCC_24BG = FOURCC('2', '4', 'B', 'G'),
|
||||
FOURCC_RAW = FOURCC('r', 'a', 'w', ' '),
|
||||
FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'),
|
||||
|
||||
@ -446,6 +446,32 @@ int H010ToAR30(const uint16_t* src_y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
// Convert I010 to AB30.
|
||||
LIBYUV_API
|
||||
int I010ToAB30(const uint16_t* src_y,
|
||||
int src_stride_y,
|
||||
const uint16_t* src_u,
|
||||
int src_stride_u,
|
||||
const uint16_t* src_v,
|
||||
int src_stride_v,
|
||||
uint8_t* dst_ab30,
|
||||
int dst_stride_ab30,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
// Convert H010 to AB30.
|
||||
LIBYUV_API
|
||||
int H010ToAB30(const uint16_t* src_y,
|
||||
int src_stride_y,
|
||||
const uint16_t* src_u,
|
||||
int src_stride_u,
|
||||
const uint16_t* src_v,
|
||||
int src_stride_v,
|
||||
uint8_t* dst_ab30,
|
||||
int dst_stride_ab30,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
// BGRA little endian (argb in memory) to ARGB.
|
||||
LIBYUV_API
|
||||
int BGRAToARGB(const uint8_t* src_bgra,
|
||||
@ -530,6 +556,8 @@ int AR30ToARGB(const uint8_t* src_ar30,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
#define AB30ToABGR
|
||||
|
||||
// Convert AR30 To ABGR.
|
||||
LIBYUV_API
|
||||
int AR30ToABGR(const uint8_t* src_ar30,
|
||||
|
||||
@ -1631,14 +1631,14 @@ void ARGB1555ToARGBRow_Any_SSE2(const uint8_t* src_ptr,
|
||||
void ARGB4444ToARGBRow_Any_SSE2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
void RGB565ToARGBRow_Any_AVX2(const uint8_t* src_rgb565,
|
||||
uint8_t* dst_argb,
|
||||
void RGB565ToARGBRow_Any_AVX2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
void ARGB1555ToARGBRow_Any_AVX2(const uint8_t* src_argb1555,
|
||||
uint8_t* dst_argb,
|
||||
void ARGB1555ToARGBRow_Any_AVX2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
void ARGB4444ToARGBRow_Any_AVX2(const uint8_t* src_argb4444,
|
||||
uint8_t* dst_argb,
|
||||
void ARGB4444ToARGBRow_Any_AVX2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
|
||||
void RGB24ToARGBRow_Any_NEON(const uint8_t* src_ptr,
|
||||
@ -1752,7 +1752,9 @@ void J400ToARGBRow_C(const uint8_t* src_y, uint8_t* dst_argb, int width);
|
||||
void J400ToARGBRow_Any_SSE2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
void J400ToARGBRow_Any_AVX2(const uint8_t* src_y, uint8_t* dst_argb, int width);
|
||||
void J400ToARGBRow_Any_AVX2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
void J400ToARGBRow_Any_NEON(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
@ -2430,14 +2432,14 @@ void ARGBToRGB565DitherRow_Any_AVX2(const uint8_t* src_ptr,
|
||||
const uint32_t param,
|
||||
int width);
|
||||
|
||||
void ARGBToRGB565Row_Any_AVX2(const uint8_t* src_argb,
|
||||
uint8_t* dst_rgb,
|
||||
void ARGBToRGB565Row_Any_AVX2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
void ARGBToARGB1555Row_Any_AVX2(const uint8_t* src_argb,
|
||||
uint8_t* dst_rgb,
|
||||
void ARGBToARGB1555Row_Any_AVX2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
void ARGBToARGB4444Row_Any_AVX2(const uint8_t* src_argb,
|
||||
uint8_t* dst_rgb,
|
||||
void ARGBToARGB4444Row_Any_AVX2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
int width);
|
||||
void ABGRToAR30Row_Any_AVX2(const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
|
||||
@ -63,11 +63,12 @@ enum FourCC {
|
||||
// 1 Secondary YUV format: row biplanar.
|
||||
FOURCC_M420 = FOURCC('M', '4', '2', '0'),
|
||||
|
||||
// 10 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc
|
||||
// 11 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc
|
||||
FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'),
|
||||
FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'),
|
||||
FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'),
|
||||
FOURCC_AR30 = FOURCC('A', 'R', '3', '0'), // 10 bit per channel. 2101010.
|
||||
FOURCC_AB30 = FOURCC('A', 'B', '3', '0'), // ABGR version of 10 bit
|
||||
FOURCC_24BG = FOURCC('2', '4', 'B', 'G'),
|
||||
FOURCC_RAW = FOURCC('r', 'a', 'w', ' '),
|
||||
FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'),
|
||||
@ -137,6 +138,7 @@ enum FourCCBpp {
|
||||
FOURCC_BPP_ABGR = 32,
|
||||
FOURCC_BPP_RGBA = 32,
|
||||
FOURCC_BPP_AR30 = 32,
|
||||
FOURCC_BPP_AB30 = 32,
|
||||
FOURCC_BPP_24BG = 24,
|
||||
FOURCC_BPP_RAW = 24,
|
||||
FOURCC_BPP_RGBP = 16,
|
||||
|
||||
@ -1716,8 +1716,8 @@ int Android420ToI420(const uint8_t* src_y,
|
||||
halfwidth, halfheight);
|
||||
return 0;
|
||||
// Split UV planes - NV12
|
||||
} else if (src_pixel_stride_uv == 2 && vu_off == 1 &&
|
||||
src_stride_u == src_stride_v) {
|
||||
}
|
||||
if (src_pixel_stride_uv == 2 && vu_off == 1 && src_stride_u == src_stride_v) {
|
||||
SplitUVPlane(src_u, src_stride_u, dst_u, dst_stride_u, dst_v, dst_stride_v,
|
||||
halfwidth, halfheight);
|
||||
return 0;
|
||||
|
||||
@ -500,6 +500,40 @@ int H010ToAR30(const uint16_t* src_y,
|
||||
&kYuvH709Constants, width, height);
|
||||
}
|
||||
|
||||
// Convert I010 to AB30.
|
||||
LIBYUV_API
|
||||
int I010ToAB30(const uint16_t* src_y,
|
||||
int src_stride_y,
|
||||
const uint16_t* src_u,
|
||||
int src_stride_u,
|
||||
const uint16_t* src_v,
|
||||
int src_stride_v,
|
||||
uint8_t* dst_ab30,
|
||||
int dst_stride_ab30,
|
||||
int width,
|
||||
int height) {
|
||||
return I010ToAR30Matrix(src_y, src_stride_y, src_v,
|
||||
src_stride_v, src_u, src_stride_u, dst_ab30, dst_stride_ab30,
|
||||
&kYvuI601Constants, width, height);
|
||||
}
|
||||
|
||||
// Convert H010 to AB30.
|
||||
LIBYUV_API
|
||||
int H010ToAB30(const uint16_t* src_y,
|
||||
int src_stride_y,
|
||||
const uint16_t* src_u,
|
||||
int src_stride_u,
|
||||
const uint16_t* src_v,
|
||||
int src_stride_v,
|
||||
uint8_t* dst_ab30,
|
||||
int dst_stride_ab30,
|
||||
int width,
|
||||
int height) {
|
||||
return I010ToAR30Matrix(src_y, src_stride_y, src_v,
|
||||
src_stride_v, src_u, src_stride_u, dst_ab30, dst_stride_ab30,
|
||||
&kYvuH709Constants, width, height);
|
||||
}
|
||||
|
||||
// Convert 10 bit YUV to ARGB with matrix
|
||||
static int I010ToARGBMatrix(const uint16_t* src_y,
|
||||
int src_stride_y,
|
||||
@ -1950,8 +1984,8 @@ int Android420ToARGBMatrix(const uint8_t* src_y,
|
||||
return NV21ToARGBMatrix(src_y, src_stride_y, src_v, src_stride_v, dst_argb,
|
||||
dst_stride_argb, yuvconstants, width, height);
|
||||
// NV12
|
||||
} else if (src_pixel_stride_uv == 2 && vu_off == 1 &&
|
||||
src_stride_u == src_stride_v) {
|
||||
}
|
||||
if (src_pixel_stride_uv == 2 && vu_off == 1 && src_stride_u == src_stride_v) {
|
||||
return NV12ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, dst_argb,
|
||||
dst_stride_argb, yuvconstants, width, height);
|
||||
}
|
||||
|
||||
@ -556,9 +556,9 @@ JpegSubsamplingType MJpegDecoder::JpegSubsamplingTypeHelper(
|
||||
if (subsample_x[0] == 1 && subsample_y[0] == 1 && subsample_x[1] == 2 &&
|
||||
subsample_y[1] == 1 && subsample_x[2] == 2 && subsample_y[2] == 1) {
|
||||
return kJpegYuv422;
|
||||
} else if (subsample_x[0] == 1 && subsample_y[0] == 1 &&
|
||||
subsample_x[1] == 1 && subsample_y[1] == 1 &&
|
||||
subsample_x[2] == 1 && subsample_y[2] == 1) {
|
||||
}
|
||||
if (subsample_x[0] == 1 && subsample_y[0] == 1 && subsample_x[1] == 1 &&
|
||||
subsample_y[1] == 1 && subsample_x[2] == 1 && subsample_y[2] == 1) {
|
||||
return kJpegYuv444;
|
||||
}
|
||||
} else if (number_of_components == 1) { // Grey-scale images.
|
||||
|
||||
@ -2122,9 +2122,11 @@ TEST_F(LibYUVConvertTest, ABGRToAR30Row_Opt) {
|
||||
TESTPLANAR16TOB(I010, 2, 2, ARGB, 4, 4, 1, 2)
|
||||
TESTPLANAR16TOB(I010, 2, 2, ABGR, 4, 4, 1, 2)
|
||||
TESTPLANAR16TOB(I010, 2, 2, AR30, 4, 4, 1, 2)
|
||||
TESTPLANAR16TOB(I010, 2, 2, AB30, 4, 4, 1, 2)
|
||||
TESTPLANAR16TOB(H010, 2, 2, ARGB, 4, 4, 1, 2)
|
||||
TESTPLANAR16TOB(H010, 2, 2, ABGR, 4, 4, 1, 2)
|
||||
TESTPLANAR16TOB(H010, 2, 2, AR30, 4, 4, 1, 2)
|
||||
TESTPLANAR16TOB(H010, 2, 2, AB30, 4, 4, 1, 2)
|
||||
|
||||
static int Clamp(int y) {
|
||||
if (y < 0) {
|
||||
@ -2331,6 +2333,69 @@ TEST_F(LibYUVConvertTest, TestH010ToAR30) {
|
||||
free_aligned_buffer_page_end(ar30_pixels);
|
||||
}
|
||||
|
||||
// Test 10 bit YUV to 10 bit RGB
|
||||
// Caveat: Result is near due to float rounding in expected result.
|
||||
TEST_F(LibYUVConvertTest, TestH010ToAB30) {
|
||||
const int kSize = 1024;
|
||||
int histogram_b[1024];
|
||||
int histogram_g[1024];
|
||||
int histogram_r[1024];
|
||||
memset(histogram_b, 0, sizeof(histogram_b));
|
||||
memset(histogram_g, 0, sizeof(histogram_g));
|
||||
memset(histogram_r, 0, sizeof(histogram_r));
|
||||
|
||||
align_buffer_page_end(orig_yuv, kSize * 2 + kSize / 2 * 2 * 2);
|
||||
align_buffer_page_end(ab30_pixels, kSize * 4);
|
||||
uint16_t* orig_y = reinterpret_cast<uint16_t*>(orig_yuv);
|
||||
uint16_t* orig_u = orig_y + kSize;
|
||||
uint16_t* orig_v = orig_u + kSize / 2;
|
||||
|
||||
// Test grey scale
|
||||
for (int i = 0; i < kSize; ++i) {
|
||||
orig_y[i] = i;
|
||||
}
|
||||
for (int i = 0; i < kSize / 2; ++i) {
|
||||
orig_u[i] = 512; // 512 is 0.
|
||||
orig_v[i] = 512;
|
||||
}
|
||||
|
||||
H010ToAB30(orig_y, 0, orig_u, 0, orig_v, 0, ab30_pixels, 0, kSize, 1);
|
||||
|
||||
for (int i = 0; i < kSize; ++i) {
|
||||
int r10 = reinterpret_cast<uint32_t*>(ab30_pixels)[i] & 1023;
|
||||
int g10 = (reinterpret_cast<uint32_t*>(ab30_pixels)[i] >> 10) & 1023;
|
||||
int b10 = (reinterpret_cast<uint32_t*>(ab30_pixels)[i] >> 20) & 1023;
|
||||
int a2 = (reinterpret_cast<uint32_t*>(ab30_pixels)[i] >> 30) & 3;
|
||||
++histogram_b[b10];
|
||||
++histogram_g[g10];
|
||||
++histogram_r[r10];
|
||||
int expected_y = Clamp10(static_cast<int>((i - 64) * 1.164f));
|
||||
EXPECT_NEAR(b10, expected_y, 4);
|
||||
EXPECT_NEAR(g10, expected_y, 4);
|
||||
EXPECT_NEAR(r10, expected_y, 4);
|
||||
EXPECT_EQ(a2, 3);
|
||||
}
|
||||
|
||||
int count_b = 0;
|
||||
int count_g = 0;
|
||||
int count_r = 0;
|
||||
for (int i = 0; i < kSize; ++i) {
|
||||
if (histogram_b[i]) {
|
||||
++count_b;
|
||||
}
|
||||
if (histogram_g[i]) {
|
||||
++count_g;
|
||||
}
|
||||
if (histogram_r[i]) {
|
||||
++count_r;
|
||||
}
|
||||
}
|
||||
printf("uniques: B %d, G, %d, R %d\n", count_b, count_g, count_r);
|
||||
|
||||
free_aligned_buffer_page_end(orig_yuv);
|
||||
free_aligned_buffer_page_end(ab30_pixels);
|
||||
}
|
||||
|
||||
// Test 8 bit YUV to 10 bit RGB
|
||||
TEST_F(LibYUVConvertTest, TestH420ToAR30) {
|
||||
const int kSize = 256;
|
||||
|
||||
@ -71,6 +71,7 @@ TEST_F(LibYUVBaseTest, TestFourCC) {
|
||||
EXPECT_TRUE(TestValidFourCC(FOURCC_BGRA, FOURCC_BPP_BGRA));
|
||||
EXPECT_TRUE(TestValidFourCC(FOURCC_ABGR, FOURCC_BPP_ABGR));
|
||||
EXPECT_TRUE(TestValidFourCC(FOURCC_AR30, FOURCC_BPP_AR30));
|
||||
EXPECT_TRUE(TestValidFourCC(FOURCC_AB30, FOURCC_BPP_AB30));
|
||||
EXPECT_TRUE(TestValidFourCC(FOURCC_24BG, FOURCC_BPP_24BG));
|
||||
EXPECT_TRUE(TestValidFourCC(FOURCC_RAW, FOURCC_BPP_RAW));
|
||||
EXPECT_TRUE(TestValidFourCC(FOURCC_RGBA, FOURCC_BPP_RGBA));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user