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  uint8_t *blk1 /* align width (8 or 16) */,
56  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(me_pre_cmp) \
98  XX(me_cmp) \
99  XX(me_sub_cmp) \
100  XX(mb_cmp) \
101  XX(ildct_cmp) \
102  XX(frame_skip_cmp) \
103  XX(median_sad)
104 
105 // tests for functions not yet implemented
106 #if 0
107  XX(dct_sad) \
108  XX(quant_psnr) \
109  XX(bit) \
110  XX(rd) \
111  XX(w53) \
112  XX(w97) \
113  XX(dct_max) \
114  XX(dct264_sad) \
115 
116 #endif
117 
118 static void check_motion(void)
119 {
120  char buf[64];
121  /* Setup AVCodecContext in a way that does not pull in all of libavcodec */
123  MECmpContext me_ctx;
124 
125  memset(&me_ctx, 0, sizeof(me_ctx));
126 
127 
128  ff_me_cmp_init(&me_ctx, &av_ctx);
129 
130  for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.pix_abs); i++) {
131  for (int j = 0; j < FF_ARRAY_ELEMS(me_ctx.pix_abs[0]); j++) {
132  snprintf(buf, sizeof(buf), "pix_abs_%d_%d", i, j);
133  test_motion(buf, me_ctx.pix_abs[i][j]);
134  }
135  }
136 
137 #define XX(me_cmp_array) \
138  for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.me_cmp_array); i++) { \
139  snprintf(buf, sizeof(buf), #me_cmp_array "_%d", i); \
140  test_motion(buf, me_ctx.me_cmp_array[i]); \
141  }
143 #undef XX
144 }
145 
147 {
148  check_motion();
149  report("motion");
150 }
declare_func_emms
#define declare_func_emms(cpu_flags, ret,...)
Definition: checkasm.h:176
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:170
call_ref
#define call_ref(...)
Definition: checkasm.h:185
bit
#define bit(string, value)
Definition: cbs_mpeg2.c:56
checkasm_check_motion
void checkasm_check_motion(void)
Definition: motion.c:146
fail
#define fail()
Definition: checkasm.h:179
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:1008
rnd
#define rnd()
Definition: checkasm.h:163
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:150
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:455
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:288
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:118
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:80
report
#define report
Definition: checkasm.h:182
HEIGHT
#define HEIGHT
bench_new
#define bench_new(...)
Definition: checkasm.h:358
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:255
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:29
AVCodecContext
main external API structure.
Definition: avcodec.h:445
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:2038
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:67
snprintf
#define snprintf
Definition: snprintf.h:34