| Index: unit_test/scale_argb_test.cc
|
| diff --git a/unit_test/scale_argb_test.cc b/unit_test/scale_argb_test.cc
|
| index cbf9cb72a064727fe8aef8a16703bba82e85dcd6..e85eb2a5456c1e9ba06245e18690784ad6e2d05d 100644
|
| --- a/unit_test/scale_argb_test.cc
|
| +++ b/unit_test/scale_argb_test.cc
|
| @@ -12,8 +12,10 @@
|
| #include <time.h>
|
|
|
| #include "libyuv/cpu_id.h"
|
| +#include "libyuv/convert.h"
|
| #include "libyuv/scale_argb.h"
|
| #include "libyuv/row.h"
|
| +#include "libyuv/video_common.h"
|
| #include "../unit_test/unit_test.h"
|
|
|
| namespace libyuv {
|
| @@ -299,4 +301,156 @@ TEST_SCALETO(ARGBScale, 1280, 720)
|
| #undef TEST_SCALETO1
|
| #undef TEST_SCALETO
|
|
|
| +// Scale with YUV conversion to ARGB and clipping.
|
| +LIBYUV_API
|
| +int YUVToARGBScaleReference2(const uint8* src_y, int src_stride_y,
|
| + const uint8* src_u, int src_stride_u,
|
| + const uint8* src_v, int src_stride_v,
|
| + uint32 src_fourcc,
|
| + int src_width, int src_height,
|
| + uint8* dst_argb, int dst_stride_argb,
|
| + uint32 dst_fourcc,
|
| + int dst_width, int dst_height,
|
| + int clip_x, int clip_y,
|
| + int clip_width, int clip_height,
|
| + enum FilterMode filtering) {
|
| +
|
| + uint8* argb_buffer = (uint8*)malloc(src_width * src_height * 4);
|
| + int r;
|
| + I420ToARGB(src_y, src_stride_y,
|
| + src_u, src_stride_u,
|
| + src_v, src_stride_v,
|
| + argb_buffer, src_width * 4,
|
| + src_width, src_height);
|
| +
|
| + r = ARGBScaleClip(argb_buffer, src_width * 4,
|
| + src_width, src_height,
|
| + dst_argb, dst_stride_argb,
|
| + dst_width, dst_height,
|
| + clip_x, clip_y, clip_width, clip_height,
|
| + filtering);
|
| + free(argb_buffer);
|
| + return r;
|
| +}
|
| +
|
| +static void FillRamp(uint8* buf, int width, int height, int v, int dx, int dy) {
|
| + int rv = v;
|
| + for (int y = 0; y < height; ++y) {
|
| + for (int x = 0; x < width; ++x) {
|
| + *buf++ = v;
|
| + v += dx;
|
| + if (v < 0 || v > 255) {
|
| + dx = -dx;
|
| + v += dx;
|
| + }
|
| + }
|
| + v = rv + dy;
|
| + if (v < 0 || v > 255) {
|
| + dy = -dy;
|
| + v += dy;
|
| + }
|
| + rv = v;
|
| + }
|
| +}
|
| +
|
| +// Test scaling with C vs Opt and return maximum pixel difference. 0 = exact.
|
| +static int YUVToARGBTestFilter(int src_width, int src_height,
|
| + int dst_width, int dst_height,
|
| + FilterMode f, int benchmark_iterations,
|
| + int disable_cpu_flags, int benchmark_cpu_info) {
|
| + int64 src_y_plane_size = Abs(src_width) * Abs(src_height);
|
| + int64 src_uv_plane_size = ((Abs(src_width) + 1) / 2) *
|
| + ((Abs(src_height) + 1) / 2);
|
| + int src_stride_y = Abs(src_width);
|
| + int src_stride_uv = (Abs(src_width) + 1) / 2;
|
| +
|
| + 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);
|
| +
|
| + int64 dst_argb_plane_size = (dst_width) * (dst_height) * 4LL;
|
| + int dst_stride_argb = (dst_width) * 4;
|
| + align_buffer_page_end(dst_argb_c, dst_argb_plane_size);
|
| + align_buffer_page_end(dst_argb_opt, dst_argb_plane_size);
|
| + if (!dst_argb_c || !dst_argb_opt || !src_y || !src_u || !src_v) {
|
| + printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
|
| + return 0;
|
| + }
|
| + // Fill YUV image with continuous ramp, which is less sensitive to
|
| + // subsampling and filtering differences for test purposes.
|
| + FillRamp(src_y, Abs(src_width), Abs(src_height), 128, 1, 1);
|
| + FillRamp(src_u, (Abs(src_width) + 1) / 2, (Abs(src_height) + 1) / 2, 3, 1, 1);
|
| + FillRamp(src_v, (Abs(src_width) + 1) / 2, (Abs(src_height) + 1) / 2, 4, 1, 1);
|
| + memset(dst_argb_c, 2, dst_argb_plane_size);
|
| + memset(dst_argb_opt, 3, dst_argb_plane_size);
|
| +
|
| + YUVToARGBScaleReference2(src_y, src_stride_y,
|
| + src_u, src_stride_uv,
|
| + src_v, src_stride_uv,
|
| + libyuv::FOURCC_I420,
|
| + src_width, src_height,
|
| + dst_argb_c, dst_stride_argb,
|
| + libyuv::FOURCC_I420,
|
| + dst_width, dst_height,
|
| + 0, 0, dst_width, dst_height,
|
| + f);
|
| +
|
| + for (int i = 0; i < benchmark_iterations; ++i) {
|
| + YUVToARGBScaleClip(src_y, src_stride_y,
|
| + src_u, src_stride_uv,
|
| + src_v, src_stride_uv,
|
| + libyuv::FOURCC_I420,
|
| + src_width, src_height,
|
| + dst_argb_opt, dst_stride_argb,
|
| + libyuv::FOURCC_I420,
|
| + dst_width, dst_height,
|
| + 0, 0, dst_width, dst_height,
|
| + f);
|
| + }
|
| + int max_diff = 0;
|
| + for (int i = 0; i < dst_height; ++i) {
|
| + for (int j = 0; j < dst_width * 4; ++j) {
|
| + int abs_diff = Abs(dst_argb_c[(i * dst_stride_argb) + j] -
|
| + dst_argb_opt[(i * dst_stride_argb) + j]);
|
| + if (abs_diff > max_diff) {
|
| + printf("error %d at %d,%d c %d opt %d",
|
| + abs_diff,
|
| + j, i,
|
| + dst_argb_c[(i * dst_stride_argb) + j],
|
| + dst_argb_opt[(i * dst_stride_argb) + j]);
|
| + EXPECT_LE(abs_diff, 40);
|
| + max_diff = abs_diff;
|
| + }
|
| + }
|
| + }
|
| +
|
| + free_aligned_buffer_page_end(dst_argb_c);
|
| + free_aligned_buffer_page_end(dst_argb_opt);
|
| + free_aligned_buffer_page_end(src_y);
|
| + free_aligned_buffer_page_end(src_u);
|
| + free_aligned_buffer_page_end(src_v);
|
| + return max_diff;
|
| +}
|
| +
|
| +TEST_F(LibYUVScaleTest, YUVToRGBScaleUp) {
|
| + int diff = YUVToARGBTestFilter(benchmark_width_, benchmark_height_,
|
| + benchmark_width_ * 3 / 2,
|
| + benchmark_height_ * 3 / 2,
|
| + libyuv::kFilterBilinear,
|
| + benchmark_iterations_,
|
| + disable_cpu_flags_, benchmark_cpu_info_);
|
| + EXPECT_LE(diff, 10);
|
| +}
|
| +
|
| +TEST_F(LibYUVScaleTest, YUVToRGBScaleDown) {
|
| + int diff = YUVToARGBTestFilter(benchmark_width_ * 3 / 2,
|
| + benchmark_height_ * 3 / 2,
|
| + benchmark_width_, benchmark_height_,
|
| + libyuv::kFilterBilinear,
|
| + benchmark_iterations_,
|
| + disable_cpu_flags_, benchmark_cpu_info_);
|
| + EXPECT_LE(diff, 10);
|
| +}
|
| +
|
| +
|
| } // namespace libyuv
|
|
|