Revision d3190644 cmdutils.c

View differences:

cmdutils.c
79 79
    av_freep(&sws_opts);
80 80
#endif
81 81
    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
        }
82
        av_freep(&opt_names[i]);
83
        av_freep(&opt_values[i]);
88 84
    }
89 85
    av_freep(&opt_names);
90 86
    av_freep(&opt_values);
......
235 231
    int ret= 0;
236 232
    const AVOption *o= NULL;
237 233
    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
234
    AVCodec *p = NULL;
235
    AVOutputFormat *oformat = NULL;
236

  
237
    while ((p = av_codec_next(p))) {
238
        AVClass *c = p->priv_class;
239
        if (c && av_find_opt(&c, opt, NULL, 0, 0))
240
            break;
241
    }
242
    if (p)
243
        goto out;
244
    while ((oformat = av_oformat_next(oformat))) {
245
        const AVClass *c = oformat->priv_class;
246
        if (c && av_find_opt(&c, opt, NULL, 0, 0))
247
            break;
248
    }
249
    if (oformat)
250
        goto out;
238 251

  
239 252
    for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
240 253
        const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
......
252 265
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
253 266
        else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE])
254 267
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
268
        if (ret >= 0)
269
            opt += 1;
255 270
    }
256 271
    if (o && ret < 0) {
257 272
        fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
258 273
        exit(1);
259 274
    }
260 275
    if (!o) {
261
        AVCodec *p = NULL;
262
        AVOutputFormat *oformat = NULL;
263
        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
        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
            fprintf(stderr, "Unrecognized option '%s'\n", opt);
277
            exit(1);
278
        }
276
        fprintf(stderr, "Unrecognized option '%s'\n", opt);
277
        exit(1);
279 278
    }
280 279

  
280
 out:
281 281
//    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 282

  
283
    //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 283
    opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
285
    opt_values[opt_name_count]= o ? NULL : av_strdup(arg);
284
    opt_values[opt_name_count] = av_strdup(arg);
286 285
    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
287
    opt_names[opt_name_count++]= o ? o->name : av_strdup(opt);
286
    opt_names[opt_name_count++] = av_strdup(opt);
288 287

  
289 288
    if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug))
290 289
        av_log_set_level(AV_LOG_DEBUG);
......
358 357
    for(i=0; i<opt_name_count; i++){
359 358
        char buf[256];
360 359
        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
            av_set_string3(ctx, opt_names[i], str, 1, NULL);
365
        /* 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) {
369
            if (av_find_opt(priv_ctx, opt_names[i], NULL, flags, flags))
370
                av_set_string3(priv_ctx, opt_names[i], opt_values[i], 0, NULL);
360
        const char *str;
361
        if (priv_ctx) {
362
            if (av_find_opt(priv_ctx, opt_names[i], NULL, flags, flags)) {
363
                if (av_set_string3(priv_ctx, opt_names[i], opt_values[i], 0, NULL) < 0) {
364
                    fprintf(stderr, "Invalid value '%s' for option '%s'\n",
365
                            opt_names[i], opt_values[i]);
366
                    exit(1);
367
                }
368
            } else
369
                goto global;
370
        } else {
371
        global:
372
            str = av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
373
            /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
374
            if (str && ((opt->flags & flags) == flags))
375
                av_set_string3(ctx, opt_names[i], str, 1, NULL);
371 376
        }
372 377
    }
373 378
}

Also available in: Unified diff