You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
5.6KB

  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_mallocz_array(width, sizeof(uint8_t));
  43. uint8_t *src1 = av_mallocz_array(width, sizeof(uint8_t));
  44. declare_func_emms(AV_CPU_FLAG_MMX, 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_mallocz_array(width, sizeof(uint8_t));
  65. uint8_t *src1 = av_mallocz_array(width, sizeof(uint8_t));
  66. uint8_t *diff0 = av_mallocz_array(width, sizeof(uint8_t));
  67. uint8_t *diff1 = av_mallocz_array(width, sizeof(uint8_t));
  68. declare_func_emms(AV_CPU_FLAG_MMX, 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. uint8_t *dst0 = av_mallocz(width);
  94. uint8_t *dst1 = av_mallocz(width);
  95. uint8_t *src0 = av_mallocz_array(width, sizeof(uint8_t));
  96. uint8_t *src1 = av_mallocz_array(width, sizeof(uint8_t));
  97. declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, ptrdiff_t w, int acc);
  98. init_buffer(src0, src1, uint8_t, width);
  99. if (!dst0 || !dst1)
  100. fail();
  101. if (check_func(c.add_left_pred, "%s", report)) {
  102. call_ref(dst0, src0, width, acc);
  103. call_new(dst1, src1, width, acc);
  104. if (memcmp(dst0, dst1, width))
  105. fail();
  106. bench_new(dst1, src1, width, acc);
  107. }
  108. av_free(src0);
  109. av_free(src1);
  110. av_free(dst0);
  111. av_free(dst1);
  112. }
  113. static void check_add_left_pred_16(LLVidDSPContext c, unsigned mask, int width, unsigned acc, const char * report)
  114. {
  115. uint16_t *dst0 = av_mallocz_array(width, sizeof(uint16_t));
  116. uint16_t *dst1 = av_mallocz_array(width, sizeof(uint16_t));
  117. uint16_t *src0 = av_mallocz_array(width, sizeof(uint16_t));
  118. uint16_t *src1 = av_mallocz_array(width, sizeof(uint16_t));
  119. declare_func_emms(AV_CPU_FLAG_MMX, void, uint16_t *dst, uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc);
  120. init_buffer(src0, src1, uint16_t, width);
  121. if (!dst0 || !dst1)
  122. fail();
  123. if (check_func(c.add_left_pred_int16, "%s", report)) {
  124. call_ref(dst0, src0, mask, width, acc);
  125. call_new(dst1, src1, mask, width, acc);
  126. if (memcmp(dst0, dst1, width))
  127. fail();
  128. bench_new(dst1, src1, mask, width, acc);
  129. }
  130. av_free(src0);
  131. av_free(src1);
  132. av_free(dst0);
  133. av_free(dst1);
  134. }
  135. void checkasm_check_llviddsp(void)
  136. {
  137. LLVidDSPContext c;
  138. int width = 16 * av_clip(rnd(), 16, 128);
  139. int accRnd = rnd() & 0xFF;
  140. ff_llviddsp_init(&c);
  141. check_add_bytes(c, width);
  142. report("add_bytes");
  143. check_add_median_pred(c, width);
  144. report("add_median_pred");
  145. check_add_left_pred(c, width, 0, "add_left_pred_zero");
  146. report("add_left_pred_zero");
  147. check_add_left_pred(c, width, accRnd, "add_left_pred_rnd_acc");
  148. report("add_left_pred_rnd_acc");
  149. check_add_left_pred_16(c, 255, width, accRnd, "add_left_pred_int16");
  150. report("add_left_pred_int16");
  151. }