[FFmpeg-cvslog] cmdutils: refactor -codecs option.
Anton Khirnov
git at videolan.org
Sat Aug 18 15:26:30 CEST 2012
ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Sat Aug 11 15:23:22 2012 +0200| [7c1019499602e23141d7ca06fe6df5ea5ab3a240] | committer: Anton Khirnov
cmdutils: refactor -codecs option.
Make it print a list of AVCodecDescriptors.
Add new -decoders and -encoders options that print lists of decoders and
encoders respectively.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7c1019499602e23141d7ca06fe6df5ea5ab3a240
---
cmdutils.c | 174 ++++++++++++++++++++++++++----------------
cmdutils.h | 12 +++
cmdutils_common_opts.h | 2 +
doc/avtools-common-opts.texi | 25 +++---
4 files changed, 131 insertions(+), 82 deletions(-)
diff --git a/cmdutils.c b/cmdutils.c
index ae59f79..b017490 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -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)
diff --git a/cmdutils.h b/cmdutils.h
index f013c2a..d787496 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -279,6 +279,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.
*/
diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h
index 1158afa..d9a09c0 100644
--- a/cmdutils_common_opts.h
+++ b/cmdutils_common_opts.h
@@ -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" },
diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi
index 0be9cf0..375e4b0 100644
--- a/doc/avtools-common-opts.texi
+++ b/doc/avtools-common-opts.texi
@@ -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:
- at table @samp
- at item D
-Decoding available
- at item E
-Encoding available
- at item V/A/S
-Video/audio/subtitle codec
- at item S
-Codec supports slices
- at item D
-Codec supports direct rendering
- at item T
-Codec can handle input truncated at random locations instead of only at frame boundaries
- at 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.
+
+ at item -decoders
+Show available decoders.
+
+ at item -encoders
+Show all available encoders.
@item -bsfs
Show available bitstream filters.
More information about the ffmpeg-cvslog
mailing list