Newer
Older
return ret;
if (*opts)
opts++;
}
return ret;
}
#endif
void print_error(const char *filename, int err)
{
const char *errbuf_ptr = errbuf;
if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
errbuf_ptr = strerror(AVUNERROR(err));
av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
static int warned_cfg = 0;
#define INDENT 1
#define SHOW_VERSION 2
#define SHOW_CONFIG 4
Stefano Sabatini
committed
#define SHOW_COPYRIGHT 8
#define PRINT_LIB_INFO(libname, LIBNAME, flags, level) \
const char *indent = flags & INDENT? " " : ""; \
if (flags & SHOW_VERSION) { \
"%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n", \
indent, #libname, \
LIB##LIBNAME##_VERSION_MAJOR, \
LIB##LIBNAME##_VERSION_MINOR, \
LIB##LIBNAME##_VERSION_MICRO, \
version >> 16, version >> 8 & 0xff, version & 0xff); \
} \
if (flags & SHOW_CONFIG) { \
const char *cfg = libname##_configuration(); \
if (strcmp(FFMPEG_CONFIGURATION, cfg)) { \
if (!warned_cfg) { \
"%sWARNING: library configuration mismatch\n", \
warned_cfg = 1; \
} \
av_log(NULL, level, "%s%-11s configuration: %s\n", \
indent, #libname, cfg); \
} \
} \
} \
Stefano Sabatini
committed
static void print_all_libs_info(int flags, int level)
Stefano Sabatini
committed
{
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(avresample, AVRESAMPLE, flags, level);
PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
PRINT_LIB_INFO(swresample,SWRESAMPLE, flags, level);
PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
Stefano Sabatini
committed
}
Stefano Sabatini
committed
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, this_year);
av_log(NULL, level, "\n");
av_log(NULL, level, "%sbuilt on %s %s with %s\n",
indent, __DATE__, __TIME__, CC_IDENT);
Stefano Sabatini
committed
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 ) {
strncpy(conflist, "~--", 3);
}
// Compensate for the weirdness this would cause
// when passing 'pkg-config --static'.
while ( (remove_tilde = strstr(str, "pkg-config~")) != NULL ) {
strncpy(remove_tilde, "pkg-config ",11);
}
splitconf = strtok(str, "~");
av_log(NULL, level, "\n%sconfiguration:\n",indent);
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 (idx)
return;
Stefano Sabatini
committed
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);
Stefano Sabatini
committed
print_program_info (0 , AV_LOG_INFO);
print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
Jeff Downs
committed
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;
}
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 );
Diego Biurrun
committed
#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 );
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 );
Jeff Downs
committed
return 0;
int show_formats(void *optctx, const char *opt, const char *arg)
AVInputFormat *ifmt = NULL;
AVOutputFormat *ofmt = NULL;
printf("File formats:\n"
" D. = Demuxing supported\n"
" .E = Muxing supported\n"
" --\n");
last_name = "000";
for (;;) {
int decode = 0;
int encode = 0;
const char *name = NULL;
const char *long_name = NULL;
while ((ofmt = av_oformat_next(ofmt))) {
if ((name == NULL || strcmp(ofmt->name, name) < 0) &&
strcmp(ofmt->name, last_name) > 0) {
name = ofmt->name;
long_name = ofmt->long_name;
encode = 1;
while ((ifmt = av_iformat_next(ifmt))) {
if ((name == NULL || 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;
printf(" %s%s %-15s %s\n",
decode ? "D" : " ",
encode ? "E" : " ",
name,
long_name ? long_name:" ");
}
Jeff Downs
committed
return 0;
#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
if (codec->field) { \
const type *p = codec->field; \
\
printf(" Supported " list_name ":"); \
while (*p != term) { \
get_name(*p); \
printf(" %s", name); \
p++; \
} \
printf("\n"); \
} \
static void print_codec(const AVCodec *c)
{
int encoder = av_codec_is_encoder(c);
printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
c->long_name ? c->long_name : "");
if (c->type == AVMEDIA_TYPE_VIDEO ||
c->type == AVMEDIA_TYPE_AUDIO) {
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
printf(" Threading capabilities: ");
switch (c->capabilities & (CODEC_CAP_FRAME_THREADS |
CODEC_CAP_SLICE_THREADS)) {
case CODEC_CAP_FRAME_THREADS |
CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
case CODEC_CAP_FRAME_THREADS: printf("frame"); break;
case CODEC_CAP_SLICE_THREADS: printf("slice"); break;
default: printf("no"); break;
}
printf("\n");
}
if (c->supported_framerates) {
const AVRational *fps = c->supported_framerates;
printf(" Supported framerates:");
while (fps->num) {
printf(" %d/%d", fps->num, fps->den);
fps++;
}
printf("\n");
}
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 (c->priv_class) {
show_help_children(c->priv_class,
AV_OPT_FLAG_ENCODING_PARAM |
AV_OPT_FLAG_DECODING_PARAM);
}
}
static char get_media_type_char(enum AVMediaType type)
{
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';
}
static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
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;
}
return NULL;
}
static int compare_codec_desc(const void *a, const void *b)
{
const AVCodecDescriptor * const *da = a;
const AVCodecDescriptor * const *db = b;
return (*da)->type != (*db)->type ? (*da)->type - (*db)->type :
strcmp((*da)->name, (*db)->name);
}
static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
{
const AVCodecDescriptor *desc = NULL;
const AVCodecDescriptor **codecs;
unsigned nb_codecs = 0, i = 0;
while ((desc = avcodec_descriptor_next(desc)))
nb_codecs++;
if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
}
desc = NULL;
while ((desc = avcodec_descriptor_next(desc)))
codecs[i++] = desc;
av_assert0(i == nb_codecs);
qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
*rcodecs = codecs;
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);
" D..... = Decoding supported\n"
" .E.... = Encoding supported\n"
" ..V... = Video codec\n"
" ..A... = Audio codec\n"
" ..S... = Subtitle codec\n"
" ...I.. = Intra frame-only codec\n"
" ....L. = Lossy compression\n"
" .....S = Lossless compression\n"
" -------\n");
for (i = 0; i < nb_codecs; i++) {
const AVCodecDescriptor *desc = codecs[i];
printf(" ");
printf(avcodec_find_decoder(desc->id) ? "D" : ".");
printf(avcodec_find_encoder(desc->id) ? "E" : ".");
printf("%c", get_media_type_char(desc->type));
printf((desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
printf((desc->props & AV_CODEC_PROP_LOSSY) ? "L" : ".");
printf((desc->props & AV_CODEC_PROP_LOSSLESS) ? "S" : ".");
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;
}
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;
}
}
printf("\n");
}
}
static void print_codecs(int encoder)
{
const AVCodecDescriptor **codecs;
unsigned i, nb_codecs = get_codecs_sorted(&codecs);
" V..... = Video\n"
" A..... = Audio\n"
" S..... = Subtitle\n"
" .F.... = Frame-level multithreading\n"
" ..S... = Slice-level multithreading\n"
" ...X.. = Codec is experimental\n"
" ....B. = Supports draw_horiz_band\n"
" .....D = Supports direct rendering method 1\n"
" ------\n",
for (i = 0; i < nb_codecs; i++) {
const AVCodecDescriptor *desc = codecs[i];
const AVCodec *codec = NULL;
while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
printf(" %c", get_media_type_char(desc->type));
printf((codec->capabilities & CODEC_CAP_FRAME_THREADS) ? "F" : ".");
printf((codec->capabilities & CODEC_CAP_SLICE_THREADS) ? "S" : ".");
printf((codec->capabilities & CODEC_CAP_EXPERIMENTAL) ? "X" : ".");
printf((codec->capabilities & CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
printf((codec->capabilities & CODEC_CAP_DR1) ? "D" : ".");
printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
if (strcmp(codec->name, desc->name))
printf(" (codec %s)", desc->name);
printf("\n");
}
}
int show_decoders(void *optctx, const char *opt, const char *arg)
{
print_codecs(0);
return 0;
}
int show_encoders(void *optctx, const char *opt, const char *arg)
Jeff Downs
committed
return 0;
int show_bsfs(void *optctx, const char *opt, const char *arg)
printf("Bitstream filters:\n");
while ((bsf = av_bitstream_filter_next(bsf)))
printf("%s\n", bsf->name);
Jeff Downs
committed
return 0;
int show_protocols(void *optctx, const char *opt, const char *arg)
void *opaque = NULL;
const char *name;
printf("Supported file protocols:\n"
"Input:\n");
while ((name = avio_enum_protocols(&opaque, 0)))
printf("%s\n", name);
printf("Output:\n");
while ((name = avio_enum_protocols(&opaque, 1)))
printf("%s\n", name);
return 0;
int show_filters(void *optctx, const char *opt, const char *arg)
{
const AVFilter av_unused(*filter) = NULL;
char descr[64], *descr_cur;
int i, j;
const AVFilterPad *pad;
" T.. = Timeline support\n"
" .S. = Slice threading\n"
" ..C = Commmand support\n"
" A = Audio input/output\n"
" V = Video input/output\n"
" N = Dynamic number and/or type of input/output\n"
" | = Source or sink filter\n");
#if CONFIG_AVFILTER
while ((filter = avfilter_next(filter))) {
descr_cur = descr;
for (i = 0; i < 2; i++) {
if (i) {
*(descr_cur++) = '-';
*(descr_cur++) = '>';
}
pad = i ? filter->outputs : filter->inputs;
for (j = 0; pad && pad[j].name; j++) {
if (descr_cur >= descr + sizeof(descr) - 4)
break;
*(descr_cur++) = get_media_type_char(pad[j].type);
}
if (!j)
*(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||
( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';
printf(" %c%c%c %-16s %-10s %s\n",
filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',
filter->flags & AVFILTER_FLAG_SLICE_THREADS ? 'S' : '.',
filter->process_command ? 'C' : '.',
filter->name, descr, filter->description);
#endif
Jeff Downs
committed
return 0;
}
int show_colors(void *optctx, const char *opt, const char *arg)
{
const char *name;
const uint8_t *rgb;
int i;
printf("%-32s #RRGGBB\n", "name");
for (i = 0; name = av_get_known_color_name(i, &rgb); i++)
printf("%-32s #%02x%02x%02x\n", name, rgb[0], rgb[1], rgb[2]);
return 0;
int show_pix_fmts(void *optctx, const char *opt, const char *arg)
const AVPixFmtDescriptor *pix_desc = NULL;
printf("Pixel formats:\n"
"I.... = Supported Input format for conversion\n"
".O... = Supported Output format for conversion\n"
"..H.. = Hardware accelerated format\n"
"...P. = Paletted format\n"
"....B = Bitstream format\n"
"FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
"-----\n");
#if !CONFIG_SWSCALE
# define sws_isSupportedInput(x) 0
# define sws_isSupportedOutput(x) 0
#endif
while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
printf("%c%c%c%c%c %-16s %d %2d\n",
sws_isSupportedInput (pix_fmt) ? 'I' : '.',
sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL ? 'H' : '.',
pix_desc->flags & AV_PIX_FMT_FLAG_PAL ? 'P' : '.',
pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
pix_desc->name,
pix_desc->nb_components,
av_get_bits_per_pixel(pix_desc));
}
Jeff Downs
committed
return 0;
}
int show_layouts(void *optctx, const char *opt, const char *arg)
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
{
int i = 0;
uint64_t layout, j;
const char *name, *descr;
printf("Individual channels:\n"
"NAME DESCRIPTION\n");
for (i = 0; i < 63; i++) {
name = av_get_channel_name((uint64_t)1 << i);
if (!name)
continue;
descr = av_get_channel_description((uint64_t)1 << i);
printf("%-12s%s\n", name, descr);
}
printf("\nStandard channel layouts:\n"
"NAME DECOMPOSITION\n");
for (i = 0; !av_get_standard_channel_layout(i, &layout, &name); i++) {
if (name) {
printf("%-12s", name);
for (j = 1; j; j <<= 1)
if ((layout & j))
printf("%s%s", (layout & (j - 1)) ? "+" : "", av_get_channel_name(j));
printf("\n");
}
}
return 0;
}
int show_sample_fmts(void *optctx, const char *opt, const char *arg)
{
int i;
char fmt_str[128];
for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
return 0;
}
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
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))) {
int printed = 0;
while ((codec = next_codec_for_id(desc->id, codec, 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);
}
}
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
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_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);
}
static void show_help_filter(const char *name)
{
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);
printf("Filter %s\n", f->name);
if (f->description)
printf(" %s\n", f->description);
if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
printf(" slice threading supported\n");
printf(" Inputs:\n");
count = avfilter_pad_count(f->inputs);
for (i = 0; i < count; i++) {
printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
media_type_string(avfilter_pad_get_type(f->inputs, i)));
}
if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
printf(" dynamic (depending on the options)\n");
else if (!count)
printf(" none (source filter)\n");
printf(" Outputs:\n");
count = avfilter_pad_count(f->outputs);
for (i = 0; i < count; i++) {
printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
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
int show_help(void *optctx, const char *opt, const char *arg)
{
char *topic, *par;
av_log_set_callback(log_callback_help);
topic = av_strdup(arg ? arg : "");
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, "filter")) {
show_help_filter(par);
} else {
show_help_default(topic, par);
}
av_freep(&topic);
return 0;
}
int read_yesno(void)
{
int c = getchar();
int yesno = (av_toupper(c) == 'Y');
while (c != '\n' && c != EOF)
c = getchar();
return yesno;
}
int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
{
FILE *f = fopen(filename, "rb");
if (!f) {
av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
strerror(errno));
return AVERROR(errno);
}
fseek(f, 0, SEEK_END);
*size = ftell(f);
fseek(f, 0, SEEK_SET);
if (*size == (size_t)-1) {
av_log(NULL, AV_LOG_ERROR, "IO error: %s\n", strerror(errno));
return AVERROR(errno);
}
*bufptr = av_malloc(*size + 1);
if (!*bufptr) {
av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
fclose(f);
return AVERROR(ENOMEM);
}
ret = fread(*bufptr, 1, *size, f);
if (ret < *size) {
av_free(*bufptr);
if (ferror(f)) {
av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
filename, strerror(errno));
ret = AVERROR(errno);
} else
ret = AVERROR_EOF;
} else {
ret = 0;
(*bufptr)[(*size)++] = '\0';
fclose(f);
}
FILE *get_preset_file(char *filename, size_t filename_size,
const char *preset_name, int is_path,
const char *codec_name)
{
FILE *f = NULL;
int i;
const char *base[3] = { getenv("FFMPEG_DATADIR"),
if (is_path) {
av_strlcpy(filename, preset_name, filename_size);
f = fopen(filename, "r");
} else {
#ifdef _WIN32
char datadir[MAX_PATH], *ls;
base[2] = NULL;
if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
{
for (ls = datadir; ls < datadir + strlen(datadir); ls++)
if (*ls == '\\') *ls = '/';
if (ls = strrchr(datadir, '/'))
{
*ls = 0;
strncat(datadir, "/ffpresets", sizeof(datadir) - 1 - strlen(datadir));
base[2] = datadir;
}
}
#endif
for (i = 0; i < 3 && !f; i++) {
if (!base[i])
continue;
snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
i != 1 ? "" : "/.ffmpeg", preset_name);
f = fopen(filename, "r");
if (!f && codec_name) {
snprintf(filename, filename_size,
base[i], i != 1 ? "" : "/.ffmpeg", codec_name,
f = fopen(filename, "r");
}
}
}
return f;
}
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
{
int ret = avformat_match_stream_specifier(s, st, spec);
if (ret < 0)
av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
return ret;
AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
AVFormatContext *s, AVStream *st, AVCodec *codec)
{
AVDictionary *ret = NULL;
AVDictionaryEntry *t = NULL;
int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
: AV_OPT_FLAG_DECODING_PARAM;
char prefix = 0;
const AVClass *cc = avcodec_get_class();
if (!codec)
codec = s->oformat ? avcodec_find_encoder(codec_id)
: avcodec_find_decoder(codec_id);
switch (st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
prefix = 'v';
flags |= AV_OPT_FLAG_VIDEO_PARAM;
break;
case AVMEDIA_TYPE_AUDIO:
prefix = 'a';
flags |= AV_OPT_FLAG_AUDIO_PARAM;
break;
case AVMEDIA_TYPE_SUBTITLE:
prefix = 's';
flags |= AV_OPT_FLAG_SUBTITLE_PARAM;
break;
}
while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
char *p = strchr(t->key, ':');
/* check stream specification in opt name */
if (p)
switch (check_stream_specifier(s, st, p + 1)) {
case 1: *p = 0; break;
case 0: continue;
default: return NULL;
}
if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
(codec && codec->priv_class &&
av_opt_find(&codec->priv_class, t->key, NULL, flags,
AV_OPT_SEARCH_FAKE_OBJ)))
av_dict_set(&ret, t->key, t->value, 0);
else if (t->key[0] == prefix &&
av_opt_find(&cc, t->key + 1, NULL, flags,
AV_OPT_SEARCH_FAKE_OBJ))
av_dict_set(&ret, t->key + 1, t->value, 0);
if (p)
*p = ':';
}
return ret;
}
AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
AVDictionary *codec_opts)
{
int i;
AVDictionary **opts;
if (!s->nb_streams)
return NULL;
opts = av_mallocz(s->nb_streams * sizeof(*opts));
if (!opts) {
av_log(NULL, AV_LOG_ERROR,
"Could not alloc memory for stream options.\n");
return NULL;
}
for (i = 0; i < s->nb_streams; i++)
opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id,
s, s->streams[i], NULL);
return opts;
}