It stores options as metadata to be passed to new open calls.
---
cmdutils.c | 49 +++++++++++++++++++++++++++++++++++++++++++++----
cmdutils.h | 1 +
2 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/cmdutils.c b/cmdutils.c
index feeea69..a301bcf 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -38,6 +38,7 @@
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/eval.h"
+#include "libavutil/meta.h"
#include "libavutil/opt.h"
#include "cmdutils.h"
#include "version.h"
@@ -54,6 +55,7 @@ static int opt_name_count;
AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
AVFormatContext *avformat_opts;
struct SwsContext *sws_opts;
+AVMetadata *format_opts, *video_opts, *audio_opts, *sub_opts;
static const int this_year = 2011;
@@ -89,6 +91,10 @@ void uninit_opts(void)
av_freep(&opt_names);
av_freep(&opt_values);
opt_name_count = 0;
+ avmeta_free(&format_opts);
+ avmeta_free(&video_opts);
+ avmeta_free(&audio_opts);
+ avmeta_free(&sub_opts);
}
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
@@ -293,6 +299,42 @@ unknown_opt:
}
}
+#define SET_PREFIXED_OPTS(ch, flag, output) \
+ if (opt[0] == ch && avcodec_opts[0] && (o = av_find_opt(avcodec_opts[0],
opt+1, NULL, flag, flag)))\
+ avmeta_set(&output, opt+1, arg, 0);
+
+static int opt_default2(const char *opt, const char *arg)
+{
+ const AVOption *o;
+ if ((o = avopt_find(avcodec_opts[0], opt, NULL, 0,
AVOPT_SEARCH_CHILDREN))) {
+ if (o->flags & AV_OPT_FLAG_VIDEO_PARAM)
+ avmeta_set(&video_opts, opt, arg, 0);
+ if (o->flags & AV_OPT_FLAG_AUDIO_PARAM)
+ avmeta_set(&audio_opts, opt, arg, 0);
+ if (o->flags & AV_OPT_FLAG_SUBTITLE_PARAM)
+ avmeta_set(&sub_opts, opt, arg, 0);
+ } else if ((o = avopt_find(avformat_opts, opt, NULL, 0,
AVOPT_SEARCH_CHILDREN)))
+ avmeta_set(&format_opts, opt, arg, 0);
+ else if ((o = avopt_find(sws_opts, opt, NULL, 0, AVOPT_SEARCH_CHILDREN)))
{ // XXX
+ int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
+ return ret;
+ }
+ }
+
+ if (!o) {
+ SET_PREFIXED_OPTS('v', AV_OPT_FLAG_VIDEO_PARAM, video_opts)
+ SET_PREFIXED_OPTS('a', AV_OPT_FLAG_AUDIO_PARAM, audio_opts)
+ SET_PREFIXED_OPTS('s', AV_OPT_FLAG_SUBTITLE_PARAM, sub_opts)
+ }
+
+ if (o)
+ return 0;
+ fprintf(stderr, "Unrecognized option '%s'\n", opt);
+ return AVERROR_OPTION_NOT_FOUND;
+}
+
int opt_default(const char *opt, const char *arg){
int type;
int ret= 0;
@@ -335,12 +377,11 @@ int opt_default(const char *opt, const char *arg){
break;
}
}
- if(!p && !oformat){
- fprintf(stderr, "Unrecognized option '%s'\n", opt);
- exit(1);
- }
}
+ if ((ret = opt_default2(opt, arg)) < 0)
+ return ret;
+
// 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));
//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
diff --git a/cmdutils.h b/cmdutils.h
index 3bb1cd6..514d6b9 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -43,6 +43,7 @@ extern const char **opt_names;
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
extern AVFormatContext *avformat_opts;
extern struct SwsContext *sws_opts;
+extern AVMetadata *format_opts, *video_opts, *audio_opts, *sub_opts;
/**
* Initialize the cmdutils option system, in particular
--
1.7.5.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel