1489 lines · 47.9 KB · C
RawDownload
/* * Option handlers shared between the tools. * * 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 "config.h" #include <stdio.h> #include "cmdutils.h"#include "opt_common.h" #include "libavutil/avassert.h"#include "libavutil/avstring.h"#include "libavutil/bprint.h"#include "libavutil/channel_layout.h"#include "libavutil/cpu.h"#include "libavutil/dict.h"#include "libavutil/error.h"#include "libavutil/ffversion.h"#include "libavutil/log.h"#include "libavutil/mem.h"#include "libavutil/parseutils.h"#include "libavutil/pixdesc.h"#include "libavutil/version.h" #include "libavcodec/avcodec.h"#include "libavcodec/bsf.h"#include "libavcodec/codec.h"#include "libavcodec/codec_desc.h"#include "libavcodec/version.h" #include "libavformat/avformat.h"#include "libavformat/version.h" #include "libavdevice/avdevice.h"#include "libavdevice/version.h" #include "libavfilter/avfilter.h"#include "libavfilter/version.h" #include "libswscale/swscale.h"#include "libswscale/version.h" #include "libswresample/swresample.h"#include "libswresample/version.h" #include "libpostproc/postprocess.h"#include "libpostproc/version.h" enum show_muxdemuxers {    SHOW_DEFAULT,    SHOW_DEMUXERS,    SHOW_MUXERS,}; static FILE *report_file;static int report_file_level = AV_LOG_DEBUG; int show_license(void *optctx, const char *opt, const char *arg){#if CONFIG_NONFREE    printf(    "This version of %s has nonfree parts compiled in.\n"    "Therefore it is not legally redistributable.\n",    program_name );#elif CONFIG_GPLV3    printf(    "%s is free software; you can redistribute it and/or modify\n"    "it under the terms of the GNU General Public License as published by\n"    "the Free Software Foundation; either version 3 of the License, or\n"    "(at your option) any later version.\n"    "\n"    "%s is distributed in the hope that it will be useful,\n"    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"    "GNU General Public License for more details.\n"    "\n"    "You should have received a copy of the GNU General Public License\n"    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",    program_name, program_name, program_name );#elif CONFIG_GPL    printf(    "%s is free software; you can redistribute it and/or modify\n"    "it under the terms of the GNU General Public License as published by\n"    "the Free Software Foundation; either version 2 of the License, or\n"    "(at your option) any later version.\n"    "\n"    "%s is distributed in the hope that it will be useful,\n"    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"    "GNU General Public License for more details.\n"    "\n"    "You should have received a copy of the GNU General Public License\n"    "along with %s; if not, write to the Free Software\n"    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",    program_name, program_name, program_name );#elif CONFIG_LGPLV3    printf(    "%s is free software; you can redistribute it and/or modify\n"    "it under the terms of the GNU Lesser General Public License as published by\n"    "the Free Software Foundation; either version 3 of the License, or\n"    "(at your option) any later version.\n"    "\n"    "%s is distributed in the hope that it will be useful,\n"    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"    "GNU Lesser General Public License for more details.\n"    "\n"    "You should have received a copy of the GNU Lesser General Public License\n"    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",    program_name, program_name, program_name );#else    printf(    "%s is free software; you can redistribute it and/or\n"    "modify it under the terms of the GNU Lesser General Public\n"    "License as published by the Free Software Foundation; either\n"    "version 2.1 of the License, or (at your option) any later version.\n"    "\n"    "%s is distributed in the hope that it will be useful,\n"    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"    "Lesser General Public License for more details.\n"    "\n"    "You should have received a copy of the GNU Lesser General Public\n"    "License along with %s; if not, write to the Free Software\n"    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",    program_name, program_name, program_name );#endif     return 0;} static int warned_cfg = 0; #define INDENT        1#define SHOW_VERSION  2#define SHOW_CONFIG   4#define SHOW_COPYRIGHT 8 #define PRINT_LIB_INFO(libname, LIBNAME, flags, level)                  \    if (CONFIG_##LIBNAME) {                                             \        const char *indent = flags & INDENT? "  " : "";                 \        if (flags & SHOW_VERSION) {                                     \            unsigned int version = libname##_version();                 \            av_log(NULL, level,                                         \                   "%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n",            \                   indent, #libname,                                    \                   LIB##LIBNAME##_VERSION_MAJOR,                        \                   LIB##LIBNAME##_VERSION_MINOR,                        \                   LIB##LIBNAME##_VERSION_MICRO,                        \                   AV_VERSION_MAJOR(version), AV_VERSION_MINOR(version),\                   AV_VERSION_MICRO(version));                          \        }                                                               \        if (flags & SHOW_CONFIG) {                                      \            const char *cfg = libname##_configuration();                \            if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \                if (!warned_cfg) {                                      \                    av_log(NULL, level,                                 \                            "%sWARNING: library configuration mismatch\n", \                            indent);                                    \                    warned_cfg = 1;                                     \                }                                                       \                av_log(NULL, level, "%s%-11s configuration: %s\n",      \                        indent, #libname, cfg);                         \            }                                                           \        }                                                               \    }                                                                   \ static void print_all_libs_info(int flags, int level){    PRINT_LIB_INFO(avutil,     AVUTIL,     flags, level);    PRINT_LIB_INFO(avcodec,    AVCODEC,    flags, level);    PRINT_LIB_INFO(avformat,   AVFORMAT,   flags, level);    PRINT_LIB_INFO(avdevice,   AVDEVICE,   flags, level);    PRINT_LIB_INFO(avfilter,   AVFILTER,   flags, level);    PRINT_LIB_INFO(swscale,    SWSCALE,    flags, level);    PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level);    PRINT_LIB_INFO(postproc,   POSTPROC,   flags, level);} static void print_program_info(int flags, int level){    const char *indent = flags & INDENT? "  " : "";     av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);    if (flags & SHOW_COPYRIGHT)        av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",               program_birth_year, CONFIG_THIS_YEAR);    av_log(NULL, level, "\n");    av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);     av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);} static void print_buildconf(int flags, int level){    const char *indent = flags & INDENT ? "  " : "";    char str[] = { FFMPEG_CONFIGURATION };    char *conflist, *remove_tilde, *splitconf;     // Change all the ' --' strings to '~--' so that    // they can be identified as tokens.    while ((conflist = strstr(str, " --")) != NULL) {        conflist[0] = '~';    }     // Compensate for the weirdness this would cause    // when passing 'pkg-config --static'.    while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {        remove_tilde[sizeof("pkg-config~") - 2] = ' ';    }     splitconf = strtok(str, "~");    av_log(NULL, level, "\n%sconfiguration:\n", indent);    while (splitconf != NULL) {        av_log(NULL, level, "%s%s%s\n", indent, indent, splitconf);        splitconf = strtok(NULL, "~");    }} void show_banner(int argc, char **argv, const OptionDef *options){    int idx = locate_option(argc, argv, options, "version");    if (hide_banner || idx)        return;     print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);    print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_INFO);    print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);} int show_version(void *optctx, const char *opt, const char *arg){    av_log_set_callback(log_callback_help);    print_program_info (SHOW_COPYRIGHT, AV_LOG_INFO);    print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);     return 0;} int show_buildconf(void *optctx, const char *opt, const char *arg){    av_log_set_callback(log_callback_help);    print_buildconf      (INDENT|0, AV_LOG_INFO);     return 0;} #define PRINT_CODEC_SUPPORTED(codec, config, type, name, elem, fmt, ...)        \    do {                                                                        \        int num = 0;                                                            \        const type *elem = NULL;                                                \        avcodec_get_supported_config(NULL, codec, config, 0,                    \                                     (const void **) &elem, &num);              \        if (elem) {                                                             \            printf("    Supported " name ":");                                  \            for (int i = 0; i < num; i++) {                                     \                printf(" " fmt, __VA_ARGS__);                                   \                elem++;                                                         \            }                                                                   \            printf("\n");                                                       \        }                                                                       \    } while (0) static const char *get_channel_layout_desc(const AVChannelLayout *layout, AVBPrint *bp){    int ret;    av_bprint_clear(bp);    ret = av_channel_layout_describe_bprint(layout, bp);    if (!av_bprint_is_complete(bp) || ret < 0)        return "unknown/invalid";    return bp->str;} static void print_codec(const AVCodec *c){    int encoder = av_codec_is_encoder(c);    AVBPrint desc;     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_DELAY)        printf("delay ");    if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)        printf("small ");    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_OTHER_THREADS))        printf("threads ");    if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)        printf("avoidprobe ");    if (c->capabilities & AV_CODEC_CAP_HARDWARE)        printf("hardware ");    if (c->capabilities & AV_CODEC_CAP_HYBRID)        printf("hybrid ");    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_OTHER_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_OTHER_THREADS: printf("other");           break;        default:                         printf("none");            break;        }        printf("\n");    }     if (avcodec_get_hw_config(c, 0)) {        printf("    Supported hardware devices: ");        for (int i = 0;; i++) {            const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);            const char *name;            if (!config)                break;            name = av_hwdevice_get_type_name(config->device_type);            if (name)                printf("%s ", name);        }        printf("\n");    }     PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_FRAME_RATE, AVRational, "framerates",                          fps, "%d/%d", fps->num, fps->den);    PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_PIX_FORMAT, enum AVPixelFormat,                          "pixel formats", fmt,  "%s", av_get_pix_fmt_name(*fmt));    PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_SAMPLE_RATE, int, "sample rates",                          rate, "%d", *rate);    PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_SAMPLE_FORMAT, enum AVSampleFormat,                          "sample formats", fmt, "%s", av_get_sample_fmt_name(*fmt));     av_bprint_init(&desc, 0, AV_BPRINT_SIZE_AUTOMATIC);    PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_CHANNEL_LAYOUT, AVChannelLayout,                          "channel layouts", layout, "%s",                          get_channel_layout_desc(layout, &desc));    av_bprint_finalize(&desc, NULL);     if (c->priv_class) {        show_help_children(c->priv_class,                           AV_OPT_FLAG_ENCODING_PARAM |                           AV_OPT_FLAG_DECODING_PARAM);    }} static const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,                                        int encoder){    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;    }    return NULL;} 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))) {        void *iter = NULL;        int printed = 0;         while ((codec = next_codec_for_id(desc->id, &iter, 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);     if (!fmt) {        av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);        return;    }     printf("Demuxer %s [%s]:\n", fmt->name, fmt->long_name);     if (fmt->extensions)        printf("    Common extensions: %s.\n", fmt->extensions);     if (fmt->priv_class)        show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM);} static void show_help_protocol(const char *name){    const AVClass *proto_class;     if (!name) {        av_log(NULL, AV_LOG_ERROR, "No protocol name specified.\n");        return;    }     proto_class = avio_protocol_get_class(name);    if (!proto_class) {        av_log(NULL, AV_LOG_ERROR, "Unknown protocol '%s'.\n", name);        return;    }     show_help_children(proto_class, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM);} static void show_help_muxer(const char *name){    const AVCodecDescriptor *desc;    const AVOutputFormat *fmt = av_guess_format(name, NULL, NULL);     if (!fmt) {        av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);        return;    }     printf("Muxer %s [%s]:\n", fmt->name, fmt->long_name);     if (fmt->extensions)        printf("    Common extensions: %s.\n", fmt->extensions);    if (fmt->mime_type)        printf("    Mime type: %s.\n", fmt->mime_type);    if (fmt->video_codec != AV_CODEC_ID_NONE &&        (desc = avcodec_descriptor_get(fmt->video_codec))) {        printf("    Default video codec: %s.\n", desc->name);    }    if (fmt->audio_codec != AV_CODEC_ID_NONE &&        (desc = avcodec_descriptor_get(fmt->audio_codec))) {        printf("    Default audio codec: %s.\n", desc->name);    }    if (fmt->subtitle_codec != AV_CODEC_ID_NONE &&        (desc = avcodec_descriptor_get(fmt->subtitle_codec))) {        printf("    Default subtitle codec: %s.\n", desc->name);    }     if (fmt->priv_class)        show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM);} #if CONFIG_AVFILTERstatic void show_help_filter(const char *name)

Lines 1–500 of 1489.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t