81#include "libavformat/avformat.h"
82#include "libswscale/swscale.h"
83#include "libswresample/swresample.h"
84#include "libavutil/avassert.h"
85#include "libavutil/avstring.h"
86#include "libavutil/channel_layout.h"
87#include "libavutil/display.h"
88#include "libavutil/getenv_utf8.h"
89#include "libavutil/mathematics.h"
90#include "libavutil/imgutils.h"
91#include "libavutil/libm.h"
92#include "libavutil/parseutils.h"
93#include "libavutil/eval.h"
94#include "libavutil/dict.h"
95#include "libavutil/opt.h"
102#include "compat/w32dlfcn.h"
125#if HAVE_SETDLLDIRECTORY && defined(_WIN32)
141 av_log(NULL, AV_LOG_FATAL,
"%s\n", av_err2str(ret));
158 double min,
double max)
162 double d = av_strtod(numstr, &tail);
164 error =
"Expected number for %s but found: %s\n";
165 else if (d < min || d > max)
166 error =
"The value for %s was %s which is not within %f - %f\n";
168 error =
"Expected int64 for %s but found %s\n";
170 error =
"Expected int for %s but found %s\n";
173 av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
182 if (av_parse_time(&us, timestr, is_duration) < 0) {
183 av_log(NULL, AV_LOG_FATAL,
"Invalid %s specification for %s: %s\n",
184 is_duration ?
"duration" :
"date", context, timestr);
191 int rej_flags,
int alt_flags)
197 for (po = options; po->
name; po++) {
200 if (((po->
flags & req_flags) != req_flags) ||
201 (alt_flags && !(po->
flags & alt_flags)) ||
202 (po->
flags & rej_flags))
209 av_strlcpy(buf, po->
name,
sizeof(buf));
211 av_strlcat(buf,
" ",
sizeof(buf));
212 av_strlcat(buf, po->
argname,
sizeof(buf));
222 const AVClass *child;
224 av_opt_show2(&
class, NULL, flags, 0);
228 while ((child = av_opt_child_class_iterate(
class, &iter)))
236 if (av_strstart(name, po->
name, &end) && (!*end || *end ==
':'))
246#if HAVE_COMMANDLINETOARGVW && defined(_WIN32)
249static char** win32_argv_utf8 = NULL;
250static int win32_argc = 0;
263 int i, buffsize = 0, offset = 0;
265 if (win32_argv_utf8) {
266 *argc_ptr = win32_argc;
267 *argv_ptr = win32_argv_utf8;
272 argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
273 if (win32_argc <= 0 || !argv_w)
277 for (i = 0; i < win32_argc; i++)
278 buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
279 NULL, 0, NULL, NULL);
281 win32_argv_utf8 = av_mallocz(
sizeof(
char *) * (win32_argc + 1) + buffsize);
282 argstr_flat = (
char *)win32_argv_utf8 +
sizeof(
char *) * (win32_argc + 1);
283 if (!win32_argv_utf8) {
288 for (i = 0; i < win32_argc; i++) {
289 win32_argv_utf8[i] = &argstr_flat[offset];
290 offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
291 &argstr_flat[offset],
292 buffsize - offset, NULL, NULL);
294 win32_argv_utf8[i] = NULL;
297 *argc_ptr = win32_argc;
298 *argv_ptr = win32_argv_utf8;
318 char *p = strchr(opt,
':');
321 dstcount = (
int *)(so + 1);
322 *so =
grow_array(*so,
sizeof(**so), dstcount, *dstcount + 1);
323 str = av_strdup(p ? p + 1 :
"");
325 return AVERROR(ENOMEM);
326 (*so)[*dstcount - 1].specifier = str;
327 dst = &(*so)[*dstcount - 1].u;
332 str = av_strdup(arg);
335 return AVERROR(ENOMEM);
348 int ret = po->
u.
func_arg(optctx, opt, arg);
350 av_log(NULL, AV_LOG_ERROR,
351 "Failed to set value '%s' for option '%s': %s\n",
352 arg, opt, av_err2str(ret));
366 .
name =
"AVOption passthrough",
375 if (!po->
name && opt[0] ==
'n' && opt[1] ==
'o') {
386 av_log(NULL, AV_LOG_ERROR,
"Unrecognized option '%s'\n", opt);
387 return AVERROR(EINVAL);
390 av_log(NULL, AV_LOG_ERROR,
"Missing argument for option '%s'\n", opt);
391 return AVERROR(EINVAL);
402 void (*parse_arg_function)(
void *,
const char*))
405 int optindex, handleoptions = 1, ret;
412 while (optindex < argc) {
413 opt = argv[optindex++];
415 if (handleoptions && opt[0] ==
'-' && opt[1] !=
'\0') {
416 if (opt[1] ==
'-' && opt[2] ==
'\0') {
421 if (optindex >= argc) {
422 if ((ret =
parse_option(optctx, opt, NULL, options)) < 0)
425 if ((ret =
parse_option(optctx, opt, argv[optindex], options)) < 0)
430 if (parse_arg_function)
431 parse_arg_function(optctx, opt);
440 av_log(NULL, AV_LOG_DEBUG,
"Parsing a group of options: %s %s.\n",
443 for (i = 0; i < g->
nb_opts; i++) {
448 av_log(NULL, AV_LOG_ERROR,
"Option %s (%s) cannot be applied to "
449 "%s %s -- you are trying to apply an input option to an "
450 "output file or vice versa. Move this option before the "
451 "file it belongs to.\n", o->
key, o->
opt->
help,
453 return AVERROR(EINVAL);
456 av_log(NULL, AV_LOG_DEBUG,
"Applying option %s (%s) with argument %s.\n",
464 av_log(NULL, AV_LOG_DEBUG,
"Successfully parsed a group of options.\n");
475 for (i = 1; i < argc; i++) {
476 const char *cur_opt = argv[i];
478 if (*cur_opt++ !=
'-')
482 if (!po->
name && cur_opt[0] ==
'n' && cur_opt[1] ==
'o')
485 if ((!po->
name && !strcmp(cur_opt, optname)) ||
486 (po->
name && !strcmp(optname, po->
name)))
497 const unsigned char *p;
500 if (!((*p >=
'+' && *p <=
':') || (*p >=
'@' && *p <=
'Z') ||
501 *p ==
'_' || (*p >=
'a' && *p <=
'z')))
508 for (p = a; *p; p++) {
509 if (*p ==
'\\' || *p ==
'"' || *p ==
'$' || *p ==
'`')
511 else if (*p <
' ' || *p >
'~')
537 if (idx && (idx + 1 < argc) && argv[idx + 1])
540 env = getenv_utf8(
"FFREPORT");
547 for (i = 0; i < argc; i++) {
560static const AVOption *
opt_find(
void *obj,
const char *name,
const char *unit,
561 int opt_flags,
int search_flags)
563 const AVOption *o = av_opt_find(obj, name, unit, opt_flags, search_flags);
569#define FLAGS (o->type == AV_OPT_TYPE_FLAGS && (arg[0]=='-' || arg[0]=='+')) ? AV_DICT_APPEND : 0
574 char opt_stripped[128];
576 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();
578 const AVClass *sc = sws_get_class();
581 const AVClass *swr_class = swr_get_class();
584 if (!strcmp(opt,
"debug") || !strcmp(opt,
"fdebug"))
585 av_log_set_level(AV_LOG_DEBUG);
587 if (!(p = strchr(opt,
':')))
588 p = opt + strlen(opt);
589 av_strlcpy(opt_stripped, opt, FFMIN(
sizeof(opt_stripped), p - opt + 1));
591 if ((o =
opt_find(&cc, opt_stripped, NULL, 0,
592 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
593 ((opt[0] ==
'v' || opt[0] ==
'a' || opt[0] ==
's') &&
594 (o =
opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)))) {
598 if ((o =
opt_find(&fc, opt, NULL, 0,
599 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
602 av_log(NULL, AV_LOG_VERBOSE,
"Routing option %s to both codec and muxer layer\n", opt);
606 if (!consumed && (o =
opt_find(&sc, opt, NULL, 0,
607 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
608 if (!strcmp(opt,
"srcw") || !strcmp(opt,
"srch") ||
609 !strcmp(opt,
"dstw") || !strcmp(opt,
"dsth") ||
610 !strcmp(opt,
"src_format") || !strcmp(opt,
"dst_format")) {
611 av_log(NULL, AV_LOG_ERROR,
"Directly using swscale dimensions/format options is not supported, please use the -s or -pix_fmt options\n");
612 return AVERROR(EINVAL);
619 if (!consumed && !strcmp(opt,
"sws_flags")) {
620 av_log(NULL, AV_LOG_WARNING,
"Ignoring %s %s, due to disabled swscale\n", opt, arg);
625 if (!consumed && (o=
opt_find(&swr_class, opt, NULL, 0,
626 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
634 return AVERROR_OPTION_NOT_FOUND;
647 for (i = 0; i < nb_groups; i++) {
649 if (p->
sep && !strcmp(p->
sep, opt))
691 const char *key,
const char *val)
708 memset(octx, 0,
sizeof(*octx));
758 av_log(NULL, AV_LOG_DEBUG,
"Splitting the commandline.\n");
760 while (optindex < argc) {
761 const char *opt = argv[optindex++], *arg;
765 av_log(NULL, AV_LOG_DEBUG,
"Reading option '%s' ...", opt);
767 if (opt[0] ==
'-' && opt[1] ==
'-' && !opt[2]) {
772 if (opt[0] !=
'-' || !opt[1] || dashdash+1 == optindex) {
774 av_log(NULL, AV_LOG_DEBUG,
" matched as %s.\n",
groups[0].name);
779#define GET_ARG(arg) \
781 if (optindex < argc) { \
782 arg = argv[optindex++]; \
784 av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'.\n", opt);\
785 return AVERROR(EINVAL); \
793 av_log(NULL, AV_LOG_DEBUG,
" matched as %s with argument '%s'.\n",
803 if (optindex < argc) {
804 arg = argv[optindex++];
815 av_log(NULL, AV_LOG_DEBUG,
" matched as option '%s' (%s) with "
816 "argument '%s'.\n", po->
name, po->
help, arg);
821 if ((optindex < argc) && argv[optindex]) {
824 av_log(NULL, AV_LOG_DEBUG,
" matched as AVOption '%s' with "
825 "argument '%s'.\n", opt, argv[optindex]);
828 }
else if (ret != AVERROR_OPTION_NOT_FOUND) {
829 av_log(NULL, AV_LOG_ERROR,
"Error parsing option '%s' "
830 "with argument '%s'.\n", opt, argv[optindex]);
836 if (opt[0] ==
'n' && opt[1] ==
'o' &&
840 av_log(NULL, AV_LOG_DEBUG,
" matched as option '%s' (%s) with "
841 "argument 0.\n", po->
name, po->
help);
845 av_log(NULL, AV_LOG_ERROR,
"Unrecognized option '%s'.\n", opt);
846 return AVERROR_OPTION_NOT_FOUND;
850 av_log(NULL, AV_LOG_WARNING,
"Trailing option(s) found in the "
851 "command: may be ignored.\n");
853 av_log(NULL, AV_LOG_DEBUG,
"Finished splitting the commandline.\n");
860 av_log(NULL, AV_LOG_ERROR,
"%s: %s\n", filename, av_err2str(err));
866 int yesno = (av_toupper(c) ==
'Y');
868 while (c !=
'\n' && c != EOF)
875 const char *preset_name,
int is_path,
876 const char *codec_name)
880#if HAVE_GETMODULEHANDLE && defined(_WIN32)
881 char *datadir = NULL;
883 char *env_home = getenv_utf8(
"HOME");
884 char *env_ffmpeg_datadir = getenv_utf8(
"FFMPEG_DATADIR");
885 const char *base[3] = { env_ffmpeg_datadir,
890 av_strlcpy(filename, preset_name, filename_size);
893#if HAVE_GETMODULEHANDLE && defined(_WIN32)
894 wchar_t *datadir_w = get_module_filename(NULL);
897 if (wchartoutf8(datadir_w, &datadir))
904 for (ls = datadir; *ls; ls++)
905 if (*ls ==
'\\') *ls =
'/';
907 if (ls = strrchr(datadir,
'/'))
909 ptrdiff_t datadir_len = ls - datadir;
910 size_t desired_size = datadir_len + strlen(
"/ffpresets") + 1;
911 char *new_datadir = av_realloc_array(
912 datadir, desired_size,
sizeof *datadir);
914 datadir = new_datadir;
915 datadir[datadir_len] = 0;
916 strncat(datadir,
"/ffpresets", desired_size - 1 - datadir_len);
922 for (i = 0; i < 3 && !f; i++) {
925 snprintf(filename, filename_size,
"%s%s/%s.ffpreset", base[i],
926 i != 1 ?
"" :
"/.ffmpeg", preset_name);
928 if (!f && codec_name) {
929 snprintf(filename, filename_size,
930 "%s%s/%s-%s.ffpreset",
931 base[i], i != 1 ?
"" :
"/.ffmpeg", codec_name,
938#if HAVE_GETMODULEHANDLE && defined(_WIN32)
941 freeenv_utf8(env_ffmpeg_datadir);
942 freeenv_utf8(env_home);
948 int ret = avformat_match_stream_specifier(s, st, spec);
950 av_log(s, AV_LOG_ERROR,
"Invalid stream specifier: %s.\n", spec);
955 AVFormatContext *s, AVStream *st,
const AVCodec *codec)
957 AVDictionary *ret = NULL;
958 const AVDictionaryEntry *t = NULL;
959 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
960 : AV_OPT_FLAG_DECODING_PARAM;
962 const AVClass *cc = avcodec_get_class();
965 codec = s->oformat ? avcodec_find_encoder(codec_id)
966 : avcodec_find_decoder(codec_id);
968 switch (st->codecpar->codec_type) {
969 case AVMEDIA_TYPE_VIDEO:
971 flags |= AV_OPT_FLAG_VIDEO_PARAM;
973 case AVMEDIA_TYPE_AUDIO:
975 flags |= AV_OPT_FLAG_AUDIO_PARAM;
977 case AVMEDIA_TYPE_SUBTITLE:
979 flags |= AV_OPT_FLAG_SUBTITLE_PARAM;
983 while ((t = av_dict_iterate(opts, t))) {
984 const AVClass *priv_class;
985 char *p = strchr(t->key,
':');
990 case 1: *p = 0;
break;
995 if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
997 ((priv_class = codec->priv_class) &&
998 av_opt_find(&priv_class, t->key, NULL, flags,
999 AV_OPT_SEARCH_FAKE_OBJ)))
1000 av_dict_set(&ret, t->key, t->value, 0);
1001 else if (t->key[0] == prefix &&
1002 av_opt_find(&cc, t->key + 1, NULL, flags,
1003 AV_OPT_SEARCH_FAKE_OBJ))
1004 av_dict_set(&ret, t->key + 1, t->value, 0);
1016 AVDictionary **opts;
1020 opts = av_calloc(s->nb_streams,
sizeof(*opts));
1023 for (i = 0; i < s->nb_streams; i++)
1025 s, s->streams[i], NULL);
1029void *
grow_array(
void *array,
int elem_size,
int *size,
int new_size)
1031 if (new_size >= INT_MAX / elem_size) {
1032 av_log(NULL, AV_LOG_ERROR,
"Array too big.\n");
1035 if (*size < new_size) {
1036 uint8_t *tmp = av_realloc_array(array, new_size, elem_size);
1039 memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
1050 if (!(new_elem = av_mallocz(elem_size)) ||
1051 av_dynarray_add_nofree(ptr, nb_elems, new_elem) < 0)
1060 theta = -round(av_display_rotation_get((int32_t*) displaymatrix));
1062 theta -= 360*floor(theta/360 + 0.9/360);
1064 if (fabs(theta - 90*round(theta/90)) > 2)
1065 av_log(NULL, AV_LOG_WARNING,
"Odd rotation angle.\n"
1066 "If you want to help, upload a sample "
1067 "of this file to https://streams.videolan.org/upload/ "
1068 "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)");
__thread jmp_buf ex_buf__
int(* func_arg)(void *, const char *, const char *)
const OptionGroupDef * group_def
AVDictionary * codec_opts
AVDictionary * format_opts
const OptionGroupDef * group_def