FFmpeg
pixelutils.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
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <stdio.h>
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/internal.h"
23 #include "libavutil/log.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/pixdesc.h"
26 #include "libavutil/pixelutils.c"
27 #include "libavutil/pixfmt.h"
28 
29 #define W1 320
30 #define H1 240
31 #define W2 640
32 #define H2 480
33 
34 static void check_pixfmt_descriptors(void)
35 {
36  const AVPixFmtDescriptor *d, *last = NULL;
37  int i;
38 
39  for (i = AV_PIX_FMT_NONE, d = NULL; i++, d = av_pix_fmt_desc_next(d);) {
40  uint8_t fill[4][8 + 6 + 3] = {{ 0 }};
41  uint8_t *data[4] = { fill[0], fill[1], fill[2], fill[3] };
42  int linesize[4] = { 0, 0, 0, 0 };
43  uint16_t tmp[2];
44 
45  av_assert0(d->name && d->name[0]);
46  av_log(NULL, AV_LOG_INFO, "Checking: %s\n", d->name);
47  av_assert0(d->log2_chroma_w <= 3);
48  av_assert0(d->log2_chroma_h <= 3);
49  av_assert0(d->nb_components <= 4);
50  av_assert0(d->nb_components || (d->flags & AV_PIX_FMT_FLAG_HWACCEL));
52 
53  /* The following two checks as well as the one after the loop
54  * would need to be changed if we changed the way the descriptors
55  * are stored. */
57  av_assert0(!last || last + 1 == d);
58 
59  for (int j = 0; j < FF_ARRAY_ELEMS(d->comp); j++) {
60  const AVComponentDescriptor *c = &d->comp[j];
61  if (j >= d->nb_components) {
62  av_assert0(!c->plane && !c->step && !c->offset && !c->shift && !c->depth);
63  continue;
64  }
65  if (d->flags & AV_PIX_FMT_FLAG_BITSTREAM) {
66  av_assert0(c->step >= c->depth);
67  } else {
68  av_assert0(8*c->step >= c->depth);
69  }
70  if (d->flags & AV_PIX_FMT_FLAG_BAYER)
71  continue;
72  av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 0);
73  av_assert0(tmp[0] == 0 && tmp[1] == 0);
74  tmp[0] = tmp[1] = (1ULL << c->depth) - 1;
75  av_write_image_line(tmp, data, linesize, d, 0, 0, j, 2);
76  }
77  last = d;
78  }
80 }
81 
82 static int run_single_test(const char *test,
83  const uint8_t *block1, ptrdiff_t stride1,
84  const uint8_t *block2, ptrdiff_t stride2,
85  int align, int n)
86 {
87  int out, ref;
88  av_pixelutils_sad_fn f_ref = sad_c[n - 1];
90 
91  switch (align) {
92  case 0: block1++; block2++; break;
93  case 1: block2++; break;
94  case 2: break;
95  }
96 
97  out = f_out(block1, stride1, block2, stride2);
98  ref = f_ref(block1, stride1, block2, stride2);
99  printf("[%s] [%c%c] SAD [%s] %dx%d=%d ref=%d\n",
100  out == ref ? "OK" : "FAIL",
101  align ? 'A' : 'U', align == 2 ? 'A' : 'U',
102  test, 1<<n, 1<<n, out, ref);
103  return out != ref;
104 }
105 
106 static int run_test(const char *test,
107  const uint8_t *b1, const uint8_t *b2)
108 {
109  int i, a, ret = 0;
110 
111  for (a = 0; a < 3; a++) {
112  const uint8_t *block1 = b1;
113  const uint8_t *block2 = b2;
114 
115  switch (a) {
116  case 0: block1++; block2++; break;
117  case 1: block2++; break;
118  case 2: break;
119  }
120  for (i = 1; i <= FF_ARRAY_ELEMS(sad_c); i++) {
121  int r = run_single_test(test, b1, W1, b2, W2, a, i);
122  if (r)
123  ret = r;
124  }
125  }
126  return ret;
127 }
128 
129 int main(void)
130 {
131  int i, align, ret;
132  uint8_t *buf1 = av_malloc(W1*H1);
133  uint8_t *buf2 = av_malloc(W2*H2);
134  uint32_t state = 0;
135 
136  if (!buf1 || !buf2) {
137  fprintf(stderr, "malloc failure\n");
138  ret = 1;
139  goto end;
140  }
141 
143 
144 #define RANDOM_INIT(buf, size) do { \
145  int k; \
146  for (k = 0; k < size; k++) { \
147  state = state * 1664525 + 1013904223; \
148  buf[k] = state>>24; \
149  } \
150 } while (0)
151 
152  /* Normal test with different strides */
153  RANDOM_INIT(buf1, W1*H1);
154  RANDOM_INIT(buf2, W2*H2);
155  ret = run_test("random", buf1, buf2);
156  if (ret < 0)
157  goto end;
158 
159  /* Check for maximum SAD */
160  memset(buf1, 0xff, W1*H1);
161  memset(buf2, 0x00, W2*H2);
162  ret = run_test("max", buf1, buf2);
163  if (ret < 0)
164  goto end;
165 
166  /* Check for minimum SAD */
167  memset(buf1, 0x90, W1*H1);
168  memset(buf2, 0x90, W2*H2);
169  ret = run_test("min", buf1, buf2);
170  if (ret < 0)
171  goto end;
172 
173  /* Exact buffer sizes, to check for overreads */
174  for (i = 1; i <= 5; i++) {
175  for (align = 0; align < 3; align++) {
176  int size1, size2;
177 
178  av_freep(&buf1);
179  av_freep(&buf2);
180 
181  size1 = size2 = 1 << (i << 1);
182 
183  switch (align) {
184  case 0: size1++; size2++; break;
185  case 1: size2++; break;
186  case 2: break;
187  }
188 
189  buf1 = av_malloc(size1);
190  buf2 = av_malloc(size2);
191  if (!buf1 || !buf2) {
192  fprintf(stderr, "malloc failure\n");
193  ret = 1;
194  goto end;
195  }
196  RANDOM_INIT(buf1, size1);
197  RANDOM_INIT(buf2, size2);
198  ret = run_single_test("small", buf1, 1<<i, buf2, 1<<i, align, i);
199  if (ret < 0)
200  goto end;
201  }
202  }
203 
204 end:
205  av_free(buf1);
206  av_free(buf2);
207  return ret;
208 }
r
const char * r
Definition: vf_curves.c:126
out
FILE * out
Definition: movenc.c:54
av_write_image_line
void av_write_image_line(const uint16_t *src, uint8_t *data[4], const int linesize[4], const AVPixFmtDescriptor *desc, int x, int y, int c, int w)
Definition: pixdesc.c:189
av_pixelutils_sad_fn
int(* av_pixelutils_sad_fn)(const uint8_t *src1, ptrdiff_t stride1, const uint8_t *src2, ptrdiff_t stride2)
Sum of abs(src1[x] - src2[x])
Definition: pixelutils.h:28
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
pixdesc.h
H2
#define H2
Definition: pixelutils.c:32
data
const char data[16]
Definition: mxf.c:148
test
Definition: idctdsp.c:35
av_pix_fmt_desc_next
const AVPixFmtDescriptor * av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev)
Iterate over all pixel format descriptors known to libavutil.
Definition: pixdesc.c:2971
W2
#define W2
Definition: pixelutils.c:31
run_single_test
static int run_single_test(const char *test, const uint8_t *block1, ptrdiff_t stride1, const uint8_t *block2, ptrdiff_t stride2, int align, int n)
Definition: pixelutils.c:82
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AV_PIX_FMT_NB
@ AV_PIX_FMT_NB
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:432
b1
static double b1(void *priv, double x, double y)
Definition: vf_xfade.c:2035
AV_PIX_FMT_FLAG_HWACCEL
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:128
avassert.h
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
NULL
#define NULL
Definition: coverity.c:32
AVComponentDescriptor
Definition: pixdesc.h:30
check_pixfmt_descriptors
static void check_pixfmt_descriptors(void)
Definition: pixelutils.c:34
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
main
int main(void)
Definition: pixelutils.c:129
AV_PIX_FMT_FLAG_BITSTREAM
#define AV_PIX_FMT_FLAG_BITSTREAM
All values of a component are bit-wise packed end to end.
Definition: pixdesc.h:124
printf
printf("static const uint8_t my_array[100] = {\n")
align
static const uint8_t *BS_FUNC() align(BSCTX *bc)
Skip bits to a byte boundary.
Definition: bitstream_template.h:411
b2
static double b2(void *priv, double x, double y)
Definition: vf_xfade.c:2036
block1
static int16_t block1[64]
Definition: dct.c:120
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_pix_fmt_desc_get_id
enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc)
Definition: pixdesc.c:2983
AV_PIX_FMT_FLAG_BAYER
#define AV_PIX_FMT_FLAG_BAYER
The pixel format is following a Bayer pattern.
Definition: pixdesc.h:152
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
internal.h
W1
#define W1
Definition: pixelutils.c:29
ret
ret
Definition: filter_design.txt:187
pixfmt.h
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:2896
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
av_pixelutils_get_sad_fn
av_pixelutils_sad_fn av_pixelutils_get_sad_fn(int w_bits, int h_bits, int aligned, void *log_ctx)
Get a potentially optimized pointer to a Sum-of-absolute-differences function (see the av_pixelutils_...
Definition: pixelutils.c:72
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
state
static struct @362 state
H1
#define H1
Definition: pixelutils.c:30
mem.h
RANDOM_INIT
#define RANDOM_INIT(buf, size)
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_read_image_line
void av_read_image_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4], const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component)
Definition: pixdesc.c:103
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
d
d
Definition: ffmpeg_filter.c:368
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
pixelutils.c
run_test
static int run_test(const char *test, const uint8_t *b1, const uint8_t *b2)
Definition: pixelutils.c:106