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_cur = me_ctx->linesize_cur;
255 int linesize_next = me_ctx->linesize_ref;
256 int mv_x1 = x_mv - x;
257 int mv_y1 = y_mv - y;
258 int mv_x, mv_y, i, j;
259 uint64_t sbad = 0;
260
261 x = av_clip(x, me_ctx->x_min, me_ctx->x_max);
262 y = av_clip(y, me_ctx->y_min, me_ctx->y_max);
263 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));
264 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));
265
266 data_cur += (y + mv_y) * linesize_cur;
267 data_next += (y - mv_y) * linesize_next;
268
269 for (j = 0; j < me_ctx->mb_size; j++)
270 for (i = 0; i < me_ctx->mb_size; i++)
271 sbad += FFABS(data_cur[x + mv_x + i + j * linesize_cur] - data_next[x - mv_x + i + j * linesize_next]);
272
273 return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - me_ctx->pred_y)) * COST_PRED_SCALE;
274}
275
276static uint64_t get_sbad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
277{
278 uint8_t *data_cur = me_ctx->data_cur;
279 uint8_t *data_next = me_ctx->data_ref;
280 int linesize_cur = me_ctx->linesize_cur;
281 int linesize_next = me_ctx->linesize_ref;
282 int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
283 int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
284 int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
285 int y_max = me_ctx->y_max - me_ctx->mb_size / 2;
286 int mv_x1 = x_mv - x;
287 int mv_y1 = y_mv - y;
288 int mv_x, mv_y, i, j;
289 uint64_t sbad = 0;
290
291 x = av_clip(x, x_min, x_max);
292 y = av_clip(y, y_min, y_max);
293 mv_x = av_clip(x_mv - x, -FFMIN(x - x_min, x_max - x), FFMIN(x - x_min, x_max - x));
294 mv_y = av_clip(y_mv - y, -FFMIN(y - y_min, y_max - y), FFMIN(y - y_min, y_max - y));
295
296 for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
297 for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
298 sbad += FFABS(data_cur[x + mv_x + i + (y + mv_y + j) * linesize_cur] - data_next[x - mv_x + i + (y - mv_y + j) * linesize_next]);
299
300 return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - me_ctx->pred_y)) * COST_PRED_SCALE;
301}
302
303static uint64_t get_sad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
304{
305 uint8_t *data_ref = me_ctx->data_ref;
306 uint8_t *data_cur = me_ctx->data_cur;
307 int linesize_ref = me_ctx->linesize_ref;
308 int linesize_cur = me_ctx->linesize_cur;
309 int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
310 int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
311 int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
312 int y_max = me_ctx->y_max - me_ctx->mb_size / 2;
313 int mv_x = x_mv - x;
314 int mv_y = y_mv - y;
315 int i, j;
316 uint64_t sad = 0;
317
318 x = av_clip(x, x_min, x_max);
319 y = av_clip(y, y_min, y_max);
320 x_mv = av_clip(x_mv, x_min, x_max);
321 y_mv = av_clip(y_mv, y_min, y_max);
322
323 for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
324 for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
325 sad += FFABS(data_ref[x_mv + i + (y_mv + j) * linesize_ref] - data_cur[x + i + (y + j) * linesize_cur]);
326
327 return sad + (FFABS(mv_x - me_ctx->pred_x) + FFABS(mv_y - me_ctx->pred_y)) * COST_PRED_SCALE;
328}
329
330static int config_input(AVFilterLink *inlink)
331{
332 MIContext *mi_ctx = inlink->dst->priv;
333 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
335 const int height = inlink->h;
336 const int width = inlink->w;
337 int i;
338
339 mi_ctx->log2_chroma_h = desc->log2_chroma_h;
340 mi_ctx->log2_chroma_w = desc->log2_chroma_w;
341 mi_ctx->bitdepth = desc->comp[0].depth;
342
343 mi_ctx->nb_planes = av_pix_fmt_count_planes(inlink->format);
344
345 mi_ctx->log2_mb_size = av_ceil_log2_c(mi_ctx->mb_size);
346 mi_ctx->mb_size = 1 << mi_ctx->log2_mb_size;
347
348 mi_ctx->b_width = width >> mi_ctx->log2_mb_size;
349 mi_ctx->b_height = height >> mi_ctx->log2_mb_size;
350 mi_ctx->b_count = mi_ctx->b_width * mi_ctx->b_height;
351
352 for (i = 0; i < NB_FRAMES; i++) {
353 Frame *frame = &mi_ctx->frames[i];
354 frame->blocks = av_calloc(mi_ctx->b_count, sizeof(*frame->blocks));
355 if (!frame->blocks)
356 return AVERROR(ENOMEM);
357 }
358
359 if (mi_ctx->mi_mode == MI_MODE_MCI) {
360 if (mi_ctx->b_width < 2 || mi_ctx->b_height < 2) {
361 av_log(inlink->dst, AV_LOG_ERROR, "Height or width < %d\n",
362 2 * mi_ctx->mb_size);
363 return AVERROR(EINVAL);
364 }
365 ff_me_init_context(me_ctx, mi_ctx->mb_size, mi_ctx->search_param,
366 width, height, 0, (mi_ctx->b_width - 1) << mi_ctx->log2_mb_size,
367 0, (mi_ctx->b_height - 1) << mi_ctx->log2_mb_size);
368
369 if (mi_ctx->me_mode == ME_MODE_BIDIR)
370 me_ctx->get_cost = &get_sad_ob;
371 else if (mi_ctx->me_mode == ME_MODE_BILAT)
372 me_ctx->get_cost = &get_sbad_ob;
373
374 mi_ctx->pixel_mvs = av_calloc(width * height, sizeof(*mi_ctx->pixel_mvs));
375 mi_ctx->pixel_weights = av_calloc(width * height, sizeof(*mi_ctx->pixel_weights));
376 mi_ctx->pixel_refs = av_calloc(width * height, sizeof(*mi_ctx->pixel_refs));
377 if (!mi_ctx->pixel_mvs || !mi_ctx->pixel_weights || !mi_ctx->pixel_refs)
378 return AVERROR(ENOMEM);
379
380 if (mi_ctx->me_mode == ME_MODE_BILAT)
381 if (!FF_ALLOCZ_TYPED_ARRAY(mi_ctx->int_blocks, mi_ctx->b_count))
382 return AVERROR(ENOMEM);
383
384 if (mi_ctx->me_method == AV_ME_METHOD_EPZS) {
385 for (i = 0; i < 3; i++) {
386 mi_ctx->mv_table[i] = av_calloc(mi_ctx->b_count, sizeof(*mi_ctx->mv_table[0]));
387 if (!mi_ctx->mv_table[i])
388 return AVERROR(ENOMEM);
389 }
390 }
391 }
392
393 if (mi_ctx->scd_method == SCD_METHOD_FDIFF) {
394 mi_ctx->sad = ff_scene_sad_get_fn(mi_ctx->bitdepth);
395 if (!mi_ctx->sad)
396 return AVERROR(EINVAL);
397 }
398
399 return 0;
400}
401
402static int config_output(AVFilterLink *outlink)
403{
404 MIContext *mi_ctx = outlink->src->priv;
405 FilterLink *l = ff_filter_link(outlink);
406
407 l->frame_rate = mi_ctx->frame_rate;
408 outlink->time_base = av_inv_q(mi_ctx->frame_rate);
409
410 return 0;
411}
412
413#define ADD_PRED(preds, px, py)\
414 do {\
415 preds.mvs[preds.nb][0] = px;\
416 preds.mvs[preds.nb][1] = py;\
417 preds.nb++;\
418 } while(0)
419
420static void search_mv(MIContext *mi_ctx, Block *blocks, int mb_x, int mb_y, int dir)
421{
422 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
423 AVMotionEstPredictor *preds = me_ctx->preds;
424 Block *block = &blocks[mb_x + mb_y * mi_ctx->b_width];
425
426 const int x_mb = mb_x << mi_ctx->log2_mb_size;
427 const int y_mb = mb_y << mi_ctx->log2_mb_size;
428 const int mb_i = mb_x + mb_y * mi_ctx->b_width;
429 int mv[2] = {x_mb, y_mb};
430
431 switch (mi_ctx->me_method) {
432 case AV_ME_METHOD_ESA:
433 ff_me_search_esa(me_ctx, x_mb, y_mb, mv);
434 break;
435 case AV_ME_METHOD_TSS:
436 ff_me_search_tss(me_ctx, x_mb, y_mb, mv);
437 break;
439 ff_me_search_tdls(me_ctx, x_mb, y_mb, mv);
440 break;
442 ff_me_search_ntss(me_ctx, x_mb, y_mb, mv);
443 break;
444 case AV_ME_METHOD_FSS:
445 ff_me_search_fss(me_ctx, x_mb, y_mb, mv);
446 break;
447 case AV_ME_METHOD_DS:
448 ff_me_search_ds(me_ctx, x_mb, y_mb, mv);
449 break;
451 ff_me_search_hexbs(me_ctx, x_mb, y_mb, mv);
452 break;
454
455 preds[0].nb = 0;
456 preds[1].nb = 0;
457
458 ADD_PRED(preds[0], 0, 0);
459
460 //left mb in current frame
461 if (mb_x > 0)
462 ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - 1][dir][0], mi_ctx->mv_table[0][mb_i - 1][dir][1]);
463
464 //top mb in current frame
465 if (mb_y > 0)
466 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]);
467
468 //top-right mb in current frame
469 if (mb_y > 0 && mb_x + 1 < mi_ctx->b_width)
470 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]);
471
472 //median predictor
473 if (preds[0].nb == 4) {
474 me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
475 me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
476 } else if (preds[0].nb == 3) {
477 me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
478 me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
479 } else if (preds[0].nb == 2) {
480 me_ctx->pred_x = preds[0].mvs[1][0];
481 me_ctx->pred_y = preds[0].mvs[1][1];
482 } else {
483 me_ctx->pred_x = 0;
484 me_ctx->pred_y = 0;
485 }
486
487 //collocated mb in prev frame
488 ADD_PRED(preds[0], mi_ctx->mv_table[1][mb_i][dir][0], mi_ctx->mv_table[1][mb_i][dir][1]);
489
490 //accelerator motion vector of collocated block in prev frame
491 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]),
492 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]));
493
494 //left mb in prev frame
495 if (mb_x > 0)
496 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i - 1][dir][0], mi_ctx->mv_table[1][mb_i - 1][dir][1]);
497
498 //top mb in prev frame
499 if (mb_y > 0)
500 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]);
501
502 //right mb in prev frame
503 if (mb_x + 1 < mi_ctx->b_width)
504 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i + 1][dir][0], mi_ctx->mv_table[1][mb_i + 1][dir][1]);
505
506 //bottom mb in prev frame
507 if (mb_y + 1 < mi_ctx->b_height)
508 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]);
509
510 ff_me_search_epzs(me_ctx, x_mb, y_mb, mv);
511
512 mi_ctx->mv_table[0][mb_i][dir][0] = mv[0] - x_mb;
513 mi_ctx->mv_table[0][mb_i][dir][1] = mv[1] - y_mb;
514
515 break;
516 case AV_ME_METHOD_UMH:
517
518 preds[0].nb = 0;
519
520 ADD_PRED(preds[0], 0, 0);
521
522 //left mb in current frame
523 if (mb_x > 0)
524 ADD_PRED(preds[0], blocks[mb_i - 1].mvs[dir][0], blocks[mb_i - 1].mvs[dir][1]);
525
526 if (mb_y > 0) {
527 //top mb in current frame
528 ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width].mvs[dir][0], blocks[mb_i - mi_ctx->b_width].mvs[dir][1]);
529
530 //top-right mb in current frame
531 if (mb_x + 1 < mi_ctx->b_width)
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 //top-left mb in current frame
534 else if (mb_x > 0)
535 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]);
536 }
537
538 //median predictor
539 if (preds[0].nb == 4) {
540 me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
541 me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
542 } else if (preds[0].nb == 3) {
543 me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
544 me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
545 } else if (preds[0].nb == 2) {
546 me_ctx->pred_x = preds[0].mvs[1][0];
547 me_ctx->pred_y = preds[0].mvs[1][1];
548 } else {
549 me_ctx->pred_x = 0;
550 me_ctx->pred_y = 0;
551 }
552
553 ff_me_search_umh(me_ctx, x_mb, y_mb, mv);
554
555 break;
556 }
557
558 block->mvs[dir][0] = mv[0] - x_mb;
559 block->mvs[dir][1] = mv[1] - y_mb;
560}
561
562static void bilateral_me(MIContext *mi_ctx)
563{
564 Block *block;
565 int mb_x, mb_y;
566
567 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
568 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
569 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
570
571 block->cid = 0;
572 block->sb = 0;
573
574 block->mvs[0][0] = 0;
575 block->mvs[0][1] = 0;
576 }
577
578 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
579 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
580 search_mv(mi_ctx, mi_ctx->int_blocks, mb_x, mb_y, 0);
581}
582
583static int var_size_bme(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n)
584{
585 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
586 uint64_t cost_sb, cost_old;
587 int mb_size = me_ctx->mb_size;
588 int search_param = me_ctx->search_param;
589 int mv_x, mv_y;
590 int x, y;
591 int ret;
592
593 me_ctx->mb_size = 1 << n;
594 cost_old = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
595 me_ctx->mb_size = mb_size;
596
597 if (!cost_old) {
598 block->sb = 0;
599 return 0;
600 }
601
602 if (!block->subs) {
603 block->subs = av_mallocz(4 * sizeof(*block->subs));
604 if (!block->subs)
605 return AVERROR(ENOMEM);
606 }
607
608 block->sb = 1;
609
610 for (y = 0; y < 2; y++)
611 for (x = 0; x < 2; x++) {
612 Block *sb = &block->subs[x + y * 2];
613 int mv[2] = {x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]};
614
615 me_ctx->mb_size = 1 << (n - 1);
616 me_ctx->search_param = 2;
617 me_ctx->pred_x = block->mvs[0][0];
618 me_ctx->pred_y = block->mvs[0][1];
619
620 cost_sb = ff_me_search_ds(&mi_ctx->me_ctx, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1], mv);
621 mv_x = mv[0] - x_mb;
622 mv_y = mv[1] - y_mb;
623
624 me_ctx->mb_size = mb_size;
625 me_ctx->search_param = search_param;
626
627 if (cost_sb < cost_old / 4) {
628 sb->mvs[0][0] = mv_x;
629 sb->mvs[0][1] = mv_y;
630
631 if (n > 1) {
632 if (ret = var_size_bme(mi_ctx, sb, x_mb + (x << (n - 1)), y_mb + (y << (n - 1)), n - 1))
633 return ret;
634 } else
635 sb->sb = 0;
636 } else {
637 block->sb = 0;
638 return 0;
639 }
640 }
641
642 return 0;
643}
644
645static int cluster_mvs(MIContext *mi_ctx)
646{
647 int changed, c, c_max = 0;
648 int mb_x, mb_y, x, y;
649 int mv_x, mv_y, avg_x, avg_y, dx, dy;
650 int d, ret;
651 Block *block;
652 Cluster *cluster, *cluster_new;
653
654 do {
655 changed = 0;
656 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
657 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
658 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
659 c = block->cid;
660 cluster = &mi_ctx->clusters[c];
661 mv_x = block->mvs[0][0];
662 mv_y = block->mvs[0][1];
663
664 if (cluster->nb < 2)
665 continue;
666
667 avg_x = cluster->sum[0] / cluster->nb;
668 avg_y = cluster->sum[1] / cluster->nb;
669 dx = avg_x - mv_x;
670 dy = avg_y - mv_y;
671
672 if (FFABS(dx) > CLUSTER_THRESHOLD || FFABS(dy) > CLUSTER_THRESHOLD) {
673
674 for (d = 1; d < 5; d++)
675 for (y = FFMAX(mb_y - d, 0); y < FFMIN(mb_y + d + 1, mi_ctx->b_height); y++)
676 for (x = FFMAX(mb_x - d, 0); x < FFMIN(mb_x + d + 1, mi_ctx->b_width); x++) {
677 Block *nb = &mi_ctx->int_blocks[x + y * mi_ctx->b_width];
678 if (nb->cid > block->cid) {
679 if (nb->cid < c || c == block->cid)
680 c = nb->cid;
681 }
682 }
683
684 if (c == block->cid)
685 c = c_max + 1;
686
687 if (c >= NB_CLUSTERS) {
688 continue;
689 }
690
691 cluster_new = &mi_ctx->clusters[c];
692 cluster_new->sum[0] += mv_x;
693 cluster_new->sum[1] += mv_y;
694 cluster->sum[0] -= mv_x;
695 cluster->sum[1] -= mv_y;
696 cluster_new->nb++;
697 cluster->nb--;
698
699 c_max = FFMAX(c_max, c);
700 block->cid = c;
701
702 changed = 1;
703 }
704 }
705 } while (changed);
706
707 /* find boundaries */
708 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
709 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
710 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
711 for (y = FFMAX(mb_y - 1, 0); y < FFMIN(mb_y + 2, mi_ctx->b_height); y++)
712 for (x = FFMAX(mb_x - 1, 0); x < FFMIN(mb_x + 2, mi_ctx->b_width); x++) {
713 dx = x - mb_x;
714 dy = y - mb_y;
715
716 if ((x - mb_x) && (y - mb_y) || !dx && !dy)
717 continue;
718
719 if (!mb_x || !mb_y || mb_x == mi_ctx->b_width - 1 || mb_y == mi_ctx->b_height - 1)
720 continue;
721
722 if (block->cid != mi_ctx->int_blocks[x + y * mi_ctx->b_width].cid) {
723 if (!dx && block->cid == mi_ctx->int_blocks[x + (mb_y - dy) * mi_ctx->b_width].cid ||
724 !dy && block->cid == mi_ctx->int_blocks[(mb_x - dx) + y * mi_ctx->b_width].cid) {
725 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))
726 return ret;
727 }
728 }
729 }
730 }
731
732 return 0;
733}
734
735static int inject_frame(AVFilterLink *inlink, AVFrame *avf_in)
736{
737 AVFilterContext *ctx = inlink->dst;
738 MIContext *mi_ctx = ctx->priv;
739 Frame frame_tmp;
740 int mb_x, mb_y, dir;
741
742 av_frame_free(&mi_ctx->frames[0].avf);
743 frame_tmp = mi_ctx->frames[0];
744 memmove(&mi_ctx->frames[0], &mi_ctx->frames[1], sizeof(mi_ctx->frames[0]) * (NB_FRAMES - 1));
745 mi_ctx->frames[NB_FRAMES - 1] = frame_tmp;
746 mi_ctx->frames[NB_FRAMES - 1].avf = avf_in;
747
748 if (mi_ctx->mi_mode == MI_MODE_MCI) {
749
750 if (mi_ctx->me_method == AV_ME_METHOD_EPZS) {
751 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);
752 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);
753 }
754
755 if (mi_ctx->me_mode == ME_MODE_BIDIR) {
756
757 if (mi_ctx->frames[1].avf) {
758 for (dir = 0; dir < 2; dir++) {
759 mi_ctx->me_ctx.linesize_cur = mi_ctx->frames[2].avf->linesize[0];
760 mi_ctx->me_ctx.linesize_ref = mi_ctx->frames[dir ? 3 : 1].avf->linesize[0];
761 mi_ctx->me_ctx.data_cur = mi_ctx->frames[2].avf->data[0];
762 mi_ctx->me_ctx.data_ref = mi_ctx->frames[dir ? 3 : 1].avf->data[0];
763
764 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
765 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
766 search_mv(mi_ctx, mi_ctx->frames[2].blocks, mb_x, mb_y, dir);
767 }
768 }
769
770 } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
771 Block *block;
772 int i, ret;
773
774 if (!mi_ctx->frames[0].avf)
775 return 0;
776
777 mi_ctx->me_ctx.linesize_cur = mi_ctx->frames[1].avf->linesize[0];
778 mi_ctx->me_ctx.linesize_ref = mi_ctx->frames[2].avf->linesize[0];
779 mi_ctx->me_ctx.data_cur = mi_ctx->frames[1].avf->data[0];
780 mi_ctx->me_ctx.data_ref = mi_ctx->frames[2].avf->data[0];
781
782 bilateral_me(mi_ctx);
783
784 if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
785
786 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
787 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
788 int x_mb = mb_x << mi_ctx->log2_mb_size;
789 int y_mb = mb_y << mi_ctx->log2_mb_size;
790 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
791
792 block->sbad = get_sbad(&mi_ctx->me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
793 }
794 }
795
796 if (mi_ctx->vsbmc) {
797
798 for (i = 0; i < NB_CLUSTERS; i++) {
799 mi_ctx->clusters[i].sum[0] = 0;
800 mi_ctx->clusters[i].sum[1] = 0;
801 mi_ctx->clusters[i].nb = 0;
802 }
803
804 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
805 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
806 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
807
808 mi_ctx->clusters[0].sum[0] += block->mvs[0][0];
809 mi_ctx->clusters[0].sum[1] += block->mvs[0][1];
810 }
811
812 mi_ctx->clusters[0].nb = mi_ctx->b_count;
813
814 if (ret = cluster_mvs(mi_ctx))
815 return ret;
816 }
817 }
818 }
819
820 return 0;
821}
822
824{
825 MIContext *mi_ctx = ctx->priv;
826 AVFilterLink *input = ctx->inputs[0];
827 uint8_t *p1 = mi_ctx->frames[1].avf->data[0];
828 ptrdiff_t linesize1 = mi_ctx->frames[1].avf->linesize[0];
829 uint8_t *p2 = mi_ctx->frames[2].avf->data[0];
830 ptrdiff_t linesize2 = mi_ctx->frames[2].avf->linesize[0];
831
832 if (mi_ctx->scd_method == SCD_METHOD_FDIFF) {
833 double ret = 0, mafd, diff;
834 uint64_t sad;
835 mi_ctx->sad(p1, linesize1, p2, linesize2, input->w, input->h, &sad);
836 mafd = (double) sad * 100.0 / (input->h * input->w) / (1 << mi_ctx->bitdepth);
837 diff = fabs(mafd - mi_ctx->prev_mafd);
838 ret = av_clipf(FFMIN(mafd, diff), 0, 100.0);
839 mi_ctx->prev_mafd = mafd;
840
841 return ret >= mi_ctx->scd_threshold;
842 }
843
844 return 0;
845}
846
847#define ADD_PIXELS(b_weight, mv_x, mv_y)\
848 do {\
849 if (!b_weight || pixel_refs->nb + 1 >= NB_PIXEL_MVS)\
850 continue;\
851 pixel_refs->refs[pixel_refs->nb] = 1;\
852 pixel_weights->weights[pixel_refs->nb] = b_weight * (ALPHA_MAX - alpha);\
853 pixel_mvs->mvs[pixel_refs->nb][0] = av_clip((mv_x * alpha) / ALPHA_MAX, x_min, x_max);\
854 pixel_mvs->mvs[pixel_refs->nb][1] = av_clip((mv_y * alpha) / ALPHA_MAX, y_min, y_max);\
855 pixel_refs->nb++;\
856 pixel_refs->refs[pixel_refs->nb] = 2;\
857 pixel_weights->weights[pixel_refs->nb] = b_weight * alpha;\
858 pixel_mvs->mvs[pixel_refs->nb][0] = av_clip(-mv_x * (ALPHA_MAX - alpha) / ALPHA_MAX, x_min, x_max);\
859 pixel_mvs->mvs[pixel_refs->nb][1] = av_clip(-mv_y * (ALPHA_MAX - alpha) / ALPHA_MAX, y_min, y_max);\
860 pixel_refs->nb++;\
861 } while(0)
862
863static void bidirectional_obmc(MIContext *mi_ctx, int alpha)
864{
865 int x, y;
866 int width = mi_ctx->frames[0].avf->width;
867 int height = mi_ctx->frames[0].avf->height;
868 int mb_y, mb_x, dir;
869
870 for (y = 0; y < height; y++)
871 for (x = 0; x < width; x++)
872 mi_ctx->pixel_refs[x + y * width].nb = 0;
873
874 for (dir = 0; dir < 2; dir++)
875 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
876 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
877 int a = dir ? alpha : (ALPHA_MAX - alpha);
878 int mv_x = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][0];
879 int mv_y = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][1];
880 int start_x, start_y;
881 int startc_x, startc_y, endc_x, endc_y;
882
883 start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_x * a / ALPHA_MAX;
884 start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_y * a / ALPHA_MAX;
885
886 startc_x = av_clip(start_x, 0, width - 1);
887 startc_y = av_clip(start_y, 0, height - 1);
888 endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
889 endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
890
891 if (dir) {
892 mv_x = -mv_x;
893 mv_y = -mv_y;
894 }
895
896 for (y = startc_y; y < endc_y; y++) {
897 int y_min = -y;
898 int y_max = height - y - 1;
899 for (x = startc_x; x < endc_x; x++) {
900 int x_min = -x;
901 int x_max = width - x - 1;
902 int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
903 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
904 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
905 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
906
907 ADD_PIXELS(obmc_weight, mv_x, mv_y);
908 }
909 }
910 }
911}
912
913static void set_frame_data(MIContext *mi_ctx, int alpha, AVFrame *avf_out)
914{
915 int x, y, plane;
916
917 for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
918 int width = avf_out->width;
919 int height = avf_out->height;
920 int chroma = plane == 1 || plane == 2;
921
922 for (y = 0; y < height; y++)
923 for (x = 0; x < width; x++) {
924 int x_mv, y_mv;
925 int weight_sum = 0;
926 int i, val = 0;
927 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
928 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
929 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
930
931 for (i = 0; i < pixel_refs->nb; i++)
932 weight_sum += pixel_weights->weights[i];
933
934 if (!weight_sum || !pixel_refs->nb) {
935 pixel_weights->weights[0] = ALPHA_MAX - alpha;
936 pixel_refs->refs[0] = 1;
937 pixel_mvs->mvs[0][0] = 0;
938 pixel_mvs->mvs[0][1] = 0;
939 pixel_weights->weights[1] = alpha;
940 pixel_refs->refs[1] = 2;
941 pixel_mvs->mvs[1][0] = 0;
942 pixel_mvs->mvs[1][1] = 0;
943 pixel_refs->nb = 2;
944
945 weight_sum = ALPHA_MAX;
946 }
947
948 if (chroma) {
949 for (i = 0; i < pixel_refs->nb; i++) {
950 Frame *frame = &mi_ctx->frames[pixel_refs->refs[i]];
951 x_mv = (x >> mi_ctx->log2_chroma_w) + pixel_mvs->mvs[i][0] / (1 << mi_ctx->log2_chroma_w);
952 y_mv = (y >> mi_ctx->log2_chroma_h) + pixel_mvs->mvs[i][1] / (1 << mi_ctx->log2_chroma_h);
953 val += pixel_weights->weights[i] * frame->avf->data[plane][x_mv + y_mv * frame->avf->linesize[plane]];
954 }
955 } else {
956 for (i = 0; i < pixel_refs->nb; i++) {
957 Frame *frame = &mi_ctx->frames[pixel_refs->refs[i]];
958 x_mv = x + pixel_mvs->mvs[i][0];
959 y_mv = y + pixel_mvs->mvs[i][1];
960 val += pixel_weights->weights[i] * frame->avf->data[plane][x_mv + y_mv * frame->avf->linesize[plane]];
961 }
962 }
963
964 val = ROUNDED_DIV(val, weight_sum);
965
966 if (chroma)
967 avf_out->data[plane][(x >> mi_ctx->log2_chroma_w) + (y >> mi_ctx->log2_chroma_h) * avf_out->linesize[plane]] = val;
968 else
969 avf_out->data[plane][x + y * avf_out->linesize[plane]] = val;
970 }
971 }
972}
973
974static void var_size_bmc(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n, int alpha)
975{
976 int sb_x, sb_y;
977 int width = mi_ctx->frames[0].avf->width;
978 int height = mi_ctx->frames[0].avf->height;
979
980 for (sb_y = 0; sb_y < 2; sb_y++)
981 for (sb_x = 0; sb_x < 2; sb_x++) {
982 Block *sb = &block->subs[sb_x + sb_y * 2];
983
984 if (sb->sb)
985 var_size_bmc(mi_ctx, sb, x_mb + (sb_x << (n - 1)), y_mb + (sb_y << (n - 1)), n - 1, alpha);
986 else {
987 int x, y;
988 int mv_x = sb->mvs[0][0] * 2;
989 int mv_y = sb->mvs[0][1] * 2;
990
991 int start_x = x_mb + (sb_x << (n - 1));
992 int start_y = y_mb + (sb_y << (n - 1));
993 int end_x = start_x + (1 << (n - 1));
994 int end_y = start_y + (1 << (n - 1));
995
996 for (y = start_y; y < end_y; y++) {
997 int y_min = -y;
998 int y_max = height - y - 1;
999 for (x = start_x; x < end_x; x++) {
1000 int x_min = -x;
1001 int x_max = width - x - 1;
1002 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
1003 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
1004 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
1005
1006 ADD_PIXELS(PX_WEIGHT_MAX, mv_x, mv_y);
1007 }
1008 }
1009 }
1010 }
1011}
1012
1013static void bilateral_obmc(MIContext *mi_ctx, Block *block, int mb_x, int mb_y, int alpha)
1014{
1015 int x, y;
1016 int width = mi_ctx->frames[0].avf->width;
1017 int height = mi_ctx->frames[0].avf->height;
1018
1019 Block *nb;
1020 int nb_x, nb_y;
1021 uint64_t sbads[9];
1022
1023 int mv_x = block->mvs[0][0] * 2;
1024 int mv_y = block->mvs[0][1] * 2;
1025 int start_x, start_y;
1026 int startc_x, startc_y, endc_x, endc_y;
1027
1028 if (mi_ctx->mc_mode == MC_MODE_AOBMC)
1029 for (nb_y = FFMAX(0, mb_y - 1); nb_y < FFMIN(mb_y + 2, mi_ctx->b_height); nb_y++)
1030 for (nb_x = FFMAX(0, mb_x - 1); nb_x < FFMIN(mb_x + 2, mi_ctx->b_width); nb_x++) {
1031 int x_nb = nb_x << mi_ctx->log2_mb_size;
1032 int y_nb = nb_y << mi_ctx->log2_mb_size;
1033
1034 if (nb_x - mb_x || nb_y - mb_y)
1035 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]);
1036 }
1037
1038 start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1039 start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1040
1041 startc_x = av_clip(start_x, 0, width - 1);
1042 startc_y = av_clip(start_y, 0, height - 1);
1043 endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
1044 endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
1045
1046 for (y = startc_y; y < endc_y; y++) {
1047 int y_min = -y;
1048 int y_max = height - y - 1;
1049 for (x = startc_x; x < endc_x; x++) {
1050 int x_min = -x;
1051 int x_max = width - x - 1;
1052 int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
1053 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
1054 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
1055 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
1056
1057 if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
1058 nb_x = (((x - start_x) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1059 nb_y = (((y - start_y) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1060
1061 if ((nb_x || nb_y) && mb_x + nb_x < mi_ctx->b_width && mb_y + nb_y < mi_ctx->b_height) {
1062 uint64_t sbad = sbads[nb_x + 1 + (nb_y + 1) * 3];
1063 nb = &mi_ctx->int_blocks[mb_x + nb_x + (mb_y + nb_y) * mi_ctx->b_width];
1064
1065 if (sbad && sbad != UINT64_MAX && nb->sbad != UINT64_MAX) {
1066 int phi = av_clip(ALPHA_MAX * nb->sbad / sbad, 0, ALPHA_MAX);
1067 obmc_weight = obmc_weight * phi / ALPHA_MAX;
1068 }
1069 }
1070 }
1071
1072 ADD_PIXELS(obmc_weight, mv_x, mv_y);
1073 }
1074 }
1075}
1076
1077static void interpolate(AVFilterLink *inlink, AVFrame *avf_out)
1078{
1079 AVFilterContext *ctx = inlink->dst;
1080 AVFilterLink *outlink = ctx->outputs[0];
1081 MIContext *mi_ctx = ctx->priv;
1082 int x, y;
1083 int plane, alpha;
1084 int64_t pts;
1085
1086 pts = av_rescale(avf_out->pts, (int64_t) ALPHA_MAX * outlink->time_base.num * inlink->time_base.den,
1087 (int64_t) outlink->time_base.den * inlink->time_base.num);
1088
1089 if (mi_ctx->frames[2].avf->pts > mi_ctx->frames[1].avf->pts) {
1090 alpha = (pts - mi_ctx->frames[1].avf->pts * ALPHA_MAX) / (mi_ctx->frames[2].avf->pts - mi_ctx->frames[1].avf->pts);
1092 } else {
1093 av_log(ctx, AV_LOG_DEBUG, "duplicate input PTS detected\n");
1094 alpha = 0;
1095 }
1096
1097 if (alpha == 0 || alpha == ALPHA_MAX) {
1098 av_frame_copy(avf_out, alpha ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1099 return;
1100 }
1101
1102 if (mi_ctx->scene_changed) {
1103 av_log(ctx, AV_LOG_DEBUG, "scene changed, input pts %"PRId64"\n", mi_ctx->frames[1].avf->pts);
1104 /* duplicate frame */
1105 av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1106 return;
1107 }
1108
1109 switch(mi_ctx->mi_mode) {
1110 case MI_MODE_DUP:
1111 av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1112
1113 break;
1114 case MI_MODE_BLEND:
1115 for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
1116 int width = avf_out->width;
1117 int height = avf_out->height;
1118
1119 if (plane == 1 || plane == 2) {
1122 }
1123
1124 for (y = 0; y < height; y++) {
1125 for (x = 0; x < width; x++) {
1126 avf_out->data[plane][x + y * avf_out->linesize[plane]] =
1127 (alpha * mi_ctx->frames[2].avf->data[plane][x + y * mi_ctx->frames[2].avf->linesize[plane]] +
1128 (ALPHA_MAX - alpha) * mi_ctx->frames[1].avf->data[plane][x + y * mi_ctx->frames[1].avf->linesize[plane]] + 512) >> 10;
1129 }
1130 }
1131 }
1132
1133 break;
1134 case MI_MODE_MCI:
1135 if (mi_ctx->me_mode == ME_MODE_BIDIR) {
1136 bidirectional_obmc(mi_ctx, alpha);
1137 set_frame_data(mi_ctx, alpha, avf_out);
1138
1139 } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
1140 int mb_x, mb_y;
1141 Block *block;
1142
1143 for (y = 0; y < mi_ctx->frames[0].avf->height; y++)
1144 for (x = 0; x < mi_ctx->frames[0].avf->width; x++)
1145 mi_ctx->pixel_refs[x + y * mi_ctx->frames[0].avf->width].nb = 0;
1146
1147 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
1148 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
1149 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
1150
1151 if (block->sb)
1152 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);
1153
1154 bilateral_obmc(mi_ctx, block, mb_x, mb_y, alpha);
1155
1156 }
1157
1158 set_frame_data(mi_ctx, alpha, avf_out);
1159 }
1160
1161 break;
1162 }
1163}
1164
1165static int filter_frame(AVFilterLink *inlink, AVFrame *avf_in)
1166{
1167 AVFilterContext *ctx = inlink->dst;
1168 AVFilterLink *outlink = ctx->outputs[0];
1169 MIContext *mi_ctx = ctx->priv;
1170 int ret;
1171
1172 if (avf_in->pts == AV_NOPTS_VALUE) {
1173 ret = ff_filter_frame(ctx->outputs[0], avf_in);
1174 return ret;
1175 }
1176
1177 if (!mi_ctx->frames[NB_FRAMES - 1].avf || avf_in->pts < mi_ctx->frames[NB_FRAMES - 1].avf->pts) {
1178 av_log(ctx, AV_LOG_VERBOSE, "Initializing out pts from input pts %"PRId64"\n", avf_in->pts);
1179 mi_ctx->out_pts = av_rescale_q(avf_in->pts, inlink->time_base, outlink->time_base);
1180 }
1181
1182 if (!mi_ctx->frames[NB_FRAMES - 1].avf)
1183 if (ret = inject_frame(inlink, av_frame_clone(avf_in)))
1184 return ret;
1185
1186 if (ret = inject_frame(inlink, avf_in))
1187 return ret;
1188
1189 if (!mi_ctx->frames[0].avf)
1190 return 0;
1191
1193
1194 for (;;) {
1195 AVFrame *avf_out;
1196
1197 if (av_compare_ts(mi_ctx->out_pts, outlink->time_base, mi_ctx->frames[2].avf->pts, inlink->time_base) > 0)
1198 break;
1199
1200 if (!(avf_out = ff_get_video_buffer(ctx->outputs[0], inlink->w, inlink->h)))
1201 return AVERROR(ENOMEM);
1202
1203 av_frame_copy_props(avf_out, mi_ctx->frames[NB_FRAMES - 1].avf);
1204 avf_out->pts = mi_ctx->out_pts++;
1205 avf_out->duration = 1;
1206
1207 interpolate(inlink, avf_out);
1208
1209 if ((ret = ff_filter_frame(ctx->outputs[0], avf_out)) < 0)
1210 return ret;
1211 }
1212
1213 return 0;
1214}
1215
1217{
1218 if (block->subs)
1219 for (int i = 0; i < 4; i++)
1220 free_blocks(&block->subs[i]);
1221 av_freep(&block->subs);
1222}
1223
1225{
1226 MIContext *mi_ctx = ctx->priv;
1227 int i, m;
1228
1229 av_freep(&mi_ctx->pixel_mvs);
1230 av_freep(&mi_ctx->pixel_weights);
1231 av_freep(&mi_ctx->pixel_refs);
1232 if (mi_ctx->int_blocks)
1233 for (m = 0; m < mi_ctx->b_count; m++)
1234 free_blocks(&mi_ctx->int_blocks[m]);
1235 av_freep(&mi_ctx->int_blocks);
1236
1237 for (i = 0; i < NB_FRAMES; i++) {
1238 Frame *frame = &mi_ctx->frames[i];
1239 av_freep(&frame->blocks);
1240 av_frame_free(&frame->avf);
1241 }
1242
1243 for (i = 0; i < 3; i++)
1244 av_freep(&mi_ctx->mv_table[i]);
1245}
1246
1248 {
1249 .name = "default",
1250 .type = AVMEDIA_TYPE_VIDEO,
1251 .filter_frame = filter_frame,
1252 .config_props = config_input,
1253 },
1254};
1255
1257 {
1258 .name = "default",
1259 .type = AVMEDIA_TYPE_VIDEO,
1260 .config_props = config_output,
1261 },
1262};
1263
1265 .p.name = "minterpolate",
1266 .p.description = NULL_IF_CONFIG_SMALL("Frame rate conversion using Motion Interpolation."),
1267 .p.priv_class = &minterpolate_class,
1268 .priv_size = sizeof(MIContext),
1269 .uninit = uninit,
1273};
static double val(void *priv, double ch)
Definition aeval.c:77
static int config_input(AVFilterLink *inlink)
const FFFilter ff_vf_minterpolate
static AVFormatContext * ctx
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1079
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define FLAGS
Definition cmdutils.c:596
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
int ret
Definition ffplay.c:391
@ 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:65
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:602
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition frame.c:486
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition frame.c:714
#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:279
#define FILTER_OUTPUTS(array)
Definition filters.h:280
#define FILTER_PIXFMTS_ARRAY(array)
Definition filters.h:259
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:493
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:97
#define FF_ALLOCZ_TYPED_ARRAY(p, nelem)
Definition internal.h:81
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:370
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:3524
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3484
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:279
void * priv
private data for use by the filter
Definition avfilter.h:294
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:479
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition frame.h:581
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:500
int width
Definition frame.h:551
int height
Definition frame.h:551
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:524
int64_t duration
Duration of the frame, in the same units as pts.
Definition frame.h:830
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,...)
#define height
Definition dsp.h:99
#define width
Definition dsp.h:99
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)
#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)
static av_cold void free_blocks(Block *block)
#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:120
static double c[64]