/* * 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. Load more
/* * 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_AVFILTER static void show_help_filter(const char *name)