FFmpeg
mpegvideoencdsp.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 "libavutil/intreadwrite.h"
20 #include "libavutil/mem.h"
21 #include "libavutil/mem_internal.h"
22 
24 
25 #include "checkasm.h"
26 
27 #define randomize_buffers(buf, size) \
28  do { \
29  for (int j = 0; j < size; j += 4) \
30  AV_WN32(buf + j, rnd()); \
31  } while (0)
32 
34 {
35  LOCAL_ALIGNED_16(uint8_t, src, [16 * 16]);
36 
37  declare_func(int, const uint8_t *pix, ptrdiff_t line_size);
38 
39  randomize_buffers(src, 16 * 16);
40 
41  for (int n = 0; n < 2; n++) {
42  const char *negstride_str = n ? "_negstride" : "";
43  if (check_func(c->pix_sum, "pix_sum%s", negstride_str)) {
44  int sum0, sum1;
45  const uint8_t *pix = src + (n ? (15 * 16) : 0);
46  ptrdiff_t line_size = 16 * (n ? -1 : 1);
47  sum0 = call_ref(pix, line_size);
48  sum1 = call_new(pix, line_size);
49  if (sum0 != sum1)
50  fail();
51  bench_new(pix, line_size);
52  }
53  }
54 }
55 
57 {
58  LOCAL_ALIGNED_16(uint8_t, src, [16 * 16]);
59 
60  declare_func(int, const uint8_t *pix, ptrdiff_t line_size);
61 
62  randomize_buffers(src, 16 * 16);
63 
64  for (int n = 0; n < 2; n++) {
65  const char *negstride_str = n ? "_negstride" : "";
66  if (check_func(c->pix_norm1, "pix_norm1%s", negstride_str)) {
67  int sum0, sum1;
68  const uint8_t *pix = src + (n ? (15 * 16) : 0);
69  ptrdiff_t line_size = 16 * (n ? -1 : 1);
70  sum0 = call_ref(pix, line_size);
71  sum1 = call_new(pix, line_size);
72  if (sum0 != sum1)
73  fail();
74  bench_new(pix, line_size);
75  }
76  }
77 }
78 
79 #define NUM_LINES 4
80 #define MAX_LINE_SIZE 1920
81 #define EDGE_WIDTH 16
82 #define LINESIZE (EDGE_WIDTH + MAX_LINE_SIZE + EDGE_WIDTH)
83 #define BUFSIZE ((EDGE_WIDTH + NUM_LINES + EDGE_WIDTH) * LINESIZE)
84 
86 {
87  static const int input_sizes[] = {8, 128, 1080, MAX_LINE_SIZE, -MAX_LINE_SIZE};
88  LOCAL_ALIGNED_16(uint8_t, buf0, [BUFSIZE]);
89  LOCAL_ALIGNED_16(uint8_t, buf1, [BUFSIZE]);
90 
91  declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *buf, ptrdiff_t wrap, int width, int height,
92  int w, int h, int sides);
93 
94  for (int isi = 0; isi < FF_ARRAY_ELEMS(input_sizes); isi++) {
95  int input_size = input_sizes[isi];
96  int negstride = input_size < 0;
97  const char *negstride_str = negstride ? "_negstride" : "";
98  int width = FFABS(input_size);
99  ptrdiff_t linesize = EDGE_WIDTH + width + EDGE_WIDTH;
100  /* calculate height based on specified width to use the entire buffer. */
101  int height = (BUFSIZE / linesize) - (2 * EDGE_WIDTH);
102  uint8_t *dst0 = buf0 + EDGE_WIDTH * linesize + EDGE_WIDTH;
103  uint8_t *dst1 = buf1 + EDGE_WIDTH * linesize + EDGE_WIDTH;
104 
105  if (negstride) {
106  dst0 += (height - 1) * linesize;
107  dst1 += (height - 1) * linesize;
108  linesize *= -1;
109  }
110 
111  for (int shift = 0; shift < 3; shift++) {
112  int edge = EDGE_WIDTH >> shift;
113  if (check_func(c->draw_edges, "draw_edges_%d_%d_%d%s", width, height, edge, negstride_str)) {
114  randomize_buffers(buf0, BUFSIZE);
115  memcpy(buf1, buf0, BUFSIZE);
116  call_ref(dst0, linesize, width, height, edge, edge, EDGE_BOTTOM | EDGE_TOP);
117  call_new(dst1, linesize, width, height, edge, edge, EDGE_BOTTOM | EDGE_TOP);
118  if (memcmp(buf0, buf1, BUFSIZE))
119  fail();
120  bench_new(dst1, linesize, width, height, edge, edge, EDGE_BOTTOM | EDGE_TOP);
121  }
122  }
123  }
124 }
125 
126 #undef NUM_LINES
127 #undef MAX_LINE_SIZE
128 #undef EDGE_WIDTH
129 #undef LINESIZE
130 #undef BUFSIZE
131 
133 {
134  AVCodecContext avctx = {
135  .bits_per_raw_sample = 8,
136  };
137  MpegvideoEncDSPContext c = { 0 };
138 
139  ff_mpegvideoencdsp_init(&c, &avctx);
140 
141  check_pix_sum(&c);
142  report("pix_sum");
143  check_pix_norm1(&c);
144  report("pix_norm1");
146  report("draw_edges");
147 }
declare_func_emms
#define declare_func_emms(cpu_flags, ret,...)
Definition: checkasm.h:190
mem_internal.h
EDGE_BOTTOM
#define EDGE_BOTTOM
Definition: mpegvideoencdsp.h:30
w
uint8_t w
Definition: llviddspenc.c:38
check_func
#define check_func(func,...)
Definition: checkasm.h:184
call_ref
#define call_ref(...)
Definition: checkasm.h:199
checkasm_check_mpegvideoencdsp
void checkasm_check_mpegvideoencdsp(void)
Definition: mpegvideoencdsp.c:132
check_pix_norm1
static void check_pix_norm1(MpegvideoEncDSPContext *c)
Definition: mpegvideoencdsp.c:56
fail
#define fail()
Definition: checkasm.h:193
wrap
#define wrap(func)
Definition: neontest.h:65
checkasm.h
check_pix_sum
static void check_pix_sum(MpegvideoEncDSPContext *c)
Definition: mpegvideoencdsp.c:33
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
intreadwrite.h
MAX_LINE_SIZE
#define MAX_LINE_SIZE
Definition: mpegvideoencdsp.c:80
input_sizes
static const int input_sizes[]
Definition: sw_rgb.c:347
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:130
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1593
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
call_new
#define call_new(...)
Definition: checkasm.h:302
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
height
#define height
Definition: dsp.h:85
shift
static int shift(int a, int b)
Definition: bonk.c:261
MpegvideoEncDSPContext
Definition: mpegvideoencdsp.h:32
report
#define report
Definition: checkasm.h:196
bench_new
#define bench_new(...)
Definition: checkasm.h:373
BUFSIZE
#define BUFSIZE
Definition: mpegvideoencdsp.c:83
EDGE_WIDTH
#define EDGE_WIDTH
Definition: mpegvideoencdsp.c:81
randomize_buffers
#define randomize_buffers(buf, size)
Definition: mpegvideoencdsp.c:27
AV_CPU_FLAG_MMX
#define AV_CPU_FLAG_MMX
standard MMX
Definition: cpu.h:30
AVCodecContext
main external API structure.
Definition: avcodec.h:451
EDGE_TOP
#define EDGE_TOP
Definition: mpegvideoencdsp.h:29
mpegvideoencdsp.h
mem.h
declare_func
#define declare_func(ret,...)
Definition: checkasm.h:188
ff_mpegvideoencdsp_init
av_cold void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c, AVCodecContext *avctx)
Definition: mpegvideoencdsp.c:253
check_draw_edges
static void check_draw_edges(MpegvideoEncDSPContext *c)
Definition: mpegvideoencdsp.c:85
h
h
Definition: vp9dsp_template.c:2070
width
#define width
Definition: dsp.h:85
src
#define src
Definition: vp8dsp.c:248