From a3ad68d36c0bff87c525035b3f745bb274b00d41 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 13 Aug 2012 20:06:25 +0200 Subject: cmdutils: extend -h to allow printing codec details. --- cmdutils.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) (limited to 'cmdutils.c') diff --git a/cmdutils.c b/cmdutils.c index bc5cb8aae2..55cf3f082a 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -132,7 +132,7 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags, first = 0; } av_strlcpy(buf, po->name, sizeof(buf)); - if (po->flags & HAS_ARG) { + if (po->argname) { av_strlcat(buf, " ", sizeof(buf)); av_strlcat(buf, po->argname, sizeof(buf)); } @@ -642,6 +642,65 @@ int show_formats(const char *opt, const char *arg) return 0; } +#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \ + if (codec->field) { \ + const type *p = c->field; \ + \ + printf(" Supported " list_name ":"); \ + while (*p != term) { \ + get_name(*p); \ + printf(" %s", name); \ + p++; \ + } \ + printf("\n"); \ + } \ + +static void print_codec(const AVCodec *c) +{ + int encoder = av_codec_is_encoder(c); + + printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name, + c->long_name ? c->long_name : ""); + + if (c->type == AVMEDIA_TYPE_VIDEO) { + printf(" Threading capabilities: "); + switch (c->capabilities & (CODEC_CAP_FRAME_THREADS | + CODEC_CAP_SLICE_THREADS)) { + case CODEC_CAP_FRAME_THREADS | + CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break; + case CODEC_CAP_FRAME_THREADS: printf("frame"); break; + case CODEC_CAP_SLICE_THREADS: printf("slice"); break; + default: printf("no"); break; + } + printf("\n"); + } + + if (c->supported_framerates) { + const AVRational *fps = c->supported_framerates; + + printf(" Supported framerates:"); + while (fps->num) { + printf(" %d/%d", fps->num, fps->den); + fps++; + } + printf("\n"); + } + PRINT_CODEC_SUPPORTED(c, pix_fmts, enum PixelFormat, "pixel formats", + PIX_FMT_NONE, GET_PIX_FMT_NAME); + PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0, + GET_SAMPLE_RATE_NAME); + PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats", + AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME); + PRINT_CODEC_SUPPORTED(c, channel_layouts, uint64_t, "channel layouts", + 0, GET_CH_LAYOUT_DESC); + + if (c->priv_class) { + show_help_children(c->priv_class, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_DECODING_PARAM); + } +} + static char get_media_type_char(enum AVMediaType type) { switch (type) { @@ -842,6 +901,65 @@ int show_sample_fmts(const char *opt, const char *arg) return 0; } +static void show_help_codec(const char *name, int encoder) +{ + const AVCodecDescriptor *desc; + const AVCodec *codec; + + if (!name) { + av_log(NULL, AV_LOG_ERROR, "No codec name specified.\n"); + return; + } + + codec = encoder ? avcodec_find_encoder_by_name(name) : + avcodec_find_decoder_by_name(name); + + if (codec) + print_codec(codec); + else if ((desc = avcodec_descriptor_get_by_name(name))) { + int printed = 0; + + while ((codec = next_codec_for_id(desc->id, codec, encoder))) { + printed = 1; + print_codec(codec); + } + + if (!printed) { + av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to Libav, " + "but no %s for it are available. Libav might need to be " + "recompiled with additional external libraries.\n", + name, encoder ? "encoders" : "decoders"); + } + } else { + av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by Libav.\n", + name); + } +} + +int show_help(const char *opt, const char *arg) +{ + char *topic, *par; + av_log_set_callback(log_callback_help); + + topic = av_strdup(arg ? arg : ""); + par = strchr(topic, '='); + if (par) + *par++ = 0; + + if (!*topic) { + show_help_default(topic, par); + } else if (!strcmp(topic, "decoder")) { + show_help_codec(par, 0); + } else if (!strcmp(topic, "encoder")) { + show_help_codec(par, 1); + } else { + show_help_default(topic, par); + } + + av_freep(&topic); + return 0; +} + int read_yesno(void) { int c = getchar(); -- cgit v1.2.3