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
36
37 #if CONFIG_AVCODEC
39 #endif
40
42 "TB", ///< timebase
43
44 "pts", ///< original pts in the file of the frame
45 "start_pts", ///< first PTS in the stream, expressed in TB units
46 "prev_pts", ///< previous frame PTS
47 "prev_selected_pts", ///< previous selected frame PTS
48
49 "t", ///< first PTS in seconds
50 "start_t", ///< first PTS in the stream, expressed in seconds
51 "prev_t", ///< previous frame time
52 "prev_selected_t", ///< previously selected time
53
54 "pict_type", ///< the type of picture in the movie
55 "I",
56 "P",
57 "B",
58 "S",
59 "SI",
60 "SP",
61 "BI",
62 "PICT_TYPE_I",
63 "PICT_TYPE_P",
64 "PICT_TYPE_B",
65 "PICT_TYPE_S",
66 "PICT_TYPE_SI",
67 "PICT_TYPE_SP",
68 "PICT_TYPE_BI",
69
70 "interlace_type", ///< the frame interlace type
71 "PROGRESSIVE",
72 "TOPFIRST",
73 "BOTTOMFIRST",
74
75 "consumed_samples_n",///< number of samples consumed by the filter (only audio)
76 "samples_n", ///< number of samples in the current frame (only audio)
77 "sample_rate", ///< sample rate (only audio)
78
79 "n", ///< frame number (starting from zero)
80 "selected_n", ///< selected frame number (starting from zero)
81 "prev_selected_n", ///< number of the last selected frame
82
83 "key", ///< tell if the frame is a key frame
84 "pos", ///< original position in the file of the frame
85
86 "scene",
87
88 NULL
89 };
90
93
98
103
119
124
128
132
135
137
139 };
140
146 int do_scene_detect;
///< 1 if the expression requires scene detection variables, 0 otherwise
147 #if CONFIG_AVCODEC
148 AVCodecContext *avctx;
///< codec context required for the DSPContext (scene detect only)
149 DSPContext c;
///< context providing optimized SAD methods (scene detect only)
150 double prev_mafd; ///< previous MAFD (scene detect only)
151 #endif
157
158 #define OFFSET(x) offsetof(SelectContext, x)
159 #define DEFINE_OPTIONS(filt_name, FLAGS) \
160 static const AVOption filt_name##_options[] = { \
161 { "expr", "set an expression to use for selecting frames", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "1" }, .flags=FLAGS }, \
162 { "e", "set an expression to use for selecting frames", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "1" }, .flags=FLAGS }, \
163 { "outputs", "set the number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags=FLAGS }, \
164 { "n", "set the number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags=FLAGS }, \
165 { NULL } \
166 }
167
169
171 {
174
176 var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
180 }
182
185
192 }
193
194 return 0;
195 }
196
197 #define INTERLACE_TYPE_P 0
198 #define INTERLACE_TYPE_T 1
199 #define INTERLACE_TYPE_B 2
200
202 {
204
207
209
216
229
233
239
242
243 #if CONFIG_AVCODEC
246 if (!select->avctx)
249 }
250 #endif
251 return 0;
252 }
253
254 #if CONFIG_AVCODEC
256 {
260
261 if (prev_picref &&
265 int x,
y, nb_sad = 0;
266 int64_t sad = 0;
270 const int linesize = frame->
linesize[0];
271
272 for (y = 0; y < frame->
height - 8; y += 8) {
273 for (x = 0; x < frame->
width*3 - 8; x += 8) {
274 sad += select->c.sad[1](select, p1 + x, p2 + x,
275 linesize, 8);
276 nb_sad += 8 * 8;
277 }
278 p1 += 8 * linesize;
279 p2 += 8 * linesize;
280 }
282 mafd = nb_sad ? sad / nb_sad : 0;
283 diff = fabs(mafd - select->prev_mafd);
284 ret = av_clipf(
FFMIN(mafd, diff) / 100., 0, 1);
285 select->prev_mafd = mafd;
287 }
290 }
291 #endif
292
293 #define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
294 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
295
297 {
301
306
311
312 switch (inlink->
type) {
315 break;
316
322 #if CONFIG_AVCODEC
326 // TODO: document metadata
329 }
330 #endif
331 break;
332 }
333
336 "n:%f pts:%f t:%f key:%d",
341
342 switch (inlink->
type) {
350 break;
355 break;
356 }
357
358 if (res == 0) {
360 }
else if (
isnan(res) || res < 0) {
362 } else {
364 }
365
367
368 if (res) {
375 }
376
379 }
380
382 {
385
389
391 return 0;
392 }
393
395 {
400
401 do {
403 if (ret < 0)
406
407 return 0;
408 }
409
411 {
413 int i;
414
417
420
421 #if CONFIG_AVCODEC
424 if (select->avctx) {
427 }
428 }
429 #endif
430 }
431
433 {
435
438 } else {
442 };
444 }
445 return 0;
446 }
447
448 #if CONFIG_ASELECT_FILTER
449
452
454 {
457
458 if ((ret =
init(ctx)) < 0)
460
464 }
465
466 return 0;
467 }
468
469 static const AVFilterPad avfilter_af_aselect_inputs[] = {
470 {
476 },
477 { NULL }
478 };
479
483 .init = aselect_init,
486 .
inputs = avfilter_af_aselect_inputs,
487 .priv_class = &aselect_class,
489 };
490 #endif /* CONFIG_ASELECT_FILTER */
491
492 #if CONFIG_SELECT_FILTER
493
496
498 {
501
502 if ((ret =
init(ctx)) < 0)
504
508 }
509
510 return 0;
511 }
512
513 static const AVFilterPad avfilter_vf_select_inputs[] = {
514 {
520 },
521 { NULL }
522 };
523
527 .init = select_init,
530
532 .priv_class = &select_class,
533
534 .
inputs = avfilter_vf_select_inputs,
536 };
537 #endif /* CONFIG_SELECT_FILTER */