1 /*
2 * Copyright (c) 2011 Stefano Sabatini
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * filter for selecting which frame passes in the filterchain
24 */
25
37
39 "TB", ///< timebase
40
41 "pts", ///< original pts in the file of the frame
42 "start_pts", ///< first PTS in the stream, expressed in TB units
43 "prev_pts", ///< previous frame PTS
44 "prev_selected_pts", ///< previous selected frame PTS
45
46 "t", ///< timestamp expressed in seconds
47 "start_t", ///< first PTS in the stream, expressed in seconds
48 "prev_t", ///< previous frame time
49 "prev_selected_t", ///< previously selected time
50
51 "pict_type", ///< the type of picture in the movie
52 "I",
53 "P",
54 "B",
55 "S",
56 "SI",
57 "SP",
58 "BI",
59 "PICT_TYPE_I",
60 "PICT_TYPE_P",
61 "PICT_TYPE_B",
62 "PICT_TYPE_S",
63 "PICT_TYPE_SI",
64 "PICT_TYPE_SP",
65 "PICT_TYPE_BI",
66
67 "interlace_type", ///< the frame interlace type
68 "PROGRESSIVE",
69 "TOPFIRST",
70 "BOTTOMFIRST",
71
72 "consumed_samples_n",///< number of samples consumed by the filter (only audio)
73 "samples_n", ///< number of samples in the current frame (only audio)
74 "sample_rate", ///< sample rate (only audio)
75
76 "n", ///< frame number (starting from zero)
77 "selected_n", ///< selected frame number (starting from zero)
78 "prev_selected_n", ///< number of the last selected frame
79
80 "key", ///< tell if the frame is a key frame
81 "pos", ///< original position in the file of the frame
82
83 "scene",
84
86 };
87
90
95
100
116
121
125
129
132
134
136 };
137
143 int do_scene_detect;
///< 1 if the expression requires scene detection variables, 0 otherwise
145 double prev_mafd;
///< previous MAFD (scene detect only)
151
152 #define OFFSET(x) offsetof(SelectContext, x)
153 #define DEFINE_OPTIONS(filt_name, FLAGS) \
154 static const AVOption filt_name##_options[] = { \
155 { "expr", "set an expression to use for selecting frames", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "1" }, .flags=FLAGS }, \
156 { "e", "set an expression to use for selecting frames", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "1" }, .flags=FLAGS }, \
157 { "outputs", "set the number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags=FLAGS }, \
158 { "n", "set the number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags=FLAGS }, \
159 { NULL } \
160 }
161
163
165 {
168
174 }
176
179
186 }
187
188 return 0;
189 }
190
191 #define INTERLACE_TYPE_P 0
192 #define INTERLACE_TYPE_T 1
193 #define INTERLACE_TYPE_B 2
194
196 {
198
201
203
210
223
227
233
236
241 }
242 return 0;
243 }
244
246 {
250
251 if (prev_picref &&
254 int x,
y, nb_sad = 0;
255 int64_t sad = 0;
259 const int p1_linesize = frame->
linesize[0];
260 const int p2_linesize = prev_picref->
linesize[0];
261
262 for (y = 0; y < frame->
height - 7; y += 8) {
263 for (x = 0; x < frame->
width*3 - 7; x += 8) {
264 sad += select->
sad(p1 + x, p1_linesize, p2 + x, p2_linesize);
265 nb_sad += 8 * 8;
266 }
267 p1 += 8 * p1_linesize;
268 p2 += 8 * p2_linesize;
269 }
270 emms_c();
271 mafd = nb_sad ? (double)sad / nb_sad : 0;
273 ret = av_clipf(
FFMIN(mafd, diff) / 100., 0, 1);
276 }
279 }
280
281 #define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
282 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
283
285 {
288 double res;
289
294
300
301 switch (inlink->
type) {
304 break;
305
314 // TODO: document metadata
317 }
318 break;
319 }
320
323 "n:%f pts:%f t:%f key:%d",
328
329 switch (inlink->
type) {
336 break;
341 break;
342 }
343
344 if (res == 0) {
346 }
else if (
isnan(res) || res < 0) {
348 } else {
350 }
351
353
354 if (res) {
361 }
362
365 }
366
368 {
371
375
377 return 0;
378 }
379
381 {
386
387 do {
389 if (ret < 0)
392
393 return 0;
394 }
395
397 {
399 int i;
400
403
406
409 }
410 }
411
413 {
415
418 } else {
422 };
424 }
425 return 0;
426 }
427
428 #if CONFIG_ASELECT_FILTER
429
432
434 {
437
438 if ((ret =
init(ctx)) < 0)
440
444 }
445
446 return 0;
447 }
448
449 static const AVFilterPad avfilter_af_aselect_inputs[] = {
450 {
455 },
457 };
458
462 .init = aselect_init,
465 .
inputs = avfilter_af_aselect_inputs,
466 .priv_class = &aselect_class,
468 };
469 #endif /* CONFIG_ASELECT_FILTER */
470
471 #if CONFIG_SELECT_FILTER
472
475
477 {
479
480 if ((ret =
init(ctx)) < 0)
482
483 return 0;
484 }
485
486 static const AVFilterPad avfilter_vf_select_inputs[] = {
487 {
492 },
494 };
495
499 .init = select_init,
503 .priv_class = &select_class,
504 .
inputs = avfilter_vf_select_inputs,
506 };
507 #endif /* CONFIG_SELECT_FILTER */