cmdutils: refactor -codecs option.
authorAnton Khirnov <anton@khirnov.net>
Sat, 11 Aug 2012 13:23:22 +0000 (15:23 +0200)
committerAnton Khirnov <anton@khirnov.net>
Sat, 18 Aug 2012 06:48:30 +0000 (08:48 +0200)
Make it print a list of AVCodecDescriptors.

Add new -decoders and -encoders options that print lists of decoders and
encoders respectively.

cmdutils.c
cmdutils.h
cmdutils_common_opts.h
doc/avtools-common-opts.texi

index ae59f7953c592213c5387aa0ec1a3b47a41033c2..b017490f3f37bed3fae2f6d9d9b45011575d59c6 100644 (file)
@@ -632,81 +632,123 @@ void show_formats(void)
     }
 }
 
+static char get_media_type_char(enum AVMediaType type)
+{
+    switch (type) {
+        case AVMEDIA_TYPE_VIDEO:    return 'V';
+        case AVMEDIA_TYPE_AUDIO:    return 'A';
+        case AVMEDIA_TYPE_SUBTITLE: return 'S';
+        default:                    return '?';
+    }
+}
+
+static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
+                                        int encoder)
+{
+    while ((prev = av_codec_next(prev))) {
+        if (prev->id == id &&
+            (encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
+            return prev;
+    }
+    return NULL;
+}
+
+static void print_codecs_for_id(enum AVCodecID id, int encoder)
+{
+    const AVCodec *codec = NULL;
+
+    printf(" (%s: ", encoder ? "encoders" : "decoders");
+
+    while ((codec = next_codec_for_id(id, codec, encoder)))
+        printf("%s ", codec->name);
+
+    printf(")");
+}
+
 void show_codecs(void)
 {
-    AVCodec *p = NULL, *p2;
-    const char *last_name;
+    const AVCodecDescriptor *desc = NULL;
+
     printf("Codecs:\n"
-           " D..... = Decoding supported\n"
-           " .E.... = Encoding supported\n"
-           " ..V... = Video codec\n"
-           " ..A... = Audio codec\n"
-           " ..S... = Subtitle codec\n"
-           " ...S.. = Supports draw_horiz_band\n"
-           " ....D. = Supports direct rendering method 1\n"
-           " .....T = Supports weird frame truncation\n"
-           " ------\n");
-    last_name= "000";
-    for (;;) {
-        int decode = 0;
-        int encode = 0;
-        int cap    = 0;
-        const char *type_str;
-
-        p2 = NULL;
-        while ((p = av_codec_next(p))) {
-            if ((p2 == NULL || strcmp(p->name, p2->name) < 0) &&
-                strcmp(p->name, last_name) > 0) {
-                p2 = p;
-                decode = encode = cap = 0;
+           " D... = Decoding supported\n"
+           " .E.. = Encoding supported\n"
+           " ..V. = Video codec\n"
+           " ..A. = Audio codec\n"
+           " ..S. = Subtitle codec\n"
+           " ...I = Intra frame-only codec\n"
+           " -----\n");
+    while ((desc = avcodec_descriptor_next(desc))) {
+        const AVCodec *codec = NULL;
+
+        printf(avcodec_find_decoder(desc->id) ? "D" : ".");
+        printf(avcodec_find_encoder(desc->id) ? "E" : ".");
+
+        printf("%c", get_media_type_char(desc->type));
+        printf((desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
+
+        printf(" %-20s %s", desc->name, desc->long_name ? desc->long_name : "");
+
+        /* print decoders/encoders when there's more than one or their
+         * names are different from codec name */
+        while ((codec = next_codec_for_id(desc->id, codec, 0))) {
+            if (strcmp(codec->name, desc->name)) {
+                print_codecs_for_id(desc->id, 0);
+                break;
             }
-            if (p2 && strcmp(p->name, p2->name) == 0) {
-                if (av_codec_is_decoder(p))
-                    decode = 1;
-                if (av_codec_is_encoder(p))
-                    encode = 1;
-                cap |= p->capabilities;
+        }
+        codec = NULL;
+        while ((codec = next_codec_for_id(desc->id, codec, 1))) {
+            if (strcmp(codec->name, desc->name)) {
+                print_codecs_for_id(desc->id, 1);
+                break;
             }
         }
-        if (p2 == NULL)
-            break;
-        last_name = p2->name;
 
-        switch (p2->type) {
-        case AVMEDIA_TYPE_VIDEO:
-            type_str = "V";
-            break;
-        case AVMEDIA_TYPE_AUDIO:
-            type_str = "A";
-            break;
-        case AVMEDIA_TYPE_SUBTITLE:
-            type_str = "S";
-            break;
-        default:
-            type_str = "?";
-            break;
-        }
-        printf(" %s%s%s%s%s%s %-15s %s",
-               decode ? "D" : (/* p2->decoder ? "d" : */ " "),
-               encode ? "E" : " ",
-               type_str,
-               cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S" : " ",
-               cap & CODEC_CAP_DR1 ? "D" : " ",
-               cap & CODEC_CAP_TRUNCATED ? "T" : " ",
-               p2->name,
-               p2->long_name ? p2->long_name : "");
-#if 0
-            if (p2->decoder && decode == 0)
-                printf(" use %s for decoding", p2->decoder->name);
-#endif
         printf("\n");
     }
-    printf("\n");
-    printf("Note, the names of encoders and decoders do not always match, so there are\n"
-           "several cases where the above table shows encoder only or decoder only entries\n"
-           "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");
+}
+
+static void print_codecs(int encoder)
+{
+    const AVCodecDescriptor *desc = NULL;
+
+    printf("%s:\n"
+           " V... = Video\n"
+           " A... = Audio\n"
+           " S... = Subtitle\n"
+           " .F.. = Frame-level multithreading\n"
+           " ..S. = Slice-level multithreading\n"
+           " ...X = Codec is experimental\n"
+           " ---\n",
+           encoder ? "Encoders" : "Decoders");
+    while ((desc = avcodec_descriptor_next(desc))) {
+        const AVCodec *codec = NULL;
+
+        while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
+            printf("%c", get_media_type_char(desc->type));
+            printf((codec->capabilities & CODEC_CAP_FRAME_THREADS) ? "F" : ".");
+            printf((codec->capabilities & CODEC_CAP_SLICE_THREADS) ? "S" : ".");
+            printf((codec->capabilities & CODEC_CAP_EXPERIMENTAL)  ? "X" : ".");
+
+            printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
+            if (strcmp(codec->name, desc->name))
+                printf(" (codec %s)", desc->name);
+
+            printf("\n");
+        }
+    }
+}
+
+int show_decoders(const char *opt, const char *arg)
+{
+    print_codecs(0);
+    return 0;
+}
+
+int show_encoders(const char *opt, const char *arg)
+{
+    print_codecs(1);
+    return 0;
 }
 
 void show_bsfs(void)
index f013c2a33f78b15f052888f73aa4936a851119f7..d787496a36248fd11cb23df961750d242229383b 100644 (file)
@@ -278,6 +278,18 @@ void show_formats(void);
  */
 void show_codecs(void);
 
+/**
+ * Print a listing containing all the decoders supported by the
+ * program.
+ */
+int show_decoders(const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the encoders supported by the
+ * program.
+ */
+int show_encoders(const char *opt, const char *arg);
+
 /**
  * Print a listing containing all the filters supported by the
  * program.
index 1158afab9912f17144957e0cdc9f33db1ec95d0f..d9a09c0c193a5604be6f476bb84a1efbd5d04d13 100644 (file)
@@ -6,6 +6,8 @@
     { "version", OPT_EXIT, {(void*)show_version}, "show version" },
     { "formats"  , OPT_EXIT, {(void*)show_formats  }, "show available formats" },
     { "codecs"   , OPT_EXIT, {(void*)show_codecs   }, "show available codecs" },
+    { "decoders" , OPT_EXIT, {(void*)show_decoders }, "show available decoders" },
+    { "encoders" , OPT_EXIT, {(void*)show_encoders }, "show available encoders" },
     { "bsfs"     , OPT_EXIT, {(void*)show_bsfs     }, "show available bit stream filters" },
     { "protocols", OPT_EXIT, {(void*)show_protocols}, "show available protocols" },
     { "filters",   OPT_EXIT, {(void*)show_filters  }, "show available filters" },
index 0be9cf06342ae4caf9fe80e24c4e2aaac236fd7f..375e4b041c21214abc3d229734ee514e28eea647 100644 (file)
@@ -69,23 +69,16 @@ Encoding available
 @end table
 
 @item -codecs
-Show available codecs.
+Show all codecs known to libavcodec.
 
-The fields preceding the codec names have the following meanings:
-@table @samp
-@item D
-Decoding available
-@item E
-Encoding available
-@item V/A/S
-Video/audio/subtitle codec
-@item S
-Codec supports slices
-@item D
-Codec supports direct rendering
-@item T
-Codec can handle input truncated at random locations instead of only at frame boundaries
-@end table
+Note that the term 'codec' is used throughout this documentation as a shortcut
+for what is more correctly called a media bitstream format.
+
+@item -decoders
+Show available decoders.
+
+@item -encoders
+Show all available encoders.
 
 @item -bsfs
 Show available bitstream filters.