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