Newer
Older
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);
}
}
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
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_SUBTITLE: return 'S';
default: return '?';
}
}
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 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 *desc = NULL;
" 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");
while ((desc = avcodec_descriptor_next(desc))) {
const AVCodec *codec = NULL;
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");
}
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
}
static void print_codecs(int encoder)
{
const AVCodecDescriptor *desc = NULL;
printf("%s:\n"
" V... = Video\n"
" A... = Audio\n"
" S... = Subtitle\n"
" .F.. = Frame-level multithreading\n"
" ..S. = Slice-level multithreading\n"
" ...X = Codec is experimental\n"
" ---\n",
encoder ? "Encoders" : "Decoders");
while ((desc = avcodec_descriptor_next(desc))) {
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(" %-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)
{
print_codecs(1);
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);
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);
int show_filters(void *optctx, const char *opt, const char *arg)
{
#if CONFIG_AVFILTER
const AVFilter *filter = NULL;
printf("Filters:\n");
while ((filter = avfilter_next(filter)))
printf("%-16s %s\n", filter->name, filter->description);
#else
printf("No filters available: libavfilter disabled\n");
#endif
}
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));
}
}
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;
}
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
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 Libav, "
"but no %s for it are available. Libav 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 Libav.\n",
name);
}
}
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
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);
return;
}
printf("Filter %s [%s]:\n", f->name, f->description);
if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
printf(" slice threading supported\n");
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
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");
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");
if (f->priv_class)
show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM |
AV_OPT_FLAG_AUDIO_PARAM);
}
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 : "");
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, "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);
}
ret = fseek(f, 0, SEEK_END);
if (ret == -1) {
ret = AVERROR(errno);
goto out;
}
ret = ftell(f);
if (ret < 0) {
ret = AVERROR(errno);
goto out;
}
*size = ret;
ret = fseek(f, 0, SEEK_SET);
if (ret == -1) {
ret = AVERROR(errno);
goto out;
}
*bufptr = av_malloc(*size + 1);
if (!*bufptr) {
av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
ret = AVERROR(ENOMEM);
goto out;
}
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);
}
void init_pts_correction(PtsCorrectionContext *ctx)
{
ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
ctx->last_pts = ctx->last_dts = INT64_MIN;
}
int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts,
int64_t dts)
{
int64_t pts = AV_NOPTS_VALUE;
if (dts != AV_NOPTS_VALUE) {
ctx->num_faulty_dts += dts <= ctx->last_dts;
ctx->last_dts = dts;
}
if (reordered_pts != AV_NOPTS_VALUE) {
ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
ctx->last_pts = reordered_pts;
}
if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
&& reordered_pts != AV_NOPTS_VALUE)
pts = reordered_pts;
else
pts = dts;
return pts;
}
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("AVCONV_DATADIR"),
getenv("HOME"),
AVCONV_DATADIR, };
if (is_path) {
av_strlcpy(filename, preset_name, filename_size);
f = fopen(filename, "r");
} else {
for (i = 0; i < 3 && !f; i++) {
if (!base[i])
continue;
snprintf(filename, filename_size, "%s%s/%s.avpreset", base[i],
i != 1 ? "" : "/.avconv", preset_name);
f = fopen(filename, "r");
if (!f && codec_name) {
snprintf(filename, filename_size,
base[i], i != 1 ? "" : "/.avconv", codec_name,
preset_name);
f = fopen(filename, "r");
}
}
}
return f;
}
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
{
if (*spec <= '9' && *spec >= '0') /* opt:index */
return strtol(spec, NULL, 0) == st->index;
else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
*spec == 't') { /* opt:[vasdt] */
enum AVMediaType type;
switch (*spec++) {
case 'v': type = AVMEDIA_TYPE_VIDEO; break;
case 'a': type = AVMEDIA_TYPE_AUDIO; break;
case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
case 'd': type = AVMEDIA_TYPE_DATA; break;
case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
default: av_assert0(0);
}
if (type != st->codec->codec_type)
return 0;
if (*spec++ == ':') { /* possibly followed by :index */
int i, index = strtol(spec, NULL, 0);
for (i = 0; i < s->nb_streams; i++)
if (s->streams[i]->codec->codec_type == type && index-- == 0)
return i == st->index;
return 0;
}
return 1;
} else if (*spec == 'p' && *(spec + 1) == ':') {
int prog_id, i, j;
char *endptr;
spec += 2;
prog_id = strtol(spec, &endptr, 0);
for (i = 0; i < s->nb_programs; i++) {
if (s->programs[i]->id != prog_id)
continue;
if (*endptr++ == ':') {
int stream_idx = strtol(endptr, NULL, 0);
return stream_idx >= 0 &&
stream_idx < s->programs[i]->nb_stream_indexes &&
st->index == s->programs[i]->stream_index[stream_idx];
}
for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
if (st->index == s->programs[i]->stream_index[j])
return 1;
}
return 0;
} else if (*spec == 'i' && *(spec + 1) == ':') {
int stream_id;
char *endptr;
spec += 2;
stream_id = strtol(spec, &endptr, 0);
return stream_id == st->id;
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
} else if (*spec == 'm' && *(spec + 1) == ':') {
AVDictionaryEntry *tag;
char *key, *val;
int ret;
spec += 2;
val = strchr(spec, ':');
key = val ? av_strndup(spec, val - spec) : av_strdup(spec);
if (!key)
return AVERROR(ENOMEM);
tag = av_dict_get(st->metadata, key, NULL, 0);
if (tag) {
if (!val || !strcmp(tag->value, val + 1))
ret = 1;
else
ret = 0;
} else
ret = 0;
av_freep(&key);
return ret;
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
} else if (*spec == 'u') {
AVCodecContext *avctx = st->codec;
int val;
switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
val = avctx->sample_rate && avctx->channels;
if (avctx->sample_fmt == AV_SAMPLE_FMT_NONE)
return 0;
break;
case AVMEDIA_TYPE_VIDEO:
val = avctx->width && avctx->height;
if (avctx->pix_fmt == AV_PIX_FMT_NONE)
return 0;
break;
case AVMEDIA_TYPE_UNKNOWN:
val = 0;
break;
default:
val = 1;
break;
}
return avctx->codec_id != AV_CODEC_ID_NONE && val != 0;
} else if (!*spec) /* empty specifier, matches everything */
return 1;
av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
return AVERROR(EINVAL);
}
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;
}
void *grow_array(void *array, int elem_size, int *size, int new_size)
{
if (new_size >= INT_MAX / elem_size) {
av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
}
if (*size < new_size) {
uint8_t *tmp = av_realloc(array, new_size*elem_size);
if (!tmp) {
av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
}
memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
*size = new_size;
return tmp;
}
return array;
}
const char *media_type_string(enum AVMediaType media_type)
{
switch (media_type) {
case AVMEDIA_TYPE_VIDEO: return "video";
case AVMEDIA_TYPE_AUDIO: return "audio";
case AVMEDIA_TYPE_DATA: return "data";
case AVMEDIA_TYPE_SUBTITLE: return "subtitle";
case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
default: return "unknown";
}
}