Browse code

lavfi: mv vf_select.c -> f_select.c

The file now contains also an audio select implementation. Also move the
aselect/select documentation from video filters to the multimedia filters
section.

Stefano Sabatini authored on 2012/12/12 07:26:01
Showing 4 changed files
... ...
@@ -3506,140 +3506,6 @@ scale='min(500\, iw*3/2):-1'
3506 3506
 @end example
3507 3507
 @end itemize
3508 3508
 
3509
-@section aselect, select
3510
-Select frames to pass in output.
3511
-
3512
-It accepts in input an expression, which is evaluated for each input
3513
-frame. If the expression is evaluated to a non-zero value, the frame
3514
-is selected and passed to the output, otherwise it is discarded.
3515
-
3516
-The expression can contain the following constants:
3517
-
3518
-@table @option
3519
-@item n
3520
-the sequential number of the filtered frame, starting from 0
3521
-
3522
-@item selected_n
3523
-the sequential number of the selected frame, starting from 0
3524
-
3525
-@item prev_selected_n
3526
-the sequential number of the last selected frame, NAN if undefined
3527
-
3528
-@item TB
3529
-timebase of the input timestamps
3530
-
3531
-@item pts
3532
-the PTS (Presentation TimeStamp) of the filtered video frame,
3533
-expressed in @var{TB} units, NAN if undefined
3534
-
3535
-@item t
3536
-the PTS (Presentation TimeStamp) of the filtered video frame,
3537
-expressed in seconds, NAN if undefined
3538
-
3539
-@item prev_pts
3540
-the PTS of the previously filtered video frame, NAN if undefined
3541
-
3542
-@item prev_selected_pts
3543
-the PTS of the last previously filtered video frame, NAN if undefined
3544
-
3545
-@item prev_selected_t
3546
-the PTS of the last previously selected video frame, NAN if undefined
3547
-
3548
-@item start_pts
3549
-the PTS of the first video frame in the video, NAN if undefined
3550
-
3551
-@item start_t
3552
-the time of the first video frame in the video, NAN if undefined
3553
-
3554
-@item pict_type @emph{(video only)}
3555
-the type of the filtered frame, can assume one of the following
3556
-values:
3557
-@table @option
3558
-@item I
3559
-@item P
3560
-@item B
3561
-@item S
3562
-@item SI
3563
-@item SP
3564
-@item BI
3565
-@end table
3566
-
3567
-@item interlace_type @emph{(video only)}
3568
-the frame interlace type, can assume one of the following values:
3569
-@table @option
3570
-@item PROGRESSIVE
3571
-the frame is progressive (not interlaced)
3572
-@item TOPFIRST
3573
-the frame is top-field-first
3574
-@item BOTTOMFIRST
3575
-the frame is bottom-field-first
3576
-@end table
3577
-
3578
-@item consumed_sample_n @emph{(audio only)}
3579
-the number of selected samples before the current frame
3580
-
3581
-@item samples_n @emph{(audio only)}
3582
-the number of samples in the current frame
3583
-
3584
-@item sample_rate @emph{(audio only)}
3585
-the input sample rate
3586
-
3587
-@item key
3588
-1 if the filtered frame is a key-frame, 0 otherwise
3589
-
3590
-@item pos
3591
-the position in the file of the filtered frame, -1 if the information
3592
-is not available (e.g. for synthetic video)
3593
-
3594
-@item scene @emph{(video only)}
3595
-value between 0 and 1 to indicate a new scene; a low value reflects a low
3596
-probability for the current frame to introduce a new scene, while a higher
3597
-value means the current frame is more likely to be one (see the example below)
3598
-
3599
-@end table
3600
-
3601
-The default value of the select expression is "1".
3602
-
3603
-Some examples follow:
3604
-
3605
-@example
3606
-# select all frames in input
3607
-select
3608
-
3609
-# the above is the same as:
3610
-select=1
3611
-
3612
-# skip all frames:
3613
-select=0
3614
-
3615
-# select only I-frames
3616
-select='eq(pict_type\,I)'
3617
-
3618
-# select one frame every 100
3619
-select='not(mod(n\,100))'
3620
-
3621
-# select only frames contained in the 10-20 time interval
3622
-select='gte(t\,10)*lte(t\,20)'
3623
-
3624
-# select only I frames contained in the 10-20 time interval
3625
-select='gte(t\,10)*lte(t\,20)*eq(pict_type\,I)'
3626
-
3627
-# select frames with a minimum distance of 10 seconds
3628
-select='isnan(prev_selected_t)+gte(t-prev_selected_t\,10)'
3629
-
3630
-# use aselect to select only audio frames with samples number > 100
3631
-aselect='gt(samples_n\,100)'
3632
-@end example
3633
-
3634
-Complete example to create a mosaic of the first scenes:
3635
-
3636
-@example
3637
-ffmpeg -i video.avi -vf select='gt(scene\,0.4)',scale=160:120,tile -frames:v 1 preview.png
3638
-@end example
3639
-
3640
-Comparing @var{scene} against a value between 0.3 and 0.5 is generally a sane
3641
-choice.
3642
-
3643 3509
 @section setdar, setsar
3644 3510
 
3645 3511
 The @code{setdar} filter sets the Display Aspect Ratio for the filter
... ...
@@ -4768,6 +4634,140 @@ tools.
4768 4768
 
4769 4769
 Below is a description of the currently available multimedia filters.
4770 4770
 
4771
+@section aselect, select
4772
+Select frames to pass in output.
4773
+
4774
+It accepts in input an expression, which is evaluated for each input
4775
+frame. If the expression is evaluated to a non-zero value, the frame
4776
+is selected and passed to the output, otherwise it is discarded.
4777
+
4778
+The expression can contain the following constants:
4779
+
4780
+@table @option
4781
+@item n
4782
+the sequential number of the filtered frame, starting from 0
4783
+
4784
+@item selected_n
4785
+the sequential number of the selected frame, starting from 0
4786
+
4787
+@item prev_selected_n
4788
+the sequential number of the last selected frame, NAN if undefined
4789
+
4790
+@item TB
4791
+timebase of the input timestamps
4792
+
4793
+@item pts
4794
+the PTS (Presentation TimeStamp) of the filtered video frame,
4795
+expressed in @var{TB} units, NAN if undefined
4796
+
4797
+@item t
4798
+the PTS (Presentation TimeStamp) of the filtered video frame,
4799
+expressed in seconds, NAN if undefined
4800
+
4801
+@item prev_pts
4802
+the PTS of the previously filtered video frame, NAN if undefined
4803
+
4804
+@item prev_selected_pts
4805
+the PTS of the last previously filtered video frame, NAN if undefined
4806
+
4807
+@item prev_selected_t
4808
+the PTS of the last previously selected video frame, NAN if undefined
4809
+
4810
+@item start_pts
4811
+the PTS of the first video frame in the video, NAN if undefined
4812
+
4813
+@item start_t
4814
+the time of the first video frame in the video, NAN if undefined
4815
+
4816
+@item pict_type @emph{(video only)}
4817
+the type of the filtered frame, can assume one of the following
4818
+values:
4819
+@table @option
4820
+@item I
4821
+@item P
4822
+@item B
4823
+@item S
4824
+@item SI
4825
+@item SP
4826
+@item BI
4827
+@end table
4828
+
4829
+@item interlace_type @emph{(video only)}
4830
+the frame interlace type, can assume one of the following values:
4831
+@table @option
4832
+@item PROGRESSIVE
4833
+the frame is progressive (not interlaced)
4834
+@item TOPFIRST
4835
+the frame is top-field-first
4836
+@item BOTTOMFIRST
4837
+the frame is bottom-field-first
4838
+@end table
4839
+
4840
+@item consumed_sample_n @emph{(audio only)}
4841
+the number of selected samples before the current frame
4842
+
4843
+@item samples_n @emph{(audio only)}
4844
+the number of samples in the current frame
4845
+
4846
+@item sample_rate @emph{(audio only)}
4847
+the input sample rate
4848
+
4849
+@item key
4850
+1 if the filtered frame is a key-frame, 0 otherwise
4851
+
4852
+@item pos
4853
+the position in the file of the filtered frame, -1 if the information
4854
+is not available (e.g. for synthetic video)
4855
+
4856
+@item scene @emph{(video only)}
4857
+value between 0 and 1 to indicate a new scene; a low value reflects a low
4858
+probability for the current frame to introduce a new scene, while a higher
4859
+value means the current frame is more likely to be one (see the example below)
4860
+
4861
+@end table
4862
+
4863
+The default value of the select expression is "1".
4864
+
4865
+Some examples follow:
4866
+
4867
+@example
4868
+# select all frames in input
4869
+select
4870
+
4871
+# the above is the same as:
4872
+select=1
4873
+
4874
+# skip all frames:
4875
+select=0
4876
+
4877
+# select only I-frames
4878
+select='eq(pict_type\,I)'
4879
+
4880
+# select one frame every 100
4881
+select='not(mod(n\,100))'
4882
+
4883
+# select only frames contained in the 10-20 time interval
4884
+select='gte(t\,10)*lte(t\,20)'
4885
+
4886
+# select only I frames contained in the 10-20 time interval
4887
+select='gte(t\,10)*lte(t\,20)*eq(pict_type\,I)'
4888
+
4889
+# select frames with a minimum distance of 10 seconds
4890
+select='isnan(prev_selected_t)+gte(t-prev_selected_t\,10)'
4891
+
4892
+# use aselect to select only audio frames with samples number > 100
4893
+aselect='gt(samples_n\,100)'
4894
+@end example
4895
+
4896
+Complete example to create a mosaic of the first scenes:
4897
+
4898
+@example
4899
+ffmpeg -i video.avi -vf select='gt(scene\,0.4)',scale=160:120,tile -frames:v 1 preview.png
4900
+@end example
4901
+
4902
+Comparing @var{scene} against a value between 0.3 and 0.5 is generally a sane
4903
+choice.
4904
+
4771 4905
 @section asendcmd, sendcmd
4772 4906
 
4773 4907
 Send commands to filters in the filtergraph.
... ...
@@ -54,7 +54,7 @@ OBJS-$(CONFIG_AMERGE_FILTER)                 += af_amerge.o
54 54
 OBJS-$(CONFIG_AMIX_FILTER)                   += af_amix.o
55 55
 OBJS-$(CONFIG_ANULL_FILTER)                  += af_anull.o
56 56
 OBJS-$(CONFIG_ARESAMPLE_FILTER)              += af_aresample.o
57
-OBJS-$(CONFIG_ASELECT_FILTER)                += vf_select.o
57
+OBJS-$(CONFIG_ASELECT_FILTER)                += f_select.o
58 58
 OBJS-$(CONFIG_ASENDCMD_FILTER)               += f_sendcmd.o
59 59
 OBJS-$(CONFIG_ASETNSAMPLES_FILTER)           += af_asetnsamples.o
60 60
 OBJS-$(CONFIG_ASETPTS_FILTER)                += f_setpts.o
... ...
@@ -125,7 +125,7 @@ OBJS-$(CONFIG_PAD_FILTER)                    += vf_pad.o
125 125
 OBJS-$(CONFIG_PIXDESCTEST_FILTER)            += vf_pixdesctest.o
126 126
 OBJS-$(CONFIG_REMOVELOGO_FILTER)             += bbox.o lswsutils.o lavfutils.o vf_removelogo.o
127 127
 OBJS-$(CONFIG_SCALE_FILTER)                  += vf_scale.o
128
-OBJS-$(CONFIG_SELECT_FILTER)                 += vf_select.o
128
+OBJS-$(CONFIG_SELECT_FILTER)                 += f_select.o
129 129
 OBJS-$(CONFIG_SENDCMD_FILTER)                += f_sendcmd.o
130 130
 OBJS-$(CONFIG_SETDAR_FILTER)                 += vf_aspect.o
131 131
 OBJS-$(CONFIG_SETFIELD_FILTER)               += vf_setfield.o
132 132
new file mode 100644
... ...
@@ -0,0 +1,441 @@
0
+/*
1
+ * Copyright (c) 2011 Stefano Sabatini
2
+ *
3
+ * This file is part of FFmpeg.
4
+ *
5
+ * FFmpeg is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * FFmpeg is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with FFmpeg; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+/**
21
+ * @file
22
+ * filter for selecting which frame passes in the filterchain
23
+ */
24
+
25
+#include "libavutil/eval.h"
26
+#include "libavutil/fifo.h"
27
+#include "libavutil/internal.h"
28
+#include "avfilter.h"
29
+#include "audio.h"
30
+#include "formats.h"
31
+#include "internal.h"
32
+#include "video.h"
33
+
34
+#if CONFIG_AVCODEC
35
+#include "libavcodec/dsputil.h"
36
+#endif
37
+
38
+static const char *const var_names[] = {
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",                 ///< first PTS 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
+
60
+    "interlace_type",    ///< the frame interlace type
61
+    "PROGRESSIVE",
62
+    "TOPFIRST",
63
+    "BOTTOMFIRST",
64
+
65
+    "consumed_samples_n",///< number of samples consumed by the filter (only audio)
66
+    "samples_n",         ///< number of samples in the current frame (only audio)
67
+    "sample_rate",       ///< sample rate (only audio)
68
+
69
+    "n",                 ///< frame number (starting from zero)
70
+    "selected_n",        ///< selected frame number (starting from zero)
71
+    "prev_selected_n",   ///< number of the last selected frame
72
+
73
+    "key",               ///< tell if the frame is a key frame
74
+    "pos",               ///< original position in the file of the frame
75
+
76
+    "scene",
77
+
78
+    NULL
79
+};
80
+
81
+enum var_name {
82
+    VAR_TB,
83
+
84
+    VAR_PTS,
85
+    VAR_START_PTS,
86
+    VAR_PREV_PTS,
87
+    VAR_PREV_SELECTED_PTS,
88
+
89
+    VAR_T,
90
+    VAR_START_T,
91
+    VAR_PREV_T,
92
+    VAR_PREV_SELECTED_T,
93
+
94
+    VAR_PICT_TYPE,
95
+    VAR_PICT_TYPE_I,
96
+    VAR_PICT_TYPE_P,
97
+    VAR_PICT_TYPE_B,
98
+    VAR_PICT_TYPE_S,
99
+    VAR_PICT_TYPE_SI,
100
+    VAR_PICT_TYPE_SP,
101
+    VAR_PICT_TYPE_BI,
102
+
103
+    VAR_INTERLACE_TYPE,
104
+    VAR_INTERLACE_TYPE_P,
105
+    VAR_INTERLACE_TYPE_T,
106
+    VAR_INTERLACE_TYPE_B,
107
+
108
+    VAR_CONSUMED_SAMPLES_N,
109
+    VAR_SAMPLES_N,
110
+    VAR_SAMPLE_RATE,
111
+
112
+    VAR_N,
113
+    VAR_SELECTED_N,
114
+    VAR_PREV_SELECTED_N,
115
+
116
+    VAR_KEY,
117
+    VAR_POS,
118
+
119
+    VAR_SCENE,
120
+
121
+    VAR_VARS_NB
122
+};
123
+
124
+typedef struct {
125
+    AVExpr *expr;
126
+    double var_values[VAR_VARS_NB];
127
+    int do_scene_detect;            ///< 1 if the expression requires scene detection variables, 0 otherwise
128
+#if CONFIG_AVCODEC
129
+    AVCodecContext *avctx;          ///< codec context required for the DSPContext (scene detect only)
130
+    DSPContext c;                   ///< context providing optimized SAD methods   (scene detect only)
131
+    double prev_mafd;               ///< previous MAFD                             (scene detect only)
132
+#endif
133
+    AVFilterBufferRef *prev_picref; ///< previous frame                            (scene detect only)
134
+    double select;
135
+} SelectContext;
136
+
137
+static av_cold int init(AVFilterContext *ctx, const char *args)
138
+{
139
+    SelectContext *select = ctx->priv;
140
+    int ret;
141
+
142
+    if ((ret = av_expr_parse(&select->expr, args ? args : "1",
143
+                             var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
144
+        av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args);
145
+        return ret;
146
+    }
147
+
148
+    select->do_scene_detect = args && strstr(args, "scene");
149
+    if (select->do_scene_detect && !CONFIG_AVCODEC) {
150
+        av_log(ctx, AV_LOG_ERROR, "Scene detection is not available without libavcodec.\n");
151
+        return AVERROR(EINVAL);
152
+    }
153
+    return 0;
154
+}
155
+
156
+#define INTERLACE_TYPE_P 0
157
+#define INTERLACE_TYPE_T 1
158
+#define INTERLACE_TYPE_B 2
159
+
160
+static int config_input(AVFilterLink *inlink)
161
+{
162
+    SelectContext *select = inlink->dst->priv;
163
+
164
+    select->var_values[VAR_N]          = 0.0;
165
+    select->var_values[VAR_SELECTED_N] = 0.0;
166
+
167
+    select->var_values[VAR_TB] = av_q2d(inlink->time_base);
168
+
169
+    select->var_values[VAR_PREV_PTS]          = NAN;
170
+    select->var_values[VAR_PREV_SELECTED_PTS] = NAN;
171
+    select->var_values[VAR_PREV_SELECTED_T]   = NAN;
172
+    select->var_values[VAR_START_PTS]         = NAN;
173
+    select->var_values[VAR_START_T]           = NAN;
174
+
175
+    select->var_values[VAR_PICT_TYPE_I]  = AV_PICTURE_TYPE_I;
176
+    select->var_values[VAR_PICT_TYPE_P]  = AV_PICTURE_TYPE_P;
177
+    select->var_values[VAR_PICT_TYPE_B]  = AV_PICTURE_TYPE_B;
178
+    select->var_values[VAR_PICT_TYPE_SI] = AV_PICTURE_TYPE_SI;
179
+    select->var_values[VAR_PICT_TYPE_SP] = AV_PICTURE_TYPE_SP;
180
+
181
+    select->var_values[VAR_INTERLACE_TYPE_P] = INTERLACE_TYPE_P;
182
+    select->var_values[VAR_INTERLACE_TYPE_T] = INTERLACE_TYPE_T;
183
+    select->var_values[VAR_INTERLACE_TYPE_B] = INTERLACE_TYPE_B;
184
+
185
+    select->var_values[VAR_SAMPLE_RATE] =
186
+        inlink->type == AVMEDIA_TYPE_AUDIO ? inlink->sample_rate : NAN;
187
+
188
+    if (CONFIG_AVCODEC && select->do_scene_detect) {
189
+        select->avctx = avcodec_alloc_context3(NULL);
190
+        if (!select->avctx)
191
+            return AVERROR(ENOMEM);
192
+        dsputil_init(&select->c, select->avctx);
193
+    }
194
+    return 0;
195
+}
196
+
197
+#if CONFIG_AVCODEC
198
+static double get_scene_score(AVFilterContext *ctx, AVFilterBufferRef *picref)
199
+{
200
+    double ret = 0;
201
+    SelectContext *select = ctx->priv;
202
+    AVFilterBufferRef *prev_picref = select->prev_picref;
203
+
204
+    if (prev_picref &&
205
+        picref->video->h    == prev_picref->video->h &&
206
+        picref->video->w    == prev_picref->video->w &&
207
+        picref->linesize[0] == prev_picref->linesize[0]) {
208
+        int x, y, nb_sad = 0;
209
+        int64_t sad = 0;
210
+        double mafd, diff;
211
+        uint8_t *p1 =      picref->data[0];
212
+        uint8_t *p2 = prev_picref->data[0];
213
+        const int linesize = picref->linesize[0];
214
+
215
+        for (y = 0; y < picref->video->h - 8; y += 8) {
216
+            for (x = 0; x < picref->video->w*3 - 8; x += 8) {
217
+                sad += select->c.sad[1](select, p1 + x, p2 + x,
218
+                                        linesize, 8);
219
+                nb_sad += 8 * 8;
220
+            }
221
+            p1 += 8 * linesize;
222
+            p2 += 8 * linesize;
223
+        }
224
+        emms_c();
225
+        mafd = nb_sad ? sad / nb_sad : 0;
226
+        diff = fabs(mafd - select->prev_mafd);
227
+        ret  = av_clipf(FFMIN(mafd, diff) / 100., 0, 1);
228
+        select->prev_mafd = mafd;
229
+        avfilter_unref_buffer(prev_picref);
230
+    }
231
+    select->prev_picref = avfilter_ref_buffer(picref, ~0);
232
+    return ret;
233
+}
234
+#endif
235
+
236
+#define D2TS(d)  (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
237
+#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
238
+
239
+static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref)
240
+{
241
+    SelectContext *select = ctx->priv;
242
+    AVFilterLink *inlink = ctx->inputs[0];
243
+    double res;
244
+
245
+    if (isnan(select->var_values[VAR_START_PTS]))
246
+        select->var_values[VAR_START_PTS] = TS2D(picref->pts);
247
+    if (isnan(select->var_values[VAR_START_T]))
248
+        select->var_values[VAR_START_T] = TS2D(picref->pts) * av_q2d(inlink->time_base);
249
+
250
+    select->var_values[VAR_PTS] = TS2D(picref->pts);
251
+    select->var_values[VAR_T  ] = TS2D(picref->pts) * av_q2d(inlink->time_base);
252
+    select->var_values[VAR_POS] = picref->pos == -1 ? NAN : picref->pos;
253
+    select->var_values[VAR_PREV_PTS] = TS2D(picref ->pts);
254
+
255
+    switch (inlink->type) {
256
+    case AVMEDIA_TYPE_AUDIO:
257
+        select->var_values[VAR_SAMPLES_N] = picref->audio->nb_samples;
258
+        break;
259
+
260
+    case AVMEDIA_TYPE_VIDEO:
261
+        select->var_values[VAR_INTERLACE_TYPE] =
262
+            !picref->video->interlaced     ? INTERLACE_TYPE_P :
263
+        picref->video->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B;
264
+        select->var_values[VAR_PICT_TYPE] = picref->video->pict_type;
265
+        if (CONFIG_AVCODEC && select->do_scene_detect) {
266
+            char buf[32];
267
+            select->var_values[VAR_SCENE] = get_scene_score(ctx, picref);
268
+            // TODO: document metadata
269
+            snprintf(buf, sizeof(buf), "%f", select->var_values[VAR_SCENE]);
270
+            av_dict_set(&picref->metadata, "lavfi.scene_score", buf, 0);
271
+        }
272
+        break;
273
+    }
274
+
275
+    res = av_expr_eval(select->expr, select->var_values, NULL);
276
+    av_log(inlink->dst, AV_LOG_DEBUG,
277
+           "n:%d pts:%d t:%f pos:%d key:%d",
278
+           (int)select->var_values[VAR_N],
279
+           (int)select->var_values[VAR_PTS],
280
+           select->var_values[VAR_T],
281
+           (int)select->var_values[VAR_POS],
282
+           (int)select->var_values[VAR_KEY]);
283
+
284
+    switch (inlink->type) {
285
+    case AVMEDIA_TYPE_VIDEO:
286
+        av_log(inlink->dst, AV_LOG_DEBUG, " interlace_type:%c pict_type:%c",
287
+               select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_P ? 'P' :
288
+               select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_T ? 'T' :
289
+               select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_B ? 'B' : '?',
290
+               av_get_picture_type_char(select->var_values[VAR_PICT_TYPE]));
291
+        break;
292
+    case AVMEDIA_TYPE_AUDIO:
293
+        av_log(inlink->dst, AV_LOG_DEBUG, " samples_n:%d consumed_samples_n:%d",
294
+               (int)select->var_values[VAR_SAMPLES_N],
295
+               (int)select->var_values[VAR_CONSUMED_SAMPLES_N]);
296
+        break;
297
+    }
298
+
299
+    av_log(inlink->dst, AV_LOG_DEBUG, " -> select:%f\n", res);
300
+
301
+    if (res) {
302
+        select->var_values[VAR_PREV_SELECTED_N]   = select->var_values[VAR_N];
303
+        select->var_values[VAR_PREV_SELECTED_PTS] = select->var_values[VAR_PTS];
304
+        select->var_values[VAR_PREV_SELECTED_T]   = select->var_values[VAR_T];
305
+        select->var_values[VAR_SELECTED_N] += 1.0;
306
+        if (inlink->type == AVMEDIA_TYPE_AUDIO)
307
+            select->var_values[VAR_CONSUMED_SAMPLES_N] += picref->audio->nb_samples;
308
+    }
309
+
310
+    select->var_values[VAR_N] += 1.0;
311
+
312
+    return res;
313
+}
314
+
315
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
316
+{
317
+    SelectContext *select = inlink->dst->priv;
318
+
319
+    select->select = select_frame(inlink->dst, frame);
320
+    if (select->select)
321
+        return ff_filter_frame(inlink->dst->outputs[0], frame);
322
+
323
+    avfilter_unref_bufferp(&frame);
324
+    return 0;
325
+}
326
+
327
+static int request_frame(AVFilterLink *outlink)
328
+{
329
+    AVFilterContext *ctx = outlink->src;
330
+    SelectContext *select = ctx->priv;
331
+    AVFilterLink *inlink = outlink->src->inputs[0];
332
+    select->select = 0;
333
+
334
+    do {
335
+        int ret = ff_request_frame(inlink);
336
+        if (ret < 0)
337
+            return ret;
338
+    } while (!select->select);
339
+
340
+    return 0;
341
+}
342
+
343
+static av_cold void uninit(AVFilterContext *ctx)
344
+{
345
+    SelectContext *select = ctx->priv;
346
+
347
+    av_expr_free(select->expr);
348
+    select->expr = NULL;
349
+
350
+    if (select->do_scene_detect) {
351
+        avfilter_unref_bufferp(&select->prev_picref);
352
+        if (select->avctx) {
353
+            avcodec_close(select->avctx);
354
+            av_freep(&select->avctx);
355
+        }
356
+    }
357
+}
358
+
359
+static int query_formats(AVFilterContext *ctx)
360
+{
361
+    SelectContext *select = ctx->priv;
362
+
363
+    if (!select->do_scene_detect) {
364
+        return ff_default_query_formats(ctx);
365
+    } else {
366
+        static const enum AVPixelFormat pix_fmts[] = {
367
+            AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
368
+            AV_PIX_FMT_NONE
369
+        };
370
+        ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
371
+    }
372
+    return 0;
373
+}
374
+
375
+#if CONFIG_ASELECT_FILTER
376
+static const AVFilterPad avfilter_af_aselect_inputs[] = {
377
+    {
378
+        .name             = "default",
379
+        .type             = AVMEDIA_TYPE_AUDIO,
380
+        .get_audio_buffer = ff_null_get_audio_buffer,
381
+        .config_props     = config_input,
382
+        .filter_frame     = filter_frame,
383
+    },
384
+    { NULL }
385
+};
386
+
387
+static const AVFilterPad avfilter_af_aselect_outputs[] = {
388
+    {
389
+        .name = "default",
390
+        .type = AVMEDIA_TYPE_AUDIO,
391
+    },
392
+    { NULL }
393
+};
394
+
395
+AVFilter avfilter_af_aselect = {
396
+    .name      = "aselect",
397
+    .description = NULL_IF_CONFIG_SMALL("Select audio frames to pass in output."),
398
+    .init      = init,
399
+    .uninit    = uninit,
400
+    .priv_size = sizeof(SelectContext),
401
+    .inputs    = avfilter_af_aselect_inputs,
402
+    .outputs   = avfilter_af_aselect_outputs,
403
+};
404
+#endif /* CONFIG_ASELECT_FILTER */
405
+
406
+#if CONFIG_SELECT_FILTER
407
+static const AVFilterPad avfilter_vf_select_inputs[] = {
408
+    {
409
+        .name             = "default",
410
+        .type             = AVMEDIA_TYPE_VIDEO,
411
+        .get_video_buffer = ff_null_get_video_buffer,
412
+        .min_perms        = AV_PERM_PRESERVE,
413
+        .config_props     = config_input,
414
+        .filter_frame     = filter_frame,
415
+    },
416
+    { NULL }
417
+};
418
+
419
+static const AVFilterPad avfilter_vf_select_outputs[] = {
420
+    {
421
+        .name          = "default",
422
+        .type          = AVMEDIA_TYPE_VIDEO,
423
+        .request_frame = request_frame,
424
+    },
425
+    { NULL }
426
+};
427
+
428
+AVFilter avfilter_vf_select = {
429
+    .name      = "select",
430
+    .description = NULL_IF_CONFIG_SMALL("Select video frames to pass in output."),
431
+    .init      = init,
432
+    .uninit    = uninit,
433
+    .query_formats = query_formats,
434
+
435
+    .priv_size = sizeof(SelectContext),
436
+
437
+    .inputs    = avfilter_vf_select_inputs,
438
+    .outputs   = avfilter_vf_select_outputs,
439
+};
440
+#endif /* CONFIG_SELECT_FILTER */
0 441
deleted file mode 100644
... ...
@@ -1,441 +0,0 @@
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
-
26
-#include "libavutil/eval.h"
27
-#include "libavutil/fifo.h"
28
-#include "libavutil/internal.h"
29
-#include "avfilter.h"
30
-#include "audio.h"
31
-#include "formats.h"
32
-#include "internal.h"
33
-#include "video.h"
34
-
35
-#if CONFIG_AVCODEC
36
-#include "libavcodec/dsputil.h"
37
-#endif
38
-
39
-static const char *const var_names[] = {
40
-    "TB",                ///< timebase
41
-
42
-    "pts",               ///< original pts in the file of the frame
43
-    "start_pts",         ///< first PTS in the stream, expressed in TB units
44
-    "prev_pts",          ///< previous frame PTS
45
-    "prev_selected_pts", ///< previous selected frame PTS
46
-
47
-    "t",                 ///< first PTS in seconds
48
-    "start_t",           ///< first PTS in the stream, expressed in seconds
49
-    "prev_t",            ///< previous frame time
50
-    "prev_selected_t",   ///< previously selected time
51
-
52
-    "pict_type",         ///< the type of picture in the movie
53
-    "I",
54
-    "P",
55
-    "B",
56
-    "S",
57
-    "SI",
58
-    "SP",
59
-    "BI",
60
-
61
-    "interlace_type",    ///< the frame interlace type
62
-    "PROGRESSIVE",
63
-    "TOPFIRST",
64
-    "BOTTOMFIRST",
65
-
66
-    "consumed_samples_n",///< number of samples consumed by the filter (only audio)
67
-    "samples_n",         ///< number of samples in the current frame (only audio)
68
-    "sample_rate",       ///< sample rate (only audio)
69
-
70
-    "n",                 ///< frame number (starting from zero)
71
-    "selected_n",        ///< selected frame number (starting from zero)
72
-    "prev_selected_n",   ///< number of the last selected frame
73
-
74
-    "key",               ///< tell if the frame is a key frame
75
-    "pos",               ///< original position in the file of the frame
76
-
77
-    "scene",
78
-
79
-    NULL
80
-};
81
-
82
-enum var_name {
83
-    VAR_TB,
84
-
85
-    VAR_PTS,
86
-    VAR_START_PTS,
87
-    VAR_PREV_PTS,
88
-    VAR_PREV_SELECTED_PTS,
89
-
90
-    VAR_T,
91
-    VAR_START_T,
92
-    VAR_PREV_T,
93
-    VAR_PREV_SELECTED_T,
94
-
95
-    VAR_PICT_TYPE,
96
-    VAR_PICT_TYPE_I,
97
-    VAR_PICT_TYPE_P,
98
-    VAR_PICT_TYPE_B,
99
-    VAR_PICT_TYPE_S,
100
-    VAR_PICT_TYPE_SI,
101
-    VAR_PICT_TYPE_SP,
102
-    VAR_PICT_TYPE_BI,
103
-
104
-    VAR_INTERLACE_TYPE,
105
-    VAR_INTERLACE_TYPE_P,
106
-    VAR_INTERLACE_TYPE_T,
107
-    VAR_INTERLACE_TYPE_B,
108
-
109
-    VAR_CONSUMED_SAMPLES_N,
110
-    VAR_SAMPLES_N,
111
-    VAR_SAMPLE_RATE,
112
-
113
-    VAR_N,
114
-    VAR_SELECTED_N,
115
-    VAR_PREV_SELECTED_N,
116
-
117
-    VAR_KEY,
118
-    VAR_POS,
119
-
120
-    VAR_SCENE,
121
-
122
-    VAR_VARS_NB
123
-};
124
-
125
-typedef struct {
126
-    AVExpr *expr;
127
-    double var_values[VAR_VARS_NB];
128
-    int do_scene_detect;            ///< 1 if the expression requires scene detection variables, 0 otherwise
129
-#if CONFIG_AVCODEC
130
-    AVCodecContext *avctx;          ///< codec context required for the DSPContext (scene detect only)
131
-    DSPContext c;                   ///< context providing optimized SAD methods   (scene detect only)
132
-    double prev_mafd;               ///< previous MAFD                             (scene detect only)
133
-#endif
134
-    AVFilterBufferRef *prev_picref; ///< previous frame                            (scene detect only)
135
-    double select;
136
-} SelectContext;
137
-
138
-static av_cold int init(AVFilterContext *ctx, const char *args)
139
-{
140
-    SelectContext *select = ctx->priv;
141
-    int ret;
142
-
143
-    if ((ret = av_expr_parse(&select->expr, args ? args : "1",
144
-                             var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
145
-        av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args);
146
-        return ret;
147
-    }
148
-
149
-    select->do_scene_detect = args && strstr(args, "scene");
150
-    if (select->do_scene_detect && !CONFIG_AVCODEC) {
151
-        av_log(ctx, AV_LOG_ERROR, "Scene detection is not available without libavcodec.\n");
152
-        return AVERROR(EINVAL);
153
-    }
154
-    return 0;
155
-}
156
-
157
-#define INTERLACE_TYPE_P 0
158
-#define INTERLACE_TYPE_T 1
159
-#define INTERLACE_TYPE_B 2
160
-
161
-static int config_input(AVFilterLink *inlink)
162
-{
163
-    SelectContext *select = inlink->dst->priv;
164
-
165
-    select->var_values[VAR_N]          = 0.0;
166
-    select->var_values[VAR_SELECTED_N] = 0.0;
167
-
168
-    select->var_values[VAR_TB] = av_q2d(inlink->time_base);
169
-
170
-    select->var_values[VAR_PREV_PTS]          = NAN;
171
-    select->var_values[VAR_PREV_SELECTED_PTS] = NAN;
172
-    select->var_values[VAR_PREV_SELECTED_T]   = NAN;
173
-    select->var_values[VAR_START_PTS]         = NAN;
174
-    select->var_values[VAR_START_T]           = NAN;
175
-
176
-    select->var_values[VAR_PICT_TYPE_I]  = AV_PICTURE_TYPE_I;
177
-    select->var_values[VAR_PICT_TYPE_P]  = AV_PICTURE_TYPE_P;
178
-    select->var_values[VAR_PICT_TYPE_B]  = AV_PICTURE_TYPE_B;
179
-    select->var_values[VAR_PICT_TYPE_SI] = AV_PICTURE_TYPE_SI;
180
-    select->var_values[VAR_PICT_TYPE_SP] = AV_PICTURE_TYPE_SP;
181
-
182
-    select->var_values[VAR_INTERLACE_TYPE_P] = INTERLACE_TYPE_P;
183
-    select->var_values[VAR_INTERLACE_TYPE_T] = INTERLACE_TYPE_T;
184
-    select->var_values[VAR_INTERLACE_TYPE_B] = INTERLACE_TYPE_B;
185
-
186
-    select->var_values[VAR_SAMPLE_RATE] =
187
-        inlink->type == AVMEDIA_TYPE_AUDIO ? inlink->sample_rate : NAN;
188
-
189
-    if (CONFIG_AVCODEC && select->do_scene_detect) {
190
-        select->avctx = avcodec_alloc_context3(NULL);
191
-        if (!select->avctx)
192
-            return AVERROR(ENOMEM);
193
-        dsputil_init(&select->c, select->avctx);
194
-    }
195
-    return 0;
196
-}
197
-
198
-#if CONFIG_AVCODEC
199
-static double get_scene_score(AVFilterContext *ctx, AVFilterBufferRef *picref)
200
-{
201
-    double ret = 0;
202
-    SelectContext *select = ctx->priv;
203
-    AVFilterBufferRef *prev_picref = select->prev_picref;
204
-
205
-    if (prev_picref &&
206
-        picref->video->h    == prev_picref->video->h &&
207
-        picref->video->w    == prev_picref->video->w &&
208
-        picref->linesize[0] == prev_picref->linesize[0]) {
209
-        int x, y, nb_sad = 0;
210
-        int64_t sad = 0;
211
-        double mafd, diff;
212
-        uint8_t *p1 =      picref->data[0];
213
-        uint8_t *p2 = prev_picref->data[0];
214
-        const int linesize = picref->linesize[0];
215
-
216
-        for (y = 0; y < picref->video->h - 8; y += 8) {
217
-            for (x = 0; x < picref->video->w*3 - 8; x += 8) {
218
-                sad += select->c.sad[1](select, p1 + x, p2 + x,
219
-                                        linesize, 8);
220
-                nb_sad += 8 * 8;
221
-            }
222
-            p1 += 8 * linesize;
223
-            p2 += 8 * linesize;
224
-        }
225
-        emms_c();
226
-        mafd = nb_sad ? sad / nb_sad : 0;
227
-        diff = fabs(mafd - select->prev_mafd);
228
-        ret  = av_clipf(FFMIN(mafd, diff) / 100., 0, 1);
229
-        select->prev_mafd = mafd;
230
-        avfilter_unref_buffer(prev_picref);
231
-    }
232
-    select->prev_picref = avfilter_ref_buffer(picref, ~0);
233
-    return ret;
234
-}
235
-#endif
236
-
237
-#define D2TS(d)  (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
238
-#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
239
-
240
-static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref)
241
-{
242
-    SelectContext *select = ctx->priv;
243
-    AVFilterLink *inlink = ctx->inputs[0];
244
-    double res;
245
-
246
-    if (isnan(select->var_values[VAR_START_PTS]))
247
-        select->var_values[VAR_START_PTS] = TS2D(picref->pts);
248
-    if (isnan(select->var_values[VAR_START_T]))
249
-        select->var_values[VAR_START_T] = TS2D(picref->pts) * av_q2d(inlink->time_base);
250
-
251
-    select->var_values[VAR_PTS] = TS2D(picref->pts);
252
-    select->var_values[VAR_T  ] = TS2D(picref->pts) * av_q2d(inlink->time_base);
253
-    select->var_values[VAR_POS] = picref->pos == -1 ? NAN : picref->pos;
254
-    select->var_values[VAR_PREV_PTS] = TS2D(picref ->pts);
255
-
256
-    switch (inlink->type) {
257
-    case AVMEDIA_TYPE_AUDIO:
258
-        select->var_values[VAR_SAMPLES_N] = picref->audio->nb_samples;
259
-        break;
260
-
261
-    case AVMEDIA_TYPE_VIDEO:
262
-        select->var_values[VAR_INTERLACE_TYPE] =
263
-            !picref->video->interlaced     ? INTERLACE_TYPE_P :
264
-        picref->video->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B;
265
-        select->var_values[VAR_PICT_TYPE] = picref->video->pict_type;
266
-        if (CONFIG_AVCODEC && select->do_scene_detect) {
267
-            char buf[32];
268
-            select->var_values[VAR_SCENE] = get_scene_score(ctx, picref);
269
-            // TODO: document metadata
270
-            snprintf(buf, sizeof(buf), "%f", select->var_values[VAR_SCENE]);
271
-            av_dict_set(&picref->metadata, "lavfi.scene_score", buf, 0);
272
-        }
273
-        break;
274
-    }
275
-
276
-    res = av_expr_eval(select->expr, select->var_values, NULL);
277
-    av_log(inlink->dst, AV_LOG_DEBUG,
278
-           "n:%d pts:%d t:%f pos:%d key:%d",
279
-           (int)select->var_values[VAR_N],
280
-           (int)select->var_values[VAR_PTS],
281
-           select->var_values[VAR_T],
282
-           (int)select->var_values[VAR_POS],
283
-           (int)select->var_values[VAR_KEY]);
284
-
285
-    switch (inlink->type) {
286
-    case AVMEDIA_TYPE_VIDEO:
287
-        av_log(inlink->dst, AV_LOG_DEBUG, " interlace_type:%c pict_type:%c",
288
-               select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_P ? 'P' :
289
-               select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_T ? 'T' :
290
-               select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_B ? 'B' : '?',
291
-               av_get_picture_type_char(select->var_values[VAR_PICT_TYPE]));
292
-        break;
293
-    case AVMEDIA_TYPE_AUDIO:
294
-        av_log(inlink->dst, AV_LOG_DEBUG, " samples_n:%d consumed_samples_n:%d",
295
-               (int)select->var_values[VAR_SAMPLES_N],
296
-               (int)select->var_values[VAR_CONSUMED_SAMPLES_N]);
297
-        break;
298
-    }
299
-
300
-    av_log(inlink->dst, AV_LOG_DEBUG, " -> select:%f\n", res);
301
-
302
-    if (res) {
303
-        select->var_values[VAR_PREV_SELECTED_N]   = select->var_values[VAR_N];
304
-        select->var_values[VAR_PREV_SELECTED_PTS] = select->var_values[VAR_PTS];
305
-        select->var_values[VAR_PREV_SELECTED_T]   = select->var_values[VAR_T];
306
-        select->var_values[VAR_SELECTED_N] += 1.0;
307
-        if (inlink->type == AVMEDIA_TYPE_AUDIO)
308
-            select->var_values[VAR_CONSUMED_SAMPLES_N] += picref->audio->nb_samples;
309
-    }
310
-
311
-    select->var_values[VAR_N] += 1.0;
312
-
313
-    return res;
314
-}
315
-
316
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
317
-{
318
-    SelectContext *select = inlink->dst->priv;
319
-
320
-    select->select = select_frame(inlink->dst, frame);
321
-    if (select->select)
322
-        return ff_filter_frame(inlink->dst->outputs[0], frame);
323
-
324
-    avfilter_unref_bufferp(&frame);
325
-    return 0;
326
-}
327
-
328
-static int request_frame(AVFilterLink *outlink)
329
-{
330
-    AVFilterContext *ctx = outlink->src;
331
-    SelectContext *select = ctx->priv;
332
-    AVFilterLink *inlink = outlink->src->inputs[0];
333
-    select->select = 0;
334
-
335
-    do {
336
-        int ret = ff_request_frame(inlink);
337
-        if (ret < 0)
338
-            return ret;
339
-    } while (!select->select);
340
-
341
-    return 0;
342
-}
343
-
344
-static av_cold void uninit(AVFilterContext *ctx)
345
-{
346
-    SelectContext *select = ctx->priv;
347
-
348
-    av_expr_free(select->expr);
349
-    select->expr = NULL;
350
-
351
-    if (select->do_scene_detect) {
352
-        avfilter_unref_bufferp(&select->prev_picref);
353
-        if (select->avctx) {
354
-            avcodec_close(select->avctx);
355
-            av_freep(&select->avctx);
356
-        }
357
-    }
358
-}
359
-
360
-static int query_formats(AVFilterContext *ctx)
361
-{
362
-    SelectContext *select = ctx->priv;
363
-
364
-    if (!select->do_scene_detect) {
365
-        return ff_default_query_formats(ctx);
366
-    } else {
367
-        static const enum AVPixelFormat pix_fmts[] = {
368
-            AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
369
-            AV_PIX_FMT_NONE
370
-        };
371
-        ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
372
-    }
373
-    return 0;
374
-}
375
-
376
-#if CONFIG_ASELECT_FILTER
377
-static const AVFilterPad avfilter_af_aselect_inputs[] = {
378
-    {
379
-        .name             = "default",
380
-        .type             = AVMEDIA_TYPE_AUDIO,
381
-        .get_audio_buffer = ff_null_get_audio_buffer,
382
-        .config_props     = config_input,
383
-        .filter_frame     = filter_frame,
384
-    },
385
-    { NULL }
386
-};
387
-
388
-static const AVFilterPad avfilter_af_aselect_outputs[] = {
389
-    {
390
-        .name = "default",
391
-        .type = AVMEDIA_TYPE_AUDIO,
392
-    },
393
-    { NULL }
394
-};
395
-
396
-AVFilter avfilter_af_aselect = {
397
-    .name      = "aselect",
398
-    .description = NULL_IF_CONFIG_SMALL("Select audio frames to pass in output."),
399
-    .init      = init,
400
-    .uninit    = uninit,
401
-    .priv_size = sizeof(SelectContext),
402
-    .inputs    = avfilter_af_aselect_inputs,
403
-    .outputs   = avfilter_af_aselect_outputs,
404
-};
405
-#endif /* CONFIG_ASELECT_FILTER */
406
-
407
-#if CONFIG_SELECT_FILTER
408
-static const AVFilterPad avfilter_vf_select_inputs[] = {
409
-    {
410
-        .name             = "default",
411
-        .type             = AVMEDIA_TYPE_VIDEO,
412
-        .get_video_buffer = ff_null_get_video_buffer,
413
-        .min_perms        = AV_PERM_PRESERVE,
414
-        .config_props     = config_input,
415
-        .filter_frame     = filter_frame,
416
-    },
417
-    { NULL }
418
-};
419
-
420
-static const AVFilterPad avfilter_vf_select_outputs[] = {
421
-    {
422
-        .name          = "default",
423
-        .type          = AVMEDIA_TYPE_VIDEO,
424
-        .request_frame = request_frame,
425
-    },
426
-    { NULL }
427
-};
428
-
429
-AVFilter avfilter_vf_select = {
430
-    .name      = "select",
431
-    .description = NULL_IF_CONFIG_SMALL("Select video frames to pass in output."),
432
-    .init      = init,
433
-    .uninit    = uninit,
434
-    .query_formats = query_formats,
435
-
436
-    .priv_size = sizeof(SelectContext),
437
-
438
-    .inputs    = avfilter_vf_select_inputs,
439
-    .outputs   = avfilter_vf_select_outputs,
440
-};
441
-#endif /* CONFIG_SELECT_FILTER */