diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-08-20 17:03:04 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-08-20 17:06:50 +0200 |
commit | aee51039ee204197fdb4c924f8ee433b803ab1e1 (patch) | |
tree | b1138f704eec5bf82e6fcc23591c7b245f728ac5 | |
parent | 67a6dac7c18caecb418f7590a484dcbfcad869ab (diff) | |
parent | f8b1e665539010d3ca148f09cb1203c20c1ca174 (diff) | |
download | ffmpeg-aee51039ee204197fdb4c924f8ee433b803ab1e1.tar.gz |
Merge commit 'f8b1e665539010d3ca148f09cb1203c20c1ca174'
* commit 'f8b1e665539010d3ca148f09cb1203c20c1ca174':
avconv: print info/capabilities options in a separate help group.
avtools: add -h demuxer/muxer
cmdutils: extend -h to allow printing codec details.
Conflicts:
cmdutils.h
ffmpeg_filter.c
ffmpeg_opt.c
ffplay.c
ffserver.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | cmdutils.c | 175 | ||||
-rw-r--r-- | cmdutils.h | 30 | ||||
-rw-r--r-- | cmdutils_common_opts.h | 8 | ||||
-rw-r--r-- | doc/avtools-common-opts.texi | 25 | ||||
-rw-r--r-- | ffmpeg_filter.c | 14 | ||||
-rw-r--r-- | ffmpeg_opt.c | 10 | ||||
-rw-r--r-- | ffplay.c | 5 | ||||
-rw-r--r-- | ffprobe.c | 3 | ||||
-rw-r--r-- | ffserver.c | 2 |
9 files changed, 240 insertions, 32 deletions
diff --git a/cmdutils.c b/cmdutils.c index 443873b779..0d8b426183 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -160,7 +160,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)); } @@ -806,6 +806,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) { @@ -1034,6 +1093,120 @@ 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 FFmpeg, " + "but no %s for it are available. FFmpeg 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 FFmpeg.\n", + name); + } +} + +static void show_help_demuxer(const char *name) +{ + const AVInputFormat *fmt = av_find_input_format(name); + + if (!fmt) { + av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name); + return; + } + + printf("Demuxer %s [%s]:\n", fmt->name, fmt->long_name); + + if (fmt->extensions) + printf(" Common extensions: %s.\n", fmt->extensions); + + if (fmt->priv_class) + show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM); +} + +static void show_help_muxer(const char *name) +{ + const AVCodecDescriptor *desc; + const AVOutputFormat *fmt = av_guess_format(name, NULL, NULL); + + if (!fmt) { + av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name); + return; + } + + printf("Muxer %s [%s]:\n", fmt->name, fmt->long_name); + + if (fmt->extensions) + printf(" Common extensions: %s.\n", fmt->extensions); + if (fmt->mime_type) + printf(" Mime type: %s.\n", fmt->mime_type); + if (fmt->video_codec != AV_CODEC_ID_NONE && + (desc = avcodec_descriptor_get(fmt->video_codec))) { + printf(" Default video codec: %s.\n", desc->name); + } + if (fmt->audio_codec != AV_CODEC_ID_NONE && + (desc = avcodec_descriptor_get(fmt->audio_codec))) { + printf(" Default audio codec: %s.\n", desc->name); + } + if (fmt->subtitle_codec != AV_CODEC_ID_NONE && + (desc = avcodec_descriptor_get(fmt->subtitle_codec))) { + printf(" Default subtitle codec: %s.\n", desc->name); + } + + if (fmt->priv_class) + show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM); +} + +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 if (!strcmp(topic, "demuxer")) { + show_help_demuxer(par); + } else if (!strcmp(topic, "muxer")) { + show_help_muxer(par); + } else { + show_help_default(topic, par); + } + + av_freep(&topic); + return 0; +} + int read_yesno(void) { int c = getchar(); diff --git a/cmdutils.h b/cmdutils.h index fb2229fc50..84ef3718df 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -189,6 +189,17 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags, void show_help_children(const AVClass *class, int flags); /** + * Per-avtool specific help handler. Implemented in each + * avtool, called by show_help(). + */ +void show_help_default(const char *opt, const char *arg); + +/** + * Generic -h handler common to all avtools. + */ +int show_help(const char *opt, const char *arg); + +/** * Parse the command line arguments. * * @param optctx an opaque options context @@ -449,4 +460,23 @@ void filter_release_buffer(AVFilterBuffer *fb); * buffers have been released. */ void free_buffer_pool(FrameBuffer **pool); + +#define GET_PIX_FMT_NAME(pix_fmt)\ + const char *name = av_get_pix_fmt_name(pix_fmt); + +#define GET_SAMPLE_FMT_NAME(sample_fmt)\ + const char *name = av_get_sample_fmt_name(sample_fmt) + +#define GET_SAMPLE_RATE_NAME(rate)\ + char name[16];\ + snprintf(name, sizeof(name), "%d", rate); + +#define GET_CH_LAYOUT_NAME(ch_layout)\ + char name[16];\ + snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout); + +#define GET_CH_LAYOUT_DESC(ch_layout)\ + char name[128];\ + av_get_channel_layout_string(name, sizeof(name), 0, ch_layout); + #endif /* CMDUTILS_H */ diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h index f3bb415adf..b4892bbfe6 100644 --- a/cmdutils_common_opts.h +++ b/cmdutils_common_opts.h @@ -1,8 +1,8 @@ { "L" , OPT_EXIT, {.func_arg = show_license}, "show license" }, - { "h" , OPT_EXIT, {.func_arg = show_help}, "show help" }, - { "?" , OPT_EXIT, {.func_arg = show_help}, "show help" }, - { "help" , OPT_EXIT, {.func_arg = show_help}, "show help" }, - { "-help" , OPT_EXIT, {.func_arg = show_help}, "show help" }, + { "h" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" }, + { "?" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" }, + { "help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" }, + { "-help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" }, { "version" , OPT_EXIT, {.func_arg = show_version}, "show version" }, { "formats" , OPT_EXIT, {.func_arg = show_formats }, "show available formats" }, { "codecs" , OPT_EXIT, {.func_arg = show_codecs }, "show available codecs" }, diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi index 91460b30b2..805064c854 100644 --- a/doc/avtools-common-opts.texi +++ b/doc/avtools-common-opts.texi @@ -54,8 +54,29 @@ These options are shared amongst the av* tools. @item -L Show license. -@item -h, -?, -help, --help -Show help. +@item -h, -?, -help, --help [@var{arg}] +Show help. An optional parameter may be specified to print help about a specific +item. + +Possible values of @var{arg} are: +@table @option +@item decoder=@var{decoder_name} +Print detailed information about the decoder named @var{decoder_name}. Use the +@option{-decoders} option to get a list of all decoders. + +@item encoder=@var{encoder_name} +Print detailed information about the encoder named @var{encoder_name}. Use the +@option{-encoders} option to get a list of all encoders. + +@item demuxer=@var{demuxer_name} +Print detailed information about the demuxer named @var{demuxer_name}. Use the +@option{-formats} option to get a list of all demuxers and muxers. + +@item muxer=@var{muxer_name} +Print detailed information about the muxer named @var{muxer_name}. Use the +@option{-formats} option to get a list of all muxers and demuxers. + +@end table @item -version Show version. diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 498803c30a..5dcfaa4601 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -159,29 +159,15 @@ static char *choose_ ## var ## s(OutputStream *ost) \ return NULL; \ } -#define GET_PIX_FMT_NAME(pix_fmt)\ - const char *name = av_get_pix_fmt_name(pix_fmt); - // DEF_CHOOSE_FORMAT(enum PixelFormat, pix_fmt, pix_fmts, PIX_FMT_NONE, // GET_PIX_FMT_NAME, ":") -#define GET_SAMPLE_FMT_NAME(sample_fmt)\ - const char *name = av_get_sample_fmt_name(sample_fmt) - DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts, AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME, ",") -#define GET_SAMPLE_RATE_NAME(rate)\ - char name[16];\ - snprintf(name, sizeof(name), "%d", rate); - DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0, GET_SAMPLE_RATE_NAME, ",") -#define GET_CH_LAYOUT_NAME(ch_layout)\ - char name[16];\ - snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout); - DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0, GET_CH_LAYOUT_NAME, ",") diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index aba9a1b6ff..02137b9bff 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -2139,13 +2139,16 @@ static int opt_filter_complex(const char *opt, const char *arg) return 0; } -static int show_help(const char *opt, const char *arg) +void show_help_default(const char *opt, const char *arg) { int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM; - av_log_set_callback(log_callback_help); + show_usage(); + show_help_options(options, "Print help / information / capabilities:", + OPT_EXIT, 0); show_help_options(options, "Main options:", - 0, OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE); + 0, OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | + OPT_EXIT); show_help_options(options, "Advanced options:", OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE); show_help_options(options, "Video options:", @@ -2164,7 +2167,6 @@ static int show_help(const char *opt, const char *arg) show_help_children(sws_get_class(), flags); show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM); show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM); - return 0; } void show_usage(void) @@ -244,8 +244,6 @@ typedef struct AllocEventProps { AVFrame *frame; } AllocEventProps; -static int show_help(const char *opt, const char *arg); - /* options specified by the user */ static AVInputFormat *file_iformat; static const char *input_filename; @@ -3023,7 +3021,7 @@ static void show_usage(void) av_log(NULL, AV_LOG_INFO, "\n"); } -static int show_help(const char *opt, const char *arg) +void show_help_default(const char *opt, const char *arg) { av_log_set_callback(log_callback_help); show_usage(); @@ -3051,7 +3049,6 @@ static int show_help(const char *opt, const char *arg) "page down/page up seek backward/forward 10 minutes\n" "mouse click seek to percentage in file corresponding to fraction of width\n" ); - return 0; } static int lockmgr(void **mtx, enum AVLockOp op) @@ -2072,7 +2072,7 @@ static void opt_input_file(void *optctx, const char *arg) input_filename = arg; } -static int show_help(const char *opt, const char *arg) +void show_help_default(const char *opt, const char *arg) { av_log_set_callback(log_callback_help); show_usage(); @@ -2080,7 +2080,6 @@ static int show_help(const char *opt, const char *arg) printf("\n"); show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM); - return 0; } static int opt_pretty(const char *opt, const char *arg) diff --git a/ffserver.c b/ffserver.c index c03278c0b1..0e25f24b5d 100644 --- a/ffserver.c +++ b/ffserver.c @@ -4645,7 +4645,7 @@ static void opt_debug(void) logfilename[0] = '-'; } -static int show_help(const char *opt, const char *arg) +void show_help_default(const char *opt, const char *arg) { printf("usage: ffserver [options]\n" "Hyper fast multi format Audio/Video streaming server\n"); |