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  AVCodecContext *av_ctx;
122  MECmpContext me_ctx;
123 
124  memset(&me_ctx, 0, sizeof(me_ctx));
125 
126  /* allocate AVCodecContext */
127  av_ctx = avcodec_alloc_context3(NULL);
128  av_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
129 
130  ff_me_cmp_init(&me_ctx, av_ctx);
131 
132  for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.pix_abs); i++) {
133  for (int j = 0; j < FF_ARRAY_ELEMS(me_ctx.pix_abs[0]); j++) {
134  snprintf(buf, sizeof(buf), "pix_abs_%d_%d", i, j);
135  test_motion(buf, me_ctx.pix_abs[i][j]);
136  }
137  }
138 
139 #define XX(me_cmp_array) \
140  for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.me_cmp_array); i++) { \
141  snprintf(buf, sizeof(buf), #me_cmp_array "_%d", i); \
142  test_motion(buf, me_ctx.me_cmp_array[i]); \
143  }
145 #undef XX
146 
147  avcodec_free_context(&av_ctx);
148 }
149 
151 {
152  check_motion();
153  report("motion");
154 }
declare_func_emms
#define declare_func_emms(cpu_flags, ret,...)
Definition: checkasm.h:131
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:125
call_ref
#define call_ref(...)
Definition: checkasm.h:140
bit
#define bit(string, value)
Definition: cbs_mpeg2.c:58
checkasm_check_motion
void checkasm_check_motion(void)
Definition: motion.c:150
fail
#define fail()
Definition: checkasm.h:134
checkasm.h
ff_me_cmp_init
av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp.c:1003
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:506
rnd
#define rnd()
Definition: checkasm.h:118
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
avcodec_alloc_context3
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:153
intreadwrite.h
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:129
img1
static uint8_t img1[WIDTH *HEIGHT]
Definition: motion.c:43
MECmpContext
Definition: me_cmp.h:55
call_new
#define call_new(...)
Definition: checkasm.h:222
NULL
#define NULL
Definition: coverity.c:32
XX
#define XX(me_cmp_array)
avcodec_free_context
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer.
Definition: options.c:168
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
tab
static const uint8_t tab[16]
Definition: rka.c:668
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:44
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:137
HEIGHT
#define HEIGHT
bench_new
#define bench_new(...)
Definition: checkasm.h:287
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
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:426
AV_CODEC_FLAG_BITEXACT
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
Definition: avcodec.h:321
ITERATIONS
#define ITERATIONS
h
h
Definition: vp9dsp_template.c:2038
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:67
snprintf
#define snprintf
Definition: snprintf.h:34