Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * This file is part of FFmpeg. | ||
3 | * | ||
4 | * FFmpeg is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * FFmpeg is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with FFmpeg; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | |||
19 | #include <stdint.h> | ||
20 | |||
21 | #include "config.h" | ||
22 | #include "config_components.h" | ||
23 | |||
24 | #include "libavutil/channel_layout.h" | ||
25 | #include "libavutil/common.h" | ||
26 | #include "libavutil/log.h" | ||
27 | #include "libavutil/mathematics.h" | ||
28 | #include "libavutil/opt.h" | ||
29 | #include "libavutil/samplefmt.h" | ||
30 | |||
31 | #include "audio.h" | ||
32 | #include "avfilter.h" | ||
33 | #include "filters.h" | ||
34 | #include "video.h" | ||
35 | |||
36 | typedef struct TrimContext { | ||
37 | const AVClass *class; | ||
38 | |||
39 | /* | ||
40 | * AVOptions | ||
41 | */ | ||
42 | int64_t duration; | ||
43 | int64_t start_time, end_time; | ||
44 | int64_t start_frame, end_frame; | ||
45 | /* | ||
46 | * in the link timebase for video, | ||
47 | * in 1/samplerate for audio | ||
48 | */ | ||
49 | int64_t start_pts, end_pts; | ||
50 | int64_t start_sample, end_sample; | ||
51 | |||
52 | /* | ||
53 | * number of video frames that arrived on this filter so far | ||
54 | */ | ||
55 | int64_t nb_frames; | ||
56 | /* | ||
57 | * number of audio samples that arrived on this filter so far | ||
58 | */ | ||
59 | int64_t nb_samples; | ||
60 | /* | ||
61 | * timestamp of the first frame in the output, in the timebase units | ||
62 | */ | ||
63 | int64_t first_pts; | ||
64 | /* | ||
65 | * duration in the timebase units | ||
66 | */ | ||
67 | int64_t duration_tb; | ||
68 | |||
69 | int64_t next_pts; | ||
70 | |||
71 | int eof; | ||
72 | |||
73 | int (*filter_frame)(AVFilterLink *inlink, AVFrame *frame); | ||
74 | } TrimContext; | ||
75 | |||
76 | 1706 | static av_cold int init(AVFilterContext *ctx) | |
77 | { | ||
78 | 1706 | TrimContext *s = ctx->priv; | |
79 | |||
80 | 1706 | s->first_pts = AV_NOPTS_VALUE; | |
81 | |||
82 | 1706 | return 0; | |
83 | } | ||
84 | |||
85 | #if CONFIG_TRIM_FILTER | ||
86 | 24019 | static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame) | |
87 | { | ||
88 | 24019 | AVFilterContext *ctx = inlink->dst; | |
89 | 24019 | TrimContext *s = ctx->priv; | |
90 | int drop; | ||
91 | |||
92 | /* drop everything if EOF has already been returned */ | ||
93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24019 times.
|
24019 | if (s->eof) { |
94 | ✗ | av_frame_free(&frame); | |
95 | ✗ | return 0; | |
96 | } | ||
97 | |||
98 |
4/4✓ Branch 0 taken 23997 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 155 times.
✓ Branch 3 taken 23842 times.
|
24019 | if (s->start_frame >= 0 || s->start_pts != AV_NOPTS_VALUE) { |
99 | 177 | drop = 1; | |
100 |
4/4✓ Branch 0 taken 22 times.
✓ Branch 1 taken 155 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 4 times.
|
177 | if (s->start_frame >= 0 && s->nb_frames >= s->start_frame) |
101 | 18 | drop = 0; | |
102 |
3/4✓ Branch 0 taken 166 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 166 times.
✗ Branch 3 not taken.
|
177 | if (s->start_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE && |
103 |
2/2✓ Branch 0 taken 151 times.
✓ Branch 1 taken 15 times.
|
166 | frame->pts >= s->start_pts) |
104 | 151 | drop = 0; | |
105 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 163 times.
|
177 | if (drop) |
106 | 14 | goto drop; | |
107 | } | ||
108 | |||
109 |
3/4✓ Branch 0 taken 894 times.
✓ Branch 1 taken 23111 times.
✓ Branch 2 taken 894 times.
✗ Branch 3 not taken.
|
24005 | if (s->first_pts == AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE) |
110 | 894 | s->first_pts = frame->pts; | |
111 | |||
112 |
6/6✓ Branch 0 taken 23987 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 23984 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 23844 times.
✓ Branch 5 taken 140 times.
|
24005 | if (s->end_frame != INT64_MAX || s->end_pts != AV_NOPTS_VALUE || s->duration_tb) { |
113 | 23865 | drop = 1; | |
114 | |||
115 |
4/4✓ Branch 0 taken 18 times.
✓ Branch 1 taken 23847 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 9 times.
|
23865 | if (s->end_frame != INT64_MAX && s->nb_frames < s->end_frame) |
116 | 9 | drop = 0; | |
117 |
3/4✓ Branch 0 taken 13 times.
✓ Branch 1 taken 23852 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
23865 | if (s->end_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE && |
118 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
|
13 | frame->pts < s->end_pts) |
119 | 11 | drop = 0; | |
120 |
3/4✓ Branch 0 taken 23844 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 23844 times.
✗ Branch 3 not taken.
|
23865 | if (s->duration_tb && frame->pts != AV_NOPTS_VALUE && |
121 |
2/2✓ Branch 0 taken 22961 times.
✓ Branch 1 taken 883 times.
|
23844 | frame->pts - s->first_pts < s->duration_tb) |
122 | 22961 | drop = 0; | |
123 | |||
124 |
2/2✓ Branch 0 taken 886 times.
✓ Branch 1 taken 22979 times.
|
23865 | if (drop) { |
125 | 886 | s->eof = 1; | |
126 | 886 | ff_inlink_set_status(inlink, AVERROR_EOF); | |
127 | 886 | ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, frame->pts); | |
128 | 886 | goto drop; | |
129 | } | ||
130 | } | ||
131 | |||
132 | 23119 | s->nb_frames++; | |
133 | |||
134 | 23119 | return ff_filter_frame(ctx->outputs[0], frame); | |
135 | |||
136 | 900 | drop: | |
137 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 886 times.
|
900 | if (!s->eof) |
138 | 14 | ff_filter_set_ready(ctx, 100); | |
139 | 900 | s->nb_frames++; | |
140 | 900 | av_frame_free(&frame); | |
141 | 900 | return 0; | |
142 | } | ||
143 | #endif // CONFIG_TRIM_FILTER | ||
144 | |||
145 | #if CONFIG_ATRIM_FILTER | ||
146 | 10468 | static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame) | |
147 | { | ||
148 | 10468 | AVFilterContext *ctx = inlink->dst; | |
149 | 10468 | TrimContext *s = ctx->priv; | |
150 | int64_t start_sample, end_sample; | ||
151 | int64_t pts; | ||
152 | int drop; | ||
153 | |||
154 | /* drop everything if EOF has already been returned */ | ||
155 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10468 times.
|
10468 | if (s->eof) { |
156 | ✗ | av_frame_free(&frame); | |
157 | ✗ | return 0; | |
158 | } | ||
159 | |||
160 |
1/2✓ Branch 0 taken 10468 times.
✗ Branch 1 not taken.
|
10468 | if (frame->pts != AV_NOPTS_VALUE) |
161 | 10468 | pts = av_rescale_q(frame->pts, inlink->time_base, | |
162 | 10468 | (AVRational){ 1, inlink->sample_rate }); | |
163 | else | ||
164 | ✗ | pts = s->next_pts; | |
165 | 10468 | s->next_pts = pts + frame->nb_samples; | |
166 | |||
167 | /* check if at least a part of the frame is after the start time */ | ||
168 |
4/4✓ Branch 0 taken 10463 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 8688 times.
✓ Branch 3 taken 1775 times.
|
10468 | if (s->start_sample < 0 && s->start_pts == AV_NOPTS_VALUE) { |
169 | 8688 | start_sample = 0; | |
170 | } else { | ||
171 | 1780 | drop = 1; | |
172 | 1780 | start_sample = frame->nb_samples; | |
173 | |||
174 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1775 times.
|
1780 | if (s->start_sample >= 0 && |
175 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | s->nb_samples + frame->nb_samples > s->start_sample) { |
176 | 5 | drop = 0; | |
177 | 5 | start_sample = FFMIN(start_sample, s->start_sample - s->nb_samples); | |
178 | } | ||
179 | |||
180 |
3/4✓ Branch 0 taken 1778 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1778 times.
✗ Branch 3 not taken.
|
1780 | if (s->start_pts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && |
181 |
2/2✓ Branch 0 taken 1454 times.
✓ Branch 1 taken 324 times.
|
1778 | pts + frame->nb_samples > s->start_pts) { |
182 | 1454 | drop = 0; | |
183 | 1454 | start_sample = FFMIN(start_sample, s->start_pts - pts); | |
184 | } | ||
185 | |||
186 |
2/2✓ Branch 0 taken 324 times.
✓ Branch 1 taken 1456 times.
|
1780 | if (drop) |
187 | 324 | goto drop; | |
188 | } | ||
189 | |||
190 |
2/2✓ Branch 0 taken 468 times.
✓ Branch 1 taken 9676 times.
|
10144 | if (s->first_pts == AV_NOPTS_VALUE) |
191 | 468 | s->first_pts = pts + start_sample; | |
192 | |||
193 | /* check if at least a part of the frame is before the end time */ | ||
194 |
6/6✓ Branch 0 taken 4892 times.
✓ Branch 1 taken 5252 times.
✓ Branch 2 taken 4872 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 1446 times.
✓ Branch 5 taken 3426 times.
|
10144 | if (s->end_sample == INT64_MAX && s->end_pts == AV_NOPTS_VALUE && !s->duration_tb) { |
195 | 1446 | end_sample = frame->nb_samples; | |
196 | } else { | ||
197 | 8698 | drop = 1; | |
198 | 8698 | end_sample = 0; | |
199 | |||
200 |
2/2✓ Branch 0 taken 5252 times.
✓ Branch 1 taken 3446 times.
|
8698 | if (s->end_sample != INT64_MAX && |
201 |
2/2✓ Branch 0 taken 4916 times.
✓ Branch 1 taken 336 times.
|
5252 | s->nb_samples < s->end_sample) { |
202 | 4916 | drop = 0; | |
203 | 4916 | end_sample = FFMAX(end_sample, s->end_sample - s->nb_samples); | |
204 | } | ||
205 | |||
206 |
3/4✓ Branch 0 taken 23 times.
✓ Branch 1 taken 8675 times.
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
|
8698 | if (s->end_pts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && |
207 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 3 times.
|
23 | pts < s->end_pts) { |
208 | 20 | drop = 0; | |
209 | 20 | end_sample = FFMAX(end_sample, s->end_pts - pts); | |
210 | } | ||
211 | |||
212 |
4/4✓ Branch 0 taken 3426 times.
✓ Branch 1 taken 5272 times.
✓ Branch 2 taken 3314 times.
✓ Branch 3 taken 112 times.
|
8698 | if (s->duration_tb && pts - s->first_pts < s->duration_tb) { |
213 | 3314 | drop = 0; | |
214 | 3314 | end_sample = FFMAX(end_sample, s->first_pts + s->duration_tb - pts); | |
215 | } | ||
216 | |||
217 |
2/2✓ Branch 0 taken 450 times.
✓ Branch 1 taken 8248 times.
|
8698 | if (drop) { |
218 | 450 | s->eof = 1; | |
219 | 450 | ff_inlink_set_status(inlink, AVERROR_EOF); | |
220 | 450 | ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, frame->pts); | |
221 | 450 | goto drop; | |
222 | } | ||
223 | } | ||
224 | |||
225 | 9694 | s->nb_samples += frame->nb_samples; | |
226 | 9694 | start_sample = FFMAX(0, start_sample); | |
227 | 9694 | end_sample = FFMIN(frame->nb_samples, end_sample); | |
228 |
2/4✓ Branch 0 taken 9694 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9694 times.
|
9694 | if (start_sample >= end_sample || !frame->nb_samples) |
229 | ✗ | goto drop; | |
230 | |||
231 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 9688 times.
|
9694 | if (start_sample) { |
232 | 6 | AVFrame *out = ff_get_audio_buffer(ctx->outputs[0], end_sample - start_sample); | |
233 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (!out) { |
234 | ✗ | av_frame_free(&frame); | |
235 | ✗ | return AVERROR(ENOMEM); | |
236 | } | ||
237 | |||
238 | 6 | av_frame_copy_props(out, frame); | |
239 | 6 | av_samples_copy(out->extended_data, frame->extended_data, 0, start_sample, | |
240 | out->nb_samples, inlink->ch_layout.nb_channels, | ||
241 | 6 | frame->format); | |
242 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if (out->pts != AV_NOPTS_VALUE) |
243 | 6 | out->pts += av_rescale_q(start_sample, (AVRational){ 1, out->sample_rate }, | |
244 | inlink->time_base); | ||
245 | |||
246 | 6 | av_frame_free(&frame); | |
247 | 6 | frame = out; | |
248 | } else | ||
249 | 9688 | frame->nb_samples = end_sample; | |
250 | |||
251 | 9694 | return ff_filter_frame(ctx->outputs[0], frame); | |
252 | |||
253 | 774 | drop: | |
254 |
2/2✓ Branch 0 taken 324 times.
✓ Branch 1 taken 450 times.
|
774 | if (!s->eof) |
255 | 324 | ff_filter_set_ready(ctx, 100); | |
256 | 774 | s->nb_samples += frame->nb_samples; | |
257 | 774 | av_frame_free(&frame); | |
258 | 774 | return 0; | |
259 | } | ||
260 | #endif // CONFIG_ATRIM_FILTER | ||
261 | |||
262 | 1362 | static int config_input(AVFilterLink *inlink) | |
263 | { | ||
264 | 1362 | AVFilterContext *ctx = inlink->dst; | |
265 | 1362 | TrimContext *s = ctx->priv; | |
266 | 894 | AVRational tb = (inlink->type == AVMEDIA_TYPE_VIDEO) ? | |
267 |
2/2✓ Branch 0 taken 894 times.
✓ Branch 1 taken 468 times.
|
1362 | inlink->time_base : (AVRational){ 1, inlink->sample_rate }; |
268 | |||
269 | #if CONFIG_TRIM_FILTER | ||
270 |
2/2✓ Branch 0 taken 894 times.
✓ Branch 1 taken 468 times.
|
1362 | if (inlink->type == AVMEDIA_TYPE_VIDEO) |
271 | 894 | s->filter_frame = trim_filter_frame; | |
272 | #endif | ||
273 | #if CONFIG_ATRIM_FILTER | ||
274 |
2/2✓ Branch 0 taken 468 times.
✓ Branch 1 taken 894 times.
|
1362 | if (inlink->type == AVMEDIA_TYPE_AUDIO) |
275 | 468 | s->filter_frame = atrim_filter_frame; | |
276 | #endif | ||
277 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1337 times.
|
1362 | if (s->start_time != INT64_MAX) { |
278 | 25 | int64_t start_pts = av_rescale_q(s->start_time, AV_TIME_BASE_Q, tb); | |
279 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
25 | if (s->start_pts == AV_NOPTS_VALUE || start_pts < s->start_pts) |
280 | 25 | s->start_pts = start_pts; | |
281 | } | ||
282 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1357 times.
|
1362 | if (s->end_time != INT64_MAX) { |
283 | 5 | int64_t end_pts = av_rescale_q(s->end_time, AV_TIME_BASE_Q, tb); | |
284 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
5 | if (s->end_pts == AV_NOPTS_VALUE || end_pts > s->end_pts) |
285 | 5 | s->end_pts = end_pts; | |
286 | } | ||
287 |
2/2✓ Branch 0 taken 1002 times.
✓ Branch 1 taken 360 times.
|
1362 | if (s->duration) |
288 | 1002 | s->duration_tb = av_rescale_q(s->duration, AV_TIME_BASE_Q, tb); | |
289 | |||
290 | 1362 | return 0; | |
291 | } | ||
292 | |||
293 | 68263 | static int activate(AVFilterContext *ctx) | |
294 | { | ||
295 | 68263 | TrimContext *s = ctx->priv; | |
296 | 68263 | AVFilterLink *inlink = ctx->inputs[0]; | |
297 | 68263 | AVFilterLink *outlink = ctx->outputs[0]; | |
298 | |||
299 |
2/2✓ Branch 1 taken 7 times.
✓ Branch 2 taken 68256 times.
|
68263 | FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); |
300 | |||
301 |
3/4✓ Branch 0 taken 68256 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 34487 times.
✓ Branch 4 taken 33769 times.
|
68256 | if (!s->eof && ff_inlink_queued_frames(inlink)) { |
302 | 34487 | AVFrame *frame = NULL; | |
303 | int ret; | ||
304 | |||
305 | 34487 | ret = ff_inlink_consume_frame(inlink, &frame); | |
306 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34487 times.
|
34487 | if (ret < 0) |
307 | 34487 | return ret; | |
308 |
1/2✓ Branch 0 taken 34487 times.
✗ Branch 1 not taken.
|
34487 | if (ret > 0) |
309 | 34487 | return s->filter_frame(inlink, frame); | |
310 | } | ||
311 | |||
312 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 33755 times.
|
33769 | FF_FILTER_FORWARD_STATUS(inlink, outlink); |
313 |
2/2✓ Branch 1 taken 33749 times.
✓ Branch 2 taken 6 times.
|
33755 | FF_FILTER_FORWARD_WANTED(outlink, inlink); |
314 | |||
315 | 6 | return FFERROR_NOT_READY; | |
316 | } | ||
317 | |||
318 | #define OFFSET(x) offsetof(TrimContext, x) | ||
319 | #define COMMON_OPTS \ | ||
320 | { "start", "Timestamp of the first frame that " \ | ||
321 | "should be passed", OFFSET(start_time), AV_OPT_TYPE_DURATION, { .i64 = INT64_MAX }, INT64_MIN, INT64_MAX, FLAGS }, \ | ||
322 | { "starti", "Timestamp of the first frame that " \ | ||
323 | "should be passed", OFFSET(start_time), AV_OPT_TYPE_DURATION, { .i64 = INT64_MAX }, INT64_MIN, INT64_MAX, FLAGS }, \ | ||
324 | { "end", "Timestamp of the first frame that " \ | ||
325 | "should be dropped again", OFFSET(end_time), AV_OPT_TYPE_DURATION, { .i64 = INT64_MAX }, INT64_MIN, INT64_MAX, FLAGS }, \ | ||
326 | { "endi", "Timestamp of the first frame that " \ | ||
327 | "should be dropped again", OFFSET(end_time), AV_OPT_TYPE_DURATION, { .i64 = INT64_MAX }, INT64_MIN, INT64_MAX, FLAGS }, \ | ||
328 | { "start_pts", "Timestamp of the first frame that should be " \ | ||
329 | " passed", OFFSET(start_pts), AV_OPT_TYPE_INT64, { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, FLAGS }, \ | ||
330 | { "end_pts", "Timestamp of the first frame that should be " \ | ||
331 | "dropped again", OFFSET(end_pts), AV_OPT_TYPE_INT64, { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, FLAGS }, \ | ||
332 | { "duration", "Maximum duration of the output", OFFSET(duration), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT64_MAX, FLAGS }, \ | ||
333 | { "durationi", "Maximum duration of the output", OFFSET(duration), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT64_MAX, FLAGS }, | ||
334 | |||
335 | |||
336 | #if CONFIG_TRIM_FILTER | ||
337 | |||
338 | #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | ||
339 | static const AVOption trim_options[] = { | ||
340 | COMMON_OPTS | ||
341 | { "start_frame", "Number of the first frame that should be passed " | ||
342 | "to the output", OFFSET(start_frame), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, FLAGS }, | ||
343 | { "end_frame", "Number of the first frame that should be dropped " | ||
344 | "again", OFFSET(end_frame), AV_OPT_TYPE_INT64, { .i64 = INT64_MAX }, 0, INT64_MAX, FLAGS }, | ||
345 | { NULL } | ||
346 | }; | ||
347 | #undef FLAGS | ||
348 | |||
349 | AVFILTER_DEFINE_CLASS(trim); | ||
350 | |||
351 | static const AVFilterPad trim_inputs[] = { | ||
352 | { | ||
353 | .name = "default", | ||
354 | .type = AVMEDIA_TYPE_VIDEO, | ||
355 | .config_props = config_input, | ||
356 | }, | ||
357 | }; | ||
358 | |||
359 | const AVFilter ff_vf_trim = { | ||
360 | .name = "trim", | ||
361 | .description = NULL_IF_CONFIG_SMALL("Pick one continuous section from the input, drop the rest."), | ||
362 | .init = init, | ||
363 | .activate = activate, | ||
364 | .priv_size = sizeof(TrimContext), | ||
365 | .priv_class = &trim_class, | ||
366 | .flags = AVFILTER_FLAG_METADATA_ONLY, | ||
367 | FILTER_INPUTS(trim_inputs), | ||
368 | FILTER_OUTPUTS(ff_video_default_filterpad), | ||
369 | }; | ||
370 | #endif // CONFIG_TRIM_FILTER | ||
371 | |||
372 | #if CONFIG_ATRIM_FILTER | ||
373 | |||
374 | #define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | ||
375 | static const AVOption atrim_options[] = { | ||
376 | COMMON_OPTS | ||
377 | { "start_sample", "Number of the first audio sample that should be " | ||
378 | "passed to the output", OFFSET(start_sample), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, FLAGS }, | ||
379 | { "end_sample", "Number of the first audio sample that should be " | ||
380 | "dropped again", OFFSET(end_sample), AV_OPT_TYPE_INT64, { .i64 = INT64_MAX }, 0, INT64_MAX, FLAGS }, | ||
381 | { NULL } | ||
382 | }; | ||
383 | #undef FLAGS | ||
384 | |||
385 | AVFILTER_DEFINE_CLASS(atrim); | ||
386 | |||
387 | static const AVFilterPad atrim_inputs[] = { | ||
388 | { | ||
389 | .name = "default", | ||
390 | .type = AVMEDIA_TYPE_AUDIO, | ||
391 | .config_props = config_input, | ||
392 | }, | ||
393 | }; | ||
394 | |||
395 | const AVFilter ff_af_atrim = { | ||
396 | .name = "atrim", | ||
397 | .description = NULL_IF_CONFIG_SMALL("Pick one continuous section from the input, drop the rest."), | ||
398 | .init = init, | ||
399 | .activate = activate, | ||
400 | .priv_size = sizeof(TrimContext), | ||
401 | .priv_class = &atrim_class, | ||
402 | .flags = AVFILTER_FLAG_METADATA_ONLY, | ||
403 | FILTER_INPUTS(atrim_inputs), | ||
404 | FILTER_OUTPUTS(ff_audio_default_filterpad), | ||
405 | }; | ||
406 | #endif // CONFIG_ATRIM_FILTER | ||
407 |