[FFmpeg-devel] [PATCH 2/2] move cmdutils show_* related to avcodec into libavcodec
Michael Niedermayer
michael at niedermayer.cc
Fri Nov 4 22:16:36 EET 2016
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
cmdutils.c | 287 +-----------------------------------
cmdutils.h | 26 ----
cmdutils_common_opts.h | 8 +-
libavcodec/Makefile | 1 +
libavcodec/avcodec.h | 28 ++++
libavcodec/cmdutils.c | 383 +++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 418 insertions(+), 315 deletions(-)
create mode 100644 libavcodec/cmdutils.c
diff --git a/cmdutils.c b/cmdutils.c
index 9f58b14..8e0f73e 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -1337,84 +1337,6 @@ int show_devices(void *optctx, const char *opt, const char *arg)
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 : "");
-
- printf(" General capabilities: ");
- if (c->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)
- printf("horizband ");
- if (c->capabilities & AV_CODEC_CAP_DR1)
- printf("dr1 ");
- if (c->capabilities & AV_CODEC_CAP_TRUNCATED)
- printf("trunc ");
- if (c->capabilities & AV_CODEC_CAP_DELAY)
- printf("delay ");
- if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)
- printf("small ");
- if (c->capabilities & AV_CODEC_CAP_SUBFRAMES)
- printf("subframes ");
- if (c->capabilities & AV_CODEC_CAP_EXPERIMENTAL)
- printf("exp ");
- if (c->capabilities & AV_CODEC_CAP_CHANNEL_CONF)
- printf("chconf ");
- if (c->capabilities & AV_CODEC_CAP_PARAM_CHANGE)
- printf("paramchange ");
- if (c->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
- printf("variable ");
- if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
- AV_CODEC_CAP_SLICE_THREADS |
- AV_CODEC_CAP_AUTO_THREADS))
- printf("threads ");
- if (!c->capabilities)
- printf("none");
- printf("\n");
-
- if (c->type == AVMEDIA_TYPE_VIDEO ||
- c->type == AVMEDIA_TYPE_AUDIO) {
- printf(" Threading capabilities: ");
- switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
- AV_CODEC_CAP_SLICE_THREADS |
- AV_CODEC_CAP_AUTO_THREADS)) {
- case AV_CODEC_CAP_FRAME_THREADS |
- AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
- case AV_CODEC_CAP_FRAME_THREADS: printf("frame"); break;
- case AV_CODEC_CAP_SLICE_THREADS: printf("slice"); break;
- case AV_CODEC_CAP_AUTO_THREADS : printf("auto"); break;
- default: printf("none"); 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 AVPixelFormat, "pixel formats",
- AV_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) {
- av_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) {
@@ -1427,176 +1349,6 @@ static char get_media_type_char(enum AVMediaType type)
}
}
-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 int compare_codec_desc(const void *a, const void *b)
-{
- const AVCodecDescriptor * const *da = a;
- const AVCodecDescriptor * const *db = b;
-
- return (*da)->type != (*db)->type ? FFDIFFSIGN((*da)->type, (*db)->type) :
- strcmp((*da)->name, (*db)->name);
-}
-
-static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
-{
- const AVCodecDescriptor *desc = NULL;
- const AVCodecDescriptor **codecs;
- unsigned nb_codecs = 0, i = 0;
-
- while ((desc = avcodec_descriptor_next(desc)))
- nb_codecs++;
- if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
- av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
- exit_program(1);
- }
- desc = NULL;
- while ((desc = avcodec_descriptor_next(desc)))
- codecs[i++] = desc;
- av_assert0(i == nb_codecs);
- qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
- *rcodecs = codecs;
- 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);
-
- printf("Codecs:\n"
- " 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"
- " ....L. = Lossy compression\n"
- " .....S = Lossless compression\n"
- " -------\n");
- for (i = 0; i < nb_codecs; i++) {
- const AVCodecDescriptor *desc = codecs[i];
- const AVCodec *codec = NULL;
-
- if (strstr(desc->name, "_deprecated"))
- continue;
-
- printf(" ");
- 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((desc->props & AV_CODEC_PROP_LOSSY) ? "L" : ".");
- printf((desc->props & AV_CODEC_PROP_LOSSLESS) ? "S" : ".");
-
- 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;
- }
- }
-
- printf("\n");
- }
- av_free(codecs);
- return 0;
-}
-
-static void print_codecs(int encoder)
-{
- const AVCodecDescriptor **codecs;
- unsigned i, nb_codecs = get_codecs_sorted(&codecs);
-
- 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"
- " ....B. = Supports draw_horiz_band\n"
- " .....D = Supports direct rendering method 1\n"
- " ------\n",
- encoder ? "Encoders" : "Decoders");
- for (i = 0; i < nb_codecs; i++) {
- const AVCodecDescriptor *desc = codecs[i];
- 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 & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
- printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
- printf((codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) ? "X" : ".");
- printf((codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
- printf((codec->capabilities & AV_CODEC_CAP_DR1) ? "D" : ".");
-
- printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
- if (strcmp(codec->name, desc->name))
- printf(" (codec %s)", desc->name);
-
- printf("\n");
- }
- }
- av_free(codecs);
-}
-
-int show_decoders(void *optctx, const char *opt, const char *arg)
-{
- print_codecs(0);
- return 0;
-}
-
-int show_encoders(void *optctx, const char *opt, const char *arg)
-{
- print_codecs(1);
- return 0;
-}
-
-int show_bsfs(void *optctx, const char *opt, const char *arg)
-{
- const AVBitStreamFilter *bsf = NULL;
- void *opaque = NULL;
-
- printf("Bitstream filters:\n");
- while ((bsf = av_bsf_next(&opaque)))
- printf("%s\n", bsf->name);
- printf("\n");
- return 0;
-}
-
int show_protocols(void *optctx, const char *opt, const char *arg)
{
void *opaque = NULL;
@@ -1743,41 +1495,6 @@ int show_sample_fmts(void *optctx, 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);
@@ -1900,9 +1617,9 @@ int show_help(void *optctx, const char *opt, const char *arg)
if (!*topic) {
show_help_default(topic, par);
} else if (!strcmp(topic, "decoder")) {
- show_help_codec(par, 0);
+ av_show_help_codec(par, 0);
} else if (!strcmp(topic, "encoder")) {
- show_help_codec(par, 1);
+ av_show_help_codec(par, 1);
} else if (!strcmp(topic, "demuxer")) {
show_help_demuxer(par);
} else if (!strcmp(topic, "muxer")) {
diff --git a/cmdutils.h b/cmdutils.h
index 38589cd..1ffee32 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -472,25 +472,6 @@ int show_sources(void *optctx, const char *opt, const char *arg);
#endif
/**
- * Print a listing containing all the codecs supported by the
- * program.
- * This option processing function does not utilize the arguments.
- */
-int show_codecs(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the decoders supported by the
- * program.
- */
-int show_decoders(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the encoders supported by the
- * program.
- */
-int show_encoders(void *optctx, const char *opt, const char *arg);
-
-/**
* Print a listing containing all the filters supported by the
* program.
* This option processing function does not utilize the arguments.
@@ -498,13 +479,6 @@ int show_encoders(void *optctx, const char *opt, const char *arg);
int show_filters(void *optctx, const char *opt, const char *arg);
/**
- * Print a listing containing all the bit stream filters supported by the
- * program.
- * This option processing function does not utilize the arguments.
- */
-int show_bsfs(void *optctx, const char *opt, const char *arg);
-
-/**
* Print a listing containing all the protocols supported by the
* program.
* This option processing function does not utilize the arguments.
diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h
index f7c1ca4..2f5574f 100644
--- a/cmdutils_common_opts.h
+++ b/cmdutils_common_opts.h
@@ -9,10 +9,10 @@
{ "muxers" , OPT_EXIT, {.func_arg = show_muxers }, "show available muxers" },
{ "demuxers" , OPT_EXIT, {.func_arg = show_demuxers }, "show available demuxers" },
{ "devices" , OPT_EXIT, {.func_arg = show_devices }, "show available devices" },
- { "codecs" , OPT_EXIT, {.func_arg = show_codecs }, "show available codecs" },
- { "decoders" , OPT_EXIT, {.func_arg = show_decoders }, "show available decoders" },
- { "encoders" , OPT_EXIT, {.func_arg = show_encoders }, "show available encoders" },
- { "bsfs" , OPT_EXIT, {.func_arg = show_bsfs }, "show available bit stream filters" },
+ { "codecs" , OPT_EXIT, {.func_arg = av_show_codecs }, "show available codecs" },
+ { "decoders" , OPT_EXIT, {.func_arg = av_show_decoders }, "show available decoders" },
+ { "encoders" , OPT_EXIT, {.func_arg = av_show_encoders }, "show available encoders" },
+ { "bsfs" , OPT_EXIT, {.func_arg = av_show_bsfs }, "show available bit stream filters" },
{ "protocols" , OPT_EXIT, {.func_arg = show_protocols}, "show available protocols" },
{ "filters" , OPT_EXIT, {.func_arg = show_filters }, "show available filters" },
{ "pix_fmts" , OPT_EXIT, {.func_arg = show_pix_fmts }, "show available pixel formats" },
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index f1d5bf1..08ca7fd 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -29,6 +29,7 @@ OBJS = allcodecs.o \
bitstream_filter.o \
bitstream_filters.o \
bsf.o \
+ cmdutils.o \
codec_desc.o \
d3d11va.o \
dirac.o \
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 211112f..0cfe6ce 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -6234,6 +6234,34 @@ const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name);
AVCPBProperties *av_cpb_properties_alloc(size_t *size);
/**
+ * Print a listing containing all the codecs supported by the
+ * program.
+ * This option processing function does not utilize the arguments.
+ */
+int av_show_codecs(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the decoders supported by the
+ * program.
+ */
+int av_show_decoders(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the encoders supported by the
+ * program.
+ */
+int av_show_encoders(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the bit stream filters supported by the
+ * program.
+ * This option processing function does not utilize the arguments.
+ */
+int av_show_bsfs(void *optctx, const char *opt, const char *arg);
+
+void av_show_help_codec(const char *name, int encoder);
+
+/**
* @}
*/
diff --git a/libavcodec/cmdutils.c b/libavcodec/cmdutils.c
new file mode 100644
index 0000000..c22ce8c
--- /dev/null
+++ b/libavcodec/cmdutils.c
@@ -0,0 +1,383 @@
+/*
+ * Various utilities for command line tools
+ * Copyright (c) 2000-2003 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <math.h>
+
+/* Include only the enabled headers since some compilers (namely, Sun
+ Studio) will not omit unused inline functions and create undefined
+ references to libraries that are not being built. */
+
+#include "config.h"
+#include "compat/va_copy.h"
+#include "libavformat/avformat.h"
+#include "libavfilter/avfilter.h"
+#include "libavdevice/avdevice.h"
+#include "libavresample/avresample.h"
+#include "libswscale/swscale.h"
+#include "libswresample/swresample.h"
+#include "libpostproc/postprocess.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/display.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/libm.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/eval.h"
+#include "libavutil/dict.h"
+#include "libavutil/opt.h"
+#include "libavutil/cpu.h"
+#include "libavutil/ffversion.h"
+#include "libavutil/version.h"
+
+
+#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_DESC(ch_layout)\
+ char name[128];\
+ av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
+
+#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
+ if (codec->field) { \
+ const type *p = codec->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 : "");
+
+ printf(" General capabilities: ");
+ if (c->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)
+ printf("horizband ");
+ if (c->capabilities & AV_CODEC_CAP_DR1)
+ printf("dr1 ");
+ if (c->capabilities & AV_CODEC_CAP_TRUNCATED)
+ printf("trunc ");
+ if (c->capabilities & AV_CODEC_CAP_DELAY)
+ printf("delay ");
+ if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)
+ printf("small ");
+ if (c->capabilities & AV_CODEC_CAP_SUBFRAMES)
+ printf("subframes ");
+ if (c->capabilities & AV_CODEC_CAP_EXPERIMENTAL)
+ printf("exp ");
+ if (c->capabilities & AV_CODEC_CAP_CHANNEL_CONF)
+ printf("chconf ");
+ if (c->capabilities & AV_CODEC_CAP_PARAM_CHANGE)
+ printf("paramchange ");
+ if (c->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
+ printf("variable ");
+ if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_SLICE_THREADS |
+ AV_CODEC_CAP_AUTO_THREADS))
+ printf("threads ");
+ if (!c->capabilities)
+ printf("none");
+ printf("\n");
+
+ if (c->type == AVMEDIA_TYPE_VIDEO ||
+ c->type == AVMEDIA_TYPE_AUDIO) {
+ printf(" Threading capabilities: ");
+ switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_SLICE_THREADS |
+ AV_CODEC_CAP_AUTO_THREADS)) {
+ case AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
+ case AV_CODEC_CAP_FRAME_THREADS: printf("frame"); break;
+ case AV_CODEC_CAP_SLICE_THREADS: printf("slice"); break;
+ case AV_CODEC_CAP_AUTO_THREADS : printf("auto"); break;
+ default: printf("none"); 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 AVPixelFormat, "pixel formats",
+ AV_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) {
+ av_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) {
+ case AVMEDIA_TYPE_VIDEO: return 'V';
+ case AVMEDIA_TYPE_AUDIO: return 'A';
+ case AVMEDIA_TYPE_DATA: return 'D';
+ case AVMEDIA_TYPE_SUBTITLE: return 'S';
+ case AVMEDIA_TYPE_ATTACHMENT:return 'T';
+ 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 int compare_codec_desc(const void *a, const void *b)
+{
+ const AVCodecDescriptor * const *da = a;
+ const AVCodecDescriptor * const *db = b;
+
+ return (*da)->type != (*db)->type ? FFDIFFSIGN((*da)->type, (*db)->type) :
+ strcmp((*da)->name, (*db)->name);
+}
+
+static int get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
+{
+ const AVCodecDescriptor *desc = NULL;
+ const AVCodecDescriptor **codecs;
+ unsigned nb_codecs = 0, i = 0;
+
+ while ((desc = avcodec_descriptor_next(desc)))
+ nb_codecs++;
+ if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
+ av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
+ return AVERROR(ENOMEM);
+ }
+ desc = NULL;
+ while ((desc = avcodec_descriptor_next(desc)))
+ codecs[i++] = desc;
+ av_assert0(i == nb_codecs);
+ qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
+ *rcodecs = codecs;
+ 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 av_show_codecs(void *optctx, const char *opt, const char *arg)
+{
+ const AVCodecDescriptor **codecs;
+ unsigned i;
+ int nb_codecs = get_codecs_sorted(&codecs);
+ if (nb_codecs < 0)
+ return nb_codecs;
+
+ printf("Codecs:\n"
+ " 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"
+ " ....L. = Lossy compression\n"
+ " .....S = Lossless compression\n"
+ " -------\n");
+ for (i = 0; i < nb_codecs; i++) {
+ const AVCodecDescriptor *desc = codecs[i];
+ const AVCodec *codec = NULL;
+
+ if (strstr(desc->name, "_deprecated"))
+ continue;
+
+ printf(" ");
+ 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((desc->props & AV_CODEC_PROP_LOSSY) ? "L" : ".");
+ printf((desc->props & AV_CODEC_PROP_LOSSLESS) ? "S" : ".");
+
+ 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;
+ }
+ }
+
+ printf("\n");
+ }
+ av_free(codecs);
+ return 0;
+}
+
+static int print_codecs(int encoder)
+{
+ const AVCodecDescriptor **codecs;
+ unsigned i;
+ int nb_codecs = get_codecs_sorted(&codecs);
+ if (nb_codecs < 0)
+ return nb_codecs;
+
+ 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"
+ " ....B. = Supports draw_horiz_band\n"
+ " .....D = Supports direct rendering method 1\n"
+ " ------\n",
+ encoder ? "Encoders" : "Decoders");
+ for (i = 0; i < nb_codecs; i++) {
+ const AVCodecDescriptor *desc = codecs[i];
+ 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 & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
+ printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
+ printf((codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) ? "X" : ".");
+ printf((codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
+ printf((codec->capabilities & AV_CODEC_CAP_DR1) ? "D" : ".");
+
+ printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
+ if (strcmp(codec->name, desc->name))
+ printf(" (codec %s)", desc->name);
+
+ printf("\n");
+ }
+ }
+ av_free(codecs);
+ return 0;
+}
+
+int av_show_decoders(void *optctx, const char *opt, const char *arg)
+{
+ return print_codecs(0);
+}
+
+int av_show_encoders(void *optctx, const char *opt, const char *arg)
+{
+ return print_codecs(1);
+}
+
+int av_show_bsfs(void *optctx, const char *opt, const char *arg)
+{
+ const AVBitStreamFilter *bsf = NULL;
+ void *opaque = NULL;
+
+ printf("Bitstream filters:\n");
+ while ((bsf = av_bsf_next(&opaque)))
+ printf("%s\n", bsf->name);
+ printf("\n");
+ return 0;
+}
+
+void av_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);
+ }
+}
--
2.10.2
More information about the ffmpeg-devel
mailing list