On Wed, Apr 20, 2011 at 3:40 PM, Alex Converse <[email protected]> wrote:
> ---
> cmdutils.c | 79
> ++++++++++++++++++++++++++++++++----------------------------
> 1 files changed, 42 insertions(+), 37 deletions(-)
>
>
From 480dd6ea23b6f8f4c88e92c6cf02c49255c613d3 Mon Sep 17 00:00:00 2001
From: Baptiste Coudurier <[email protected]>
Date: Tue, 19 Apr 2011 12:57:46 -0700
Subject: [PATCH 2/6] Prefer codec specific options over global ones, allowing codec
to override global options.
(cherry picked from commit d319064465e148b8adb53d1ea5d38c09f987056e)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------1"
This is a multi-part message in MIME format.
--------------1
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
cmdutils.c | 79 ++++++++++++++++++++++++++++++++----------------------------
1 files changed, 42 insertions(+), 37 deletions(-)
--------------1
Content-Type: text/x-patch; name="0002-Prefer-codec-specific-options-over-global-ones-allow.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0002-Prefer-codec-specific-options-over-global-ones-allow.patch"
diff --git a/cmdutils.c b/cmdutils.c
index 4aef03d..cd4c05b 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -79,12 +79,8 @@ void uninit_opts(void)
av_freep(&sws_opts);
#endif
for (i = 0; i < opt_name_count; i++) {
- //opt_values are only stored for codec-specific options in which case
- //both the name and value are dup'd
- if (opt_values[i]) {
- av_freep(&opt_names[i]);
- av_freep(&opt_values[i]);
- }
+ av_freep(&opt_names[i]);
+ av_freep(&opt_values[i]);
}
av_freep(&opt_names);
av_freep(&opt_values);
@@ -231,6 +227,23 @@ int opt_default(const char *opt, const char *arg){
int ret= 0;
const AVOption *o= NULL;
int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
+ AVCodec *p = NULL;
+ AVOutputFormat *oformat = NULL;
+
+ while ((p = av_codec_next(p))) {
+ AVClass *c = p->priv_class;
+ if (c && av_find_opt(&c, opt, NULL, 0, 0))
+ break;
+ }
+ if (p)
+ goto out;
+ while ((oformat = av_oformat_next(oformat))) {
+ const AVClass *c = oformat->priv_class;
+ if (c && av_find_opt(&c, opt, NULL, 0, 0))
+ break;
+ }
+ if (oformat)
+ goto out;
for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
@@ -248,39 +261,25 @@ int opt_default(const char *opt, const char *arg){
ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE])
ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
+ if (ret >= 0)
+ opt += 1;
}
if (o && ret < 0) {
fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
exit(1);
}
if (!o) {
- AVCodec *p = NULL;
- AVOutputFormat *oformat = NULL;
- while ((p=av_codec_next(p))){
- AVClass *c= p->priv_class;
- if(c && av_find_opt(&c, opt, NULL, 0, 0))
- break;
- }
- if (!p) {
- while ((oformat = av_oformat_next(oformat))) {
- const AVClass *c = oformat->priv_class;
- if (c && av_find_opt(&c, opt, NULL, 0, 0))
- break;
- }
- }
- if(!p && !oformat){
- fprintf(stderr, "Unrecognized option '%s'\n", opt);
- exit(1);
- }
+ fprintf(stderr, "Unrecognized option '%s'\n", opt);
+ exit(1);
}
+ out:
// 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
opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
- opt_values[opt_name_count]= o ? NULL : av_strdup(arg);
+ opt_values[opt_name_count] = av_strdup(arg);
opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
- opt_names[opt_name_count++]= o ? o->name : av_strdup(opt);
+ opt_names[opt_name_count++] = av_strdup(opt);
if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug))
av_log_set_level(AV_LOG_DEBUG);
@@ -354,16 +353,22 @@ void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec)
for(i=0; i<opt_name_count; i++){
char buf[256];
const AVOption *opt;
- const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
- /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
- if(str && ((opt->flags & flags) == flags))
- av_set_string3(ctx, opt_names[i], str, 1, NULL);
- /* We need to use a differnt system to pass options to the private context because
- it is not known which codec and thus context kind that will be when parsing options
- we thus use opt_values directly instead of opts_ctx */
- if(!str && priv_ctx) {
- if (av_find_opt(priv_ctx, opt_names[i], NULL, flags, flags))
- av_set_string3(priv_ctx, opt_names[i], opt_values[i], 0, NULL);
+ const char *str;
+ if (priv_ctx) {
+ if (av_find_opt(priv_ctx, opt_names[i], NULL, flags, flags)) {
+ if (av_set_string3(priv_ctx, opt_names[i], opt_values[i], 0, NULL) < 0) {
+ fprintf(stderr, "Invalid value '%s' for option '%s'\n",
+ opt_names[i], opt_values[i]);
+ exit(1);
+ }
+ } else
+ goto global;
+ } else {
+ global:
+ str = av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
+ /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
+ if (str && ((opt->flags & flags) == flags))
+ av_set_string3(ctx, opt_names[i], str, 1, NULL);
}
}
}
--------------1--
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel