FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/vf_minterpolate.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 297 612 48.5%
Functions: 13 19 68.4%
Branches: 143 402 35.6%

Line Branch Exec Source
1 /**
2 * Copyright (c) 2014-2015 Michael Niedermayer <michaelni@gmx.at>
3 * Copyright (c) 2016 Davinder Singh (DSM_) <ds.mudhar<@gmail.com>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "motion_estimation.h"
23 #include "libavcodec/mathops.h"
24 #include "libavutil/common.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/pixdesc.h"
28 #include "avfilter.h"
29 #include "filters.h"
30 #include "video.h"
31 #include "scene_sad.h"
32
33 #define ME_MODE_BIDIR 0
34 #define ME_MODE_BILAT 1
35
36 #define MC_MODE_OBMC 0
37 #define MC_MODE_AOBMC 1
38
39 #define SCD_METHOD_NONE 0
40 #define SCD_METHOD_FDIFF 1
41
42 #define NB_FRAMES 4
43 #define NB_PIXEL_MVS 32
44 #define NB_CLUSTERS 128
45
46 #define ALPHA_MAX 1024
47 #define CLUSTER_THRESHOLD 4
48 #define PX_WEIGHT_MAX 255
49 #define COST_PRED_SCALE 64
50
51 static const uint8_t obmc_linear32[1024] = {
52 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
53 0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
54 0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
55 0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
56 4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
57 4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
58 4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
59 4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
60 4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
61 4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
62 4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
63 4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
64 8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
65 8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
66 8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
67 8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
68 8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
69 8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
70 8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
71 8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
72 4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
73 4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
74 4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
75 4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
76 4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
77 4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
78 4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
79 4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
80 0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
81 0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
82 0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
83 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
84 };
85
86 static const uint8_t obmc_linear16[256] = {
87 0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
88 4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
89 4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
90 8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
91 8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
92 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
93 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
94 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
95 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
96 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
97 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
98 8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
99 8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
100 4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
101 4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
102 0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
103 };
104
105 static const uint8_t obmc_linear8[64] = {
106 4, 12, 20, 28, 28, 20, 12, 4,
107 12, 36, 60, 84, 84, 60, 36, 12,
108 20, 60,100,140,140,100, 60, 20,
109 28, 84,140,196,196,140, 84, 28,
110 28, 84,140,196,196,140, 84, 28,
111 20, 60,100,140,140,100, 60, 20,
112 12, 36, 60, 84, 84, 60, 36, 12,
113 4, 12, 20, 28, 28, 20, 12, 4,
114 };
115
116 static const uint8_t obmc_linear4[16] = {
117 16, 48, 48, 16,
118 48,144,144, 48,
119 48,144,144, 48,
120 16, 48, 48, 16,
121 };
122
123 static const uint8_t * const obmc_tab_linear[4]= {
124 obmc_linear32, obmc_linear16, obmc_linear8, obmc_linear4
125 };
126
127 enum MIMode {
128 MI_MODE_DUP = 0,
129 MI_MODE_BLEND = 1,
130 MI_MODE_MCI = 2,
131 };
132
133 typedef struct Cluster {
134 int64_t sum[2];
135 int nb;
136 } Cluster;
137
138 typedef struct Block {
139 int16_t mvs[2][2];
140 int cid;
141 uint64_t sbad;
142 int sb;
143 struct Block *subs;
144 } Block;
145
146 typedef struct PixelMVS {
147 int16_t mvs[NB_PIXEL_MVS][2];
148 } PixelMVS;
149
150 typedef struct PixelWeights {
151 uint32_t weights[NB_PIXEL_MVS];
152 } PixelWeights;
153
154 typedef struct PixelRefs {
155 int8_t refs[NB_PIXEL_MVS];
156 int nb;
157 } PixelRefs;
158
159 typedef struct Frame {
160 AVFrame *avf;
161 Block *blocks;
162 } Frame;
163
164 typedef struct MIContext {
165 const AVClass *class;
166 AVMotionEstContext me_ctx;
167 AVRational frame_rate;
168 enum MIMode mi_mode;
169 int mc_mode;
170 int me_mode;
171 int me_method;
172 int mb_size;
173 int search_param;
174 int vsbmc;
175
176 Frame frames[NB_FRAMES];
177 Cluster clusters[NB_CLUSTERS];
178 Block *int_blocks;
179 PixelMVS *pixel_mvs;
180 PixelWeights *pixel_weights;
181 PixelRefs *pixel_refs;
182 int (*mv_table[3])[2][2];
183 int64_t out_pts;
184 int b_width, b_height, b_count;
185 int log2_mb_size;
186 int bitdepth;
187
188 int scd_method;
189 int scene_changed;
190 ff_scene_sad_fn sad;
191 double prev_mafd;
192 double scd_threshold;
193
194 int log2_chroma_w;
195 int log2_chroma_h;
196 int nb_planes;
197 } MIContext;
198
199 #define OFFSET(x) offsetof(MIContext, x)
200 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
201 #define CONST(name, help, val, u) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, 0, 0, FLAGS, .unit = u }
202
203 static const AVOption minterpolate_options[] = {
204 { "fps", "output's frame rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "60"}, 0, INT_MAX, FLAGS },
205 { "mi_mode", "motion interpolation mode", OFFSET(mi_mode), AV_OPT_TYPE_INT, {.i64 = MI_MODE_MCI}, MI_MODE_DUP, MI_MODE_MCI, FLAGS, .unit = "mi_mode" },
206 CONST("dup", "duplicate frames", MI_MODE_DUP, "mi_mode"),
207 CONST("blend", "blend frames", MI_MODE_BLEND, "mi_mode"),
208 CONST("mci", "motion compensated interpolation", MI_MODE_MCI, "mi_mode"),
209 { "mc_mode", "motion compensation mode", OFFSET(mc_mode), AV_OPT_TYPE_INT, {.i64 = MC_MODE_OBMC}, MC_MODE_OBMC, MC_MODE_AOBMC, FLAGS, .unit = "mc_mode" },
210 CONST("obmc", "overlapped block motion compensation", MC_MODE_OBMC, "mc_mode"),
211 CONST("aobmc", "adaptive overlapped block motion compensation", MC_MODE_AOBMC, "mc_mode"),
212 { "me_mode", "motion estimation mode", OFFSET(me_mode), AV_OPT_TYPE_INT, {.i64 = ME_MODE_BILAT}, ME_MODE_BIDIR, ME_MODE_BILAT, FLAGS, .unit = "me_mode" },
213 CONST("bidir", "bidirectional motion estimation", ME_MODE_BIDIR, "me_mode"),
214 CONST("bilat", "bilateral motion estimation", ME_MODE_BILAT, "me_mode"),
215 { "me", "motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = AV_ME_METHOD_EPZS}, AV_ME_METHOD_ESA, AV_ME_METHOD_UMH, FLAGS, .unit = "me" },
216 CONST("esa", "exhaustive search", AV_ME_METHOD_ESA, "me"),
217 CONST("tss", "three step search", AV_ME_METHOD_TSS, "me"),
218 CONST("tdls", "two dimensional logarithmic search", AV_ME_METHOD_TDLS, "me"),
219 CONST("ntss", "new three step search", AV_ME_METHOD_NTSS, "me"),
220 CONST("fss", "four step search", AV_ME_METHOD_FSS, "me"),
221 CONST("ds", "diamond search", AV_ME_METHOD_DS, "me"),
222 CONST("hexbs", "hexagon-based search", AV_ME_METHOD_HEXBS, "me"),
223 CONST("epzs", "enhanced predictive zonal search", AV_ME_METHOD_EPZS, "me"),
224 CONST("umh", "uneven multi-hexagon search", AV_ME_METHOD_UMH, "me"),
225 { "mb_size", "macroblock size", OFFSET(mb_size), AV_OPT_TYPE_INT, {.i64 = 16}, 4, 16, FLAGS },
226 { "search_param", "search parameter", OFFSET(search_param), AV_OPT_TYPE_INT, {.i64 = 32}, 4, INT_MAX, FLAGS },
227 { "vsbmc", "variable-size block motion compensation", OFFSET(vsbmc), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
228 { "scd", "scene change detection method", OFFSET(scd_method), AV_OPT_TYPE_INT, {.i64 = SCD_METHOD_FDIFF}, SCD_METHOD_NONE, SCD_METHOD_FDIFF, FLAGS, .unit = "scene" },
229 CONST("none", "disable detection", SCD_METHOD_NONE, "scene"),
230 CONST("fdiff", "frame difference", SCD_METHOD_FDIFF, "scene"),
231 { "scd_threshold", "scene change threshold", OFFSET(scd_threshold), AV_OPT_TYPE_DOUBLE, {.dbl = 10.}, 0, 100.0, FLAGS },
232 { NULL }
233 };
234
235 AVFILTER_DEFINE_CLASS(minterpolate);
236
237 static const enum AVPixelFormat pix_fmts[] = {
238 AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
239 AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P,
240 AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P,
241 AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P,
242 AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P,
243 AV_PIX_FMT_YUVJ411P,
244 AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,
245 AV_PIX_FMT_GRAY8,
246 AV_PIX_FMT_NONE
247 };
248
249 static uint64_t get_sbad(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
250 {
251 uint8_t *data_cur = me_ctx->data_cur;
252 uint8_t *data_next = me_ctx->data_ref;
253 int linesize = me_ctx->linesize;
254 int mv_x1 = x_mv - x;
255 int mv_y1 = y_mv - y;
256 int mv_x, mv_y, i, j;
257 uint64_t sbad = 0;
258
259 x = av_clip(x, me_ctx->x_min, me_ctx->x_max);
260 y = av_clip(y, me_ctx->y_min, me_ctx->y_max);
261 mv_x = av_clip(x_mv - x, -FFMIN(x - me_ctx->x_min, me_ctx->x_max - x), FFMIN(x - me_ctx->x_min, me_ctx->x_max - x));
262 mv_y = av_clip(y_mv - y, -FFMIN(y - me_ctx->y_min, me_ctx->y_max - y), FFMIN(y - me_ctx->y_min, me_ctx->y_max - y));
263
264 data_cur += (y + mv_y) * linesize;
265 data_next += (y - mv_y) * linesize;
266
267 for (j = 0; j < me_ctx->mb_size; j++)
268 for (i = 0; i < me_ctx->mb_size; i++)
269 sbad += FFABS(data_cur[x + mv_x + i + j * linesize] - data_next[x - mv_x + i + j * linesize]);
270
271 return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - me_ctx->pred_y)) * COST_PRED_SCALE;
272 }
273
274 23392 static uint64_t get_sbad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
275 {
276 23392 uint8_t *data_cur = me_ctx->data_cur;
277 23392 uint8_t *data_next = me_ctx->data_ref;
278 23392 int linesize = me_ctx->linesize;
279 23392 int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
280 23392 int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
281 23392 int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
282 23392 int y_max = me_ctx->y_max - me_ctx->mb_size / 2;
283 23392 int mv_x1 = x_mv - x;
284 23392 int mv_y1 = y_mv - y;
285 int mv_x, mv_y, i, j;
286 23392 uint64_t sbad = 0;
287
288 23392 x = av_clip(x, x_min, x_max);
289 23392 y = av_clip(y, y_min, y_max);
290 23392 mv_x = av_clip(x_mv - x, -FFMIN(x - x_min, x_max - x), FFMIN(x - x_min, x_max - x));
291 23392 mv_y = av_clip(y_mv - y, -FFMIN(y - y_min, y_max - y), FFMIN(y - y_min, y_max - y));
292
293
2/2
✓ Branch 0 taken 748544 times.
✓ Branch 1 taken 23392 times.
771936 for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
294
2/2
✓ Branch 0 taken 23953408 times.
✓ Branch 1 taken 748544 times.
24701952 for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
295
2/2
✓ Branch 0 taken 22169924 times.
✓ Branch 1 taken 1783484 times.
23953408 sbad += FFABS(data_cur[x + mv_x + i + (y + mv_y + j) * linesize] - data_next[x - mv_x + i + (y - mv_y + j) * linesize]);
296
297 23392 return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - me_ctx->pred_y)) * COST_PRED_SCALE;
298 }
299
300 static uint64_t get_sad_ob(AVMotionEstContext *me_ctx, int x, int y, int x_mv, int y_mv)
301 {
302 uint8_t *data_ref = me_ctx->data_ref;
303 uint8_t *data_cur = me_ctx->data_cur;
304 int linesize = me_ctx->linesize;
305 int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
306 int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
307 int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
308 int y_max = me_ctx->y_max - me_ctx->mb_size / 2;
309 int mv_x = x_mv - x;
310 int mv_y = y_mv - y;
311 int i, j;
312 uint64_t sad = 0;
313
314 x = av_clip(x, x_min, x_max);
315 y = av_clip(y, y_min, y_max);
316 x_mv = av_clip(x_mv, x_min, x_max);
317 y_mv = av_clip(y_mv, y_min, y_max);
318
319 for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
320 for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
321 sad += FFABS(data_ref[x_mv + i + (y_mv + j) * linesize] - data_cur[x + i + (y + j) * linesize]);
322
323 return sad + (FFABS(mv_x - me_ctx->pred_x) + FFABS(mv_y - me_ctx->pred_y)) * COST_PRED_SCALE;
324 }
325
326 2 static int config_input(AVFilterLink *inlink)
327 {
328 2 MIContext *mi_ctx = inlink->dst->priv;
329 2 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
330 2 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
331 2 const int height = inlink->h;
332 2 const int width = inlink->w;
333 int i;
334
335 2 mi_ctx->log2_chroma_h = desc->log2_chroma_h;
336 2 mi_ctx->log2_chroma_w = desc->log2_chroma_w;
337 2 mi_ctx->bitdepth = desc->comp[0].depth;
338
339 2 mi_ctx->nb_planes = av_pix_fmt_count_planes(inlink->format);
340
341 2 mi_ctx->log2_mb_size = av_ceil_log2_c(mi_ctx->mb_size);
342 2 mi_ctx->mb_size = 1 << mi_ctx->log2_mb_size;
343
344 2 mi_ctx->b_width = width >> mi_ctx->log2_mb_size;
345 2 mi_ctx->b_height = height >> mi_ctx->log2_mb_size;
346 2 mi_ctx->b_count = mi_ctx->b_width * mi_ctx->b_height;
347
348
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 for (i = 0; i < NB_FRAMES; i++) {
349 8 Frame *frame = &mi_ctx->frames[i];
350 8 frame->blocks = av_calloc(mi_ctx->b_count, sizeof(*frame->blocks));
351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!frame->blocks)
352 return AVERROR(ENOMEM);
353 }
354
355
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (mi_ctx->mi_mode == MI_MODE_MCI) {
356
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (mi_ctx->b_width < 2 || mi_ctx->b_height < 2) {
357 av_log(inlink->dst, AV_LOG_ERROR, "Height or width < %d\n",
358 2 * mi_ctx->mb_size);
359 return AVERROR(EINVAL);
360 }
361 2 ff_me_init_context(me_ctx, mi_ctx->mb_size, mi_ctx->search_param,
362 2 width, height, 0, (mi_ctx->b_width - 1) << mi_ctx->log2_mb_size,
363 2 0, (mi_ctx->b_height - 1) << mi_ctx->log2_mb_size);
364
365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (mi_ctx->me_mode == ME_MODE_BIDIR)
366 me_ctx->get_cost = &get_sad_ob;
367
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else if (mi_ctx->me_mode == ME_MODE_BILAT)
368 2 me_ctx->get_cost = &get_sbad_ob;
369
370 2 mi_ctx->pixel_mvs = av_calloc(width * height, sizeof(*mi_ctx->pixel_mvs));
371 2 mi_ctx->pixel_weights = av_calloc(width * height, sizeof(*mi_ctx->pixel_weights));
372 2 mi_ctx->pixel_refs = av_calloc(width * height, sizeof(*mi_ctx->pixel_refs));
373
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2 if (!mi_ctx->pixel_mvs || !mi_ctx->pixel_weights || !mi_ctx->pixel_refs)
374 return AVERROR(ENOMEM);
375
376
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (mi_ctx->me_mode == ME_MODE_BILAT)
377
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!FF_ALLOCZ_TYPED_ARRAY(mi_ctx->int_blocks, mi_ctx->b_count))
378 return AVERROR(ENOMEM);
379
380
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (mi_ctx->me_method == AV_ME_METHOD_EPZS) {
381
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 for (i = 0; i < 3; i++) {
382 6 mi_ctx->mv_table[i] = av_calloc(mi_ctx->b_count, sizeof(*mi_ctx->mv_table[0]));
383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!mi_ctx->mv_table[i])
384 return AVERROR(ENOMEM);
385 }
386 }
387 }
388
389
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (mi_ctx->scd_method == SCD_METHOD_FDIFF) {
390
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 mi_ctx->sad = ff_scene_sad_get_fn(mi_ctx->bitdepth == 8 ? 8 : 16);
391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!mi_ctx->sad)
392 return AVERROR(EINVAL);
393 }
394
395 2 return 0;
396 }
397
398 2 static int config_output(AVFilterLink *outlink)
399 {
400 2 MIContext *mi_ctx = outlink->src->priv;
401 2 FilterLink *l = ff_filter_link(outlink);
402
403 2 l->frame_rate = mi_ctx->frame_rate;
404 2 outlink->time_base = av_inv_q(mi_ctx->frame_rate);
405
406 2 return 0;
407 }
408
409 #define ADD_PRED(preds, px, py)\
410 do {\
411 preds.mvs[preds.nb][0] = px;\
412 preds.mvs[preds.nb][1] = py;\
413 preds.nb++;\
414 } while(0)
415
416 1200 static void search_mv(MIContext *mi_ctx, Block *blocks, int mb_x, int mb_y, int dir)
417 {
418 1200 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
419 1200 AVMotionEstPredictor *preds = me_ctx->preds;
420 1200 Block *block = &blocks[mb_x + mb_y * mi_ctx->b_width];
421
422 1200 const int x_mb = mb_x << mi_ctx->log2_mb_size;
423 1200 const int y_mb = mb_y << mi_ctx->log2_mb_size;
424 1200 const int mb_i = mb_x + mb_y * mi_ctx->b_width;
425 1200 int mv[2] = {x_mb, y_mb};
426
427
1/10
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1200 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1200 switch (mi_ctx->me_method) {
428 case AV_ME_METHOD_ESA:
429 ff_me_search_esa(me_ctx, x_mb, y_mb, mv);
430 break;
431 case AV_ME_METHOD_TSS:
432 ff_me_search_tss(me_ctx, x_mb, y_mb, mv);
433 break;
434 case AV_ME_METHOD_TDLS:
435 ff_me_search_tdls(me_ctx, x_mb, y_mb, mv);
436 break;
437 case AV_ME_METHOD_NTSS:
438 ff_me_search_ntss(me_ctx, x_mb, y_mb, mv);
439 break;
440 case AV_ME_METHOD_FSS:
441 ff_me_search_fss(me_ctx, x_mb, y_mb, mv);
442 break;
443 case AV_ME_METHOD_DS:
444 ff_me_search_ds(me_ctx, x_mb, y_mb, mv);
445 break;
446 case AV_ME_METHOD_HEXBS:
447 ff_me_search_hexbs(me_ctx, x_mb, y_mb, mv);
448 break;
449 1200 case AV_ME_METHOD_EPZS:
450
451 1200 preds[0].nb = 0;
452 1200 preds[1].nb = 0;
453
454 1200 ADD_PRED(preds[0], 0, 0);
455
456 //left mb in current frame
457
2/2
✓ Branch 0 taken 1140 times.
✓ Branch 1 taken 60 times.
1200 if (mb_x > 0)
458 1140 ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - 1][dir][0], mi_ctx->mv_table[0][mb_i - 1][dir][1]);
459
460 //top mb in current frame
461
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 80 times.
1200 if (mb_y > 0)
462 1120 ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width][dir][0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width][dir][1]);
463
464 //top-right mb in current frame
465
4/4
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 1064 times.
✓ Branch 3 taken 56 times.
1200 if (mb_y > 0 && mb_x + 1 < mi_ctx->b_width)
466 1064 ADD_PRED(preds[0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width + 1][dir][0], mi_ctx->mv_table[0][mb_i - mi_ctx->b_width + 1][dir][1]);
467
468 //median predictor
469
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 192 times.
1200 if (preds[0].nb == 4) {
470 1008 me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
471 1008 me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
472
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 80 times.
192 } else if (preds[0].nb == 3) {
473 112 me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
474 112 me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
475
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 4 times.
80 } else if (preds[0].nb == 2) {
476 76 me_ctx->pred_x = preds[0].mvs[1][0];
477 76 me_ctx->pred_y = preds[0].mvs[1][1];
478 } else {
479 4 me_ctx->pred_x = 0;
480 4 me_ctx->pred_y = 0;
481 }
482
483 //collocated mb in prev frame
484 1200 ADD_PRED(preds[0], mi_ctx->mv_table[1][mb_i][dir][0], mi_ctx->mv_table[1][mb_i][dir][1]);
485
486 //accelerator motion vector of collocated block in prev frame
487 1200 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i][dir][0] + (mi_ctx->mv_table[1][mb_i][dir][0] - mi_ctx->mv_table[2][mb_i][dir][0]),
488 mi_ctx->mv_table[1][mb_i][dir][1] + (mi_ctx->mv_table[1][mb_i][dir][1] - mi_ctx->mv_table[2][mb_i][dir][1]));
489
490 //left mb in prev frame
491
2/2
✓ Branch 0 taken 1140 times.
✓ Branch 1 taken 60 times.
1200 if (mb_x > 0)
492 1140 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i - 1][dir][0], mi_ctx->mv_table[1][mb_i - 1][dir][1]);
493
494 //top mb in prev frame
495
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 80 times.
1200 if (mb_y > 0)
496 1120 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i - mi_ctx->b_width][dir][0], mi_ctx->mv_table[1][mb_i - mi_ctx->b_width][dir][1]);
497
498 //right mb in prev frame
499
2/2
✓ Branch 0 taken 1140 times.
✓ Branch 1 taken 60 times.
1200 if (mb_x + 1 < mi_ctx->b_width)
500 1140 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i + 1][dir][0], mi_ctx->mv_table[1][mb_i + 1][dir][1]);
501
502 //bottom mb in prev frame
503
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 80 times.
1200 if (mb_y + 1 < mi_ctx->b_height)
504 1120 ADD_PRED(preds[1], mi_ctx->mv_table[1][mb_i + mi_ctx->b_width][dir][0], mi_ctx->mv_table[1][mb_i + mi_ctx->b_width][dir][1]);
505
506 1200 ff_me_search_epzs(me_ctx, x_mb, y_mb, mv);
507
508 1200 mi_ctx->mv_table[0][mb_i][dir][0] = mv[0] - x_mb;
509 1200 mi_ctx->mv_table[0][mb_i][dir][1] = mv[1] - y_mb;
510
511 1200 break;
512 case AV_ME_METHOD_UMH:
513
514 preds[0].nb = 0;
515
516 ADD_PRED(preds[0], 0, 0);
517
518 //left mb in current frame
519 if (mb_x > 0)
520 ADD_PRED(preds[0], blocks[mb_i - 1].mvs[dir][0], blocks[mb_i - 1].mvs[dir][1]);
521
522 if (mb_y > 0) {
523 //top mb in current frame
524 ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width].mvs[dir][0], blocks[mb_i - mi_ctx->b_width].mvs[dir][1]);
525
526 //top-right mb in current frame
527 if (mb_x + 1 < mi_ctx->b_width)
528 ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width + 1].mvs[dir][0], blocks[mb_i - mi_ctx->b_width + 1].mvs[dir][1]);
529 //top-left mb in current frame
530 else if (mb_x > 0)
531 ADD_PRED(preds[0], blocks[mb_i - mi_ctx->b_width - 1].mvs[dir][0], blocks[mb_i - mi_ctx->b_width - 1].mvs[dir][1]);
532 }
533
534 //median predictor
535 if (preds[0].nb == 4) {
536 me_ctx->pred_x = mid_pred(preds[0].mvs[1][0], preds[0].mvs[2][0], preds[0].mvs[3][0]);
537 me_ctx->pred_y = mid_pred(preds[0].mvs[1][1], preds[0].mvs[2][1], preds[0].mvs[3][1]);
538 } else if (preds[0].nb == 3) {
539 me_ctx->pred_x = mid_pred(0, preds[0].mvs[1][0], preds[0].mvs[2][0]);
540 me_ctx->pred_y = mid_pred(0, preds[0].mvs[1][1], preds[0].mvs[2][1]);
541 } else if (preds[0].nb == 2) {
542 me_ctx->pred_x = preds[0].mvs[1][0];
543 me_ctx->pred_y = preds[0].mvs[1][1];
544 } else {
545 me_ctx->pred_x = 0;
546 me_ctx->pred_y = 0;
547 }
548
549 ff_me_search_umh(me_ctx, x_mb, y_mb, mv);
550
551 break;
552 }
553
554 1200 block->mvs[dir][0] = mv[0] - x_mb;
555 1200 block->mvs[dir][1] = mv[1] - y_mb;
556 1200 }
557
558 4 static void bilateral_me(MIContext *mi_ctx)
559 {
560 Block *block;
561 int mb_x, mb_y;
562
563
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 4 times.
64 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
564
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 60 times.
1260 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
565 1200 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
566
567 1200 block->cid = 0;
568 1200 block->sb = 0;
569
570 1200 block->mvs[0][0] = 0;
571 1200 block->mvs[0][1] = 0;
572 }
573
574
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 4 times.
64 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
575
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 60 times.
1260 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
576 1200 search_mv(mi_ctx, mi_ctx->int_blocks, mb_x, mb_y, 0);
577 4 }
578
579 static int var_size_bme(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n)
580 {
581 AVMotionEstContext *me_ctx = &mi_ctx->me_ctx;
582 uint64_t cost_sb, cost_old;
583 int mb_size = me_ctx->mb_size;
584 int search_param = me_ctx->search_param;
585 int mv_x, mv_y;
586 int x, y;
587 int ret;
588
589 me_ctx->mb_size = 1 << n;
590 cost_old = me_ctx->get_cost(me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
591 me_ctx->mb_size = mb_size;
592
593 if (!cost_old) {
594 block->sb = 0;
595 return 0;
596 }
597
598 if (!block->subs) {
599 block->subs = av_mallocz(4 * sizeof(*block->subs));
600 if (!block->subs)
601 return AVERROR(ENOMEM);
602 }
603
604 block->sb = 1;
605
606 for (y = 0; y < 2; y++)
607 for (x = 0; x < 2; x++) {
608 Block *sb = &block->subs[x + y * 2];
609 int mv[2] = {x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]};
610
611 me_ctx->mb_size = 1 << (n - 1);
612 me_ctx->search_param = 2;
613 me_ctx->pred_x = block->mvs[0][0];
614 me_ctx->pred_y = block->mvs[0][1];
615
616 cost_sb = ff_me_search_ds(&mi_ctx->me_ctx, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1], mv);
617 mv_x = mv[0] - x_mb;
618 mv_y = mv[1] - y_mb;
619
620 me_ctx->mb_size = mb_size;
621 me_ctx->search_param = search_param;
622
623 if (cost_sb < cost_old / 4) {
624 sb->mvs[0][0] = mv_x;
625 sb->mvs[0][1] = mv_y;
626
627 if (n > 1) {
628 if (ret = var_size_bme(mi_ctx, sb, x_mb + (x << (n - 1)), y_mb + (y << (n - 1)), n - 1))
629 return ret;
630 } else
631 sb->sb = 0;
632 } else {
633 block->sb = 0;
634 return 0;
635 }
636 }
637
638 return 0;
639 }
640
641 static int cluster_mvs(MIContext *mi_ctx)
642 {
643 int changed, c, c_max = 0;
644 int mb_x, mb_y, x, y;
645 int mv_x, mv_y, avg_x, avg_y, dx, dy;
646 int d, ret;
647 Block *block;
648 Cluster *cluster, *cluster_new;
649
650 do {
651 changed = 0;
652 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
653 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
654 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
655 c = block->cid;
656 cluster = &mi_ctx->clusters[c];
657 mv_x = block->mvs[0][0];
658 mv_y = block->mvs[0][1];
659
660 if (cluster->nb < 2)
661 continue;
662
663 avg_x = cluster->sum[0] / cluster->nb;
664 avg_y = cluster->sum[1] / cluster->nb;
665 dx = avg_x - mv_x;
666 dy = avg_y - mv_y;
667
668 if (FFABS(dx) > CLUSTER_THRESHOLD || FFABS(dy) > CLUSTER_THRESHOLD) {
669
670 for (d = 1; d < 5; d++)
671 for (y = FFMAX(mb_y - d, 0); y < FFMIN(mb_y + d + 1, mi_ctx->b_height); y++)
672 for (x = FFMAX(mb_x - d, 0); x < FFMIN(mb_x + d + 1, mi_ctx->b_width); x++) {
673 Block *nb = &mi_ctx->int_blocks[x + y * mi_ctx->b_width];
674 if (nb->cid > block->cid) {
675 if (nb->cid < c || c == block->cid)
676 c = nb->cid;
677 }
678 }
679
680 if (c == block->cid)
681 c = c_max + 1;
682
683 if (c >= NB_CLUSTERS) {
684 continue;
685 }
686
687 cluster_new = &mi_ctx->clusters[c];
688 cluster_new->sum[0] += mv_x;
689 cluster_new->sum[1] += mv_y;
690 cluster->sum[0] -= mv_x;
691 cluster->sum[1] -= mv_y;
692 cluster_new->nb++;
693 cluster->nb--;
694
695 c_max = FFMAX(c_max, c);
696 block->cid = c;
697
698 changed = 1;
699 }
700 }
701 } while (changed);
702
703 /* find boundaries */
704 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
705 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
706 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
707 for (y = FFMAX(mb_y - 1, 0); y < FFMIN(mb_y + 2, mi_ctx->b_height); y++)
708 for (x = FFMAX(mb_x - 1, 0); x < FFMIN(mb_x + 2, mi_ctx->b_width); x++) {
709 dx = x - mb_x;
710 dy = y - mb_y;
711
712 if ((x - mb_x) && (y - mb_y) || !dx && !dy)
713 continue;
714
715 if (!mb_x || !mb_y || mb_x == mi_ctx->b_width - 1 || mb_y == mi_ctx->b_height - 1)
716 continue;
717
718 if (block->cid != mi_ctx->int_blocks[x + y * mi_ctx->b_width].cid) {
719 if (!dx && block->cid == mi_ctx->int_blocks[x + (mb_y - dy) * mi_ctx->b_width].cid ||
720 !dy && block->cid == mi_ctx->int_blocks[(mb_x - dx) + y * mi_ctx->b_width].cid) {
721 if (ret = var_size_bme(mi_ctx, block, mb_x << mi_ctx->log2_mb_size, mb_y << mi_ctx->log2_mb_size, mi_ctx->log2_mb_size))
722 return ret;
723 }
724 }
725 }
726 }
727
728 return 0;
729 }
730
731 10 static int inject_frame(AVFilterLink *inlink, AVFrame *avf_in)
732 {
733 10 AVFilterContext *ctx = inlink->dst;
734 10 MIContext *mi_ctx = ctx->priv;
735 Frame frame_tmp;
736 int mb_x, mb_y, dir;
737
738 10 av_frame_free(&mi_ctx->frames[0].avf);
739 10 frame_tmp = mi_ctx->frames[0];
740 10 memmove(&mi_ctx->frames[0], &mi_ctx->frames[1], sizeof(mi_ctx->frames[0]) * (NB_FRAMES - 1));
741 10 mi_ctx->frames[NB_FRAMES - 1] = frame_tmp;
742 10 mi_ctx->frames[NB_FRAMES - 1].avf = avf_in;
743
744
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (mi_ctx->mi_mode == MI_MODE_MCI) {
745
746
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (mi_ctx->me_method == AV_ME_METHOD_EPZS) {
747 10 mi_ctx->mv_table[2] = memcpy(mi_ctx->mv_table[2], mi_ctx->mv_table[1], sizeof(*mi_ctx->mv_table[1]) * mi_ctx->b_count);
748 10 mi_ctx->mv_table[1] = memcpy(mi_ctx->mv_table[1], mi_ctx->mv_table[0], sizeof(*mi_ctx->mv_table[0]) * mi_ctx->b_count);
749 }
750
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (mi_ctx->me_mode == ME_MODE_BIDIR) {
752
753 if (mi_ctx->frames[1].avf) {
754 for (dir = 0; dir < 2; dir++) {
755 mi_ctx->me_ctx.linesize = mi_ctx->frames[2].avf->linesize[0];
756 mi_ctx->me_ctx.data_cur = mi_ctx->frames[2].avf->data[0];
757 mi_ctx->me_ctx.data_ref = mi_ctx->frames[dir ? 3 : 1].avf->data[0];
758
759 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
760 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++)
761 search_mv(mi_ctx, mi_ctx->frames[2].blocks, mb_x, mb_y, dir);
762 }
763 }
764
765
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
766 Block *block;
767 int i, ret;
768
769
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
10 if (!mi_ctx->frames[0].avf)
770 6 return 0;
771
772 4 mi_ctx->me_ctx.linesize = mi_ctx->frames[0].avf->linesize[0];
773 4 mi_ctx->me_ctx.data_cur = mi_ctx->frames[1].avf->data[0];
774 4 mi_ctx->me_ctx.data_ref = mi_ctx->frames[2].avf->data[0];
775
776 4 bilateral_me(mi_ctx);
777
778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
779
780 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
781 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
782 int x_mb = mb_x << mi_ctx->log2_mb_size;
783 int y_mb = mb_y << mi_ctx->log2_mb_size;
784 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
785
786 block->sbad = get_sbad(&mi_ctx->me_ctx, x_mb, y_mb, x_mb + block->mvs[0][0], y_mb + block->mvs[0][1]);
787 }
788 }
789
790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (mi_ctx->vsbmc) {
791
792 for (i = 0; i < NB_CLUSTERS; i++) {
793 mi_ctx->clusters[i].sum[0] = 0;
794 mi_ctx->clusters[i].sum[1] = 0;
795 mi_ctx->clusters[i].nb = 0;
796 }
797
798 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
799 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
800 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
801
802 mi_ctx->clusters[0].sum[0] += block->mvs[0][0];
803 mi_ctx->clusters[0].sum[1] += block->mvs[0][1];
804 }
805
806 mi_ctx->clusters[0].nb = mi_ctx->b_count;
807
808 if (ret = cluster_mvs(mi_ctx))
809 return ret;
810 }
811 }
812 }
813
814 4 return 0;
815 }
816
817 4 static int detect_scene_change(AVFilterContext *ctx)
818 {
819 4 MIContext *mi_ctx = ctx->priv;
820 4 AVFilterLink *input = ctx->inputs[0];
821 4 uint8_t *p1 = mi_ctx->frames[1].avf->data[0];
822 4 ptrdiff_t linesize1 = mi_ctx->frames[1].avf->linesize[0];
823 4 uint8_t *p2 = mi_ctx->frames[2].avf->data[0];
824 4 ptrdiff_t linesize2 = mi_ctx->frames[2].avf->linesize[0];
825
826
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (mi_ctx->scd_method == SCD_METHOD_FDIFF) {
827 4 double ret = 0, mafd, diff;
828 uint64_t sad;
829 4 mi_ctx->sad(p1, linesize1, p2, linesize2, input->w, input->h, &sad);
830 4 mafd = (double) sad * 100.0 / (input->h * input->w) / (1 << mi_ctx->bitdepth);
831 4 diff = fabs(mafd - mi_ctx->prev_mafd);
832
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 ret = av_clipf(FFMIN(mafd, diff), 0, 100.0);
833 4 mi_ctx->prev_mafd = mafd;
834
835 4 return ret >= mi_ctx->scd_threshold;
836 }
837
838 return 0;
839 }
840
841 #define ADD_PIXELS(b_weight, mv_x, mv_y)\
842 do {\
843 if (!b_weight || pixel_refs->nb + 1 >= NB_PIXEL_MVS)\
844 continue;\
845 pixel_refs->refs[pixel_refs->nb] = 1;\
846 pixel_weights->weights[pixel_refs->nb] = b_weight * (ALPHA_MAX - alpha);\
847 pixel_mvs->mvs[pixel_refs->nb][0] = av_clip((mv_x * alpha) / ALPHA_MAX, x_min, x_max);\
848 pixel_mvs->mvs[pixel_refs->nb][1] = av_clip((mv_y * alpha) / ALPHA_MAX, y_min, y_max);\
849 pixel_refs->nb++;\
850 pixel_refs->refs[pixel_refs->nb] = 2;\
851 pixel_weights->weights[pixel_refs->nb] = b_weight * alpha;\
852 pixel_mvs->mvs[pixel_refs->nb][0] = av_clip(-mv_x * (ALPHA_MAX - alpha) / ALPHA_MAX, x_min, x_max);\
853 pixel_mvs->mvs[pixel_refs->nb][1] = av_clip(-mv_y * (ALPHA_MAX - alpha) / ALPHA_MAX, y_min, y_max);\
854 pixel_refs->nb++;\
855 } while(0)
856
857 static void bidirectional_obmc(MIContext *mi_ctx, int alpha)
858 {
859 int x, y;
860 int width = mi_ctx->frames[0].avf->width;
861 int height = mi_ctx->frames[0].avf->height;
862 int mb_y, mb_x, dir;
863
864 for (y = 0; y < height; y++)
865 for (x = 0; x < width; x++)
866 mi_ctx->pixel_refs[x + y * width].nb = 0;
867
868 for (dir = 0; dir < 2; dir++)
869 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
870 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
871 int a = dir ? alpha : (ALPHA_MAX - alpha);
872 int mv_x = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][0];
873 int mv_y = mi_ctx->frames[2 - dir].blocks[mb_x + mb_y * mi_ctx->b_width].mvs[dir][1];
874 int start_x, start_y;
875 int startc_x, startc_y, endc_x, endc_y;
876
877 start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_x * a / ALPHA_MAX;
878 start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2 + mv_y * a / ALPHA_MAX;
879
880 startc_x = av_clip(start_x, 0, width - 1);
881 startc_y = av_clip(start_y, 0, height - 1);
882 endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
883 endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
884
885 if (dir) {
886 mv_x = -mv_x;
887 mv_y = -mv_y;
888 }
889
890 for (y = startc_y; y < endc_y; y++) {
891 int y_min = -y;
892 int y_max = height - y - 1;
893 for (x = startc_x; x < endc_x; x++) {
894 int x_min = -x;
895 int x_max = width - x - 1;
896 int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
897 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
898 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
899 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
900
901 ADD_PIXELS(obmc_weight, mv_x, mv_y);
902 }
903 }
904 }
905 }
906
907 8 static void set_frame_data(MIContext *mi_ctx, int alpha, AVFrame *avf_out)
908 {
909 int x, y, plane;
910
911
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
32 for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
912 24 int width = avf_out->width;
913 24 int height = avf_out->height;
914
4/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
24 int chroma = plane == 1 || plane == 2;
915
916
2/2
✓ Branch 0 taken 5760 times.
✓ Branch 1 taken 24 times.
5784 for (y = 0; y < height; y++)
917
2/2
✓ Branch 0 taken 1843200 times.
✓ Branch 1 taken 5760 times.
1848960 for (x = 0; x < width; x++) {
918 int x_mv, y_mv;
919 1843200 int weight_sum = 0;
920 1843200 int i, val = 0;
921 1843200 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * avf_out->width];
922 1843200 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * avf_out->width];
923 1843200 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * avf_out->width];
924
925
2/2
✓ Branch 0 taken 13505936 times.
✓ Branch 1 taken 1843200 times.
15349136 for (i = 0; i < pixel_refs->nb; i++)
926 13505936 weight_sum += pixel_weights->weights[i];
927
928
3/4
✓ Branch 0 taken 1838728 times.
✓ Branch 1 taken 4472 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1838728 times.
1843200 if (!weight_sum || !pixel_refs->nb) {
929 4472 pixel_weights->weights[0] = ALPHA_MAX - alpha;
930 4472 pixel_refs->refs[0] = 1;
931 4472 pixel_mvs->mvs[0][0] = 0;
932 4472 pixel_mvs->mvs[0][1] = 0;
933 4472 pixel_weights->weights[1] = alpha;
934 4472 pixel_refs->refs[1] = 2;
935 4472 pixel_mvs->mvs[1][0] = 0;
936 4472 pixel_mvs->mvs[1][1] = 0;
937 4472 pixel_refs->nb = 2;
938
939 4472 weight_sum = ALPHA_MAX;
940 }
941
942
2/2
✓ Branch 0 taken 13514880 times.
✓ Branch 1 taken 1843200 times.
15358080 for (i = 0; i < pixel_refs->nb; i++) {
943 13514880 Frame *frame = &mi_ctx->frames[pixel_refs->refs[i]];
944
2/2
✓ Branch 0 taken 9009920 times.
✓ Branch 1 taken 4504960 times.
13514880 if (chroma) {
945 9009920 x_mv = (x >> mi_ctx->log2_chroma_w) + pixel_mvs->mvs[i][0] / (1 << mi_ctx->log2_chroma_w);
946 9009920 y_mv = (y >> mi_ctx->log2_chroma_h) + pixel_mvs->mvs[i][1] / (1 << mi_ctx->log2_chroma_h);
947 } else {
948 4504960 x_mv = x + pixel_mvs->mvs[i][0];
949 4504960 y_mv = y + pixel_mvs->mvs[i][1];
950 }
951
952 13514880 val += pixel_weights->weights[i] * frame->avf->data[plane][x_mv + y_mv * frame->avf->linesize[plane]];
953 }
954
955
1/2
✓ Branch 0 taken 1843200 times.
✗ Branch 1 not taken.
1843200 val = ROUNDED_DIV(val, weight_sum);
956
957
2/2
✓ Branch 0 taken 1228800 times.
✓ Branch 1 taken 614400 times.
1843200 if (chroma)
958 1228800 avf_out->data[plane][(x >> mi_ctx->log2_chroma_w) + (y >> mi_ctx->log2_chroma_h) * avf_out->linesize[plane]] = val;
959 else
960 614400 avf_out->data[plane][x + y * avf_out->linesize[plane]] = val;
961 }
962 }
963 8 }
964
965 static void var_size_bmc(MIContext *mi_ctx, Block *block, int x_mb, int y_mb, int n, int alpha)
966 {
967 int sb_x, sb_y;
968 int width = mi_ctx->frames[0].avf->width;
969 int height = mi_ctx->frames[0].avf->height;
970
971 for (sb_y = 0; sb_y < 2; sb_y++)
972 for (sb_x = 0; sb_x < 2; sb_x++) {
973 Block *sb = &block->subs[sb_x + sb_y * 2];
974
975 if (sb->sb)
976 var_size_bmc(mi_ctx, sb, x_mb + (sb_x << (n - 1)), y_mb + (sb_y << (n - 1)), n - 1, alpha);
977 else {
978 int x, y;
979 int mv_x = sb->mvs[0][0] * 2;
980 int mv_y = sb->mvs[0][1] * 2;
981
982 int start_x = x_mb + (sb_x << (n - 1));
983 int start_y = y_mb + (sb_y << (n - 1));
984 int end_x = start_x + (1 << (n - 1));
985 int end_y = start_y + (1 << (n - 1));
986
987 for (y = start_y; y < end_y; y++) {
988 int y_min = -y;
989 int y_max = height - y - 1;
990 for (x = start_x; x < end_x; x++) {
991 int x_min = -x;
992 int x_max = width - x - 1;
993 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
994 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
995 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
996
997 ADD_PIXELS(PX_WEIGHT_MAX, mv_x, mv_y);
998 }
999 }
1000 }
1001 }
1002 }
1003
1004 2400 static void bilateral_obmc(MIContext *mi_ctx, Block *block, int mb_x, int mb_y, int alpha)
1005 {
1006 int x, y;
1007 2400 int width = mi_ctx->frames[0].avf->width;
1008 2400 int height = mi_ctx->frames[0].avf->height;
1009
1010 Block *nb;
1011 int nb_x, nb_y;
1012 uint64_t sbads[9];
1013
1014 2400 int mv_x = block->mvs[0][0] * 2;
1015 2400 int mv_y = block->mvs[0][1] * 2;
1016 int start_x, start_y;
1017 int startc_x, startc_y, endc_x, endc_y;
1018
1019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2400 times.
2400 if (mi_ctx->mc_mode == MC_MODE_AOBMC)
1020 for (nb_y = FFMAX(0, mb_y - 1); nb_y < FFMIN(mb_y + 2, mi_ctx->b_height); nb_y++)
1021 for (nb_x = FFMAX(0, mb_x - 1); nb_x < FFMIN(mb_x + 2, mi_ctx->b_width); nb_x++) {
1022 int x_nb = nb_x << mi_ctx->log2_mb_size;
1023 int y_nb = nb_y << mi_ctx->log2_mb_size;
1024
1025 if (nb_x - mb_x || nb_y - mb_y)
1026 sbads[nb_x - mb_x + 1 + (nb_y - mb_y + 1) * 3] = get_sbad(&mi_ctx->me_ctx, x_nb, y_nb, x_nb + block->mvs[0][0], y_nb + block->mvs[0][1]);
1027 }
1028
1029 2400 start_x = (mb_x << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1030 2400 start_y = (mb_y << mi_ctx->log2_mb_size) - mi_ctx->mb_size / 2;
1031
1032 2400 startc_x = av_clip(start_x, 0, width - 1);
1033 2400 startc_y = av_clip(start_y, 0, height - 1);
1034 2400 endc_x = av_clip(start_x + (2 << mi_ctx->log2_mb_size), 0, width - 1);
1035 2400 endc_y = av_clip(start_y + (2 << mi_ctx->log2_mb_size), 0, height - 1);
1036
1037
2/2
✓ Branch 0 taken 74080 times.
✓ Branch 1 taken 2400 times.
76480 for (y = startc_y; y < endc_y; y++) {
1038 74080 int y_min = -y;
1039 74080 int y_max = height - y - 1;
1040
2/2
✓ Branch 0 taken 2307592 times.
✓ Branch 1 taken 74080 times.
2381672 for (x = startc_x; x < endc_x; x++) {
1041 2307592 int x_min = -x;
1042 2307592 int x_max = width - x - 1;
1043 2307592 int obmc_weight = obmc_tab_linear[4 - mi_ctx->log2_mb_size][(x - start_x) + ((y - start_y) << (mi_ctx->log2_mb_size + 1))];
1044 2307592 PixelMVS *pixel_mvs = &mi_ctx->pixel_mvs[x + y * width];
1045 2307592 PixelWeights *pixel_weights = &mi_ctx->pixel_weights[x + y * width];
1046 2307592 PixelRefs *pixel_refs = &mi_ctx->pixel_refs[x + y * width];
1047
1048
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2307592 times.
2307592 if (mi_ctx->mc_mode == MC_MODE_AOBMC) {
1049 nb_x = (((x - start_x) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1050 nb_y = (((y - start_y) >> (mi_ctx->log2_mb_size - 1)) * 2 - 3) / 2;
1051
1052 if (nb_x || nb_y) {
1053 uint64_t sbad = sbads[nb_x + 1 + (nb_y + 1) * 3];
1054 nb = &mi_ctx->int_blocks[mb_x + nb_x + (mb_y + nb_y) * mi_ctx->b_width];
1055
1056 if (sbad && sbad != UINT64_MAX && nb->sbad != UINT64_MAX) {
1057 int phi = av_clip(ALPHA_MAX * nb->sbad / sbad, 0, ALPHA_MAX);
1058 obmc_weight = obmc_weight * phi / ALPHA_MAX;
1059 }
1060 }
1061 }
1062
1063
3/4
✓ Branch 0 taken 2248008 times.
✓ Branch 1 taken 59584 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2248008 times.
2307592 ADD_PIXELS(obmc_weight, mv_x, mv_y);
1064 }
1065 }
1066 2400 }
1067
1068 13 static void interpolate(AVFilterLink *inlink, AVFrame *avf_out)
1069 {
1070 13 AVFilterContext *ctx = inlink->dst;
1071 13 AVFilterLink *outlink = ctx->outputs[0];
1072 13 MIContext *mi_ctx = ctx->priv;
1073 int x, y;
1074 int plane, alpha;
1075 int64_t pts;
1076
1077 13 pts = av_rescale(avf_out->pts, (int64_t) ALPHA_MAX * outlink->time_base.num * inlink->time_base.den,
1078 13 (int64_t) outlink->time_base.den * inlink->time_base.num);
1079
1080
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (mi_ctx->frames[2].avf->pts > mi_ctx->frames[1].avf->pts) {
1081 13 alpha = (pts - mi_ctx->frames[1].avf->pts * ALPHA_MAX) / (mi_ctx->frames[2].avf->pts - mi_ctx->frames[1].avf->pts);
1082 13 alpha = av_clip(alpha, 0, ALPHA_MAX);
1083 } else {
1084 av_log(ctx, AV_LOG_DEBUG, "duplicate input PTS detected\n");
1085 alpha = 0;
1086 }
1087
1088
4/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 8 times.
13 if (alpha == 0 || alpha == ALPHA_MAX) {
1089
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 av_frame_copy(avf_out, alpha ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1090 5 return;
1091 }
1092
1093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (mi_ctx->scene_changed) {
1094 av_log(ctx, AV_LOG_DEBUG, "scene changed, input pts %"PRId64"\n", mi_ctx->frames[1].avf->pts);
1095 /* duplicate frame */
1096 av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1097 return;
1098 }
1099
1100
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 switch(mi_ctx->mi_mode) {
1101 case MI_MODE_DUP:
1102 av_frame_copy(avf_out, alpha > ALPHA_MAX / 2 ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf);
1103
1104 break;
1105 case MI_MODE_BLEND:
1106 for (plane = 0; plane < mi_ctx->nb_planes; plane++) {
1107 int width = avf_out->width;
1108 int height = avf_out->height;
1109
1110 if (plane == 1 || plane == 2) {
1111 width = AV_CEIL_RSHIFT(width, mi_ctx->log2_chroma_w);
1112 height = AV_CEIL_RSHIFT(height, mi_ctx->log2_chroma_h);
1113 }
1114
1115 for (y = 0; y < height; y++) {
1116 for (x = 0; x < width; x++) {
1117 avf_out->data[plane][x + y * avf_out->linesize[plane]] =
1118 (alpha * mi_ctx->frames[2].avf->data[plane][x + y * mi_ctx->frames[2].avf->linesize[plane]] +
1119 (ALPHA_MAX - alpha) * mi_ctx->frames[1].avf->data[plane][x + y * mi_ctx->frames[1].avf->linesize[plane]] + 512) >> 10;
1120 }
1121 }
1122 }
1123
1124 break;
1125 8 case MI_MODE_MCI:
1126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (mi_ctx->me_mode == ME_MODE_BIDIR) {
1127 bidirectional_obmc(mi_ctx, alpha);
1128 set_frame_data(mi_ctx, alpha, avf_out);
1129
1130
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 } else if (mi_ctx->me_mode == ME_MODE_BILAT) {
1131 int mb_x, mb_y;
1132 Block *block;
1133
1134
2/2
✓ Branch 0 taken 1920 times.
✓ Branch 1 taken 8 times.
1928 for (y = 0; y < mi_ctx->frames[0].avf->height; y++)
1135
2/2
✓ Branch 0 taken 614400 times.
✓ Branch 1 taken 1920 times.
616320 for (x = 0; x < mi_ctx->frames[0].avf->width; x++)
1136 614400 mi_ctx->pixel_refs[x + y * mi_ctx->frames[0].avf->width].nb = 0;
1137
1138
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 8 times.
128 for (mb_y = 0; mb_y < mi_ctx->b_height; mb_y++)
1139
2/2
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 120 times.
2520 for (mb_x = 0; mb_x < mi_ctx->b_width; mb_x++) {
1140 2400 block = &mi_ctx->int_blocks[mb_x + mb_y * mi_ctx->b_width];
1141
1142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2400 times.
2400 if (block->sb)
1143 var_size_bmc(mi_ctx, block, mb_x << mi_ctx->log2_mb_size, mb_y << mi_ctx->log2_mb_size, mi_ctx->log2_mb_size, alpha);
1144
1145 2400 bilateral_obmc(mi_ctx, block, mb_x, mb_y, alpha);
1146
1147 }
1148
1149 8 set_frame_data(mi_ctx, alpha, avf_out);
1150 }
1151
1152 8 break;
1153 }
1154 }
1155
1156 8 static int filter_frame(AVFilterLink *inlink, AVFrame *avf_in)
1157 {
1158 8 AVFilterContext *ctx = inlink->dst;
1159 8 AVFilterLink *outlink = ctx->outputs[0];
1160 8 MIContext *mi_ctx = ctx->priv;
1161 int ret;
1162
1163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (avf_in->pts == AV_NOPTS_VALUE) {
1164 ret = ff_filter_frame(ctx->outputs[0], avf_in);
1165 return ret;
1166 }
1167
1168
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
8 if (!mi_ctx->frames[NB_FRAMES - 1].avf || avf_in->pts < mi_ctx->frames[NB_FRAMES - 1].avf->pts) {
1169 2 av_log(ctx, AV_LOG_VERBOSE, "Initializing out pts from input pts %"PRId64"\n", avf_in->pts);
1170 2 mi_ctx->out_pts = av_rescale_q(avf_in->pts, inlink->time_base, outlink->time_base);
1171 }
1172
1173
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (!mi_ctx->frames[NB_FRAMES - 1].avf)
1174
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (ret = inject_frame(inlink, av_frame_clone(avf_in)))
1175 return ret;
1176
1177
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (ret = inject_frame(inlink, avf_in))
1178 return ret;
1179
1180
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (!mi_ctx->frames[0].avf)
1181 4 return 0;
1182
1183 4 mi_ctx->scene_changed = detect_scene_change(ctx);
1184
1185 13 for (;;) {
1186 AVFrame *avf_out;
1187
1188
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 13 times.
17 if (av_compare_ts(mi_ctx->out_pts, outlink->time_base, mi_ctx->frames[2].avf->pts, inlink->time_base) > 0)
1189 4 break;
1190
1191
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if (!(avf_out = ff_get_video_buffer(ctx->outputs[0], inlink->w, inlink->h)))
1192 return AVERROR(ENOMEM);
1193
1194 13 av_frame_copy_props(avf_out, mi_ctx->frames[NB_FRAMES - 1].avf);
1195 13 avf_out->pts = mi_ctx->out_pts++;
1196 13 avf_out->duration = 1;
1197
1198 13 interpolate(inlink, avf_out);
1199
1200
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if ((ret = ff_filter_frame(ctx->outputs[0], avf_out)) < 0)
1201 return ret;
1202 }
1203
1204 4 return 0;
1205 }
1206
1207 600 static av_cold void free_blocks(Block *block, int sb)
1208 {
1209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 600 times.
600 if (block->subs)
1210 free_blocks(block->subs, 1);
1211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 600 times.
600 if (sb)
1212 av_freep(&block);
1213 600 }
1214
1215 4 static av_cold void uninit(AVFilterContext *ctx)
1216 {
1217 4 MIContext *mi_ctx = ctx->priv;
1218 int i, m;
1219
1220 4 av_freep(&mi_ctx->pixel_mvs);
1221 4 av_freep(&mi_ctx->pixel_weights);
1222 4 av_freep(&mi_ctx->pixel_refs);
1223
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (mi_ctx->int_blocks)
1224
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 2 times.
602 for (m = 0; m < mi_ctx->b_count; m++)
1225 600 free_blocks(&mi_ctx->int_blocks[m], 0);
1226 4 av_freep(&mi_ctx->int_blocks);
1227
1228
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 for (i = 0; i < NB_FRAMES; i++) {
1229 16 Frame *frame = &mi_ctx->frames[i];
1230 16 av_freep(&frame->blocks);
1231 16 av_frame_free(&frame->avf);
1232 }
1233
1234
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
16 for (i = 0; i < 3; i++)
1235 12 av_freep(&mi_ctx->mv_table[i]);
1236 4 }
1237
1238 static const AVFilterPad minterpolate_inputs[] = {
1239 {
1240 .name = "default",
1241 .type = AVMEDIA_TYPE_VIDEO,
1242 .filter_frame = filter_frame,
1243 .config_props = config_input,
1244 },
1245 };
1246
1247 static const AVFilterPad minterpolate_outputs[] = {
1248 {
1249 .name = "default",
1250 .type = AVMEDIA_TYPE_VIDEO,
1251 .config_props = config_output,
1252 },
1253 };
1254
1255 const AVFilter ff_vf_minterpolate = {
1256 .name = "minterpolate",
1257 .description = NULL_IF_CONFIG_SMALL("Frame rate conversion using Motion Interpolation."),
1258 .priv_size = sizeof(MIContext),
1259 .priv_class = &minterpolate_class,
1260 .uninit = uninit,
1261 FILTER_INPUTS(minterpolate_inputs),
1262 FILTER_OUTPUTS(minterpolate_outputs),
1263 FILTER_PIXFMTS_ARRAY(pix_fmts),
1264 };
1265