vf_bwdif.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * FFmpeg is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. */
  18. #include <string.h>
  19. #include "checkasm.h"
  20. #include "libavfilter/bwdifdsp.h"
  21. #include "libavutil/mem_internal.h"
  22. #define WIDTH 256
  23. #define randomize_buffers(buf0, buf1, mask, count) \
  24. for (size_t i = 0; i < count; i++) \
  25. buf0[i] = buf1[i] = rnd() & mask
  26. #define randomize_overflow_check(buf0, buf1, mask, count) \
  27. for (size_t i = 0; i < count; i++) \
  28. buf0[i] = buf1[i] = (rnd() & 1) != 0 ? mask : 0;
  29. #define BODY(type, depth) \
  30. do { \
  31. type prev0[9*WIDTH], prev1[9*WIDTH]; \
  32. type next0[9*WIDTH], next1[9*WIDTH]; \
  33. type cur0[9*WIDTH], cur1[9*WIDTH]; \
  34. type dst0[WIDTH], dst1[WIDTH]; \
  35. const int stride = WIDTH; \
  36. const int mask = (1<<depth)-1; \
  37. \
  38. declare_func(void, void *dst, const void *prev, const void *cur, const void *next, \
  39. int w, int prefs, int mrefs, int prefs2, int mrefs2, \
  40. int prefs3, int mrefs3, int prefs4, int mrefs4, \
  41. int parity, int clip_max); \
  42. \
  43. randomize_buffers(prev0, prev1, mask, 9*WIDTH); \
  44. randomize_buffers(next0, next1, mask, 9*WIDTH); \
  45. randomize_buffers( cur0, cur1, mask, 9*WIDTH); \
  46. \
  47. call_ref(dst0, prev0 + 4*WIDTH, cur0 + 4*WIDTH, next0 + 4*WIDTH, \
  48. WIDTH, stride, -stride, 2*stride, -2*stride, \
  49. 3*stride, -3*stride, 4*stride, -4*stride, \
  50. 0, mask); \
  51. call_new(dst1, prev1 + 4*WIDTH, cur1 + 4*WIDTH, next1 + 4*WIDTH, \
  52. WIDTH, stride, -stride, 2*stride, -2*stride, \
  53. 3*stride, -3*stride, 4*stride, -4*stride, \
  54. 0, mask); \
  55. \
  56. if (memcmp(dst0, dst1, sizeof dst0) \
  57. || memcmp(prev0, prev1, sizeof prev0) \
  58. || memcmp(next0, next1, sizeof next0) \
  59. || memcmp( cur0, cur1, sizeof cur0)) \
  60. fail(); \
  61. bench_new(dst1, prev1 + 4*WIDTH, cur1 + 4*WIDTH, next1 + 4*WIDTH, \
  62. WIDTH, stride, -stride, 2*stride, -2*stride, \
  63. 3*stride, -3*stride, 4*stride, -4*stride, \
  64. 0, mask); \
  65. } while (0)
  66. void checkasm_check_vf_bwdif(void)
  67. {
  68. BWDIFDSPContext ctx_8, ctx_10;
  69. ff_bwdif_init_filter_line(&ctx_8, 8);
  70. ff_bwdif_init_filter_line(&ctx_10, 10);
  71. if (check_func(ctx_8.filter_line, "bwdif8")) {
  72. BODY(uint8_t, 8);
  73. report("bwdif8");
  74. }
  75. if (check_func(ctx_10.filter_line, "bwdif10")) {
  76. BODY(uint16_t, 10);
  77. report("bwdif10");
  78. }
  79. if (!ctx_8.filter_line3)
  80. ctx_8.filter_line3 = ff_bwdif_filter_line3_c;
  81. {
  82. LOCAL_ALIGNED_16(uint8_t, prev0, [11*WIDTH]);
  83. LOCAL_ALIGNED_16(uint8_t, prev1, [11*WIDTH]);
  84. LOCAL_ALIGNED_16(uint8_t, next0, [11*WIDTH]);
  85. LOCAL_ALIGNED_16(uint8_t, next1, [11*WIDTH]);
  86. LOCAL_ALIGNED_16(uint8_t, cur0, [11*WIDTH]);
  87. LOCAL_ALIGNED_16(uint8_t, cur1, [11*WIDTH]);
  88. LOCAL_ALIGNED_16(uint8_t, dst0, [WIDTH*3]);
  89. LOCAL_ALIGNED_16(uint8_t, dst1, [WIDTH*3]);
  90. const int stride = WIDTH;
  91. const int mask = (1<<8)-1;
  92. int parity;
  93. for (parity = 0; parity != 2; ++parity) {
  94. if (check_func(ctx_8.filter_line3, "bwdif8.line3.rnd.p%d", parity)) {
  95. declare_func(void, void * dst1, int d_stride,
  96. const void * prev1, const void * cur1, const void * next1, int prefs,
  97. int w, int parity, int clip_max);
  98. randomize_buffers(prev0, prev1, mask, 11*WIDTH);
  99. randomize_buffers(next0, next1, mask, 11*WIDTH);
  100. randomize_buffers( cur0, cur1, mask, 11*WIDTH);
  101. call_ref(dst0, stride,
  102. prev0 + stride * 4, cur0 + stride * 4, next0 + stride * 4, stride,
  103. WIDTH, parity, mask);
  104. call_new(dst1, stride,
  105. prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, stride,
  106. WIDTH, parity, mask);
  107. if (memcmp(dst0, dst1, WIDTH*3)
  108. || memcmp(prev0, prev1, WIDTH*11)
  109. || memcmp(next0, next1, WIDTH*11)
  110. || memcmp( cur0, cur1, WIDTH*11))
  111. fail();
  112. bench_new(dst1, stride,
  113. prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, stride,
  114. WIDTH, parity, mask);
  115. }
  116. }
  117. // Use just 0s and ~0s to try to provoke bad cropping or overflow
  118. // Parity makes no difference to this test so just test 0
  119. if (check_func(ctx_8.filter_line3, "bwdif8.line3.overflow")) {
  120. declare_func(void, void * dst1, int d_stride,
  121. const void * prev1, const void * cur1, const void * next1, int prefs,
  122. int w, int parity, int clip_max);
  123. randomize_overflow_check(prev0, prev1, mask, 11*WIDTH);
  124. randomize_overflow_check(next0, next1, mask, 11*WIDTH);
  125. randomize_overflow_check( cur0, cur1, mask, 11*WIDTH);
  126. call_ref(dst0, stride,
  127. prev0 + stride * 4, cur0 + stride * 4, next0 + stride * 4, stride,
  128. WIDTH, 0, mask);
  129. call_new(dst1, stride,
  130. prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, stride,
  131. WIDTH, 0, mask);
  132. if (memcmp(dst0, dst1, WIDTH*3)
  133. || memcmp(prev0, prev1, WIDTH*11)
  134. || memcmp(next0, next1, WIDTH*11)
  135. || memcmp( cur0, cur1, WIDTH*11))
  136. fail();
  137. // No point to benching
  138. }
  139. report("bwdif8.line3");
  140. }
  141. {
  142. LOCAL_ALIGNED_16(uint8_t, prev0, [11*WIDTH]);
  143. LOCAL_ALIGNED_16(uint8_t, prev1, [11*WIDTH]);
  144. LOCAL_ALIGNED_16(uint8_t, next0, [11*WIDTH]);
  145. LOCAL_ALIGNED_16(uint8_t, next1, [11*WIDTH]);
  146. LOCAL_ALIGNED_16(uint8_t, cur0, [11*WIDTH]);
  147. LOCAL_ALIGNED_16(uint8_t, cur1, [11*WIDTH]);
  148. LOCAL_ALIGNED_16(uint8_t, dst0, [WIDTH*3]);
  149. LOCAL_ALIGNED_16(uint8_t, dst1, [WIDTH*3]);
  150. const int stride = WIDTH;
  151. const int mask = (1<<8)-1;
  152. int spat;
  153. int parity;
  154. for (spat = 0; spat != 2; ++spat) {
  155. for (parity = 0; parity != 2; ++parity) {
  156. if (check_func(ctx_8.filter_edge, "bwdif8.edge.s%d.p%d", spat, parity)) {
  157. declare_func(void, void *dst1, const void *prev1, const void *cur1, const void *next1,
  158. int w, int prefs, int mrefs, int prefs2, int mrefs2,
  159. int parity, int clip_max, int spat);
  160. randomize_buffers(prev0, prev1, mask, 11*WIDTH);
  161. randomize_buffers(next0, next1, mask, 11*WIDTH);
  162. randomize_buffers( cur0, cur1, mask, 11*WIDTH);
  163. memset(dst0, 0xba, WIDTH * 3);
  164. memset(dst1, 0xba, WIDTH * 3);
  165. call_ref(dst0 + stride,
  166. prev0 + stride * 4, cur0 + stride * 4, next0 + stride * 4, WIDTH,
  167. stride, -stride, stride * 2, -stride * 2,
  168. parity, mask, spat);
  169. call_new(dst1 + stride,
  170. prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, WIDTH,
  171. stride, -stride, stride * 2, -stride * 2,
  172. parity, mask, spat);
  173. if (memcmp(dst0, dst1, WIDTH*3)
  174. || memcmp(prev0, prev1, WIDTH*11)
  175. || memcmp(next0, next1, WIDTH*11)
  176. || memcmp( cur0, cur1, WIDTH*11))
  177. fail();
  178. bench_new(dst1 + stride,
  179. prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, WIDTH,
  180. stride, -stride, stride * 2, -stride * 2,
  181. parity, mask, spat);
  182. }
  183. }
  184. }
  185. report("bwdif8.edge");
  186. }
  187. if (check_func(ctx_8.filter_intra, "bwdif8.intra")) {
  188. LOCAL_ALIGNED_16(uint8_t, cur0, [11*WIDTH]);
  189. LOCAL_ALIGNED_16(uint8_t, cur1, [11*WIDTH]);
  190. LOCAL_ALIGNED_16(uint8_t, dst0, [WIDTH*3]);
  191. LOCAL_ALIGNED_16(uint8_t, dst1, [WIDTH*3]);
  192. const int stride = WIDTH;
  193. const int mask = (1<<8)-1;
  194. declare_func(void, void *dst1, const void *cur1, int w, int prefs, int mrefs,
  195. int prefs3, int mrefs3, int parity, int clip_max);
  196. randomize_buffers( cur0, cur1, mask, 11*WIDTH);
  197. memset(dst0, 0xba, WIDTH * 3);
  198. memset(dst1, 0xba, WIDTH * 3);
  199. call_ref(dst0 + stride,
  200. cur0 + stride * 4, WIDTH,
  201. stride, -stride, stride * 3, -stride * 3,
  202. 0, mask);
  203. call_new(dst1 + stride,
  204. cur0 + stride * 4, WIDTH,
  205. stride, -stride, stride * 3, -stride * 3,
  206. 0, mask);
  207. if (memcmp(dst0, dst1, WIDTH*3)
  208. || memcmp( cur0, cur1, WIDTH*11))
  209. fail();
  210. bench_new(dst1 + stride,
  211. cur0 + stride * 4, WIDTH,
  212. stride, -stride, stride * 3, -stride * 3,
  213. 0, mask);
  214. report("bwdif8.intra");
  215. }
  216. }