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, 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 
72  ptr = img2 + y * WIDTH + x;
73  d2 = call_ref(NULL, img1, ptr, WIDTH, 8);
74  d1 = call_new(NULL, img1, ptr, WIDTH, 8);
75 
76  if (d1 != d2) {
77  fail();
78  printf("func: %s, x=%d y=%d, error: asm=%d c=%d\n", name, x, y, d1, d2);
79  break;
80  }
81  }
82  // benchmark with the final value of ptr
83  bench_new(NULL, img1, ptr, WIDTH, 8);
84  }
85 }
86 
87 #define ME_CMP_1D_ARRAYS(XX) \
88  XX(sad) \
89  XX(sse) \
90  XX(hadamard8_diff) \
91  XX(vsad) \
92  XX(vsse) \
93  XX(nsse) \
94  XX(me_pre_cmp) \
95  XX(me_cmp) \
96  XX(me_sub_cmp) \
97  XX(mb_cmp) \
98  XX(ildct_cmp) \
99  XX(frame_skip_cmp) \
100  XX(median_sad)
101 
102 // tests for functions not yet implemented
103 #if 0
104  XX(dct_sad) \
105  XX(quant_psnr) \
106  XX(bit) \
107  XX(rd) \
108  XX(w53) \
109  XX(w97) \
110  XX(dct_max) \
111  XX(dct264_sad) \
112 
113 #endif
114 
115 static void check_motion(void)
116 {
117  char buf[64];
118  AVCodecContext *av_ctx;
119  MECmpContext me_ctx;
120 
121  memset(&me_ctx, 0, sizeof(me_ctx));
122 
123  /* allocate AVCodecContext */
124  av_ctx = avcodec_alloc_context3(NULL);
125  av_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
126 
127  ff_me_cmp_init(&me_ctx, av_ctx);
128 
129  for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.pix_abs); i++) {
130  for (int j = 0; j < FF_ARRAY_ELEMS(me_ctx.pix_abs[0]); j++) {
131  snprintf(buf, sizeof(buf), "pix_abs_%d_%d", i, j);
132  test_motion(buf, me_ctx.pix_abs[i][j]);
133  }
134  }
135 
136 #define XX(me_cmp_array) \
137  for (int i = 0; i < FF_ARRAY_ELEMS(me_ctx.me_cmp_array); i++) { \
138  snprintf(buf, sizeof(buf), #me_cmp_array "_%d", i); \
139  test_motion(buf, me_ctx.me_cmp_array[i]); \
140  }
142 #undef XX
143 
144  avcodec_free_context(&av_ctx);
145 }
146 
148 {
149  check_motion();
150  report("motion");
151 }
declare_func_emms
#define declare_func_emms(cpu_flags, ret,...)
Definition: checkasm.h:128
ME_CMP_1D_ARRAYS
#define ME_CMP_1D_ARRAYS(XX)
Definition: motion.c:87
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:122
call_ref
#define call_ref(...)
Definition: checkasm.h:137
bit
#define bit(string, value)
Definition: cbs_mpeg2.c:58
checkasm_check_motion
void checkasm_check_motion(void)
Definition: motion.c:147
fail
#define fail()
Definition: checkasm.h:131
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:1016
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:469
rnd
#define rnd()
Definition: checkasm.h:115
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:149
intreadwrite.h
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:130
img1
static uint8_t img1[WIDTH *HEIGHT]
Definition: motion.c:43
MECmpContext
Definition: me_cmp.h:53
call_new
#define call_new(...)
Definition: checkasm.h:209
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:164
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:115
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:78
report
#define report
Definition: checkasm.h:134
HEIGHT
#define HEIGHT
bench_new
#define bench_new(...)
Definition: checkasm.h:272
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.h
AV_CPU_FLAG_MMX
#define AV_CPU_FLAG_MMX
standard MMX
Definition: cpu.h:29
AVCodecContext
main external API structure.
Definition: avcodec.h:389
AV_CODEC_FLAG_BITEXACT
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
Definition: avcodec.h:278
me_cmp_func
int(* me_cmp_func)(struct MpegEncContext *c, uint8_t *blk1, uint8_t *blk2, ptrdiff_t stride, int h)
Definition: me_cmp.h:48
ITERATIONS
#define ITERATIONS
h
h
Definition: vp9dsp_template.c:2038
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:62
snprintf
#define snprintf
Definition: snprintf.h:34