diff options
author | Sergio Garcia Murillo <sergio.garcia.murillo@gmail.com> | 2022-04-06 20:57:53 +0200 |
---|---|---|
committer | libyuv LUCI CQ <libyuv-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-04-06 23:49:35 +0000 |
commit | a77d615e1067fe5bb48444a073f7ee08fd273b8a (patch) | |
tree | 6f85baa2f8a3d60a40b31f317e1d10663e2b6f72 /unit_test | |
parent | 4589081cea3dc5364dc433f9a20e67706fd3e29c (diff) | |
download | libyuv-a77d615e1067fe5bb48444a073f7ee08fd273b8a.tar.gz |
Add tentative I422Rotate.
When doing 90 or 270 degrees rotation we need to do a rotate&scale of the UV planes, as there are no helper optimized functions to do this, we use the Y plane as temporal memory and perform each of the transforms independently:
First U plane is rotated, putting the result in the Y plane. After the rotation, the output has double the samples horizontally and half the samples vertically, so it is scaled into the final U plane. Same process is done with the V plane.
Last the Y plane that can be just rotated without scaling.
It would be great to have an optimized version for this, but maybe this is helpfull for triggering the discussions.
Bug: libyuv:926
Change-Id: I188af103c4d0e3f9522021b4bf2b63c9d5de8b93
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/3568424
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Diffstat (limited to 'unit_test')
-rw-r--r-- | unit_test/rotate_test.cc | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/unit_test/rotate_test.cc b/unit_test/rotate_test.cc index c140960e..d3887414 100644 --- a/unit_test/rotate_test.cc +++ b/unit_test/rotate_test.cc @@ -137,6 +137,94 @@ TEST_F(LibYUVRotateTest, DISABLED_I420Rotate270_Odd) { benchmark_cpu_info_); } +static void I422TestRotate(int src_width, + int src_height, + int dst_width, + int dst_height, + libyuv::RotationMode mode, + int benchmark_iterations, + int disable_cpu_flags, + int benchmark_cpu_info) { + if (src_width < 1) { + src_width = 1; + } + if (src_height == 0) { + src_height = 1; + } + if (dst_width < 1) { + dst_width = 1; + } + if (dst_height < 1) { + dst_height = 1; + } + int src_i422_y_size = src_width * Abs(src_height); + int src_i422_uv_size = ((src_width + 1) / 2) * Abs(src_height); + int src_i422_size = src_i422_y_size + src_i422_uv_size * 2; + align_buffer_page_end(src_i422, src_i422_size); + for (int i = 0; i < src_i422_size; ++i) { + src_i422[i] = fastrand() & 0xff; + } + + int dst_i422_y_size = dst_width * dst_height; + int dst_i422_uv_size = ((dst_width + 1) / 2) * dst_height; + int dst_i422_size = dst_i422_y_size + dst_i422_uv_size * 2; + align_buffer_page_end(dst_i422_c, dst_i422_size); + align_buffer_page_end(dst_i422_opt, dst_i422_size); + memset(dst_i422_c, 2, dst_i422_size); + memset(dst_i422_opt, 3, dst_i422_size); + + MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization. + I422Rotate(src_i422, src_width, src_i422 + src_i422_y_size, + (src_width + 1) / 2, src_i422 + src_i422_y_size + src_i422_uv_size, + (src_width + 1) / 2, dst_i422_c, dst_width, + dst_i422_c + dst_i422_y_size, (dst_width + 1) / 2, + dst_i422_c + dst_i422_y_size + dst_i422_uv_size, + (dst_width + 1) / 2, src_width, src_height, mode); + + MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization. + for (int i = 0; i < benchmark_iterations; ++i) { + I422Rotate( + src_i422, src_width, src_i422 + src_i422_y_size, (src_width + 1) / 2, + src_i422 + src_i422_y_size + src_i422_uv_size, (src_width + 1) / 2, + dst_i422_opt, dst_width, dst_i422_opt + dst_i422_y_size, + (dst_width + 1) / 2, dst_i422_opt + dst_i422_y_size + dst_i422_uv_size, + (dst_width + 1) / 2, src_width, src_height, mode); + } + + // Rotation should be exact. + for (int i = 0; i < dst_i422_size; ++i) { + EXPECT_EQ(dst_i422_c[i], dst_i422_opt[i]); + } + + free_aligned_buffer_page_end(dst_i422_c); + free_aligned_buffer_page_end(dst_i422_opt); + free_aligned_buffer_page_end(src_i422); +} + +TEST_F(LibYUVRotateTest, I422Rotate0_Opt) { + I422TestRotate(benchmark_width_, benchmark_height_, benchmark_width_, + benchmark_height_, kRotate0, benchmark_iterations_, + disable_cpu_flags_, benchmark_cpu_info_); +} + +TEST_F(LibYUVRotateTest, I422Rotate90_Opt) { + I422TestRotate(benchmark_width_, benchmark_height_, benchmark_height_, + benchmark_width_, kRotate90, benchmark_iterations_, + disable_cpu_flags_, benchmark_cpu_info_); +} + +TEST_F(LibYUVRotateTest, I422Rotate180_Opt) { + I422TestRotate(benchmark_width_, benchmark_height_, benchmark_width_, + benchmark_height_, kRotate180, benchmark_iterations_, + disable_cpu_flags_, benchmark_cpu_info_); +} + +TEST_F(LibYUVRotateTest, I422Rotate270_Opt) { + I422TestRotate(benchmark_width_, benchmark_height_, benchmark_height_, + benchmark_width_, kRotate270, benchmark_iterations_, + disable_cpu_flags_, benchmark_cpu_info_); +} + static void I444TestRotate(int src_width, int src_height, int dst_width, |