FFmpeg
motion.c
Go to the documentation of this file.
1 /*
2  *
3  * This file is part of FFmpeg.
4  *
5  * FFmpeg is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * FFmpeg is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include <string.h>
21 
22 #include "libavutil/common.h"
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/mem_internal.h"
25 
26 #include "libavcodec/me_cmp.h"
27 
28 #include "checkasm.h"
29 
30 static void fill_random(uint8_t *tab, int size)
31 {
32  int i;
33  for (i = 0; i < size; i++) {
34  tab[i] = rnd() % 256;
35  }
36 }
37 
38 static void test_motion(const char *name, me_cmp_func test_func)
39 {
40  /* test configurarion */
41 #define ITERATIONS 16
42 #define WIDTH 64
43 #define HEIGHT 64
44 
45  /* motion estimation can look up to 17 bytes ahead */
46  static const int look_ahead = 17;
47 
48  int i, x, y, h, d1, d2;
49  uint8_t *ptr;
50 
51  LOCAL_ALIGNED_16(uint8_t, img1, [WIDTH * HEIGHT]);
52  LOCAL_ALIGNED_16(uint8_t, img2, [WIDTH * HEIGHT]);
53 
55  const uint8_t *blk1 /* align width (8 or 16) */,
56  const uint8_t *blk2 /* align 1 */, ptrdiff_t stride,
57  int h);
58 
59  if (test_func == NULL) {
60  return;
61  }
62 
63  /* test correctness */
66 
67  if (check_func(test_func, "%s", name)) {
68  for (i = 0; i < ITERATIONS; i++) {
69  x = rnd() % (WIDTH - look_ahead);
70  y = rnd() % (HEIGHT - look_ahead);
71  // Pick a random h between 4 and 16; pick an even value.
72  h = 4 + ((rnd() % (16 + 1 - 4)) & ~1);
73 
74  ptr = img2 + y * WIDTH + x;
75  d2 = call_ref(NULL, img1, ptr, WIDTH, h);
76  d1 = call_new(NULL, img1, ptr, WIDTH, h);
77 
78  if (d1 != d2) {
79  fail();
80  printf("func: %s, x=%d y=%d h=%d, error: asm=%d c=%d\n", name, x, y, h, d1, d2);
81  break;
82  }
83  }
84  // Test with a fixed offset, for benchmark stability
85  ptr = img2 + 3 * WIDTH + 3;
86  bench_new(NULL, img1, ptr, WIDTH, 8);
87  }
88 }
89 
90 #define ME_CMP_1D_ARRAYS(XX) \
91  XX(sad) \
92  XX(sse) \
93  XX(hadamard8_diff) \
94  XX(vsad) \
95  XX(vsse) \
96  XX(nsse) \
97  XX(median_sad)
98 
99 // tests for functions not yet implemented
100 #if 0
101  XX(dct_sad) \
102  XX(quant_psnr) \
103  XX(bit) \
104  XX(rd) \
105  XX(w53) \
106  XX(w97) \
107  XX(dct_max) \
108  XX(dct264_sad) \
109 
110 #endif
111 
112 static void check_motion(void)
113 {
114  char buf[64];
115  /* Setup AVCodecContext in a way that does not pull in all of libavcodec */
117  MECmpContext me_ctx;
118 
119  ff_me_cmp_init(&me_ctx, &av_ctx);
120 
121  for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.pix_abs); i++) {
122  for (int j = 0; j < FF_ARRAY_ELEMS(me_ctx.pix_abs[0]); j++) {
123  snprintf(buf, sizeof(buf), "pix_abs_%d_%d", i, j);
124  test_motion(buf, me_ctx.pix_abs[i][j]);
125  }
126  }
127 
128 #define XX(me_cmp_array) \
129  for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.me_cmp_array); i++) { \
130  snprintf(buf, sizeof(buf), #me_cmp_array "_%d", i); \
131  test_motion(buf, me_ctx.me_cmp_array[i]); \
132  }
134 #undef XX
135 }
136 
138 {
139  check_motion();
140  report("motion");
141 }
declare_func_emms
#define declare_func_emms(cpu_flags, ret,...)
Definition: checkasm.h:190
ME_CMP_1D_ARRAYS
#define ME_CMP_1D_ARRAYS(XX)
Definition: motion.c:90
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
mem_internal.h
test_motion
static void test_motion(const char *name, me_cmp_func test_func)
Definition: motion.c:38
check_func
#define check_func(func,...)
Definition: checkasm.h:184
call_ref
#define call_ref(...)
Definition: checkasm.h:199
bit
#define bit(string, value)
Definition: cbs_mpeg2.c:56
checkasm_check_motion
void checkasm_check_motion(void)
Definition: motion.c:137
fail
#define fail()
Definition: checkasm.h:193
tab
static const struct twinvq_data tab
Definition: twinvq_data.h:10345
checkasm.h
ff_me_cmp_init
av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp.c:996
rnd
#define rnd()
Definition: checkasm.h:177
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
intreadwrite.h
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:128
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:461
img1
static uint8_t img1[WIDTH *HEIGHT]
Definition: motion.c:44
MECmpContext
Definition: me_cmp.h:55
call_new
#define call_new(...)
Definition: checkasm.h:302
NULL
#define NULL
Definition: coverity.c:32
XX
#define XX(me_cmp_array)
WIDTH
#define WIDTH
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
check_motion
static void check_motion(void)
Definition: motion.c:112
size
int size
Definition: twinvq_data.h:10344
fill_random
static void fill_random(uint8_t *tab, int size)
Definition: motion.c:30
img2
static uint8_t img2[WIDTH *HEIGHT]
Definition: motion.c:45
printf
printf("static const uint8_t my_array[100] = {\n")
MECmpContext::pix_abs
me_cmp_func pix_abs[2][4]
Definition: me_cmp.h:73
report
#define report
Definition: checkasm.h:196
HEIGHT
#define HEIGHT
bench_new
#define bench_new(...)
Definition: checkasm.h:373
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
common.h
stride
#define stride
Definition: h264pred_template.c:537
me_cmp_func
int(* me_cmp_func)(struct MpegEncContext *c, const uint8_t *blk1, const uint8_t *blk2, ptrdiff_t stride, int h)
Definition: me_cmp.h:50
me_cmp.h
AV_CPU_FLAG_MMX
#define AV_CPU_FLAG_MMX
standard MMX
Definition: cpu.h:30
AVCodecContext
main external API structure.
Definition: avcodec.h:451
AV_CODEC_FLAG_BITEXACT
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
Definition: avcodec.h:342
ITERATIONS
#define ITERATIONS
h
h
Definition: vp9dsp_template.c:2070
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:73
snprintf
#define snprintf
Definition: snprintf.h:34