Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52867 views
1
/*
2
* Various utilities for command line tools
3
* Copyright (c) 2000-2003 Fabrice Bellard
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* 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
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include <string.h>
23
#include <stdint.h>
24
#include <stdlib.h>
25
#include <errno.h>
26
#include <math.h>
27
28
/* Include only the enabled headers since some compilers (namely, Sun
29
Studio) will not omit unused inline functions and create undefined
30
references to libraries that are not being built. */
31
32
#include "config.h"
33
#include "compat/va_copy.h"
34
#include "libavformat/avformat.h"
35
#include "libavfilter/avfilter.h"
36
#include "libavdevice/avdevice.h"
37
#include "libavresample/avresample.h"
38
#include "libswscale/swscale.h"
39
#include "libswresample/swresample.h"
40
#include "libpostproc/postprocess.h"
41
#include "libavutil/avassert.h"
42
#include "libavutil/avstring.h"
43
#include "libavutil/bprint.h"
44
#include "libavutil/display.h"
45
#include "libavutil/mathematics.h"
46
#include "libavutil/imgutils.h"
47
#include "libavutil/libm.h"
48
#include "libavutil/parseutils.h"
49
#include "libavutil/pixdesc.h"
50
#include "libavutil/eval.h"
51
#include "libavutil/dict.h"
52
#include "libavutil/opt.h"
53
#include "libavutil/cpu.h"
54
#include "libavutil/ffversion.h"
55
#include "libavutil/version.h"
56
#include "cmdutils.h"
57
#if CONFIG_NETWORK
58
#include "libavformat/network.h"
59
#endif
60
#if HAVE_SYS_RESOURCE_H
61
#include <sys/time.h>
62
#include <sys/resource.h>
63
#endif
64
65
static int init_report(const char *env);
66
67
AVDictionary *sws_dict;
68
AVDictionary *swr_opts;
69
AVDictionary *format_opts, *codec_opts, *resample_opts;
70
71
static FILE *report_file;
72
static int report_file_level = AV_LOG_DEBUG;
73
int hide_banner = 0;
74
75
void init_opts(void)
76
{
77
av_dict_set(&sws_dict, "flags", "bicubic", 0);
78
}
79
80
void uninit_opts(void)
81
{
82
av_dict_free(&swr_opts);
83
av_dict_free(&sws_dict);
84
av_dict_free(&format_opts);
85
av_dict_free(&codec_opts);
86
av_dict_free(&resample_opts);
87
}
88
89
void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
90
{
91
vfprintf(stdout, fmt, vl);
92
}
93
94
static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
95
{
96
va_list vl2;
97
char line[1024];
98
static int print_prefix = 1;
99
100
va_copy(vl2, vl);
101
av_log_default_callback(ptr, level, fmt, vl);
102
av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
103
va_end(vl2);
104
if (report_file_level >= level) {
105
fputs(line, report_file);
106
fflush(report_file);
107
}
108
}
109
110
static void (*program_exit)(int ret);
111
112
void register_exit(void (*cb)(int ret))
113
{
114
program_exit = cb;
115
}
116
117
void exit_program(int ret)
118
{
119
if (program_exit)
120
program_exit(ret);
121
122
exit(ret);
123
}
124
125
double parse_number_or_die(const char *context, const char *numstr, int type,
126
double min, double max)
127
{
128
char *tail;
129
const char *error;
130
double d = av_strtod(numstr, &tail);
131
if (*tail)
132
error = "Expected number for %s but found: %s\n";
133
else if (d < min || d > max)
134
error = "The value for %s was %s which is not within %f - %f\n";
135
else if (type == OPT_INT64 && (int64_t)d != d)
136
error = "Expected int64 for %s but found %s\n";
137
else if (type == OPT_INT && (int)d != d)
138
error = "Expected int for %s but found %s\n";
139
else
140
return d;
141
av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
142
exit_program(1);
143
return 0;
144
}
145
146
int64_t parse_time_or_die(const char *context, const char *timestr,
147
int is_duration)
148
{
149
int64_t us;
150
if (av_parse_time(&us, timestr, is_duration) < 0) {
151
av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
152
is_duration ? "duration" : "date", context, timestr);
153
exit_program(1);
154
}
155
return us;
156
}
157
158
void show_help_options(const OptionDef *options, const char *msg, int req_flags,
159
int rej_flags, int alt_flags)
160
{
161
const OptionDef *po;
162
int first;
163
164
first = 1;
165
for (po = options; po->name; po++) {
166
char buf[64];
167
168
if (((po->flags & req_flags) != req_flags) ||
169
(alt_flags && !(po->flags & alt_flags)) ||
170
(po->flags & rej_flags))
171
continue;
172
173
if (first) {
174
printf("%s\n", msg);
175
first = 0;
176
}
177
av_strlcpy(buf, po->name, sizeof(buf));
178
if (po->argname) {
179
av_strlcat(buf, " ", sizeof(buf));
180
av_strlcat(buf, po->argname, sizeof(buf));
181
}
182
printf("-%-17s %s\n", buf, po->help);
183
}
184
printf("\n");
185
}
186
187
void show_help_children(const AVClass *class, int flags)
188
{
189
const AVClass *child = NULL;
190
if (class->option) {
191
av_opt_show2(&class, NULL, flags, 0);
192
printf("\n");
193
}
194
195
while (child = av_opt_child_class_next(class, child))
196
show_help_children(child, flags);
197
}
198
199
static const OptionDef *find_option(const OptionDef *po, const char *name)
200
{
201
const char *p = strchr(name, ':');
202
int len = p ? p - name : strlen(name);
203
204
while (po->name) {
205
if (!strncmp(name, po->name, len) && strlen(po->name) == len)
206
break;
207
po++;
208
}
209
return po;
210
}
211
212
/* _WIN32 means using the windows libc - cygwin doesn't define that
213
* by default. HAVE_COMMANDLINETOARGVW is true on cygwin, while
214
* it doesn't provide the actual command line via GetCommandLineW(). */
215
#if HAVE_COMMANDLINETOARGVW && defined(_WIN32)
216
#include <windows.h>
217
#include <shellapi.h>
218
/* Will be leaked on exit */
219
static char** win32_argv_utf8 = NULL;
220
static int win32_argc = 0;
221
222
/**
223
* Prepare command line arguments for executable.
224
* For Windows - perform wide-char to UTF-8 conversion.
225
* Input arguments should be main() function arguments.
226
* @param argc_ptr Arguments number (including executable)
227
* @param argv_ptr Arguments list.
228
*/
229
static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
230
{
231
char *argstr_flat;
232
wchar_t **argv_w;
233
int i, buffsize = 0, offset = 0;
234
235
if (win32_argv_utf8) {
236
*argc_ptr = win32_argc;
237
*argv_ptr = win32_argv_utf8;
238
return;
239
}
240
241
win32_argc = 0;
242
argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
243
if (win32_argc <= 0 || !argv_w)
244
return;
245
246
/* determine the UTF-8 buffer size (including NULL-termination symbols) */
247
for (i = 0; i < win32_argc; i++)
248
buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
249
NULL, 0, NULL, NULL);
250
251
win32_argv_utf8 = av_mallocz(sizeof(char *) * (win32_argc + 1) + buffsize);
252
argstr_flat = (char *)win32_argv_utf8 + sizeof(char *) * (win32_argc + 1);
253
if (!win32_argv_utf8) {
254
LocalFree(argv_w);
255
return;
256
}
257
258
for (i = 0; i < win32_argc; i++) {
259
win32_argv_utf8[i] = &argstr_flat[offset];
260
offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
261
&argstr_flat[offset],
262
buffsize - offset, NULL, NULL);
263
}
264
win32_argv_utf8[i] = NULL;
265
LocalFree(argv_w);
266
267
*argc_ptr = win32_argc;
268
*argv_ptr = win32_argv_utf8;
269
}
270
#else
271
static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
272
{
273
/* nothing to do */
274
}
275
#endif /* HAVE_COMMANDLINETOARGVW */
276
277
static int write_option(void *optctx, const OptionDef *po, const char *opt,
278
const char *arg)
279
{
280
/* new-style options contain an offset into optctx, old-style address of
281
* a global var*/
282
void *dst = po->flags & (OPT_OFFSET | OPT_SPEC) ?
283
(uint8_t *)optctx + po->u.off : po->u.dst_ptr;
284
int *dstcount;
285
286
if (po->flags & OPT_SPEC) {
287
SpecifierOpt **so = dst;
288
char *p = strchr(opt, ':');
289
char *str;
290
291
dstcount = (int *)(so + 1);
292
*so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
293
str = av_strdup(p ? p + 1 : "");
294
if (!str)
295
return AVERROR(ENOMEM);
296
(*so)[*dstcount - 1].specifier = str;
297
dst = &(*so)[*dstcount - 1].u;
298
}
299
300
if (po->flags & OPT_STRING) {
301
char *str;
302
str = av_strdup(arg);
303
av_freep(dst);
304
if (!str)
305
return AVERROR(ENOMEM);
306
*(char **)dst = str;
307
} else if (po->flags & OPT_BOOL || po->flags & OPT_INT) {
308
*(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
309
} else if (po->flags & OPT_INT64) {
310
*(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
311
} else if (po->flags & OPT_TIME) {
312
*(int64_t *)dst = parse_time_or_die(opt, arg, 1);
313
} else if (po->flags & OPT_FLOAT) {
314
*(float *)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
315
} else if (po->flags & OPT_DOUBLE) {
316
*(double *)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
317
} else if (po->u.func_arg) {
318
int ret = po->u.func_arg(optctx, opt, arg);
319
if (ret < 0) {
320
av_log(NULL, AV_LOG_ERROR,
321
"Failed to set value '%s' for option '%s': %s\n",
322
arg, opt, av_err2str(ret));
323
return ret;
324
}
325
}
326
if (po->flags & OPT_EXIT)
327
exit_program(0);
328
329
return 0;
330
}
331
332
int parse_option(void *optctx, const char *opt, const char *arg,
333
const OptionDef *options)
334
{
335
const OptionDef *po;
336
int ret;
337
338
po = find_option(options, opt);
339
if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
340
/* handle 'no' bool option */
341
po = find_option(options, opt + 2);
342
if ((po->name && (po->flags & OPT_BOOL)))
343
arg = "0";
344
} else if (po->flags & OPT_BOOL)
345
arg = "1";
346
347
if (!po->name)
348
po = find_option(options, "default");
349
if (!po->name) {
350
av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
351
return AVERROR(EINVAL);
352
}
353
if (po->flags & HAS_ARG && !arg) {
354
av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
355
return AVERROR(EINVAL);
356
}
357
358
ret = write_option(optctx, po, opt, arg);
359
if (ret < 0)
360
return ret;
361
362
return !!(po->flags & HAS_ARG);
363
}
364
365
void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
366
void (*parse_arg_function)(void *, const char*))
367
{
368
const char *opt;
369
int optindex, handleoptions = 1, ret;
370
371
/* perform system-dependent conversions for arguments list */
372
prepare_app_arguments(&argc, &argv);
373
374
/* parse options */
375
optindex = 1;
376
while (optindex < argc) {
377
opt = argv[optindex++];
378
379
if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
380
if (opt[1] == '-' && opt[2] == '\0') {
381
handleoptions = 0;
382
continue;
383
}
384
opt++;
385
386
if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
387
exit_program(1);
388
optindex += ret;
389
} else {
390
if (parse_arg_function)
391
parse_arg_function(optctx, opt);
392
}
393
}
394
}
395
396
int parse_optgroup(void *optctx, OptionGroup *g)
397
{
398
int i, ret;
399
400
av_log(NULL, AV_LOG_DEBUG, "Parsing a group of options: %s %s.\n",
401
g->group_def->name, g->arg);
402
403
for (i = 0; i < g->nb_opts; i++) {
404
Option *o = &g->opts[i];
405
406
if (g->group_def->flags &&
407
!(g->group_def->flags & o->opt->flags)) {
408
av_log(NULL, AV_LOG_ERROR, "Option %s (%s) cannot be applied to "
409
"%s %s -- you are trying to apply an input option to an "
410
"output file or vice versa. Move this option before the "
411
"file it belongs to.\n", o->key, o->opt->help,
412
g->group_def->name, g->arg);
413
return AVERROR(EINVAL);
414
}
415
416
av_log(NULL, AV_LOG_DEBUG, "Applying option %s (%s) with argument %s.\n",
417
o->key, o->opt->help, o->val);
418
419
ret = write_option(optctx, o->opt, o->key, o->val);
420
if (ret < 0)
421
return ret;
422
}
423
424
av_log(NULL, AV_LOG_DEBUG, "Successfully parsed a group of options.\n");
425
426
return 0;
427
}
428
429
int locate_option(int argc, char **argv, const OptionDef *options,
430
const char *optname)
431
{
432
const OptionDef *po;
433
int i;
434
435
for (i = 1; i < argc; i++) {
436
const char *cur_opt = argv[i];
437
438
if (*cur_opt++ != '-')
439
continue;
440
441
po = find_option(options, cur_opt);
442
if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
443
po = find_option(options, cur_opt + 2);
444
445
if ((!po->name && !strcmp(cur_opt, optname)) ||
446
(po->name && !strcmp(optname, po->name)))
447
return i;
448
449
if (!po->name || po->flags & HAS_ARG)
450
i++;
451
}
452
return 0;
453
}
454
455
static void dump_argument(const char *a)
456
{
457
const unsigned char *p;
458
459
for (p = a; *p; p++)
460
if (!((*p >= '+' && *p <= ':') || (*p >= '@' && *p <= 'Z') ||
461
*p == '_' || (*p >= 'a' && *p <= 'z')))
462
break;
463
if (!*p) {
464
fputs(a, report_file);
465
return;
466
}
467
fputc('"', report_file);
468
for (p = a; *p; p++) {
469
if (*p == '\\' || *p == '"' || *p == '$' || *p == '`')
470
fprintf(report_file, "\\%c", *p);
471
else if (*p < ' ' || *p > '~')
472
fprintf(report_file, "\\x%02x", *p);
473
else
474
fputc(*p, report_file);
475
}
476
fputc('"', report_file);
477
}
478
479
static void check_options(const OptionDef *po)
480
{
481
while (po->name) {
482
if (po->flags & OPT_PERFILE)
483
av_assert0(po->flags & (OPT_INPUT | OPT_OUTPUT));
484
po++;
485
}
486
}
487
488
void parse_loglevel(int argc, char **argv, const OptionDef *options)
489
{
490
int idx = locate_option(argc, argv, options, "loglevel");
491
const char *env;
492
493
check_options(options);
494
495
if (!idx)
496
idx = locate_option(argc, argv, options, "v");
497
if (idx && argv[idx + 1])
498
opt_loglevel(NULL, "loglevel", argv[idx + 1]);
499
idx = locate_option(argc, argv, options, "report");
500
if ((env = getenv("FFREPORT")) || idx) {
501
init_report(env);
502
if (report_file) {
503
int i;
504
fprintf(report_file, "Command line:\n");
505
for (i = 0; i < argc; i++) {
506
dump_argument(argv[i]);
507
fputc(i < argc - 1 ? ' ' : '\n', report_file);
508
}
509
fflush(report_file);
510
}
511
}
512
idx = locate_option(argc, argv, options, "hide_banner");
513
if (idx)
514
hide_banner = 1;
515
}
516
517
static const AVOption *opt_find(void *obj, const char *name, const char *unit,
518
int opt_flags, int search_flags)
519
{
520
const AVOption *o = av_opt_find(obj, name, unit, opt_flags, search_flags);
521
if(o && !o->flags)
522
return NULL;
523
return o;
524
}
525
526
#define FLAGS (o->type == AV_OPT_TYPE_FLAGS && (arg[0]=='-' || arg[0]=='+')) ? AV_DICT_APPEND : 0
527
int opt_default(void *optctx, const char *opt, const char *arg)
528
{
529
const AVOption *o;
530
int consumed = 0;
531
char opt_stripped[128];
532
const char *p;
533
const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();
534
#if CONFIG_AVRESAMPLE
535
const AVClass *rc = avresample_get_class();
536
#endif
537
#if CONFIG_SWSCALE
538
const AVClass *sc = sws_get_class();
539
#endif
540
#if CONFIG_SWRESAMPLE
541
const AVClass *swr_class = swr_get_class();
542
#endif
543
544
if (!strcmp(opt, "debug") || !strcmp(opt, "fdebug"))
545
av_log_set_level(AV_LOG_DEBUG);
546
547
if (!(p = strchr(opt, ':')))
548
p = opt + strlen(opt);
549
av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
550
551
if ((o = opt_find(&cc, opt_stripped, NULL, 0,
552
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
553
((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
554
(o = opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)))) {
555
av_dict_set(&codec_opts, opt, arg, FLAGS);
556
consumed = 1;
557
}
558
if ((o = opt_find(&fc, opt, NULL, 0,
559
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
560
av_dict_set(&format_opts, opt, arg, FLAGS);
561
if (consumed)
562
av_log(NULL, AV_LOG_VERBOSE, "Routing option %s to both codec and muxer layer\n", opt);
563
consumed = 1;
564
}
565
#if CONFIG_SWSCALE
566
if (!consumed && (o = opt_find(&sc, opt, NULL, 0,
567
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
568
struct SwsContext *sws = sws_alloc_context();
569
int ret = av_opt_set(sws, opt, arg, 0);
570
sws_freeContext(sws);
571
if (!strcmp(opt, "srcw") || !strcmp(opt, "srch") ||
572
!strcmp(opt, "dstw") || !strcmp(opt, "dsth") ||
573
!strcmp(opt, "src_format") || !strcmp(opt, "dst_format")) {
574
av_log(NULL, AV_LOG_ERROR, "Directly using swscale dimensions/format options is not supported, please use the -s or -pix_fmt options\n");
575
return AVERROR(EINVAL);
576
}
577
if (ret < 0) {
578
av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
579
return ret;
580
}
581
582
av_dict_set(&sws_dict, opt, arg, FLAGS);
583
584
consumed = 1;
585
}
586
#else
587
if (!consumed && !strcmp(opt, "sws_flags")) {
588
av_log(NULL, AV_LOG_WARNING, "Ignoring %s %s, due to disabled swscale\n", opt, arg);
589
consumed = 1;
590
}
591
#endif
592
#if CONFIG_SWRESAMPLE
593
if (!consumed && (o=opt_find(&swr_class, opt, NULL, 0,
594
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
595
struct SwrContext *swr = swr_alloc();
596
int ret = av_opt_set(swr, opt, arg, 0);
597
swr_free(&swr);
598
if (ret < 0) {
599
av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
600
return ret;
601
}
602
av_dict_set(&swr_opts, opt, arg, FLAGS);
603
consumed = 1;
604
}
605
#endif
606
#if CONFIG_AVRESAMPLE
607
if ((o=opt_find(&rc, opt, NULL, 0,
608
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
609
av_dict_set(&resample_opts, opt, arg, FLAGS);
610
consumed = 1;
611
}
612
#endif
613
614
if (consumed)
615
return 0;
616
return AVERROR_OPTION_NOT_FOUND;
617
}
618
619
/*
620
* Check whether given option is a group separator.
621
*
622
* @return index of the group definition that matched or -1 if none
623
*/
624
static int match_group_separator(const OptionGroupDef *groups, int nb_groups,
625
const char *opt)
626
{
627
int i;
628
629
for (i = 0; i < nb_groups; i++) {
630
const OptionGroupDef *p = &groups[i];
631
if (p->sep && !strcmp(p->sep, opt))
632
return i;
633
}
634
635
return -1;
636
}
637
638
/*
639
* Finish parsing an option group.
640
*
641
* @param group_idx which group definition should this group belong to
642
* @param arg argument of the group delimiting option
643
*/
644
static void finish_group(OptionParseContext *octx, int group_idx,
645
const char *arg)
646
{
647
OptionGroupList *l = &octx->groups[group_idx];
648
OptionGroup *g;
649
650
GROW_ARRAY(l->groups, l->nb_groups);
651
g = &l->groups[l->nb_groups - 1];
652
653
*g = octx->cur_group;
654
g->arg = arg;
655
g->group_def = l->group_def;
656
g->sws_dict = sws_dict;
657
g->swr_opts = swr_opts;
658
g->codec_opts = codec_opts;
659
g->format_opts = format_opts;
660
g->resample_opts = resample_opts;
661
662
codec_opts = NULL;
663
format_opts = NULL;
664
resample_opts = NULL;
665
sws_dict = NULL;
666
swr_opts = NULL;
667
init_opts();
668
669
memset(&octx->cur_group, 0, sizeof(octx->cur_group));
670
}
671
672
/*
673
* Add an option instance to currently parsed group.
674
*/
675
static void add_opt(OptionParseContext *octx, const OptionDef *opt,
676
const char *key, const char *val)
677
{
678
int global = !(opt->flags & (OPT_PERFILE | OPT_SPEC | OPT_OFFSET));
679
OptionGroup *g = global ? &octx->global_opts : &octx->cur_group;
680
681
GROW_ARRAY(g->opts, g->nb_opts);
682
g->opts[g->nb_opts - 1].opt = opt;
683
g->opts[g->nb_opts - 1].key = key;
684
g->opts[g->nb_opts - 1].val = val;
685
}
686
687
static void init_parse_context(OptionParseContext *octx,
688
const OptionGroupDef *groups, int nb_groups)
689
{
690
static const OptionGroupDef global_group = { "global" };
691
int i;
692
693
memset(octx, 0, sizeof(*octx));
694
695
octx->nb_groups = nb_groups;
696
octx->groups = av_mallocz_array(octx->nb_groups, sizeof(*octx->groups));
697
if (!octx->groups)
698
exit_program(1);
699
700
for (i = 0; i < octx->nb_groups; i++)
701
octx->groups[i].group_def = &groups[i];
702
703
octx->global_opts.group_def = &global_group;
704
octx->global_opts.arg = "";
705
706
init_opts();
707
}
708
709
void uninit_parse_context(OptionParseContext *octx)
710
{
711
int i, j;
712
713
for (i = 0; i < octx->nb_groups; i++) {
714
OptionGroupList *l = &octx->groups[i];
715
716
for (j = 0; j < l->nb_groups; j++) {
717
av_freep(&l->groups[j].opts);
718
av_dict_free(&l->groups[j].codec_opts);
719
av_dict_free(&l->groups[j].format_opts);
720
av_dict_free(&l->groups[j].resample_opts);
721
722
av_dict_free(&l->groups[j].sws_dict);
723
av_dict_free(&l->groups[j].swr_opts);
724
}
725
av_freep(&l->groups);
726
}
727
av_freep(&octx->groups);
728
729
av_freep(&octx->cur_group.opts);
730
av_freep(&octx->global_opts.opts);
731
732
uninit_opts();
733
}
734
735
int split_commandline(OptionParseContext *octx, int argc, char *argv[],
736
const OptionDef *options,
737
const OptionGroupDef *groups, int nb_groups)
738
{
739
int optindex = 1;
740
int dashdash = -2;
741
742
/* perform system-dependent conversions for arguments list */
743
prepare_app_arguments(&argc, &argv);
744
745
init_parse_context(octx, groups, nb_groups);
746
av_log(NULL, AV_LOG_DEBUG, "Splitting the commandline.\n");
747
748
while (optindex < argc) {
749
const char *opt = argv[optindex++], *arg;
750
const OptionDef *po;
751
int ret;
752
753
av_log(NULL, AV_LOG_DEBUG, "Reading option '%s' ...", opt);
754
755
if (opt[0] == '-' && opt[1] == '-' && !opt[2]) {
756
dashdash = optindex;
757
continue;
758
}
759
/* unnamed group separators, e.g. output filename */
760
if (opt[0] != '-' || !opt[1] || dashdash+1 == optindex) {
761
finish_group(octx, 0, opt);
762
av_log(NULL, AV_LOG_DEBUG, " matched as %s.\n", groups[0].name);
763
continue;
764
}
765
opt++;
766
767
#define GET_ARG(arg) \
768
do { \
769
arg = argv[optindex++]; \
770
if (!arg) { \
771
av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'.\n", opt);\
772
return AVERROR(EINVAL); \
773
} \
774
} while (0)
775
776
/* named group separators, e.g. -i */
777
if ((ret = match_group_separator(groups, nb_groups, opt)) >= 0) {
778
GET_ARG(arg);
779
finish_group(octx, ret, arg);
780
av_log(NULL, AV_LOG_DEBUG, " matched as %s with argument '%s'.\n",
781
groups[ret].name, arg);
782
continue;
783
}
784
785
/* normal options */
786
po = find_option(options, opt);
787
if (po->name) {
788
if (po->flags & OPT_EXIT) {
789
/* optional argument, e.g. -h */
790
arg = argv[optindex++];
791
} else if (po->flags & HAS_ARG) {
792
GET_ARG(arg);
793
} else {
794
arg = "1";
795
}
796
797
add_opt(octx, po, opt, arg);
798
av_log(NULL, AV_LOG_DEBUG, " matched as option '%s' (%s) with "
799
"argument '%s'.\n", po->name, po->help, arg);
800
continue;
801
}
802
803
/* AVOptions */
804
if (argv[optindex]) {
805
ret = opt_default(NULL, opt, argv[optindex]);
806
if (ret >= 0) {
807
av_log(NULL, AV_LOG_DEBUG, " matched as AVOption '%s' with "
808
"argument '%s'.\n", opt, argv[optindex]);
809
optindex++;
810
continue;
811
} else if (ret != AVERROR_OPTION_NOT_FOUND) {
812
av_log(NULL, AV_LOG_ERROR, "Error parsing option '%s' "
813
"with argument '%s'.\n", opt, argv[optindex]);
814
return ret;
815
}
816
}
817
818
/* boolean -nofoo options */
819
if (opt[0] == 'n' && opt[1] == 'o' &&
820
(po = find_option(options, opt + 2)) &&
821
po->name && po->flags & OPT_BOOL) {
822
add_opt(octx, po, opt, "0");
823
av_log(NULL, AV_LOG_DEBUG, " matched as option '%s' (%s) with "
824
"argument 0.\n", po->name, po->help);
825
continue;
826
}
827
828
av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'.\n", opt);
829
return AVERROR_OPTION_NOT_FOUND;
830
}
831
832
if (octx->cur_group.nb_opts || codec_opts || format_opts || resample_opts)
833
av_log(NULL, AV_LOG_WARNING, "Trailing options were found on the "
834
"commandline.\n");
835
836
av_log(NULL, AV_LOG_DEBUG, "Finished splitting the commandline.\n");
837
838
return 0;
839
}
840
841
int opt_cpuflags(void *optctx, const char *opt, const char *arg)
842
{
843
int ret;
844
unsigned flags = av_get_cpu_flags();
845
846
if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
847
return ret;
848
849
av_force_cpu_flags(flags);
850
return 0;
851
}
852
853
int opt_loglevel(void *optctx, const char *opt, const char *arg)
854
{
855
const struct { const char *name; int level; } log_levels[] = {
856
{ "quiet" , AV_LOG_QUIET },
857
{ "panic" , AV_LOG_PANIC },
858
{ "fatal" , AV_LOG_FATAL },
859
{ "error" , AV_LOG_ERROR },
860
{ "warning", AV_LOG_WARNING },
861
{ "info" , AV_LOG_INFO },
862
{ "verbose", AV_LOG_VERBOSE },
863
{ "debug" , AV_LOG_DEBUG },
864
{ "trace" , AV_LOG_TRACE },
865
};
866
char *tail;
867
int level;
868
int flags;
869
int i;
870
871
flags = av_log_get_flags();
872
tail = strstr(arg, "repeat");
873
if (tail)
874
flags &= ~AV_LOG_SKIP_REPEATED;
875
else
876
flags |= AV_LOG_SKIP_REPEATED;
877
878
av_log_set_flags(flags);
879
if (tail == arg)
880
arg += 6 + (arg[6]=='+');
881
if(tail && !*arg)
882
return 0;
883
884
for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
885
if (!strcmp(log_levels[i].name, arg)) {
886
av_log_set_level(log_levels[i].level);
887
return 0;
888
}
889
}
890
891
level = strtol(arg, &tail, 10);
892
if (*tail) {
893
av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
894
"Possible levels are numbers or:\n", arg);
895
for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
896
av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
897
exit_program(1);
898
}
899
av_log_set_level(level);
900
return 0;
901
}
902
903
static void expand_filename_template(AVBPrint *bp, const char *template,
904
struct tm *tm)
905
{
906
int c;
907
908
while ((c = *(template++))) {
909
if (c == '%') {
910
if (!(c = *(template++)))
911
break;
912
switch (c) {
913
case 'p':
914
av_bprintf(bp, "%s", program_name);
915
break;
916
case 't':
917
av_bprintf(bp, "%04d%02d%02d-%02d%02d%02d",
918
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
919
tm->tm_hour, tm->tm_min, tm->tm_sec);
920
break;
921
case '%':
922
av_bprint_chars(bp, c, 1);
923
break;
924
}
925
} else {
926
av_bprint_chars(bp, c, 1);
927
}
928
}
929
}
930
931
static int init_report(const char *env)
932
{
933
char *filename_template = NULL;
934
char *key, *val;
935
int ret, count = 0;
936
time_t now;
937
struct tm *tm;
938
AVBPrint filename;
939
940
if (report_file) /* already opened */
941
return 0;
942
time(&now);
943
tm = localtime(&now);
944
945
while (env && *env) {
946
if ((ret = av_opt_get_key_value(&env, "=", ":", 0, &key, &val)) < 0) {
947
if (count)
948
av_log(NULL, AV_LOG_ERROR,
949
"Failed to parse FFREPORT environment variable: %s\n",
950
av_err2str(ret));
951
break;
952
}
953
if (*env)
954
env++;
955
count++;
956
if (!strcmp(key, "file")) {
957
av_free(filename_template);
958
filename_template = val;
959
val = NULL;
960
} else if (!strcmp(key, "level")) {
961
char *tail;
962
report_file_level = strtol(val, &tail, 10);
963
if (*tail) {
964
av_log(NULL, AV_LOG_FATAL, "Invalid report file level\n");
965
exit_program(1);
966
}
967
} else {
968
av_log(NULL, AV_LOG_ERROR, "Unknown key '%s' in FFREPORT\n", key);
969
}
970
av_free(val);
971
av_free(key);
972
}
973
974
av_bprint_init(&filename, 0, 1);
975
expand_filename_template(&filename,
976
av_x_if_null(filename_template, "%p-%t.log"), tm);
977
av_free(filename_template);
978
if (!av_bprint_is_complete(&filename)) {
979
av_log(NULL, AV_LOG_ERROR, "Out of memory building report file name\n");
980
return AVERROR(ENOMEM);
981
}
982
983
report_file = fopen(filename.str, "w");
984
if (!report_file) {
985
int ret = AVERROR(errno);
986
av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
987
filename.str, strerror(errno));
988
return ret;
989
}
990
av_log_set_callback(log_callback_report);
991
av_log(NULL, AV_LOG_INFO,
992
"%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
993
"Report written to \"%s\"\n",
994
program_name,
995
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
996
tm->tm_hour, tm->tm_min, tm->tm_sec,
997
filename.str);
998
av_bprint_finalize(&filename, NULL);
999
return 0;
1000
}
1001
1002
int opt_report(const char *opt)
1003
{
1004
return init_report(NULL);
1005
}
1006
1007
int opt_max_alloc(void *optctx, const char *opt, const char *arg)
1008
{
1009
char *tail;
1010
size_t max;
1011
1012
max = strtol(arg, &tail, 10);
1013
if (*tail) {
1014
av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
1015
exit_program(1);
1016
}
1017
av_max_alloc(max);
1018
return 0;
1019
}
1020
1021
int opt_timelimit(void *optctx, const char *opt, const char *arg)
1022
{
1023
#if HAVE_SETRLIMIT
1024
int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
1025
struct rlimit rl = { lim, lim + 1 };
1026
if (setrlimit(RLIMIT_CPU, &rl))
1027
perror("setrlimit");
1028
#else
1029
av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
1030
#endif
1031
return 0;
1032
}
1033
1034
void print_error(const char *filename, int err)
1035
{
1036
char errbuf[128];
1037
const char *errbuf_ptr = errbuf;
1038
1039
if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
1040
errbuf_ptr = strerror(AVUNERROR(err));
1041
av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
1042
}
1043
1044
static int warned_cfg = 0;
1045
1046
#define INDENT 1
1047
#define SHOW_VERSION 2
1048
#define SHOW_CONFIG 4
1049
#define SHOW_COPYRIGHT 8
1050
1051
#define PRINT_LIB_INFO(libname, LIBNAME, flags, level) \
1052
if (CONFIG_##LIBNAME) { \
1053
const char *indent = flags & INDENT? " " : ""; \
1054
if (flags & SHOW_VERSION) { \
1055
unsigned int version = libname##_version(); \
1056
av_log(NULL, level, \
1057
"%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n", \
1058
indent, #libname, \
1059
LIB##LIBNAME##_VERSION_MAJOR, \
1060
LIB##LIBNAME##_VERSION_MINOR, \
1061
LIB##LIBNAME##_VERSION_MICRO, \
1062
AV_VERSION_MAJOR(version), AV_VERSION_MINOR(version),\
1063
AV_VERSION_MICRO(version)); \
1064
} \
1065
if (flags & SHOW_CONFIG) { \
1066
const char *cfg = libname##_configuration(); \
1067
if (strcmp(FFMPEG_CONFIGURATION, cfg)) { \
1068
if (!warned_cfg) { \
1069
av_log(NULL, level, \
1070
"%sWARNING: library configuration mismatch\n", \
1071
indent); \
1072
warned_cfg = 1; \
1073
} \
1074
av_log(NULL, level, "%s%-11s configuration: %s\n", \
1075
indent, #libname, cfg); \
1076
} \
1077
} \
1078
} \
1079
1080
static void print_all_libs_info(int flags, int level)
1081
{
1082
PRINT_LIB_INFO(avutil, AVUTIL, flags, level);
1083
PRINT_LIB_INFO(avcodec, AVCODEC, flags, level);
1084
PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
1085
PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
1086
PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
1087
PRINT_LIB_INFO(avresample, AVRESAMPLE, flags, level);
1088
PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
1089
PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level);
1090
PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
1091
}
1092
1093
static void print_program_info(int flags, int level)
1094
{
1095
const char *indent = flags & INDENT? " " : "";
1096
1097
av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
1098
if (flags & SHOW_COPYRIGHT)
1099
av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
1100
program_birth_year, CONFIG_THIS_YEAR);
1101
av_log(NULL, level, "\n");
1102
av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);
1103
1104
av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
1105
}
1106
1107
static void print_buildconf(int flags, int level)
1108
{
1109
const char *indent = flags & INDENT ? " " : "";
1110
char str[] = { FFMPEG_CONFIGURATION };
1111
char *conflist, *remove_tilde, *splitconf;
1112
1113
// Change all the ' --' strings to '~--' so that
1114
// they can be identified as tokens.
1115
while ((conflist = strstr(str, " --")) != NULL) {
1116
strncpy(conflist, "~--", 3);
1117
}
1118
1119
// Compensate for the weirdness this would cause
1120
// when passing 'pkg-config --static'.
1121
while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {
1122
strncpy(remove_tilde, "pkg-config ", 11);
1123
}
1124
1125
splitconf = strtok(str, "~");
1126
av_log(NULL, level, "\n%sconfiguration:\n", indent);
1127
while (splitconf != NULL) {
1128
av_log(NULL, level, "%s%s%s\n", indent, indent, splitconf);
1129
splitconf = strtok(NULL, "~");
1130
}
1131
}
1132
1133
void show_banner(int argc, char **argv, const OptionDef *options)
1134
{
1135
int idx = locate_option(argc, argv, options, "version");
1136
if (hide_banner || idx)
1137
return;
1138
1139
print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);
1140
print_all_libs_info(INDENT|SHOW_CONFIG, AV_LOG_INFO);
1141
print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
1142
}
1143
1144
int show_version(void *optctx, const char *opt, const char *arg)
1145
{
1146
av_log_set_callback(log_callback_help);
1147
print_program_info (SHOW_COPYRIGHT, AV_LOG_INFO);
1148
print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
1149
1150
return 0;
1151
}
1152
1153
int show_buildconf(void *optctx, const char *opt, const char *arg)
1154
{
1155
av_log_set_callback(log_callback_help);
1156
print_buildconf (INDENT|0, AV_LOG_INFO);
1157
1158
return 0;
1159
}
1160
1161
int show_license(void *optctx, const char *opt, const char *arg)
1162
{
1163
#if CONFIG_NONFREE
1164
printf(
1165
"This version of %s has nonfree parts compiled in.\n"
1166
"Therefore it is not legally redistributable.\n",
1167
program_name );
1168
#elif CONFIG_GPLV3
1169
printf(
1170
"%s is free software; you can redistribute it and/or modify\n"
1171
"it under the terms of the GNU General Public License as published by\n"
1172
"the Free Software Foundation; either version 3 of the License, or\n"
1173
"(at your option) any later version.\n"
1174
"\n"
1175
"%s is distributed in the hope that it will be useful,\n"
1176
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1177
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1178
"GNU General Public License for more details.\n"
1179
"\n"
1180
"You should have received a copy of the GNU General Public License\n"
1181
"along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
1182
program_name, program_name, program_name );
1183
#elif CONFIG_GPL
1184
printf(
1185
"%s is free software; you can redistribute it and/or modify\n"
1186
"it under the terms of the GNU General Public License as published by\n"
1187
"the Free Software Foundation; either version 2 of the License, or\n"
1188
"(at your option) any later version.\n"
1189
"\n"
1190
"%s is distributed in the hope that it will be useful,\n"
1191
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1192
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1193
"GNU General Public License for more details.\n"
1194
"\n"
1195
"You should have received a copy of the GNU General Public License\n"
1196
"along with %s; if not, write to the Free Software\n"
1197
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
1198
program_name, program_name, program_name );
1199
#elif CONFIG_LGPLV3
1200
printf(
1201
"%s is free software; you can redistribute it and/or modify\n"
1202
"it under the terms of the GNU Lesser General Public License as published by\n"
1203
"the Free Software Foundation; either version 3 of the License, or\n"
1204
"(at your option) any later version.\n"
1205
"\n"
1206
"%s is distributed in the hope that it will be useful,\n"
1207
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1208
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1209
"GNU Lesser General Public License for more details.\n"
1210
"\n"
1211
"You should have received a copy of the GNU Lesser General Public License\n"
1212
"along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
1213
program_name, program_name, program_name );
1214
#else
1215
printf(
1216
"%s is free software; you can redistribute it and/or\n"
1217
"modify it under the terms of the GNU Lesser General Public\n"
1218
"License as published by the Free Software Foundation; either\n"
1219
"version 2.1 of the License, or (at your option) any later version.\n"
1220
"\n"
1221
"%s is distributed in the hope that it will be useful,\n"
1222
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1223
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
1224
"Lesser General Public License for more details.\n"
1225
"\n"
1226
"You should have received a copy of the GNU Lesser General Public\n"
1227
"License along with %s; if not, write to the Free Software\n"
1228
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
1229
program_name, program_name, program_name );
1230
#endif
1231
1232
return 0;
1233
}
1234
1235
static int is_device(const AVClass *avclass)
1236
{
1237
if (!avclass)
1238
return 0;
1239
return AV_IS_INPUT_DEVICE(avclass->category) || AV_IS_OUTPUT_DEVICE(avclass->category);
1240
}
1241
1242
static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only)
1243
{
1244
AVInputFormat *ifmt = NULL;
1245
AVOutputFormat *ofmt = NULL;
1246
const char *last_name;
1247
int is_dev;
1248
1249
printf("%s\n"
1250
" D. = Demuxing supported\n"
1251
" .E = Muxing supported\n"
1252
" --\n", device_only ? "Devices:" : "File formats:");
1253
last_name = "000";
1254
for (;;) {
1255
int decode = 0;
1256
int encode = 0;
1257
const char *name = NULL;
1258
const char *long_name = NULL;
1259
1260
while ((ofmt = av_oformat_next(ofmt))) {
1261
is_dev = is_device(ofmt->priv_class);
1262
if (!is_dev && device_only)
1263
continue;
1264
if ((!name || strcmp(ofmt->name, name) < 0) &&
1265
strcmp(ofmt->name, last_name) > 0) {
1266
name = ofmt->name;
1267
long_name = ofmt->long_name;
1268
encode = 1;
1269
}
1270
}
1271
while ((ifmt = av_iformat_next(ifmt))) {
1272
is_dev = is_device(ifmt->priv_class);
1273
if (!is_dev && device_only)
1274
continue;
1275
if ((!name || strcmp(ifmt->name, name) < 0) &&
1276
strcmp(ifmt->name, last_name) > 0) {
1277
name = ifmt->name;
1278
long_name = ifmt->long_name;
1279
encode = 0;
1280
}
1281
if (name && strcmp(ifmt->name, name) == 0)
1282
decode = 1;
1283
}
1284
if (!name)
1285
break;
1286
last_name = name;
1287
1288
printf(" %s%s %-15s %s\n",
1289
decode ? "D" : " ",
1290
encode ? "E" : " ",
1291
name,
1292
long_name ? long_name:" ");
1293
}
1294
return 0;
1295
}
1296
1297
int show_formats(void *optctx, const char *opt, const char *arg)
1298
{
1299
return show_formats_devices(optctx, opt, arg, 0);
1300
}
1301
1302
int show_devices(void *optctx, const char *opt, const char *arg)
1303
{
1304
return show_formats_devices(optctx, opt, arg, 1);
1305
}
1306
1307
#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
1308
if (codec->field) { \
1309
const type *p = codec->field; \
1310
\
1311
printf(" Supported " list_name ":"); \
1312
while (*p != term) { \
1313
get_name(*p); \
1314
printf(" %s", name); \
1315
p++; \
1316
} \
1317
printf("\n"); \
1318
} \
1319
1320
static void print_codec(const AVCodec *c)
1321
{
1322
int encoder = av_codec_is_encoder(c);
1323
1324
printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
1325
c->long_name ? c->long_name : "");
1326
1327
printf(" General capabilities: ");
1328
if (c->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)
1329
printf("horizband ");
1330
if (c->capabilities & AV_CODEC_CAP_DR1)
1331
printf("dr1 ");
1332
if (c->capabilities & AV_CODEC_CAP_TRUNCATED)
1333
printf("trunc ");
1334
if (c->capabilities & AV_CODEC_CAP_DELAY)
1335
printf("delay ");
1336
if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)
1337
printf("small ");
1338
if (c->capabilities & AV_CODEC_CAP_SUBFRAMES)
1339
printf("subframes ");
1340
if (c->capabilities & AV_CODEC_CAP_EXPERIMENTAL)
1341
printf("exp ");
1342
if (c->capabilities & AV_CODEC_CAP_CHANNEL_CONF)
1343
printf("chconf ");
1344
if (c->capabilities & AV_CODEC_CAP_PARAM_CHANGE)
1345
printf("paramchange ");
1346
if (c->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
1347
printf("variable ");
1348
if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
1349
AV_CODEC_CAP_SLICE_THREADS |
1350
AV_CODEC_CAP_AUTO_THREADS))
1351
printf("threads ");
1352
if (!c->capabilities)
1353
printf("none");
1354
printf("\n");
1355
1356
if (c->type == AVMEDIA_TYPE_VIDEO ||
1357
c->type == AVMEDIA_TYPE_AUDIO) {
1358
printf(" Threading capabilities: ");
1359
switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
1360
AV_CODEC_CAP_SLICE_THREADS |
1361
AV_CODEC_CAP_AUTO_THREADS)) {
1362
case AV_CODEC_CAP_FRAME_THREADS |
1363
AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
1364
case AV_CODEC_CAP_FRAME_THREADS: printf("frame"); break;
1365
case AV_CODEC_CAP_SLICE_THREADS: printf("slice"); break;
1366
case AV_CODEC_CAP_AUTO_THREADS : printf("auto"); break;
1367
default: printf("none"); break;
1368
}
1369
printf("\n");
1370
}
1371
1372
if (c->supported_framerates) {
1373
const AVRational *fps = c->supported_framerates;
1374
1375
printf(" Supported framerates:");
1376
while (fps->num) {
1377
printf(" %d/%d", fps->num, fps->den);
1378
fps++;
1379
}
1380
printf("\n");
1381
}
1382
PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel formats",
1383
AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
1384
PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0,
1385
GET_SAMPLE_RATE_NAME);
1386
PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats",
1387
AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
1388
PRINT_CODEC_SUPPORTED(c, channel_layouts, uint64_t, "channel layouts",
1389
0, GET_CH_LAYOUT_DESC);
1390
1391
if (c->priv_class) {
1392
show_help_children(c->priv_class,
1393
AV_OPT_FLAG_ENCODING_PARAM |
1394
AV_OPT_FLAG_DECODING_PARAM);
1395
}
1396
}
1397
1398
static char get_media_type_char(enum AVMediaType type)
1399
{
1400
switch (type) {
1401
case AVMEDIA_TYPE_VIDEO: return 'V';
1402
case AVMEDIA_TYPE_AUDIO: return 'A';
1403
case AVMEDIA_TYPE_DATA: return 'D';
1404
case AVMEDIA_TYPE_SUBTITLE: return 'S';
1405
case AVMEDIA_TYPE_ATTACHMENT:return 'T';
1406
default: return '?';
1407
}
1408
}
1409
1410
static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
1411
int encoder)
1412
{
1413
while ((prev = av_codec_next(prev))) {
1414
if (prev->id == id &&
1415
(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
1416
return prev;
1417
}
1418
return NULL;
1419
}
1420
1421
static int compare_codec_desc(const void *a, const void *b)
1422
{
1423
const AVCodecDescriptor * const *da = a;
1424
const AVCodecDescriptor * const *db = b;
1425
1426
return (*da)->type != (*db)->type ? FFDIFFSIGN((*da)->type, (*db)->type) :
1427
strcmp((*da)->name, (*db)->name);
1428
}
1429
1430
static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
1431
{
1432
const AVCodecDescriptor *desc = NULL;
1433
const AVCodecDescriptor **codecs;
1434
unsigned nb_codecs = 0, i = 0;
1435
1436
while ((desc = avcodec_descriptor_next(desc)))
1437
nb_codecs++;
1438
if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
1439
av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
1440
exit_program(1);
1441
}
1442
desc = NULL;
1443
while ((desc = avcodec_descriptor_next(desc)))
1444
codecs[i++] = desc;
1445
av_assert0(i == nb_codecs);
1446
qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
1447
*rcodecs = codecs;
1448
return nb_codecs;
1449
}
1450
1451
static void print_codecs_for_id(enum AVCodecID id, int encoder)
1452
{
1453
const AVCodec *codec = NULL;
1454
1455
printf(" (%s: ", encoder ? "encoders" : "decoders");
1456
1457
while ((codec = next_codec_for_id(id, codec, encoder)))
1458
printf("%s ", codec->name);
1459
1460
printf(")");
1461
}
1462
1463
int show_codecs(void *optctx, const char *opt, const char *arg)
1464
{
1465
const AVCodecDescriptor **codecs;
1466
unsigned i, nb_codecs = get_codecs_sorted(&codecs);
1467
1468
printf("Codecs:\n"
1469
" D..... = Decoding supported\n"
1470
" .E.... = Encoding supported\n"
1471
" ..V... = Video codec\n"
1472
" ..A... = Audio codec\n"
1473
" ..S... = Subtitle codec\n"
1474
" ...I.. = Intra frame-only codec\n"
1475
" ....L. = Lossy compression\n"
1476
" .....S = Lossless compression\n"
1477
" -------\n");
1478
for (i = 0; i < nb_codecs; i++) {
1479
const AVCodecDescriptor *desc = codecs[i];
1480
const AVCodec *codec = NULL;
1481
1482
if (strstr(desc->name, "_deprecated"))
1483
continue;
1484
1485
printf(" ");
1486
printf(avcodec_find_decoder(desc->id) ? "D" : ".");
1487
printf(avcodec_find_encoder(desc->id) ? "E" : ".");
1488
1489
printf("%c", get_media_type_char(desc->type));
1490
printf((desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
1491
printf((desc->props & AV_CODEC_PROP_LOSSY) ? "L" : ".");
1492
printf((desc->props & AV_CODEC_PROP_LOSSLESS) ? "S" : ".");
1493
1494
printf(" %-20s %s", desc->name, desc->long_name ? desc->long_name : "");
1495
1496
/* print decoders/encoders when there's more than one or their
1497
* names are different from codec name */
1498
while ((codec = next_codec_for_id(desc->id, codec, 0))) {
1499
if (strcmp(codec->name, desc->name)) {
1500
print_codecs_for_id(desc->id, 0);
1501
break;
1502
}
1503
}
1504
codec = NULL;
1505
while ((codec = next_codec_for_id(desc->id, codec, 1))) {
1506
if (strcmp(codec->name, desc->name)) {
1507
print_codecs_for_id(desc->id, 1);
1508
break;
1509
}
1510
}
1511
1512
printf("\n");
1513
}
1514
av_free(codecs);
1515
return 0;
1516
}
1517
1518
static void print_codecs(int encoder)
1519
{
1520
const AVCodecDescriptor **codecs;
1521
unsigned i, nb_codecs = get_codecs_sorted(&codecs);
1522
1523
printf("%s:\n"
1524
" V..... = Video\n"
1525
" A..... = Audio\n"
1526
" S..... = Subtitle\n"
1527
" .F.... = Frame-level multithreading\n"
1528
" ..S... = Slice-level multithreading\n"
1529
" ...X.. = Codec is experimental\n"
1530
" ....B. = Supports draw_horiz_band\n"
1531
" .....D = Supports direct rendering method 1\n"
1532
" ------\n",
1533
encoder ? "Encoders" : "Decoders");
1534
for (i = 0; i < nb_codecs; i++) {
1535
const AVCodecDescriptor *desc = codecs[i];
1536
const AVCodec *codec = NULL;
1537
1538
while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
1539
printf(" %c", get_media_type_char(desc->type));
1540
printf((codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
1541
printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
1542
printf((codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) ? "X" : ".");
1543
printf((codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
1544
printf((codec->capabilities & AV_CODEC_CAP_DR1) ? "D" : ".");
1545
1546
printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
1547
if (strcmp(codec->name, desc->name))
1548
printf(" (codec %s)", desc->name);
1549
1550
printf("\n");
1551
}
1552
}
1553
av_free(codecs);
1554
}
1555
1556
int show_decoders(void *optctx, const char *opt, const char *arg)
1557
{
1558
print_codecs(0);
1559
return 0;
1560
}
1561
1562
int show_encoders(void *optctx, const char *opt, const char *arg)
1563
{
1564
print_codecs(1);
1565
return 0;
1566
}
1567
1568
int show_bsfs(void *optctx, const char *opt, const char *arg)
1569
{
1570
AVBitStreamFilter *bsf = NULL;
1571
1572
printf("Bitstream filters:\n");
1573
while ((bsf = av_bitstream_filter_next(bsf)))
1574
printf("%s\n", bsf->name);
1575
printf("\n");
1576
return 0;
1577
}
1578
1579
int show_protocols(void *optctx, const char *opt, const char *arg)
1580
{
1581
void *opaque = NULL;
1582
const char *name;
1583
1584
printf("Supported file protocols:\n"
1585
"Input:\n");
1586
while ((name = avio_enum_protocols(&opaque, 0)))
1587
printf(" %s\n", name);
1588
printf("Output:\n");
1589
while ((name = avio_enum_protocols(&opaque, 1)))
1590
printf(" %s\n", name);
1591
return 0;
1592
}
1593
1594
int show_filters(void *optctx, const char *opt, const char *arg)
1595
{
1596
#if CONFIG_AVFILTER
1597
const AVFilter *filter = NULL;
1598
char descr[64], *descr_cur;
1599
int i, j;
1600
const AVFilterPad *pad;
1601
1602
printf("Filters:\n"
1603
" T.. = Timeline support\n"
1604
" .S. = Slice threading\n"
1605
" ..C = Command support\n"
1606
" A = Audio input/output\n"
1607
" V = Video input/output\n"
1608
" N = Dynamic number and/or type of input/output\n"
1609
" | = Source or sink filter\n");
1610
while ((filter = avfilter_next(filter))) {
1611
descr_cur = descr;
1612
for (i = 0; i < 2; i++) {
1613
if (i) {
1614
*(descr_cur++) = '-';
1615
*(descr_cur++) = '>';
1616
}
1617
pad = i ? filter->outputs : filter->inputs;
1618
for (j = 0; pad && avfilter_pad_get_name(pad, j); j++) {
1619
if (descr_cur >= descr + sizeof(descr) - 4)
1620
break;
1621
*(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j));
1622
}
1623
if (!j)
1624
*(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||
1625
( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';
1626
}
1627
*descr_cur = 0;
1628
printf(" %c%c%c %-17s %-10s %s\n",
1629
filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',
1630
filter->flags & AVFILTER_FLAG_SLICE_THREADS ? 'S' : '.',
1631
filter->process_command ? 'C' : '.',
1632
filter->name, descr, filter->description);
1633
}
1634
#else
1635
printf("No filters available: libavfilter disabled\n");
1636
#endif
1637
return 0;
1638
}
1639
1640
int show_colors(void *optctx, const char *opt, const char *arg)
1641
{
1642
const char *name;
1643
const uint8_t *rgb;
1644
int i;
1645
1646
printf("%-32s #RRGGBB\n", "name");
1647
1648
for (i = 0; name = av_get_known_color_name(i, &rgb); i++)
1649
printf("%-32s #%02x%02x%02x\n", name, rgb[0], rgb[1], rgb[2]);
1650
1651
return 0;
1652
}
1653
1654
int show_pix_fmts(void *optctx, const char *opt, const char *arg)
1655
{
1656
const AVPixFmtDescriptor *pix_desc = NULL;
1657
1658
printf("Pixel formats:\n"
1659
"I.... = Supported Input format for conversion\n"
1660
".O... = Supported Output format for conversion\n"
1661
"..H.. = Hardware accelerated format\n"
1662
"...P. = Paletted format\n"
1663
"....B = Bitstream format\n"
1664
"FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
1665
"-----\n");
1666
1667
#if !CONFIG_SWSCALE
1668
# define sws_isSupportedInput(x) 0
1669
# define sws_isSupportedOutput(x) 0
1670
#endif
1671
1672
while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
1673
enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
1674
printf("%c%c%c%c%c %-16s %d %2d\n",
1675
sws_isSupportedInput (pix_fmt) ? 'I' : '.',
1676
sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
1677
pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL ? 'H' : '.',
1678
pix_desc->flags & AV_PIX_FMT_FLAG_PAL ? 'P' : '.',
1679
pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
1680
pix_desc->name,
1681
pix_desc->nb_components,
1682
av_get_bits_per_pixel(pix_desc));
1683
}
1684
return 0;
1685
}
1686
1687
int show_layouts(void *optctx, const char *opt, const char *arg)
1688
{
1689
int i = 0;
1690
uint64_t layout, j;
1691
const char *name, *descr;
1692
1693
printf("Individual channels:\n"
1694
"NAME DESCRIPTION\n");
1695
for (i = 0; i < 63; i++) {
1696
name = av_get_channel_name((uint64_t)1 << i);
1697
if (!name)
1698
continue;
1699
descr = av_get_channel_description((uint64_t)1 << i);
1700
printf("%-14s %s\n", name, descr);
1701
}
1702
printf("\nStandard channel layouts:\n"
1703
"NAME DECOMPOSITION\n");
1704
for (i = 0; !av_get_standard_channel_layout(i, &layout, &name); i++) {
1705
if (name) {
1706
printf("%-14s ", name);
1707
for (j = 1; j; j <<= 1)
1708
if ((layout & j))
1709
printf("%s%s", (layout & (j - 1)) ? "+" : "", av_get_channel_name(j));
1710
printf("\n");
1711
}
1712
}
1713
return 0;
1714
}
1715
1716
int show_sample_fmts(void *optctx, const char *opt, const char *arg)
1717
{
1718
int i;
1719
char fmt_str[128];
1720
for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
1721
printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
1722
return 0;
1723
}
1724
1725
static void show_help_codec(const char *name, int encoder)
1726
{
1727
const AVCodecDescriptor *desc;
1728
const AVCodec *codec;
1729
1730
if (!name) {
1731
av_log(NULL, AV_LOG_ERROR, "No codec name specified.\n");
1732
return;
1733
}
1734
1735
codec = encoder ? avcodec_find_encoder_by_name(name) :
1736
avcodec_find_decoder_by_name(name);
1737
1738
if (codec)
1739
print_codec(codec);
1740
else if ((desc = avcodec_descriptor_get_by_name(name))) {
1741
int printed = 0;
1742
1743
while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
1744
printed = 1;
1745
print_codec(codec);
1746
}
1747
1748
if (!printed) {
1749
av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to FFmpeg, "
1750
"but no %s for it are available. FFmpeg might need to be "
1751
"recompiled with additional external libraries.\n",
1752
name, encoder ? "encoders" : "decoders");
1753
}
1754
} else {
1755
av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by FFmpeg.\n",
1756
name);
1757
}
1758
}
1759
1760
static void show_help_demuxer(const char *name)
1761
{
1762
const AVInputFormat *fmt = av_find_input_format(name);
1763
1764
if (!fmt) {
1765
av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
1766
return;
1767
}
1768
1769
printf("Demuxer %s [%s]:\n", fmt->name, fmt->long_name);
1770
1771
if (fmt->extensions)
1772
printf(" Common extensions: %s.\n", fmt->extensions);
1773
1774
if (fmt->priv_class)
1775
show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM);
1776
}
1777
1778
static void show_help_muxer(const char *name)
1779
{
1780
const AVCodecDescriptor *desc;
1781
const AVOutputFormat *fmt = av_guess_format(name, NULL, NULL);
1782
1783
if (!fmt) {
1784
av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
1785
return;
1786
}
1787
1788
printf("Muxer %s [%s]:\n", fmt->name, fmt->long_name);
1789
1790
if (fmt->extensions)
1791
printf(" Common extensions: %s.\n", fmt->extensions);
1792
if (fmt->mime_type)
1793
printf(" Mime type: %s.\n", fmt->mime_type);
1794
if (fmt->video_codec != AV_CODEC_ID_NONE &&
1795
(desc = avcodec_descriptor_get(fmt->video_codec))) {
1796
printf(" Default video codec: %s.\n", desc->name);
1797
}
1798
if (fmt->audio_codec != AV_CODEC_ID_NONE &&
1799
(desc = avcodec_descriptor_get(fmt->audio_codec))) {
1800
printf(" Default audio codec: %s.\n", desc->name);
1801
}
1802
if (fmt->subtitle_codec != AV_CODEC_ID_NONE &&
1803
(desc = avcodec_descriptor_get(fmt->subtitle_codec))) {
1804
printf(" Default subtitle codec: %s.\n", desc->name);
1805
}
1806
1807
if (fmt->priv_class)
1808
show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM);
1809
}
1810
1811
#if CONFIG_AVFILTER
1812
static void show_help_filter(const char *name)
1813
{
1814
#if CONFIG_AVFILTER
1815
const AVFilter *f = avfilter_get_by_name(name);
1816
int i, count;
1817
1818
if (!name) {
1819
av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
1820
return;
1821
} else if (!f) {
1822
av_log(NULL, AV_LOG_ERROR, "Unknown filter '%s'.\n", name);
1823
return;
1824
}
1825
1826
printf("Filter %s\n", f->name);
1827
if (f->description)
1828
printf(" %s\n", f->description);
1829
1830
if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
1831
printf(" slice threading supported\n");
1832
1833
printf(" Inputs:\n");
1834
count = avfilter_pad_count(f->inputs);
1835
for (i = 0; i < count; i++) {
1836
printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
1837
media_type_string(avfilter_pad_get_type(f->inputs, i)));
1838
}
1839
if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
1840
printf(" dynamic (depending on the options)\n");
1841
else if (!count)
1842
printf(" none (source filter)\n");
1843
1844
printf(" Outputs:\n");
1845
count = avfilter_pad_count(f->outputs);
1846
for (i = 0; i < count; i++) {
1847
printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
1848
media_type_string(avfilter_pad_get_type(f->outputs, i)));
1849
}
1850
if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
1851
printf(" dynamic (depending on the options)\n");
1852
else if (!count)
1853
printf(" none (sink filter)\n");
1854
1855
if (f->priv_class)
1856
show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM |
1857
AV_OPT_FLAG_AUDIO_PARAM);
1858
if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)
1859
printf("This filter has support for timeline through the 'enable' option.\n");
1860
#else
1861
av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; "
1862
"can not to satisfy request\n");
1863
#endif
1864
}
1865
#endif
1866
1867
int show_help(void *optctx, const char *opt, const char *arg)
1868
{
1869
char *topic, *par;
1870
av_log_set_callback(log_callback_help);
1871
1872
topic = av_strdup(arg ? arg : "");
1873
if (!topic)
1874
return AVERROR(ENOMEM);
1875
par = strchr(topic, '=');
1876
if (par)
1877
*par++ = 0;
1878
1879
if (!*topic) {
1880
show_help_default(topic, par);
1881
} else if (!strcmp(topic, "decoder")) {
1882
show_help_codec(par, 0);
1883
} else if (!strcmp(topic, "encoder")) {
1884
show_help_codec(par, 1);
1885
} else if (!strcmp(topic, "demuxer")) {
1886
show_help_demuxer(par);
1887
} else if (!strcmp(topic, "muxer")) {
1888
show_help_muxer(par);
1889
#if CONFIG_AVFILTER
1890
} else if (!strcmp(topic, "filter")) {
1891
show_help_filter(par);
1892
#endif
1893
} else {
1894
show_help_default(topic, par);
1895
}
1896
1897
av_freep(&topic);
1898
return 0;
1899
}
1900
1901
int read_yesno(void)
1902
{
1903
int c = getchar();
1904
int yesno = (av_toupper(c) == 'Y');
1905
1906
while (c != '\n' && c != EOF)
1907
c = getchar();
1908
1909
return yesno;
1910
}
1911
1912
FILE *get_preset_file(char *filename, size_t filename_size,
1913
const char *preset_name, int is_path,
1914
const char *codec_name)
1915
{
1916
FILE *f = NULL;
1917
int i;
1918
const char *base[3] = { getenv("FFMPEG_DATADIR"),
1919
getenv("HOME"),
1920
FFMPEG_DATADIR, };
1921
1922
if (is_path) {
1923
av_strlcpy(filename, preset_name, filename_size);
1924
f = fopen(filename, "r");
1925
} else {
1926
#ifdef _WIN32
1927
char datadir[MAX_PATH], *ls;
1928
base[2] = NULL;
1929
1930
if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
1931
{
1932
for (ls = datadir; ls < datadir + strlen(datadir); ls++)
1933
if (*ls == '\\') *ls = '/';
1934
1935
if (ls = strrchr(datadir, '/'))
1936
{
1937
*ls = 0;
1938
strncat(datadir, "/ffpresets", sizeof(datadir) - 1 - strlen(datadir));
1939
base[2] = datadir;
1940
}
1941
}
1942
#endif
1943
for (i = 0; i < 3 && !f; i++) {
1944
if (!base[i])
1945
continue;
1946
snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
1947
i != 1 ? "" : "/.ffmpeg", preset_name);
1948
f = fopen(filename, "r");
1949
if (!f && codec_name) {
1950
snprintf(filename, filename_size,
1951
"%s%s/%s-%s.ffpreset",
1952
base[i], i != 1 ? "" : "/.ffmpeg", codec_name,
1953
preset_name);
1954
f = fopen(filename, "r");
1955
}
1956
}
1957
}
1958
1959
return f;
1960
}
1961
1962
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
1963
{
1964
int ret = avformat_match_stream_specifier(s, st, spec);
1965
if (ret < 0)
1966
av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
1967
return ret;
1968
}
1969
1970
AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
1971
AVFormatContext *s, AVStream *st, AVCodec *codec)
1972
{
1973
AVDictionary *ret = NULL;
1974
AVDictionaryEntry *t = NULL;
1975
int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
1976
: AV_OPT_FLAG_DECODING_PARAM;
1977
char prefix = 0;
1978
const AVClass *cc = avcodec_get_class();
1979
1980
if (!codec)
1981
codec = s->oformat ? avcodec_find_encoder(codec_id)
1982
: avcodec_find_decoder(codec_id);
1983
1984
switch (st->codec->codec_type) {
1985
case AVMEDIA_TYPE_VIDEO:
1986
prefix = 'v';
1987
flags |= AV_OPT_FLAG_VIDEO_PARAM;
1988
break;
1989
case AVMEDIA_TYPE_AUDIO:
1990
prefix = 'a';
1991
flags |= AV_OPT_FLAG_AUDIO_PARAM;
1992
break;
1993
case AVMEDIA_TYPE_SUBTITLE:
1994
prefix = 's';
1995
flags |= AV_OPT_FLAG_SUBTITLE_PARAM;
1996
break;
1997
}
1998
1999
while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
2000
char *p = strchr(t->key, ':');
2001
2002
/* check stream specification in opt name */
2003
if (p)
2004
switch (check_stream_specifier(s, st, p + 1)) {
2005
case 1: *p = 0; break;
2006
case 0: continue;
2007
default: exit_program(1);
2008
}
2009
2010
if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
2011
!codec ||
2012
(codec->priv_class &&
2013
av_opt_find(&codec->priv_class, t->key, NULL, flags,
2014
AV_OPT_SEARCH_FAKE_OBJ)))
2015
av_dict_set(&ret, t->key, t->value, 0);
2016
else if (t->key[0] == prefix &&
2017
av_opt_find(&cc, t->key + 1, NULL, flags,
2018
AV_OPT_SEARCH_FAKE_OBJ))
2019
av_dict_set(&ret, t->key + 1, t->value, 0);
2020
2021
if (p)
2022
*p = ':';
2023
}
2024
return ret;
2025
}
2026
2027
AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
2028
AVDictionary *codec_opts)
2029
{
2030
int i;
2031
AVDictionary **opts;
2032
2033
if (!s->nb_streams)
2034
return NULL;
2035
opts = av_mallocz_array(s->nb_streams, sizeof(*opts));
2036
if (!opts) {
2037
av_log(NULL, AV_LOG_ERROR,
2038
"Could not alloc memory for stream options.\n");
2039
return NULL;
2040
}
2041
for (i = 0; i < s->nb_streams; i++)
2042
opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id,
2043
s, s->streams[i], NULL);
2044
return opts;
2045
}
2046
2047
void *grow_array(void *array, int elem_size, int *size, int new_size)
2048
{
2049
if (new_size >= INT_MAX / elem_size) {
2050
av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
2051
exit_program(1);
2052
}
2053
if (*size < new_size) {
2054
uint8_t *tmp = av_realloc_array(array, new_size, elem_size);
2055
if (!tmp) {
2056
av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
2057
exit_program(1);
2058
}
2059
memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
2060
*size = new_size;
2061
return tmp;
2062
}
2063
return array;
2064
}
2065
2066
double get_rotation(AVStream *st)
2067
{
2068
AVDictionaryEntry *rotate_tag = av_dict_get(st->metadata, "rotate", NULL, 0);
2069
uint8_t* displaymatrix = av_stream_get_side_data(st,
2070
AV_PKT_DATA_DISPLAYMATRIX, NULL);
2071
double theta = 0;
2072
2073
if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
2074
char *tail;
2075
theta = av_strtod(rotate_tag->value, &tail);
2076
if (*tail)
2077
theta = 0;
2078
}
2079
if (displaymatrix && !theta)
2080
theta = -av_display_rotation_get((int32_t*) displaymatrix);
2081
2082
theta -= 360*floor(theta/360 + 0.9/360);
2083
2084
if (fabs(theta - 90*round(theta/90)) > 2)
2085
av_log(NULL, AV_LOG_WARNING, "Odd rotation angle.\n"
2086
"If you want to help, upload a sample "
2087
"of this file to ftp://upload.ffmpeg.org/incoming/ "
2088
"and contact the ffmpeg-devel mailing list. ([email protected])");
2089
2090
return theta;
2091
}
2092
2093
#if CONFIG_AVDEVICE
2094
static int print_device_sources(AVInputFormat *fmt, AVDictionary *opts)
2095
{
2096
int ret, i;
2097
AVDeviceInfoList *device_list = NULL;
2098
2099
if (!fmt || !fmt->priv_class || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
2100
return AVERROR(EINVAL);
2101
2102
printf("Audo-detected sources for %s:\n", fmt->name);
2103
if (!fmt->get_device_list) {
2104
ret = AVERROR(ENOSYS);
2105
printf("Cannot list sources. Not implemented.\n");
2106
goto fail;
2107
}
2108
2109
if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
2110
printf("Cannot list sources.\n");
2111
goto fail;
2112
}
2113
2114
for (i = 0; i < device_list->nb_devices; i++) {
2115
printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
2116
device_list->devices[i]->device_name, device_list->devices[i]->device_description);
2117
}
2118
2119
fail:
2120
avdevice_free_list_devices(&device_list);
2121
return ret;
2122
}
2123
2124
static int print_device_sinks(AVOutputFormat *fmt, AVDictionary *opts)
2125
{
2126
int ret, i;
2127
AVDeviceInfoList *device_list = NULL;
2128
2129
if (!fmt || !fmt->priv_class || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
2130
return AVERROR(EINVAL);
2131
2132
printf("Audo-detected sinks for %s:\n", fmt->name);
2133
if (!fmt->get_device_list) {
2134
ret = AVERROR(ENOSYS);
2135
printf("Cannot list sinks. Not implemented.\n");
2136
goto fail;
2137
}
2138
2139
if ((ret = avdevice_list_output_sinks(fmt, NULL, opts, &device_list)) < 0) {
2140
printf("Cannot list sinks.\n");
2141
goto fail;
2142
}
2143
2144
for (i = 0; i < device_list->nb_devices; i++) {
2145
printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
2146
device_list->devices[i]->device_name, device_list->devices[i]->device_description);
2147
}
2148
2149
fail:
2150
avdevice_free_list_devices(&device_list);
2151
return ret;
2152
}
2153
2154
static int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionary **opts)
2155
{
2156
int ret;
2157
if (arg) {
2158
char *opts_str = NULL;
2159
av_assert0(dev && opts);
2160
*dev = av_strdup(arg);
2161
if (!*dev)
2162
return AVERROR(ENOMEM);
2163
if ((opts_str = strchr(*dev, ','))) {
2164
*(opts_str++) = '\0';
2165
if (opts_str[0] && ((ret = av_dict_parse_string(opts, opts_str, "=", ":", 0)) < 0)) {
2166
av_freep(dev);
2167
return ret;
2168
}
2169
}
2170
} else
2171
printf("\nDevice name is not provided.\n"
2172
"You can pass devicename[,opt1=val1[,opt2=val2...]] as an argument.\n\n");
2173
return 0;
2174
}
2175
2176
int show_sources(void *optctx, const char *opt, const char *arg)
2177
{
2178
AVInputFormat *fmt = NULL;
2179
char *dev = NULL;
2180
AVDictionary *opts = NULL;
2181
int ret = 0;
2182
int error_level = av_log_get_level();
2183
2184
av_log_set_level(AV_LOG_ERROR);
2185
2186
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
2187
goto fail;
2188
2189
do {
2190
fmt = av_input_audio_device_next(fmt);
2191
if (fmt) {
2192
if (!strcmp(fmt->name, "lavfi"))
2193
continue; //it's pointless to probe lavfi
2194
if (dev && !av_match_name(dev, fmt->name))
2195
continue;
2196
print_device_sources(fmt, opts);
2197
}
2198
} while (fmt);
2199
do {
2200
fmt = av_input_video_device_next(fmt);
2201
if (fmt) {
2202
if (dev && !av_match_name(dev, fmt->name))
2203
continue;
2204
print_device_sources(fmt, opts);
2205
}
2206
} while (fmt);
2207
fail:
2208
av_dict_free(&opts);
2209
av_free(dev);
2210
av_log_set_level(error_level);
2211
return ret;
2212
}
2213
2214
int show_sinks(void *optctx, const char *opt, const char *arg)
2215
{
2216
AVOutputFormat *fmt = NULL;
2217
char *dev = NULL;
2218
AVDictionary *opts = NULL;
2219
int ret = 0;
2220
int error_level = av_log_get_level();
2221
2222
av_log_set_level(AV_LOG_ERROR);
2223
2224
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
2225
goto fail;
2226
2227
do {
2228
fmt = av_output_audio_device_next(fmt);
2229
if (fmt) {
2230
if (dev && !av_match_name(dev, fmt->name))
2231
continue;
2232
print_device_sinks(fmt, opts);
2233
}
2234
} while (fmt);
2235
do {
2236
fmt = av_output_video_device_next(fmt);
2237
if (fmt) {
2238
if (dev && !av_match_name(dev, fmt->name))
2239
continue;
2240
print_device_sinks(fmt, opts);
2241
}
2242
} while (fmt);
2243
fail:
2244
av_dict_free(&opts);
2245
av_free(dev);
2246
av_log_set_level(error_level);
2247
return ret;
2248
}
2249
2250
#endif
2251
2252