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