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.

177 lines
5.1KB

  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. type *a0 = av_mallocz_array(width, sizeof(type));\
  35. type *a1 = av_mallocz_array(width, sizeof(type));\
  36. if (!a0 || !a1)\
  37. fail();\
  38. randomize_buffers(a0, width * sizeof(type));\
  39. memcpy(a1, a0, width*sizeof(type));\
  40. static void check_add_bytes(LLVidDSPContext c, int width)
  41. {
  42. uint8_t *dst0 = av_mallocz(width);
  43. uint8_t *dst1 = av_mallocz(width);
  44. init_buffer(src0, src1, uint8_t, width);
  45. if (!dst0 || !dst1)
  46. fail();
  47. declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, ptrdiff_t w);
  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. init_buffer(src0, src1, uint8_t, width);
  65. init_buffer(diff0, diff1, uint8_t, width);
  66. A0 = rnd() & 0xFF;
  67. B0 = rnd() & 0xFF;
  68. A1 = A0;
  69. B1 = B0;
  70. declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const uint8_t *src1,
  71. const uint8_t *diff, ptrdiff_t w,
  72. int *left, int *left_top);
  73. if (check_func(c.add_median_pred, "add_median_pred")) {
  74. call_ref(dst0, src0, diff0, width, &A0, &B0);
  75. call_new(dst1, src1, diff1, width, &A1, &B1);
  76. if (memcmp(dst0, dst1, width) || (A0 != A1) || (B0 != B1))
  77. fail();
  78. bench_new(dst1, src1, diff1, width, &A1, &B1);
  79. }
  80. av_free(src0);
  81. av_free(src1);
  82. av_free(diff0);
  83. av_free(diff1);
  84. av_free(dst0);
  85. av_free(dst1);
  86. }
  87. static void check_add_left_pred(LLVidDSPContext c, int width, int acc, const char * report)
  88. {
  89. uint8_t *dst0 = av_mallocz(width);
  90. uint8_t *dst1 = av_mallocz(width);
  91. init_buffer(src0, src1, uint8_t, width);
  92. if (!dst0 || !dst1)
  93. fail();
  94. declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, ptrdiff_t w, int acc);
  95. if (check_func(c.add_left_pred, "%s", report)) {
  96. call_ref(dst0, src0, width, acc);
  97. call_new(dst1, src1, width, acc);
  98. if (memcmp(dst0, dst1, width))
  99. fail();
  100. bench_new(dst1, src1, width, acc);
  101. }
  102. av_free(src0);
  103. av_free(src1);
  104. av_free(dst0);
  105. av_free(dst1);
  106. }
  107. static void check_add_left_pred_16(LLVidDSPContext c, unsigned mask, int width, unsigned acc, const char * report)
  108. {
  109. uint16_t *dst0 = av_mallocz_array(width, sizeof(uint16_t));
  110. uint16_t *dst1 = av_mallocz_array(width, sizeof(uint16_t));
  111. init_buffer(src0, src1, uint16_t, width);
  112. if (!dst0 || !dst1)
  113. fail();
  114. declare_func_emms(AV_CPU_FLAG_MMX, void, uint16_t *dst, uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc);
  115. if (check_func(c.add_left_pred_int16, "%s", report)) {
  116. call_ref(dst0, src0, mask, width, acc);
  117. call_new(dst1, src1, mask, width, acc);
  118. if (memcmp(dst0, dst1, width))
  119. fail();
  120. bench_new(dst1, src1, mask, width, acc);
  121. }
  122. av_free(src0);
  123. av_free(src1);
  124. av_free(dst0);
  125. av_free(dst1);
  126. }
  127. void checkasm_check_llviddsp(void)
  128. {
  129. LLVidDSPContext c;
  130. int width = 16 * av_clip(rnd(), 16, 128);
  131. int accRnd = rnd() & 0xFF;
  132. ff_llviddsp_init(&c);
  133. check_add_bytes(c, width);
  134. report("add_bytes");
  135. check_add_median_pred(c, width);
  136. report("add_median_pred");
  137. check_add_left_pred(c, width, 0, "add_left_pred_zero");
  138. report("add_left_pred_zero");
  139. check_add_left_pred(c, width, accRnd, "add_left_pred_rnd_acc");
  140. report("add_left_pred_rnd_acc");
  141. check_add_left_pred_16(c, 255, width, accRnd, "add_left_pred_int16");
  142. report("add_left_pred_int16");
  143. }