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