[FFmpeg-devel] [PATCH 04/10] fftools/cmdutils: split common option handlers into their own file

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Thu Mar 17 17:30:04 EET 2022


Anton Khirnov:
> ---
>  fftools/Makefile                     |    2 +-
>  fftools/cmdutils.c                   | 1399 +--------------
>  fftools/cmdutils.h                   |  202 ---
>  fftools/ffmpeg_opt.c                 |    1 +
>  fftools/ffplay.c                     |    1 +
>  fftools/ffprobe.c                    |    1 +
>  fftools/{cmdutils.c => opt_common.c} | 2450 ++++++++------------------
>  fftools/opt_common.h                 |  231 +++
>  8 files changed, 985 insertions(+), 3302 deletions(-)
>  copy fftools/{cmdutils.c => opt_common.c} (60%)
>  create mode 100644 fftools/opt_common.h

Very weird stats. When I apply this, I get:

fftools/Makefile     |    2 +-
fftools/cmdutils.c   | 1399
+------------------------------------------------
 fftools/cmdutils.h   |  202 -------
 fftools/ffmpeg_opt.c |    1 +
 fftools/ffplay.c     |    1 +
 fftools/ffprobe.c    |    1 +
 fftools/opt_common.c | 1445
+++++++++++++++++++++++++++++++++++++++++++++++++++
 fftools/opt_common.h |  231 ++++++++
 8 files changed, 1685 insertions(+), 1597 deletions(-)



> +#if CONFIG_AVFILTER
> +static void show_help_filter(const char *name)
> +{
> +#if CONFIG_AVFILTER
> +    const AVFilter *f = avfilter_get_by_name(name);
> +    int i, count;
> +
> +    if (!name) {
> +        av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
> +        return;
> +    } else if (!f) {
> +        av_log(NULL, AV_LOG_ERROR, "Unknown filter '%s'.\n", name);
> +        return;
> +    }
> +
> +    printf("Filter %s\n", f->name);
> +    if (f->description)
> +        printf("  %s\n", f->description);
>  
> -        printf("    Supported framerates:");
> -        while (fps->num) {
> -            printf(" %d/%d", fps->num, fps->den);
> -            fps++;
> -        }
> -        printf("\n");
> +    if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
> +        printf("    slice threading supported\n");
> +
> +    printf("    Inputs:\n");
> +    count = avfilter_filter_pad_count(f, 0);
> +    for (i = 0; i < count; i++) {

You can use a local loop variable here and in several other places here.

> +        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
> +               av_get_media_type_string(avfilter_pad_get_type(f->inputs, i)));
>      }
> -    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 (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
> +        printf("        dynamic (depending on the options)\n");
> +    else if (!count)
> +        printf("        none (source filter)\n");
>  
> -    if (c->priv_class) {
> -        show_help_children(c->priv_class,
> -                           AV_OPT_FLAG_ENCODING_PARAM |
> -                           AV_OPT_FLAG_DECODING_PARAM);
> +    printf("    Outputs:\n");
> +    count = avfilter_filter_pad_count(f, 1);
> +    for (i = 0; i < count; i++) {
> +        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
> +               av_get_media_type_string(avfilter_pad_get_type(f->outputs, i)));
>      }
> +    if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
> +        printf("        dynamic (depending on the options)\n");
> +    else if (!count)
> +        printf("        none (sink filter)\n");
> +
> +    if (f->priv_class)
> +        show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM |
> +                                          AV_OPT_FLAG_AUDIO_PARAM);
> +    if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)
> +        printf("This filter has support for timeline through the 'enable' option.\n");
> +#else
> +    av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; "
> +           "can not to satisfy request\n");
> +#endif
>  }
> +#endif
>  
> -static char get_media_type_char(enum AVMediaType type)
> +static void show_help_bsf(const char *name)
>  {
> -    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 '?';
> +    const AVBitStreamFilter *bsf = av_bsf_get_by_name(name);
> +
> +    if (!name) {
> +        av_log(NULL, AV_LOG_ERROR, "No bitstream filter name specified.\n");
> +        return;
> +    } else if (!bsf) {
> +        av_log(NULL, AV_LOG_ERROR, "Unknown bit stream filter '%s'.\n", name);
> +        return;
>      }
> +
> +    printf("Bit stream filter %s\n", bsf->name);
> +    PRINT_CODEC_SUPPORTED(bsf, codec_ids, enum AVCodecID, "codecs",
> +                          AV_CODEC_ID_NONE, GET_CODEC_NAME);
> +    if (bsf->priv_class)
> +        show_help_children(bsf->priv_class, AV_OPT_FLAG_BSF_PARAM);
>  }
>  
> -static const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,
> -                                        int encoder)
> +int show_help(void *optctx, const char *opt, const char *arg)
>  {
> -    const AVCodec *c;
> -    while ((c = av_codec_iterate(iter))) {
> -        if (c->id == id &&
> -            (encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c)))
> -            return c;
> +    char *topic, *par;
> +    av_log_set_callback(log_callback_help);
> +
> +    topic = av_strdup(arg ? arg : "");
> +    if (!topic)
> +        return AVERROR(ENOMEM);
> +    par = strchr(topic, '=');
> +    if (par)
> +        *par++ = 0;
> +
> +    if (!*topic) {
> +        show_help_default(topic, par);
> +    } else if (!strcmp(topic, "decoder")) {
> +        show_help_codec(par, 0);
> +    } else if (!strcmp(topic, "encoder")) {
> +        show_help_codec(par, 1);
> +    } else if (!strcmp(topic, "demuxer")) {
> +        show_help_demuxer(par);
> +    } else if (!strcmp(topic, "muxer")) {
> +        show_help_muxer(par);
> +    } else if (!strcmp(topic, "protocol")) {
> +        show_help_protocol(par);
> +#if CONFIG_AVFILTER
> +    } else if (!strcmp(topic, "filter")) {
> +        show_help_filter(par);
> +#endif
> +    } else if (!strcmp(topic, "bsf")) {
> +        show_help_bsf(par);
> +    } else {
> +        show_help_default(topic, par);
>      }
> -    return NULL;
> +
> +    av_freep(&topic);
> +    return 0;
> +}
> +
> +static void print_codecs_for_id(enum AVCodecID id, int encoder)
> +{
> +    void *iter = NULL;
> +    const AVCodec *codec;
> +
> +    printf(" (%s: ", encoder ? "encoders" : "decoders");
> +
> +    while ((codec = next_codec_for_id(id, &iter, encoder)))
> +        printf("%s ", codec->name);
> +
> +    printf(")");
>  }
>  
>  static int compare_codec_desc(const void *a, const void *b)
> @@ -1534,17 +638,16 @@ static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
>      return nb_codecs;
>  }
>  
> -static void print_codecs_for_id(enum AVCodecID id, int encoder)
> +static char get_media_type_char(enum AVMediaType type)
>  {
> -    void *iter = NULL;
> -    const AVCodec *codec;
> -
> -    printf(" (%s: ", encoder ? "encoders" : "decoders");
> -
> -    while ((codec = next_codec_for_id(id, &iter, encoder)))
> -        printf("%s ", codec->name);
> -
> -    printf(")");
> +    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 '?';

AVMEDIA_TYPE_ATTACHMENT has obviously been added later. You now have an
opportunity to fix the formatting. You should use it.

> +    }
>  }
>  
>  int show_codecs(void *optctx, const char *opt, const char *arg)
> @@ -1666,21 +769,6 @@ int show_bsfs(void *optctx, const char *opt, const char *arg)
>      return 0;
>  }
>  
> +static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only, int muxdemuxers)
> +{
> +    void *ifmt_opaque = NULL;
> +    const AVInputFormat *ifmt  = NULL;
> +    void *ofmt_opaque = NULL;
> +    const AVOutputFormat *ofmt = NULL;
> +    const char *last_name;
> +    int is_dev;
> +
> +    printf("%s\n"
> +           " D. = Demuxing supported\n"
> +           " .E = Muxing supported\n"
> +           " --\n", device_only ? "Devices:" : "File formats:");
> +    last_name = "000";
> +    for (;;) {
> +        int decode = 0;
> +        int encode = 0;
> +        const char *name      = NULL;
> +        const char *long_name = NULL;
> +
> +        if (muxdemuxers !=SHOW_DEMUXERS) {
> +            ofmt_opaque = NULL;

Can use smaller scope; same below.

> +            while ((ofmt = av_muxer_iterate(&ofmt_opaque))) {
> +                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) {
> +            ifmt_opaque = NULL;
> +            while ((ifmt = av_demuxer_iterate(&ifmt_opaque))) {
> +                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;
> +            }
> +        }
> +        if (!name)
> +            break;
> +        last_name = name;
> +
> +        printf(" %c%c %-15s %s\n",
> +               decode ? 'D' : ' ',
> +               encode ? 'E' : ' ',
> +               name,
> +            long_name ? long_name:" ");
> +    }
> +    return 0;
> +}
> +


More information about the ffmpeg-devel mailing list