FFmpeg  4.0
llviddsp.c
Go to the documentation of this file.
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 
21 #include <string.h>
22 
23 #include "libavutil/common.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/mem.h"
26 
28 
29 #include "checkasm.h"
30 
31 #define randomize_buffers(buf, size) \
32  do { \
33  int j; \
34  uint8_t *tmp_buf = (uint8_t *)buf;\
35  for (j = 0; j < size; j++) \
36  tmp_buf[j] = rnd() & 0xFF; \
37  } while (0)
38 
39 #define init_buffer(a0, a1, type, width)\
40  if (!a0 || !a1)\
41  fail();\
42  randomize_buffers(a0, width * sizeof(type));\
43  memcpy(a1, a0, width*sizeof(type));\
44 
46 {
47  uint8_t *dst0 = av_mallocz(width);
48  uint8_t *dst1 = av_mallocz(width);
49  uint8_t *src0 = av_mallocz_array(width, sizeof(uint8_t));
50  uint8_t *src1 = av_mallocz_array(width, sizeof(uint8_t));
51  declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, ptrdiff_t w);
52 
53  init_buffer(src0, src1, uint8_t, width);
54 
55  if (!dst0 || !dst1)
56  fail();
57 
58 
59  if (check_func(c.add_bytes, "add_bytes")) {
60  call_ref(dst0, src0, width);
61  call_new(dst1, src1, width);
62  if (memcmp(dst0, dst1, width))
63  fail();
64  bench_new(dst1, src1, width);
65  }
66 
67  av_free(src0);
68  av_free(src1);
69  av_free(dst0);
70  av_free(dst1);
71 }
72 
74  int A0, A1, B0, B1;
75  uint8_t *dst0 = av_mallocz(width);
76  uint8_t *dst1 = av_mallocz(width);
77  uint8_t *src0 = av_mallocz_array(width, sizeof(uint8_t));
78  uint8_t *src1 = av_mallocz_array(width, sizeof(uint8_t));
79  uint8_t *diff0 = av_mallocz_array(width, sizeof(uint8_t));
80  uint8_t *diff1 = av_mallocz_array(width, sizeof(uint8_t));
81  declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const uint8_t *src1,
82  const uint8_t *diff, ptrdiff_t w,
83  int *left, int *left_top);
84 
85  init_buffer(src0, src1, uint8_t, width);
86  init_buffer(diff0, diff1, uint8_t, width);
87 
88  A0 = rnd() & 0xFF;
89  B0 = rnd() & 0xFF;
90  A1 = A0;
91  B1 = B0;
92 
93 
94  if (check_func(c.add_median_pred, "add_median_pred")) {
95  call_ref(dst0, src0, diff0, width, &A0, &B0);
96  call_new(dst1, src1, diff1, width, &A1, &B1);
97  if (memcmp(dst0, dst1, width) || (A0 != A1) || (B0 != B1))
98  fail();
99  bench_new(dst1, src1, diff1, width, &A1, &B1);
100  }
101 
102  av_free(src0);
103  av_free(src1);
104  av_free(diff0);
105  av_free(diff1);
106  av_free(dst0);
107  av_free(dst1);
108 }
109 
110 static void check_add_left_pred(LLVidDSPContext c, int width, int acc, const char * report)
111 {
112  int res0, res1;
113  uint8_t *dst0 = av_mallocz(width);
114  uint8_t *dst1 = av_mallocz(width);
115  uint8_t *src0 = av_mallocz_array(width, sizeof(uint8_t));
116  uint8_t *src1 = av_mallocz_array(width, sizeof(uint8_t));
117  declare_func_emms(AV_CPU_FLAG_MMX, int, uint8_t *dst, uint8_t *src, ptrdiff_t w, int acc);
118 
119  init_buffer(src0, src1, uint8_t, width);
120 
121  if (!dst0 || !dst1)
122  fail();
123 
124  if (check_func(c.add_left_pred, "%s", report)) {
125  res0 = call_ref(dst0, src0, width, acc);
126  res1 = call_new(dst1, src1, width, acc);
127  if ((res0 & 0xFF) != (res1 & 0xFF)||\
128  memcmp(dst0, dst1, width))
129  fail();
130  bench_new(dst1, src1, width, acc);
131  }
132 
133  av_free(src0);
134  av_free(src1);
135  av_free(dst0);
136  av_free(dst1);
137 }
138 
139 static void check_add_left_pred_16(LLVidDSPContext c, unsigned mask, int width, unsigned acc, const char * report)
140 {
141  int res0, res1;
142  uint16_t *dst0 = av_mallocz_array(width, sizeof(uint16_t));
143  uint16_t *dst1 = av_mallocz_array(width, sizeof(uint16_t));
144  uint16_t *src0 = av_mallocz_array(width, sizeof(uint16_t));
145  uint16_t *src1 = av_mallocz_array(width, sizeof(uint16_t));
146  declare_func_emms(AV_CPU_FLAG_MMX, int, uint16_t *dst, uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc);
147 
148  init_buffer(src0, src1, uint16_t, width);
149 
150  if (!dst0 || !dst1)
151  fail();
152 
153  if (check_func(c.add_left_pred_int16, "%s", report)) {
154  res0 = call_ref(dst0, src0, mask, width, acc);
155  res1 = call_new(dst1, src1, mask, width, acc);
156  if ((res0 &0xFFFF) != (res1 &0xFFFF)||\
157  memcmp(dst0, dst1, width))
158  fail();
159  bench_new(dst1, src1, mask, width, acc);
160  }
161 
162  av_free(src0);
163  av_free(src1);
164  av_free(dst0);
165  av_free(dst1);
166 }
167 
169  int src_size, stride;
170  uint8_t *src0, *src1;
171  declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *src, const ptrdiff_t stride,
172  const ptrdiff_t width);
173 
174  stride = w + 32;
175  src_size = (stride + 32) * 2; /* dsp need previous line, and ignore the start of the line */
176  src0 = av_mallocz(src_size);
177  src1 = av_mallocz(src_size);
178 
179  init_buffer(src0, src1, uint8_t, src_size);
180 
181  if (check_func(c.add_gradient_pred, "add_gradient_pred")) {
182  call_ref(src0 + stride + 32, stride, w);
183  call_new(src1 + stride + 32, stride, w);
184  if (memcmp(src0, src1, stride)||/* previous line doesn't change */
185  memcmp(src0+stride, src1 + stride, w + 32)) {
186  fail();
187  }
188  bench_new(src1 + stride + 32, stride, w);
189  }
190 
191  av_free(src0);
192  av_free(src1);
193 }
194 
196 {
198  int width = 16 * av_clip(rnd(), 16, 128);
199  int accRnd = rnd() & 0xFF;
200 
201  ff_llviddsp_init(&c);
202 
203  check_add_bytes(c, width);
204  report("add_bytes");
205 
206  check_add_median_pred(c, width);
207  report("add_median_pred");
208 
209  check_add_left_pred(c, width, 0, "add_left_pred_zero");
210  report("add_left_pred_zero");
211 
212  check_add_left_pred(c, width, accRnd, "add_left_pred_rnd_acc");
213  report("add_left_pred_rnd_acc");
214 
215  check_add_left_pred_16(c, 255, width, accRnd, "add_left_pred_int16");
216  report("add_left_pred_int16");
217 
218  check_add_gradient_pred(c, width);
219  report("add_gradient_pred");
220 }
int(* add_left_pred)(uint8_t *dst, const uint8_t *src, ptrdiff_t w, int left)
#define A1
Definition: binkdsp.c:31
Memory handling functions.
int acc
Definition: yuv2rgb.c:554
#define src
Definition: vp8dsp.c:254
int stride
Definition: mace.c:144
#define report
Definition: checkasm.h:119
#define B1
Definition: faandct.c:41
void checkasm_check_llviddsp(void)
Definition: llviddsp.c:195
uint8_t
void(* add_median_pred)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, ptrdiff_t w, int *left, int *left_top)
void(* add_gradient_pred)(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width)
static const uint16_t mask[17]
Definition: lzw.c:38
uint16_t width
Definition: gdv.c:47
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
#define fail()
Definition: checkasm.h:116
uint8_t w
Definition: llviddspenc.c:38
#define declare_func_emms(cpu_flags, ret,...)
Definition: checkasm.h:113
#define call_ref(...)
Definition: checkasm.h:122
int(* add_left_pred_int16)(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned left)
#define src1
Definition: h264pred.c:139
static void check_add_bytes(LLVidDSPContext c, int width)
Definition: llviddsp.c:45
#define AV_CPU_FLAG_MMX
standard MMX
Definition: cpu.h:31
static void check_add_median_pred(LLVidDSPContext c, int width)
Definition: llviddsp.c:73
void ff_llviddsp_init(LLVidDSPContext *c)
#define check_func(func,...)
Definition: checkasm.h:107
#define src0
Definition: h264pred.c:138
common internal and external API header
static double c[64]
#define rnd()
Definition: checkasm.h:100
static void check_add_left_pred_16(LLVidDSPContext c, unsigned mask, int width, unsigned acc, const char *report)
Definition: llviddsp.c:139
static av_always_inline int diff(const uint32_t a, const uint32_t b)
#define av_free(p)
#define bench_new(...)
Definition: checkasm.h:249
#define call_new(...)
Definition: checkasm.h:189
#define init_buffer(a0, a1, type, width)
Definition: llviddsp.c:39
void(* add_bytes)(uint8_t *dst, uint8_t *src, ptrdiff_t w)
static void check_add_left_pred(LLVidDSPContext c, int width, int acc, const char *report)
Definition: llviddsp.c:110
#define B0
Definition: faandct.c:40
static void check_add_gradient_pred(LLVidDSPContext c, int w)
Definition: llviddsp.c:168
void * av_mallocz_array(size_t nmemb, size_t size)
Allocate a memory block for an array with av_mallocz().
Definition: mem.c:191