Browse Source

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>
Michael Niedermayer 12 years ago
parent
commit
aee51039ee
9 changed files with 240 additions and 32 deletions
  1. 174 1
      cmdutils.c
  2. 30 0
      cmdutils.h
  3. 4 4
      cmdutils_common_opts.h
  4. 23 2
      doc/avtools-common-opts.texi
  5. 0 14
      ffmpeg_filter.c
  6. 6 4
      ffmpeg_opt.c
  7. 1 4
      ffplay.c
  8. 1 2
      ffprobe.c
  9. 1 1
      ffserver.c

+ 174 - 1
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();

+ 30 - 0
cmdutils.h

@@ -188,6 +188,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.
  *
@@ -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 */

+ 4 - 4
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" },

+ 23 - 2
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.

+ 0 - 14
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, ",")
 

+ 6 - 4
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)

+ 1 - 4
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)

+ 1 - 2
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)

+ 1 - 1
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");