rotate_test.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright 2012 The LibYuv Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include <stdlib.h>
  11. #include "libyuv/cpu_id.h"
  12. #include "libyuv/rotate.h"
  13. #include "../unit_test/unit_test.h"
  14. namespace libyuv {
  15. static void I420TestRotate(int src_width, int src_height,
  16. int dst_width, int dst_height,
  17. libyuv::RotationMode mode,
  18. int benchmark_iterations,
  19. int disable_cpu_flags, int benchmark_cpu_info) {
  20. if (src_width < 1) {
  21. src_width = 1;
  22. }
  23. if (src_height == 0) {
  24. src_height = 1;
  25. }
  26. if (dst_width < 1) {
  27. dst_width = 1;
  28. }
  29. if (dst_height < 1) {
  30. dst_height = 1;
  31. }
  32. int src_i420_y_size = src_width * Abs(src_height);
  33. int src_i420_uv_size = ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2);
  34. int src_i420_size = src_i420_y_size + src_i420_uv_size * 2;
  35. align_buffer_page_end(src_i420, src_i420_size);
  36. for (int i = 0; i < src_i420_size; ++i) {
  37. src_i420[i] = fastrand() & 0xff;
  38. }
  39. int dst_i420_y_size = dst_width * dst_height;
  40. int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
  41. int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
  42. align_buffer_page_end(dst_i420_c, dst_i420_size);
  43. align_buffer_page_end(dst_i420_opt, dst_i420_size);
  44. memset(dst_i420_c, 2, dst_i420_size);
  45. memset(dst_i420_opt, 3, dst_i420_size);
  46. MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
  47. I420Rotate(src_i420, src_width,
  48. src_i420 + src_i420_y_size, (src_width + 1) / 2,
  49. src_i420 + src_i420_y_size + src_i420_uv_size, (src_width + 1) / 2,
  50. dst_i420_c, dst_width,
  51. dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
  52. dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
  53. (dst_width + 1) / 2,
  54. src_width, src_height, mode);
  55. MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
  56. for (int i = 0; i < benchmark_iterations; ++i) {
  57. I420Rotate(src_i420, src_width,
  58. src_i420 + src_i420_y_size, (src_width + 1) / 2,
  59. src_i420 + src_i420_y_size + src_i420_uv_size,
  60. (src_width + 1) / 2,
  61. dst_i420_opt, dst_width,
  62. dst_i420_opt + dst_i420_y_size, (dst_width + 1) / 2,
  63. dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
  64. (dst_width + 1) / 2,
  65. src_width, src_height, mode);
  66. }
  67. // Rotation should be exact.
  68. for (int i = 0; i < dst_i420_size; ++i) {
  69. EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
  70. }
  71. free_aligned_buffer_page_end(dst_i420_c);
  72. free_aligned_buffer_page_end(dst_i420_opt);
  73. free_aligned_buffer_page_end(src_i420);
  74. }
  75. TEST_F(LibYUVRotateTest, I420Rotate0_Opt) {
  76. I420TestRotate(benchmark_width_, benchmark_height_,
  77. benchmark_width_, benchmark_height_,
  78. kRotate0, benchmark_iterations_,
  79. disable_cpu_flags_, benchmark_cpu_info_);
  80. }
  81. TEST_F(LibYUVRotateTest, I420Rotate90_Opt) {
  82. I420TestRotate(benchmark_width_, benchmark_height_,
  83. benchmark_height_, benchmark_width_,
  84. kRotate90, benchmark_iterations_,
  85. disable_cpu_flags_, benchmark_cpu_info_);
  86. }
  87. TEST_F(LibYUVRotateTest, I420Rotate180_Opt) {
  88. I420TestRotate(benchmark_width_, benchmark_height_,
  89. benchmark_width_, benchmark_height_,
  90. kRotate180, benchmark_iterations_,
  91. disable_cpu_flags_, benchmark_cpu_info_);
  92. }
  93. TEST_F(LibYUVRotateTest, I420Rotate270_Opt) {
  94. I420TestRotate(benchmark_width_, benchmark_height_,
  95. benchmark_height_, benchmark_width_,
  96. kRotate270, benchmark_iterations_,
  97. disable_cpu_flags_, benchmark_cpu_info_);
  98. }
  99. // TODO(fbarchard): Remove odd width tests.
  100. // Odd width tests work but disabled because they use C code and can be
  101. // tested by passing an odd width command line or environment variable.
  102. TEST_F(LibYUVRotateTest, DISABLED_I420Rotate0_Odd) {
  103. I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  104. benchmark_width_ - 3, benchmark_height_ - 1,
  105. kRotate0, benchmark_iterations_,
  106. disable_cpu_flags_, benchmark_cpu_info_);
  107. }
  108. TEST_F(LibYUVRotateTest, DISABLED_I420Rotate90_Odd) {
  109. I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  110. benchmark_height_ - 1, benchmark_width_ - 3,
  111. kRotate90, benchmark_iterations_,
  112. disable_cpu_flags_, benchmark_cpu_info_);
  113. }
  114. TEST_F(LibYUVRotateTest, DISABLED_I420Rotate180_Odd) {
  115. I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  116. benchmark_width_ - 3, benchmark_height_ - 1,
  117. kRotate180, benchmark_iterations_,
  118. disable_cpu_flags_, benchmark_cpu_info_);
  119. }
  120. TEST_F(LibYUVRotateTest, DISABLED_I420Rotate270_Odd) {
  121. I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  122. benchmark_height_ - 1, benchmark_width_ - 3,
  123. kRotate270, benchmark_iterations_,
  124. disable_cpu_flags_, benchmark_cpu_info_);
  125. }
  126. static void NV12TestRotate(int src_width, int src_height,
  127. int dst_width, int dst_height,
  128. libyuv::RotationMode mode,
  129. int benchmark_iterations,
  130. int disable_cpu_flags, int benchmark_cpu_info) {
  131. if (src_width < 1) {
  132. src_width = 1;
  133. }
  134. if (src_height == 0) { // allow negative for inversion test.
  135. src_height = 1;
  136. }
  137. if (dst_width < 1) {
  138. dst_width = 1;
  139. }
  140. if (dst_height < 1) {
  141. dst_height = 1;
  142. }
  143. int src_nv12_y_size = src_width * Abs(src_height);
  144. int src_nv12_uv_size =
  145. ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2) * 2;
  146. int src_nv12_size = src_nv12_y_size + src_nv12_uv_size;
  147. align_buffer_page_end(src_nv12, src_nv12_size);
  148. for (int i = 0; i < src_nv12_size; ++i) {
  149. src_nv12[i] = fastrand() & 0xff;
  150. }
  151. int dst_i420_y_size = dst_width * dst_height;
  152. int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
  153. int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
  154. align_buffer_page_end(dst_i420_c, dst_i420_size);
  155. align_buffer_page_end(dst_i420_opt, dst_i420_size);
  156. memset(dst_i420_c, 2, dst_i420_size);
  157. memset(dst_i420_opt, 3, dst_i420_size);
  158. MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
  159. NV12ToI420Rotate(src_nv12, src_width,
  160. src_nv12 + src_nv12_y_size, (src_width + 1) & ~1,
  161. dst_i420_c, dst_width,
  162. dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
  163. dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
  164. (dst_width + 1) / 2,
  165. src_width, src_height, mode);
  166. MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
  167. for (int i = 0; i < benchmark_iterations; ++i) {
  168. NV12ToI420Rotate(src_nv12, src_width,
  169. src_nv12 + src_nv12_y_size, (src_width + 1) & ~1,
  170. dst_i420_opt, dst_width,
  171. dst_i420_opt + dst_i420_y_size, (dst_width + 1) / 2,
  172. dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
  173. (dst_width + 1) / 2,
  174. src_width, src_height, mode);
  175. }
  176. // Rotation should be exact.
  177. for (int i = 0; i < dst_i420_size; ++i) {
  178. EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
  179. }
  180. free_aligned_buffer_page_end(dst_i420_c);
  181. free_aligned_buffer_page_end(dst_i420_opt);
  182. free_aligned_buffer_page_end(src_nv12);
  183. }
  184. TEST_F(LibYUVRotateTest, NV12Rotate0_Opt) {
  185. NV12TestRotate(benchmark_width_, benchmark_height_,
  186. benchmark_width_, benchmark_height_,
  187. kRotate0, benchmark_iterations_,
  188. disable_cpu_flags_, benchmark_cpu_info_);
  189. }
  190. TEST_F(LibYUVRotateTest, NV12Rotate90_Opt) {
  191. NV12TestRotate(benchmark_width_, benchmark_height_,
  192. benchmark_height_, benchmark_width_,
  193. kRotate90, benchmark_iterations_,
  194. disable_cpu_flags_, benchmark_cpu_info_);
  195. }
  196. TEST_F(LibYUVRotateTest, NV12Rotate180_Opt) {
  197. NV12TestRotate(benchmark_width_, benchmark_height_,
  198. benchmark_width_, benchmark_height_,
  199. kRotate180, benchmark_iterations_,
  200. disable_cpu_flags_, benchmark_cpu_info_);
  201. }
  202. TEST_F(LibYUVRotateTest, NV12Rotate270_Opt) {
  203. NV12TestRotate(benchmark_width_, benchmark_height_,
  204. benchmark_height_, benchmark_width_,
  205. kRotate270, benchmark_iterations_,
  206. disable_cpu_flags_, benchmark_cpu_info_);
  207. }
  208. TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate0_Odd) {
  209. NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  210. benchmark_width_ - 3, benchmark_height_ - 1,
  211. kRotate0, benchmark_iterations_,
  212. disable_cpu_flags_, benchmark_cpu_info_);
  213. }
  214. TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate90_Odd) {
  215. NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  216. benchmark_height_ - 1, benchmark_width_ - 3,
  217. kRotate90, benchmark_iterations_,
  218. disable_cpu_flags_, benchmark_cpu_info_);
  219. }
  220. TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate180_Odd) {
  221. NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  222. benchmark_width_ - 3, benchmark_height_ - 1,
  223. kRotate180, benchmark_iterations_,
  224. disable_cpu_flags_, benchmark_cpu_info_);
  225. }
  226. TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate270_Odd) {
  227. NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  228. benchmark_height_ - 1, benchmark_width_ - 3,
  229. kRotate270, benchmark_iterations_,
  230. disable_cpu_flags_, benchmark_cpu_info_);
  231. }
  232. TEST_F(LibYUVRotateTest, NV12Rotate0_Invert) {
  233. NV12TestRotate(benchmark_width_, -benchmark_height_,
  234. benchmark_width_, benchmark_height_,
  235. kRotate0, benchmark_iterations_,
  236. disable_cpu_flags_, benchmark_cpu_info_);
  237. }
  238. TEST_F(LibYUVRotateTest, NV12Rotate90_Invert) {
  239. NV12TestRotate(benchmark_width_, -benchmark_height_,
  240. benchmark_height_, benchmark_width_,
  241. kRotate90, benchmark_iterations_,
  242. disable_cpu_flags_, benchmark_cpu_info_);
  243. }
  244. TEST_F(LibYUVRotateTest, NV12Rotate180_Invert) {
  245. NV12TestRotate(benchmark_width_, -benchmark_height_,
  246. benchmark_width_, benchmark_height_,
  247. kRotate180, benchmark_iterations_,
  248. disable_cpu_flags_, benchmark_cpu_info_);
  249. }
  250. TEST_F(LibYUVRotateTest, NV12Rotate270_Invert) {
  251. NV12TestRotate(benchmark_width_, -benchmark_height_,
  252. benchmark_height_, benchmark_width_,
  253. kRotate270, benchmark_iterations_,
  254. disable_cpu_flags_, benchmark_cpu_info_);
  255. }
  256. } // namespace libyuv