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
20 #include <math.h>
21 #include <stdint.h>
22
23 #include "config.h"
24
32
36
39
40 /*
41 * AVOptions
42 */
46
49 /*
50 * in the link timebase for video,
51 * in 1/samplerate for audio
52 */
55
56 /*
57 * number of video frames that arrived on this filter so far
58 */
60 /*
61 * number of audio samples that arrived on this filter so far
62 */
64 /*
65 * timestamp of the first frame in the output, in the timebase units
66 */
68 /*
69 * duration in the timebase units
70 */
72
74
77
79 {
81
83
84 return 0;
85 }
86
88 {
93
100
105 }
110 }
113
114 return 0;
115 }
116
118 {
120 return 0;
121 }
122
123 #define OFFSET(x) offsetof(TrimContext, x)
124 #define COMMON_OPTS \
125 { "starti", "Timestamp of the first frame that " \
126 "should be passed", OFFSET(start_time), AV_OPT_TYPE_DURATION, { .i64 = INT64_MAX }, INT64_MIN, INT64_MAX, FLAGS }, \
127 { "endi", "Timestamp of the first frame that " \
128 "should be dropped again", OFFSET(end_time), AV_OPT_TYPE_DURATION, { .i64 = INT64_MAX }, INT64_MIN, INT64_MAX, FLAGS }, \
129 { "start_pts", "Timestamp of the first frame that should be " \
130 " passed", OFFSET(start_pts), AV_OPT_TYPE_INT64, { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, FLAGS }, \
131 { "end_pts", "Timestamp of the first frame that should be " \
132 "dropped again", OFFSET(end_pts), AV_OPT_TYPE_INT64, { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, FLAGS }, \
133 { "durationi", "Maximum duration of the output", OFFSET(duration), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT64_MAX, FLAGS },
134
135 #define COMPAT_OPTS \
136 { "start", "Timestamp in seconds of the first frame that " \
137 "should be passed", OFFSET(start_time_dbl),AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX }, -DBL_MAX, DBL_MAX, FLAGS }, \
138 { "end", "Timestamp in seconds of the first frame that " \
139 "should be dropped again", OFFSET(end_time_dbl), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX }, -DBL_MAX, DBL_MAX, FLAGS }, \
140 { "duration", "Maximum duration of the output in seconds", OFFSET(duration_dbl), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, 0, DBL_MAX, FLAGS },
141
142
143 #if CONFIG_TRIM_FILTER
145 {
148 int drop;
149
150 /* drop everything if EOF has already been returned */
153 return 0;
154 }
155
157 drop = 1;
159 drop = 0;
162 drop = 0;
163 if (drop)
164 goto drop;
165 }
166
169
171 drop = 1;
172
174 drop = 0;
177 drop = 0;
180 drop = 0;
181
182 if (drop) {
184 goto drop;
185 }
186 }
187
189
191
192 drop:
195 return 0;
196 }
197
198 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
199 static const AVOption trim_options[] = {
201 { "start_frame", "Number of the first frame that should be passed "
203 { "end_frame", "Number of the first frame that should be dropped "
207 };
208 #undef FLAGS
209
211
213 {
216 .filter_frame = trim_filter_frame,
218 },
220 };
221
223 {
227 },
229 };
230
233 .description =
NULL_IF_CONFIG_SMALL(
"Pick one continuous section from the input, drop the rest."),
236 .priv_class = &trim_class,
239 };
240 #endif // CONFIG_TRIM_FILTER
241
242 #if CONFIG_ATRIM_FILTER
244 {
247 int64_t start_sample, end_sample;
249 int drop;
250
251 /* drop everything if EOF has already been returned */
254 return 0;
255 }
256
260 else
263
264 /* check if at least a part of the frame is after the start time */
266 start_sample = 0;
267 } else {
268 drop = 1;
270
273 drop = 0;
275 }
276
279 drop = 0;
281 }
282
283 if (drop)
284 goto drop;
285 }
286
289
290 /* check if at least a part of the frame is before the end time */
293 } else {
294 drop = 1;
295 end_sample = 0;
296
299 drop = 0;
301 }
302
304 pts < s->end_pts) {
305 drop = 0;
307 }
308
310 drop = 0;
312 }
313
314 if (drop) {
316 goto drop;
317 }
318 }
319
321 start_sample =
FFMAX(0, start_sample);
324
325 if (start_sample) {
327 if (!out) {
330 }
331
339
342 } else
344
346
347 drop:
350 return 0;
351 }
352
353 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
354 static const AVOption atrim_options[] = {
356 { "start_sample", "Number of the first audio sample that should be "
358 { "end_sample", "Number of the first audio sample that should be "
362 };
363 #undef FLAGS
364
366
368 {
371 .filter_frame = atrim_filter_frame,
373 },
375 };
376
378 {
382 },
384 };
385
388 .description =
NULL_IF_CONFIG_SMALL(
"Pick one continuous section from the input, drop the rest."),
391 .priv_class = &atrim_class,
394 };
395 #endif // CONFIG_ATRIM_FILTER