2 * Copyright (c) 2014-2015 Michael Niedermayer <michaelni@gmx.at>
3 * Copyright (c) 2016 Davinder Singh (DSM_) <ds.mudhar<@gmail.com>
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "motion_estimation.h"
23 #include "libavcodec/mathops.h"
24 #include "libavutil/avassert.h"
25 #include "libavutil/common.h"
26 #include "libavutil/motion_vector.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/pixdesc.h"
33 #include "scene_sad.h"
35 #define ME_MODE_BIDIR 0
36 #define ME_MODE_BILAT 1
38 #define MC_MODE_OBMC 0
39 #define MC_MODE_AOBMC 1
41 #define SCD_METHOD_NONE 0
42 #define SCD_METHOD_FDIFF 1
45 #define NB_PIXEL_MVS 32
46 #define NB_CLUSTERS 128
48 #define ALPHA_MAX 1024
49 #define CLUSTER_THRESHOLD 4
50 #define PX_WEIGHT_MAX 255
51 #define COST_PRED_SCALE 64
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,
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,
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,
118 static const uint8_t obmc_linear4[16] = {
125 static const uint8_t * const obmc_tab_linear[4]= {
126 obmc_linear32, obmc_linear16, obmc_linear8, obmc_linear4
135 typedef struct Cluster {
140 typedef struct Block {
148 typedef struct PixelMVS {
149 int16_t mvs[NB_PIXEL_MVS][2];
152 typedef struct PixelWeights {
153 uint32_t weights[NB_PIXEL_MVS];
156 typedef struct PixelRefs {
157 int8_t refs[NB_PIXEL_MVS];
161 typedef struct Frame {
166 typedef struct MIContext {
167 const AVClass *class;
168 AVMotionEstContext me_ctx;
169 AVRational frame_rate;
178 Frame frames[NB_FRAMES];
179 Cluster clusters[NB_CLUSTERS];
182 PixelWeights *pixel_weights;
183 PixelRefs *pixel_refs;
184 int (*mv_table[3])[2][2];
186 int b_width, b_height, b_count;
193 double scd_threshold;
200 #define OFFSET(x) offsetof(MIContext, x)
201 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
202 #define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, 0, 0, FLAGS, unit }
204 static const AVOption minterpolate_options[] = {
205 { "fps", "output's frame rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "60"}, 0, INT_MAX, FLAGS },
206 { "mi_mode", "motion interpolation mode", OFFSET(mi_mode), AV_OPT_TYPE_INT, {.i64 = MI_MODE_MCI}, MI_MODE_DUP, MI_MODE_MCI, FLAGS, "mi_mode" },
207 CONST("dup", "duplicate frames", MI_MODE_DUP, "mi_mode"),
208 CONST("blend", "blend frames", MI_MODE_BLEND, "mi_mode"),
209 CONST("mci", "motion compensated interpolation", MI_MODE_MCI, "mi_mode"),
210 { "mc_mode", "motion compensation mode", OFFSET(mc_mode), AV_OPT_TYPE_INT, {.i64 = MC_MODE_OBMC}, MC_MODE_OBMC, MC_MODE_AOBMC, FLAGS, "mc_mode" },
211 CONST("obmc", "overlapped block motion compensation", MC_MODE_OBMC, "mc_mode"),
212 CONST("aobmc", "adaptive overlapped block motion compensation", MC_MODE_AOBMC, "mc_mode"),
213 { "me_mode", "motion estimation mode", OFFSET(me_mode), AV_OPT_TYPE_INT, {.i64 = ME_MODE_BILAT}, ME_MODE_BIDIR, ME_MODE_BILAT, FLAGS, "me_mode" },
214 CONST("bidir", "bidirectional motion estimation", ME_MODE_BIDIR, "me_mode"),
215 CONST("bilat", "bilateral motion estimation", ME_MODE_BILAT, "me_mode"),
216 { "me", "motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = AV_ME_METHOD_EPZS}, AV_ME_METHOD_ESA, AV_ME_METHOD_UMH, FLAGS, "me" },
217 CONST("esa", "exhaustive search", AV_ME_METHOD_ESA, "me"),
218 CONST("tss", "three step search", AV_ME_METHOD_TSS, "me"),
219 CONST("tdls", "two dimensional logarithmic search", AV_ME_METHOD_TDLS, "me"),
220 CONST("ntss", "new three step search", AV_ME_METHOD_NTSS, "me"),
221 CONST("fss", "four step search", AV_ME_METHOD_FSS, "me"),
222 CONST("ds", "diamond search", AV_ME_METHOD_DS, "me"),
223 CONST("hexbs", "hexagon-based search", AV_ME_METHOD_HEXBS, "me"),
224 CONST("epzs", "enhanced predictive zonal search", AV_ME_METHOD_EPZS, "me"),
225 CONST("umh", "uneven multi-hexagon search", AV_ME_METHOD_UMH, "me"),
226 { "mb_size", "macroblock size", OFFSET(mb_size), AV_OPT_TYPE_INT, {.i64 = 16}, 4, 16, FLAGS },
227 { "search_param", "search parameter", OFFSET(search_param), AV_OPT_TYPE_INT, {.i64 = 32}, 4, INT_MAX, FLAGS },
228 { "vsbmc", "variable-size block motion compensation", OFFSET(vsbmc), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
229 { "scd", "scene change detection method", OFFSET(scd_method), AV_OPT_TYPE_INT, {.i64 = SCD_METHOD_FDIFF}, SCD_METHOD_NONE, SCD_METHOD_FDIFF, FLAGS, "scene" },
230 CONST("none", "disable detection", SCD_METHOD_NONE, "scene"),
231 CONST("fdiff", "frame difference", SCD_METHOD_FDIFF, "scene"),
232 { "scd_threshold", "scene change threshold", OFFSET(scd_threshold), AV_OPT_TYPE_DOUBLE, {.dbl = 5.0}, 0, 100.0, FLAGS },
236 AVFILTER_DEFINE_CLASS(minterpolate);
238 static int query_formats(AVFilterContext *ctx)
240 static const enum AVPixelFormat pix_fmts[] = {
241 AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
242 AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P,
243 AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P,
244 AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P,
245 AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P,
247 AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,
252 AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
254 return AVERROR(ENOMEM);
255 return ff_set_common_formats(ctx, fmts_list);
258 static uint64_t get_sbad(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
260 uint8_t *data_cur = me_ctx->data_cur;
261 uint8_t *data_next = me_ctx->data_ref;
262 int linesize = me_ctx->linesize;
263 int mv_x1 = x_mv - x;
264 int mv_y1 = y_mv - y;
265 int mv_x, mv_y, i, j;
268 x = av_clip(x, me_ctx->x_min, me_ctx->x_max);
269 y = av_clip(y, me_ctx->y_min, me_ctx->y_max);
270 mv_x = av_clip(x_mv - x, -FFMIN(x - me_ctx->x_min, me_ctx->x_max - x), FFMIN(x - me_ctx->x_min, me_ctx->x_max - x));
271 mv_y = av_clip(y_mv - y, -FFMIN(y - me_ctx->y_min, me_ctx->y_max - y), FFMIN(y - me_ctx->y_min, me_ctx->y_max - y));
273 data_cur += (y + mv_y) * linesize;
274 data_next += (y - mv_y) * linesize;
276 for (j = 0; j < me_ctx->mb_size; j++)
277 for (i = 0; i < me_ctx->mb_size; i++)
278 sbad += FFABS(data_cur[x + mv_x + i + j * linesize] - data_next[x - mv_x + i + j * linesize]);
280 return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - me_ctx->pred_y)) * COST_PRED_SCALE;
283 static uint64_t get_sbad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
285 uint8_t *data_cur = me_ctx->data_cur;
286 uint8_t *data_next = me_ctx->data_ref;
287 int linesize = me_ctx->linesize;
288 int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
289 int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
290 int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
291 int y_max = me_ctx->y_max - me_ctx->mb_size / 2;
292 int mv_x1 = x_mv - x;
293 int mv_y1 = y_mv - y;
294 int mv_x, mv_y, i, j;
297 x = av_clip(x, x_min, x_max);
298 y = av_clip(y, y_min, y_max);
299 mv_x = av_clip(x_mv - x, -FFMIN(x - x_min, x_max - x), FFMIN(x - x_min, x_max - x));
300 mv_y = av_clip(y_mv - y, -FFMIN(y - y_min, y_max - y), FFMIN(y - y_min, y_max - y));
302 for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
303 for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
304 sbad += FFABS(data_cur[x + mv_x + i + (y + mv_y + j) * linesize] - data_next[x - mv_x + i + (y - mv_y + j) * linesize]);
306 return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - me_ctx->pred_y)) * COST_PRED_SCALE;
309 static uint64_t get_sad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
311 uint8_t *data_ref = me_ctx->data_ref;
312 uint8_t *data_cur = me_ctx->data_cur;
313 int linesize = me_ctx->linesize;
314 int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
315 int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
316 int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
317 int y_max = me_ctx->y_max - me_ctx->mb_size / 2;
323 x = av_clip(x, x_min, x_max);
324 y = av_clip(y, y_min, y_max);
325 x_mv = av_clip(x_mv, x_min, x_max);
326 y_mv = av_clip(y_mv, y_min, y_max);
328 for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
329 for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
330 sad += FFABS(data_ref[x_mv + i + (y_mv + j) * linesize] - data_cur[x + i + (y + j) * linesize]);
332 return sad + (FFABS(mv_x - me_ctx->pred_x) + FFABS(mv_y - me_ctx->pred_y)) * COST_PRED_SCALE;
335 static int config_input(AVFilterLink *inlink)
337 MIContext *mi_ctx = inlink->dst->priv;
338 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
339 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
340 const int height = inlink->h;
341 const int width = inlink->w;
344 mi_ctx->log2_chroma_h = desc->log2_chroma_h;
345 mi_ctx->log2_chroma_w = desc->log2_chroma_w;
347 mi_ctx->nb_planes = av_pix_fmt_count_planes(inlink->format);
349 mi_ctx->log2_mb_size = av_ceil_log2_c(mi_ctx->mb_size);
350 mi_ctx->mb_size = 1 << mi_ctx->log2_mb_size;
352 mi_ctx->b_width = width >> mi_ctx->log2_mb_size;
353 mi_ctx->b_height = height >> mi_ctx->log2_mb_size;
354 mi_ctx->b_count = mi_ctx->b_width * mi_ctx->b_height;
356 for (i = 0; i < NB_FRAMES; i++) {
357 Frame *frame = &mi_ctx->frames[i];
358 frame->blocks = av_mallocz_array(mi_ctx->b_count, sizeof(Block));
360 return AVERROR(ENOMEM);
363 if (mi_ctx->mi_mode == MI_MODE_MCI) {
364 mi_ctx->pixel_mvs = av_mallocz_array(width * height, sizeof(PixelMVS));
365 mi_ctx->pixel_weights = av_mallocz_array(width * height, sizeof(PixelWeights));
366 mi_ctx->pixel_refs = av_mallocz_array(width * height, sizeof(PixelRefs));
367 if (!mi_ctx->pixel_mvs || !mi_ctx->pixel_weights || !mi_ctx->pixel_refs) {
368 ret = AVERROR(ENOMEM);
372 if (mi_ctx->me_mode == ME_MODE_BILAT)
373 if (!(mi_ctx->int_blocks = av_mallocz_array(mi_ctx->b_count, sizeof(Block))))
374 return AVERROR(ENOMEM);
376 if (mi_ctx->me_method == AV_ME_METHOD_EPZS) {
377 for (i = 0; i < 3; i++) {
378 mi_ctx->mv_table[i] = av_mallocz_array(mi_ctx->b_count, sizeof(*mi_ctx->mv_table[0]));
379 if (!mi_ctx->mv_table[i])
380 return AVERROR(ENOMEM);
385 if (mi_ctx->scd_method == SCD_METHOD_FDIFF) {
386 mi_ctx->sad = ff_scene_sad_get_fn(8);
388 return AVERROR(EINVAL);
391 ff_me_init_context(me_ctx, mi_ctx->mb_size, mi_ctx->search_param, width, height, 0, (mi_ctx->b_width - 1) << mi_ctx->log2_mb_size, 0, (mi_ctx->b_height - 1) << mi_ctx->log2_mb_size);
393 if (mi_ctx->me_mode == ME_MODE_BIDIR)
394 me_ctx->get_cost = &get_sad_ob;
395 else if (mi_ctx->me_mode == ME_MODE_BILAT)
396 me_ctx->get_cost = &get_sbad_ob;
400 for (i = 0; i < NB_FRAMES; i++)
401 av_freep(&mi_ctx->frames[i].blocks);
402 av_freep(&mi_ctx->pixel_mvs);
403 av_freep(&mi_ctx->pixel_weights);
404 av_freep(&mi_ctx->pixel_refs);
408 static int config_output(AVFilterLink *outlink)
410 MIContext *mi_ctx = outlink->src->priv;
412 outlink->frame_rate = mi_ctx->frame_rate;
413 outlink->time_base = av_inv_q(mi_ctx->frame_rate);
418 #define ADD_PRED(preds, px, py)\
420 preds.mvs[preds.nb][0] = px;\
421 preds.mvs[preds.nb][1] = py;\
425 static void search_mv(MIContext *mi_ctx, Block *blocks, int mb_x, int mb_y, int dir)
427 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
428 AVMotionEstPredictor *preds = me_ctx->preds;
429 Block *block = &blocks[mb_x + mb_y * mi_ctx->b_width];
431 const int x_mb = mb_x << mi_ctx->log2_mb_size;
432 const int y_mb = mb_y << mi_ctx->log2_mb_size;
433 const int mb_i = mb_x + mb_y * mi_ctx->b_width;
434 int mv[2] = {x_mb, y_mb};
436 switch (mi_ctx->me_method) {
437 case AV_ME_METHOD_ESA:
438 ff_me_search_esa(me_ctx, x_mb, y_mb, mv);
440 case AV_ME_METHOD_TSS:
441 ff_me_search_tss(me_ctx, x_mb, y_mb, mv);
443 case AV_ME_METHOD_TDLS:
444 ff_me_search_tdls(me_ctx, x_mb, y_mb, mv);
446 case AV_ME_METHOD_NTSS:
447 ff_me_search_ntss(me_ctx, x_mb, y_mb, mv);
449 case AV_ME_METHOD_FSS:
450 ff_me_search_fss(me_ctx, x_mb, y_mb, mv);
452 case AV_ME_METHOD_DS:
453 ff_me_search_ds(me_ctx, x_mb, y_mb, mv);
455 case AV_ME_METHOD_HEXBS:
456 ff_me_search_hexbs(me_ctx, x_mb, y_mb, mv);
458 case AV_ME_METHOD_EPZS:
463 ADD_PRED(preds[0], 0, 0);
465 //left mb in current frame
467 ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - 1][dir][0], mi_ctx->mv_table[0][mb_i - 1][dir][1]);
469 //top mb in current frame
471 ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width][dir][0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width][dir][1]);
473 //top-right mb in current frame
474 if (mb_y > 0 && mb_x + 1 < mi_ctx->b_width)
475 ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width + 1][dir][0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width + 1][dir][1]);
478 if (preds[0].nb == 4) {
479 me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
480 me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
481 } else if (preds[0].nb == 3) {
482 me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
483 me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
484 } else if (preds[0].nb == 2) {
485 me_ctx->pred_x = preds[0].mvs[1][0];
486 me_ctx->pred_y = preds[0].mvs[1][1];
492 //collocated mb in prev frame
493 ADD_PRED(preds[0], mi_ctx->mv_table[1][mb_i][dir][0], mi_ctx->mv_table[1][mb_i][dir][1]);
495 //accelerator motion vector of collocated block in prev frame
496 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i][dir][0] + (mi_ctx->mv_table[1][mb_i][dir][0] - mi_ctx->mv_table[2][mb_i][dir][0]),
497 mi_ctx->mv_table[1][mb_i][dir][1] + (mi_ctx->mv_table[1][mb_i][dir][1] - mi_ctx->mv_table[2][mb_i][dir][1]));
499 //left mb in prev frame
501 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i - 1][dir][0], mi_ctx->mv_table[1][mb_i - 1][dir][1]);
503 //top mb in prev frame
505 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i - mi_ctx->b_width][dir][0], mi_ctx->mv_table[1][mb_i - mi_ctx->b_width][dir][1]);
507 //right mb in prev frame
508 if (mb_x + 1 < mi_ctx->b_width)
509 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i + 1][dir][0], mi_ctx->mv_table[1][mb_i + 1][dir][1]);
511 //bottom mb in prev frame
512 if (mb_y + 1 < mi_ctx->b_height)
513 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i + mi_ctx->b_width][dir][0], mi_ctx->mv_table[1][mb_i + mi_ctx->b_width][dir][1]);
515 ff_me_search_epzs(me_ctx, x_mb, y_mb, mv);
517 mi_ctx->mv_table[0][mb_i][dir][0] = mv[0] - x_mb;
518 mi_ctx->mv_table[0][mb_i][dir][1] = mv[1] - y_mb;
521 case AV_ME_METHOD_UMH:
525 ADD_PRED(preds[0], 0, 0);
527 //left mb in current frame
529 ADD_PRED(preds[0], blocks[mb_i - 1].mvs[dir][0], blocks[mb_i - 1].mvs[dir][1]);
532 //top mb in current frame
533 ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width].mvs[dir][0], blocks[mb_i - mi_ctx->b_width].mvs[dir][1]);
535 //top-right mb in current frame
536 if (mb_x + 1 < mi_ctx->b_width)
537 ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width + 1].mvs[dir][0], blocks[mb_i - mi_ctx->b_width + 1].mvs[dir][1]);
538 //top-left mb in current frame
540 ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width - 1].mvs[dir][0], blocks[mb_i - mi_ctx->b_width - 1].mvs[dir][1]);
544 if (preds[0].nb == 4) {
545 me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
546 me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
547 } else if (preds[0].nb == 3) {
548 me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
549 me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
550 } else if (preds[0].nb == 2) {
551 me_ctx->pred_x = preds[0].mvs[1][0];
552 me_ctx->pred_y = preds[0].mvs[1][1];
558 ff_me_search_umh(me_ctx, x_mb, y_mb, mv);
563 block->mvs[dir][0] = mv[0] - x_mb;
564 block->mvs[dir][1] = mv[1] - y_mb;
567 static void bilateral_me(MIContext *mi_ctx)
572 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
573 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
574 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
579 block->mvs[0][0] = 0;
580 block->mvs[0][1] = 0;
583 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
584 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
585 search_mv(mi_ctx, mi_ctx->int_blocks, mb_x, mb_y, 0);
588 static int var_size_bme(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n)
590 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
591 uint64_t cost_sb, cost_old;
592 int mb_size = me_ctx->mb_size;
593 int search_param = me_ctx->search_param;
598 me_ctx->mb_size = 1 << n;
599 cost_old = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
600 me_ctx->mb_size = mb_size;
608 block->subs = av_mallocz_array(4, sizeof(Block));
610 return AVERROR(ENOMEM);
615 for (y = 0; y < 2; y++)
616 for (x = 0; x < 2; x++) {
617 Block *sb = &block->subs[x + y * 2];
618 int mv[2] = {x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]};
620 me_ctx->mb_size = 1 << (n - 1);
621 me_ctx->search_param = 2;
622 me_ctx->pred_x = block->mvs[0][0];
623 me_ctx->pred_y = block->mvs[0][1];
625 cost_sb = ff_me_search_ds(&mi_ctx->me_ctx, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1], mv);
629 me_ctx->mb_size = mb_size;
630 me_ctx->search_param = search_param;
632 if (cost_sb < cost_old / 4) {
633 sb->mvs[0][0] = mv_x;
634 sb->mvs[0][1] = mv_y;
637 if (ret = var_size_bme(mi_ctx, sb, x_mb + (x << (n - 1)), y_mb + (y << (n - 1)), n - 1))
650 static int cluster_mvs(MIContext *mi_ctx)
652 int changed, c, c_max = 0;
653 int mb_x, mb_y, x, y;
654 int mv_x, mv_y, avg_x, avg_y, dx, dy;
657 Cluster *cluster, *cluster_new;
661 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
662 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
663 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
665 cluster = &mi_ctx->clusters[c];
666 mv_x = block->mvs[0][0];
667 mv_y = block->mvs[0][1];
672 avg_x = cluster->sum[0] / cluster->nb;
673 avg_y = cluster->sum[1] / cluster->nb;
677 if (FFABS(dx) > CLUSTER_THRESHOLD || FFABS(dy) > CLUSTER_THRESHOLD) {
679 for (d = 1; d < 5; d++)
680 for (y = FFMAX(mb_y - d, 0); y < FFMIN(mb_y + d + 1, mi_ctx->b_height); y++)
681 for (x = FFMAX(mb_x - d, 0); x < FFMIN(mb_x + d + 1, mi_ctx->b_width); x++) {
682 Block *nb = &mi_ctx->int_blocks[x + y * mi_ctx->b_width];
683 if (nb->cid > block->cid) {
684 if (nb->cid < c || c == block->cid)
692 if (c >= NB_CLUSTERS) {
696 cluster_new = &mi_ctx->clusters[c];
697 cluster_new->sum[0] += mv_x;
698 cluster_new->sum[1] += mv_y;
699 cluster->sum[0] -= mv_x;
700 cluster->sum[1] -= mv_y;
704 c_max = FFMAX(c_max, c);
712 /* find boundaries */
713 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
714 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
715 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
716 for (y = FFMAX(mb_y - 1, 0); y < FFMIN(mb_y + 2, mi_ctx->b_height); y++)
717 for (x = FFMAX(mb_x - 1, 0); x < FFMIN(mb_x + 2, mi_ctx->b_width); x++) {
721 if ((x - mb_x) && (y - mb_y) || !dx && !dy)
724 if (!mb_x || !mb_y || mb_x == mi_ctx->b_width - 1 || mb_y == mi_ctx->b_height - 1)
727 if (block->cid != mi_ctx->int_blocks[x + y * mi_ctx->b_width].cid) {
728 if (!dx && block->cid == mi_ctx->int_blocks[x + (mb_y - dy) * mi_ctx->b_width].cid ||
729 !dy && block->cid == mi_ctx->int_blocks[(mb_x - dx) + y * mi_ctx->b_width].cid) {
730 if (ret = var_size_bme(mi_ctx, block, mb_x << mi_ctx->log2_mb_size, mb_y << mi_ctx->log2_mb_size, mi_ctx->log2_mb_size))
740 static int inject_frame(AVFilterLink *inlink, AVFrame *avf_in)
742 AVFilterContext *ctx = inlink->dst;
743 MIContext *mi_ctx = ctx->priv;
747 av_frame_free(&mi_ctx->frames[0].avf);
748 frame_tmp = mi_ctx->frames[0];
749 memmove(&mi_ctx->frames[0], &mi_ctx->frames[1], sizeof(mi_ctx->frames[0]) * (NB_FRAMES - 1));
750 mi_ctx->frames[NB_FRAMES - 1] = frame_tmp;
751 mi_ctx->frames[NB_FRAMES - 1].avf = avf_in;
753 if (mi_ctx->mi_mode == MI_MODE_MCI) {
755 if (mi_ctx->me_method == AV_ME_METHOD_EPZS) {
756 mi_ctx->mv_table[2] = memcpy(mi_ctx->mv_table[2], mi_ctx->mv_table[1], sizeof(*mi_ctx->mv_table[1]) * mi_ctx->b_count);
757 mi_ctx->mv_table[1] = memcpy(mi_ctx->mv_table[1], mi_ctx->mv_table[0], sizeof(*mi_ctx->mv_table[0]) * mi_ctx->b_count);
760 if (mi_ctx->me_mode == ME_MODE_BIDIR) {
762 if (mi_ctx->frames[1].avf) {
763 for (dir = 0; dir < 2; dir++) {
764 mi_ctx->me_ctx.linesize = mi_ctx->frames[2].avf->linesize[0];
765 mi_ctx->me_ctx.data_cur = mi_ctx->frames[2].avf->data[0];
766 mi_ctx->me_ctx.data_ref = mi_ctx->frames[dir ? 3 : 1].avf->data[0];
768 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
769 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
770 search_mv(mi_ctx, mi_ctx->frames[2].blocks, mb_x, mb_y, dir);
774 } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
778 if (!mi_ctx->frames[0].avf)
781 mi_ctx->me_ctx.linesize = mi_ctx->frames[0].avf->linesize[0];
782 mi_ctx->me_ctx.data_cur = mi_ctx->frames[1].avf->data[0];
783 mi_ctx->me_ctx.data_ref = mi_ctx->frames[2].avf->data[0];
785 bilateral_me(mi_ctx);
787 if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
789 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
790 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
791 int x_mb = mb_x << mi_ctx->log2_mb_size;
792 int y_mb = mb_y << mi_ctx->log2_mb_size;
793 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
795 block->sbad = get_sbad(&mi_ctx->me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
801 for (i = 0; i < NB_CLUSTERS; i++) {
802 mi_ctx->clusters[i].sum[0] = 0;
803 mi_ctx->clusters[i].sum[1] = 0;
804 mi_ctx->clusters[i].nb = 0;
807 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
808 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
809 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
811 mi_ctx->clusters[0].sum[0] += block->mvs[0][0];
812 mi_ctx->clusters[0].sum[1] += block->mvs[0][1];
815 mi_ctx->clusters[0].nb = mi_ctx->b_count;
817 if (ret = cluster_mvs(mi_ctx))
826 static int detect_scene_change(MIContext *mi_ctx)
828 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
829 uint8_t *p1 = mi_ctx->frames[1].avf->data[0];
830 ptrdiff_t linesize1 = mi_ctx->frames[1].avf->linesize[0];
831 uint8_t *p2 = mi_ctx->frames[2].avf->data[0];
832 ptrdiff_t linesize2 = mi_ctx->frames[2].avf->linesize[0];
834 if (mi_ctx->scd_method == SCD_METHOD_FDIFF) {
835 double ret = 0, mafd = HUGE_VAL, diff;
837 AVDictionaryEntry *e_mafd = NULL;
840 e_mafd = av_dict_get(mi_ctx->frames[2].avf->metadata, "lavfi.scd.mafd", NULL, AV_DICT_MATCH_CASE);
842 mafd = strtod(e_mafd->value, &tail);
843 if (*tail || mafd == HUGE_VAL) {
844 mi_ctx->sad(p1, linesize1, p2, linesize2, me_ctx->width, me_ctx->height, &sad);
846 mafd = (double) sad / (me_ctx->height * me_ctx->width * 3);
848 diff = fabs(mafd - mi_ctx->prev_mafd);
849 ret = av_clipf(FFMIN(mafd, diff), 0, 100.0);
850 mi_ctx->prev_mafd = mafd;
852 return ret >= mi_ctx->scd_threshold;
858 #define ADD_PIXELS(b_weight, mv_x, mv_y)\
860 if (!b_weight || pixel_refs->nb + 1 >= NB_PIXEL_MVS)\
862 pixel_refs->refs[pixel_refs->nb] = 1;\
863 pixel_weights->weights[pixel_refs->nb] = b_weight * (ALPHA_MAX - alpha);\
864 pixel_mvs->mvs[pixel_refs->nb][0] = av_clip((mv_x * alpha) / ALPHA_MAX, x_min, x_max);\
865 pixel_mvs->mvs[pixel_refs->nb][1] = av_clip((mv_y * alpha) / ALPHA_MAX, y_min, y_max);\
867 pixel_refs->refs[pixel_refs->nb] = 2;\
868 pixel_weights->weights[pixel_refs->nb] = b_weight * alpha;\
869 pixel_mvs->mvs[pixel_refs->nb][0] = av_clip(-mv_x * (ALPHA_MAX - alpha) / ALPHA_MAX, x_min, x_max);\
870 pixel_mvs->mvs[pixel_refs->nb][1] = av_clip(-mv_y * (ALPHA_MAX - alpha) / ALPHA_MAX, y_min, y_max);\
874 static void bidirectional_obmc(MIContext *mi_ctx, int alpha)
877 int width = mi_ctx->frames[0].avf->width;
878 int height = mi_ctx->frames[0].avf->height;
881 for (y = 0; y < height; y++)
882 for (x = 0; x < width; x++)
883 mi_ctx->pixel_refs[x + y * width].nb = 0;
885 for (dir = 0; dir < 2; dir++)
886 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
887 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
888 int a = dir ? alpha : (ALPHA_MAX - alpha);
889 int mv_x = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][0];
890 int mv_y = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][1];
891 int start_x, start_y;
892 int startc_x, startc_y, endc_x, endc_y;
894 start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_x * a / ALPHA_MAX;
895 start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_y * a / ALPHA_MAX;
897 startc_x = av_clip(start_x, 0, width - 1);
898 startc_y = av_clip(start_y, 0, height - 1);
899 endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
900 endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
907 for (y = startc_y; y < endc_y; y++) {
909 int y_max = height - y - 1;
910 for (x = startc_x; x < endc_x; x++) {
912 int x_max = width - x - 1;
913 int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
914 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
915 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
916 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
918 ADD_PIXELS(obmc_weight, mv_x, mv_y);
924 static void set_frame_data(MIContext *mi_ctx, int alpha, AVFrame *avf_out)
928 for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
929 int width = avf_out->width;
930 int height = avf_out->height;
931 int chroma = plane == 1 || plane == 2;
933 for (y = 0; y < height; y++)
934 for (x = 0; x < width; x++) {
938 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * avf_out->width];
939 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * avf_out->width];
940 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * avf_out->width];
942 for (i = 0; i < pixel_refs->nb; i++)
943 weight_sum += pixel_weights->weights[i];
945 if (!weight_sum || !pixel_refs->nb) {
946 pixel_weights->weights[0] = ALPHA_MAX - alpha;
947 pixel_refs->refs[0] = 1;
948 pixel_mvs->mvs[0][0] = 0;
949 pixel_mvs->mvs[0][1] = 0;
950 pixel_weights->weights[1] = alpha;
951 pixel_refs->refs[1] = 2;
952 pixel_mvs->mvs[1][0] = 0;
953 pixel_mvs->mvs[1][1] = 0;
956 weight_sum = ALPHA_MAX;
959 for (i = 0; i < pixel_refs->nb; i++) {
960 Frame *frame = &mi_ctx->frames[pixel_refs->refs[i]];
962 x_mv = (x >> mi_ctx->log2_chroma_w) + pixel_mvs->mvs[i][0] / (1 << mi_ctx->log2_chroma_w);
963 y_mv = (y >> mi_ctx->log2_chroma_h) + pixel_mvs->mvs[i][1] / (1 << mi_ctx->log2_chroma_h);
965 x_mv = x + pixel_mvs->mvs[i][0];
966 y_mv = y + pixel_mvs->mvs[i][1];
969 val += pixel_weights->weights[i] * frame->avf->data[plane][x_mv + y_mv * frame->avf->linesize[plane]];
972 val = ROUNDED_DIV(val, weight_sum);
975 avf_out->data[plane][(x >> mi_ctx->log2_chroma_w) + (y >> mi_ctx->log2_chroma_h) * avf_out->linesize[plane]] = val;
977 avf_out->data[plane][x + y * avf_out->linesize[plane]] = val;
982 static void var_size_bmc(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n, int alpha)
985 int width = mi_ctx->frames[0].avf->width;
986 int height = mi_ctx->frames[0].avf->height;
988 for (sb_y = 0; sb_y < 2; sb_y++)
989 for (sb_x = 0; sb_x < 2; sb_x++) {
990 Block *sb = &block->subs[sb_x + sb_y * 2];
993 var_size_bmc(mi_ctx, sb, x_mb + (sb_x << (n - 1)), y_mb + (sb_y << (n - 1)), n - 1, alpha);
996 int mv_x = sb->mvs[0][0] * 2;
997 int mv_y = sb->mvs[0][1] * 2;
999 int start_x = x_mb + (sb_x << (n - 1));
1000 int start_y = y_mb + (sb_y << (n - 1));
1001 int end_x = start_x + (1 << (n - 1));
1002 int end_y = start_y + (1 << (n - 1));
1004 for (y = start_y; y < end_y; y++) {
1006 int y_max = height - y - 1;
1007 for (x = start_x; x < end_x; x++) {
1009 int x_max = width - x - 1;
1010 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
1011 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
1012 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
1014 ADD_PIXELS(PX_WEIGHT_MAX, mv_x, mv_y);
1021 static void bilateral_obmc(MIContext *mi_ctx, Block *block, int mb_x, int mb_y, int alpha)
1024 int width = mi_ctx->frames[0].avf->width;
1025 int height = mi_ctx->frames[0].avf->height;
1031 int mv_x = block->mvs[0][0] * 2;
1032 int mv_y = block->mvs[0][1] * 2;
1033 int start_x, start_y;
1034 int startc_x, startc_y, endc_x, endc_y;
1036 if (mi_ctx->mc_mode == MC_MODE_AOBMC)
1037 for (nb_y = FFMAX(0, mb_y - 1); nb_y < FFMIN(mb_y + 2, mi_ctx->b_height); nb_y++)
1038 for (nb_x = FFMAX(0, mb_x - 1); nb_x < FFMIN(mb_x + 2, mi_ctx->b_width); nb_x++) {
1039 int x_nb = nb_x << mi_ctx->log2_mb_size;
1040 int y_nb = nb_y << mi_ctx->log2_mb_size;
1042 if (nb_x - mb_x || nb_y - mb_y)
1043 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 start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1047 start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1049 startc_x = av_clip(start_x, 0, width - 1);
1050 startc_y = av_clip(start_y, 0, height - 1);
1051 endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
1052 endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
1054 for (y = startc_y; y < endc_y; y++) {
1056 int y_max = height - y - 1;
1057 for (x = startc_x; x < endc_x; x++) {
1059 int x_max = width - x - 1;
1060 int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
1061 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
1062 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
1063 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
1065 if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
1066 nb_x = (((x - start_x) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1067 nb_y = (((y - start_y) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1070 uint64_t sbad = sbads[nb_x + 1 + (nb_y + 1) * 3];
1071 nb = &mi_ctx->int_blocks[mb_x + nb_x + (mb_y + nb_y) * mi_ctx->b_width];
1073 if (sbad && sbad != UINT64_MAX && nb->sbad != UINT64_MAX) {
1074 int phi = av_clip(ALPHA_MAX * nb->sbad / sbad, 0, ALPHA_MAX);
1075 obmc_weight = obmc_weight * phi / ALPHA_MAX;
1080 ADD_PIXELS(obmc_weight, mv_x, mv_y);
1085 static void interpolate(AVFilterLink *inlink, AVFrame *avf_out)
1087 AVFilterContext *ctx = inlink->dst;
1088 AVFilterLink *outlink = ctx->outputs[0];
1089 MIContext *mi_ctx = ctx->priv;
1094 pts = av_rescale(avf_out->pts, (int64_t) ALPHA_MAX * outlink->time_base.num * inlink->time_base.den,
1095 (int64_t) outlink->time_base.den * inlink->time_base.num);
1097 alpha = (pts - mi_ctx->frames[1].avf->pts * ALPHA_MAX) / (mi_ctx->frames[2].avf->pts - mi_ctx->frames[1].avf->pts);
1098 alpha = av_clip(alpha, 0, ALPHA_MAX);
1100 if (alpha == 0 || alpha == ALPHA_MAX) {
1101 av_frame_copy(avf_out, alpha ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1105 if (mi_ctx->scene_changed) {
1106 /* duplicate frame */
1107 av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1111 switch(mi_ctx->mi_mode) {
1113 av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1117 for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
1118 int width = avf_out->width;
1119 int height = avf_out->height;
1121 if (plane == 1 || plane == 2) {
1122 width = AV_CEIL_RSHIFT(width, mi_ctx->log2_chroma_w);
1123 height = AV_CEIL_RSHIFT(height, mi_ctx->log2_chroma_h);
1126 for (y = 0; y < height; y++) {
1127 for (x = 0; x < width; x++) {
1128 avf_out->data[plane][x + y * avf_out->linesize[plane]] =
1129 (alpha * mi_ctx->frames[2].avf->data[plane][x + y * mi_ctx->frames[2].avf->linesize[plane]] +
1130 (ALPHA_MAX - alpha) * mi_ctx->frames[1].avf->data[plane][x + y * mi_ctx->frames[1].avf->linesize[plane]] + 512) >> 10;
1137 if (mi_ctx->me_mode == ME_MODE_BIDIR) {
1138 bidirectional_obmc(mi_ctx, alpha);
1139 set_frame_data(mi_ctx, alpha, avf_out);
1141 } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
1145 for (y = 0; y < mi_ctx->frames[0].avf->height; y++)
1146 for (x = 0; x < mi_ctx->frames[0].avf->width; x++)
1147 mi_ctx->pixel_refs[x + y * mi_ctx->frames[0].avf->width].nb = 0;
1149 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
1150 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
1151 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
1154 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);
1156 bilateral_obmc(mi_ctx, block, mb_x, mb_y, alpha);
1160 set_frame_data(mi_ctx, alpha, avf_out);
1167 static int filter_frame(AVFilterLink *inlink, AVFrame *avf_in)
1169 AVFilterContext *ctx = inlink->dst;
1170 AVFilterLink *outlink = ctx->outputs[0];
1171 MIContext *mi_ctx = ctx->priv;
1174 if (avf_in->pts == AV_NOPTS_VALUE) {
1175 ret = ff_filter_frame(ctx->outputs[0], avf_in);
1179 if (!mi_ctx->frames[NB_FRAMES - 1].avf || avf_in->pts < mi_ctx->frames[NB_FRAMES - 1].avf->pts) {
1180 av_log(ctx, AV_LOG_VERBOSE, "Initializing out pts from input pts %"PRId64"\n", avf_in->pts);
1181 mi_ctx->out_pts = av_rescale_q(avf_in->pts, inlink->time_base, outlink->time_base);
1184 if (!mi_ctx->frames[NB_FRAMES - 1].avf)
1185 if (ret = inject_frame(inlink, av_frame_clone(avf_in)))
1188 if (ret = inject_frame(inlink, avf_in))
1191 if (!mi_ctx->frames[0].avf)
1194 mi_ctx->scene_changed = detect_scene_change(mi_ctx);
1199 if (av_compare_ts(mi_ctx->out_pts, outlink->time_base, mi_ctx->frames[2].avf->pts, inlink->time_base) > 0)
1202 if (!(avf_out = ff_get_video_buffer(ctx->outputs[0], inlink->w, inlink->h)))
1203 return AVERROR(ENOMEM);
1205 av_frame_copy_props(avf_out, mi_ctx->frames[NB_FRAMES - 1].avf);
1206 avf_out->pts = mi_ctx->out_pts++;
1208 interpolate(inlink, avf_out);
1210 if ((ret = ff_filter_frame(ctx->outputs[0], avf_out)) < 0)
1217 static av_cold void free_blocks(Block *block, int sb)
1220 free_blocks(block->subs, 1);
1225 static av_cold void uninit(AVFilterContext *ctx)
1227 MIContext *mi_ctx = ctx->priv;
1230 av_freep(&mi_ctx->pixel_mvs);
1231 av_freep(&mi_ctx->pixel_weights);
1232 av_freep(&mi_ctx->pixel_refs);
1233 if (mi_ctx->int_blocks)
1234 for (m = 0; m < mi_ctx->b_count; m++)
1235 free_blocks(&mi_ctx->int_blocks[m], 0);
1236 av_freep(&mi_ctx->int_blocks);
1238 for (i = 0; i < NB_FRAMES; i++) {
1239 Frame *frame = &mi_ctx->frames[i];
1240 av_freep(&frame->blocks);
1241 av_frame_free(&frame->avf);
1244 for (i = 0; i < 3; i++)
1245 av_freep(&mi_ctx->mv_table[i]);
1248 static const AVFilterPad minterpolate_inputs[] = {
1251 .type = AVMEDIA_TYPE_VIDEO,
1252 .filter_frame = filter_frame,
1253 .config_props = config_input,
1258 static const AVFilterPad minterpolate_outputs[] = {
1261 .type = AVMEDIA_TYPE_VIDEO,
1262 .config_props = config_output,
1267 AVFilter ff_vf_minterpolate = {
1268 .name = "minterpolate",
1269 .description = NULL_IF_CONFIG_SMALL("Frame rate conversion using Motion Interpolation."),
1270 .priv_size = sizeof(MIContext),
1271 .priv_class = &minterpolate_class,
1273 .query_formats = query_formats,
1274 .inputs = minterpolate_inputs,
1275 .outputs = minterpolate_outputs,