FFmpeg
vf_minterpolate.c
Go to the documentation of this file.
1 /**
2  * Copyright (c) 2014-2015 Michael Niedermayer <michaelni@gmx.at>
3  * Copyright (c) 2016 Davinder Singh (DSM_) <ds.mudhar<@gmail.com>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "motion_estimation.h"
23 #include "libavcodec/mathops.h"
24 #include "libavutil/common.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/pixdesc.h"
28 #include "avfilter.h"
29 #include "filters.h"
30 #include "video.h"
31 #include "scene_sad.h"
32 
33 #define ME_MODE_BIDIR 0
34 #define ME_MODE_BILAT 1
35 
36 #define MC_MODE_OBMC 0
37 #define MC_MODE_AOBMC 1
38 
39 #define SCD_METHOD_NONE 0
40 #define SCD_METHOD_FDIFF 1
41 
42 #define NB_FRAMES 4
43 #define NB_PIXEL_MVS 32
44 #define NB_CLUSTERS 128
45 
46 #define ALPHA_MAX 1024
47 #define CLUSTER_THRESHOLD 4
48 #define PX_WEIGHT_MAX 255
49 #define COST_PRED_SCALE 64
50 
51 static const uint8_t obmc_linear32[1024] = {
52  0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
53  0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
54  0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
55  0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
56  4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
57  4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
58  4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
59  4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
60  4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
61  4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
62  4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
63  4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
64  8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
65  8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
66  8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
67  8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
68  8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
69  8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
70  8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
71  8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
72  4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
73  4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
74  4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
75  4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
76  4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
77  4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
78  4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
79  4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
80  0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
81  0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
82  0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
83  0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
84 };
85 
86 static const uint8_t obmc_linear16[256] = {
87  0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
88  4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
89  4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
90  8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
91  8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
92  12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
93  12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
94  16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
95  16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
96  12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
97  12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
98  8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
99  8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
100  4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
101  4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
102  0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
103 };
104 
105 static const uint8_t obmc_linear8[64] = {
106  4, 12, 20, 28, 28, 20, 12, 4,
107  12, 36, 60, 84, 84, 60, 36, 12,
108  20, 60,100,140,140,100, 60, 20,
109  28, 84,140,196,196,140, 84, 28,
110  28, 84,140,196,196,140, 84, 28,
111  20, 60,100,140,140,100, 60, 20,
112  12, 36, 60, 84, 84, 60, 36, 12,
113  4, 12, 20, 28, 28, 20, 12, 4,
114 };
115 
116 static const uint8_t obmc_linear4[16] = {
117  16, 48, 48, 16,
118  48,144,144, 48,
119  48,144,144, 48,
120  16, 48, 48, 16,
121 };
122 
123 static const uint8_t * const obmc_tab_linear[4]= {
125 };
126 
127 enum MIMode {
131 };
132 
133 typedef struct Cluster {
135  int nb;
136 } Cluster;
137 
138 typedef struct Block {
139  int16_t mvs[2][2];
140  int cid;
141  uint64_t sbad;
142  int sb;
143  struct Block *subs;
144 } Block;
145 
146 typedef struct PixelMVS {
147  int16_t mvs[NB_PIXEL_MVS][2];
148 } PixelMVS;
149 
150 typedef struct PixelWeights {
152 } PixelWeights;
153 
154 typedef struct PixelRefs {
156  int nb;
157 } PixelRefs;
158 
159 typedef struct Frame {
162 } Frame;
163 
164 typedef struct MIContext {
165  const AVClass *class;
169  int mc_mode;
170  int me_mode;
172  int mb_size;
174  int vsbmc;
175 
182  int (*mv_table[3])[2][2];
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  FilterLink *l = ff_filter_link(outlink);
402 
403  l->frame_rate = mi_ctx->frame_rate;
404  outlink->time_base = av_inv_q(mi_ctx->frame_rate);
405 
406  return 0;
407 }
408 
409 #define ADD_PRED(preds, px, py)\
410  do {\
411  preds.mvs[preds.nb][0] = px;\
412  preds.mvs[preds.nb][1] = py;\
413  preds.nb++;\
414  } while(0)
415 
416 static void search_mv(MIContext *mi_ctx, Block *blocks, int mb_x, int mb_y, int dir)
417 {
418  AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
419  AVMotionEstPredictor *preds = me_ctx->preds;
420  Block *block = &blocks[mb_x + mb_y * mi_ctx->b_width];
421 
422  const int x_mb = mb_x << mi_ctx->log2_mb_size;
423  const int y_mb = mb_y << mi_ctx->log2_mb_size;
424  const int mb_i = mb_x + mb_y * mi_ctx->b_width;
425  int mv[2] = {x_mb, y_mb};
426 
427  switch (mi_ctx->me_method) {
428  case AV_ME_METHOD_ESA:
429  ff_me_search_esa(me_ctx, x_mb, y_mb, mv);
430  break;
431  case AV_ME_METHOD_TSS:
432  ff_me_search_tss(me_ctx, x_mb, y_mb, mv);
433  break;
434  case AV_ME_METHOD_TDLS:
435  ff_me_search_tdls(me_ctx, x_mb, y_mb, mv);
436  break;
437  case AV_ME_METHOD_NTSS:
438  ff_me_search_ntss(me_ctx, x_mb, y_mb, mv);
439  break;
440  case AV_ME_METHOD_FSS:
441  ff_me_search_fss(me_ctx, x_mb, y_mb, mv);
442  break;
443  case AV_ME_METHOD_DS:
444  ff_me_search_ds(me_ctx, x_mb, y_mb, mv);
445  break;
446  case AV_ME_METHOD_HEXBS:
447  ff_me_search_hexbs(me_ctx, x_mb, y_mb, mv);
448  break;
449  case AV_ME_METHOD_EPZS:
450 
451  preds[0].nb = 0;
452  preds[1].nb = 0;
453 
454  ADD_PRED(preds[0], 0, 0);
455 
456  //left mb in current frame
457  if (mb_x > 0)
458  ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - 1][dir][0], mi_ctx->mv_table[0][mb_i - 1][dir][1]);
459 
460  //top mb in current frame
461  if (mb_y > 0)
462  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]);
463 
464  //top-right mb in current frame
465  if (mb_y > 0 && mb_x + 1 < mi_ctx->b_width)
466  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]);
467 
468  //median predictor
469  if (preds[0].nb == 4) {
470  me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
471  me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
472  } else if (preds[0].nb == 3) {
473  me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
474  me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
475  } else if (preds[0].nb == 2) {
476  me_ctx->pred_x = preds[0].mvs[1][0];
477  me_ctx->pred_y = preds[0].mvs[1][1];
478  } else {
479  me_ctx->pred_x = 0;
480  me_ctx->pred_y = 0;
481  }
482 
483  //collocated mb in prev frame
484  ADD_PRED(preds[0], mi_ctx->mv_table[1][mb_i][dir][0], mi_ctx->mv_table[1][mb_i][dir][1]);
485 
486  //accelerator motion vector of collocated block in prev frame
487  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]),
488  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]));
489 
490  //left mb in prev frame
491  if (mb_x > 0)
492  ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i - 1][dir][0], mi_ctx->mv_table[1][mb_i - 1][dir][1]);
493 
494  //top mb in prev frame
495  if (mb_y > 0)
496  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]);
497 
498  //right mb in prev frame
499  if (mb_x + 1 < mi_ctx->b_width)
500  ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i + 1][dir][0], mi_ctx->mv_table[1][mb_i + 1][dir][1]);
501 
502  //bottom mb in prev frame
503  if (mb_y + 1 < mi_ctx->b_height)
504  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]);
505 
506  ff_me_search_epzs(me_ctx, x_mb, y_mb, mv);
507 
508  mi_ctx->mv_table[0][mb_i][dir][0] = mv[0] - x_mb;
509  mi_ctx->mv_table[0][mb_i][dir][1] = mv[1] - y_mb;
510 
511  break;
512  case AV_ME_METHOD_UMH:
513 
514  preds[0].nb = 0;
515 
516  ADD_PRED(preds[0], 0, 0);
517 
518  //left mb in current frame
519  if (mb_x > 0)
520  ADD_PRED(preds[0], blocks[mb_i - 1].mvs[dir][0], blocks[mb_i - 1].mvs[dir][1]);
521 
522  if (mb_y > 0) {
523  //top mb in current frame
524  ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width].mvs[dir][0], blocks[mb_i - mi_ctx->b_width].mvs[dir][1]);
525 
526  //top-right mb in current frame
527  if (mb_x + 1 < mi_ctx->b_width)
528  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]);
529  //top-left mb in current frame
530  else if (mb_x > 0)
531  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]);
532  }
533 
534  //median predictor
535  if (preds[0].nb == 4) {
536  me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
537  me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
538  } else if (preds[0].nb == 3) {
539  me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
540  me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
541  } else if (preds[0].nb == 2) {
542  me_ctx->pred_x = preds[0].mvs[1][0];
543  me_ctx->pred_y = preds[0].mvs[1][1];
544  } else {
545  me_ctx->pred_x = 0;
546  me_ctx->pred_y = 0;
547  }
548 
549  ff_me_search_umh(me_ctx, x_mb, y_mb, mv);
550 
551  break;
552  }
553 
554  block->mvs[dir][0] = mv[0] - x_mb;
555  block->mvs[dir][1] = mv[1] - y_mb;
556 }
557 
558 static void bilateral_me(MIContext *mi_ctx)
559 {
560  Block *block;
561  int mb_x, mb_y;
562 
563  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
564  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
565  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
566 
567  block->cid = 0;
568  block->sb = 0;
569 
570  block->mvs[0][0] = 0;
571  block->mvs[0][1] = 0;
572  }
573 
574  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
575  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
576  search_mv(mi_ctx, mi_ctx->int_blocks, mb_x, mb_y, 0);
577 }
578 
579 static int var_size_bme(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n)
580 {
581  AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
582  uint64_t cost_sb, cost_old;
583  int mb_size = me_ctx->mb_size;
584  int search_param = me_ctx->search_param;
585  int mv_x, mv_y;
586  int x, y;
587  int ret;
588 
589  me_ctx->mb_size = 1 << n;
590  cost_old = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
591  me_ctx->mb_size = mb_size;
592 
593  if (!cost_old) {
594  block->sb = 0;
595  return 0;
596  }
597 
598  if (!block->subs) {
599  block->subs = av_mallocz(4 * sizeof(*block->subs));
600  if (!block->subs)
601  return AVERROR(ENOMEM);
602  }
603 
604  block->sb = 1;
605 
606  for (y = 0; y < 2; y++)
607  for (x = 0; x < 2; x++) {
608  Block *sb = &block->subs[x + y * 2];
609  int mv[2] = {x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]};
610 
611  me_ctx->mb_size = 1 << (n - 1);
612  me_ctx->search_param = 2;
613  me_ctx->pred_x = block->mvs[0][0];
614  me_ctx->pred_y = block->mvs[0][1];
615 
616  cost_sb = ff_me_search_ds(&mi_ctx->me_ctx, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1], mv);
617  mv_x = mv[0] - x_mb;
618  mv_y = mv[1] - y_mb;
619 
620  me_ctx->mb_size = mb_size;
621  me_ctx->search_param = search_param;
622 
623  if (cost_sb < cost_old / 4) {
624  sb->mvs[0][0] = mv_x;
625  sb->mvs[0][1] = mv_y;
626 
627  if (n > 1) {
628  if (ret = var_size_bme(mi_ctx, sb, x_mb + (x << (n - 1)), y_mb + (y << (n - 1)), n - 1))
629  return ret;
630  } else
631  sb->sb = 0;
632  } else {
633  block->sb = 0;
634  return 0;
635  }
636  }
637 
638  return 0;
639 }
640 
641 static int cluster_mvs(MIContext *mi_ctx)
642 {
643  int changed, c, c_max = 0;
644  int mb_x, mb_y, x, y;
645  int mv_x, mv_y, avg_x, avg_y, dx, dy;
646  int d, ret;
647  Block *block;
648  Cluster *cluster, *cluster_new;
649 
650  do {
651  changed = 0;
652  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
653  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
654  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
655  c = block->cid;
656  cluster = &mi_ctx->clusters[c];
657  mv_x = block->mvs[0][0];
658  mv_y = block->mvs[0][1];
659 
660  if (cluster->nb < 2)
661  continue;
662 
663  avg_x = cluster->sum[0] / cluster->nb;
664  avg_y = cluster->sum[1] / cluster->nb;
665  dx = avg_x - mv_x;
666  dy = avg_y - mv_y;
667 
668  if (FFABS(dx) > CLUSTER_THRESHOLD || FFABS(dy) > CLUSTER_THRESHOLD) {
669 
670  for (d = 1; d < 5; d++)
671  for (y = FFMAX(mb_y - d, 0); y < FFMIN(mb_y + d + 1, mi_ctx->b_height); y++)
672  for (x = FFMAX(mb_x - d, 0); x < FFMIN(mb_x + d + 1, mi_ctx->b_width); x++) {
673  Block *nb = &mi_ctx->int_blocks[x + y * mi_ctx->b_width];
674  if (nb->cid > block->cid) {
675  if (nb->cid < c || c == block->cid)
676  c = nb->cid;
677  }
678  }
679 
680  if (c == block->cid)
681  c = c_max + 1;
682 
683  if (c >= NB_CLUSTERS) {
684  continue;
685  }
686 
687  cluster_new = &mi_ctx->clusters[c];
688  cluster_new->sum[0] += mv_x;
689  cluster_new->sum[1] += mv_y;
690  cluster->sum[0] -= mv_x;
691  cluster->sum[1] -= mv_y;
692  cluster_new->nb++;
693  cluster->nb--;
694 
695  c_max = FFMAX(c_max, c);
696  block->cid = c;
697 
698  changed = 1;
699  }
700  }
701  } while (changed);
702 
703  /* find boundaries */
704  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
705  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
706  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
707  for (y = FFMAX(mb_y - 1, 0); y < FFMIN(mb_y + 2, mi_ctx->b_height); y++)
708  for (x = FFMAX(mb_x - 1, 0); x < FFMIN(mb_x + 2, mi_ctx->b_width); x++) {
709  dx = x - mb_x;
710  dy = y - mb_y;
711 
712  if ((x - mb_x) && (y - mb_y) || !dx && !dy)
713  continue;
714 
715  if (!mb_x || !mb_y || mb_x == mi_ctx->b_width - 1 || mb_y == mi_ctx->b_height - 1)
716  continue;
717 
718  if (block->cid != mi_ctx->int_blocks[x + y * mi_ctx->b_width].cid) {
719  if (!dx && block->cid == mi_ctx->int_blocks[x + (mb_y - dy) * mi_ctx->b_width].cid ||
720  !dy && block->cid == mi_ctx->int_blocks[(mb_x - dx) + y * mi_ctx->b_width].cid) {
721  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))
722  return ret;
723  }
724  }
725  }
726  }
727 
728  return 0;
729 }
730 
732 {
733  AVFilterContext *ctx = inlink->dst;
734  MIContext *mi_ctx = ctx->priv;
735  Frame frame_tmp;
736  int mb_x, mb_y, dir;
737 
738  av_frame_free(&mi_ctx->frames[0].avf);
739  frame_tmp = mi_ctx->frames[0];
740  memmove(&mi_ctx->frames[0], &mi_ctx->frames[1], sizeof(mi_ctx->frames[0]) * (NB_FRAMES - 1));
741  mi_ctx->frames[NB_FRAMES - 1] = frame_tmp;
742  mi_ctx->frames[NB_FRAMES - 1].avf = avf_in;
743 
744  if (mi_ctx->mi_mode == MI_MODE_MCI) {
745 
746  if (mi_ctx->me_method == AV_ME_METHOD_EPZS) {
747  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);
748  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);
749  }
750 
751  if (mi_ctx->me_mode == ME_MODE_BIDIR) {
752 
753  if (mi_ctx->frames[1].avf) {
754  for (dir = 0; dir < 2; dir++) {
755  mi_ctx->me_ctx.linesize = mi_ctx->frames[2].avf->linesize[0];
756  mi_ctx->me_ctx.data_cur = mi_ctx->frames[2].avf->data[0];
757  mi_ctx->me_ctx.data_ref = mi_ctx->frames[dir ? 3 : 1].avf->data[0];
758 
759  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
760  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
761  search_mv(mi_ctx, mi_ctx->frames[2].blocks, mb_x, mb_y, dir);
762  }
763  }
764 
765  } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
766  Block *block;
767  int i, ret;
768 
769  if (!mi_ctx->frames[0].avf)
770  return 0;
771 
772  mi_ctx->me_ctx.linesize = mi_ctx->frames[0].avf->linesize[0];
773  mi_ctx->me_ctx.data_cur = mi_ctx->frames[1].avf->data[0];
774  mi_ctx->me_ctx.data_ref = mi_ctx->frames[2].avf->data[0];
775 
776  bilateral_me(mi_ctx);
777 
778  if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
779 
780  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
781  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
782  int x_mb = mb_x << mi_ctx->log2_mb_size;
783  int y_mb = mb_y << mi_ctx->log2_mb_size;
784  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
785 
786  block->sbad = get_sbad(&mi_ctx->me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
787  }
788  }
789 
790  if (mi_ctx->vsbmc) {
791 
792  for (i = 0; i < NB_CLUSTERS; i++) {
793  mi_ctx->clusters[i].sum[0] = 0;
794  mi_ctx->clusters[i].sum[1] = 0;
795  mi_ctx->clusters[i].nb = 0;
796  }
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  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
801 
802  mi_ctx->clusters[0].sum[0] += block->mvs[0][0];
803  mi_ctx->clusters[0].sum[1] += block->mvs[0][1];
804  }
805 
806  mi_ctx->clusters[0].nb = mi_ctx->b_count;
807 
808  if (ret = cluster_mvs(mi_ctx))
809  return ret;
810  }
811  }
812  }
813 
814  return 0;
815 }
816 
818 {
819  MIContext *mi_ctx = ctx->priv;
820  AVFilterLink *input = ctx->inputs[0];
821  uint8_t *p1 = mi_ctx->frames[1].avf->data[0];
822  ptrdiff_t linesize1 = mi_ctx->frames[1].avf->linesize[0];
823  uint8_t *p2 = mi_ctx->frames[2].avf->data[0];
824  ptrdiff_t linesize2 = mi_ctx->frames[2].avf->linesize[0];
825 
826  if (mi_ctx->scd_method == SCD_METHOD_FDIFF) {
827  double ret = 0, mafd, diff;
828  uint64_t sad;
829  mi_ctx->sad(p1, linesize1, p2, linesize2, input->w, input->h, &sad);
830  mafd = (double) sad * 100.0 / (input->h * input->w) / (1 << mi_ctx->bitdepth);
831  diff = fabs(mafd - mi_ctx->prev_mafd);
832  ret = av_clipf(FFMIN(mafd, diff), 0, 100.0);
833  mi_ctx->prev_mafd = mafd;
834 
835  return ret >= mi_ctx->scd_threshold;
836  }
837 
838  return 0;
839 }
840 
841 #define ADD_PIXELS(b_weight, mv_x, mv_y)\
842  do {\
843  if (!b_weight || pixel_refs->nb + 1 >= NB_PIXEL_MVS)\
844  continue;\
845  pixel_refs->refs[pixel_refs->nb] = 1;\
846  pixel_weights->weights[pixel_refs->nb] = b_weight * (ALPHA_MAX - alpha);\
847  pixel_mvs->mvs[pixel_refs->nb][0] = av_clip((mv_x * alpha) / ALPHA_MAX, x_min, x_max);\
848  pixel_mvs->mvs[pixel_refs->nb][1] = av_clip((mv_y * alpha) / ALPHA_MAX, y_min, y_max);\
849  pixel_refs->nb++;\
850  pixel_refs->refs[pixel_refs->nb] = 2;\
851  pixel_weights->weights[pixel_refs->nb] = b_weight * alpha;\
852  pixel_mvs->mvs[pixel_refs->nb][0] = av_clip(-mv_x * (ALPHA_MAX - alpha) / ALPHA_MAX, x_min, x_max);\
853  pixel_mvs->mvs[pixel_refs->nb][1] = av_clip(-mv_y * (ALPHA_MAX - alpha) / ALPHA_MAX, y_min, y_max);\
854  pixel_refs->nb++;\
855  } while(0)
856 
857 static void bidirectional_obmc(MIContext *mi_ctx, int alpha)
858 {
859  int x, y;
860  int width = mi_ctx->frames[0].avf->width;
861  int height = mi_ctx->frames[0].avf->height;
862  int mb_y, mb_x, dir;
863 
864  for (y = 0; y < height; y++)
865  for (x = 0; x < width; x++)
866  mi_ctx->pixel_refs[x + y * width].nb = 0;
867 
868  for (dir = 0; dir < 2; dir++)
869  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
870  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
871  int a = dir ? alpha : (ALPHA_MAX - alpha);
872  int mv_x = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][0];
873  int mv_y = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][1];
874  int start_x, start_y;
875  int startc_x, startc_y, endc_x, endc_y;
876 
877  start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_x * a / ALPHA_MAX;
878  start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_y * a / ALPHA_MAX;
879 
880  startc_x = av_clip(start_x, 0, width - 1);
881  startc_y = av_clip(start_y, 0, height - 1);
882  endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
883  endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
884 
885  if (dir) {
886  mv_x = -mv_x;
887  mv_y = -mv_y;
888  }
889 
890  for (y = startc_y; y < endc_y; y++) {
891  int y_min = -y;
892  int y_max = height - y - 1;
893  for (x = startc_x; x < endc_x; x++) {
894  int x_min = -x;
895  int x_max = width - x - 1;
896  int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
897  PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
898  PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
899  PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
900 
901  ADD_PIXELS(obmc_weight, mv_x, mv_y);
902  }
903  }
904  }
905 }
906 
907 static void set_frame_data(MIContext *mi_ctx, int alpha, AVFrame *avf_out)
908 {
909  int x, y, plane;
910 
911  for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
912  int width = avf_out->width;
913  int height = avf_out->height;
914  int chroma = plane == 1 || plane == 2;
915 
916  for (y = 0; y < height; y++)
917  for (x = 0; x < width; x++) {
918  int x_mv, y_mv;
919  int weight_sum = 0;
920  int i, val = 0;
921  PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * avf_out->width];
922  PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * avf_out->width];
923  PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * avf_out->width];
924 
925  for (i = 0; i < pixel_refs->nb; i++)
926  weight_sum += pixel_weights->weights[i];
927 
928  if (!weight_sum || !pixel_refs->nb) {
929  pixel_weights->weights[0] = ALPHA_MAX - alpha;
930  pixel_refs->refs[0] = 1;
931  pixel_mvs->mvs[0][0] = 0;
932  pixel_mvs->mvs[0][1] = 0;
933  pixel_weights->weights[1] = alpha;
934  pixel_refs->refs[1] = 2;
935  pixel_mvs->mvs[1][0] = 0;
936  pixel_mvs->mvs[1][1] = 0;
937  pixel_refs->nb = 2;
938 
939  weight_sum = ALPHA_MAX;
940  }
941 
942  for (i = 0; i < pixel_refs->nb; i++) {
943  Frame *frame = &mi_ctx->frames[pixel_refs->refs[i]];
944  if (chroma) {
945  x_mv = (x >> mi_ctx->log2_chroma_w) + pixel_mvs->mvs[i][0] / (1 << mi_ctx->log2_chroma_w);
946  y_mv = (y >> mi_ctx->log2_chroma_h) + pixel_mvs->mvs[i][1] / (1 << mi_ctx->log2_chroma_h);
947  } else {
948  x_mv = x + pixel_mvs->mvs[i][0];
949  y_mv = y + pixel_mvs->mvs[i][1];
950  }
951 
952  val += pixel_weights->weights[i] * frame->avf->data[plane][x_mv + y_mv * frame->avf->linesize[plane]];
953  }
954 
955  val = ROUNDED_DIV(val, weight_sum);
956 
957  if (chroma)
958  avf_out->data[plane][(x >> mi_ctx->log2_chroma_w) + (y >> mi_ctx->log2_chroma_h) * avf_out->linesize[plane]] = val;
959  else
960  avf_out->data[plane][x + y * avf_out->linesize[plane]] = val;
961  }
962  }
963 }
964 
965 static void var_size_bmc(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n, int alpha)
966 {
967  int sb_x, sb_y;
968  int width = mi_ctx->frames[0].avf->width;
969  int height = mi_ctx->frames[0].avf->height;
970 
971  for (sb_y = 0; sb_y < 2; sb_y++)
972  for (sb_x = 0; sb_x < 2; sb_x++) {
973  Block *sb = &block->subs[sb_x + sb_y * 2];
974 
975  if (sb->sb)
976  var_size_bmc(mi_ctx, sb, x_mb + (sb_x << (n - 1)), y_mb + (sb_y << (n - 1)), n - 1, alpha);
977  else {
978  int x, y;
979  int mv_x = sb->mvs[0][0] * 2;
980  int mv_y = sb->mvs[0][1] * 2;
981 
982  int start_x = x_mb + (sb_x << (n - 1));
983  int start_y = y_mb + (sb_y << (n - 1));
984  int end_x = start_x + (1 << (n - 1));
985  int end_y = start_y + (1 << (n - 1));
986 
987  for (y = start_y; y < end_y; y++) {
988  int y_min = -y;
989  int y_max = height - y - 1;
990  for (x = start_x; x < end_x; x++) {
991  int x_min = -x;
992  int x_max = width - x - 1;
993  PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
994  PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
995  PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
996 
997  ADD_PIXELS(PX_WEIGHT_MAX, mv_x, mv_y);
998  }
999  }
1000  }
1001  }
1002 }
1003 
1004 static void bilateral_obmc(MIContext *mi_ctx, Block *block, int mb_x, int mb_y, int alpha)
1005 {
1006  int x, y;
1007  int width = mi_ctx->frames[0].avf->width;
1008  int height = mi_ctx->frames[0].avf->height;
1009 
1010  Block *nb;
1011  int nb_x, nb_y;
1012  uint64_t sbads[9];
1013 
1014  int mv_x = block->mvs[0][0] * 2;
1015  int mv_y = block->mvs[0][1] * 2;
1016  int start_x, start_y;
1017  int startc_x, startc_y, endc_x, endc_y;
1018 
1019  if (mi_ctx->mc_mode == MC_MODE_AOBMC)
1020  for (nb_y = FFMAX(0, mb_y - 1); nb_y < FFMIN(mb_y + 2, mi_ctx->b_height); nb_y++)
1021  for (nb_x = FFMAX(0, mb_x - 1); nb_x < FFMIN(mb_x + 2, mi_ctx->b_width); nb_x++) {
1022  int x_nb = nb_x << mi_ctx->log2_mb_size;
1023  int y_nb = nb_y << mi_ctx->log2_mb_size;
1024 
1025  if (nb_x - mb_x || nb_y - mb_y)
1026  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]);
1027  }
1028 
1029  start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1030  start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1031 
1032  startc_x = av_clip(start_x, 0, width - 1);
1033  startc_y = av_clip(start_y, 0, height - 1);
1034  endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
1035  endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
1036 
1037  for (y = startc_y; y < endc_y; y++) {
1038  int y_min = -y;
1039  int y_max = height - y - 1;
1040  for (x = startc_x; x < endc_x; x++) {
1041  int x_min = -x;
1042  int x_max = width - x - 1;
1043  int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
1044  PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
1045  PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
1046  PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
1047 
1048  if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
1049  nb_x = (((x - start_x) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1050  nb_y = (((y - start_y) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1051 
1052  if (nb_x || nb_y) {
1053  uint64_t sbad = sbads[nb_x + 1 + (nb_y + 1) * 3];
1054  nb = &mi_ctx->int_blocks[mb_x + nb_x + (mb_y + nb_y) * mi_ctx->b_width];
1055 
1056  if (sbad && sbad != UINT64_MAX && nb->sbad != UINT64_MAX) {
1057  int phi = av_clip(ALPHA_MAX * nb->sbad / sbad, 0, ALPHA_MAX);
1058  obmc_weight = obmc_weight * phi / ALPHA_MAX;
1059  }
1060  }
1061  }
1062 
1063  ADD_PIXELS(obmc_weight, mv_x, mv_y);
1064  }
1065  }
1066 }
1067 
1068 static void interpolate(AVFilterLink *inlink, AVFrame *avf_out)
1069 {
1070  AVFilterContext *ctx = inlink->dst;
1071  AVFilterLink *outlink = ctx->outputs[0];
1072  MIContext *mi_ctx = ctx->priv;
1073  int x, y;
1074  int plane, alpha;
1075  int64_t pts;
1076 
1077  pts = av_rescale(avf_out->pts, (int64_t) ALPHA_MAX * outlink->time_base.num * inlink->time_base.den,
1078  (int64_t) outlink->time_base.den * inlink->time_base.num);
1079 
1080  if (mi_ctx->frames[2].avf->pts > mi_ctx->frames[1].avf->pts) {
1081  alpha = (pts - mi_ctx->frames[1].avf->pts * ALPHA_MAX) / (mi_ctx->frames[2].avf->pts - mi_ctx->frames[1].avf->pts);
1082  alpha = av_clip(alpha, 0, ALPHA_MAX);
1083  } else {
1084  av_log(ctx, AV_LOG_DEBUG, "duplicate input PTS detected\n");
1085  alpha = 0;
1086  }
1087 
1088  if (alpha == 0 || alpha == ALPHA_MAX) {
1089  av_frame_copy(avf_out, alpha ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1090  return;
1091  }
1092 
1093  if (mi_ctx->scene_changed) {
1094  av_log(ctx, AV_LOG_DEBUG, "scene changed, input pts %"PRId64"\n", mi_ctx->frames[1].avf->pts);
1095  /* duplicate frame */
1096  av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1097  return;
1098  }
1099 
1100  switch(mi_ctx->mi_mode) {
1101  case MI_MODE_DUP:
1102  av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1103 
1104  break;
1105  case MI_MODE_BLEND:
1106  for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
1107  int width = avf_out->width;
1108  int height = avf_out->height;
1109 
1110  if (plane == 1 || plane == 2) {
1113  }
1114 
1115  for (y = 0; y < height; y++) {
1116  for (x = 0; x < width; x++) {
1117  avf_out->data[plane][x + y * avf_out->linesize[plane]] =
1118  (alpha * mi_ctx->frames[2].avf->data[plane][x + y * mi_ctx->frames[2].avf->linesize[plane]] +
1119  (ALPHA_MAX - alpha) * mi_ctx->frames[1].avf->data[plane][x + y * mi_ctx->frames[1].avf->linesize[plane]] + 512) >> 10;
1120  }
1121  }
1122  }
1123 
1124  break;
1125  case MI_MODE_MCI:
1126  if (mi_ctx->me_mode == ME_MODE_BIDIR) {
1127  bidirectional_obmc(mi_ctx, alpha);
1128  set_frame_data(mi_ctx, alpha, avf_out);
1129 
1130  } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
1131  int mb_x, mb_y;
1132  Block *block;
1133 
1134  for (y = 0; y < mi_ctx->frames[0].avf->height; y++)
1135  for (x = 0; x < mi_ctx->frames[0].avf->width; x++)
1136  mi_ctx->pixel_refs[x + y * mi_ctx->frames[0].avf->width].nb = 0;
1137 
1138  for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
1139  for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
1140  block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
1141 
1142  if (block->sb)
1143  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);
1144 
1145  bilateral_obmc(mi_ctx, block, mb_x, mb_y, alpha);
1146 
1147  }
1148 
1149  set_frame_data(mi_ctx, alpha, avf_out);
1150  }
1151 
1152  break;
1153  }
1154 }
1155 
1157 {
1158  AVFilterContext *ctx = inlink->dst;
1159  AVFilterLink *outlink = ctx->outputs[0];
1160  MIContext *mi_ctx = ctx->priv;
1161  int ret;
1162 
1163  if (avf_in->pts == AV_NOPTS_VALUE) {
1164  ret = ff_filter_frame(ctx->outputs[0], avf_in);
1165  return ret;
1166  }
1167 
1168  if (!mi_ctx->frames[NB_FRAMES - 1].avf || avf_in->pts < mi_ctx->frames[NB_FRAMES - 1].avf->pts) {
1169  av_log(ctx, AV_LOG_VERBOSE, "Initializing out pts from input pts %"PRId64"\n", avf_in->pts);
1170  mi_ctx->out_pts = av_rescale_q(avf_in->pts, inlink->time_base, outlink->time_base);
1171  }
1172 
1173  if (!mi_ctx->frames[NB_FRAMES - 1].avf)
1174  if (ret = inject_frame(inlink, av_frame_clone(avf_in)))
1175  return ret;
1176 
1177  if (ret = inject_frame(inlink, avf_in))
1178  return ret;
1179 
1180  if (!mi_ctx->frames[0].avf)
1181  return 0;
1182 
1184 
1185  for (;;) {
1186  AVFrame *avf_out;
1187 
1188  if (av_compare_ts(mi_ctx->out_pts, outlink->time_base, mi_ctx->frames[2].avf->pts, inlink->time_base) > 0)
1189  break;
1190 
1191  if (!(avf_out = ff_get_video_buffer(ctx->outputs[0], inlink->w, inlink->h)))
1192  return AVERROR(ENOMEM);
1193 
1194  av_frame_copy_props(avf_out, mi_ctx->frames[NB_FRAMES - 1].avf);
1195  avf_out->pts = mi_ctx->out_pts++;
1196  avf_out->duration = 1;
1197 
1198  interpolate(inlink, avf_out);
1199 
1200  if ((ret = ff_filter_frame(ctx->outputs[0], avf_out)) < 0)
1201  return ret;
1202  }
1203 
1204  return 0;
1205 }
1206 
1207 static av_cold void free_blocks(Block *block, int sb)
1208 {
1209  if (block->subs)
1210  free_blocks(block->subs, 1);
1211  if (sb)
1212  av_freep(&block);
1213 }
1214 
1216 {
1217  MIContext *mi_ctx = ctx->priv;
1218  int i, m;
1219 
1220  av_freep(&mi_ctx->pixel_mvs);
1221  av_freep(&mi_ctx->pixel_weights);
1222  av_freep(&mi_ctx->pixel_refs);
1223  if (mi_ctx->int_blocks)
1224  for (m = 0; m < mi_ctx->b_count; m++)
1225  free_blocks(&mi_ctx->int_blocks[m], 0);
1226  av_freep(&mi_ctx->int_blocks);
1227 
1228  for (i = 0; i < NB_FRAMES; i++) {
1229  Frame *frame = &mi_ctx->frames[i];
1230  av_freep(&frame->blocks);
1231  av_frame_free(&frame->avf);
1232  }
1233 
1234  for (i = 0; i < 3; i++)
1235  av_freep(&mi_ctx->mv_table[i]);
1236 }
1237 
1239  {
1240  .name = "default",
1241  .type = AVMEDIA_TYPE_VIDEO,
1242  .filter_frame = filter_frame,
1243  .config_props = config_input,
1244  },
1245 };
1246 
1248  {
1249  .name = "default",
1250  .type = AVMEDIA_TYPE_VIDEO,
1251  .config_props = config_output,
1252  },
1253 };
1254 
1256  .name = "minterpolate",
1257  .description = NULL_IF_CONFIG_SMALL("Frame rate conversion using Motion Interpolation."),
1258  .priv_size = sizeof(MIContext),
1259  .priv_class = &minterpolate_class,
1260  .uninit = uninit,
1264 };
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:116
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:100
obmc_linear32
static const uint8_t obmc_linear32[1024]
Definition: vf_minterpolate.c:51
AVMotionEstContext::data_ref
uint8_t * data_ref
Definition: motion_estimation.h:42
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *avf_in)
Definition: vf_minterpolate.c:1156
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:731
av_compare_ts
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
Compare two timestamps each in its own time base.
Definition: mathematics.c:147
AVMotionEstPredictor
Definition: motion_estimation.h:36
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: filters.h:242
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:1061
AVFrame::duration
int64_t duration
Duration of the frame, in the same units as pts.
Definition: frame.h:795
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:3170
minterpolate_outputs
static const AVFilterPad minterpolate_outputs[]
Definition: vf_minterpolate.c:1247
AV_OPT_TYPE_VIDEO_RATE
@ AV_OPT_TYPE_VIDEO_RATE
Underlying C type is AVRational.
Definition: opt.h:315
obmc_linear4
static const uint8_t obmc_linear4[16]
Definition: vf_minterpolate.c:116
ff_me_search_esa
uint64_t ff_me_search_esa(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:78
MIContext::pixel_weights
PixelWeights * pixel_weights
Definition: vf_minterpolate.c:180
bilateral_me
static void bilateral_me(MIContext *mi_ctx)
Definition: vf_minterpolate.c:558
int64_t
long long int64_t
Definition: coverity.c:34
mv
static const int8_t mv[256][2]
Definition: 4xm.c:81
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:162
AVMotionEstContext::data_cur
uint8_t * data_cur
Definition: motion_estimation.h:42
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:501
AVFrame::width
int width
Definition: frame.h:461
PixelRefs::refs
int8_t refs[NB_PIXEL_MVS]
Definition: vf_minterpolate.c:155
AVOption
AVOption.
Definition: opt.h:429
FLAGS
#define FLAGS
Definition: vf_minterpolate.c: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:225
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:1238
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
Frame
Definition: ffplay.c:152
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:205
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:410
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:3210
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:472
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:77
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: filters.h:38
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:209
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
set_frame_data
static void set_frame_data(MIContext *mi_ctx, int alpha, AVFrame *avf_out)
Definition: vf_minterpolate.c:907
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:60
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
Underlying C type is double.
Definition: opt.h:267
AVMotionEstContext::x_min
int x_min
Definition: motion_estimation.h:51
filters.h
MIContext::me_ctx
AVMotionEstContext me_ctx
Definition: vf_minterpolate.c:166
ME_MODE_BILAT
#define ME_MODE_BILAT
Definition: vf_minterpolate.c:34
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
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:965
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:609
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:841
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
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
AVMotionEstContext
Definition: motion_estimation.h:41
Cluster::sum
int64_t sum[2]
Definition: vf_minterpolate.c:134
MI_MODE_MCI
@ MI_MODE_MCI
Definition: vf_minterpolate.c:130
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:87
ff_me_search_ds
uint64_t ff_me_search_ds(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:245
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
if
if(ret)
Definition: filter_design.txt:179
get_sbad_ob
static uint64_t get_sbad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
Definition: vf_minterpolate.c: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:75
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:725
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:857
ROUNDED_DIV
#define ROUNDED_DIV(a, b)
Definition: common.h:58
motion_estimation.h
mathops.h
Frame::blocks
Block * blocks
Definition: vf_minterpolate.c:161
ff_vf_minterpolate
const AVFilter ff_vf_minterpolate
Definition: vf_minterpolate.c:1255
double
double
Definition: af_crystalizer.c:132
Block::mvs
int16_t mvs[2][2]
Definition: vf_minterpolate.c:139
av_clipf
av_clipf
Definition: af_crystalizer.c:122
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
Block::subs
struct Block * subs
Definition: vf_minterpolate.c:143
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
scene_sad.h
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
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:1207
ff_me_search_hexbs
uint64_t ff_me_search_hexbs(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int *mv)
Definition: motion_estimation.c:300
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
height
#define height
Definition: dsp.h:85
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:1015
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:817
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:416
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:166
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:174
AV_ME_METHOD_EPZS
#define AV_ME_METHOD_EPZS
Definition: motion_estimation.h:33
interpolate
static void interpolate(AVFilterLink *inlink, AVFrame *avf_out)
Definition: vf_minterpolate.c:1068
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
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:409
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: filters.h:44
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:201
mid_pred
#define mid_pred
Definition: mathops.h:96
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:461
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(minterpolate)
AV_ME_METHOD_UMH
#define AV_ME_METHOD_UMH
Definition: motion_estimation.h:34
var_size_bme
static int var_size_bme(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n)
Definition: vf_minterpolate.c:579
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:457
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:641
AV_ME_METHOD_NTSS
#define AV_ME_METHOD_NTSS
Definition: motion_estimation.h:29
AVMotionEstContext::linesize
int linesize
Definition: motion_estimation.h:43
NB_FRAMES
#define NB_FRAMES
Definition: vf_minterpolate.c:42
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
MIContext::frame_rate
AVRational frame_rate
Definition: vf_minterpolate.c:167
MIContext::clusters
Cluster clusters[NB_CLUSTERS]
Definition: vf_minterpolate.c: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
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:434
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
width
#define width
Definition: dsp.h:85
AVMotionEstPredictor::mvs
int mvs[10][2]
Definition: motion_estimation.h:37
AV_ME_METHOD_TDLS
#define AV_ME_METHOD_TDLS
Definition: motion_estimation.h:28
PixelRefs
Definition: vf_minterpolate.c:154
Block::sbad
uint64_t sbad
Definition: vf_minterpolate.c:141
AVMotionEstContext::preds
AVMotionEstPredictor preds[2]
Definition: motion_estimation.h:58
AVMotionEstContext::get_cost
uint64_t(* get_cost)(struct AVMotionEstContext *me_ctx, int x_mb, int y_mb, int mv_x, int mv_y)
Definition: motion_estimation.h:60
bilateral_obmc
static void bilateral_obmc(MIContext *mi_ctx, Block *block, int mb_x, int mb_y, int alpha)
Definition: vf_minterpolate.c:1004
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:173
AVMotionEstContext::mb_size
int mb_size
Definition: motion_estimation.h:45
av_ceil_log2_c
static av_always_inline av_const int av_ceil_log2_c(int x)
Compute ceil(log2(x)).
Definition: common.h:436
MIContext
Definition: vf_minterpolate.c:164
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_minterpolate.c:1215