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