Commit d9eb63fc authored by fbarchard@google.com's avatar fbarchard@google.com

UNDER_ALLOCATED_HACK for scale that detects odd width and odd height were…

UNDER_ALLOCATED_HACK for scale that detects odd width and odd height were miscalculated and adjusts scaler for it.
BUG=none
TEST=none
Review URL: https://webrtc-codereview.appspot.com/663007

git-svn-id: http://libyuv.googlecode.com/svn/trunk@290 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 81b804e3
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 289
Version: 290
License: BSD
License File: LICENSE
......
......@@ -11,7 +11,7 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 289
#define LIBYUV_VERSION 290
#endif // INCLUDE_LIBYUV_VERSION_H_
......@@ -3361,6 +3361,8 @@ void ScalePlane(const uint8* src, int src_stride,
// Scale an I420 image.
// This function in turn calls a scaling function for each plane.
#define UNDER_ALLOCATED_HACK 1
int I420Scale(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
......@@ -3390,6 +3392,28 @@ int I420Scale(const uint8* src_y, int src_stride_y,
int dst_halfwidth = (dst_width + 1) >> 1;
int dst_halfheight = (dst_height + 1) >> 1;
#ifdef UNDER_ALLOCATED_HACK
// If caller passed width / 2 for stride, adjust halfwidth to match.
if ((src_width & 1) && src_stride_u && src_halfwidth > abs(src_stride_u)) {
src_halfwidth = src_width >> 1;
}
if ((dst_width & 1) && dst_stride_u && dst_halfwidth > abs(dst_stride_u)) {
dst_halfwidth = dst_width >> 1;
}
// If caller used height / 2 when computing src_v, it will point into what
// should be the src_u plane. Detect this and reduce halfheight to match.
int uv_src_plane_size = src_halfwidth * src_halfheight;
if ((src_height & 1) &&
(src_v > src_u) && (src_v < (src_u + uv_src_plane_size))) {
src_halfheight = src_height >> 1;
}
int uv_dst_plane_size = dst_halfwidth * dst_halfheight;
if ((dst_height & 1) &&
(dst_v > dst_u) && (dst_v < (dst_u + uv_dst_plane_size))) {
dst_halfheight = dst_height >> 1;
}
#endif
ScalePlane(src_y, src_stride_y, src_width, src_height,
dst_y, dst_stride_y, dst_width, dst_height,
filtering);
......@@ -3431,6 +3455,28 @@ int Scale(const uint8* src_y, const uint8* src_u, const uint8* src_v,
int dst_halfheight = (dst_height + 1) >> 1;
FilterMode filtering = interpolate ? kFilterBox : kFilterNone;
#ifdef UNDER_ALLOCATED_HACK
// If caller passed width / 2 for stride, adjust halfwidth to match.
if ((src_width & 1) && src_stride_u && src_halfwidth > abs(src_stride_u)) {
src_halfwidth = src_width >> 1;
}
if ((dst_width & 1) && dst_stride_u && dst_halfwidth > abs(dst_stride_u)) {
dst_halfwidth = dst_width >> 1;
}
// If caller used height / 2 when computing src_v, it will point into what
// should be the src_u plane. Detect this and reduce halfheight to match.
int uv_src_plane_size = src_halfwidth * src_halfheight;
if ((src_height & 1) &&
(src_v > src_u) && (src_v < (src_u + uv_src_plane_size))) {
src_halfheight = src_height >> 1;
}
int uv_dst_plane_size = dst_halfwidth * dst_halfheight;
if ((dst_height & 1) &&
(dst_v > dst_u) && (dst_v < (dst_u + uv_dst_plane_size))) {
dst_halfheight = dst_height >> 1;
}
#endif
ScalePlane(src_y, src_stride_y, src_width, src_height,
dst_y, dst_stride_y, dst_width, dst_height,
filtering);
......
......@@ -18,17 +18,17 @@
namespace libyuv {
static int ARGBTestFilter(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode f) {
int dst_width, int dst_height,
FilterMode f) {
const int b = 128;
int src_argb_plane_size = (src_width + (2 * b)) * (src_height + (2 * b)) * 4;
int src_stride_argb = (2 * b + src_width) * 4;
int src_argb_plane_size = (src_width + b * 2) * (src_height + b * 2) * 4;
int src_stride_argb = (b * 2 + src_width) * 4;
align_buffer_16(src_argb, src_argb_plane_size)
memset(src_argb, 1, src_argb_plane_size);
int dst_argb_plane_size = (dst_width + (2 * b)) * (dst_height + (2 * b)) * 4;
int dst_stride_argb = (2 * b + dst_width) * 4;
int dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4;
int dst_stride_argb = (b * 2 + dst_width) * 4;
srandom(time(NULL));
......@@ -213,4 +213,18 @@ TEST_F(libyuvTest, ARGBScaleTo1366) {
}
}
TEST_F(libyuvTest, ARGBScaleTo853) {
int src_width = 1280;
int src_height = 720;
int dst_width = 853;
int dst_height = 480;
for (int f = 0; f < 2; ++f) {
int err = ARGBTestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f));
EXPECT_GE(1, err);
}
}
} // namespace libyuv
......@@ -19,29 +19,29 @@ namespace libyuv {
static int TestFilter(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode f) {
const int b = 128;
int src_width_uv = (src_width + 1) >> 1;
int src_height_uv = (src_height + 1) >> 1;
FilterMode f, int rounding) {
const int b = 128 * rounding;
int src_width_uv = (src_width + rounding) >> 1;
int src_height_uv = (src_height + rounding) >> 1;
int src_y_plane_size = (src_width + (2 * b)) * (src_height + (2 * b));
int src_uv_plane_size = (src_width_uv + (2 * b)) * (src_height_uv + (2 * b));
int src_y_plane_size = (src_width + b * 2) * (src_height + b * 2);
int src_uv_plane_size = (src_width_uv + b * 2) * (src_height_uv + b * 2);
int src_stride_y = 2 * b + src_width;
int src_stride_uv = 2 * b + src_width_uv;
int src_stride_y = b * 2 + src_width;
int src_stride_uv = b * 2 + src_width_uv;
align_buffer_16(src_y, src_y_plane_size)
align_buffer_16(src_u, src_uv_plane_size)
align_buffer_16(src_v, src_uv_plane_size)
align_buffer_page_end(src_y, src_y_plane_size)
align_buffer_page_end(src_u, src_uv_plane_size)
align_buffer_page_end(src_v, src_uv_plane_size)
int dst_width_uv = (dst_width + 1) >> 1;
int dst_height_uv = (dst_height + 1) >> 1;
int dst_width_uv = (dst_width + rounding) >> 1;
int dst_height_uv = (dst_height + rounding) >> 1;
int dst_y_plane_size = (dst_width + (2 * b)) * (dst_height + (2 * b));
int dst_uv_plane_size = (dst_width_uv + (2 * b)) * (dst_height_uv + (2 * b));
int dst_y_plane_size = (dst_width + b * 2) * (dst_height + b * 2);
int dst_uv_plane_size = (dst_width_uv + b * 2) * (dst_height_uv + b * 2);
int dst_stride_y = 2 * b + dst_width;
int dst_stride_uv = 2 * b + dst_width_uv;
int dst_stride_y = b * 2 + dst_width;
int dst_stride_uv = b * 2 + dst_width_uv;
srandom(time(NULL));
......@@ -60,12 +60,12 @@ static int TestFilter(int src_width, int src_height,
}
const int runs = 1000;
align_buffer_16(dst_y_c, dst_y_plane_size)
align_buffer_16(dst_u_c, dst_uv_plane_size)
align_buffer_16(dst_v_c, dst_uv_plane_size)
align_buffer_16(dst_y_opt, dst_y_plane_size)
align_buffer_16(dst_u_opt, dst_uv_plane_size)
align_buffer_16(dst_v_opt, dst_uv_plane_size)
align_buffer_page_end(dst_y_c, dst_y_plane_size)
align_buffer_page_end(dst_u_c, dst_uv_plane_size)
align_buffer_page_end(dst_v_c, dst_uv_plane_size)
align_buffer_page_end(dst_y_opt, dst_y_plane_size)
align_buffer_page_end(dst_u_opt, dst_uv_plane_size)
align_buffer_page_end(dst_v_opt, dst_uv_plane_size)
// Warm up both versions for consistent benchmarks.
MaskCpuFlags(0); // Disable all CPU optimization.
......@@ -149,16 +149,16 @@ static int TestFilter(int src_width, int src_height,
}
}
free_aligned_buffer_16(dst_y_c)
free_aligned_buffer_16(dst_u_c)
free_aligned_buffer_16(dst_v_c)
free_aligned_buffer_16(dst_y_opt)
free_aligned_buffer_16(dst_u_opt)
free_aligned_buffer_16(dst_v_opt)
free_aligned_buffer_page_end(dst_y_c)
free_aligned_buffer_page_end(dst_u_c)
free_aligned_buffer_page_end(dst_v_c)
free_aligned_buffer_page_end(dst_y_opt)
free_aligned_buffer_page_end(dst_u_opt)
free_aligned_buffer_page_end(dst_v_opt)
free_aligned_buffer_16(src_y)
free_aligned_buffer_16(src_u)
free_aligned_buffer_16(src_v)
free_aligned_buffer_page_end(src_y)
free_aligned_buffer_page_end(src_u)
free_aligned_buffer_page_end(src_v)
return max_diff;
}
......@@ -172,7 +172,7 @@ TEST_F(libyuvTest, ScaleDownBy2) {
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f));
static_cast<FilterMode>(f), 1);
EXPECT_GE(1, err);
}
}
......@@ -186,7 +186,7 @@ TEST_F(libyuvTest, ScaleDownBy4) {
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f));
static_cast<FilterMode>(f), 1);
EXPECT_GE(2, err); // This is the only scale factor with error of 2.
}
}
......@@ -200,7 +200,7 @@ TEST_F(libyuvTest, ScaleDownBy5) {
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f));
static_cast<FilterMode>(f), 1);
EXPECT_GE(1, err);
}
}
......@@ -214,7 +214,7 @@ TEST_F(libyuvTest, ScaleDownBy8) {
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f));
static_cast<FilterMode>(f), 1);
EXPECT_GE(1, err);
}
}
......@@ -228,7 +228,7 @@ TEST_F(libyuvTest, ScaleDownBy16) {
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f));
static_cast<FilterMode>(f), 1);
EXPECT_GE(1, err);
}
}
......@@ -242,7 +242,7 @@ TEST_F(libyuvTest, ScaleDownBy34) {
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f));
static_cast<FilterMode>(f), 1);
EXPECT_GE(1, err);
}
}
......@@ -256,7 +256,7 @@ TEST_F(libyuvTest, ScaleDownBy38) {
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f));
static_cast<FilterMode>(f), 1);
EXPECT_GE(1, err);
}
}
......@@ -270,7 +270,35 @@ TEST_F(libyuvTest, ScaleTo1366) {
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f));
static_cast<FilterMode>(f), 1);
EXPECT_GE(1, err);
}
}
TEST_F(libyuvTest, ScaleTo853) {
int src_width = 1280;
int src_height = 720;
int dst_width = 853;
int dst_height = 480;
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f), 1);
EXPECT_GE(1, err);
}
}
TEST_F(libyuvTest, ScaleTo853Wrong) {
int src_width = 1280;
int src_height = 720;
int dst_width = 853;
int dst_height = 480;
for (int f = 0; f < 3; ++f) {
int err = TestFilter(src_width, src_height,
dst_width, dst_height,
static_cast<FilterMode>(f), 0);
EXPECT_GE(1, err);
}
}
......
......@@ -29,7 +29,7 @@
uint8* var; \
uint8* var##_mem; \
var##_mem = reinterpret_cast<uint8*>(malloc(((size) + 4095) & ~4095)); \
var = var##_mem + (-(size) & 4095)
var = var##_mem + (-(size) & 4095);
#define free_aligned_buffer_page_end(var) \
free(var##_mem); \
......
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