133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp/* 233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * Copyright 2011 The LibYuv Project Authors. All rights reserved. 333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * 433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * Use of this source code is governed by a BSD-style license 533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * that can be found in the LICENSE file in the root of the source 633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * tree. An additional intellectual property rights grant can be found 7f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * in the file PATENTS. All contributing project authors may 833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * be found in the AUTHORS file in the root of the source tree. 933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp */ 1033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 1133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include <stdlib.h> 1233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include <time.h> 1333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 14b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard#include "../unit_test/unit_test.h" 15f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/convert_argb.h" 1633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/cpu_id.h" 1733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/scale_argb.h" 18f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/video_common.h" 1933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 2033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampnamespace libyuv { 2133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 22f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define STRINGIZE(line) #line 23f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define FILELINESTR(file, line) file ":" STRINGIZE(line) 24f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 25f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Test scaling with C vs Opt and return maximum pixel difference. 0 = exact. 26b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchardstatic int ARGBTestFilter(int src_width, 27b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_height, 28b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_width, 29b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_height, 30b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard FilterMode f, 31b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int benchmark_iterations, 32b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int disable_cpu_flags, 33b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int benchmark_cpu_info) { 34f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (!SizeValid(src_width, src_height, dst_width, dst_height)) { 35f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return 0; 36f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 3733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 38f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int i, j; 39f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const int b = 0; // 128 to test for padding/stride. 40b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int64 src_argb_plane_size = 41b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard (Abs(src_width) + b * 2) * (Abs(src_height) + b * 2) * 4LL; 42f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int src_stride_argb = (b * 2 + Abs(src_width)) * 4; 43f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 44f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(src_argb, src_argb_plane_size); 45f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (!src_argb) { 46f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n"); 47f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return 0; 48f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 49f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang MemRandomize(src_argb, src_argb_plane_size); 5033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 51f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4LL; 5233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int dst_stride_argb = (b * 2 + dst_width) * 4; 5333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 54f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(dst_argb_c, dst_argb_plane_size); 55f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(dst_argb_opt, dst_argb_plane_size); 56f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (!dst_argb_c || !dst_argb_opt) { 57f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n"); 58f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return 0; 5933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 6033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp memset(dst_argb_c, 2, dst_argb_plane_size); 6133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp memset(dst_argb_opt, 3, dst_argb_plane_size); 6233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 6333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // Warm up both versions for consistent benchmarks. 64f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization. 6533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 66b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_width, src_height, dst_argb_c + (dst_stride_argb * b) + b * 4, 67b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard dst_stride_argb, dst_width, dst_height, f); 68f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization. 6933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 70b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_width, src_height, dst_argb_opt + (dst_stride_argb * b) + b * 4, 71b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard dst_stride_argb, dst_width, dst_height, f); 7233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 73f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization. 7433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp double c_time = get_time(); 75f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 76b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_width, src_height, dst_argb_c + (dst_stride_argb * b) + b * 4, 77b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard dst_stride_argb, dst_width, dst_height, f); 78f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 79f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang c_time = (get_time() - c_time); 8033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 81f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization. 8233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp double opt_time = get_time(); 8333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp for (i = 0; i < benchmark_iterations; ++i) { 8433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 8533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp src_width, src_height, 8633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb, 8733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_width, dst_height, f); 8833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 8933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp opt_time = (get_time() - opt_time) / benchmark_iterations; 9033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 9133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // Report performance of C vs OPT 92b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard printf("filter %d - %8d us C - %8d us OPT\n", f, 93b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard static_cast<int>(c_time * 1e6), static_cast<int>(opt_time * 1e6)); 9433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 9533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // C version may be a little off from the optimized. Order of 9633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // operations may introduce rounding somewhere. So do a difference 9733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // of the buffers and look to see that the max difference isn't 9833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // over 2. 9933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int max_diff = 0; 10033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp for (i = b; i < (dst_height + b); ++i) { 10133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp for (j = b * 4; j < (dst_width + b) * 4; ++j) { 102f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int abs_diff = Abs(dst_argb_c[(i * dst_stride_argb) + j] - 10333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_argb_opt[(i * dst_stride_argb) + j]); 10433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp if (abs_diff > max_diff) { 10533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp max_diff = abs_diff; 10633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 10733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 10833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 10933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 110f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(dst_argb_c); 111f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(dst_argb_opt); 112f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(src_argb); 11333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp return max_diff; 11433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 11533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 116f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangstatic const int kTileX = 8; 117f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangstatic const int kTileY = 8; 118f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 119b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchardstatic int TileARGBScale(const uint8* src_argb, 120b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_stride_argb, 121b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_width, 122b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_height, 123b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard uint8* dst_argb, 124b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_stride_argb, 125b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_width, 126b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_height, 127f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang FilterMode filtering) { 128f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (int y = 0; y < dst_height; y += kTileY) { 129f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (int x = 0; x < dst_width; x += kTileX) { 130f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int clip_width = kTileX; 131f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (x + clip_width > dst_width) { 132f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang clip_width = dst_width - x; 133f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 134f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int clip_height = kTileY; 135f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (y + clip_height > dst_height) { 136f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang clip_height = dst_height - y; 137f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 138b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int r = ARGBScaleClip(src_argb, src_stride_argb, src_width, src_height, 139b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard dst_argb, dst_stride_argb, dst_width, dst_height, x, 140b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard y, clip_width, clip_height, filtering); 141f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (r) { 142f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return r; 143f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 144f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 14533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 146f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return 0; 14733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 14833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 149b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchardstatic int ARGBClipTestFilter(int src_width, 150b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_height, 151b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_width, 152b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_height, 153b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard FilterMode f, 154b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int benchmark_iterations) { 155f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (!SizeValid(src_width, src_height, dst_width, dst_height)) { 156f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return 0; 157f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 15833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 159f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const int b = 128; 160b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int64 src_argb_plane_size = 161b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard (Abs(src_width) + b * 2) * (Abs(src_height) + b * 2) * 4; 162f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int src_stride_argb = (b * 2 + Abs(src_width)) * 4; 163f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 164f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(src_argb, src_argb_plane_size); 165f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (!src_argb) { 166f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n"); 167f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return 0; 16833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 169f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang memset(src_argb, 1, src_argb_plane_size); 17033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 171f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4; 172f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_stride_argb = (b * 2 + dst_width) * 4; 17333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 174f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int i, j; 175f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (i = b; i < (Abs(src_height) + b); ++i) { 176f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = b; j < (Abs(src_width) + b) * 4; ++j) { 177f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb[(i * src_stride_argb) + j] = (fastrand() & 0xff); 178f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 17933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 18033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 181f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(dst_argb_c, dst_argb_plane_size); 182f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(dst_argb_opt, dst_argb_plane_size); 183f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (!dst_argb_c || !dst_argb_opt) { 184f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n"); 185f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return 0; 18633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 187f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang memset(dst_argb_c, 2, dst_argb_plane_size); 188f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang memset(dst_argb_opt, 3, dst_argb_plane_size); 18933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 190f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Do full image, no clipping. 191f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang double c_time = get_time(); 192f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 193b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_width, src_height, dst_argb_c + (dst_stride_argb * b) + b * 4, 194b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard dst_stride_argb, dst_width, dst_height, f); 195f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang c_time = (get_time() - c_time); 19633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 197f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Do tiled image, clipping scale to a tile at a time. 198f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang double opt_time = get_time(); 199f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (i = 0; i < benchmark_iterations; ++i) { 200f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang TileARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 201f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_width, src_height, 202f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb, 203f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_width, dst_height, f); 20433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 205f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang opt_time = (get_time() - opt_time) / benchmark_iterations; 20633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 207f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Report performance of Full vs Tiled. 208b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard printf("filter %d - %8d us Full - %8d us Tiled\n", f, 209b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard static_cast<int>(c_time * 1e6), static_cast<int>(opt_time * 1e6)); 21033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 211f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Compare full scaled image vs tiled image. 212f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int max_diff = 0; 213f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (i = b; i < (dst_height + b); ++i) { 214f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = b * 4; j < (dst_width + b) * 4; ++j) { 215f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int abs_diff = Abs(dst_argb_c[(i * dst_stride_argb) + j] - 216f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb_opt[(i * dst_stride_argb) + j]); 217f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (abs_diff > max_diff) { 218f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang max_diff = abs_diff; 219f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 220f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 22133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 222f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 223f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(dst_argb_c); 224f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(dst_argb_opt); 225f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(src_argb); 226f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return max_diff; 22733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 22833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 229f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// The following adjustments in dimensions ensure the scale factor will be 230f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// exactly achieved. 231f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define DX(x, nom, denom) static_cast<int>((Abs(x) / nom) * nom) 232f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define SX(x, nom, denom) static_cast<int>((x / nom) * denom) 233f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 234b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard#define TEST_FACTOR1(name, filter, nom, denom, max_diff) \ 235b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_F(LibYUVScaleTest, ARGBScaleDownBy##name##_##filter) { \ 236b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int diff = ARGBTestFilter( \ 237b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard SX(benchmark_width_, nom, denom), SX(benchmark_height_, nom, denom), \ 238b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard DX(benchmark_width_, nom, denom), DX(benchmark_height_, nom, denom), \ 239b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard kFilter##filter, benchmark_iterations_, disable_cpu_flags_, \ 240b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard benchmark_cpu_info_); \ 241b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard EXPECT_LE(diff, max_diff); \ 242b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard } \ 243b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_F(LibYUVScaleTest, ARGBScaleDownClipBy##name##_##filter) { \ 244b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int diff = ARGBClipTestFilter( \ 245b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard SX(benchmark_width_, nom, denom), SX(benchmark_height_, nom, denom), \ 246b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard DX(benchmark_width_, nom, denom), DX(benchmark_height_, nom, denom), \ 247b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard kFilter##filter, benchmark_iterations_); \ 248b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard EXPECT_LE(diff, max_diff); \ 249b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard } 25033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 251f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Test a scale factor with all 4 filters. Expect unfiltered to be exact, but 252f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// filtering is different fixed point implementations for SSSE3, Neon and C. 253b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard#define TEST_FACTOR(name, nom, denom) \ 254b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_FACTOR1(name, None, nom, denom, 0) \ 255b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_FACTOR1(name, Linear, nom, denom, 3) \ 256b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_FACTOR1(name, Bilinear, nom, denom, 3) \ 257b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_FACTOR1(name, Box, nom, denom, 3) 258f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 259f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_FACTOR(2, 1, 2) 260f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_FACTOR(4, 1, 4) 261f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_FACTOR(8, 1, 8) 262f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_FACTOR(3by4, 3, 4) 263f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_FACTOR(3by8, 3, 8) 264f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_FACTOR(3, 1, 3) 265f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef TEST_FACTOR1 266f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef TEST_FACTOR 267f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef SX 268f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef DX 269f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 270f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define TEST_SCALETO1(name, width, height, filter, max_diff) \ 271b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_F(LibYUVScaleTest, name##To##width##x##height##_##filter) { \ 272b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int diff = ARGBTestFilter(benchmark_width_, benchmark_height_, width, \ 273b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard height, kFilter##filter, benchmark_iterations_, \ 274b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard disable_cpu_flags_, benchmark_cpu_info_); \ 275b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard EXPECT_LE(diff, max_diff); \ 276b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard } \ 277b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_F(LibYUVScaleTest, name##From##width##x##height##_##filter) { \ 278b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int diff = ARGBTestFilter(width, height, Abs(benchmark_width_), \ 279b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard Abs(benchmark_height_), kFilter##filter, \ 280b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard benchmark_iterations_, disable_cpu_flags_, \ 281b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard benchmark_cpu_info_); \ 282b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard EXPECT_LE(diff, max_diff); \ 283b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard } \ 284b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_F(LibYUVScaleTest, name##ClipTo##width##x##height##_##filter) { \ 285b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int diff = \ 286b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard ARGBClipTestFilter(benchmark_width_, benchmark_height_, width, height, \ 287b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard kFilter##filter, benchmark_iterations_); \ 288b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard EXPECT_LE(diff, max_diff); \ 289b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard } \ 290b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_F(LibYUVScaleTest, name##ClipFrom##width##x##height##_##filter) { \ 291b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int diff = ARGBClipTestFilter(width, height, Abs(benchmark_width_), \ 292b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard Abs(benchmark_height_), kFilter##filter, \ 293b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard benchmark_iterations_); \ 294b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard EXPECT_LE(diff, max_diff); \ 295b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard } 29633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 297f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang/// Test scale to a specified size with all 4 filters. 298b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard#define TEST_SCALETO(name, width, height) \ 299b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_SCALETO1(name, width, height, None, 0) \ 300b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_SCALETO1(name, width, height, Linear, 3) \ 301b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard TEST_SCALETO1(name, width, height, Bilinear, 3) 302f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 303f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_SCALETO(ARGBScale, 1, 1) 304f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_SCALETO(ARGBScale, 320, 240) 305f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_SCALETO(ARGBScale, 352, 288) 306f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_SCALETO(ARGBScale, 569, 480) 307f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_SCALETO(ARGBScale, 640, 360) 308f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_SCALETO(ARGBScale, 1280, 720) 309f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef TEST_SCALETO1 310f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef TEST_SCALETO 311f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 312f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Scale with YUV conversion to ARGB and clipping. 313f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangLIBYUV_API 314b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchardint YUVToARGBScaleReference2(const uint8* src_y, 315b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_stride_y, 316b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard const uint8* src_u, 317b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_stride_u, 318b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard const uint8* src_v, 319b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_stride_v, 320b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard uint32 /* src_fourcc */, // TODO: Add support. 321b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_width, 322b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_height, 323b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard uint8* dst_argb, 324b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_stride_argb, 325b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard uint32 /* dst_fourcc */, // TODO: Add support. 326b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_width, 327b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_height, 328b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int clip_x, 329b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int clip_y, 330b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int clip_width, 331b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int clip_height, 332f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang enum FilterMode filtering) { 333f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* argb_buffer = static_cast<uint8*>(malloc(src_width * src_height * 4)); 334f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int r; 335b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, 336b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard argb_buffer, src_width * 4, src_width, src_height); 337b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard 338b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard r = ARGBScaleClip(argb_buffer, src_width * 4, src_width, src_height, dst_argb, 339b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard dst_stride_argb, dst_width, dst_height, clip_x, clip_y, 340b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard clip_width, clip_height, filtering); 341f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free(argb_buffer); 342f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return r; 343f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 34433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 345f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangstatic void FillRamp(uint8* buf, int width, int height, int v, int dx, int dy) { 346f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int rv = v; 347f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (int y = 0; y < height; ++y) { 348f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (int x = 0; x < width; ++x) { 349f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *buf++ = v; 350f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang v += dx; 351f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (v < 0 || v > 255) { 352f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dx = -dx; 353f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang v += dx; 354f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 355f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 356f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang v = rv + dy; 357f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (v < 0 || v > 255) { 358f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dy = -dy; 359f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang v += dy; 360f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 361f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang rv = v; 36233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 36333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 36433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 365f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Test scaling with C vs Opt and return maximum pixel difference. 0 = exact. 366b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchardstatic int YUVToARGBTestFilter(int src_width, 367b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int src_height, 368b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_width, 369b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_height, 370b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard FilterMode f, 371b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int benchmark_iterations) { 372f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 src_y_plane_size = Abs(src_width) * Abs(src_height); 373b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int64 src_uv_plane_size = 374b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard ((Abs(src_width) + 1) / 2) * ((Abs(src_height) + 1) / 2); 375f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int src_stride_y = Abs(src_width); 376f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int src_stride_uv = (Abs(src_width) + 1) / 2; 377f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 378f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(src_y, src_y_plane_size); 379f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(src_u, src_uv_plane_size); 380f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(src_v, src_uv_plane_size); 381f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 382b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int64 dst_argb_plane_size = (dst_width) * (dst_height)*4LL; 383b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int dst_stride_argb = (dst_width)*4; 384f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(dst_argb_c, dst_argb_plane_size); 385f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang align_buffer_page_end(dst_argb_opt, dst_argb_plane_size); 386f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (!dst_argb_c || !dst_argb_opt || !src_y || !src_u || !src_v) { 387f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n"); 388f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return 0; 389f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 390f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Fill YUV image with continuous ramp, which is less sensitive to 391f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // subsampling and filtering differences for test purposes. 392f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang FillRamp(src_y, Abs(src_width), Abs(src_height), 128, 1, 1); 393f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang FillRamp(src_u, (Abs(src_width) + 1) / 2, (Abs(src_height) + 1) / 2, 3, 1, 1); 394f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang FillRamp(src_v, (Abs(src_width) + 1) / 2, (Abs(src_height) + 1) / 2, 4, 1, 1); 395f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang memset(dst_argb_c, 2, dst_argb_plane_size); 396f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang memset(dst_argb_opt, 3, dst_argb_plane_size); 39733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 398b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard YUVToARGBScaleReference2(src_y, src_stride_y, src_u, src_stride_uv, src_v, 399b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_stride_uv, libyuv::FOURCC_I420, src_width, 400b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_height, dst_argb_c, dst_stride_argb, 401b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard libyuv::FOURCC_I420, dst_width, dst_height, 0, 0, 402b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard dst_width, dst_height, f); 403f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 404f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (int i = 0; i < benchmark_iterations; ++i) { 405b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard YUVToARGBScaleClip(src_y, src_stride_y, src_u, src_stride_uv, src_v, 406b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_stride_uv, libyuv::FOURCC_I420, src_width, 407b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard src_height, dst_argb_opt, dst_stride_argb, 408b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard libyuv::FOURCC_I420, dst_width, dst_height, 0, 0, 409b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard dst_width, dst_height, f); 410f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 411f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int max_diff = 0; 412f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (int i = 0; i < dst_height; ++i) { 413f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (int j = 0; j < dst_width * 4; ++j) { 414f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int abs_diff = Abs(dst_argb_c[(i * dst_stride_argb) + j] - 415f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb_opt[(i * dst_stride_argb) + j]); 416f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (abs_diff > max_diff) { 417b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard printf("error %d at %d,%d c %d opt %d", abs_diff, j, i, 418f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb_c[(i * dst_stride_argb) + j], 419f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb_opt[(i * dst_stride_argb) + j]); 420f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang EXPECT_LE(abs_diff, 40); 421f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang max_diff = abs_diff; 422f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 423f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 42433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 42533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 426f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(dst_argb_c); 427f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(dst_argb_opt); 428f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(src_y); 429f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(src_u); 430f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang free_aligned_buffer_page_end(src_v); 431f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return max_diff; 432f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 43333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 434f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_F(LibYUVScaleTest, YUVToRGBScaleUp) { 435b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int diff = 436b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard YUVToARGBTestFilter(benchmark_width_, benchmark_height_, 437b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard benchmark_width_ * 3 / 2, benchmark_height_ * 3 / 2, 438b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard libyuv::kFilterBilinear, benchmark_iterations_); 439f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang EXPECT_LE(diff, 10); 440f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 44133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 442f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu KuangTEST_F(LibYUVScaleTest, YUVToRGBScaleDown) { 443b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard int diff = YUVToARGBTestFilter( 444b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard benchmark_width_ * 3 / 2, benchmark_height_ * 3 / 2, benchmark_width_, 445b83bb38f0a92bedeb52baa31e515220927ef53bbFrank Barchard benchmark_height_, libyuv::kFilterBilinear, benchmark_iterations_); 446f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang EXPECT_LE(diff, 10); 44733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 44833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 44933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} // namespace libyuv 450