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