[FFmpeg-devel] [PATCH] cmdutils: fix printing of codecs
Josh de Kock
josh at itanimul.li
Wed Feb 7 23:07:39 EET 2018
Yes, my bad. It looked like it worked initially (was more
worried about getting a fix out quickly), but it didnt. Try this one.
---
fftools/cmdutils.c | 104 +++++++++++++++++++++++++++++------------------------
1 file changed, 58 insertions(+), 46 deletions(-)
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 0b06ccc..83088f0 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -1421,16 +1421,43 @@ static char get_media_type_char(enum AVMediaType type)
}
}
-static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
- int encoder)
+
+static int compare_codec(const void *a, const void *b)
{
- void *i = 0;
- while ((prev = av_codec_iterate(&i))) {
- if (prev->id == id &&
- (encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
- return prev;
+ const AVCodec * const *da = a;
+ const AVCodec * const *db = b;
+
+ return strcmp((*da)->name, (*db)->name);
+}
+
+static unsigned get_codecs_sorted(enum AVCodecID id, const AVCodec ***rcodecs, int encoder)
+{
+ const AVCodec *codec = NULL;
+ const AVCodec **codecs;
+ unsigned nb_codecs = 0, i = 0;
+ void *opaque = 0;
+
+ while ((codec = av_codec_iterate(&opaque))) {
+ if (codec->id == id &&
+ (encoder ? av_codec_is_encoder(codec) : av_codec_is_decoder(codec)))
+ nb_codecs++;
}
- return NULL;
+ if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
+ av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
+ exit_program(1);
+ }
+
+ opaque = 0;
+ while ((codec = av_codec_iterate(&opaque))) {
+ if (codec->id == id &&
+ (encoder ? av_codec_is_encoder(codec) : av_codec_is_decoder(codec)))
+ codecs[i++] = codec;
+ }
+ av_assert0(i == nb_codecs);
+ qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec);
+ *rcodecs = codecs;
+ return nb_codecs;
+
}
static int compare_codec_desc(const void *a, const void *b)
@@ -1442,7 +1469,7 @@ static int compare_codec_desc(const void *a, const void *b)
strcmp((*da)->name, (*db)->name);
}
-static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
+static unsigned get_codec_descs_sorted(const AVCodecDescriptor ***rcodecs)
{
const AVCodecDescriptor *desc = NULL;
const AVCodecDescriptor **codecs;
@@ -1463,22 +1490,10 @@ static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
return nb_codecs;
}
-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(")");
-}
-
int show_codecs(void *optctx, const char *opt, const char *arg)
{
const AVCodecDescriptor **codecs;
- unsigned i, nb_codecs = get_codecs_sorted(&codecs);
+ unsigned i, nb_codecs = get_codec_descs_sorted(&codecs);
printf("Codecs:\n"
" D..... = Decoding supported\n"
@@ -1492,7 +1507,6 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
" -------\n");
for (i = 0; i < nb_codecs; i++) {
const AVCodecDescriptor *desc = codecs[i];
- const AVCodec *codec = NULL;
if (strstr(desc->name, "_deprecated"))
continue;
@@ -1508,22 +1522,18 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
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;
- }
- }
- 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;
+ for (int encoder = 0; encoder < 2; encoder++) {
+ const AVCodec **codec_codecs;
+ const int nb_codec_codecs = get_codecs_sorted(desc->id, &codec_codecs, encoder);
+ if (nb_codec_codecs) {
+ printf(" (%s: ", encoder ? "encoders" : "decoders");
+ for (int j = 0; j < nb_codec_codecs; j++) {
+ printf("%s ", codec_codecs[j]->name);
+ }
+ printf(")");
}
+ av_free(codec_codecs);
}
-
printf("\n");
}
av_free(codecs);
@@ -1533,7 +1543,7 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
static void print_codecs(int encoder)
{
const AVCodecDescriptor **codecs;
- unsigned i, nb_codecs = get_codecs_sorted(&codecs);
+ unsigned i, nb_codecs = get_codec_descs_sorted(&codecs);
printf("%s:\n"
" V..... = Video\n"
@@ -1549,8 +1559,11 @@ static void print_codecs(int encoder)
for (i = 0; i < nb_codecs; i++) {
const AVCodecDescriptor *desc = codecs[i];
const AVCodec *codec = NULL;
+ const AVCodec **codec_codecs;
+ const int nb_codec_codecs = get_codecs_sorted(desc->id, &codec_codecs, encoder);
- while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
+ for (int j = 0; j < nb_codec_codecs; j++) {
+ codec = codec_codecs[j];
printf(" %c", get_media_type_char(desc->type));
printf((codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
@@ -1564,6 +1577,7 @@ static void print_codecs(int encoder)
printf("\n");
}
+ av_free(codec_codecs);
}
av_free(codecs);
}
@@ -1754,19 +1768,17 @@ static void show_help_codec(const char *name, int encoder)
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);
- }
+ const AVCodec **codec_codecs;
- if (!printed) {
+ if (get_codecs_sorted(desc->id, &codec_codecs, encoder)) {
+ print_codec(codec_codecs[0]);
+ } else {
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");
}
+ av_free(codec_codecs);
} else {
av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by FFmpeg.\n",
name);
--
2.7.4
More information about the ffmpeg-devel
mailing list