FFmpeg
snowdsp.c
Go to the documentation of this file.
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 
19 #include <assert.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <string.h>
23 
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/macros.h"
26 #include "libavutil/mem_internal.h"
27 
28 #include "libavcodec/snow.h"
29 #include "libavcodec/snow_dwt.h"
30 
31 #include "checkasm.h"
32 
33 #define randomize_buffer(buf) \
34 do { \
35  for (size_t k = 0; k < (sizeof(buf) & ~3); k += 4) \
36  AV_WN32A((char*)buf + k, rnd()); \
37  for (size_t k = sizeof(buf) & ~3; k < sizeof(buf); ++k) \
38  ((char*)buf)[k] = rnd(); \
39 } while (0)
40 
41 static void checkasm_check_inner_add_yblock(const SnowDWTContext *const snowdsp)
42 {
43  enum {
44  LOG2_MAX_BLOCKSIZE = 4,
45  MAX_BLOCKSIZE = 1 << LOG2_MAX_BLOCKSIZE,
46  LOG2_MIN_BLOCKSIZE = 1,
47  MAX_STRIDE = 256,
48  };
49  declare_func(void, const uint8_t *obmc, const int obmc_stride,
50  uint8_t **block, int b_w, int b_h, int src_x,
51  int src_stride, IDWTELEM * const *lines,
52  int add, uint8_t *dst8);
53  DECLARE_ALIGNED(16, uint8_t, dst8_ref)[MAX_STRIDE * MAX_BLOCKSIZE];
54  DECLARE_ALIGNED(16, uint8_t, dst8_new)[MAX_STRIDE * MAX_BLOCKSIZE];
55  DECLARE_ALIGNED(16, uint8_t, block)[4][MAX_STRIDE * (MAX_BLOCKSIZE - 1) + MAX_BLOCKSIZE];
57  int inited = 0;
58 
59  for (int i = 0; i < 2; ++i) {
60  for (int j = LOG2_MIN_BLOCKSIZE; j <= LOG2_MAX_BLOCKSIZE; ++j) {
61  int b_w = 1 << j;
62 
63  if (!check_func(snowdsp->inner_add_yblock, "inner_add_yblock_%d%s", b_w, i ? "_border" : ""))
64  continue;
65 
66  const uint8_t *obmc = ff_obmc_tab[LOG2_MAX_BLOCKSIZE - j];
67  int obmc_stride = 2 << j;
68  int b_h = b_w, mb_x;
69  int width = 1 + rnd() % MAX_STRIDE;
70 
71  if (!i) {
72  // Test the ordinary case of a complete block.
73  width = FFMAX(width, 2 * b_w);
74  int nb_complete_blocks = (width - b_w / 2) / b_w;
75  mb_x = 1 + rnd() % nb_complete_blocks;
76  } else {
77  // Test a boundary block. If width == b_w/2 mod b_w,
78  // there is no right boundary block, so use the left one.
79  mb_x = (width + b_w/2) % b_w && rnd() & 1 ? (width + b_w/2) / b_w : 0;
80  }
81  ptrdiff_t src_stride = FFALIGN(width + rnd() % (MAX_STRIDE - width + 1), 16);
82  int src_x = b_w*mb_x - b_w/2;
83 
84  if (src_x < 0) {
85  obmc -= src_x;
86  b_w += src_x;
87  src_x = 0;
88  }
89  if (src_x + b_w > width) {
90  b_w = width - src_x;
91  }
92 
93  uint8_t *dst8p_ref = dst8_ref + src_x;
94  uint8_t *dst8p_new = dst8_new + src_x;
95  unsigned rand = rnd();
96  uint8_t *blocks[4] = { block[rand % 4], block[rand / 4 % 4],
97  block[rand / 16 % 4], block[rand / 64 % 4] };
98  if (rnd() & 1) { // negate stride
99  dst8p_ref += (b_h - 1) * src_stride;
100  dst8p_new += (b_h - 1) * src_stride;
101  blocks[0] += (b_h - 1) * src_stride;
102  blocks[1] += (b_h - 1) * src_stride;
103  blocks[2] += (b_h - 1) * src_stride;
104  blocks[3] += (b_h - 1) * src_stride;
105  src_stride = -src_stride;
106  }
107  IDWTELEM *lines[MAX_BLOCKSIZE];
108 
109  for (int k = 0; k < b_h; ++k)
110  lines[k] = linebuf[rnd() % MAX_BLOCKSIZE];
111 
112  if (!inited) {
113  inited = 1;
115  randomize_buffer(dst8_ref);
116  for (size_t k = 0; k < FF_ARRAY_ELEMS(linebuf); ++k) {
117  for (size_t l = 0; l < FF_ARRAY_ELEMS(linebuf[0]); ++l)
118  linebuf[k][l] = sign_extend(rnd(), 15);
119  }
120  }
121 
122  memcpy(dst8_new, dst8_ref, sizeof(dst8_new));
123 
124  call_ref(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, lines, 1, dst8p_ref);
125  call_new(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, lines, 1, dst8p_new);
126 
127  if (memcmp(dst8_ref, dst8_new, sizeof(dst8_new)))
128  fail();
129 
130  bench_new(obmc, obmc_stride, blocks, b_w, b_h, src_x, src_stride, lines, 1, dst8p_new);
131  }
132  }
133  report("inner_add_yblock");
134 }
135 
137 {
138  SnowDWTContext snowdsp;
139 
140  ff_dwt_init(&snowdsp);
141 
143 }
mem_internal.h
check_func
#define check_func(func,...)
Definition: checkasm.h:214
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
SnowDWTContext
Definition: snow_dwt.h:56
call_ref
#define call_ref(...)
Definition: checkasm.h:230
SnowDWTContext::inner_add_yblock
void(* inner_add_yblock)(const uint8_t *obmc, const int obmc_stride, uint8_t **block, int b_w, int b_h, int src_x, int src_stride, IDWTELEM *const *lines, int add, uint8_t *dst8)
Definition: snow_dwt.h:61
macros.h
fail
#define fail()
Definition: checkasm.h:224
checkasm.h
ff_dwt_init
av_cold void ff_dwt_init(SnowDWTContext *c)
Definition: snow_dwt.c:851
rnd
#define rnd()
Definition: checkasm.h:207
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
intreadwrite.h
call_new
#define call_new(...)
Definition: checkasm.h:238
snow.h
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem_internal.h:104
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
snow_dwt.h
ff_obmc_tab
const uint8_t *const ff_obmc_tab[4]
Definition: snowdata.h:124
report
#define report
Definition: checkasm.h:227
bench_new
#define bench_new(...)
Definition: checkasm.h:429
MAX_BLOCKSIZE
#define MAX_BLOCKSIZE
Definition: diracdec.c:56
randomize_buffer
#define randomize_buffer(buf)
Definition: snowdsp.c:33
checkasm_check_inner_add_yblock
static void checkasm_check_inner_add_yblock(const SnowDWTContext *const snowdsp)
Definition: snowdsp.c:41
MAX_STRIDE
#define MAX_STRIDE
Definition: hpeldsp.c:31
sign_extend
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:135
checkasm_check_snowdsp
void checkasm_check_snowdsp(void)
Definition: snowdsp.c:136
declare_func
#define declare_func(ret,...)
Definition: checkasm.h:219
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
IDWTELEM
short IDWTELEM
Definition: dirac_dwt.h:27
width
#define width
Definition: dsp.h:89