Commit 20bf569a authored by Frank Barchard's avatar Frank Barchard

Fix ConvertToI420() for odd crop_y

The original src_u calculation of FOURCC_I420 shifted half width if
crop_y is odd.
This CL fixs the problem and also add a test case for it.

Bug: b:115278653
Test: pass libyuv_unittest
Change-Id: Ia9732d22e64e13de26df47726ba44ad1c5a06484
Reviewed-on: https://chromium-review.googlesource.com/c/1258743Reviewed-by: 's avatarFrank Barchard <fbarchard@chromium.org>
parent 9a07219d
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 1717
Version: 1718
License: BSD
License File: LICENSE
......
......@@ -1067,10 +1067,10 @@ void ARGB1555ToUVRow_MMI(const uint8_t* src_argb1555,
uint8_t* dst_v,
int width);
void ARGB4444ToUVRow_MMI(const uint8_t* src_argb4444,
int src_stride_argb4444,
uint8_t* dst_u,
uint8_t* dst_v,
int width);
int src_stride_argb4444,
uint8_t* dst_u,
uint8_t* dst_v,
int width);
void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width);
void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width);
void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width);
......@@ -1097,9 +1097,7 @@ void RGB24ToYRow_MMI(const uint8_t* src_argb0, uint8_t* dst_y, int width);
void RAWToYRow_MMI(const uint8_t* src_argb0, uint8_t* dst_y, int width);
void RGB565ToYRow_MMI(const uint8_t* src_rgb565, uint8_t* dst_y, int width);
void ARGB1555ToYRow_MMI(const uint8_t* src_argb1555, uint8_t* dst_y, int width);
void ARGB4444ToYRow_MMI(const uint8_t* src_argb4444,
uint8_t* dst_y,
int width);
void ARGB4444ToYRow_MMI(const uint8_t* src_argb4444, uint8_t* dst_y, int width);
void ARGBToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width);
void ARGBToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width);
......@@ -1155,8 +1153,8 @@ void ARGB1555ToYRow_Any_MMI(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int width);
void ARGB4444ToYRow_Any_MMI(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int width);
uint8_t* dst_ptr,
int width);
void ARGBToUVRow_AVX2(const uint8_t* src_argb0,
int src_stride_argb,
......@@ -1381,10 +1379,10 @@ void ARGB1555ToUVRow_Any_MMI(const uint8_t* src_ptr,
uint8_t* dst_v,
int width);
void ARGB4444ToUVRow_Any_MMI(const uint8_t* src_ptr,
int src_stride_ptr,
uint8_t* dst_u,
uint8_t* dst_v,
int width);
int src_stride_ptr,
uint8_t* dst_u,
uint8_t* dst_v,
int width);
void ARGBToUVRow_C(const uint8_t* src_rgb0,
int src_stride_rgb,
uint8_t* dst_u,
......@@ -1805,8 +1803,8 @@ void ARGBCopyYToAlphaRow_Any_AVX2(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int width);
void ARGBCopyYToAlphaRow_Any_MMI(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int width);
uint8_t* dst_ptr,
int width);
void SetRow_C(uint8_t* dst, uint8_t v8, int width);
void SetRow_MSA(uint8_t* dst, uint8_t v8, int width);
......
......@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1717
#define LIBYUV_VERSION 1718
#endif // INCLUDE_LIBYUV_VERSION_H_
......@@ -1053,7 +1053,8 @@ int RGB24ToI420(const uint8_t* src_rgb24,
int width,
int height) {
int y;
#if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || defined(HAS_RGB24TOYROW_MMI))
#if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || \
defined(HAS_RGB24TOYROW_MMI))
void (*RGB24ToUVRow)(const uint8_t* src_rgb24, int src_stride_rgb24,
uint8_t* dst_u, uint8_t* dst_v, int width) =
RGB24ToUVRow_C;
......@@ -1143,14 +1144,16 @@ int RGB24ToI420(const uint8_t* src_rgb24,
#endif
{
#if !(defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || defined(HAS_RGB24TOYROW_MMI))
#if !(defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || \
defined(HAS_RGB24TOYROW_MMI))
// Allocate 2 rows of ARGB.
const int kRowSize = (width * 4 + 31) & ~31;
align_buffer_64(row, kRowSize * 2);
#endif
for (y = 0; y < height - 1; y += 2) {
#if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || defined(HAS_RGB24TOYROW_MMI))
#if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || \
defined(HAS_RGB24TOYROW_MMI))
RGB24ToUVRow(src_rgb24, src_stride_rgb24, dst_u, dst_v, width);
RGB24ToYRow(src_rgb24, dst_y, width);
RGB24ToYRow(src_rgb24 + src_stride_rgb24, dst_y + dst_stride_y, width);
......@@ -1167,7 +1170,8 @@ int RGB24ToI420(const uint8_t* src_rgb24,
dst_v += dst_stride_v;
}
if (height & 1) {
#if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || defined(HAS_RGB24TOYROW_MMI))
#if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || \
defined(HAS_RGB24TOYROW_MMI))
RGB24ToUVRow(src_rgb24, 0, dst_u, dst_v, width);
RGB24ToYRow(src_rgb24, dst_y, width);
#else
......@@ -1176,7 +1180,8 @@ int RGB24ToI420(const uint8_t* src_rgb24,
ARGBToYRow(row, dst_y, width);
#endif
}
#if !(defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || defined(HAS_RGB24TOYROW_MMI))
#if !(defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || \
defined(HAS_RGB24TOYROW_MMI))
free_aligned_buffer_64(row);
#endif
}
......@@ -1196,7 +1201,8 @@ int RAWToI420(const uint8_t* src_raw,
int width,
int height) {
int y;
#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || defined(HAS_RAWTOYROW_MMI))
#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || \
defined(HAS_RAWTOYROW_MMI))
void (*RAWToUVRow)(const uint8_t* src_raw, int src_stride_raw, uint8_t* dst_u,
uint8_t* dst_v, int width) = RAWToUVRow_C;
void (*RAWToYRow)(const uint8_t* src_raw, uint8_t* dst_y, int width) =
......@@ -1285,14 +1291,16 @@ int RAWToI420(const uint8_t* src_raw,
#endif
{
#if !(defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || defined(HAS_RAWTOYROW_MMI))
#if !(defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || \
defined(HAS_RAWTOYROW_MMI))
// Allocate 2 rows of ARGB.
const int kRowSize = (width * 4 + 31) & ~31;
align_buffer_64(row, kRowSize * 2);
#endif
for (y = 0; y < height - 1; y += 2) {
#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || defined(HAS_RAWTOYROW_MMI))
#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || \
defined(HAS_RAWTOYROW_MMI))
RAWToUVRow(src_raw, src_stride_raw, dst_u, dst_v, width);
RAWToYRow(src_raw, dst_y, width);
RAWToYRow(src_raw + src_stride_raw, dst_y + dst_stride_y, width);
......@@ -1309,7 +1317,8 @@ int RAWToI420(const uint8_t* src_raw,
dst_v += dst_stride_v;
}
if (height & 1) {
#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || defined(HAS_RAWTOYROW_MMI))
#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || \
defined(HAS_RAWTOYROW_MMI))
RAWToUVRow(src_raw, 0, dst_u, dst_v, width);
RAWToYRow(src_raw, dst_y, width);
#else
......@@ -1318,7 +1327,8 @@ int RAWToI420(const uint8_t* src_raw,
ARGBToYRow(row, dst_y, width);
#endif
}
#if !(defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || defined(HAS_RAWTOYROW_MMI))
#if !(defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || \
defined(HAS_RAWTOYROW_MMI))
free_aligned_buffer_64(row);
#endif
}
......@@ -1338,7 +1348,8 @@ int RGB565ToI420(const uint8_t* src_rgb565,
int width,
int height) {
int y;
#if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || defined(HAS_RGB565TOYROW_MMI))
#if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || \
defined(HAS_RGB565TOYROW_MMI))
void (*RGB565ToUVRow)(const uint8_t* src_rgb565, int src_stride_rgb565,
uint8_t* dst_u, uint8_t* dst_v, int width) =
RGB565ToUVRow_C;
......@@ -1435,13 +1446,15 @@ int RGB565ToI420(const uint8_t* src_rgb565,
#endif
#endif
{
#if !(defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || defined(HAS_RGB565TOYROW_MMI))
#if !(defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || \
defined(HAS_RGB565TOYROW_MMI))
// Allocate 2 rows of ARGB.
const int kRowSize = (width * 4 + 31) & ~31;
align_buffer_64(row, kRowSize * 2);
#endif
for (y = 0; y < height - 1; y += 2) {
#if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || defined(HAS_RGB565TOYROW_MMI))
#if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || \
defined(HAS_RGB565TOYROW_MMI))
RGB565ToUVRow(src_rgb565, src_stride_rgb565, dst_u, dst_v, width);
RGB565ToYRow(src_rgb565, dst_y, width);
RGB565ToYRow(src_rgb565 + src_stride_rgb565, dst_y + dst_stride_y, width);
......@@ -1458,7 +1471,8 @@ int RGB565ToI420(const uint8_t* src_rgb565,
dst_v += dst_stride_v;
}
if (height & 1) {
#if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || defined(HAS_RGB565TOYROW_MMI))
#if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || \
defined(HAS_RGB565TOYROW_MMI))
RGB565ToUVRow(src_rgb565, 0, dst_u, dst_v, width);
RGB565ToYRow(src_rgb565, dst_y, width);
#else
......@@ -1467,7 +1481,8 @@ int RGB565ToI420(const uint8_t* src_rgb565,
ARGBToYRow(row, dst_y, width);
#endif
}
#if !(defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || defined(HAS_RGB565TOYROW_MMI))
#if !(defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA) || \
defined(HAS_RGB565TOYROW_MMI))
free_aligned_buffer_64(row);
#endif
}
......@@ -1487,7 +1502,8 @@ int ARGB1555ToI420(const uint8_t* src_argb1555,
int width,
int height) {
int y;
#if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || defined(HAS_ARGB1555TOYROW_MMI))
#if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || \
defined(HAS_ARGB1555TOYROW_MMI))
void (*ARGB1555ToUVRow)(const uint8_t* src_argb1555, int src_stride_argb1555,
uint8_t* dst_u, uint8_t* dst_v, int width) =
ARGB1555ToUVRow_C;
......@@ -1585,14 +1601,16 @@ int ARGB1555ToI420(const uint8_t* src_argb1555,
#endif
#endif
{
#if !(defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || defined(HAS_ARGB1555TOYROW_MMI))
#if !(defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || \
defined(HAS_ARGB1555TOYROW_MMI))
// Allocate 2 rows of ARGB.
const int kRowSize = (width * 4 + 31) & ~31;
align_buffer_64(row, kRowSize * 2);
#endif
for (y = 0; y < height - 1; y += 2) {
#if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || defined(HAS_ARGB1555TOYROW_MMI))
#if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || \
defined(HAS_ARGB1555TOYROW_MMI))
ARGB1555ToUVRow(src_argb1555, src_stride_argb1555, dst_u, dst_v, width);
ARGB1555ToYRow(src_argb1555, dst_y, width);
ARGB1555ToYRow(src_argb1555 + src_stride_argb1555, dst_y + dst_stride_y,
......@@ -1611,7 +1629,8 @@ int ARGB1555ToI420(const uint8_t* src_argb1555,
dst_v += dst_stride_v;
}
if (height & 1) {
#if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || defined(HAS_ARGB1555TOYROW_MMI))
#if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || \
defined(HAS_ARGB1555TOYROW_MMI))
ARGB1555ToUVRow(src_argb1555, 0, dst_u, dst_v, width);
ARGB1555ToYRow(src_argb1555, dst_y, width);
#else
......@@ -1620,7 +1639,8 @@ int ARGB1555ToI420(const uint8_t* src_argb1555,
ARGBToYRow(row, dst_y, width);
#endif
}
#if !(defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || defined(HAS_ARGB1555TOYROW_MMI))
#if !(defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA) || \
defined(HAS_ARGB1555TOYROW_MMI))
free_aligned_buffer_64(row);
#endif
}
......
......@@ -933,16 +933,16 @@ int I420ToARGB4444(const uint8_t* src_y,
// Convert I420 to RGB565 with specified color matrix.
LIBYUV_API
int I420ToRGB565Matrix(const uint8_t* src_y,
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_rgb565,
int dst_stride_rgb565,
const struct YuvConstants* yuvconstants,
int width,
int height) {
int src_stride_y,
const uint8_t* src_u,
int src_stride_u,
const uint8_t* src_v,
int src_stride_v,
uint8_t* dst_rgb565,
int dst_stride_rgb565,
const struct YuvConstants* yuvconstants,
int width,
int height) {
int y;
void (*I422ToRGB565Row)(const uint8_t* y_buf, const uint8_t* u_buf,
const uint8_t* v_buf, uint8_t* rgb_buf,
......@@ -1014,17 +1014,9 @@ int I420ToRGB565(const uint8_t* src_y,
int dst_stride_rgb565,
int width,
int height) {
return I420ToRGB565Matrix(src_y,
src_stride_y,
src_u,
src_stride_u,
src_v,
src_stride_v,
dst_rgb565,
dst_stride_rgb565,
&kYuvI601Constants,
width,
height);
return I420ToRGB565Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_rgb565, dst_stride_rgb565,
&kYuvI601Constants, width, height);
}
// Convert J420 to RGB565.
......@@ -1039,17 +1031,9 @@ int J420ToRGB565(const uint8_t* src_y,
int dst_stride_rgb565,
int width,
int height) {
return I420ToRGB565Matrix(src_y,
src_stride_y,
src_u,
src_stride_u,
src_v,
src_stride_v,
dst_rgb565,
dst_stride_rgb565,
&kYuvJPEGConstants,
width,
height);
return I420ToRGB565Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_rgb565, dst_stride_rgb565,
&kYuvJPEGConstants, width, height);
}
// Convert H420 to RGB565.
......@@ -1064,17 +1048,9 @@ int H420ToRGB565(const uint8_t* src_y,
int dst_stride_rgb565,
int width,
int height) {
return I420ToRGB565Matrix(src_y,
src_stride_y,
src_u,
src_stride_u,
src_v,
src_stride_v,
dst_rgb565,
dst_stride_rgb565,
&kYuvH709Constants,
width,
height);
return I420ToRGB565Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_rgb565, dst_stride_rgb565,
&kYuvH709Constants, width, height);
}
// Convert I422 to RGB565.
......
......@@ -193,15 +193,15 @@ int ConvertToI420(const uint8_t* sample,
int halfwidth = (src_width + 1) / 2;
int halfheight = (abs_src_height + 1) / 2;
if (format == FOURCC_YV12) {
src_v = sample + src_width * abs_src_height +
(halfwidth * crop_y + crop_x) / 2;
src_v = sample + src_width * abs_src_height + halfwidth * (crop_y / 2) +
(crop_x / 2);
src_u = sample + src_width * abs_src_height +
halfwidth * (halfheight + crop_y / 2) + crop_x / 2;
halfwidth * (halfheight + (crop_y / 2)) + (crop_x / 2);
} else {
src_u = sample + src_width * abs_src_height +
(halfwidth * crop_y + crop_x) / 2;
src_u = sample + src_width * abs_src_height + halfwidth * (crop_y / 2) +
(crop_x / 2);
src_v = sample + src_width * abs_src_height +
halfwidth * (halfheight + crop_y / 2) + crop_x / 2;
halfwidth * (halfheight + (crop_y / 2)) + (crop_x / 2);
}
r = I420Rotate(src_y, src_width, src_u, halfwidth, src_v, halfwidth,
dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v,
......@@ -216,14 +216,14 @@ int ConvertToI420(const uint8_t* sample,
int halfwidth = (src_width + 1) / 2;
if (format == FOURCC_YV16) {
src_v = sample + src_width * abs_src_height + halfwidth * crop_y +
crop_x / 2;
(crop_x / 2);
src_u = sample + src_width * abs_src_height +
halfwidth * (abs_src_height + crop_y) + crop_x / 2;
halfwidth * (abs_src_height + crop_y) + (crop_x / 2);
} else {
src_u = sample + src_width * abs_src_height + halfwidth * crop_y +
crop_x / 2;
(crop_x / 2);
src_v = sample + src_width * abs_src_height +
halfwidth * (abs_src_height + crop_y) + crop_x / 2;
halfwidth * (abs_src_height + crop_y) + (crop_x / 2);
}
r = I422ToI420(src_y, src_width, src_u, halfwidth, src_v, halfwidth,
dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v,
......
......@@ -188,7 +188,7 @@ LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name,
}
return 0;
}
} else if(memcmp(cpuinfo_line, "cpu model", 9) == 0) {
} else if (memcmp(cpuinfo_line, "cpu model", 9) == 0) {
char* p = strstr(cpuinfo_line, "Loongson-3");
if (p) {
fclose(f);
......
......@@ -3539,7 +3539,7 @@ int ARGBExtractAlpha(const uint8_t* src_argb,
#if defined(HAS_ARGBEXTRACTALPHAROW_MMI)
if (TestCpuFlag(kCpuHasMMI)) {
ARGBExtractAlphaRow = IS_ALIGNED(width, 8) ? ARGBExtractAlphaRow_MMI
: ARGBExtractAlphaRow_Any_MMI;
: ARGBExtractAlphaRow_Any_MMI;
}
#endif
......
......@@ -4595,10 +4595,10 @@ void SobelYRow_MMI(const uint8_t* src_y0,
"daddiu %[width], %[width], -8 \n\t"
"bgtz %[width], 1b \n\t"
"nop \n\t"
: [sobel] "=&f"(sobel), [y00] "=&f"(y00), [y01] "=&f"(y01), [y02] "=&f"(y02),
[y10] "=&f"(y10), [y11] "=&f"(y11), [y12] "=&f"(y12)
: [src_y0] "r"(src_y0), [src_y1] "r"(src_y1), [dst_sobely] "r"(dst_sobely),
[width] "r"(width), [zero] "f"(zero)
: [sobel] "=&f"(sobel), [y00] "=&f"(y00), [y01] "=&f"(y01),
[y02] "=&f"(y02), [y10] "=&f"(y10), [y11] "=&f"(y11), [y12] "=&f"(y12)
: [src_y0] "r"(src_y0), [src_y1] "r"(src_y1),
[dst_sobely] "r"(dst_sobely), [width] "r"(width), [zero] "f"(zero)
: "memory");
}
......@@ -5720,8 +5720,7 @@ void InterpolateRow_MMI(uint8_t* dst_ptr,
"bgtz %[width], 1b \n\t"
"nop \n\t"
:
: [dst_ptr] "r"(dst_ptr), [src_ptr] "r"(src_ptr),
[width] "r"(width)
: [dst_ptr] "r"(dst_ptr), [src_ptr] "r"(src_ptr), [width] "r"(width)
: "memory");
return;
}
......@@ -5794,9 +5793,10 @@ void InterpolateRow_MMI(uint8_t* dst_ptr,
"nop \n\t"
: [t0] "=&f"(temp), [d0] "=&f"(data[0]), [d1] "=&f"(data[1]),
[d2] "=&f"(data[2]), [d3] "=&f"(data[3])
: [src_ptr] "r"(src_ptr), [src_ptr1] "r"(src_ptr1), [dst_ptr] "r"(dst_ptr),
[width] "r"(width), [fy1] "f"(source_y_fraction), [fy0] "f"(fy0),
[c0] "f"(c0), [shift] "f"(shift), [zero] "f"(zero)
: [src_ptr] "r"(src_ptr), [src_ptr1] "r"(src_ptr1),
[dst_ptr] "r"(dst_ptr), [width] "r"(width),
[fy1] "f"(source_y_fraction), [fy0] "f"(fy0), [c0] "f"(c0),
[shift] "f"(shift), [zero] "f"(zero)
: "memory");
}
......
......@@ -163,14 +163,14 @@ extern "C" {
v8u16 reg0_m, reg1_m, reg2_m, reg3_m, reg4_m, reg5_m, reg6_m, reg7_m; \
v8u16 reg8_m, reg9_m; \
\
src0_m = (v16u8)__msa_ld_b((void*)s, 0); \
src1_m = (v16u8)__msa_ld_b((void*)s, 16); \
src2_m = (v16u8)__msa_ld_b((void*)s, 32); \
src3_m = (v16u8)__msa_ld_b((void*)s, 48); \
src4_m = (v16u8)__msa_ld_b((void*)t, 0); \
src5_m = (v16u8)__msa_ld_b((void*)t, 16); \
src6_m = (v16u8)__msa_ld_b((void*)t, 32); \
src7_m = (v16u8)__msa_ld_b((void*)t, 48); \
src0_m = (v16u8)__msa_ld_b((void*)s, 0); \
src1_m = (v16u8)__msa_ld_b((void*)s, 16); \
src2_m = (v16u8)__msa_ld_b((void*)s, 32); \
src3_m = (v16u8)__msa_ld_b((void*)s, 48); \
src4_m = (v16u8)__msa_ld_b((void*)t, 0); \
src5_m = (v16u8)__msa_ld_b((void*)t, 16); \
src6_m = (v16u8)__msa_ld_b((void*)t, 32); \
src7_m = (v16u8)__msa_ld_b((void*)t, 48); \
vec0_m = (v16u8)__msa_ilvr_b((v16i8)src0_m, (v16i8)src4_m); \
vec1_m = (v16u8)__msa_ilvr_b((v16i8)src1_m, (v16i8)src5_m); \
vec2_m = (v16u8)__msa_ilvr_b((v16i8)src2_m, (v16i8)src6_m); \
......@@ -201,14 +201,14 @@ extern "C" {
reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, 2); \
argb0 = (v16u8)__msa_pckev_b((v16i8)reg9_m, (v16i8)reg8_m); \
argb1 = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \
src0_m = (v16u8)__msa_ld_b((void*)s, 64); \
src1_m = (v16u8)__msa_ld_b((void*)s, 80); \
src2_m = (v16u8)__msa_ld_b((void*)s, 96); \
src3_m = (v16u8)__msa_ld_b((void*)s, 112); \
src4_m = (v16u8)__msa_ld_b((void*)t, 64); \
src5_m = (v16u8)__msa_ld_b((void*)t, 80); \
src6_m = (v16u8)__msa_ld_b((void*)t, 96); \
src7_m = (v16u8)__msa_ld_b((void*)t, 112); \
src0_m = (v16u8)__msa_ld_b((void*)s, 64); \
src1_m = (v16u8)__msa_ld_b((void*)s, 80); \
src2_m = (v16u8)__msa_ld_b((void*)s, 96); \
src3_m = (v16u8)__msa_ld_b((void*)s, 112); \
src4_m = (v16u8)__msa_ld_b((void*)t, 64); \
src5_m = (v16u8)__msa_ld_b((void*)t, 80); \
src6_m = (v16u8)__msa_ld_b((void*)t, 96); \
src7_m = (v16u8)__msa_ld_b((void*)t, 112); \
vec2_m = (v16u8)__msa_ilvr_b((v16i8)src0_m, (v16i8)src4_m); \
vec3_m = (v16u8)__msa_ilvr_b((v16i8)src1_m, (v16i8)src5_m); \
vec4_m = (v16u8)__msa_ilvr_b((v16i8)src2_m, (v16i8)src6_m); \
......
......@@ -186,11 +186,10 @@ static void ScalePlaneDown2_16(int src_width,
#endif
#if defined(HAS_SCALEROWDOWN2_16_MMI)
if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(dst_width, 4)) {
ScaleRowDown2 =
filtering == kFilterNone
? ScaleRowDown2_16_MMI
: (filtering == kFilterLinear ? ScaleRowDown2Linear_16_MMI
: ScaleRowDown2Box_16_MMI);
ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_16_MMI
: (filtering == kFilterLinear
? ScaleRowDown2Linear_16_MMI
: ScaleRowDown2Box_16_MMI);
}
#endif
......@@ -319,8 +318,7 @@ static void ScalePlaneDown4_16(int src_width,
#endif
#if defined(HAS_SCALEROWDOWN4_16_MMI)
if (TestCpuFlag(kCpuHasMMI) && IS_ALIGNED(dst_width, 8)) {
ScaleRowDown4 =
filtering ? ScaleRowDown4Box_16_MMI : ScaleRowDown4_16_MMI;
ScaleRowDown4 = filtering ? ScaleRowDown4Box_16_MMI : ScaleRowDown4_16_MMI;
}
#endif
......
......@@ -542,7 +542,9 @@ void ScaleFilterCols64_C(uint8_t* dst_ptr,
// Same as 8 bit arm blender but return is cast to uint16_t
#define BLENDER(a, b, f) \
(uint16_t)((int)(a) + (int)((((int64_t)((f)) * ((int64_t)(b) - (int)(a))) + 0x8000) >> 16))
(uint16_t)( \
(int)(a) + \
(int)((((int64_t)((f)) * ((int64_t)(b) - (int)(a))) + 0x8000) >> 16))
void ScaleFilterCols_16_C(uint16_t* dst_ptr,
const uint16_t* src_ptr,
......
......@@ -1506,6 +1506,78 @@ TEST_F(LibYUVConvertTest, NV12Crop) {
free_aligned_buffer_page_end(src_y);
}
TEST_F(LibYUVConvertTest, I420CropOddY) {
const int SUBSAMP_X = 2;
const int SUBSAMP_Y = 2;
const int kWidth = benchmark_width_;
const int kHeight = benchmark_height_;
const int crop_y = 1;
const int kDestWidth = benchmark_width_;
const int kDestHeight = benchmark_height_ - crop_y * 2;
const int kStrideU = SUBSAMPLE(kWidth, SUBSAMP_X);
const int kStrideV = SUBSAMPLE(kWidth, SUBSAMP_X);
const int sample_size = kWidth * kHeight +
kStrideU * SUBSAMPLE(kHeight, SUBSAMP_Y) +
kStrideV * SUBSAMPLE(kHeight, SUBSAMP_Y);
align_buffer_page_end(src_y, sample_size);
uint8_t* src_u = src_y + kWidth * kHeight;
uint8_t* src_v = src_u + kStrideU * SUBSAMPLE(kHeight, SUBSAMP_Y);
align_buffer_page_end(dst_y, kDestWidth * kDestHeight);
align_buffer_page_end(dst_u, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
SUBSAMPLE(kDestHeight, SUBSAMP_Y));
align_buffer_page_end(dst_v, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
SUBSAMPLE(kDestHeight, SUBSAMP_Y));
for (int i = 0; i < kHeight * kWidth; ++i) {
src_y[i] = (fastrand() & 0xff);
}
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y) * kStrideU; ++i) {
src_u[i] = (fastrand() & 0xff);
}
for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y) * kStrideV; ++i) {
src_v[i] = (fastrand() & 0xff);
}
memset(dst_y, 1, kDestWidth * kDestHeight);
memset(dst_u, 2,
SUBSAMPLE(kDestWidth, SUBSAMP_X) * SUBSAMPLE(kDestHeight, SUBSAMP_Y));
memset(dst_v, 3,
SUBSAMPLE(kDestWidth, SUBSAMP_X) * SUBSAMPLE(kDestHeight, SUBSAMP_Y));
MaskCpuFlags(benchmark_cpu_info_);
for (int i = 0; i < benchmark_iterations_; ++i) {
ConvertToI420(src_y, sample_size, dst_y, kDestWidth, dst_u,
SUBSAMPLE(kDestWidth, SUBSAMP_X), dst_v,
SUBSAMPLE(kDestWidth, SUBSAMP_X), 0, crop_y, kWidth, kHeight,
kDestWidth, kDestHeight, libyuv::kRotate0,
libyuv::FOURCC_I420);
}
for (int i = 0; i < kDestHeight; ++i) {
for (int j = 0; j < kDestWidth; ++j) {
EXPECT_EQ(src_y[crop_y * kWidth + i * kWidth + j],
dst_y[i * kDestWidth + j]);
}
}
for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) {
for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) {
EXPECT_EQ(src_u[(crop_y / 2 + i) * kStrideU + j],
dst_u[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]);
}
}
for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) {
for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) {
EXPECT_EQ(src_v[(crop_y / 2 + i) * kStrideV + j],
dst_v[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]);
}
}
free_aligned_buffer_page_end(dst_y);
free_aligned_buffer_page_end(dst_u);
free_aligned_buffer_page_end(dst_v);
free_aligned_buffer_page_end(src_y);
}
TEST_F(LibYUVConvertTest, TestYToARGB) {
uint8_t y[32];
uint8_t expectedg[32];
......
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