From patchwork Sun Mar 18 13:40:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Dekker X-Patchwork-Id: 8025 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.1.70 with SMTP id c67csp1630599jad; Sun, 18 Mar 2018 06:40:48 -0700 (PDT) X-Google-Smtp-Source: AG47ELvFUPDXMJXm1HReM84dt3L3bOf+85hqHk4ipCxV9+GqioLQih2KinVtqS8a4ULPXvUQMrCj X-Received: by 10.28.53.6 with SMTP id c6mr5885453wma.18.1521380448657; Sun, 18 Mar 2018 06:40:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521380448; cv=none; d=google.com; s=arc-20160816; b=mgp4keGpJTi75HBICzIZ4PitTEsbXY16ZRbK3iCCkay5eGz7JG8GsYD6DlY1e5q8Lf uULwTGbbW1jv2pgTCBWtuT/GHXE+HuVk0ueQWX5aogLVmcG4XL3K0fh4at0oUhmvdUkp wSSLQg15IKl6NDnLocSQuaroLyzri0oCdZ47+OHt3MlSXgC6Gn8E85hSUsAvRZpnsL3L 99tPYgWh2Wgm7uXT/jBLmCYFjnQ1Hd4vMUsVVwi/WUqwkP0l9GNJlrOWgzUESZZpcvx2 JKmFrB9jDZ05O/5RynuakQuTlovYMIlUGHDfIdRUfPmGmvK94nRDLKTpyshIvalFpZww WHoA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:dkim-signature:delivered-to :arc-authentication-results; bh=KsjD69y74h8rpHjuKOKtdCP1yb/2sKb6LO06lgcXMLw=; b=BN4mnmSHfUTa/OfEy165Pn0GUJ6S1ztVJNhxnW0CSWM0dHVC5hOxHO39w6EP5jmsjU 3CUpTPjPEU5MTzSlpLU8/Vcdv/QIAmUKWEk78oLmThSqDfvwkU8yf6LR6QfA5qvTy2fD VBJo5+zvetNPPssZ7wGG3KnGfynkRfKN1GvKW4fwkHYuFDoaqLzKqX2EOBhRvFiscyfd lptUV422RNrPn7LO2Bd9heLB4fgPRI6h0BITM435h6EOxluce+604cIEL6N1daH/W8n1 uxTpc2XKRLjf/wxILeAlt8H3hcd+6Lur0gWQd5EzaWIm5c6PUSwWv8Jp4g27DSjClAsn Hzgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@itanimul.li header.s=fm1 header.b=fRmnAUWl; dkim=neutral (body hash did not verify) header.i=@messagingengine.com header.s=fm2 header.b=EOo5u7pu; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id o63si6969807wmb.213.2018.03.18.06.40.48; Sun, 18 Mar 2018 06:40:48 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@itanimul.li header.s=fm1 header.b=fRmnAUWl; dkim=neutral (body hash did not verify) header.i=@messagingengine.com header.s=fm2 header.b=EOo5u7pu; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 703B2689CC7; Sun, 18 Mar 2018 15:40:23 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from out5-smtp.messagingengine.com (out5-smtp.messagingengine.com [66.111.4.29]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0D950680A24 for ; Sun, 18 Mar 2018 15:40:16 +0200 (EET) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 2F5DD2098B; Sun, 18 Mar 2018 09:40:28 -0400 (EDT) Received: from frontend1 ([10.202.2.160]) by compute4.internal (MEProxy); Sun, 18 Mar 2018 09:40:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=itanimul.li; h= cc:date:from:in-reply-to:message-id:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=PWUzr3ffDZziqe8Et c4w0S5fCc6sVVuK3WBsWXA4wpc=; b=fRmnAUWlb6bLijcdhVaxKPNBVrrpjKEo7 t2pmQbm4yBQAVDliouBy3N93C/xqfX8KyHSEHXvfAG15ISKK53Yj5Ym+HjItkStL ZimE5dNMIPcQbWLai7p5tGavyTwfvc3Ny86898xghKorwNSVYUEhdaLQdg2uItvm gJ27T1LnOFcAxoriBMEkPF6r+CQhPVw6WxWGCGYpWKV1TDkheMtiqmFiamar3N09 FQD0anUNgTG3kREborR07Cmb09zcfGWyUsb+oJWewLxGSKiAk+Xcll/+rqD2uvWJ 1EAidkqp4SrriO2hOVqiBZ37RZd85GogSCwXyOW/2PV+ZBJNI8Qfw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=PWUzr3ffDZziqe8Etc4w0S5fCc6sVVuK3WBsWXA4wpc=; b=EOo5u7pu PUB1IFRwTNX/LzH2Wjs7aDIMYhKtgCKcIDrfHIbXH/Aoq11uPy/KN52fQ7Ged8KD IV2cBTMwitntM+X/SqKLhJ9XbBhlkl6TiUxvJ18ksnPs73IN513+PZRETNQAZNK0 N3lYPrh0tRtwFXQ6MnZKmb+PEGp/QMTg7tYe0IBYW105zMfQf0+y8uN1p8oZ1Egz BhX9c4Cfz/CRHFbPArX6QG7CXak92WnKUio5970/One8cjTn39gefz9c6R3J/Jk2 qj1sG3u1xjoE2mM9v+tTKv1lNOQPtUHDRE2oWX2d5smlVn/8W4KRZghX8glaTxXv Um6kALsgxoGqhg== X-ME-Sender: Received: from localhost.localdomain (cpc75394-sotn16-2-0-cust168.15-1.cable.virginm.net [82.22.8.169]) by mail.messagingengine.com (Postfix) with ESMTPA id 7C0147E0EE; Sun, 18 Mar 2018 09:40:27 -0400 (EDT) From: josh@itanimul.li To: ffmpeg-devel@ffmpeg.org Date: Sun, 18 Mar 2018 13:40:17 +0000 Message-Id: <20180318134018.62605-3-josh@itanimul.li> X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180318134018.62605-1-josh@itanimul.li> References: <20180318134018.62605-1-josh@itanimul.li> Subject: [FFmpeg-devel] [PATCH 3/4] cmdutils: use new iteration APIs X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Josh de Kock MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Josh de Kock --- fftools/cmdutils.c | 239 +++++++++++++++++++++++++---------------------------- 1 file changed, 112 insertions(+), 127 deletions(-) diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index 708a849f51..2da313cc0a 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); @@ -2132,7 +2136,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; @@ -2147,7 +2151,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; } @@ -2162,7 +2166,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; @@ -2177,7 +2181,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; } @@ -2216,7 +2220,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; @@ -2227,24 +2232,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); @@ -2254,7 +2249,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; @@ -2265,22 +2261,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);