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
85 "concatdec_select", ///< frame is within the interval set by the concat demuxer
86
88 };
89
92
97
102
118
123
127
131
134
136
138
140 };
141
147 int do_scene_detect;
///< 1 if the expression requires scene detection variables, 0 otherwise
149 double prev_mafd;
///< previous MAFD (scene detect only)
155
156 #define OFFSET(x) offsetof(SelectContext, x)
157 #define DEFINE_OPTIONS(filt_name, FLAGS) \
158 static const AVOption filt_name##_options[] = { \
159 { "expr", "set an expression to use for selecting frames", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "1" }, .flags=FLAGS }, \
160 { "e", "set an expression to use for selecting frames", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "1" }, .flags=FLAGS }, \
161 { "outputs", "set the number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags=FLAGS }, \
162 { "n", "set the number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags=FLAGS }, \
163 { NULL } \
164 }
165
167
169 {
171 int i, ret;
172
177 return ret;
178 }
180
183
191 return ret;
192 }
193 }
194
195 return 0;
196 }
197
198 #define INTERLACE_TYPE_P 0
199 #define INTERLACE_TYPE_T 1
200 #define INTERLACE_TYPE_B 2
201
203 {
205
208
210
217
230
234
240
243
248 }
249 return 0;
250 }
251
253 {
254 double ret = 0;
257
258 if (prev_picref &&
261 int x, y, nb_sad = 0;
262 int64_t sad = 0;
266 const int p1_linesize = frame->
linesize[0];
267 const int p2_linesize = prev_picref->
linesize[0];
268
269 for (y = 0; y < frame->
height - 7; y += 8) {
270 for (x = 0; x < frame->
width*3 - 7; x += 8) {
271 sad += select->
sad(p1 + x, p1_linesize, p2 + x, p2_linesize);
272 nb_sad += 8 * 8;
273 }
274 p1 += 8 * p1_linesize;
275 p2 += 8 * p2_linesize;
276 }
277 emms_c();
278 mafd = nb_sad ? (double)sad / nb_sad : 0;
280 ret = av_clipf(
FFMIN(mafd, diff) / 100., 0, 1);
283 }
285 return ret;
286 }
287
289 {
293 if (start_time_entry) {
295 if (pts >= start_time) {
296 if (duration_entry) {
298 if (pts < start_time + duration)
299 return -1;
300 else
301 return 0;
302 }
303 return -1;
304 }
305 return 0;
306 }
308 }
309
310 #define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
311 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
312
314 {
317 double res;
318
323
330
331 switch (inlink->
type) {
334 break;
335
344 // TODO: document metadata
347 }
348 break;
349 }
350
353 "n:%f pts:%f t:%f key:%d",
358
359 switch (inlink->
type) {
366 break;
371 break;
372 }
373
374 if (res == 0) {
376 }
else if (
isnan(res) || res < 0) {
378 } else {
380 }
381
383
384 if (res) {
391 }
392
395 }
396
398 {
401
405
407 return 0;
408 }
409
411 {
414 return ret;
415 }
416
418 {
420 int i;
421
424
427
430 }
431 }
432
434 {
436
439 } else {
440 int ret;
444 };
446
447 if (!fmts_list)
450 if (ret < 0)
451 return ret;
452 }
453 return 0;
454 }
455
456 #if CONFIG_ASELECT_FILTER
457
460
462 {
464 int ret;
465
466 if ((ret =
init(ctx)) < 0)
467 return ret;
468
472 }
473
474 return 0;
475 }
476
477 static const AVFilterPad avfilter_af_aselect_inputs[] = {
478 {
483 },
485 };
486
490 .init = aselect_init,
493 .
inputs = avfilter_af_aselect_inputs,
494 .priv_class = &aselect_class,
496 };
497 #endif /* CONFIG_ASELECT_FILTER */
498
499 #if CONFIG_SELECT_FILTER
500
503
505 {
506 int ret;
507
508 if ((ret =
init(ctx)) < 0)
509 return ret;
510
511 return 0;
512 }
513
514 static const AVFilterPad avfilter_vf_select_inputs[] = {
515 {
520 },
522 };
523
527 .init = select_init,
531 .priv_class = &select_class,
532 .
inputs = avfilter_vf_select_inputs,
534 };
535 #endif /* CONFIG_SELECT_FILTER */
This structure describes decoded (raw) audio or video data.
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
static av_cold void uninit(AVFilterContext *ctx)
Main libavfilter public API header.
packed RGB 8:8:8, 24bpp, RGBRGB...
#define AV_OPT_FLAG_AUDIO_PARAM
enum AVMediaType type
AVFilterPad type.
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
static double get_concatdec_select(AVFrame *frame, int64_t pts)
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
AVFilterPad * output_pads
array of output pads
static int64_t start_time
int(* request_frame)(AVFilterLink *link)
Frame request callback.
static void select_frame(AVFilterContext *ctx, AVFrame *frame)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
static double av_q2d(AVRational a)
Convert an AVRational to a double.
char av_get_picture_type_char(enum AVPictureType pict_type)
Return a single letter to describe the given picture type pict_type.
AVDictionary * metadata
metadata.
int interlaced_frame
The content of the picture is interlaced.
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
A filter pad used for either input or output.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
A link between two filters.
static int query_formats(AVFilterContext *ctx)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int sample_rate
samples per second
#define AV_OPT_FLAG_FILTERING_PARAM
a generic parameter which can be set by the user for filtering
double var_values[VAR_VARS_NB]
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
unsigned nb_outputs
number of output pads
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void * priv
private data for use by the filter
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
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])
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link...
int select_out
mark the selected output pad index
char * av_asprintf(const char *fmt,...)
static int config_input(AVFilterLink *inlink)
common internal API header
enum AVPictureType pict_type
Picture type of the frame.
av_pixelutils_sad_fn sad
Sum of the absolute difference function (scene detect only)
packed RGB 8:8:8, 24bpp, BGRBGR...
AVFilterContext * src
source filter
static const AVFilterPad inputs[]
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
const AVFilterPad * inputs
List of inputs, terminated by a zeroed element.
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
#define AV_OPT_FLAG_VIDEO_PARAM
static double get_scene_score(AVFilterContext *ctx, AVFrame *frame)
a very simple circular buffer FIFO implementation
double prev_mafd
previous MAFD (scene detect only)
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
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_...
Describe the class of an AVClass context structure.
const char * name
Filter name.
AVFilterLink ** outputs
array of pointers to output links
static enum AVPixelFormat pix_fmts[]
static int request_frame(AVFilterLink *outlink)
enum AVMediaType type
filter media type
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int do_scene_detect
1 if the expression requires scene detection variables, 0 otherwise
AVFrame * prev_picref
previous frame (scene detect only)
#define DEFINE_OPTIONS(filt_name, FLAGS)
static av_cold int init(AVFilterContext *ctx)
static av_always_inline int diff(const uint32_t a, const uint32_t b)
int top_field_first
If the content is interlaced, is top field displayed first.
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
AVFilterContext * dst
dest filter
#define AVFILTER_DEFINE_CLASS(fname)
int key_frame
1 -> keyframe, 0-> not
static const char *const var_names[]
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
static int ff_insert_outpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new output pad for the filter.
AVPixelFormat
Pixel format.
int nb_samples
number of audio samples (per channel) described by this frame
const AVFilter * filter
the AVFilter of which this is an instance
simple arithmetic expression evaluator