aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-08-20 17:03:04 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-08-20 17:06:50 +0200
commitaee51039ee204197fdb4c924f8ee433b803ab1e1 (patch)
treeb1138f704eec5bf82e6fcc23591c7b245f728ac5
parent67a6dac7c18caecb418f7590a484dcbfcad869ab (diff)
parentf8b1e665539010d3ca148f09cb1203c20c1ca174 (diff)
downloadffmpeg-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.c175
-rw-r--r--cmdutils.h30
-rw-r--r--cmdutils_common_opts.h8
-rw-r--r--doc/avtools-common-opts.texi25
-rw-r--r--ffmpeg_filter.c14
-rw-r--r--ffmpeg_opt.c10
-rw-r--r--ffplay.c5
-rw-r--r--ffprobe.c3
-rw-r--r--ffserver.c2
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)
diff --git a/ffplay.c b/ffplay.c
index c28883c498..2907948689 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -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)
diff --git a/ffprobe.c b/ffprobe.c
index 2046ec0f34..c1a90de692 100644
--- a/ffprobe.c
+++ b/ffprobe.c
@@ -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");