ffmpeg / cmdutils.c @ 584c2f1d
History | View | Annotate | Download (28.2 KB)
1 | 01310af2 | Fabrice Bellard | /*
|
---|---|---|---|
2 | * Various utilities for command line tools
|
||
3 | * Copyright (c) 2000-2003 Fabrice Bellard
|
||
4 | *
|
||
5 | b78e7197 | Diego Biurrun | * This file is part of FFmpeg.
|
6 | *
|
||
7 | * FFmpeg is free software; you can redistribute it and/or
|
||
8 | 01310af2 | Fabrice Bellard | * modify it under the terms of the GNU Lesser General Public
|
9 | * License as published by the Free Software Foundation; either
|
||
10 | b78e7197 | Diego Biurrun | * version 2.1 of the License, or (at your option) any later version.
|
11 | 01310af2 | Fabrice Bellard | *
|
12 | b78e7197 | Diego Biurrun | * FFmpeg is distributed in the hope that it will be useful,
|
13 | 01310af2 | Fabrice Bellard | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
15 | * Lesser General Public License for more details.
|
||
16 | *
|
||
17 | * You should have received a copy of the GNU Lesser General Public
|
||
18 | b78e7197 | Diego Biurrun | * License along with FFmpeg; if not, write to the Free Software
|
19 | 5509bffa | Diego Biurrun | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 | 01310af2 | Fabrice Bellard | */
|
21 | 364a9607 | Diego Biurrun | |
22 | 0f4e8165 | Ronald S. Bultje | #include <string.h> |
23 | #include <stdlib.h> |
||
24 | #include <errno.h> |
||
25 | 7c84b8bc | Stefano Sabatini | #include <math.h> |
26 | 0f4e8165 | Ronald S. Bultje | |
27 | 2cd39dbf | Diego Pettenò | /* Include only the enabled headers since some compilers (namely, Sun
|
28 | Studio) will not omit unused inline functions and create undefined
|
||
29 | references to libraries that are not being built. */
|
||
30 | |||
31 | 63d026b1 | Diego Biurrun | #include "config.h" |
32 | 245976da | Diego Biurrun | #include "libavformat/avformat.h" |
33 | #include "libavfilter/avfilter.h" |
||
34 | #include "libavdevice/avdevice.h" |
||
35 | db6d50c7 | Stefano Sabatini | #include "libswscale/swscale.h" |
36 | 1981deaf | Stefano Sabatini | #include "libpostproc/postprocess.h" |
37 | 245976da | Diego Biurrun | #include "libavutil/avstring.h" |
38 | 40c3fe2c | Stefano Sabatini | #include "libavutil/parseutils.h" |
39 | 9cb5c760 | Stefano Sabatini | #include "libavutil/pixdesc.h" |
40 | 25e25617 | Stefano Sabatini | #include "libavutil/eval.h" |
41 | 85663ef3 | Michael Niedermayer | #include "libavcodec/opt.h" |
42 | 01310af2 | Fabrice Bellard | #include "cmdutils.h" |
43 | 86074ed1 | Stefano Sabatini | #include "version.h" |
44 | da2dc39e | Ramiro Polla | #if CONFIG_NETWORK
|
45 | 245976da | Diego Biurrun | #include "libavformat/network.h" |
46 | da2dc39e | Ramiro Polla | #endif
|
47 | ffcc6e24 | Måns Rullgård | #if HAVE_SYS_RESOURCE_H
|
48 | #include <sys/resource.h> |
||
49 | #endif
|
||
50 | 01310af2 | Fabrice Bellard | |
51 | 85663ef3 | Michael Niedermayer | const char **opt_names; |
52 | 0093ebc2 | Michael Niedermayer | const char **opt_values; |
53 | 85663ef3 | Michael Niedermayer | static int opt_name_count; |
54 | 72415b2a | Stefano Sabatini | AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; |
55 | 85663ef3 | Michael Niedermayer | AVFormatContext *avformat_opts; |
56 | struct SwsContext *sws_opts;
|
||
57 | 086ab001 | Michael Niedermayer | |
58 | 7a0e1be8 | Diego Elio Pettenò | static const int this_year = 2011; |
59 | ef4c0bb1 | Stefano Sabatini | |
60 | a5c33faa | Reimar Döffinger | void init_opts(void) |
61 | { |
||
62 | int i;
|
||
63 | for (i = 0; i < AVMEDIA_TYPE_NB; i++) |
||
64 | avcodec_opts[i] = avcodec_alloc_context2(i); |
||
65 | avformat_opts = avformat_alloc_context(); |
||
66 | be4876ea | Stefano Sabatini | #if CONFIG_SWSCALE
|
67 | a5c33faa | Reimar Döffinger | sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL); |
68 | be4876ea | Stefano Sabatini | #endif
|
69 | a5c33faa | Reimar Döffinger | } |
70 | |||
71 | void uninit_opts(void) |
||
72 | { |
||
73 | int i;
|
||
74 | for (i = 0; i < AVMEDIA_TYPE_NB; i++) |
||
75 | av_freep(&avcodec_opts[i]); |
||
76 | av_freep(&avformat_opts->key); |
||
77 | av_freep(&avformat_opts); |
||
78 | be4876ea | Stefano Sabatini | #if CONFIG_SWSCALE
|
79 | a5c33faa | Reimar Döffinger | av_freep(&sws_opts); |
80 | be4876ea | Stefano Sabatini | #endif
|
81 | 3f171f5a | James Zern | for (i = 0; i < opt_name_count; i++) { |
82 | //opt_values are only stored for codec-specific options in which case
|
||
83 | //both the name and value are dup'd
|
||
84 | if (opt_values[i]) {
|
||
85 | av_freep(&opt_names[i]); |
||
86 | av_freep(&opt_values[i]); |
||
87 | } |
||
88 | } |
||
89 | ba3517aa | James Zern | av_freep(&opt_names); |
90 | av_freep(&opt_values); |
||
91 | a5c33faa | Reimar Döffinger | } |
92 | |||
93 | 1790d3b3 | Stefano Sabatini | void log_callback_help(void* ptr, int level, const char* fmt, va_list vl) |
94 | { |
||
95 | vfprintf(stdout, fmt, vl); |
||
96 | } |
||
97 | |||
98 | 086ab001 | Michael Niedermayer | double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max) |
99 | { |
||
100 | char *tail;
|
||
101 | const char *error; |
||
102 | 25e25617 | Stefano Sabatini | double d = av_strtod(numstr, &tail);
|
103 | 086ab001 | Michael Niedermayer | if (*tail)
|
104 | error= "Expected number for %s but found: %s\n";
|
||
105 | else if (d < min || d > max) |
||
106 | error= "The value for %s was %s which is not within %f - %f\n";
|
||
107 | else if(type == OPT_INT64 && (int64_t)d != d) |
||
108 | error= "Expected int64 for %s but found %s\n";
|
||
109 | 584c2f1d | Stefano Sabatini | else if (type == OPT_INT && (int)d != d) |
110 | error= "Expected int for %s but found %s\n";
|
||
111 | 086ab001 | Michael Niedermayer | else
|
112 | return d;
|
||
113 | fprintf(stderr, error, context, numstr, min, max); |
||
114 | exit(1);
|
||
115 | } |
||
116 | |||
117 | 7542157d | Stefano Sabatini | int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration) |
118 | { |
||
119 | 40c3fe2c | Stefano Sabatini | int64_t us; |
120 | if (av_parse_time(&us, timestr, is_duration) < 0) { |
||
121 | 7542157d | Stefano Sabatini | fprintf(stderr, "Invalid %s specification for %s: %s\n",
|
122 | is_duration ? "duration" : "date", context, timestr); |
||
123 | exit(1);
|
||
124 | } |
||
125 | return us;
|
||
126 | } |
||
127 | |||
128 | 02d504a7 | Fabrice Bellard | void show_help_options(const OptionDef *options, const char *msg, int mask, int value) |
129 | 01310af2 | Fabrice Bellard | { |
130 | const OptionDef *po;
|
||
131 | 02d504a7 | Fabrice Bellard | int first;
|
132 | 01310af2 | Fabrice Bellard | |
133 | 02d504a7 | Fabrice Bellard | first = 1;
|
134 | for(po = options; po->name != NULL; po++) { |
||
135 | char buf[64]; |
||
136 | if ((po->flags & mask) == value) {
|
||
137 | if (first) {
|
||
138 | printf("%s", msg);
|
||
139 | first = 0;
|
||
140 | } |
||
141 | f7d78f36 | Måns Rullgård | av_strlcpy(buf, po->name, sizeof(buf));
|
142 | 02d504a7 | Fabrice Bellard | if (po->flags & HAS_ARG) {
|
143 | f7d78f36 | Måns Rullgård | av_strlcat(buf, " ", sizeof(buf)); |
144 | av_strlcat(buf, po->argname, sizeof(buf));
|
||
145 | 01310af2 | Fabrice Bellard | } |
146 | 02d504a7 | Fabrice Bellard | printf("-%-17s %s\n", buf, po->help);
|
147 | 01310af2 | Fabrice Bellard | } |
148 | } |
||
149 | } |
||
150 | |||
151 | fccfc475 | Måns Rullgård | static const OptionDef* find_option(const OptionDef *po, const char *name){ |
152 | 8bbf6db9 | Michael Niedermayer | while (po->name != NULL) { |
153 | if (!strcmp(name, po->name))
|
||
154 | break;
|
||
155 | po++; |
||
156 | } |
||
157 | return po;
|
||
158 | } |
||
159 | |||
160 | 60a9966e | Stefano Sabatini | void parse_options(int argc, char **argv, const OptionDef *options, |
161 | void (* parse_arg_function)(const char*)) |
||
162 | 01310af2 | Fabrice Bellard | { |
163 | const char *opt, *arg; |
||
164 | b0d7bc1e | Loren Merritt | int optindex, handleoptions=1; |
165 | 01310af2 | Fabrice Bellard | const OptionDef *po;
|
166 | |||
167 | /* parse options */
|
||
168 | optindex = 1;
|
||
169 | while (optindex < argc) {
|
||
170 | opt = argv[optindex++]; |
||
171 | 115329f1 | Diego Biurrun | |
172 | 84bf226b | Timo Lindfors | if (handleoptions && opt[0] == '-' && opt[1] != '\0') { |
173 | b1d6e5e8 | Benoit Fouet | int bool_val = 1; |
174 | 3749076c | Stefano Sabatini | if (opt[1] == '-' && opt[2] == '\0') { |
175 | handleoptions = 0;
|
||
176 | continue;
|
||
177 | } |
||
178 | c3c78324 | Stefano Sabatini | opt++; |
179 | po= find_option(options, opt); |
||
180 | if (!po->name && opt[0] == 'n' && opt[1] == 'o') { |
||
181 | b1d6e5e8 | Benoit Fouet | /* handle 'no' bool option */
|
182 | c3c78324 | Stefano Sabatini | po = find_option(options, opt + 2);
|
183 | b1d6e5e8 | Benoit Fouet | if (!(po->name && (po->flags & OPT_BOOL)))
|
184 | goto unknown_opt;
|
||
185 | bool_val = 0;
|
||
186 | } |
||
187 | 8bbf6db9 | Michael Niedermayer | if (!po->name)
|
188 | po= find_option(options, "default");
|
||
189 | 01310af2 | Fabrice Bellard | if (!po->name) {
|
190 | 8bbf6db9 | Michael Niedermayer | unknown_opt:
|
191 | 01310af2 | Fabrice Bellard | fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt); |
192 | exit(1);
|
||
193 | } |
||
194 | arg = NULL;
|
||
195 | if (po->flags & HAS_ARG) {
|
||
196 | arg = argv[optindex++]; |
||
197 | if (!arg) {
|
||
198 | fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt); |
||
199 | exit(1);
|
||
200 | } |
||
201 | } |
||
202 | if (po->flags & OPT_STRING) {
|
||
203 | char *str;
|
||
204 | 02d504a7 | Fabrice Bellard | str = av_strdup(arg); |
205 | 01310af2 | Fabrice Bellard | *po->u.str_arg = str; |
206 | } else if (po->flags & OPT_BOOL) { |
||
207 | b1d6e5e8 | Benoit Fouet | *po->u.int_arg = bool_val; |
208 | 26d4f26b | Michael Niedermayer | } else if (po->flags & OPT_INT) { |
209 | c3c78324 | Stefano Sabatini | *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); |
210 | ffdf9a1f | Baptiste Coudurier | } else if (po->flags & OPT_INT64) { |
211 | c3c78324 | Stefano Sabatini | *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); |
212 | 1f631450 | Michael Niedermayer | } else if (po->flags & OPT_FLOAT) { |
213 | 324e7ee2 | Mans Rullgard | *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); |
214 | 8bbf6db9 | Michael Niedermayer | } else if (po->flags & OPT_FUNC2) { |
215 | 9e5381a2 | Stefano Sabatini | if (po->u.func2_arg(opt, arg) < 0) { |
216 | 330d86f5 | Stefano Sabatini | fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt); |
217 | 9e5381a2 | Stefano Sabatini | exit(1);
|
218 | } |
||
219 | 76d4c167 | Benjamin Larsson | } else if (po->flags & OPT_DUMMY) { |
220 | /* Do nothing for this option */
|
||
221 | 01310af2 | Fabrice Bellard | } else {
|
222 | bb270c08 | Diego Biurrun | po->u.func_arg(arg); |
223 | 01310af2 | Fabrice Bellard | } |
224 | a0b3bcd9 | Michael Niedermayer | if(po->flags & OPT_EXIT)
|
225 | exit(0);
|
||
226 | 01310af2 | Fabrice Bellard | } else {
|
227 | 60a9966e | Stefano Sabatini | if (parse_arg_function)
|
228 | parse_arg_function(opt); |
||
229 | 01310af2 | Fabrice Bellard | } |
230 | } |
||
231 | } |
||
232 | |||
233 | 85663ef3 | Michael Niedermayer | int opt_default(const char *opt, const char *arg){ |
234 | int type;
|
||
235 | 5c3383e5 | Stefano Sabatini | int ret= 0; |
236 | 85663ef3 | Michael Niedermayer | const AVOption *o= NULL; |
237 | int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0}; |
||
238 | |||
239 | d860aaf8 | Stefano Sabatini | for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){ |
240 | 636f1c4c | Stefano Sabatini | const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]); |
241 | 85663ef3 | Michael Niedermayer | if(o2)
|
242 | 636f1c4c | Stefano Sabatini | ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
|
243 | 85663ef3 | Michael Niedermayer | } |
244 | d860aaf8 | Stefano Sabatini | if(!o && avformat_opts)
|
245 | 5c3383e5 | Stefano Sabatini | ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
|
246 | da033b05 | Stefano Sabatini | if(!o && sws_opts)
|
247 | 5c3383e5 | Stefano Sabatini | ret = av_set_string3(sws_opts, opt, arg, 1, &o);
|
248 | 85663ef3 | Michael Niedermayer | if(!o){
|
249 | 819e2ab0 | Stefano Sabatini | if (opt[0] == 'a' && avcodec_opts[AVMEDIA_TYPE_AUDIO]) |
250 | 72415b2a | Stefano Sabatini | ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o); |
251 | 819e2ab0 | Stefano Sabatini | else if(opt[0] == 'v' && avcodec_opts[AVMEDIA_TYPE_VIDEO]) |
252 | 72415b2a | Stefano Sabatini | ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o); |
253 | 819e2ab0 | Stefano Sabatini | else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE]) |
254 | 72415b2a | Stefano Sabatini | ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o); |
255 | 5c3383e5 | Stefano Sabatini | } |
256 | if (o && ret < 0) { |
||
257 | fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
|
||
258 | exit(1);
|
||
259 | 85663ef3 | Michael Niedermayer | } |
260 | 33bc7947 | Stefano Sabatini | if (!o) {
|
261 | 0093ebc2 | Michael Niedermayer | AVCodec *p = NULL;
|
262 | ef2b2243 | Anssi Hannula | AVOutputFormat *oformat = NULL;
|
263 | 0093ebc2 | Michael Niedermayer | while ((p=av_codec_next(p))){
|
264 | AVClass *c= p->priv_class; |
||
265 | if(c && av_find_opt(&c, opt, NULL, 0, 0)) |
||
266 | break;
|
||
267 | } |
||
268 | ef2b2243 | Anssi Hannula | if (!p) {
|
269 | while ((oformat = av_oformat_next(oformat))) {
|
||
270 | const AVClass *c = oformat->priv_class;
|
||
271 | if (c && av_find_opt(&c, opt, NULL, 0, 0)) |
||
272 | break;
|
||
273 | } |
||
274 | } |
||
275 | if(!p && !oformat){
|
||
276 | f03424a7 | Martin Storsjö | fprintf(stderr, "Unrecognized option '%s'\n", opt);
|
277 | exit(1);
|
||
278 | 0093ebc2 | Michael Niedermayer | } |
279 | 33bc7947 | Stefano Sabatini | } |
280 | 85663ef3 | Michael Niedermayer | |
281 | 636f1c4c | Stefano Sabatini | // av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));
|
282 | 85663ef3 | Michael Niedermayer | |
283 | 636f1c4c | Stefano Sabatini | //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
|
284 | 0093ebc2 | Michael Niedermayer | opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1)); |
285 | 3f171f5a | James Zern | opt_values[opt_name_count]= o ? NULL : av_strdup(arg);
|
286 | 85663ef3 | Michael Niedermayer | opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1)); |
287 | 3f171f5a | James Zern | opt_names[opt_name_count++]= o ? o->name : av_strdup(opt); |
288 | 85663ef3 | Michael Niedermayer | |
289 | 20e021c7 | Stefano Sabatini | if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug)) |
290 | 85663ef3 | Michael Niedermayer | av_log_set_level(AV_LOG_DEBUG); |
291 | return 0; |
||
292 | } |
||
293 | |||
294 | 4c97a6fa | Stefano Sabatini | int opt_loglevel(const char *opt, const char *arg) |
295 | { |
||
296 | da4c2dab | Carl Eugen Hoyos | const struct { const char *name; int level; } log_levels[] = { |
297 | 4c97a6fa | Stefano Sabatini | { "quiet" , AV_LOG_QUIET },
|
298 | { "panic" , AV_LOG_PANIC },
|
||
299 | { "fatal" , AV_LOG_FATAL },
|
||
300 | { "error" , AV_LOG_ERROR },
|
||
301 | { "warning", AV_LOG_WARNING },
|
||
302 | { "info" , AV_LOG_INFO },
|
||
303 | { "verbose", AV_LOG_VERBOSE },
|
||
304 | { "debug" , AV_LOG_DEBUG },
|
||
305 | }; |
||
306 | char *tail;
|
||
307 | int level;
|
||
308 | int i;
|
||
309 | |||
310 | for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) { |
||
311 | if (!strcmp(log_levels[i].name, arg)) {
|
||
312 | av_log_set_level(log_levels[i].level); |
||
313 | return 0; |
||
314 | } |
||
315 | } |
||
316 | |||
317 | level = strtol(arg, &tail, 10);
|
||
318 | if (*tail) {
|
||
319 | fprintf(stderr, "Invalid loglevel \"%s\". "
|
||
320 | "Possible levels are numbers or:\n", arg);
|
||
321 | for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) |
||
322 | fprintf(stderr, "\"%s\"\n", log_levels[i].name);
|
||
323 | exit(1);
|
||
324 | } |
||
325 | av_log_set_level(level); |
||
326 | return 0; |
||
327 | } |
||
328 | |||
329 | ffcc6e24 | Måns Rullgård | int opt_timelimit(const char *opt, const char *arg) |
330 | { |
||
331 | 0104b608 | Måns Rullgård | #if HAVE_SETRLIMIT
|
332 | ffcc6e24 | Måns Rullgård | int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); |
333 | struct rlimit rl = { lim, lim + 1 }; |
||
334 | if (setrlimit(RLIMIT_CPU, &rl))
|
||
335 | perror("setrlimit");
|
||
336 | #else
|
||
337 | fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
|
||
338 | #endif
|
||
339 | return 0; |
||
340 | } |
||
341 | |||
342 | 0093ebc2 | Michael Niedermayer | void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec) |
343 | 85663ef3 | Michael Niedermayer | { |
344 | int i;
|
||
345 | 0093ebc2 | Michael Niedermayer | void *priv_ctx=NULL; |
346 | if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){ |
||
347 | AVCodecContext *avctx= ctx; |
||
348 | if(codec && codec->priv_class && avctx->priv_data){
|
||
349 | priv_ctx= avctx->priv_data; |
||
350 | } |
||
351 | ef2b2243 | Anssi Hannula | } else if (!strcmp("AVFormatContext", (*(AVClass**)ctx)->class_name)) { |
352 | AVFormatContext *avctx = ctx; |
||
353 | if (avctx->oformat && avctx->oformat->priv_class) {
|
||
354 | priv_ctx = avctx->priv_data; |
||
355 | } |
||
356 | 0093ebc2 | Michael Niedermayer | } |
357 | ef2b2243 | Anssi Hannula | |
358 | 85663ef3 | Michael Niedermayer | for(i=0; i<opt_name_count; i++){ |
359 | char buf[256]; |
||
360 | const AVOption *opt;
|
||
361 | const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf)); |
||
362 | /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
|
||
363 | if(str && ((opt->flags & flags) == flags))
|
||
364 | f16dd7e6 | Stefano Sabatini | av_set_string3(ctx, opt_names[i], str, 1, NULL); |
365 | 0093ebc2 | Michael Niedermayer | /* We need to use a differnt system to pass options to the private context because
|
366 | it is not known which codec and thus context kind that will be when parsing options
|
||
367 | we thus use opt_values directly instead of opts_ctx */
|
||
368 | if(!str && priv_ctx && av_get_string(priv_ctx, opt_names[i], &opt, buf, sizeof(buf))){ |
||
369 | av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL); |
||
370 | } |
||
371 | 85663ef3 | Michael Niedermayer | } |
372 | } |
||
373 | |||
374 | 01310af2 | Fabrice Bellard | void print_error(const char *filename, int err) |
375 | { |
||
376 | 7a5bdd79 | Stefano Sabatini | char errbuf[128]; |
377 | 735ef67b | Stefano Sabatini | const char *errbuf_ptr = errbuf; |
378 | 7a5bdd79 | Stefano Sabatini | |
379 | 9e94bd3e | Stefano Sabatini | if (av_strerror(err, errbuf, sizeof(errbuf)) < 0) |
380 | errbuf_ptr = strerror(AVUNERROR(err)); |
||
381 | fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
|
||
382 | 01310af2 | Fabrice Bellard | } |
383 | f35917b2 | Stefano Sabatini | |
384 | d101e731 | Stefano Sabatini | static int warned_cfg = 0; |
385 | |||
386 | 208749a0 | Stefano Sabatini | #define INDENT 1 |
387 | #define SHOW_VERSION 2 |
||
388 | d101e731 | Stefano Sabatini | #define SHOW_CONFIG 4 |
389 | 208749a0 | Stefano Sabatini | |
390 | 1044a92a | Stefano Sabatini | #define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags) \
|
391 | 5116571d | Måns Rullgård | if (CONFIG_##LIBNAME) { \ |
392 | 65dd2ded | Stefano Sabatini | const char *indent = flags & INDENT? " " : ""; \ |
393 | 208749a0 | Stefano Sabatini | if (flags & SHOW_VERSION) { \
|
394 | b6525b4b | Stefano Sabatini | unsigned int version = libname##_version(); \ |
395 | 9256dc28 | Georgi Chorbadzhiyski | fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
|
396 | 65dd2ded | Stefano Sabatini | indent, #libname, \
|
397 | b6525b4b | Stefano Sabatini | LIB##LIBNAME##_VERSION_MAJOR, \ |
398 | LIB##LIBNAME##_VERSION_MINOR, \ |
||
399 | LIB##LIBNAME##_VERSION_MICRO, \ |
||
400 | version >> 16, version >> 8 & 0xff, version & 0xff); \ |
||
401 | 208749a0 | Stefano Sabatini | } \ |
402 | d101e731 | Stefano Sabatini | if (flags & SHOW_CONFIG) { \
|
403 | const char *cfg = libname##_configuration(); \ |
||
404 | e528cdac | Michael Niedermayer | if (strcmp(FFMPEG_CONFIGURATION, cfg)) { \
|
405 | d101e731 | Stefano Sabatini | if (!warned_cfg) { \
|
406 | fprintf(outstream, \ |
||
407 | "%sWARNING: library configuration mismatch\n", \
|
||
408 | 65dd2ded | Stefano Sabatini | indent); \ |
409 | d101e731 | Stefano Sabatini | warned_cfg = 1; \
|
410 | } \ |
||
411 | fprintf(stderr, "%s%-11s configuration: %s\n", \
|
||
412 | 65dd2ded | Stefano Sabatini | indent, #libname, cfg); \
|
413 | d101e731 | Stefano Sabatini | } \ |
414 | } \ |
||
415 | 208749a0 | Stefano Sabatini | } \ |
416 | 9a109272 | Stefano Sabatini | |
417 | 1044a92a | Stefano Sabatini | static void print_all_libs_info(FILE* outstream, int flags) |
418 | 9a109272 | Stefano Sabatini | { |
419 | 1044a92a | Stefano Sabatini | PRINT_LIB_INFO(outstream, avutil, AVUTIL, flags); |
420 | PRINT_LIB_INFO(outstream, avcodec, AVCODEC, flags); |
||
421 | PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags); |
||
422 | PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags); |
||
423 | PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags); |
||
424 | PRINT_LIB_INFO(outstream, swscale, SWSCALE, flags); |
||
425 | PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags); |
||
426 | 9a109272 | Stefano Sabatini | } |
427 | |||
428 | ea9c581f | Stefano Sabatini | void show_banner(void) |
429 | 86074ed1 | Stefano Sabatini | { |
430 | 0cb88628 | Michael Niedermayer | fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n", |
431 | ef4c0bb1 | Stefano Sabatini | program_name, program_birth_year, this_year); |
432 | a3d7c197 | Diego Biurrun | fprintf(stderr, " built on %s %s with %s %s\n",
|
433 | __DATE__, __TIME__, CC_TYPE, CC_VERSION); |
||
434 | e528cdac | Michael Niedermayer | fprintf(stderr, " configuration: " FFMPEG_CONFIGURATION "\n"); |
435 | d101e731 | Stefano Sabatini | print_all_libs_info(stderr, INDENT|SHOW_CONFIG); |
436 | 1044a92a | Stefano Sabatini | print_all_libs_info(stderr, INDENT|SHOW_VERSION); |
437 | 86074ed1 | Stefano Sabatini | } |
438 | |||
439 | 64555bd9 | Michael Niedermayer | void show_version(void) { |
440 | 0cb88628 | Michael Niedermayer | printf("%s " FFMPEG_VERSION "\n", program_name); |
441 | 1044a92a | Stefano Sabatini | print_all_libs_info(stdout, SHOW_VERSION); |
442 | 86074ed1 | Stefano Sabatini | } |
443 | |||
444 | f35917b2 | Stefano Sabatini | void show_license(void) |
445 | { |
||
446 | 7ead693b | Diego Biurrun | printf( |
447 | 3bf28f9d | Stefano Sabatini | #if CONFIG_NONFREE
|
448 | 304ba23a | Stefano Sabatini | "This version of %s has nonfree parts compiled in.\n"
|
449 | "Therefore it is not legally redistributable.\n",
|
||
450 | program_name |
||
451 | 9cad0e4e | Diego Biurrun | #elif CONFIG_GPLV3
|
452 | "%s is free software; you can redistribute it and/or modify\n"
|
||
453 | "it under the terms of the GNU General Public License as published by\n"
|
||
454 | "the Free Software Foundation; either version 3 of the License, or\n"
|
||
455 | "(at your option) any later version.\n"
|
||
456 | "\n"
|
||
457 | "%s is distributed in the hope that it will be useful,\n"
|
||
458 | "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||
459 | "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||
460 | "GNU General Public License for more details.\n"
|
||
461 | "\n"
|
||
462 | "You should have received a copy of the GNU General Public License\n"
|
||
463 | "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
|
||
464 | program_name, program_name, program_name |
||
465 | 7ead693b | Diego Biurrun | #elif CONFIG_GPL
|
466 | 304ba23a | Stefano Sabatini | "%s is free software; you can redistribute it and/or modify\n"
|
467 | f35917b2 | Stefano Sabatini | "it under the terms of the GNU General Public License as published by\n"
|
468 | "the Free Software Foundation; either version 2 of the License, or\n"
|
||
469 | "(at your option) any later version.\n"
|
||
470 | "\n"
|
||
471 | 304ba23a | Stefano Sabatini | "%s is distributed in the hope that it will be useful,\n"
|
472 | f35917b2 | Stefano Sabatini | "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
473 | "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||
474 | "GNU General Public License for more details.\n"
|
||
475 | "\n"
|
||
476 | "You should have received a copy of the GNU General Public License\n"
|
||
477 | 304ba23a | Stefano Sabatini | "along with %s; if not, write to the Free Software\n"
|
478 | "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
|
||
479 | program_name, program_name, program_name |
||
480 | 9cad0e4e | Diego Biurrun | #elif CONFIG_LGPLV3
|
481 | "%s is free software; you can redistribute it and/or modify\n"
|
||
482 | "it under the terms of the GNU Lesser General Public License as published by\n"
|
||
483 | "the Free Software Foundation; either version 3 of the License, or\n"
|
||
484 | "(at your option) any later version.\n"
|
||
485 | "\n"
|
||
486 | "%s is distributed in the hope that it will be useful,\n"
|
||
487 | "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||
488 | "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||
489 | "GNU Lesser General Public License for more details.\n"
|
||
490 | "\n"
|
||
491 | "You should have received a copy of the GNU Lesser General Public License\n"
|
||
492 | "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
|
||
493 | program_name, program_name, program_name |
||
494 | f35917b2 | Stefano Sabatini | #else
|
495 | 304ba23a | Stefano Sabatini | "%s is free software; you can redistribute it and/or\n"
|
496 | f35917b2 | Stefano Sabatini | "modify it under the terms of the GNU Lesser General Public\n"
|
497 | "License as published by the Free Software Foundation; either\n"
|
||
498 | "version 2.1 of the License, or (at your option) any later version.\n"
|
||
499 | "\n"
|
||
500 | 304ba23a | Stefano Sabatini | "%s is distributed in the hope that it will be useful,\n"
|
501 | f35917b2 | Stefano Sabatini | "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
502 | "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
|
||
503 | "Lesser General Public License for more details.\n"
|
||
504 | "\n"
|
||
505 | "You should have received a copy of the GNU Lesser General Public\n"
|
||
506 | 304ba23a | Stefano Sabatini | "License along with %s; if not, write to the Free Software\n"
|
507 | "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
|
||
508 | program_name, program_name, program_name |
||
509 | f35917b2 | Stefano Sabatini | #endif
|
510 | 3bf28f9d | Stefano Sabatini | ); |
511 | f35917b2 | Stefano Sabatini | } |
512 | ba9880c1 | Stefano Sabatini | |
513 | void show_formats(void) |
||
514 | { |
||
515 | AVInputFormat *ifmt=NULL;
|
||
516 | AVOutputFormat *ofmt=NULL;
|
||
517 | const char *last_name; |
||
518 | |||
519 | 5a8597a0 | William R. Zwicky | printf( |
520 | "File formats:\n"
|
||
521 | " D. = Demuxing supported\n"
|
||
522 | " .E = Muxing supported\n"
|
||
523 | " --\n");
|
||
524 | ba9880c1 | Stefano Sabatini | last_name= "000";
|
525 | for(;;){
|
||
526 | int decode=0; |
||
527 | int encode=0; |
||
528 | const char *name=NULL; |
||
529 | const char *long_name=NULL; |
||
530 | |||
531 | while((ofmt= av_oformat_next(ofmt))) {
|
||
532 | if((name == NULL || strcmp(ofmt->name, name)<0) && |
||
533 | strcmp(ofmt->name, last_name)>0){
|
||
534 | name= ofmt->name; |
||
535 | long_name= ofmt->long_name; |
||
536 | encode=1;
|
||
537 | } |
||
538 | } |
||
539 | while((ifmt= av_iformat_next(ifmt))) {
|
||
540 | if((name == NULL || strcmp(ifmt->name, name)<0) && |
||
541 | strcmp(ifmt->name, last_name)>0){
|
||
542 | name= ifmt->name; |
||
543 | long_name= ifmt->long_name; |
||
544 | encode=0;
|
||
545 | } |
||
546 | if(name && strcmp(ifmt->name, name)==0) |
||
547 | decode=1;
|
||
548 | } |
||
549 | if(name==NULL) |
||
550 | break;
|
||
551 | last_name= name; |
||
552 | |||
553 | printf( |
||
554 | " %s%s %-15s %s\n",
|
||
555 | decode ? "D":" ", |
||
556 | encode ? "E":" ", |
||
557 | name, |
||
558 | long_name ? long_name:" ");
|
||
559 | } |
||
560 | 8447f0bd | Michael Niedermayer | } |
561 | ba9880c1 | Stefano Sabatini | |
562 | 8447f0bd | Michael Niedermayer | void show_codecs(void) |
563 | { |
||
564 | AVCodec *p=NULL, *p2;
|
||
565 | const char *last_name; |
||
566 | 5a8597a0 | William R. Zwicky | printf( |
567 | "Codecs:\n"
|
||
568 | " D..... = Decoding supported\n"
|
||
569 | " .E.... = Encoding supported\n"
|
||
570 | " ..V... = Video codec\n"
|
||
571 | " ..A... = Audio codec\n"
|
||
572 | " ..S... = Subtitle codec\n"
|
||
573 | " ...S.. = Supports draw_horiz_band\n"
|
||
574 | " ....D. = Supports direct rendering method 1\n"
|
||
575 | " .....T = Supports weird frame truncation\n"
|
||
576 | " ------\n");
|
||
577 | ba9880c1 | Stefano Sabatini | last_name= "000";
|
578 | for(;;){
|
||
579 | int decode=0; |
||
580 | int encode=0; |
||
581 | int cap=0; |
||
582 | const char *type_str; |
||
583 | |||
584 | p2=NULL;
|
||
585 | while((p= av_codec_next(p))) {
|
||
586 | if((p2==NULL || strcmp(p->name, p2->name)<0) && |
||
587 | strcmp(p->name, last_name)>0){
|
||
588 | p2= p; |
||
589 | decode= encode= cap=0;
|
||
590 | } |
||
591 | if(p2 && strcmp(p->name, p2->name)==0){ |
||
592 | if(p->decode) decode=1; |
||
593 | if(p->encode) encode=1; |
||
594 | cap |= p->capabilities; |
||
595 | } |
||
596 | } |
||
597 | if(p2==NULL) |
||
598 | break;
|
||
599 | last_name= p2->name; |
||
600 | |||
601 | switch(p2->type) {
|
||
602 | 72415b2a | Stefano Sabatini | case AVMEDIA_TYPE_VIDEO:
|
603 | ba9880c1 | Stefano Sabatini | type_str = "V";
|
604 | break;
|
||
605 | 72415b2a | Stefano Sabatini | case AVMEDIA_TYPE_AUDIO:
|
606 | ba9880c1 | Stefano Sabatini | type_str = "A";
|
607 | break;
|
||
608 | 72415b2a | Stefano Sabatini | case AVMEDIA_TYPE_SUBTITLE:
|
609 | ba9880c1 | Stefano Sabatini | type_str = "S";
|
610 | break;
|
||
611 | default:
|
||
612 | type_str = "?";
|
||
613 | break;
|
||
614 | } |
||
615 | printf( |
||
616 | " %s%s%s%s%s%s %-15s %s",
|
||
617 | decode ? "D": (/*p2->decoder ? "d":*/" "), |
||
618 | encode ? "E":" ", |
||
619 | type_str, |
||
620 | cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ", |
||
621 | cap & CODEC_CAP_DR1 ? "D":" ", |
||
622 | cap & CODEC_CAP_TRUNCATED ? "T":" ", |
||
623 | p2->name, |
||
624 | p2->long_name ? p2->long_name : "");
|
||
625 | /* if(p2->decoder && decode==0)
|
||
626 | printf(" use %s for decoding", p2->decoder->name);*/
|
||
627 | printf("\n");
|
||
628 | } |
||
629 | printf("\n");
|
||
630 | 8447f0bd | Michael Niedermayer | printf( |
631 | "Note, the names of encoders and decoders do not always match, so there are\n"
|
||
632 | "several cases where the above table shows encoder only or decoder only entries\n"
|
||
633 | "even though both encoding and decoding are supported. For example, the h263\n"
|
||
634 | "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
|
||
635 | "worse.\n");
|
||
636 | } |
||
637 | |||
638 | void show_bsfs(void) |
||
639 | { |
||
640 | AVBitStreamFilter *bsf=NULL;
|
||
641 | ba9880c1 | Stefano Sabatini | |
642 | printf("Bitstream filters:\n");
|
||
643 | while((bsf = av_bitstream_filter_next(bsf)))
|
||
644 | 2091b27b | Stefano Sabatini | printf("%s\n", bsf->name);
|
645 | ba9880c1 | Stefano Sabatini | printf("\n");
|
646 | 8447f0bd | Michael Niedermayer | } |
647 | |||
648 | void show_protocols(void) |
||
649 | { |
||
650 | URLProtocol *up=NULL;
|
||
651 | ba9880c1 | Stefano Sabatini | |
652 | 2ee5c789 | Stefano Sabatini | printf("Supported file protocols:\n"
|
653 | "I.. = Input supported\n"
|
||
654 | ".O. = Output supported\n"
|
||
655 | "..S = Seek supported\n"
|
||
656 | "FLAGS NAME\n"
|
||
657 | "----- \n");
|
||
658 | ba9880c1 | Stefano Sabatini | while((up = av_protocol_next(up)))
|
659 | 2ee5c789 | Stefano Sabatini | printf("%c%c%c %s\n",
|
660 | up->url_read ? 'I' : '.', |
||
661 | up->url_write ? 'O' : '.', |
||
662 | up->url_seek ? 'S' : '.', |
||
663 | up->name); |
||
664 | ba9880c1 | Stefano Sabatini | } |
665 | 090b61b2 | Stefano Sabatini | |
666 | 62d75662 | Stefano Sabatini | void show_filters(void) |
667 | { |
||
668 | 78638628 | Diego Biurrun | AVFilter av_unused(**filter) = NULL;
|
669 | 62d75662 | Stefano Sabatini | |
670 | printf("Filters:\n");
|
||
671 | 663c2edf | Stefano Sabatini | #if CONFIG_AVFILTER
|
672 | 62d75662 | Stefano Sabatini | while ((filter = av_filter_next(filter)) && *filter)
|
673 | printf("%-16s %s\n", (*filter)->name, (*filter)->description);
|
||
674 | 663c2edf | Stefano Sabatini | #endif
|
675 | 62d75662 | Stefano Sabatini | } |
676 | |||
677 | 3f7bb426 | Stefano Sabatini | void show_pix_fmts(void) |
678 | { |
||
679 | 9cb5c760 | Stefano Sabatini | enum PixelFormat pix_fmt;
|
680 | |||
681 | printf( |
||
682 | "Pixel formats:\n"
|
||
683 | "I.... = Supported Input format for conversion\n"
|
||
684 | ".O... = Supported Output format for conversion\n"
|
||
685 | "..H.. = Hardware accelerated format\n"
|
||
686 | "...P. = Paletted format\n"
|
||
687 | "....B = Bitstream format\n"
|
||
688 | "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
|
||
689 | "-----\n");
|
||
690 | |||
691 | e24db3e3 | Måns Rullgård | #if !CONFIG_SWSCALE
|
692 | # define sws_isSupportedInput(x) 0 |
||
693 | # define sws_isSupportedOutput(x) 0 |
||
694 | #endif
|
||
695 | |||
696 | 9cb5c760 | Stefano Sabatini | for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) { |
697 | const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
|
||
698 | printf("%c%c%c%c%c %-16s %d %2d\n",
|
||
699 | sws_isSupportedInput (pix_fmt) ? 'I' : '.', |
||
700 | sws_isSupportedOutput(pix_fmt) ? 'O' : '.', |
||
701 | pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.', |
||
702 | pix_desc->flags & PIX_FMT_PAL ? 'P' : '.', |
||
703 | pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.', |
||
704 | pix_desc->name, |
||
705 | pix_desc->nb_components, |
||
706 | av_get_bits_per_pixel(pix_desc)); |
||
707 | } |
||
708 | 3f7bb426 | Stefano Sabatini | } |
709 | |||
710 | 090b61b2 | Stefano Sabatini | int read_yesno(void) |
711 | { |
||
712 | int c = getchar();
|
||
713 | int yesno = (toupper(c) == 'Y'); |
||
714 | |||
715 | while (c != '\n' && c != EOF) |
||
716 | c = getchar(); |
||
717 | |||
718 | return yesno;
|
||
719 | } |
||
720 | 458b062d | Stefano Sabatini | |
721 | int read_file(const char *filename, char **bufptr, size_t *size) |
||
722 | { |
||
723 | c56e9e05 | Ramiro Polla | FILE *f = fopen(filename, "rb");
|
724 | 458b062d | Stefano Sabatini | |
725 | if (!f) {
|
||
726 | fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
|
||
727 | return AVERROR(errno);
|
||
728 | } |
||
729 | fseek(f, 0, SEEK_END);
|
||
730 | *size = ftell(f); |
||
731 | fseek(f, 0, SEEK_SET);
|
||
732 | *bufptr = av_malloc(*size + 1);
|
||
733 | if (!*bufptr) {
|
||
734 | fprintf(stderr, "Could not allocate file buffer\n");
|
||
735 | fclose(f); |
||
736 | return AVERROR(ENOMEM);
|
||
737 | } |
||
738 | fread(*bufptr, 1, *size, f);
|
||
739 | (*bufptr)[*size++] = '\0';
|
||
740 | |||
741 | fclose(f); |
||
742 | return 0; |
||
743 | } |
||
744 | 7a8bfa5d | Alexander Strange | |
745 | 6e872935 | Stefano Sabatini | FILE *get_preset_file(char *filename, size_t filename_size,
|
746 | const char *preset_name, int is_path, const char *codec_name) |
||
747 | { |
||
748 | FILE *f = NULL;
|
||
749 | int i;
|
||
750 | const char *base[3]= { getenv("FFMPEG_DATADIR"), |
||
751 | getenv("HOME"),
|
||
752 | FFMPEG_DATADIR, |
||
753 | }; |
||
754 | |||
755 | if (is_path) {
|
||
756 | av_strlcpy(filename, preset_name, filename_size); |
||
757 | f = fopen(filename, "r");
|
||
758 | } else {
|
||
759 | for (i = 0; i < 3 && !f; i++) { |
||
760 | if (!base[i])
|
||
761 | continue;
|
||
762 | snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name); |
||
763 | f = fopen(filename, "r");
|
||
764 | if (!f && codec_name) {
|
||
765 | snprintf(filename, filename_size, |
||
766 | "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", codec_name, preset_name); |
||
767 | f = fopen(filename, "r");
|
||
768 | } |
||
769 | } |
||
770 | } |
||
771 | |||
772 | return f;
|
||
773 | } |
||
774 | |||
775 | f7ead94c | Stefano Sabatini | #if CONFIG_AVFILTER
|
776 | |||
777 | static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque) |
||
778 | { |
||
779 | FFSinkContext *priv = ctx->priv; |
||
780 | |||
781 | if (!opaque)
|
||
782 | return AVERROR(EINVAL);
|
||
783 | *priv = *(FFSinkContext *)opaque; |
||
784 | |||
785 | return 0; |
||
786 | } |
||
787 | |||
788 | static void null_end_frame(AVFilterLink *inlink) { } |
||
789 | |||
790 | static int ffsink_query_formats(AVFilterContext *ctx) |
||
791 | { |
||
792 | FFSinkContext *priv = ctx->priv; |
||
793 | enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
|
||
794 | |||
795 | avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); |
||
796 | return 0; |
||
797 | } |
||
798 | |||
799 | AVFilter ffsink = { |
||
800 | .name = "ffsink",
|
||
801 | .priv_size = sizeof(FFSinkContext),
|
||
802 | .init = ffsink_init, |
||
803 | |||
804 | .query_formats = ffsink_query_formats, |
||
805 | |||
806 | .inputs = (AVFilterPad[]) {{ .name = "default",
|
||
807 | .type = AVMEDIA_TYPE_VIDEO, |
||
808 | .end_frame = null_end_frame, |
||
809 | .min_perms = AV_PERM_READ, }, |
||
810 | { .name = NULL }},
|
||
811 | .outputs = (AVFilterPad[]) {{ .name = NULL }},
|
||
812 | }; |
||
813 | |||
814 | ff0652e5 | Stefano Sabatini | int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
|
815 | AVFilterBufferRef **picref_ptr, AVRational *tb) |
||
816 | { |
||
817 | int ret;
|
||
818 | AVFilterBufferRef *picref; |
||
819 | |||
820 | if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0) |
||
821 | return ret;
|
||
822 | if (!(picref = ctx->inputs[0]->cur_buf)) |
||
823 | return AVERROR(ENOENT);
|
||
824 | *picref_ptr = picref; |
||
825 | ctx->inputs[0]->cur_buf = NULL; |
||
826 | *tb = ctx->inputs[0]->time_base;
|
||
827 | |||
828 | memcpy(frame->data, picref->data, sizeof(frame->data));
|
||
829 | memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
|
||
830 | frame->interlaced_frame = picref->video->interlaced; |
||
831 | frame->top_field_first = picref->video->top_field_first; |
||
832 | 09a1416d | Roger Pau Monné | frame->key_frame = picref->video->key_frame; |
833 | frame->pict_type = picref->video->pict_type; |
||
834 | ff0652e5 | Stefano Sabatini | |
835 | return 1; |
||
836 | } |
||
837 | |||
838 | f7ead94c | Stefano Sabatini | #endif /* CONFIG_AVFILTER */ |