llviddsp.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Copyright (c) 2016 Alexandra Hájková
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. */
  20. #include <string.h>
  21. #include "libavutil/common.h"
  22. #include "libavutil/intreadwrite.h"
  23. #include "libavutil/mem.h"
  24. #include "libavcodec/lossless_videodsp.h"
  25. #include "checkasm.h"
  26. #define randomize_buffers(buf, size) \
  27. do { \
  28. int j; \
  29. uint8_t *tmp_buf = (uint8_t *)buf;\
  30. for (j = 0; j < size; j++) \
  31. tmp_buf[j] = rnd() & 0xFF; \
  32. } while (0)
  33. #define init_buffer(a0, a1, type, width)\
  34. if (!a0 || !a1)\
  35. fail();\
  36. randomize_buffers(a0, width * sizeof(type));\
  37. memcpy(a1, a0, width*sizeof(type));\
  38. static void check_add_bytes(LLVidDSPContext *c, int width)
  39. {
  40. uint8_t *dst0 = av_mallocz(width);
  41. uint8_t *dst1 = av_mallocz(width);
  42. uint8_t *src0 = av_calloc(width, sizeof(*src0));
  43. uint8_t *src1 = av_calloc(width, sizeof(*src1));
  44. declare_func(void, uint8_t *dst, uint8_t *src, ptrdiff_t w);
  45. init_buffer(src0, src1, uint8_t, width);
  46. if (!dst0 || !dst1)
  47. fail();
  48. if (check_func(c->add_bytes, "add_bytes")) {
  49. call_ref(dst0, src0, width);
  50. call_new(dst1, src1, width);
  51. if (memcmp(dst0, dst1, width))
  52. fail();
  53. bench_new(dst1, src1, width);
  54. }
  55. av_free(src0);
  56. av_free(src1);
  57. av_free(dst0);
  58. av_free(dst1);
  59. }
  60. static void check_add_median_pred(LLVidDSPContext *c, int width) {
  61. int a0, a1, b0, b1;
  62. uint8_t *dst0 = av_mallocz(width);
  63. uint8_t *dst1 = av_mallocz(width);
  64. uint8_t *src0 = av_calloc(width, sizeof(*src0));
  65. uint8_t *src1 = av_calloc(width, sizeof(*src1));
  66. uint8_t *diff0 = av_calloc(width, sizeof(*diff0));
  67. uint8_t *diff1 = av_calloc(width, sizeof(*diff1));
  68. declare_func(void, uint8_t *dst, const uint8_t *src1,
  69. const uint8_t *diff, ptrdiff_t w,
  70. int *left, int *left_top);
  71. init_buffer(src0, src1, uint8_t, width);
  72. init_buffer(diff0, diff1, uint8_t, width);
  73. a0 = rnd() & 0xFF;
  74. b0 = rnd() & 0xFF;
  75. a1 = a0;
  76. b1 = b0;
  77. if (check_func(c->add_median_pred, "add_median_pred")) {
  78. call_ref(dst0, src0, diff0, width, &a0, &b0);
  79. call_new(dst1, src1, diff1, width, &a1, &b1);
  80. if (memcmp(dst0, dst1, width) || (a0 != a1) || (b0 != b1))
  81. fail();
  82. bench_new(dst1, src1, diff1, width, &a1, &b1);
  83. }
  84. av_free(src0);
  85. av_free(src1);
  86. av_free(diff0);
  87. av_free(diff1);
  88. av_free(dst0);
  89. av_free(dst1);
  90. }
  91. static void check_add_left_pred(LLVidDSPContext *c, int width, int acc, const char * report)
  92. {
  93. int res0, res1;
  94. uint8_t *dst0 = av_mallocz(width);
  95. uint8_t *dst1 = av_mallocz(width);
  96. uint8_t *src0 = av_calloc(width, sizeof(*src0));
  97. uint8_t *src1 = av_calloc(width, sizeof(*src1));
  98. declare_func(int, uint8_t *dst, const uint8_t *src, ptrdiff_t w, int acc);
  99. init_buffer(src0, src1, uint8_t, width);
  100. if (!dst0 || !dst1)
  101. fail();
  102. if (check_func(c->add_left_pred, "%s", report)) {
  103. res0 = call_ref(dst0, src0, width, acc);
  104. res1 = call_new(dst1, src1, width, acc);
  105. if ((res0 & 0xFF) != (res1 & 0xFF)||\
  106. memcmp(dst0, dst1, width))
  107. fail();
  108. bench_new(dst1, src1, width, acc);
  109. }
  110. av_free(src0);
  111. av_free(src1);
  112. av_free(dst0);
  113. av_free(dst1);
  114. }
  115. static void check_add_left_pred_16(LLVidDSPContext *c, unsigned mask, int width, unsigned acc, const char * report)
  116. {
  117. int res0, res1;
  118. uint16_t *dst0 = av_calloc(width, sizeof(*dst0));
  119. uint16_t *dst1 = av_calloc(width, sizeof(*dst1));
  120. uint16_t *src0 = av_calloc(width, sizeof(*src0));
  121. uint16_t *src1 = av_calloc(width, sizeof(*src1));
  122. declare_func(int, uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc);
  123. init_buffer(src0, src1, uint16_t, width);
  124. if (!dst0 || !dst1)
  125. fail();
  126. if (check_func(c->add_left_pred_int16, "%s", report)) {
  127. res0 = call_ref(dst0, src0, mask, width, acc);
  128. res1 = call_new(dst1, src1, mask, width, acc);
  129. if ((res0 &0xFFFF) != (res1 &0xFFFF)||\
  130. memcmp(dst0, dst1, width))
  131. fail();
  132. bench_new(dst1, src1, mask, width, acc);
  133. }
  134. av_free(src0);
  135. av_free(src1);
  136. av_free(dst0);
  137. av_free(dst1);
  138. }
  139. static void check_add_gradient_pred(LLVidDSPContext *c, int w) {
  140. int src_size, stride;
  141. uint8_t *src0, *src1;
  142. declare_func(void, uint8_t *src, const ptrdiff_t stride,
  143. const ptrdiff_t width);
  144. stride = w + 32;
  145. src_size = (stride + 32) * 2; /* dsp need previous line, and ignore the start of the line */
  146. src0 = av_mallocz(src_size);
  147. src1 = av_mallocz(src_size);
  148. init_buffer(src0, src1, uint8_t, src_size);
  149. if (check_func(c->add_gradient_pred, "add_gradient_pred")) {
  150. call_ref(src0 + stride + 32, stride, w);
  151. call_new(src1 + stride + 32, stride, w);
  152. if (memcmp(src0, src1, stride)||/* previous line doesn't change */
  153. memcmp(src0+stride, src1 + stride, w + 32)) {
  154. fail();
  155. }
  156. bench_new(src1 + stride + 32, stride, w);
  157. }
  158. av_free(src0);
  159. av_free(src1);
  160. }
  161. void checkasm_check_llviddsp(void)
  162. {
  163. LLVidDSPContext c;
  164. int width = 16 * av_clip(rnd(), 16, 128);
  165. int accRnd = rnd() & 0xFF;
  166. ff_llviddsp_init(&c);
  167. check_add_bytes(&c, width);
  168. report("add_bytes");
  169. check_add_median_pred(&c, width);
  170. report("add_median_pred");
  171. check_add_left_pred(&c, width, 0, "add_left_pred_zero");
  172. report("add_left_pred_zero");
  173. check_add_left_pred(&c, width, accRnd, "add_left_pred_rnd_acc");
  174. report("add_left_pred_rnd_acc");
  175. check_add_left_pred_16(&c, 255, width, accRnd, "add_left_pred_int16");
  176. report("add_left_pred_int16");
  177. check_add_gradient_pred(&c, width);
  178. report("add_gradient_pred");
  179. }