FFmpeg
vf_minterpolate.c
Go to the documentation of this file.
1 /**
2  * Copyright (c) 2014-2015 Michael Niedermayer <michaelni@gmx.at>
3  * Copyright (c) 2016 Davinder Singh (DSM_) <ds.mudhar<@gmail.com>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "motion_estimation.h"
23 #include "libavcodec/mathops.h"
24 #include "libavutil/common.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/pixdesc.h"
27 #include "avfilter.h"
28 #include "internal.h"
29 #include "video.h"
30 #include "scene_sad.h"
31 
32 #define ME_MODE_BIDIR 0
33 #define ME_MODE_BILAT 1
34 
35 #define MC_MODE_OBMC 0
36 #define MC_MODE_AOBMC 1
37 
38 #define SCD_METHOD_NONE 0
39 #define SCD_METHOD_FDIFF 1
40 
41 #define NB_FRAMES 4
42 #define NB_PIXEL_MVS 32
43 #define NB_CLUSTERS 128
44 
45 #define ALPHA_MAX 1024
46 #define CLUSTER_THRESHOLD 4
47 #define PX_WEIGHT_MAX 255
48 #define COST_PRED_SCALE 64
49 
50 static const uint8_t obmc_linear32[1024] = {
51  0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
52  0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
53  0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
54  0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
55  4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
56  4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
57  4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
58  4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
59  4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
60  4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
61  4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
62  4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
63  8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
64  8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
65  8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
66  8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
67  8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
68  8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
69  8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
70  8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
71  4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
72  4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
73  4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
74  4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
75  4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
76  4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
77  4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
78  4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
79  0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
80  0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
81  0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
82  0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
83 };
84 
85 static const uint8_t obmc_linear16[256] = {
86  0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
87  4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
88  4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
89  8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
90  8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
91  12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
92  12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
93  16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
94  16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
95  12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
96  12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
97  8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
98  8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
99  4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
100  4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
101  0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
102 };
103 
104 static const uint8_t obmc_linear8[64] = {
105  4, 12, 20, 28, 28, 20, 12, 4,
106  12, 36, 60, 84, 84, 60, 36, 12,
107  20, 60,100,140,140,100, 60, 20,
108  28, 84,140,196,196,140, 84, 28,
109  28, 84,140,196,196,140, 84, 28,
110  20, 60,100,140,140,100, 60, 20,
111  12, 36, 60, 84, 84, 60, 36, 12,
112  4, 12, 20, 28, 28, 20, 12, 4,
113 };
114 
115 static const uint8_t obmc_linear4[16] = {
116  16, 48, 48, 16,
117  48,144,144, 48,
118  48,144,144, 48,
119  16, 48, 48, 16,
120 };
121 
122 static const uint8_t * const obmc_tab_linear[4]= {
124 };
125 
126 enum MIMode {
130 };
131 
132 typedef struct Cluster {
134  int nb;
135 } Cluster;
136 
137 typedef struct Block {
138  int16_t mvs[2][2];
139  int cid;
140  uint64_t sbad;
141  int sb;
142  struct Block *subs;
143 } Block;
144 
145 typedef struct PixelMVS {
146  int16_t mvs[NB_PIXEL_MVS][2];
147 } PixelMVS;
148 
149 typedef struct PixelWeights {
151 } PixelWeights;
152 
153 typedef struct PixelRefs {
155  int nb;
156 } PixelRefs;
157 
158 typedef struct Frame {
161 } Frame;
162 
163 typedef struct MIContext {
164  const AVClass *class;
168  int mc_mode;
169  int me_mode;
171  int mb_size;
173  int vsbmc;
174 
181  int (*mv_table[3])[2][2];
185  int bitdepth;
186 
190  double prev_mafd;
192 
196 } MIContext;
197 
198 #define OFFSET(x) offsetof(MIContext, x)
199 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
200 #define CONST(name, help, val, u) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, 0, 0, FLAGS, .unit = u }
201 
202 static const AVOption minterpolate_options[] = {
203  { "fps", "output's frame rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "60"}, 0, INT_MAX, FLAGS },
204  { "mi_mode", "motion interpolation mode", OFFSET(mi_mode), AV_OPT_TYPE_INT, {.i64 = MI_MODE_MCI}, MI_MODE_DUP, MI_MODE_MCI, FLAGS, .unit = "mi_mode" },
205  CONST("dup", "duplicate frames", MI_MODE_DUP, "mi_mode"),
206  CONST("blend", "blend frames", MI_MODE_BLEND, "mi_mode"),
207  CONST("mci", "motion compensated interpolation", MI_MODE_MCI, "mi_mode"),
208  { "mc_mode", "motion compensation mode", OFFSET(mc_mode), AV_OPT_TYPE_INT, {.i64 = MC_MODE_OBMC}, MC_MODE_OBMC, MC_MODE_AOBMC, FLAGS, .unit = "mc_mode" },
209  CONST("obmc", "overlapped block motion compensation", MC_MODE_OBMC, "mc_mode"),
210  CONST("aobmc", "adaptive overlapped block motion compensation", MC_MODE_AOBMC, "mc_mode"),
211  { "me_mode", "motion estimation mode", OFFSET(me_mode), AV_OPT_TYPE_INT, {.i64 = ME_MODE_BILAT}, ME_MODE_BIDIR, ME_MODE_BILAT, FLAGS, .unit = "me_mode" },
212  CONST("bidir", "bidirectional motion estimation", ME_MODE_BIDIR, "me_mode"),
213  CONST("bilat", "bilateral motion estimation", ME_MODE_BILAT, "me_mode"),
214  { "me", "motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = AV_ME_METHOD_EPZS}, AV_ME_METHOD_ESA, AV_ME_METHOD_UMH, FLAGS, .unit = "me" },
215  CONST("esa", "exhaustive search", AV_ME_METHOD_ESA, "me"),
216  CONST("tss", "three step search", AV_ME_METHOD_TSS, "me"),
217  CONST("tdls", "two dimensional logarithmic search", AV_ME_METHOD_TDLS, "me"),
218  CONST("ntss", "new three step search", AV_ME_METHOD_NTSS, "me"),
219  CONST("fss", "four step search", AV_ME_METHOD_FSS, "me"),
220  CONST("ds", "diamond search", AV_ME_METHOD_DS, "me"),
221  CONST("hexbs", "hexagon-based search", AV_ME_METHOD_HEXBS, "me"),
222  CONST("epzs", "enhanced predictive zonal search", AV_ME_METHOD_EPZS, "me"),
223  CONST("umh", "uneven multi-hexagon search", AV_ME_METHOD_UMH, "me"),
224  { "mb_size", "macroblock size", OFFSET(mb_size), AV_OPT_TYPE_INT, {.i64 = 16}, 4, 16, FLAGS },
225  { "search_param", "search parameter", OFFSET(search_param), AV_OPT_TYPE_INT, {.i64 = 32}, 4, INT_MAX, FLAGS },
226  { "vsbmc", "variable-size block motion compensation", OFFSET(vsbmc), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
227  { "scd", "scene change detection method", OFFSET(scd_method), AV_OPT_TYPE_INT, {.i64 = SCD_METHOD_FDIFF}, SCD_METHOD_NONE, SCD_METHOD_FDIFF, FLAGS, .unit = "scene" },
228  CONST("none", "disable detection", SCD_METHOD_NONE, "scene"),
229  CONST("fdiff", "frame difference", SCD_METHOD_FDIFF, "scene"),
230  { "scd_threshold", "scene change threshold", OFFSET(scd_threshold), AV_OPT_TYPE_DOUBLE, {.dbl = 10.}, 0, 100.0, FLAGS },
231  { NULL }
232 };
233 
234 AVFILTER_DEFINE_CLASS(minterpolate);
235 
236 static const enum AVPixelFormat pix_fmts[] = {
246 };
247 
248 static uint64_t get_sbad(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
249 {
250  uint8_t *data_cur = me_ctx->data_cur;
251  uint8_t *data_next = me_ctx->data_ref;
252  int linesize = me_ctx->linesize;
253  int mv_x1 = x_mv - x;
254  int mv_y1 = y_mv - y;
255  int mv_x, mv_y, i, j;
256  uint64_t sbad = 0;
257 
258  x = av_clip(x, me_ctx->x_min, me_ctx->x_max);
259  y = av_clip(y, me_ctx->y_min, me_ctx->y_max);
260  mv_x = av_clip(x_mv - x, -FFMIN(x - me_ctx->x_min, me_ctx->x_max - x), FFMIN(x - me_ctx->x_min, me_ctx->x_max - x));
261  mv_y = av_clip(y_mv - y, -FFMIN(y - me_ctx->y_min, me_ctx->y_max - y), FFMIN(y - me_ctx->y_min, me_ctx->y_max - y));
262 
263  data_cur += (y + mv_y) * linesize;
264  data_next += (y - mv_y) * linesize;
265 
266  for (j = 0; j < me_ctx->mb_size; j++)
267  for (i = 0; i < me_ctx->mb_size; i++)
268  sbad += FFABS(data_cur[x + mv_x + i + j * linesize] - data_next[x - mv_x + i + j * linesize]);
269 
270  return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - me_ctx->pred_y)) * COST_PRED_SCALE;
271 }
272 
273 static uint64_t get_sbad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
274 {
275  uint8_t *data_cur = me_ctx->data_cur;
276  uint8_t *data_next = me_ctx->data_ref;
277  int linesize = me_ctx->linesize;
278  int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
279  int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
280  int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
281  int y_max = me_ctx->y_max - me_ctx->mb_size / 2;
282  int mv_x1 = x_mv - x;
283  int mv_y1 = y_mv - y;
284  int mv_x, mv_y, i, j;
285  uint64_t sbad = 0;
286 
287  x = av_clip(x, x_min, x_max);
288  y = av_clip(y, y_min, y_max);
289  mv_x = av_clip(x_mv - x, -FFMIN(x - x_min, x_max - x), FFMIN(x - x_min, x_max - x));
290  mv_y = av_clip(y_mv - y, -FFMIN(y - y_min, y_max - y), FFMIN(y - y_min, y_max - y));
291 
292  for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
293  for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
294  sbad += FFABS(data_cur[x + mv_x + i + (y + mv_y + j) * linesize] - data_next[x - mv_x + i + (y - mv_y + j) * linesize]);
295 
296  return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - me_ctx->pred_y)) * COST_PRED_SCALE;
297 }
298 
299 static uint64_t get_sad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
300 {
301  uint8_t *data_ref = me_ctx->data_ref;
302  uint8_t *data_cur = me_ctx->data_cur;
303  int linesize = me_ctx->linesize;
304  int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
305  int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
306  int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
307  int y_max = me_ctx->y_max - me_ctx->mb_size / 2;
308  int mv_x = x_mv - x;
309  int mv_y = y_mv - y;
310  int i, j;
311  uint64_t sad = 0;
312 
313  x = av_clip(x, x_min, x_max);
314  y = av_clip(y, y_min, y_max);
315  x_mv = av_clip(x_mv, x_min, x_max);
316  y_mv = av_clip(y_mv, y_min, y_max);
317 
318  for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
319  for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
320  sad += FFABS(data_ref[x_mv + i + (y_mv + j) * linesize] - data_cur[x + i + (y + j) * linesize]);
321 
322  return sad + (FFABS(mv_x - me_ctx->pred_x) + FFABS(mv_y - me_ctx->pred_y)) * COST_PRED_SCALE;
323 }
324 
326 {
327  MIContext *mi_ctx = inlink->dst->priv;
328  AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
330  const int height = inlink->h;
331  const int width = inlink->w;
332  int i;
333 
334  mi_ctx->log2_chroma_h = desc->log2_chroma_h;
335  mi_ctx->log2_chroma_w = desc->log2_chroma_w;
336  mi_ctx->bitdepth = desc->comp[0].depth;
337 
338  mi_ctx->nb_planes = av_pix_fmt_count_planes(inlink->format);
339 
340  mi_ctx->log2_mb_size = av_ceil_log2_c(mi_ctx->mb_size);
341  mi_ctx->mb_size = 1 << mi_ctx->log2_mb_size;
342 
343  mi_ctx->b_width = width >> mi_ctx->log2_mb_size;
344  mi_ctx->b_height = height >> mi_ctx->log2_mb_size;
345  mi_ctx->b_count = mi_ctx->b_width * mi_ctx->b_height;
346 
347  for (i = 0; i < NB_FRAMES; i++) {
348  Frame *frame = &mi_ctx->frames[i];
349  frame->blocks = av_calloc(mi_ctx->b_count, sizeof(*frame->blocks));
350  if (!frame->blocks)
351  return AVERROR(ENOMEM);
352  }
353 
354  if (mi_ctx->mi_mode == MI_MODE_MCI) {
355  if (mi_ctx->b_width < 2 || mi_ctx->b_height < 2) {
356  av_log(inlink->dst, AV_LOG_ERROR, "Height or width < %d\n",
357  2 * mi_ctx->mb_size);
358  return AVERROR(EINVAL);
359  }
360  ff_me_init_context(me_ctx, mi_ctx->mb_size, mi_ctx->search_param,
361  width, height, 0, (mi_ctx->b_width - 1) << mi_ctx->log2_mb_size,
362  0, (mi_ctx->b_height - 1) << mi_ctx->log2_mb_size);
363 
364  if (mi_ctx->me_mode == ME_MODE_BIDIR)
365  me_ctx->get_cost = &get_sad_ob;
366  else if (mi_ctx->me_mode == ME_MODE_BILAT)
367  me_ctx->get_cost = &get_sbad_ob;
368 
369  mi_ctx->pixel_mvs = av_calloc(width * height, sizeof(*mi_ctx->pixel_mvs));
370  mi_ctx->pixel_weights = av_calloc(width * height, sizeof(*mi_ctx->pixel_weights));
371  mi_ctx->pixel_refs = av_calloc(width * height, sizeof(*mi_ctx->pixel_refs));
372  if (!mi_ctx->pixel_mvs || !mi_ctx->pixel_weights || !mi_ctx->pixel_refs)
373  return AVERROR(ENOMEM);
374 
375  if (mi_ctx->me_mode == ME_MODE_BILAT)
376  if (!FF_ALLOCZ_TYPED_ARRAY(mi_ctx->int_blocks, mi_ctx->b_count))
377  return AVERROR(ENOMEM);
378 
379  if (mi_ctx->me_method == AV_ME_METHOD_EPZS) {
380  for (i = 0; i < 3; i++) {
381  mi_ctx->mv_table[i] = av_calloc(mi_ctx->b_count, sizeof(*mi_ctx->mv_table[0]));
382  if (!mi_ctx->mv_table[i])
383  return AVERROR(ENOMEM);
384  }
385  }
386  }
387 
388  if (mi_ctx->scd_method == SCD_METHOD_FDIFF) {
389  mi_ctx->sad = ff_scene_sad_get_fn(mi_ctx->bitdepth == 8 ? 8 : 16);
390  if (!mi_ctx->sad)
391  return AVERROR(EINVAL);
392  }
393 
394  return 0;
395 }
396 
397 static int config_output(AVFilterLink *outlink)
398 {
399  MIContext *mi_ctx = outlink->src->priv;
400 
401  outlink->frame_rate = mi_ctx->frame_rate;
402  outlink->time_base = av_inv_q(mi_ctx->frame_rate);
403 
404  return 0;
405 }
406 
407 #define ADD_PRED(preds, px, py)\
408  do {\
409  preds.mvs[preds.nb][0] = px;\
410  preds.mvs[preds.nb][1] = py;\
411  preds.nb++;\
412  } while(0)
413 
414 static void search_mv(MIContext *mi_ctx, Block *blocks, int mb_x, int mb_y, int dir)
415 {
416  AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
417  AVMotionEstPredictor *preds = me_ctx->preds;
418  Block *block = &blocks[mb_x + mb_y * mi_ctx->b_width];
419 
420  const int x_mb = mb_x << mi_ctx->log2_mb_size;
421  const int y_mb = mb_y << mi_ctx->log2_mb_size;
422  const int mb_i = mb_x + mb_y * mi_ctx->b_width;
423  int mv[2] = {x_mb, y_mb};
424 
425  switch (mi_ctx->me_method) {
426  case AV_ME_METHOD_ESA:
427  ff_me_search_esa(me_ctx, x_mb, y_mb, mv);
428  break;
429  case AV_ME_METHOD_TSS:
430  ff_me_search_tss(me_ctx, x_mb, y_mb, mv);
431  break;
432  case AV_ME_METHOD_TDLS:
433  ff_me_search_tdls(me_ctx, x_mb, y_mb, mv);
434  break;
435  case AV_ME_METHOD_NTSS:
436  ff_me_search_ntss(me_ctx, x_mb, y_mb, mv);
437  break;
438  case AV_ME_METHOD_FSS:
439  ff_me_search_fss(me_ctx, x_mb, y_mb, mv);
440  break;
441  case AV_ME_METHOD_DS:
442  ff_me_search_ds(me_ctx, x_mb, y_mb, mv);
443  break;
444  case AV_ME_METHOD_HEXBS:
445  ff_me_search_hexbs(me_ctx, x_mb, y_mb, mv);
446  break;
447  case AV_ME_METHOD_EPZS:
448 
449  preds[0].nb = 0;
450  preds[1].nb = 0;
451 
452  ADD_PRED(preds[0], 0, 0);
453 
454  //left mb in current frame
455  if (mb_x > 0)
456  ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - 1][dir][0], mi_ctx->mv_table[0][mb_i - 1][dir][1]);
457 
458  //top mb in current frame
459  if (mb_y > 0)
460  ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width][dir][0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width][dir][1]);
461 
462  //top-right mb in current frame
463  if (mb_y > 0 && mb_x + 1 < mi_ctx->b_width)
464  ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width + 1][dir][0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width + 1][dir][1]);
465 
466  //median predictor
467  if (preds[0].nb == 4) {
468  me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
469  me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
470  } else if (preds[0].nb == 3) {
471  me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
472  me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
473  } else if (preds[0].nb == 2) {
474  me_ctx->pred_x = preds[0].mvs[1][0];
475  me_ctx->pred_y = preds[0].mvs[1][1];
476  } else {
477  me_ctx->pred_x = 0;
478  me_ctx->pred_y = 0;
479  }
480 
481  //collocated mb in prev frame
482  ADD_PRED(preds[0], mi_ctx->mv_table[1][mb_i][dir][0], mi_ctx->mv_table[1][mb_i][dir][1]);
483 
484  //accelerator motion vector of collocated block in prev frame
485  ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i][dir][0] + (mi_ctx->mv_table[1][mb_i][dir][0] - mi_ctx->mv_table[2][mb_i][dir][0]),
486  mi_ctx->mv_table[1][mb_i][dir][1] + (mi_ctx->mv_table[1][mb_i][dir][1] - mi_ctx->mv_table[2][mb_i][dir][1]));
487 
488  //left mb in prev frame
489  if (mb_x > 0)
490  ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i - 1][dir][0], mi_ctx->mv_table[1][mb_i - 1][dir][1]);
491 
492  //top mb in prev frame
493  if (mb_y > 0)
494  ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i - mi_ctx->b_width][dir][0], mi_ctx->mv_table[1][mb_i - mi_ctx->b_width][dir][1]);
495 
496  //right mb in prev frame
497  if (mb_x + 1 < mi_ctx->b_width)
498  ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i + 1][dir][0], mi_ctx->mv_table[1][mb_i + 1][dir][1]);
499 
500  //bottom mb in prev frame
501  if (mb_y + 1 < mi_ctx->b_height)
502  ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i + mi_ctx->b_width][dir][0], mi_ctx->mv_table[1][mb_i + mi_ctx->b_width][dir][1]);
503 
504  ff_me_search_epzs(me_ctx, x_mb, y_mb, mv);
505 
506  mi_ctx->mv_table[0][mb_i][dir][0] = mv[0] - x_mb;
507  mi_ctx->mv_table[0][mb_i][dir][1] = mv[1] - y_mb;
508 
509  break;
510  case AV_ME_METHOD_UMH:
511 
512  preds[0].nb = 0;
513 
514  ADD_PRED(preds[0], 0, 0);
515 
516  //left mb in current frame
517  if (mb_x > 0)
518  ADD_PRED(preds[0], blocks[mb_i - 1].mvs[dir][0], blocks[mb_i - 1].mvs[dir][1]);
519 
520  if (mb_y > 0) {
521  //top mb in current frame
522  ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width].mvs[dir][0], blocks[mb_i - mi_ctx->b_width].mvs[dir][1]);
523 
524  //top-right mb in current frame
525  if (mb_x + 1 < mi_ctx->b_width)
526  ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width + 1].mvs[dir][0], blocks[mb_i - mi_ctx->b_width + 1].mvs[dir][1]);
527  //top-left mb in current frame
528  else if (mb_x > 0)
529  ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width - 1].mvs[dir][0], blocks[mb_i - mi_ctx->b_width - 1].mvs[dir][1]);
530  }
531 
532  //median predictor
533  if (preds[0].nb == 4) {
534  me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
535  me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
536  } else if (preds[0].nb == 3) {
537  me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
538  me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
539  } else if (preds[0].nb == 2) {
540  me_ctx->pred_x = preds[0].mvs[1][0];
541  me_ctx->pred_y = preds[0].mvs[1][1];
542  } else {
543  me_ctx->pred_x = 0;
544  me_ctx->pred_y = 0;
545  }
546 
547  ff_me_search_umh(me_ctx, x_mb, y_mb, mv);
548 
549  break;
550  }
551 
552  block->mvs[dir][0] = mv[0] - x_mb;
553  block->mvs[dir][1] = mv[1] - y_mb;
554 }
555 
556 static void bilateral_me(MIContext *mi_ctx)
557 {
558  Block *block;
559  int mb_x, mb_y;
560 
561  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
562  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
563  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
564 
565  block->cid = 0;
566  block->sb = 0;
567 
568  block->mvs[0][0] = 0;
569  block->mvs[0][1] = 0;
570  }
571 
572  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
573  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
574  search_mv(mi_ctx, mi_ctx->int_blocks, mb_x, mb_y, 0);
575 }
576 
577 static int var_size_bme(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n)
578 {
579  AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
580  uint64_t cost_sb, cost_old;
581  int mb_size = me_ctx->mb_size;
582  int search_param = me_ctx->search_param;
583  int mv_x, mv_y;
584  int x, y;
585  int ret;
586 
587  me_ctx->mb_size = 1 << n;
588  cost_old = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
589  me_ctx->mb_size = mb_size;
590 
591  if (!cost_old) {
592  block->sb = 0;
593  return 0;
594  }
595 
596  if (!block->subs) {
597  block->subs = av_mallocz(4 * sizeof(*block->subs));
598  if (!block->subs)
599  return AVERROR(ENOMEM);
600  }
601 
602  block->sb = 1;
603 
604  for (y = 0; y < 2; y++)
605  for (x = 0; x < 2; x++) {
606  Block *sb = &block->subs[x + y * 2];
607  int mv[2] = {x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]};
608 
609  me_ctx->mb_size = 1 << (n - 1);
610  me_ctx->search_param = 2;
611  me_ctx->pred_x = block->mvs[0][0];
612  me_ctx->pred_y = block->mvs[0][1];
613 
614  cost_sb = ff_me_search_ds(&mi_ctx->me_ctx, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1], mv);
615  mv_x = mv[0] - x_mb;
616  mv_y = mv[1] - y_mb;
617 
618  me_ctx->mb_size = mb_size;
619  me_ctx->search_param = search_param;
620 
621  if (cost_sb < cost_old / 4) {
622  sb->mvs[0][0] = mv_x;
623  sb->mvs[0][1] = mv_y;
624 
625  if (n > 1) {
626  if (ret = var_size_bme(mi_ctx, sb, x_mb + (x << (n - 1)), y_mb + (y << (n - 1)), n - 1))
627  return ret;
628  } else
629  sb->sb = 0;
630  } else {
631  block->sb = 0;
632  return 0;
633  }
634  }
635 
636  return 0;
637 }
638 
639 static int cluster_mvs(MIContext *mi_ctx)
640 {
641  int changed, c, c_max = 0;
642  int mb_x, mb_y, x, y;
643  int mv_x, mv_y, avg_x, avg_y, dx, dy;
644  int d, ret;
645  Block *block;
646  Cluster *cluster, *cluster_new;
647 
648  do {
649  changed = 0;
650  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
651  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
652  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
653  c = block->cid;
654  cluster = &mi_ctx->clusters[c];
655  mv_x = block->mvs[0][0];
656  mv_y = block->mvs[0][1];
657 
658  if (cluster->nb < 2)
659  continue;
660 
661  avg_x = cluster->sum[0] / cluster->nb;
662  avg_y = cluster->sum[1] / cluster->nb;
663  dx = avg_x - mv_x;
664  dy = avg_y - mv_y;
665 
666  if (FFABS(dx) > CLUSTER_THRESHOLD || FFABS(dy) > CLUSTER_THRESHOLD) {
667 
668  for (d = 1; d < 5; d++)
669  for (y = FFMAX(mb_y - d, 0); y < FFMIN(mb_y + d + 1, mi_ctx->b_height); y++)
670  for (x = FFMAX(mb_x - d, 0); x < FFMIN(mb_x + d + 1, mi_ctx->b_width); x++) {
671  Block *nb = &mi_ctx->int_blocks[x + y * mi_ctx->b_width];
672  if (nb->cid > block->cid) {
673  if (nb->cid < c || c == block->cid)
674  c = nb->cid;
675  }
676  }
677 
678  if (c == block->cid)
679  c = c_max + 1;
680 
681  if (c >= NB_CLUSTERS) {
682  continue;
683  }
684 
685  cluster_new = &mi_ctx->clusters[c];
686  cluster_new->sum[0] += mv_x;
687  cluster_new->sum[1] += mv_y;
688  cluster->sum[0] -= mv_x;
689  cluster->sum[1] -= mv_y;
690  cluster_new->nb++;
691  cluster->nb--;
692 
693  c_max = FFMAX(c_max, c);
694  block->cid = c;
695 
696  changed = 1;
697  }
698  }
699  } while (changed);
700 
701  /* find boundaries */
702  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
703  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
704  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
705  for (y = FFMAX(mb_y - 1, 0); y < FFMIN(mb_y + 2, mi_ctx->b_height); y++)
706  for (x = FFMAX(mb_x - 1, 0); x < FFMIN(mb_x + 2, mi_ctx->b_width); x++) {
707  dx = x - mb_x;
708  dy = y - mb_y;
709 
710  if ((x - mb_x) && (y - mb_y) || !dx && !dy)
711  continue;
712 
713  if (!mb_x || !mb_y || mb_x == mi_ctx->b_width - 1 || mb_y == mi_ctx->b_height - 1)
714  continue;
715 
716  if (block->cid != mi_ctx->int_blocks[x + y * mi_ctx->b_width].cid) {
717  if (!dx && block->cid == mi_ctx->int_blocks[x + (mb_y - dy) * mi_ctx->b_width].cid ||
718  !dy && block->cid == mi_ctx->int_blocks[(mb_x - dx) + y * mi_ctx->b_width].cid) {
719  if (ret = var_size_bme(mi_ctx, block, mb_x << mi_ctx->log2_mb_size, mb_y << mi_ctx->log2_mb_size, mi_ctx->log2_mb_size))
720  return ret;
721  }
722  }
723  }
724  }
725 
726  return 0;
727 }
728 
730 {
731  AVFilterContext *ctx = inlink->dst;
732  MIContext *mi_ctx = ctx->priv;
733  Frame frame_tmp;
734  int mb_x, mb_y, dir;
735 
736  av_frame_free(&mi_ctx->frames[0].avf);
737  frame_tmp = mi_ctx->frames[0];
738  memmove(&mi_ctx->frames[0], &mi_ctx->frames[1], sizeof(mi_ctx->frames[0]) * (NB_FRAMES - 1));
739  mi_ctx->frames[NB_FRAMES - 1] = frame_tmp;
740  mi_ctx->frames[NB_FRAMES - 1].avf = avf_in;
741 
742  if (mi_ctx->mi_mode == MI_MODE_MCI) {
743 
744  if (mi_ctx->me_method == AV_ME_METHOD_EPZS) {
745  mi_ctx->mv_table[2] = memcpy(mi_ctx->mv_table[2], mi_ctx->mv_table[1], sizeof(*mi_ctx->mv_table[1]) * mi_ctx->b_count);
746  mi_ctx->mv_table[1] = memcpy(mi_ctx->mv_table[1], mi_ctx->mv_table[0], sizeof(*mi_ctx->mv_table[0]) * mi_ctx->b_count);
747  }
748 
749  if (mi_ctx->me_mode == ME_MODE_BIDIR) {
750 
751  if (mi_ctx->frames[1].avf) {
752  for (dir = 0; dir < 2; dir++) {
753  mi_ctx->me_ctx.linesize = mi_ctx->frames[2].avf->linesize[0];
754  mi_ctx->me_ctx.data_cur = mi_ctx->frames[2].avf->data[0];
755  mi_ctx->me_ctx.data_ref = mi_ctx->frames[dir ? 3 : 1].avf->data[0];
756 
757  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
758  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
759  search_mv(mi_ctx, mi_ctx->frames[2].blocks, mb_x, mb_y, dir);
760  }
761  }
762 
763  } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
764  Block *block;
765  int i, ret;
766 
767  if (!mi_ctx->frames[0].avf)
768  return 0;
769 
770  mi_ctx->me_ctx.linesize = mi_ctx->frames[0].avf->linesize[0];
771  mi_ctx->me_ctx.data_cur = mi_ctx->frames[1].avf->data[0];
772  mi_ctx->me_ctx.data_ref = mi_ctx->frames[2].avf->data[0];
773 
774  bilateral_me(mi_ctx);
775 
776  if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
777 
778  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
779  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
780  int x_mb = mb_x << mi_ctx->log2_mb_size;
781  int y_mb = mb_y << mi_ctx->log2_mb_size;
782  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
783 
784  block->sbad = get_sbad(&mi_ctx->me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
785  }
786  }
787 
788  if (mi_ctx->vsbmc) {
789 
790  for (i = 0; i < NB_CLUSTERS; i++) {
791  mi_ctx->clusters[i].sum[0] = 0;
792  mi_ctx->clusters[i].sum[1] = 0;
793  mi_ctx->clusters[i].nb = 0;
794  }
795 
796  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
797  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
798  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
799 
800  mi_ctx->clusters[0].sum[0] += block->mvs[0][0];
801  mi_ctx->clusters[0].sum[1] += block->mvs[0][1];
802  }
803 
804  mi_ctx->clusters[0].nb = mi_ctx->b_count;
805 
806  if (ret = cluster_mvs(mi_ctx))
807  return ret;
808  }
809  }
810  }
811 
812  return 0;
813 }
814 
816 {
817  MIContext *mi_ctx = ctx->priv;
818  AVFilterLink *input = ctx->inputs[0];
819  uint8_t *p1 = mi_ctx->frames[1].avf->data[0];
820  ptrdiff_t linesize1 = mi_ctx->frames[1].avf->linesize[0];
821  uint8_t *p2 = mi_ctx->frames[2].avf->data[0];
822  ptrdiff_t linesize2 = mi_ctx->frames[2].avf->linesize[0];
823 
824  if (mi_ctx->scd_method == SCD_METHOD_FDIFF) {
825  double ret = 0, mafd, diff;
826  uint64_t sad;
827  mi_ctx->sad(p1, linesize1, p2, linesize2, input->w, input->h, &sad);
828  mafd = (double) sad * 100.0 / (input->h * input->w) / (1 << mi_ctx->bitdepth);
829  diff = fabs(mafd - mi_ctx->prev_mafd);
830  ret = av_clipf(FFMIN(mafd, diff), 0, 100.0);
831  mi_ctx->prev_mafd = mafd;
832 
833  return ret >= mi_ctx->scd_threshold;
834  }
835 
836  return 0;
837 }
838 
839 #define ADD_PIXELS(b_weight, mv_x, mv_y)\
840  do {\
841  if (!b_weight || pixel_refs->nb + 1 >= NB_PIXEL_MVS)\
842  continue;\
843  pixel_refs->refs[pixel_refs->nb] = 1;\
844  pixel_weights->weights[pixel_refs->nb] = b_weight * (ALPHA_MAX - alpha);\
845  pixel_mvs->mvs[pixel_refs->nb][0] = av_clip((mv_x * alpha) / ALPHA_MAX, x_min, x_max);\
846  pixel_mvs->mvs[pixel_refs->nb][1] = av_clip((mv_y * alpha) / ALPHA_MAX, y_min, y_max);\
847  pixel_refs->nb++;\
848  pixel_refs->refs[pixel_refs->nb] = 2;\
849  pixel_weights->weights[pixel_refs->nb] = b_weight * alpha;\
850  pixel_mvs->mvs[pixel_refs->nb][0] = av_clip(-mv_x * (ALPHA_MAX - alpha) / ALPHA_MAX, x_min, x_max);\
851  pixel_mvs->mvs[pixel_refs->nb][1] = av_clip(-mv_y * (ALPHA_MAX - alpha) / ALPHA_MAX, y_min, y_max);\
852  pixel_refs->nb++;\
853  } while(0)
854 
855 static void bidirectional_obmc(MIContext *mi_ctx, int alpha)
856 {
857  int x, y;
858  int width = mi_ctx->frames[0].avf->width;
859  int height = mi_ctx->frames[0].avf->height;
860  int mb_y, mb_x, dir;
861 
862  for (y = 0; y < height; y++)
863  for (x = 0; x < width; x++)
864  mi_ctx->pixel_refs[x + y * width].nb = 0;
865 
866  for (dir = 0; dir < 2; dir++)
867  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
868  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
869  int a = dir ? alpha : (ALPHA_MAX - alpha);
870  int mv_x = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][0];
871  int mv_y = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][1];
872  int start_x, start_y;
873  int startc_x, startc_y, endc_x, endc_y;
874 
875  start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_x * a / ALPHA_MAX;
876  start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_y * a / ALPHA_MAX;
877 
878  startc_x = av_clip(start_x, 0, width - 1);
879  startc_y = av_clip(start_y, 0, height - 1);
880  endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
881  endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
882 
883  if (dir) {
884  mv_x = -mv_x;
885  mv_y = -mv_y;
886  }
887 
888  for (y = startc_y; y < endc_y; y++) {
889  int y_min = -y;
890  int y_max = height - y - 1;
891  for (x = startc_x; x < endc_x; x++) {
892  int x_min = -x;
893  int x_max = width - x - 1;
894  int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
895  PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
896  PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
897  PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
898 
899  ADD_PIXELS(obmc_weight, mv_x, mv_y);
900  }
901  }
902  }
903 }
904 
905 static void set_frame_data(MIContext *mi_ctx, int alpha, AVFrame *avf_out)
906 {
907  int x, y, plane;
908 
909  for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
910  int width = avf_out->width;
911  int height = avf_out->height;
912  int chroma = plane == 1 || plane == 2;
913 
914  for (y = 0; y < height; y++)
915  for (x = 0; x < width; x++) {
916  int x_mv, y_mv;
917  int weight_sum = 0;
918  int i, val = 0;
919  PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * avf_out->width];
920  PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * avf_out->width];
921  PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * avf_out->width];
922 
923  for (i = 0; i < pixel_refs->nb; i++)
924  weight_sum += pixel_weights->weights[i];
925 
926  if (!weight_sum || !pixel_refs->nb) {
927  pixel_weights->weights[0] = ALPHA_MAX - alpha;
928  pixel_refs->refs[0] = 1;
929  pixel_mvs->mvs[0][0] = 0;
930  pixel_mvs->mvs[0][1] = 0;
931  pixel_weights->weights[1] = alpha;
932  pixel_refs->refs[1] = 2;
933  pixel_mvs->mvs[1][0] = 0;
934  pixel_mvs->mvs[1][1] = 0;
935  pixel_refs->nb = 2;
936 
937  weight_sum = ALPHA_MAX;
938  }
939 
940  for (i = 0; i < pixel_refs->nb; i++) {
941  Frame *frame = &mi_ctx->frames[pixel_refs->refs[i]];
942  if (chroma) {
943  x_mv = (x >> mi_ctx->log2_chroma_w) + pixel_mvs->mvs[i][0] / (1 << mi_ctx->log2_chroma_w);
944  y_mv = (y >> mi_ctx->log2_chroma_h) + pixel_mvs->mvs[i][1] / (1 << mi_ctx->log2_chroma_h);
945  } else {
946  x_mv = x + pixel_mvs->mvs[i][0];
947  y_mv = y + pixel_mvs->mvs[i][1];
948  }
949 
950  val += pixel_weights->weights[i] * frame->avf->data[plane][x_mv + y_mv * frame->avf->linesize[plane]];
951  }
952 
953  val = ROUNDED_DIV(val, weight_sum);
954 
955  if (chroma)
956  avf_out->data[plane][(x >> mi_ctx->log2_chroma_w) + (y >> mi_ctx->log2_chroma_h) * avf_out->linesize[plane]] = val;
957  else
958  avf_out->data[plane][x + y * avf_out->linesize[plane]] = val;
959  }
960  }
961 }
962 
963 static void var_size_bmc(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n, int alpha)
964 {
965  int sb_x, sb_y;
966  int width = mi_ctx->frames[0].avf->width;
967  int height = mi_ctx->frames[0].avf->height;
968 
969  for (sb_y = 0; sb_y < 2; sb_y++)
970  for (sb_x = 0; sb_x < 2; sb_x++) {
971  Block *sb = &block->subs[sb_x + sb_y * 2];
972 
973  if (sb->sb)
974  var_size_bmc(mi_ctx, sb, x_mb + (sb_x << (n - 1)), y_mb + (sb_y << (n - 1)), n - 1, alpha);
975  else {
976  int x, y;
977  int mv_x = sb->mvs[0][0] * 2;
978  int mv_y = sb->mvs[0][1] * 2;
979 
980  int start_x = x_mb + (sb_x << (n - 1));
981  int start_y = y_mb + (sb_y << (n - 1));
982  int end_x = start_x + (1 << (n - 1));
983  int end_y = start_y + (1 << (n - 1));
984 
985  for (y = start_y; y < end_y; y++) {
986  int y_min = -y;
987  int y_max = height - y - 1;
988  for (x = start_x; x < end_x; x++) {
989  int x_min = -x;
990  int x_max = width - x - 1;
991  PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
992  PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
993  PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
994 
995  ADD_PIXELS(PX_WEIGHT_MAX, mv_x, mv_y);
996  }
997  }
998  }
999  }
1000 }
1001 
1002 static void bilateral_obmc(MIContext *mi_ctx, Block *block, int mb_x, int mb_y, int alpha)
1003 {
1004  int x, y;
1005  int width = mi_ctx->frames[0].avf->width;
1006  int height = mi_ctx->frames[0].avf->height;
1007 
1008  Block *nb;
1009  int nb_x, nb_y;
1010  uint64_t sbads[9];
1011 
1012  int mv_x = block->mvs[0][0] * 2;
1013  int mv_y = block->mvs[0][1] * 2;
1014  int start_x, start_y;
1015  int startc_x, startc_y, endc_x, endc_y;
1016 
1017  if (mi_ctx->mc_mode == MC_MODE_AOBMC)
1018  for (nb_y = FFMAX(0, mb_y - 1); nb_y < FFMIN(mb_y + 2, mi_ctx->b_height); nb_y++)
1019  for (nb_x = FFMAX(0, mb_x - 1); nb_x < FFMIN(mb_x + 2, mi_ctx->b_width); nb_x++) {
1020  int x_nb = nb_x << mi_ctx->log2_mb_size;
1021  int y_nb = nb_y << mi_ctx->log2_mb_size;
1022 
1023  if (nb_x - mb_x || nb_y - mb_y)
1024  sbads[nb_x - mb_x + 1 + (nb_y - mb_y + 1) * 3] = get_sbad(&mi_ctx->me_ctx, x_nb, y_nb, x_nb + block->mvs[0][0], y_nb + block->mvs[0][1]);
1025  }
1026 
1027  start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1028  start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1029 
1030  startc_x = av_clip(start_x, 0, width - 1);
1031  startc_y = av_clip(start_y, 0, height - 1);
1032  endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
1033  endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
1034 
1035  for (y = startc_y; y < endc_y; y++) {
1036  int y_min = -y;
1037  int y_max = height - y - 1;
1038  for (x = startc_x; x < endc_x; x++) {
1039  int x_min = -x;
1040  int x_max = width - x - 1;
1041  int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
1042  PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
1043  PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
1044  PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
1045 
1046  if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
1047  nb_x = (((x - start_x) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1048  nb_y = (((y - start_y) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1049 
1050  if (nb_x || nb_y) {
1051  uint64_t sbad = sbads[nb_x + 1 + (nb_y + 1) * 3];
1052  nb = &mi_ctx->int_blocks[mb_x + nb_x + (mb_y + nb_y) * mi_ctx->b_width];
1053 
1054  if (sbad && sbad != UINT64_MAX && nb->sbad != UINT64_MAX) {
1055  int phi = av_clip(ALPHA_MAX * nb->sbad / sbad, 0, ALPHA_MAX);
1056  obmc_weight = obmc_weight * phi / ALPHA_MAX;
1057  }
1058  }
1059  }
1060 
1061  ADD_PIXELS(obmc_weight, mv_x, mv_y);
1062  }
1063  }
1064 }
1065 
1066 static void interpolate(AVFilterLink *inlink, AVFrame *avf_out)
1067 {
1068  AVFilterContext *ctx = inlink->dst;
1069  AVFilterLink *outlink = ctx->outputs[0];
1070  MIContext *mi_ctx = ctx->priv;
1071  int x, y;
1072  int plane, alpha;
1073  int64_t pts;
1074 
1075  pts = av_rescale(avf_out->pts, (int64_t) ALPHA_MAX * outlink->time_base.num * inlink->time_base.den,
1076  (int64_t) outlink->time_base.den * inlink->time_base.num);
1077 
1078  if (mi_ctx->frames[2].avf->pts > mi_ctx->frames[1].avf->pts) {
1079  alpha = (pts - mi_ctx->frames[1].avf->pts * ALPHA_MAX) / (mi_ctx->frames[2].avf->pts - mi_ctx->frames[1].avf->pts);
1080  alpha = av_clip(alpha, 0, ALPHA_MAX);
1081  } else {
1082  av_log(ctx, AV_LOG_DEBUG, "duplicate input PTS detected\n");
1083  alpha = 0;
1084  }
1085 
1086  if (alpha == 0 || alpha == ALPHA_MAX) {
1087  av_frame_copy(avf_out, alpha ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1088  return;
1089  }
1090 
1091  if (mi_ctx->scene_changed) {
1092  av_log(ctx, AV_LOG_DEBUG, "scene changed, input pts %"PRId64"\n", mi_ctx->frames[1].avf->pts);
1093  /* duplicate frame */
1094  av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1095  return;
1096  }
1097 
1098  switch(mi_ctx->mi_mode) {
1099  case MI_MODE_DUP:
1100  av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1101 
1102  break;
1103  case MI_MODE_BLEND:
1104  for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
1105  int width = avf_out->width;
1106  int height = avf_out->height;
1107 
1108  if (plane == 1 || plane == 2) {
1111  }
1112 
1113  for (y = 0; y < height; y++) {
1114  for (x = 0; x < width; x++) {
1115  avf_out->data[plane][x + y * avf_out->linesize[plane]] =
1116  (alpha * mi_ctx->frames[2].avf->data[plane][x + y * mi_ctx->frames[2].avf->linesize[plane]] +
1117  (ALPHA_MAX - alpha) * mi_ctx->frames[1].avf->data[plane][x + y * mi_ctx->frames[1].avf->linesize[plane]] + 512) >> 10;
1118  }
1119  }
1120  }
1121 
1122  break;
1123  case MI_MODE_MCI:
1124  if (mi_ctx->me_mode == ME_MODE_BIDIR) {
1125  bidirectional_obmc(mi_ctx, alpha);
1126  set_frame_data(mi_ctx, alpha, avf_out);
1127 
1128  } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
1129  int mb_x, mb_y;
1130  Block *block;
1131 
1132  for (y = 0; y < mi_ctx->frames[0].avf->height; y++)
1133  for (x = 0; x < mi_ctx->frames[0].avf->width; x++)
1134  mi_ctx->pixel_refs[x + y * mi_ctx->frames[0].avf->width].nb = 0;
1135 
1136  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
1137  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
1138  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
1139 
1140  if (block->sb)
1141  var_size_bmc(mi_ctx, block, mb_x << mi_ctx->log2_mb_size, mb_y << mi_ctx->log2_mb_size, mi_ctx->log2_mb_size, alpha);
1142 
1143  bilateral_obmc(mi_ctx, block, mb_x, mb_y, alpha);
1144 
1145  }
1146 
1147  set_frame_data(mi_ctx, alpha, avf_out);
1148  }
1149 
1150  break;
1151  }
1152 }
1153 
1155 {
1156  AVFilterContext *ctx = inlink->dst;
1157  AVFilterLink *outlink = ctx->outputs[0];
1158  MIContext *mi_ctx = ctx->priv;
1159  int ret;
1160 
1161  if (avf_in->pts == AV_NOPTS_VALUE) {
1162  ret = ff_filter_frame(ctx->outputs[0], avf_in);
1163  return ret;
1164  }
1165 
1166  if (!mi_ctx->frames[NB_FRAMES - 1].avf || avf_in->pts < mi_ctx->frames[NB_FRAMES - 1].avf->pts) {
1167  av_log(ctx, AV_LOG_VERBOSE, "Initializing out pts from input pts %"PRId64"\n", avf_in->pts);
1168  mi_ctx->out_pts = av_rescale_q(avf_in->pts, inlink->time_base, outlink->time_base);
1169  }
1170 
1171  if (!mi_ctx->frames[NB_FRAMES - 1].avf)
1172  if (ret = inject_frame(inlink, av_frame_clone(avf_in)))
1173  return ret;
1174 
1175  if (ret = inject_frame(inlink, avf_in))
1176  return ret;
1177 
1178  if (!mi_ctx->frames[0].avf)
1179  return 0;
1180 
1182 
1183  for (;;) {
1184  AVFrame *avf_out;
1185 
1186  if (av_compare_ts(mi_ctx->out_pts, outlink->time_base, mi_ctx->frames[2].avf->pts, inlink->time_base) > 0)
1187  break;
1188 
1189  if (!(avf_out = ff_get_video_buffer(ctx->outputs[0], inlink->w, inlink->h)))
1190  return AVERROR(ENOMEM);
1191 
1192  av_frame_copy_props(avf_out, mi_ctx->frames[NB_FRAMES - 1].avf);
1193  avf_out->pts = mi_ctx->out_pts++;
1194  avf_out->duration = 1;
1195 
1196  interpolate(inlink, avf_out);
1197 
1198  if ((ret = ff_filter_frame(ctx->outputs[0], avf_out)) < 0)
1199  return ret;
1200  }
1201 
1202  return 0;
1203 }
1204 
1205 static av_cold void free_blocks(Block *block, int sb)
1206 {
1207  if (block->subs)
1208  free_blocks(block->subs, 1);
1209  if (sb)
1210  av_freep(&block);
1211 }
1212 
1214 {
1215  MIContext *mi_ctx = ctx->priv;
1216  int i, m;
1217 
1218  av_freep(&mi_ctx->pixel_mvs);
1219  av_freep(&mi_ctx->pixel_weights);
1220  av_freep(&mi_ctx->pixel_refs);
1221  if (mi_ctx->int_blocks)
1222  for (m = 0; m < mi_ctx->b_count; m++)
1223  free_blocks(&mi_ctx->int_blocks[m], 0);
1224  av_freep(&mi_ctx->int_blocks);
1225 
1226  for (i = 0; i < NB_FRAMES; i++) {
1227  Frame *frame = &mi_ctx->frames[i];
1228  av_freep(&frame->blocks);
1229  av_frame_free(&frame->avf);
1230  }
1231 
1232  for (i = 0; i < 3; i++)
1233  av_freep(&mi_ctx->mv_table[i]);
1234 }
1235 
1237  {
1238  .name = "default",
1239  .type = AVMEDIA_TYPE_VIDEO,
1240  .filter_frame = filter_frame,
1241  .config_props = config_input,
1242  },
1243 };
1244 
1246  {
1247  .name = "default",
1248  .type = AVMEDIA_TYPE_VIDEO,
1249  .config_props = config_output,
1250  },
1251 };
1252 
1254  .name = "minterpolate",
1255  .description = NULL_IF_CONFIG_SMALL("Frame rate conversion using Motion Interpolation."),
1256  .priv_size = sizeof(MIContext),
1257  .priv_class = &minterpolate_class,
1258  .uninit = uninit,
1262 };
FF_ALLOCZ_TYPED_ARRAY
#define FF_ALLOCZ_TYPED_ARRAY(p, nelem)
Definition: internal.h:88
MC_MODE_OBMC
#define MC_MODE_OBMC
Definition: vf_minterpolate.c:35
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:112
AVMotionEstPredictor::nb
int nb
Definition: motion_estimation.h:38
MIContext::bitdepth
int bitdepth
Definition: vf_minterpolate.c:185
Frame::avf
AVFrame * avf
Definition: vf_minterpolate.c:159
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
av_clip
#define av_clip
Definition: common.h:98
obmc_linear32
static const uint8_t obmc_linear32[1024]
Definition: vf_minterpolate.c:50
AVMotionEstContext::data_ref
uint8_t * data_ref
Definition: motion_estimation.h:42
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *avf_in)
Definition: vf_minterpolate.c:1154
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
PX_WEIGHT_MAX
#define PX_WEIGHT_MAX
Definition: vf_minterpolate.c:47
inject_frame
static int inject_frame(AVFilterLink *inlink, AVFrame *avf_in)
Definition: vf_minterpolate.c:729
av_compare_ts
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
Compare two timestamps each in its own time base.
Definition: mathematics.c:147
AVMotionEstPredictor
Definition: motion_estimation.h:36
MIContext::scd_threshold
double scd_threshold
Definition: vf_minterpolate.c:191
MIContext::int_blocks
Block * int_blocks
Definition: vf_minterpolate.c:177
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
AVFrame::duration
int64_t duration
Duration of the frame, in the same units as pts.
Definition: frame.h:750
PixelWeights::weights
uint32_t weights[NB_PIXEL_MVS]
Definition: vf_minterpolate.c:150
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
minterpolate_outputs
static const AVFilterPad minterpolate_outputs[]
Definition: vf_minterpolate.c:1245
AV_OPT_TYPE_VIDEO_RATE
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
Definition: opt.h:248
obmc_linear4
static const uint8_t obmc_linear4[16]
Definition: vf_minterpolate.c:115
ff_me_search_esa
uint64_t ff_me_search_esa(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:78
MIContext::pixel_weights
PixelWeights * pixel_weights
Definition: vf_minterpolate.c:179
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:162
bilateral_me
static void bilateral_me(MIContext *mi_ctx)
Definition: vf_minterpolate.c:556
int64_t
long long int64_t
Definition: coverity.c:34
mv
static const int8_t mv[256][2]
Definition: 4xm.c:80
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:130
AVMotionEstContext::data_cur
uint8_t * data_cur
Definition: motion_estimation.h:42
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:344
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:456
AVFrame::width
int width
Definition: frame.h:416
PixelRefs::refs
int8_t refs[NB_PIXEL_MVS]
Definition: vf_minterpolate.c:154
AVOption
AVOption.
Definition: opt.h:346
FLAGS
#define FLAGS
Definition: vf_minterpolate.c:199
chroma
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1639
MIContext::pixel_refs
PixelRefs * pixel_refs
Definition: vf_minterpolate.c:180
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:106
SCD_METHOD_FDIFF
#define SCD_METHOD_FDIFF
Definition: vf_minterpolate.c:39
minterpolate_inputs
static const AVFilterPad minterpolate_inputs[]
Definition: vf_minterpolate.c:1236
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
Frame
Definition: ffplay.c:155
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
MIContext::b_count
int b_count
Definition: vf_minterpolate.c:183
obmc_tab_linear
static const uint8_t *const obmc_tab_linear[4]
Definition: vf_minterpolate.c:122
Block::sb
int sb
Definition: vf_minterpolate.c:141
video.h
AV_ME_METHOD_FSS
#define AV_ME_METHOD_FSS
Definition: motion_estimation.h:30
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:365
AVMotionEstContext::pred_x
int pred_x
median predictor x
Definition: motion_estimation.h:56
ff_me_search_ntss
uint64_t ff_me_search_ntss(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:160
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3002
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_minterpolate.c:325
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:422
MI_MODE_BLEND
@ MI_MODE_BLEND
Definition: vf_minterpolate.c:128
MIMode
MIMode
Definition: vf_minterpolate.c:126
MIContext::b_width
int b_width
Definition: vf_minterpolate.c:183
Cluster
Definition: vf_minterpolate.c:132
PixelMVS::mvs
int16_t mvs[NB_PIXEL_MVS][2]
Definition: vf_minterpolate.c:146
COST_PRED_SCALE
#define COST_PRED_SCALE
Definition: vf_minterpolate.c:48
val
static double val(void *priv, double ch)
Definition: aeval.c:78
pts
static int64_t pts
Definition: transcode_aac.c:643
MIContext::mv_table
int(*[3] mv_table)[2][2]
Definition: vf_minterpolate.c:181
AV_ME_METHOD_ESA
#define AV_ME_METHOD_ESA
Copyright (c) 2016 Davinder Singh (DSM_) <ds.mudhar<@gmail.com>
Definition: motion_estimation.h:26
ff_me_search_tss
uint64_t ff_me_search_tss(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:97
AVRational::num
int num
Numerator.
Definition: rational.h:59
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
AV_PIX_FMT_YUVJ411P
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:283
MIContext::log2_chroma_h
int log2_chroma_h
Definition: vf_minterpolate.c:194
SCD_METHOD_NONE
#define SCD_METHOD_NONE
Definition: vf_minterpolate.c:38
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:86
AV_ME_METHOD_TSS
#define AV_ME_METHOD_TSS
Definition: motion_estimation.h:27
width
#define width
set_frame_data
static void set_frame_data(MIContext *mi_ctx, int alpha, AVFrame *avf_out)
Definition: vf_minterpolate.c:905
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:108
get_sad_ob
static uint64_t get_sad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
Definition: vf_minterpolate.c:299
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
MIContext::prev_mafd
double prev_mafd
Definition: vf_minterpolate.c:190
AVMotionEstContext::x_max
int x_max
Definition: motion_estimation.h:52
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:237
AVMotionEstContext::x_min
int x_min
Definition: motion_estimation.h:51
MIContext::me_ctx
AVMotionEstContext me_ctx
Definition: vf_minterpolate.c:165
ME_MODE_BILAT
#define ME_MODE_BILAT
Definition: vf_minterpolate.c:33
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
MI_MODE_DUP
@ MI_MODE_DUP
Definition: vf_minterpolate.c:127
ctx
AVFormatContext * ctx
Definition: movenc.c:48
PixelRefs::nb
int nb
Definition: vf_minterpolate.c:155
var_size_bmc
static void var_size_bmc(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n, int alpha)
Definition: vf_minterpolate.c:963
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:563
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ADD_PIXELS
#define ADD_PIXELS(b_weight, mv_x, mv_y)
Definition: vf_minterpolate.c:839
ff_me_search_fss
uint64_t ff_me_search_fss(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:213
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
PixelWeights
Definition: vf_minterpolate.c:149
AVMotionEstContext
Definition: motion_estimation.h:41
Cluster::sum
int64_t sum[2]
Definition: vf_minterpolate.c:133
MI_MODE_MCI
@ MI_MODE_MCI
Definition: vf_minterpolate.c:129
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:87
frame
static AVFrame * frame
Definition: demux_decode.c:54
ff_me_search_ds
uint64_t ff_me_search_ds(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:245
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
if
if(ret)
Definition: filter_design.txt:179
get_sbad_ob
static uint64_t get_sbad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
Definition: vf_minterpolate.c:273
ff_scene_sad_get_fn
ff_scene_sad_fn ff_scene_sad_get_fn(int depth)
Definition: scene_sad.c:59
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
AVMotionEstContext::search_param
int search_param
Definition: motion_estimation.h:46
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:679
MIContext::mi_mode
enum MIMode mi_mode
Definition: vf_minterpolate.c:167
PixelMVS
Definition: vf_minterpolate.c:145
MIContext::frames
Frame frames[NB_FRAMES]
Definition: vf_minterpolate.c:175
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
CLUSTER_THRESHOLD
#define CLUSTER_THRESHOLD
Definition: vf_minterpolate.c:46
MIContext::b_height
int b_height
Definition: vf_minterpolate.c:183
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:85
bidirectional_obmc
static void bidirectional_obmc(MIContext *mi_ctx, int alpha)
Definition: vf_minterpolate.c:855
ROUNDED_DIV
#define ROUNDED_DIV(a, b)
Definition: common.h:56
motion_estimation.h
mathops.h
Frame::blocks
Block * blocks
Definition: vf_minterpolate.c:160
ff_vf_minterpolate
const AVFilter ff_vf_minterpolate
Definition: vf_minterpolate.c:1253
double
double
Definition: af_crystalizer.c:131
Block::mvs
int16_t mvs[2][2]
Definition: vf_minterpolate.c:138
av_clipf
av_clipf
Definition: af_crystalizer.c:121
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
Block::subs
struct Block * subs
Definition: vf_minterpolate.c:142
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
scene_sad.h
obmc_linear8
static const uint8_t obmc_linear8[64]
Definition: vf_minterpolate.c:104
get_sbad
static uint64_t get_sbad(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
Definition: vf_minterpolate.c:248
NB_PIXEL_MVS
#define NB_PIXEL_MVS
Definition: vf_minterpolate.c:42
Block
Definition: flashsv2enc.c:70
free_blocks
static av_cold void free_blocks(Block *block, int sb)
Definition: vf_minterpolate.c:1205
ff_me_search_hexbs
uint64_t ff_me_search_hexbs(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:300
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:890
AVMotionEstContext::y_min
int y_min
Definition: motion_estimation.h:53
ff_me_search_epzs
uint64_t ff_me_search_epzs(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:333
detect_scene_change
static int detect_scene_change(AVFilterContext *ctx)
Definition: vf_minterpolate.c:815
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
search_mv
static void search_mv(MIContext *mi_ctx, Block *blocks, int mb_x, int mb_y, int dir)
Definition: vf_minterpolate.c:414
ff_scene_sad_fn
void(* ff_scene_sad_fn)(SCENE_SAD_PARAMS)
Definition: scene_sad.h:34
MIContext::pixel_mvs
PixelMVS * pixel_mvs
Definition: vf_minterpolate.c:178
MIContext::mb_size
int mb_size
Definition: vf_minterpolate.c:171
OFFSET
#define OFFSET(x)
Definition: vf_minterpolate.c:198
MIContext::mc_mode
int mc_mode
Definition: vf_minterpolate.c:168
MIContext::scene_changed
int scene_changed
Definition: vf_minterpolate.c:188
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:164
height
#define height
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:174
AV_ME_METHOD_EPZS
#define AV_ME_METHOD_EPZS
Definition: motion_estimation.h:33
interpolate
static void interpolate(AVFilterLink *inlink, AVFrame *avf_out)
Definition: vf_minterpolate.c:1066
MIContext::scd_method
int scd_method
Definition: vf_minterpolate.c:187
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
Cluster::nb
int nb
Definition: vf_minterpolate.c:134
MIContext::sad
ff_scene_sad_fn sad
Definition: vf_minterpolate.c:189
internal.h
ME_MODE_BIDIR
#define ME_MODE_BIDIR
Copyright (c) 2014-2015 Michael Niedermayer michaelni@gmx.at Copyright (c) 2016 Davinder Singh (DSM_)...
Definition: vf_minterpolate.c:32
AV_ME_METHOD_DS
#define AV_ME_METHOD_DS
Definition: motion_estimation.h:31
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
MIContext::me_method
int me_method
Definition: vf_minterpolate.c:170
MIContext::out_pts
int64_t out_pts
Definition: vf_minterpolate.c:182
AV_ME_METHOD_HEXBS
#define AV_ME_METHOD_HEXBS
Definition: motion_estimation.h:32
common.h
ADD_PRED
#define ADD_PRED(preds, px, py)
Definition: vf_minterpolate.c:407
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_YUVJ440P
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
Definition: pixfmt.h:107
MIContext::nb_planes
int nb_planes
Definition: vf_minterpolate.c:195
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
minterpolate_options
static const AVOption minterpolate_options[]
Definition: vf_minterpolate.c:202
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
MC_MODE_AOBMC
#define MC_MODE_AOBMC
Definition: vf_minterpolate.c:36
CONST
#define CONST(name, help, val, u)
Definition: vf_minterpolate.c:200
ff_me_search_tdls
uint64_t ff_me_search_tdls(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:128
AVFilter
Filter definition.
Definition: avfilter.h:166
mid_pred
#define mid_pred
Definition: mathops.h:98
ret
ret
Definition: filter_design.txt:187
MIContext::log2_chroma_w
int log2_chroma_w
Definition: vf_minterpolate.c:193
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_minterpolate.c:236
obmc_linear16
static const uint8_t obmc_linear16[256]
Definition: vf_minterpolate.c:85
Block::cid
int cid
Definition: vf_minterpolate.c:139
AVMotionEstContext::y_max
int y_max
Definition: motion_estimation.h:54
ff_me_init_context
void ff_me_init_context(AVMotionEstContext *me_ctx, int mb_size, int search_param, int width, int height, int x_min, int x_max, int y_min, int y_max)
Definition: motion_estimation.c:46
AVFrame::height
int height
Definition: frame.h:416
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
avfilter.h
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(minterpolate)
AV_ME_METHOD_UMH
#define AV_ME_METHOD_UMH
Definition: motion_estimation.h:34
var_size_bme
static int var_size_bme(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n)
Definition: vf_minterpolate.c:577
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
ALPHA_MAX
#define ALPHA_MAX
Definition: vf_minterpolate.c:45
MIContext::me_mode
int me_mode
Definition: vf_minterpolate.c:169
AVMotionEstContext::pred_y
int pred_y
median predictor y
Definition: motion_estimation.h:57
desc
const char * desc
Definition: libsvtav1.c:75
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:77
MIContext::vsbmc
int vsbmc
Definition: vf_minterpolate.c:173
cluster_mvs
static int cluster_mvs(MIContext *mi_ctx)
Definition: vf_minterpolate.c:639
AV_ME_METHOD_NTSS
#define AV_ME_METHOD_NTSS
Definition: motion_estimation.h:29
AVMotionEstContext::linesize
int linesize
Definition: motion_estimation.h:43
NB_FRAMES
#define NB_FRAMES
Definition: vf_minterpolate.c:41
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
MIContext::frame_rate
AVRational frame_rate
Definition: vf_minterpolate.c:166
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
MIContext::clusters
Cluster clusters[NB_CLUSTERS]
Definition: vf_minterpolate.c:176
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:80
d
d
Definition: ffmpeg_filter.c:409
NB_CLUSTERS
#define NB_CLUSTERS
Definition: vf_minterpolate.c:43
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:389
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:79
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_minterpolate.c:397
ff_me_search_umh
uint64_t ff_me_search_umh(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:374
MIContext::log2_mb_size
int log2_mb_size
Definition: vf_minterpolate.c:184
MIContext::search_param
int search_param
Definition: vf_minterpolate.c:172
AVMotionEstPredictor::mvs
int mvs[10][2]
Definition: motion_estimation.h:37
AV_ME_METHOD_TDLS
#define AV_ME_METHOD_TDLS
Definition: motion_estimation.h:28
int
int
Definition: ffmpeg_filter.c:409
PixelRefs
Definition: vf_minterpolate.c:153
Block::sbad
uint64_t sbad
Definition: vf_minterpolate.c:140
AVMotionEstContext::preds
AVMotionEstPredictor preds[2]
Definition: motion_estimation.h:58
AVMotionEstContext::get_cost
uint64_t(* get_cost)(struct AVMotionEstContext *me_ctx, int x_mb, int y_mb, int mv_x, int mv_y)
Definition: motion_estimation.h:60
bilateral_obmc
static void bilateral_obmc(MIContext *mi_ctx, Block *block, int mb_x, int mb_y, int alpha)
Definition: vf_minterpolate.c:1002
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:173
AVMotionEstContext::mb_size
int mb_size
Definition: motion_estimation.h:45
av_ceil_log2_c
static av_always_inline av_const int av_ceil_log2_c(int x)
Compute ceil(log2(x)).
Definition: common.h:420
MIContext
Definition: vf_minterpolate.c:163
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_minterpolate.c:1213