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