[FFmpeg-devel] [PATCH 2/3] cmdutils: use new iteration APIs
Josh de Kock
josh at itanimul.li
Sun Feb 18 19:58:18 EET 2018
---
fftools/cmdutils.c | 239 +++++++++++++++++++++++++----------------------------
1 file changed, 112 insertions(+), 127 deletions(-)
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 0c7d13c..c341f8f 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -1250,19 +1250,11 @@ int show_license(void *optctx, const char *opt, const char *arg)
return 0;
}
-static int is_device(const AVClass *avclass)
-{
- if (!avclass)
- return 0;
- return AV_IS_INPUT_DEVICE(avclass->category) || AV_IS_OUTPUT_DEVICE(avclass->category);
-}
-
static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only, int muxdemuxers)
{
- AVInputFormat *ifmt = NULL;
- AVOutputFormat *ofmt = NULL;
+ const AVInputFormat *ifmt = NULL;
+ const AVOutputFormat *ofmt = NULL;
const char *last_name;
- int is_dev;
printf("%s\n"
" D. = Demuxing supported\n"
@@ -1270,46 +1262,38 @@ static int show_formats_devices(void *optctx, const char *opt, const char *arg,
" --\n", device_only ? "Devices:" : "File formats:");
last_name = "000";
for (;;) {
- int decode = 0;
- int encode = 0;
+ int is_ifmt = 0;
+ int is_ofmt = 0;
const char *name = NULL;
const char *long_name = NULL;
- if (muxdemuxers !=SHOW_DEMUXERS) {
- while ((ofmt = av_oformat_next(ofmt))) {
- is_dev = is_device(ofmt->priv_class);
- if (!is_dev && device_only)
- continue;
- if ((!name || strcmp(ofmt->name, name) < 0) &&
- strcmp(ofmt->name, last_name) > 0) {
- name = ofmt->name;
- long_name = ofmt->long_name;
- encode = 1;
- }
- }
- }
- if (muxdemuxers != SHOW_MUXERS) {
- while ((ifmt = av_iformat_next(ifmt))) {
- is_dev = is_device(ifmt->priv_class);
- if (!is_dev && device_only)
- continue;
- if ((!name || strcmp(ifmt->name, name) < 0) &&
- strcmp(ifmt->name, last_name) > 0) {
- name = ifmt->name;
- long_name = ifmt->long_name;
- encode = 0;
- }
- if (name && strcmp(ifmt->name, name) == 0)
- decode = 1;
- }
- }
+#define x(func, type, condition) do { \
+ void *i = 0; \
+ if (condition) { \
+ while ((type = func(&i))) { \
+ if ((!name || strcmp(type->name, name) < 0) && \
+ strcmp(type->name, last_name) > 0) { \
+ name = type->name; \
+ long_name = type->long_name; \
+ is_ ## type = 1; \
+ } \
+ } \
+ } } while(0)
+
+ x(av_muxer_iterate, ofmt, muxdemuxers != SHOW_DEMUXERS && !device_only);
+ x(av_demuxer_iterate, ifmt, muxdemuxers != SHOW_MUXERS && !device_only);
+#if CONFIG_AVDEVICE
+ x(av_outdev_iterate, ofmt, muxdemuxers != SHOW_DEMUXERS);
+ x(av_indev_iterate, ifmt, muxdemuxers != SHOW_MUXERS);
+#endif
+#undef x
if (!name)
break;
last_name = name;
printf(" %s%s %-15s %s\n",
- decode ? "D" : " ",
- encode ? "E" : " ",
+ is_ifmt ? "D" : " ",
+ is_ofmt ? "E" : " ",
name,
long_name ? long_name:" ");
}
@@ -1439,15 +1423,45 @@ 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)
+{
+ const AVCodec * const *ca = a;
+ const AVCodec * const *cb = b;
+
+ return strcmp((*ca)->name, (*cb)->name);
+}
+
+static unsigned get_codecs_sorted(enum AVCodecID id, const AVCodec ***rcodecs, 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;
+ 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++;
+ }
+
+ 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;
}
- return NULL;
+
+ 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)
@@ -1459,7 +1473,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;
@@ -1480,22 +1494,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"
@@ -1509,7 +1511,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;
@@ -1525,22 +1526,22 @@ 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;
+ 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 == 1 && !strcmp(desc->name, codec_codecs[0]->name)) {
+ av_free(codec_codecs);
+ continue;
}
- }
- 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 (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);
@@ -1550,7 +1551,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"
@@ -1566,8 +1567,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" : ".");
@@ -1581,6 +1585,7 @@ static void print_codecs(int encoder)
printf("\n");
}
+ av_free(codec_codecs);
}
av_free(codecs);
}
@@ -1628,6 +1633,7 @@ int show_filters(void *optctx, const char *opt, const char *arg)
{
#if CONFIG_AVFILTER
const AVFilter *filter = NULL;
+ void *opaque = 0;
char descr[64], *descr_cur;
int i, j;
const AVFilterPad *pad;
@@ -1640,7 +1646,7 @@ int show_filters(void *optctx, const char *opt, const char *arg)
" V = Video input/output\n"
" N = Dynamic number and/or type of input/output\n"
" | = Source or sink filter\n");
- while ((filter = avfilter_next(filter))) {
+ while ((filter = av_filter_iterate(&opaque))) {
descr_cur = descr;
for (i = 0; i < 2; i++) {
if (i) {
@@ -1771,19 +1777,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;
+ const AVCodec **codec_codecs;
- while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
- printed = 1;
- print_codec(codec);
- }
-
- 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);
@@ -2116,7 +2120,7 @@ double get_rotation(AVStream *st)
}
#if CONFIG_AVDEVICE
-static int print_device_sources(AVInputFormat *fmt, AVDictionary *opts)
+static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts)
{
int ret, i;
AVDeviceInfoList *device_list = NULL;
@@ -2131,7 +2135,7 @@ static int print_device_sources(AVInputFormat *fmt, AVDictionary *opts)
goto fail;
}
- if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
+ if ((ret = avdevice_list_input_sources((AVInputFormat*)fmt, NULL, opts, &device_list)) < 0) {
printf("Cannot list sources.\n");
goto fail;
}
@@ -2146,7 +2150,7 @@ static int print_device_sources(AVInputFormat *fmt, AVDictionary *opts)
return ret;
}
-static int print_device_sinks(AVOutputFormat *fmt, AVDictionary *opts)
+static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts)
{
int ret, i;
AVDeviceInfoList *device_list = NULL;
@@ -2161,7 +2165,7 @@ static int print_device_sinks(AVOutputFormat *fmt, AVDictionary *opts)
goto fail;
}
- if ((ret = avdevice_list_output_sinks(fmt, NULL, opts, &device_list)) < 0) {
+ if ((ret = avdevice_list_output_sinks((AVOutputFormat*)fmt, NULL, opts, &device_list)) < 0) {
printf("Cannot list sinks.\n");
goto fail;
}
@@ -2200,7 +2204,8 @@ static int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionar
int show_sources(void *optctx, const char *opt, const char *arg)
{
- AVInputFormat *fmt = NULL;
+ const AVInputFormat *fmt = NULL;
+ void *i = 0;
char *dev = NULL;
AVDictionary *opts = NULL;
int ret = 0;
@@ -2211,24 +2216,14 @@ int show_sources(void *optctx, const char *opt, const char *arg)
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
goto fail;
- do {
- fmt = av_input_audio_device_next(fmt);
- if (fmt) {
- if (!strcmp(fmt->name, "lavfi"))
- continue; //it's pointless to probe lavfi
- if (dev && !av_match_name(dev, fmt->name))
- continue;
- print_device_sources(fmt, opts);
- }
- } while (fmt);
- do {
- fmt = av_input_video_device_next(fmt);
- if (fmt) {
- if (dev && !av_match_name(dev, fmt->name))
- continue;
- print_device_sources(fmt, opts);
- }
- } while (fmt);
+ while ((fmt = av_indev_iterate(&i))) {
+ if (!strcmp(fmt->name, "lavfi"))
+ continue; //it's pointless to probe lavfi
+ if (dev && !av_match_name(dev, fmt->name))
+ continue;
+ print_device_sources(fmt, opts);
+ }
+
fail:
av_dict_free(&opts);
av_free(dev);
@@ -2238,7 +2233,8 @@ int show_sources(void *optctx, const char *opt, const char *arg)
int show_sinks(void *optctx, const char *opt, const char *arg)
{
- AVOutputFormat *fmt = NULL;
+ const AVOutputFormat *fmt = NULL;
+ void *i = 0;
char *dev = NULL;
AVDictionary *opts = NULL;
int ret = 0;
@@ -2249,22 +2245,11 @@ int show_sinks(void *optctx, const char *opt, const char *arg)
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
goto fail;
- do {
- fmt = av_output_audio_device_next(fmt);
- if (fmt) {
- if (dev && !av_match_name(dev, fmt->name))
- continue;
- print_device_sinks(fmt, opts);
- }
- } while (fmt);
- do {
- fmt = av_output_video_device_next(fmt);
- if (fmt) {
- if (dev && !av_match_name(dev, fmt->name))
- continue;
- print_device_sinks(fmt, opts);
- }
- } while (fmt);
+ while ((fmt = av_outdev_iterate(&i))) {
+ if (dev && !av_match_name(dev, fmt->name))
+ continue;
+ print_device_sinks(fmt, opts);
+ }
fail:
av_dict_free(&opts);
av_free(dev);
--
2.7.4
More information about the ffmpeg-devel
mailing list