2
0

rotate_test.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  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 "../unit_test/unit_test.h"
  12. #include "libyuv/cpu_id.h"
  13. #include "libyuv/rotate.h"
  14. namespace libyuv {
  15. static void I420TestRotate(int src_width,
  16. int src_height,
  17. int dst_width,
  18. int dst_height,
  19. libyuv::RotationMode mode,
  20. int benchmark_iterations,
  21. int disable_cpu_flags,
  22. int benchmark_cpu_info) {
  23. if (src_width < 1) {
  24. src_width = 1;
  25. }
  26. if (src_height == 0) {
  27. src_height = 1;
  28. }
  29. if (dst_width < 1) {
  30. dst_width = 1;
  31. }
  32. if (dst_height < 1) {
  33. dst_height = 1;
  34. }
  35. int src_i420_y_size = src_width * Abs(src_height);
  36. int src_i420_uv_size = ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2);
  37. int src_i420_size = src_i420_y_size + src_i420_uv_size * 2;
  38. align_buffer_page_end(src_i420, src_i420_size);
  39. for (int i = 0; i < src_i420_size; ++i) {
  40. src_i420[i] = fastrand() & 0xff;
  41. }
  42. int dst_i420_y_size = dst_width * dst_height;
  43. int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
  44. int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
  45. align_buffer_page_end(dst_i420_c, dst_i420_size);
  46. align_buffer_page_end(dst_i420_opt, dst_i420_size);
  47. memset(dst_i420_c, 2, dst_i420_size);
  48. memset(dst_i420_opt, 3, dst_i420_size);
  49. MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
  50. I420Rotate(src_i420, src_width, src_i420 + src_i420_y_size,
  51. (src_width + 1) / 2, src_i420 + src_i420_y_size + src_i420_uv_size,
  52. (src_width + 1) / 2, dst_i420_c, dst_width,
  53. dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
  54. dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
  55. (dst_width + 1) / 2, src_width, src_height, mode);
  56. MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
  57. for (int i = 0; i < benchmark_iterations; ++i) {
  58. I420Rotate(
  59. src_i420, src_width, src_i420 + src_i420_y_size, (src_width + 1) / 2,
  60. src_i420 + src_i420_y_size + src_i420_uv_size, (src_width + 1) / 2,
  61. dst_i420_opt, dst_width, dst_i420_opt + dst_i420_y_size,
  62. (dst_width + 1) / 2, dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
  63. (dst_width + 1) / 2, src_width, src_height, mode);
  64. }
  65. // Rotation should be exact.
  66. for (int i = 0; i < dst_i420_size; ++i) {
  67. EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
  68. }
  69. free_aligned_buffer_page_end(dst_i420_c);
  70. free_aligned_buffer_page_end(dst_i420_opt);
  71. free_aligned_buffer_page_end(src_i420);
  72. }
  73. TEST_F(LibYUVRotateTest, I420Rotate0_Opt) {
  74. I420TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
  75. benchmark_height_, kRotate0, benchmark_iterations_,
  76. disable_cpu_flags_, benchmark_cpu_info_);
  77. }
  78. TEST_F(LibYUVRotateTest, I420Rotate90_Opt) {
  79. I420TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
  80. benchmark_width_, kRotate90, benchmark_iterations_,
  81. disable_cpu_flags_, benchmark_cpu_info_);
  82. }
  83. TEST_F(LibYUVRotateTest, I420Rotate180_Opt) {
  84. I420TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
  85. benchmark_height_, kRotate180, benchmark_iterations_,
  86. disable_cpu_flags_, benchmark_cpu_info_);
  87. }
  88. TEST_F(LibYUVRotateTest, I420Rotate270_Opt) {
  89. I420TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
  90. benchmark_width_, kRotate270, benchmark_iterations_,
  91. disable_cpu_flags_, benchmark_cpu_info_);
  92. }
  93. // TODO(fbarchard): Remove odd width tests.
  94. // Odd width tests work but disabled because they use C code and can be
  95. // tested by passing an odd width command line or environment variable.
  96. TEST_F(LibYUVRotateTest, DISABLED_I420Rotate0_Odd) {
  97. I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  98. benchmark_width_ - 3, benchmark_height_ - 1, kRotate0,
  99. benchmark_iterations_, disable_cpu_flags_,
  100. benchmark_cpu_info_);
  101. }
  102. TEST_F(LibYUVRotateTest, DISABLED_I420Rotate90_Odd) {
  103. I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  104. benchmark_height_ - 1, benchmark_width_ - 3, kRotate90,
  105. benchmark_iterations_, disable_cpu_flags_,
  106. benchmark_cpu_info_);
  107. }
  108. TEST_F(LibYUVRotateTest, DISABLED_I420Rotate180_Odd) {
  109. I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  110. benchmark_width_ - 3, benchmark_height_ - 1, kRotate180,
  111. benchmark_iterations_, disable_cpu_flags_,
  112. benchmark_cpu_info_);
  113. }
  114. TEST_F(LibYUVRotateTest, DISABLED_I420Rotate270_Odd) {
  115. I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  116. benchmark_height_ - 1, benchmark_width_ - 3, kRotate270,
  117. benchmark_iterations_, disable_cpu_flags_,
  118. benchmark_cpu_info_);
  119. }
  120. static void I444TestRotate(int src_width,
  121. int src_height,
  122. int dst_width,
  123. int dst_height,
  124. libyuv::RotationMode mode,
  125. int benchmark_iterations,
  126. int disable_cpu_flags,
  127. int benchmark_cpu_info) {
  128. if (src_width < 1) {
  129. src_width = 1;
  130. }
  131. if (src_height == 0) {
  132. src_height = 1;
  133. }
  134. if (dst_width < 1) {
  135. dst_width = 1;
  136. }
  137. if (dst_height < 1) {
  138. dst_height = 1;
  139. }
  140. int src_i444_y_size = src_width * Abs(src_height);
  141. int src_i444_uv_size = src_width * Abs(src_height);
  142. int src_i444_size = src_i444_y_size + src_i444_uv_size * 2;
  143. align_buffer_page_end(src_i444, src_i444_size);
  144. for (int i = 0; i < src_i444_size; ++i) {
  145. src_i444[i] = fastrand() & 0xff;
  146. }
  147. int dst_i444_y_size = dst_width * dst_height;
  148. int dst_i444_uv_size = dst_width * dst_height;
  149. int dst_i444_size = dst_i444_y_size + dst_i444_uv_size * 2;
  150. align_buffer_page_end(dst_i444_c, dst_i444_size);
  151. align_buffer_page_end(dst_i444_opt, dst_i444_size);
  152. memset(dst_i444_c, 2, dst_i444_size);
  153. memset(dst_i444_opt, 3, dst_i444_size);
  154. MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
  155. I444Rotate(src_i444, src_width, src_i444 + src_i444_y_size, src_width,
  156. src_i444 + src_i444_y_size + src_i444_uv_size, src_width,
  157. dst_i444_c, dst_width, dst_i444_c + dst_i444_y_size, dst_width,
  158. dst_i444_c + dst_i444_y_size + dst_i444_uv_size, dst_width,
  159. src_width, src_height, mode);
  160. MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
  161. for (int i = 0; i < benchmark_iterations; ++i) {
  162. I444Rotate(src_i444, src_width, src_i444 + src_i444_y_size, src_width,
  163. src_i444 + src_i444_y_size + src_i444_uv_size, src_width,
  164. dst_i444_opt, dst_width, dst_i444_opt + dst_i444_y_size,
  165. dst_width, dst_i444_opt + dst_i444_y_size + dst_i444_uv_size,
  166. dst_width, src_width, src_height, mode);
  167. }
  168. // Rotation should be exact.
  169. for (int i = 0; i < dst_i444_size; ++i) {
  170. EXPECT_EQ(dst_i444_c[i], dst_i444_opt[i]);
  171. }
  172. free_aligned_buffer_page_end(dst_i444_c);
  173. free_aligned_buffer_page_end(dst_i444_opt);
  174. free_aligned_buffer_page_end(src_i444);
  175. }
  176. TEST_F(LibYUVRotateTest, I444Rotate0_Opt) {
  177. I444TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
  178. benchmark_height_, kRotate0, benchmark_iterations_,
  179. disable_cpu_flags_, benchmark_cpu_info_);
  180. }
  181. TEST_F(LibYUVRotateTest, I444Rotate90_Opt) {
  182. I444TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
  183. benchmark_width_, kRotate90, benchmark_iterations_,
  184. disable_cpu_flags_, benchmark_cpu_info_);
  185. }
  186. TEST_F(LibYUVRotateTest, I444Rotate180_Opt) {
  187. I444TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
  188. benchmark_height_, kRotate180, benchmark_iterations_,
  189. disable_cpu_flags_, benchmark_cpu_info_);
  190. }
  191. TEST_F(LibYUVRotateTest, I444Rotate270_Opt) {
  192. I444TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
  193. benchmark_width_, kRotate270, benchmark_iterations_,
  194. disable_cpu_flags_, benchmark_cpu_info_);
  195. }
  196. // TODO(fbarchard): Remove odd width tests.
  197. // Odd width tests work but disabled because they use C code and can be
  198. // tested by passing an odd width command line or environment variable.
  199. TEST_F(LibYUVRotateTest, DISABLED_I444Rotate0_Odd) {
  200. I444TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  201. benchmark_width_ - 3, benchmark_height_ - 1, kRotate0,
  202. benchmark_iterations_, disable_cpu_flags_,
  203. benchmark_cpu_info_);
  204. }
  205. TEST_F(LibYUVRotateTest, DISABLED_I444Rotate90_Odd) {
  206. I444TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  207. benchmark_height_ - 1, benchmark_width_ - 3, kRotate90,
  208. benchmark_iterations_, disable_cpu_flags_,
  209. benchmark_cpu_info_);
  210. }
  211. TEST_F(LibYUVRotateTest, DISABLED_I444Rotate180_Odd) {
  212. I444TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  213. benchmark_width_ - 3, benchmark_height_ - 1, kRotate180,
  214. benchmark_iterations_, disable_cpu_flags_,
  215. benchmark_cpu_info_);
  216. }
  217. TEST_F(LibYUVRotateTest, DISABLED_I444Rotate270_Odd) {
  218. I444TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  219. benchmark_height_ - 1, benchmark_width_ - 3, kRotate270,
  220. benchmark_iterations_, disable_cpu_flags_,
  221. benchmark_cpu_info_);
  222. }
  223. static void NV12TestRotate(int src_width,
  224. int src_height,
  225. int dst_width,
  226. int dst_height,
  227. libyuv::RotationMode mode,
  228. int benchmark_iterations,
  229. int disable_cpu_flags,
  230. int benchmark_cpu_info) {
  231. if (src_width < 1) {
  232. src_width = 1;
  233. }
  234. if (src_height == 0) { // allow negative for inversion test.
  235. src_height = 1;
  236. }
  237. if (dst_width < 1) {
  238. dst_width = 1;
  239. }
  240. if (dst_height < 1) {
  241. dst_height = 1;
  242. }
  243. int src_nv12_y_size = src_width * Abs(src_height);
  244. int src_nv12_uv_size =
  245. ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2) * 2;
  246. int src_nv12_size = src_nv12_y_size + src_nv12_uv_size;
  247. align_buffer_page_end(src_nv12, src_nv12_size);
  248. for (int i = 0; i < src_nv12_size; ++i) {
  249. src_nv12[i] = fastrand() & 0xff;
  250. }
  251. int dst_i420_y_size = dst_width * dst_height;
  252. int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
  253. int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
  254. align_buffer_page_end(dst_i420_c, dst_i420_size);
  255. align_buffer_page_end(dst_i420_opt, dst_i420_size);
  256. memset(dst_i420_c, 2, dst_i420_size);
  257. memset(dst_i420_opt, 3, dst_i420_size);
  258. MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
  259. NV12ToI420Rotate(src_nv12, src_width, src_nv12 + src_nv12_y_size,
  260. (src_width + 1) & ~1, dst_i420_c, dst_width,
  261. dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
  262. dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
  263. (dst_width + 1) / 2, src_width, src_height, mode);
  264. MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
  265. for (int i = 0; i < benchmark_iterations; ++i) {
  266. NV12ToI420Rotate(src_nv12, src_width, src_nv12 + src_nv12_y_size,
  267. (src_width + 1) & ~1, dst_i420_opt, dst_width,
  268. dst_i420_opt + dst_i420_y_size, (dst_width + 1) / 2,
  269. dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
  270. (dst_width + 1) / 2, src_width, src_height, mode);
  271. }
  272. // Rotation should be exact.
  273. for (int i = 0; i < dst_i420_size; ++i) {
  274. EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
  275. }
  276. free_aligned_buffer_page_end(dst_i420_c);
  277. free_aligned_buffer_page_end(dst_i420_opt);
  278. free_aligned_buffer_page_end(src_nv12);
  279. }
  280. TEST_F(LibYUVRotateTest, NV12Rotate0_Opt) {
  281. NV12TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
  282. benchmark_height_, kRotate0, benchmark_iterations_,
  283. disable_cpu_flags_, benchmark_cpu_info_);
  284. }
  285. TEST_F(LibYUVRotateTest, NV12Rotate90_Opt) {
  286. NV12TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
  287. benchmark_width_, kRotate90, benchmark_iterations_,
  288. disable_cpu_flags_, benchmark_cpu_info_);
  289. }
  290. TEST_F(LibYUVRotateTest, NV12Rotate180_Opt) {
  291. NV12TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
  292. benchmark_height_, kRotate180, benchmark_iterations_,
  293. disable_cpu_flags_, benchmark_cpu_info_);
  294. }
  295. TEST_F(LibYUVRotateTest, NV12Rotate270_Opt) {
  296. NV12TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
  297. benchmark_width_, kRotate270, benchmark_iterations_,
  298. disable_cpu_flags_, benchmark_cpu_info_);
  299. }
  300. TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate0_Odd) {
  301. NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  302. benchmark_width_ - 3, benchmark_height_ - 1, kRotate0,
  303. benchmark_iterations_, disable_cpu_flags_,
  304. benchmark_cpu_info_);
  305. }
  306. TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate90_Odd) {
  307. NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  308. benchmark_height_ - 1, benchmark_width_ - 3, kRotate90,
  309. benchmark_iterations_, disable_cpu_flags_,
  310. benchmark_cpu_info_);
  311. }
  312. TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate180_Odd) {
  313. NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  314. benchmark_width_ - 3, benchmark_height_ - 1, kRotate180,
  315. benchmark_iterations_, disable_cpu_flags_,
  316. benchmark_cpu_info_);
  317. }
  318. TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate270_Odd) {
  319. NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
  320. benchmark_height_ - 1, benchmark_width_ - 3, kRotate270,
  321. benchmark_iterations_, disable_cpu_flags_,
  322. benchmark_cpu_info_);
  323. }
  324. TEST_F(LibYUVRotateTest, NV12Rotate0_Invert) {
  325. NV12TestRotate(benchmark_width_, -benchmark_height_, benchmark_width_,
  326. benchmark_height_, kRotate0, benchmark_iterations_,
  327. disable_cpu_flags_, benchmark_cpu_info_);
  328. }
  329. TEST_F(LibYUVRotateTest, NV12Rotate90_Invert) {
  330. NV12TestRotate(benchmark_width_, -benchmark_height_, benchmark_height_,
  331. benchmark_width_, kRotate90, benchmark_iterations_,
  332. disable_cpu_flags_, benchmark_cpu_info_);
  333. }
  334. TEST_F(LibYUVRotateTest, NV12Rotate180_Invert) {
  335. NV12TestRotate(benchmark_width_, -benchmark_height_, benchmark_width_,
  336. benchmark_height_, kRotate180, benchmark_iterations_,
  337. disable_cpu_flags_, benchmark_cpu_info_);
  338. }
  339. TEST_F(LibYUVRotateTest, NV12Rotate270_Invert) {
  340. NV12TestRotate(benchmark_width_, -benchmark_height_, benchmark_height_,
  341. benchmark_width_, kRotate270, benchmark_iterations_,
  342. disable_cpu_flags_, benchmark_cpu_info_);
  343. }
  344. } // namespace libyuv