mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
scale with conversion using 2 steps with unittest
a prototype function to implement the yuv to rgb with conversion and scale. replace with 1 step function in future version, using same API. R=harryjin@google.com BUG=libyuv:471 Review URL: https://codereview.chromium.org/1421553016 .
This commit is contained in:
parent
6100f50f13
commit
60adcbaf32
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 1536
|
||||
Version: 1537
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -35,7 +35,6 @@ int ARGBScaleClip(const uint8* src_argb, int src_stride_argb,
|
||||
int clip_x, int clip_y, int clip_width, int clip_height,
|
||||
enum FilterMode filtering);
|
||||
|
||||
// TODO(fbarchard): Implement this.
|
||||
// Scale with YUV conversion to ARGB and clipping.
|
||||
LIBYUV_API
|
||||
int YUVToARGBScaleClip(const uint8* src_y, int src_stride_y,
|
||||
|
||||
@ -11,6 +11,6 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 1536
|
||||
#define LIBYUV_VERSION 1537
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
||||
|
||||
@ -847,6 +847,37 @@ int ARGBScale(const uint8* src_argb, int src_stride_argb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Scale with YUV conversion to ARGB and clipping.
|
||||
LIBYUV_API
|
||||
int YUVToARGBScaleClip(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;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // namespace libyuv
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user