#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/eval.h"
+#include "libavutil/dict.h"
#include "libavutil/opt.h"
#include "cmdutils.h"
#include "version.h"
AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
AVFormatContext *avformat_opts;
struct SwsContext *sws_opts;
+AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts;
static const int this_year = 2011;
av_freep(&opt_names);
av_freep(&opt_values);
opt_name_count = 0;
+ av_dict_free(&format_opts);
+ av_dict_free(&video_opts);
+ av_dict_free(&audio_opts);
+ av_dict_free(&sub_opts);
}
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
#endif /* WIN32 && !__MINGW32CE__ */
void parse_options(int argc, char **argv, const OptionDef *options,
- void (* parse_arg_function)(const char*))
+ int (* parse_arg_function)(const char *opt, const char *arg))
{
const char *opt, *arg;
int optindex, handleoptions=1;
*po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
} else if (po->flags & OPT_FLOAT) {
*po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
- } else if (po->flags & OPT_DUMMY) {
- /* Do nothing for this option */
- } else {
+ } else if (po->u.func_arg) {
if (po->u.func_arg(opt, arg) < 0) {
- fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
+ fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg ? arg : "[null]", opt);
exit(1);
}
}
if(po->flags & OPT_EXIT)
exit(0);
} else {
- if (parse_arg_function)
- parse_arg_function(opt);
+ if (parse_arg_function) {
+ if (parse_arg_function(NULL, opt) < 0)
+ exit(1);
+ }
}
}
}
+#define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
+#define SET_PREFIXED_OPTS(ch, flag, output) \
+ if (opt[0] == ch && avcodec_opts[0] && (o = av_opt_find(avcodec_opts[0], opt+1, NULL, flag, 0)))\
+ av_dict_set(&output, opt+1, arg, FLAGS);
+static int opt_default2(const char *opt, const char *arg)
+{
+ const AVOption *o;
+ if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
+ if (o->flags & AV_OPT_FLAG_VIDEO_PARAM)
+ av_dict_set(&video_opts, opt, arg, FLAGS);
+ if (o->flags & AV_OPT_FLAG_AUDIO_PARAM)
+ av_dict_set(&audio_opts, opt, arg, FLAGS);
+ if (o->flags & AV_OPT_FLAG_SUBTITLE_PARAM)
+ av_dict_set(&sub_opts, opt, arg, FLAGS);
+ } else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)))
+ av_dict_set(&format_opts, opt, arg, FLAGS);
+ else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
+ // XXX we only support sws_flags, not arbitrary sws options
+ 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;
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]);
+ const AVOption *o2 = av_opt_find(avcodec_opts[0], opt, NULL, opt_types[type], 0);
if(o2)
ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
}
}
out:
+ 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));
opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
print_all_libs_info(stderr, INDENT|SHOW_VERSION);
}
-void show_version(void) {
+int opt_version(const char *opt, const char *arg) {
printf("%s " FFMPEG_VERSION "\n", program_name);
print_all_libs_info(stdout, SHOW_VERSION);
+ return 0;
}
-void show_license(void)
+int opt_license(const char *opt, const char *arg)
{
printf(
#if CONFIG_NONFREE
program_name, program_name, program_name
#endif
);
+ return 0;
}
-void show_formats(void)
+int opt_formats(const char *opt, const char *arg)
{
AVInputFormat *ifmt=NULL;
AVOutputFormat *ofmt=NULL;
name,
long_name ? long_name:" ");
}
+ return 0;
}
-void show_codecs(void)
+int opt_codecs(const char *opt, const char *arg)
{
AVCodec *p=NULL, *p2;
const char *last_name;
"even though both encoding and decoding are supported. For example, the h263\n"
"decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
"worse.\n");
+ return 0;
}
-void show_bsfs(void)
+int opt_bsfs(const char *opt, const char *arg)
{
AVBitStreamFilter *bsf=NULL;
while((bsf = av_bitstream_filter_next(bsf)))
printf("%s\n", bsf->name);
printf("\n");
+ return 0;
}
-void show_protocols(void)
+int opt_protocols(const char *opt, const char *arg)
{
URLProtocol *up=NULL;
up->url_write ? 'O' : '.',
up->url_seek ? 'S' : '.',
up->name);
+ return 0;
}
-void show_filters(void)
+int opt_filters(const char *opt, const char *arg)
{
AVFilter av_unused(**filter) = NULL;
while ((filter = av_filter_next(filter)) && *filter)
printf("%-16s %s\n", (*filter)->name, (*filter)->description);
#endif
+ return 0;
}
-void show_pix_fmts(void)
+int opt_pix_fmts(const char *opt, const char *arg)
{
enum PixelFormat pix_fmt;
pix_desc->nb_components,
av_get_bits_per_pixel(pix_desc));
}
+ return 0;
}
int read_yesno(void)
return f;
}
-
-#if CONFIG_AVFILTER
-
-static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
-{
- FFSinkContext *priv = ctx->priv;
-
- if (!opaque)
- return AVERROR(EINVAL);
- *priv = *(FFSinkContext *)opaque;
-
- return 0;
-}
-
-static void null_end_frame(AVFilterLink *inlink) { }
-
-static int ffsink_query_formats(AVFilterContext *ctx)
-{
- FFSinkContext *priv = ctx->priv;
- enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
-
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
- return 0;
-}
-
-AVFilter ffsink = {
- .name = "ffsink",
- .priv_size = sizeof(FFSinkContext),
- .init = ffsink_init,
-
- .query_formats = ffsink_query_formats,
-
- .inputs = (AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .end_frame = null_end_frame,
- .min_perms = AV_PERM_READ, },
- { .name = NULL }},
- .outputs = (AVFilterPad[]) {{ .name = NULL }},
-};
-
-int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
- AVFilterBufferRef **picref_ptr, AVRational *tb)
-{
- int ret;
- AVFilterBufferRef *picref;
- *picref_ptr = NULL;
-
- if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
- return ret;
- if (!(picref = ctx->inputs[0]->cur_buf))
- return AVERROR(ENOENT);
- *picref_ptr = picref;
- ctx->inputs[0]->cur_buf = NULL;
- *tb = ctx->inputs[0]->time_base;
-
- memcpy(frame->data, picref->data, sizeof(frame->data));
- memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
- frame->pkt_pos = picref->pos;
- frame->interlaced_frame = picref->video->interlaced;
- frame->top_field_first = picref->video->top_field_first;
- frame->key_frame = picref->video->key_frame;
- frame->pict_type = picref->video->pict_type;
- frame->sample_aspect_ratio = picref->video->sample_aspect_ratio;
-
- return 1;
-}
-
-#endif /* CONFIG_AVFILTER */