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