use ffmpeg v4.4-dev-2765-g9f38fac053

This commit is contained in:
Taner Sener 2021-01-27 23:52:32 +00:00
parent d94bd1b873
commit 0cc4e89a9d
50 changed files with 1736 additions and 985 deletions

View File

@ -83,9 +83,6 @@
#include "libavutil/ffversion.h" #include "libavutil/ffversion.h"
#include "libavutil/version.h" #include "libavutil/version.h"
#include "fftools_cmdutils.h" #include "fftools_cmdutils.h"
#if CONFIG_NETWORK
#include "libavformat/network.h"
#endif
#if HAVE_SYS_RESOURCE_H #if HAVE_SYS_RESOURCE_H
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
@ -152,7 +149,7 @@ void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
void init_dynload(void) void init_dynload(void)
{ {
#if HAVE_SETDLLDIRECTORY #if HAVE_SETDLLDIRECTORY && defined(_WIN32)
/* Calling SetDllDirectory with the empty string (but not NULL) removes the /* Calling SetDllDirectory with the empty string (but not NULL) removes the
* current working directory from the DLL search path as a security pre-caution. */ * current working directory from the DLL search path as a security pre-caution. */
SetDllDirectory(""); SetDllDirectory("");
@ -218,7 +215,7 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags,
first = 1; first = 1;
for (po = options; po->name; po++) { for (po = options; po->name; po++) {
char buf[64]; char buf[128];
if (((po->flags & req_flags) != req_flags) || if (((po->flags & req_flags) != req_flags) ||
(alt_flags && !(po->flags & alt_flags)) || (alt_flags && !(po->flags & alt_flags)) ||
@ -241,13 +238,14 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags,
void show_help_children(const AVClass *class, int flags) void show_help_children(const AVClass *class, int flags)
{ {
const AVClass *child = NULL; void *iter = NULL;
const AVClass *child;
if (class->option) { if (class->option) {
av_opt_show2(&class, NULL, flags, 0); av_opt_show2(&class, NULL, flags, 0);
av_log(NULL, AV_LOG_STDERR, "\n"); av_log(NULL, AV_LOG_STDERR, "\n");
} }
while ((child = av_opt_child_class_next(class, child))) while ((child = av_opt_child_class_iterate(class, &iter)))
show_help_children(child, flags); show_help_children(child, flags);
} }
@ -510,7 +508,7 @@ int locate_option(int argc, char **argv, const OptionDef *options,
return 0; return 0;
} }
void dump_argument(const char *a) static void dump_argument(const char *a)
{ {
const unsigned char *p; const unsigned char *p;
@ -1020,7 +1018,7 @@ static void expand_filename_template(AVBPrint *bp, const char *template,
} }
} }
int init_report(const char *env) static int init_report(const char *env)
{ {
char *filename_template = NULL; char *filename_template = NULL;
char *key, *val; char *key, *val;
@ -1464,10 +1462,6 @@ static void print_codec(const AVCodec *c)
av_log(NULL, AV_LOG_STDERR, "threads "); av_log(NULL, AV_LOG_STDERR, "threads ");
if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING) if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)
av_log(NULL, AV_LOG_STDERR, "avoidprobe "); av_log(NULL, AV_LOG_STDERR, "avoidprobe ");
if (c->capabilities & AV_CODEC_CAP_INTRA_ONLY)
av_log(NULL, AV_LOG_STDERR, "intraonly ");
if (c->capabilities & AV_CODEC_CAP_LOSSLESS)
av_log(NULL, AV_LOG_STDERR, "lossless ");
if (c->capabilities & AV_CODEC_CAP_HARDWARE) if (c->capabilities & AV_CODEC_CAP_HARDWARE)
av_log(NULL, AV_LOG_STDERR, "hardware "); av_log(NULL, AV_LOG_STDERR, "hardware ");
if (c->capabilities & AV_CODEC_CAP_HYBRID) if (c->capabilities & AV_CODEC_CAP_HYBRID)
@ -1541,13 +1535,14 @@ static char get_media_type_char(enum AVMediaType type)
} }
} }
static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev, static const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,
int encoder) int encoder)
{ {
while ((prev = av_codec_next(prev))) { const AVCodec *c;
if (prev->id == id && while ((c = av_codec_iterate(iter))) {
(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev))) if (c->id == id &&
return prev; (encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c)))
return c;
} }
return NULL; return NULL;
} }
@ -1584,11 +1579,12 @@ static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
static void print_codecs_for_id(enum AVCodecID id, int encoder) static void print_codecs_for_id(enum AVCodecID id, int encoder)
{ {
const AVCodec *codec = NULL; void *iter = NULL;
const AVCodec *codec;
av_log(NULL, AV_LOG_STDERR, " (%s: ", encoder ? "encoders" : "decoders"); av_log(NULL, AV_LOG_STDERR, " (%s: ", encoder ? "encoders" : "decoders");
while ((codec = next_codec_for_id(id, codec, encoder))) while ((codec = next_codec_for_id(id, &iter, encoder)))
av_log(NULL, AV_LOG_STDERR, "%s ", codec->name); av_log(NULL, AV_LOG_STDERR, "%s ", codec->name);
av_log(NULL, AV_LOG_STDERR, ")"); av_log(NULL, AV_LOG_STDERR, ")");
@ -1611,7 +1607,8 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
" -------\n"); " -------\n");
for (i = 0; i < nb_codecs; i++) { for (i = 0; i < nb_codecs; i++) {
const AVCodecDescriptor *desc = codecs[i]; const AVCodecDescriptor *desc = codecs[i];
const AVCodec *codec = NULL; const AVCodec *codec;
void *iter = NULL;
if (strstr(desc->name, "_deprecated")) if (strstr(desc->name, "_deprecated"))
continue; continue;
@ -1629,14 +1626,14 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
/* print decoders/encoders when there's more than one or their /* print decoders/encoders when there's more than one or their
* names are different from codec name */ * names are different from codec name */
while ((codec = next_codec_for_id(desc->id, codec, 0))) { while ((codec = next_codec_for_id(desc->id, &iter, 0))) {
if (strcmp(codec->name, desc->name)) { if (strcmp(codec->name, desc->name)) {
print_codecs_for_id(desc->id, 0); print_codecs_for_id(desc->id, 0);
break; break;
} }
} }
codec = NULL; iter = NULL;
while ((codec = next_codec_for_id(desc->id, codec, 1))) { while ((codec = next_codec_for_id(desc->id, &iter, 1))) {
if (strcmp(codec->name, desc->name)) { if (strcmp(codec->name, desc->name)) {
print_codecs_for_id(desc->id, 1); print_codecs_for_id(desc->id, 1);
break; break;
@ -1667,9 +1664,10 @@ static void print_codecs(int encoder)
encoder ? "Encoders" : "Decoders"); encoder ? "Encoders" : "Decoders");
for (i = 0; i < nb_codecs; i++) { for (i = 0; i < nb_codecs; i++) {
const AVCodecDescriptor *desc = codecs[i]; const AVCodecDescriptor *desc = codecs[i];
const AVCodec *codec = NULL; const AVCodec *codec;
void *iter = NULL;
while ((codec = next_codec_for_id(desc->id, codec, encoder))) { while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
av_log(NULL, AV_LOG_STDERR, " %c", get_media_type_char(desc->type)); av_log(NULL, AV_LOG_STDERR, " %c", get_media_type_char(desc->type));
av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : "."); av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : "."); av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
@ -1874,9 +1872,10 @@ static void show_help_codec(const char *name, int encoder)
if (codec) if (codec)
print_codec(codec); print_codec(codec);
else if ((desc = avcodec_descriptor_get_by_name(name))) { else if ((desc = avcodec_descriptor_get_by_name(name))) {
void *iter = NULL;
int printed = 0; int printed = 0;
while ((codec = next_codec_for_id(desc->id, codec, encoder))) { while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
printed = 1; printed = 1;
print_codec(codec); print_codec(codec);
} }
@ -1911,6 +1910,24 @@ static void show_help_demuxer(const char *name)
show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM); 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) static void show_help_muxer(const char *name)
{ {
const AVCodecDescriptor *desc; const AVCodecDescriptor *desc;
@ -2044,6 +2061,8 @@ int show_help(void *optctx, const char *opt, const char *arg)
show_help_demuxer(par); show_help_demuxer(par);
} else if (!strcmp(topic, "muxer")) { } else if (!strcmp(topic, "muxer")) {
show_help_muxer(par); show_help_muxer(par);
} else if (!strcmp(topic, "protocol")) {
show_help_protocol(par);
#if CONFIG_AVFILTER #if CONFIG_AVFILTER
} else if (!strcmp(topic, "filter")) { } else if (!strcmp(topic, "filter")) {
show_help_filter(par); show_help_filter(par);
@ -2087,7 +2106,7 @@ FILE *get_preset_file(char *filename, size_t filename_size,
av_strlcpy(filename, preset_name, filename_size); av_strlcpy(filename, preset_name, filename_size);
f = fopen(filename, "r"); f = fopen(filename, "r");
} else { } else {
#if HAVE_GETMODULEHANDLE #if HAVE_GETMODULEHANDLE && defined(_WIN32)
char datadir[MAX_PATH], *ls; char datadir[MAX_PATH], *ls;
base[2] = NULL; base[2] = NULL;
@ -2240,7 +2259,7 @@ double get_rotation(AVStream *st)
if (fabs(theta - 90*round(theta/90)) > 2) if (fabs(theta - 90*round(theta/90)) > 2)
av_log(NULL, AV_LOG_WARNING, "Odd rotation angle.\n" av_log(NULL, AV_LOG_WARNING, "Odd rotation angle.\n"
"If you want to help, upload a sample " "If you want to help, upload a sample "
"of this file to ftp://upload.ffmpeg.org/incoming/ " "of this file to https://streams.videolan.org/upload/ "
"and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)"); "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)");
return theta; return theta;
@ -2337,7 +2356,7 @@ int show_sources(void *optctx, const char *opt, const char *arg)
int ret = 0; int ret = 0;
int error_level = av_log_get_level(); int error_level = av_log_get_level();
av_log_set_level(AV_LOG_ERROR); av_log_set_level(AV_LOG_WARNING);
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0) if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
goto fail; goto fail;
@ -2375,7 +2394,7 @@ int show_sinks(void *optctx, const char *opt, const char *arg)
int ret = 0; int ret = 0;
int error_level = av_log_get_level(); int error_level = av_log_get_level();
av_log_set_level(AV_LOG_ERROR); av_log_set_level(AV_LOG_WARNING);
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0) if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
goto fail; goto fail;

File diff suppressed because it is too large Load Diff

View File

@ -84,7 +84,6 @@ enum HWAccelID {
HWACCEL_GENERIC, HWACCEL_GENERIC,
HWACCEL_VIDEOTOOLBOX, HWACCEL_VIDEOTOOLBOX,
HWACCEL_QSV, HWACCEL_QSV,
HWACCEL_CUVID,
}; };
typedef struct HWAccel { typedef struct HWAccel {
@ -239,6 +238,8 @@ typedef struct OptionsContext {
int nb_passlogfiles; int nb_passlogfiles;
SpecifierOpt *max_muxing_queue_size; SpecifierOpt *max_muxing_queue_size;
int nb_max_muxing_queue_size; int nb_max_muxing_queue_size;
SpecifierOpt *muxing_queue_data_threshold;
int nb_muxing_queue_data_threshold;
SpecifierOpt *guess_layout_max; SpecifierOpt *guess_layout_max;
int nb_guess_layout_max; int nb_guess_layout_max;
SpecifierOpt *apad; SpecifierOpt *apad;
@ -253,6 +254,8 @@ typedef struct OptionsContext {
int nb_time_bases; int nb_time_bases;
SpecifierOpt *enc_time_bases; SpecifierOpt *enc_time_bases;
int nb_enc_time_bases; int nb_enc_time_bases;
SpecifierOpt *autoscale;
int nb_autoscale;
} OptionsContext; } OptionsContext;
typedef struct InputFilter { typedef struct InputFilter {
@ -372,6 +375,7 @@ typedef struct InputStream {
AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init
AVFrame *frame; AVFrame *frame;
int w, h; int w, h;
unsigned int initialize; ///< marks if sub2video_update should force an initialization
} sub2video; } sub2video;
int dr1; int dr1;
@ -454,6 +458,7 @@ enum forced_keyframes_const {
}; };
#define ABORT_ON_FLAG_EMPTY_OUTPUT (1 << 0) #define ABORT_ON_FLAG_EMPTY_OUTPUT (1 << 0)
#define ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM (1 << 1)
extern const char *const forced_keyframes_const_names[]; extern const char *const forced_keyframes_const_names[];
@ -482,8 +487,7 @@ typedef struct OutputStream {
AVRational mux_timebase; AVRational mux_timebase;
AVRational enc_timebase; AVRational enc_timebase;
int nb_bitstream_filters; AVBSFContext *bsf_ctx;
AVBSFContext **bsf_ctx;
AVCodecContext *enc_ctx; AVCodecContext *enc_ctx;
AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */ AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */
@ -502,6 +506,7 @@ typedef struct OutputStream {
int force_fps; int force_fps;
int top_field_first; int top_field_first;
int rotate_overridden; int rotate_overridden;
int autoscale;
double rotate_override_value; double rotate_override_value;
AVRational frame_aspect_ratio; AVRational frame_aspect_ratio;
@ -567,6 +572,15 @@ typedef struct OutputStream {
/* the packets are buffered here until the muxer is ready to be initialized */ /* the packets are buffered here until the muxer is ready to be initialized */
AVFifoBuffer *muxing_queue; AVFifoBuffer *muxing_queue;
/*
* The size of the AVPackets' buffers in queue.
* Updated when a packet is either pushed or pulled from the queue.
*/
size_t muxing_queue_data_size;
/* Threshold after which max_muxing_queue_size will be in effect */
size_t muxing_queue_data_threshold;
/* packet picture type */ /* packet picture type */
int pict_type; int pict_type;
@ -623,6 +637,7 @@ extern __thread int debug_ts;
extern __thread int exit_on_error; extern __thread int exit_on_error;
extern __thread int abort_on_flags; extern __thread int abort_on_flags;
extern __thread int print_stats; extern __thread int print_stats;
extern __thread int64_t stats_period;
extern __thread int qp_hist; extern __thread int qp_hist;
extern __thread int stdin_interaction; extern __thread int stdin_interaction;
extern __thread int frame_bits_per_raw_sample; extern __thread int frame_bits_per_raw_sample;
@ -633,11 +648,11 @@ extern __thread char *videotoolbox_pixfmt;
extern __thread int filter_nbthreads; extern __thread int filter_nbthreads;
extern __thread int filter_complex_nbthreads; extern __thread int filter_complex_nbthreads;
extern __thread int vstats_version; extern __thread int vstats_version;
extern __thread int auto_conversion_filters;
extern __thread const AVIOInterruptCB int_cb; extern __thread const AVIOInterruptCB int_cb;
extern const HWAccel hwaccels[]; extern const HWAccel hwaccels[];
extern __thread AVBufferRef *hw_device_ctx;
#if CONFIG_QSV #if CONFIG_QSV
extern __thread char *qsv_device; extern __thread char *qsv_device;
#endif #endif
@ -656,8 +671,8 @@ void assert_avoptions(AVDictionary *m);
int guess_input_channel_layout(InputStream *ist); int guess_input_channel_layout(InputStream *ist);
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *avctx, AVCodec *codec, enum AVPixelFormat target); enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *avctx, const AVCodec *codec, enum AVPixelFormat target);
void choose_sample_fmt(AVStream *st, AVCodec *codec); void choose_sample_fmt(AVStream *st, const AVCodec *codec);
int configure_filtergraph(FilterGraph *fg); int configure_filtergraph(FilterGraph *fg);
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out); int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out);
@ -667,7 +682,7 @@ int filtergraph_is_simple(FilterGraph *fg);
int init_simple_filtergraph(InputStream *ist, OutputStream *ost); int init_simple_filtergraph(InputStream *ist, OutputStream *ost);
int init_complex_filtergraph(FilterGraph *fg); int init_complex_filtergraph(FilterGraph *fg);
void sub2video_update(InputStream *ist, AVSubtitle *sub); void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub);
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame); int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
@ -675,7 +690,6 @@ int ffmpeg_parse_options(int argc, char **argv);
int videotoolbox_init(AVCodecContext *s); int videotoolbox_init(AVCodecContext *s);
int qsv_init(AVCodecContext *s); int qsv_init(AVCodecContext *s);
int cuvid_init(AVCodecContext *s);
HWDevice *hw_device_get_by_name(const char *name); HWDevice *hw_device_get_by_name(const char *name);
int hw_device_init_from_string(const char *arg, HWDevice **dev); int hw_device_init_from_string(const char *arg, HWDevice **dev);
@ -683,6 +697,7 @@ void hw_device_free_all(void);
int hw_device_setup_for_decode(InputStream *ist); int hw_device_setup_for_decode(InputStream *ist);
int hw_device_setup_for_encode(OutputStream *ost); int hw_device_setup_for_encode(OutputStream *ost);
int hw_device_setup_for_filter(FilterGraph *fg);
int hwaccel_decode_init(AVCodecContext *avctx); int hwaccel_decode_init(AVCodecContext *avctx);
@ -698,6 +713,7 @@ int opt_progress(void *optctx, const char *opt, const char *arg);
int opt_target(void *optctx, const char *opt, const char *arg); int opt_target(void *optctx, const char *opt, const char *arg);
int opt_vsync(void *optctx, const char *opt, const char *arg); int opt_vsync(void *optctx, const char *opt, const char *arg);
int opt_abort_on(void *optctx, const char *opt, const char *arg); int opt_abort_on(void *optctx, const char *opt, const char *arg);
int opt_stats_period(void *optctx, const char *opt, const char *arg);
int opt_qscale(void *optctx, const char *opt, const char *arg); int opt_qscale(void *optctx, const char *opt, const char *arg);
int opt_profile(void *optctx, const char *opt, const char *arg); int opt_profile(void *optctx, const char *opt, const char *arg);
int opt_filter_complex(void *optctx, const char *opt, const char *arg); int opt_filter_complex(void *optctx, const char *opt, const char *arg);

View File

@ -68,7 +68,7 @@ static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum AVCodec
} }
} }
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCodec *codec, enum AVPixelFormat target) enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, const AVCodec *codec, enum AVPixelFormat target)
{ {
if (codec && codec->pix_fmts) { if (codec && codec->pix_fmts) {
const enum AVPixelFormat *p = codec->pix_fmts; const enum AVPixelFormat *p = codec->pix_fmts;
@ -98,7 +98,7 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCod
return target; return target;
} }
void choose_sample_fmt(AVStream *st, AVCodec *codec) void choose_sample_fmt(AVStream *st, const AVCodec *codec)
{ {
if (codec && codec->sample_fmts) { if (codec && codec->sample_fmts) {
const enum AVSampleFormat *p = codec->sample_fmts; const enum AVSampleFormat *p = codec->sample_fmts;
@ -107,7 +107,8 @@ void choose_sample_fmt(AVStream *st, AVCodec *codec)
break; break;
} }
if (*p == -1) { if (*p == -1) {
if((codec->capabilities & AV_CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codecpar->format) > av_get_sample_fmt_name(codec->sample_fmts[0])) const AVCodecDescriptor *desc = avcodec_descriptor_get(codec->id);
if(desc && (desc->props & AV_CODEC_PROP_LOSSLESS) && av_get_sample_fmt_name(st->codecpar->format) > av_get_sample_fmt_name(codec->sample_fmts[0]))
av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n"); av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n");
if(av_get_sample_fmt_name(st->codecpar->format)) if(av_get_sample_fmt_name(st->codecpar->format))
av_log(NULL, AV_LOG_WARNING, av_log(NULL, AV_LOG_WARNING,
@ -477,7 +478,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ofilter->width || ofilter->height) { if ((ofilter->width || ofilter->height) && ofilter->ost->autoscale) {
char args[255]; char args[255];
AVFilterContext *filter; AVFilterContext *filter;
AVDictionaryEntry *e = NULL; AVDictionaryEntry *e = NULL;
@ -748,6 +749,12 @@ static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
ist->sub2video.last_pts = INT64_MIN; ist->sub2video.last_pts = INT64_MIN;
ist->sub2video.end_pts = INT64_MIN; ist->sub2video.end_pts = INT64_MIN;
/* sub2video structure has been (re-)initialized.
Mark it as such so that the system will be
initialized with the first received heartbeat. */
ist->sub2video.initialize = 1;
return 0; return 0;
} }
@ -794,10 +801,9 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC); av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
av_bprintf(&args, av_bprintf(&args,
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:" "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
"pixel_aspect=%d/%d:sws_param=flags=%d", "pixel_aspect=%d/%d",
ifilter->width, ifilter->height, ifilter->format, ifilter->width, ifilter->height, ifilter->format,
tb.num, tb.den, sar.num, sar.den, tb.num, tb.den, sar.num, sar.den);
SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
if (fr.num && fr.den) if (fr.num && fr.den)
av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den); av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index, snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
@ -1064,17 +1070,9 @@ int configure_filtergraph(FilterGraph *fg)
if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0) if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
goto fail; goto fail;
if (filter_hw_device || hw_device_ctx) { ret = hw_device_setup_for_filter(fg);
AVBufferRef *device = filter_hw_device ? filter_hw_device->device_ref if (ret < 0)
: hw_device_ctx;
for (i = 0; i < fg->graph->nb_filters; i++) {
fg->graph->filters[i]->hw_device_ctx = av_buffer_ref(device);
if (!fg->graph->filters[i]->hw_device_ctx) {
ret = AVERROR(ENOMEM);
goto fail; goto fail;
}
}
}
if (simple && (!inputs || inputs->next || !outputs || outputs->next)) { if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
const char *num_inputs; const char *num_inputs;
@ -1114,6 +1112,8 @@ int configure_filtergraph(FilterGraph *fg)
configure_output_filter(fg, fg->outputs[i], cur); configure_output_filter(fg, fg->outputs[i], cur);
avfilter_inout_free(&outputs); avfilter_inout_free(&outputs);
if (!auto_conversion_filters)
avfilter_graph_set_auto_convert(fg->graph, AVFILTER_AUTO_CONVERT_NONE);
if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
goto fail; goto fail;
@ -1177,7 +1177,7 @@ int configure_filtergraph(FilterGraph *fg)
while (av_fifo_size(ist->sub2video.sub_queue)) { while (av_fifo_size(ist->sub2video.sub_queue)) {
AVSubtitle tmp; AVSubtitle tmp;
av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL); av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
sub2video_update(ist, &tmp); sub2video_update(ist, INT64_MIN, &tmp);
avsubtitle_free(&tmp); avsubtitle_free(&tmp);
} }
} }

View File

@ -28,6 +28,8 @@
#include <string.h> #include <string.h>
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/pixdesc.h"
#include "libavfilter/buffersink.h"
#include "fftools_ffmpeg.h" #include "fftools_ffmpeg.h"
@ -425,18 +427,57 @@ int hw_device_setup_for_decode(InputStream *ist)
int hw_device_setup_for_encode(OutputStream *ost) int hw_device_setup_for_encode(OutputStream *ost)
{ {
HWDevice *dev; const AVCodecHWConfig *config;
HWDevice *dev = NULL;
AVBufferRef *frames_ref = NULL;
int i;
if (ost->filter) {
frames_ref = av_buffersink_get_hw_frames_ctx(ost->filter->filter);
if (frames_ref &&
((AVHWFramesContext*)frames_ref->data)->format ==
ost->enc_ctx->pix_fmt) {
// Matching format, will try to use hw_frames_ctx.
} else {
frames_ref = NULL;
}
}
for (i = 0;; i++) {
config = avcodec_get_hw_config(ost->enc, i);
if (!config)
break;
if (frames_ref &&
config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX &&
(config->pix_fmt == AV_PIX_FMT_NONE ||
config->pix_fmt == ost->enc_ctx->pix_fmt)) {
av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using input "
"frames context (format %s) with %s encoder.\n",
av_get_pix_fmt_name(ost->enc_ctx->pix_fmt),
ost->enc->name);
ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
if (!ost->enc_ctx->hw_frames_ctx)
return AVERROR(ENOMEM);
return 0;
}
if (!dev &&
config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)
dev = hw_device_get_by_type(config->device_type);
}
dev = hw_device_match_by_codec(ost->enc);
if (dev) { if (dev) {
av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using device %s "
"(type %s) with %s encoder.\n", dev->name,
av_hwdevice_get_type_name(dev->type), ost->enc->name);
ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref); ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
if (!ost->enc_ctx->hw_device_ctx) if (!ost->enc_ctx->hw_device_ctx)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
return 0;
} else { } else {
// No device required, or no device available. // No device required, or no device available.
return 0;
} }
return 0;
} }
static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input) static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input)
@ -489,3 +530,31 @@ int hwaccel_decode_init(AVCodecContext *avctx)
return 0; return 0;
} }
int hw_device_setup_for_filter(FilterGraph *fg)
{
HWDevice *dev;
int i;
// If the user has supplied exactly one hardware device then just
// give it straight to every filter for convenience. If more than
// one device is available then the user needs to pick one explcitly
// with the filter_hw_device option.
if (filter_hw_device)
dev = filter_hw_device;
else if (nb_hw_devices == 1)
dev = hw_devices[0];
else
dev = NULL;
if (dev) {
for (i = 0; i < fg->graph->nb_filters; i++) {
fg->graph->filters[i]->hw_device_ctx =
av_buffer_ref(dev->device_ref);
if (!fg->graph->filters[i]->hw_device_ctx)
return AVERROR(ENOMEM);
}
}
return 0;
}

View File

@ -62,16 +62,82 @@
#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass" #define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
#define SPECIFIER_OPT_FMT_str "%s"
#define SPECIFIER_OPT_FMT_i "%i"
#define SPECIFIER_OPT_FMT_i64 "%"PRId64
#define SPECIFIER_OPT_FMT_ui64 "%"PRIu64
#define SPECIFIER_OPT_FMT_f "%f"
#define SPECIFIER_OPT_FMT_dbl "%lf"
static const char *const opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL};
static const char *const opt_name_audio_channels[] = {"ac", NULL};
static const char *const opt_name_audio_sample_rate[] = {"ar", NULL};
static const char *const opt_name_frame_rates[] = {"r", NULL};
static const char *const opt_name_frame_sizes[] = {"s", NULL};
static const char *const opt_name_frame_pix_fmts[] = {"pix_fmt", NULL};
static const char *const opt_name_ts_scale[] = {"itsscale", NULL};
static const char *const opt_name_hwaccels[] = {"hwaccel", NULL};
static const char *const opt_name_hwaccel_devices[] = {"hwaccel_device", NULL};
static const char *const opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL};
static const char *const opt_name_autorotate[] = {"autorotate", NULL};
static const char *const opt_name_autoscale[] = {"autoscale", NULL};
static const char *const opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL};
static const char *const opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL};
static const char *const opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL};
static const char *const opt_name_sample_fmts[] = {"sample_fmt", NULL};
static const char *const opt_name_qscale[] = {"q", "qscale", NULL};
static const char *const opt_name_forced_key_frames[] = {"forced_key_frames", NULL};
static const char *const opt_name_force_fps[] = {"force_fps", NULL};
static const char *const opt_name_frame_aspect_ratios[] = {"aspect", NULL};
static const char *const opt_name_rc_overrides[] = {"rc_override", NULL};
static const char *const opt_name_intra_matrices[] = {"intra_matrix", NULL};
static const char *const opt_name_inter_matrices[] = {"inter_matrix", NULL};
static const char *const opt_name_chroma_intra_matrices[] = {"chroma_intra_matrix", NULL};
static const char *const opt_name_top_field_first[] = {"top", NULL};
static const char *const opt_name_presets[] = {"pre", "apre", "vpre", "spre", NULL};
static const char *const opt_name_copy_initial_nonkeyframes[] = {"copyinkfr", NULL};
static const char *const opt_name_copy_prior_start[] = {"copypriorss", NULL};
static const char *const opt_name_filters[] = {"filter", "af", "vf", NULL};
static const char *const opt_name_filter_scripts[] = {"filter_script", NULL};
static const char *const opt_name_reinit_filters[] = {"reinit_filter", NULL};
static const char *const opt_name_fix_sub_duration[] = {"fix_sub_duration", NULL};
static const char *const opt_name_canvas_sizes[] = {"canvas_size", NULL};
static const char *const opt_name_pass[] = {"pass", NULL};
static const char *const opt_name_passlogfiles[] = {"passlogfile", NULL};
static const char *const opt_name_max_muxing_queue_size[] = {"max_muxing_queue_size", NULL};
static const char *const opt_name_muxing_queue_data_threshold[] = {"muxing_queue_data_threshold", NULL};
static const char *const opt_name_guess_layout_max[] = {"guess_layout_max", NULL};
static const char *const opt_name_apad[] = {"apad", NULL};
static const char *const opt_name_discard[] = {"discard", NULL};
static const char *const opt_name_disposition[] = {"disposition", NULL};
static const char *const opt_name_time_bases[] = {"time_base", NULL};
static const char *const opt_name_enc_time_bases[] = {"enc_time_base", NULL};
#define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\
{\
char namestr[128] = "";\
const char *spec = so->specifier && so->specifier[0] ? so->specifier : "";\
for (i = 0; opt_name_##name[i]; i++)\
av_strlcatf(namestr, sizeof(namestr), "-%s%s", opt_name_##name[i], opt_name_##name[i+1] ? (opt_name_##name[i+2] ? ", " : " or ") : "");\
av_log(NULL, AV_LOG_WARNING, "Multiple %s options specified for stream %d, only the last option '-%s%s%s "SPECIFIER_OPT_FMT_##type"' will be used.\n",\
namestr, st->index, opt_name_##name[0], spec[0] ? ":" : "", spec, so->u.type);\
}
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\ #define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
{\ {\
int i, ret;\ int i, ret, matches = 0;\
SpecifierOpt *so;\
for (i = 0; i < o->nb_ ## name; i++) {\ for (i = 0; i < o->nb_ ## name; i++) {\
char *spec = o->name[i].specifier;\ char *spec = o->name[i].specifier;\
if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\ if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0) {\
outvar = o->name[i].u.type;\ outvar = o->name[i].u.type;\
else if (ret < 0)\ so = &o->name[i];\
matches++;\
} else if (ret < 0)\
exit_program(1);\ exit_program(1);\
}\ }\
if (matches > 1)\
WARN_MULTIPLE_OPT_USAGE(name, type, so, st);\
} }
#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\ #define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\
@ -90,13 +156,9 @@ const HWAccel hwaccels[] = {
#endif #endif
#if CONFIG_LIBMFX #if CONFIG_LIBMFX
{ "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV }, { "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV },
#endif
#if CONFIG_CUVID
{ "cuvid", cuvid_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA },
#endif #endif
{ 0 }, { 0 },
}; };
__thread AVBufferRef *hw_device_ctx;
__thread HWDevice *filter_hw_device; __thread HWDevice *filter_hw_device;
__thread char *vstats_filename; __thread char *vstats_filename;
@ -129,6 +191,8 @@ __thread float max_error_rate = 2.0/3;
__thread int filter_nbthreads = 0; __thread int filter_nbthreads = 0;
__thread int filter_complex_nbthreads = 0; __thread int filter_complex_nbthreads = 0;
__thread int vstats_version = 2; __thread int vstats_version = 2;
__thread int auto_conversion_filters = 1;
__thread int64_t stats_period = 500000;
__thread int intra_only = 0; __thread int intra_only = 0;
@ -187,19 +251,17 @@ void init_options(OptionsContext *o)
o->limit_filesize = UINT64_MAX; o->limit_filesize = UINT64_MAX;
o->chapters_input_file = INT_MAX; o->chapters_input_file = INT_MAX;
o->accurate_seek = 1; o->accurate_seek = 1;
o->thread_queue_size = -1;
} }
int show_hwaccels(void *optctx, const char *opt, const char *arg) int show_hwaccels(void *optctx, const char *opt, const char *arg)
{ {
enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE; enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
int i;
av_log(NULL, AV_LOG_STDERR, "Hardware acceleration methods:\n"); av_log(NULL, AV_LOG_STDERR, "Hardware acceleration methods:\n");
while ((type = av_hwdevice_iterate_types(type)) != while ((type = av_hwdevice_iterate_types(type)) !=
AV_HWDEVICE_TYPE_NONE) AV_HWDEVICE_TYPE_NONE)
av_log(NULL, AV_LOG_STDERR, "%s\n", av_hwdevice_get_type_name(type)); av_log(NULL, AV_LOG_STDERR, "%s\n", av_hwdevice_get_type_name(type));
for (i = 0; hwaccels[i].name; i++)
av_log(NULL, AV_LOG_STDERR, "%s\n", hwaccels[i].name);
av_log(NULL, AV_LOG_STDERR, "\n"); av_log(NULL, AV_LOG_STDERR, "\n");
return 0; return 0;
} }
@ -227,6 +289,7 @@ int opt_abort_on(void *optctx, const char *opt, const char *arg)
const AVOption opts[] = { const AVOption opts[] = {
{ "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, (double)INT64_MAX, .unit = "flags" }, { "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, (double)INT64_MAX, .unit = "flags" },
{ "empty_output" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT }, .unit = "flags" }, { "empty_output" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT }, .unit = "flags" },
{ "empty_output_stream", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM }, .unit = "flags" },
{ NULL }, { NULL },
}; };
const AVClass class = { const AVClass class = {
@ -240,6 +303,21 @@ int opt_abort_on(void *optctx, const char *opt, const char *arg)
return av_opt_eval_flags(&pclass, &opts[0], arg, &abort_on_flags); return av_opt_eval_flags(&pclass, &opts[0], arg, &abort_on_flags);
} }
int opt_stats_period(void *optctx, const char *opt, const char *arg)
{
int64_t user_stats_period = parse_time_or_die(opt, arg, 1);
if (user_stats_period <= 0) {
av_log(NULL, AV_LOG_ERROR, "stats_period %s must be positive.\n", arg);
return AVERROR(EINVAL);
}
stats_period = user_stats_period;
av_log(NULL, AV_LOG_INFO, "ffmpeg stats and -progress period set to %s.\n", arg);
return 0;
}
int opt_sameq(void *optctx, const char *opt, const char *arg) int opt_sameq(void *optctx, const char *opt, const char *arg)
{ {
av_log(NULL, AV_LOG_ERROR, "Option '%s' was removed. " av_log(NULL, AV_LOG_ERROR, "Option '%s' was removed. "
@ -498,21 +576,15 @@ int opt_sdp_file(void *optctx, const char *opt, const char *arg)
#if CONFIG_VAAPI #if CONFIG_VAAPI
int opt_vaapi_device(void *optctx, const char *opt, const char *arg) int opt_vaapi_device(void *optctx, const char *opt, const char *arg)
{ {
HWDevice *dev;
const char *prefix = "vaapi:"; const char *prefix = "vaapi:";
char *tmp; char *tmp;
int err; int err;
tmp = av_asprintf("%s%s", prefix, arg); tmp = av_asprintf("%s%s", prefix, arg);
if (!tmp) if (!tmp)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
err = hw_device_init_from_string(tmp, &dev); err = hw_device_init_from_string(tmp, NULL);
av_free(tmp); av_free(tmp);
if (err < 0)
return err; return err;
hw_device_ctx = av_buffer_ref(dev->device_ref);
if (!hw_device_ctx)
return AVERROR(ENOMEM);
return 0;
} }
#endif #endif
@ -815,15 +887,6 @@ void add_input_streams(OptionsContext *o, AVFormatContext *ic)
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
if(!ist->dec) if(!ist->dec)
ist->dec = avcodec_find_decoder(par->codec_id); ist->dec = avcodec_find_decoder(par->codec_id);
#if FF_API_LOWRES
if (st->codec->lowres) {
ist->dec_ctx->lowres = st->codec->lowres;
ist->dec_ctx->width = st->codec->width;
ist->dec_ctx->height = st->codec->height;
ist->dec_ctx->coded_width = st->codec->coded_width;
ist->dec_ctx->coded_height = st->codec->coded_height;
}
#endif
// avformat_find_stream_info() doesn't set this for us anymore. // avformat_find_stream_info() doesn't set this for us anymore.
ist->dec_ctx->framerate = st->avg_frame_rate; ist->dec_ctx->framerate = st->avg_frame_rate;
@ -840,9 +903,28 @@ void add_input_streams(OptionsContext *o, AVFormatContext *ic)
MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st); MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st); MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
hwaccel_output_format, ic, st);
if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "cuvid")) {
av_log(NULL, AV_LOG_WARNING,
"WARNING: defaulting hwaccel_output_format to cuda for compatibility "
"with old commandlines. This behaviour is DEPRECATED and will be removed "
"in the future. Please explicitly set \"-hwaccel_output_format cuda\".\n");
ist->hwaccel_output_format = AV_PIX_FMT_CUDA;
} else if (hwaccel_output_format) {
ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
"format: %s", hwaccel_output_format);
}
} else {
ist->hwaccel_output_format = AV_PIX_FMT_NONE;
}
if (hwaccel) { if (hwaccel) {
// The NVDEC hwaccels use a CUDA device, so remap the name here. // The NVDEC hwaccels use a CUDA device, so remap the name here.
if (!strcmp(hwaccel, "nvdec")) if (!strcmp(hwaccel, "nvdec") || !strcmp(hwaccel, "cuvid"))
hwaccel = "cuda"; hwaccel = "cuda";
if (!strcmp(hwaccel, "none")) if (!strcmp(hwaccel, "none"))
@ -876,8 +958,6 @@ void add_input_streams(OptionsContext *o, AVFormatContext *ic)
AV_HWDEVICE_TYPE_NONE) AV_HWDEVICE_TYPE_NONE)
av_log(NULL, AV_LOG_FATAL, "%s ", av_log(NULL, AV_LOG_FATAL, "%s ",
av_hwdevice_get_type_name(type)); av_hwdevice_get_type_name(type));
for (i = 0; hwaccels[i].name; i++)
av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
av_log(NULL, AV_LOG_FATAL, "\n"); av_log(NULL, AV_LOG_FATAL, "\n");
exit_program(1); exit_program(1);
} }
@ -891,18 +971,6 @@ void add_input_streams(OptionsContext *o, AVFormatContext *ic)
exit_program(1); exit_program(1);
} }
MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
hwaccel_output_format, ic, st);
if (hwaccel_output_format) {
ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
"format: %s", hwaccel_output_format);
}
} else {
ist->hwaccel_output_format = AV_PIX_FMT_NONE;
}
ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE; ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
break; break;
@ -1232,7 +1300,7 @@ int open_input_file(OptionsContext *o, const char *filename)
f->duration = 0; f->duration = 0;
f->time_base = (AVRational){ 1, 1 }; f->time_base = (AVRational){ 1, 1 };
#if HAVE_THREADS #if HAVE_THREADS
f->thread_queue_size = o->thread_queue_size > 0 ? o->thread_queue_size : 8; f->thread_queue_size = o->thread_queue_size;
#endif #endif
/* check if all codec options have been used */ /* check if all codec options have been used */
@ -1425,6 +1493,8 @@ OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVM
ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc); ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
ost->autoscale = 1;
MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st);
if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) { if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
do { do {
buf = get_line(s); buf = get_line(s);
@ -1492,54 +1562,12 @@ OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVM
MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st); MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st);
MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st); MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st);
while (bsfs && *bsfs) { if (bsfs && *bsfs) {
const AVBitStreamFilter *filter; ret = av_bsf_list_parse_str(bsfs, &ost->bsf_ctx);
char *bsf, *bsf_options_str, *bsf_name;
bsf = av_get_token(&bsfs, ",");
if (!bsf)
exit_program(1);
bsf_name = av_strtok(bsf, "=", &bsf_options_str);
if (!bsf_name)
exit_program(1);
filter = av_bsf_get_by_name(bsf_name);
if (!filter) {
av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf_name);
exit_program(1);
}
ost->bsf_ctx = av_realloc_array(ost->bsf_ctx,
ost->nb_bitstream_filters + 1,
sizeof(*ost->bsf_ctx));
if (!ost->bsf_ctx)
exit_program(1);
ret = av_bsf_alloc(filter, &ost->bsf_ctx[ost->nb_bitstream_filters]);
if (ret < 0) { if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n"); av_log(NULL, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret));
exit_program(1); exit_program(1);
} }
ost->nb_bitstream_filters++;
if (bsf_options_str && filter->priv_class) {
const AVOption *opt = av_opt_next(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, NULL);
const char * shorthand[2] = {NULL};
if (opt)
shorthand[0] = opt->name;
ret = av_opt_set_from_string(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, bsf_options_str, shorthand, "=", ":");
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error parsing options for bitstream filter %s\n", bsf_name);
exit_program(1);
}
}
av_freep(&bsf);
if (*bsfs)
bsfs++;
} }
MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st); MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
@ -1564,6 +1592,11 @@ OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVM
MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st); MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st);
ost->max_muxing_queue_size *= sizeof(AVPacket); ost->max_muxing_queue_size *= sizeof(AVPacket);
ost->muxing_queue_data_size = 0;
ost->muxing_queue_data_threshold = 50*1024*1024;
MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, ost->muxing_queue_data_threshold, oc, st);
if (oc->oformat->flags & AVFMT_GLOBALHEADER) if (oc->oformat->flags & AVFMT_GLOBALHEADER)
ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
@ -1702,8 +1735,6 @@ OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int sourc
MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st); MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st); MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
if (o->nb_filters > 1)
av_log(NULL, AV_LOG_ERROR, "Only '-vf %s' read, ignoring remaining -vf options: Use ',' to separate filters\n", ost->filters);
if (!ost->stream_copy) { if (!ost->stream_copy) {
const char *p = NULL; const char *p = NULL;
@ -1885,8 +1916,6 @@ OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int sourc
MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st); MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st); MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
if (o->nb_filters > 1)
av_log(NULL, AV_LOG_ERROR, "Only '-af %s' read, ignoring remaining -af options: Use ',' to separate filters\n", ost->filters);
if (!ost->stream_copy) { if (!ost->stream_copy) {
char *sample_fmt = NULL; char *sample_fmt = NULL;
@ -2214,22 +2243,23 @@ int open_output_file(OptionsContext *o, const char *filename)
/* video: highest resolution */ /* video: highest resolution */
if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) { if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {
int area = 0, idx = -1; int best_score = 0, idx = -1;
int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0); int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
for (i = 0; i < nb_input_streams; i++) { for (i = 0; i < nb_input_streams; i++) {
int new_area; int score;
ist = input_streams[i]; ist = input_streams[i];
new_area = ist->st->codecpar->width * ist->st->codecpar->height + 100000000*!!ist->st->codec_info_nb_frames score = ist->st->codecpar->width * ist->st->codecpar->height
+ 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
+ 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT); + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
if (ist->user_set_discard == AVDISCARD_ALL) if (ist->user_set_discard == AVDISCARD_ALL)
continue; continue;
if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
new_area = 1; score = 1;
if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
new_area > area) { score > best_score) {
if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
continue; continue;
area = new_area; best_score = score;
idx = i; idx = i;
} }
} }
@ -2393,12 +2423,14 @@ loop_end:
o->attachments[i]); o->attachments[i]);
exit_program(1); exit_program(1);
} }
if (!(attachment = av_malloc(len))) { if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n", !(attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) {
av_log(NULL, AV_LOG_FATAL, "Attachment %s too large.\n",
o->attachments[i]); o->attachments[i]);
exit_program(1); exit_program(1);
} }
avio_read(pb, attachment, len); avio_read(pb, attachment, len);
memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
ost = new_attachment_stream(o, oc, -1); ost = new_attachment_stream(o, oc, -1);
ost->stream_copy = 0; ost->stream_copy = 0;
@ -3217,7 +3249,7 @@ void show_help_default_ffmpeg(const char *opt, const char *arg)
" -h -- print basic options\n" " -h -- print basic options\n"
" -h long -- print more options\n" " -h long -- print more options\n"
" -h full -- print all options (including all format and codec specific options, very long)\n" " -h full -- print all options (including all format and codec specific options, very long)\n"
" -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf\n" " -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf/protocol\n"
" See man %s for detailed description of the options.\n" " See man %s for detailed description of the options.\n"
"\n", program_name); "\n", program_name);
@ -3225,7 +3257,7 @@ void show_help_default_ffmpeg(const char *opt, const char *arg)
OPT_EXIT, 0, 0); OPT_EXIT, 0, 0);
show_help_options(options, "Global options (affect whole program " show_help_options(options, "Global options (affect whole program "
"instead of just one file:", "instead of just one file):",
0, per_file | OPT_EXIT | OPT_EXPERT, 0); 0, per_file | OPT_EXIT | OPT_EXPERT, 0);
if (show_advanced) if (show_advanced)
show_help_options(options, "Advanced global options:", OPT_EXPERT, show_help_options(options, "Advanced global options:", OPT_EXPERT,
@ -3301,6 +3333,7 @@ int open_files(OptionGroupList *l, const char *inout,
if (ret < 0) { if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file " av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
"%s.\n", inout, g->arg); "%s.\n", inout, g->arg);
uninit_options(&o);
return ret; return ret;
} }

View File

@ -42,7 +42,9 @@
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
#include "libavutil/display.h" #include "libavutil/display.h"
#include "libavutil/hash.h" #include "libavutil/hash.h"
#include "libavutil/hdr_dynamic_metadata.h"
#include "libavutil/mastering_display_metadata.h" #include "libavutil/mastering_display_metadata.h"
#include "libavutil/dovi_meta.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
#include "libavutil/spherical.h" #include "libavutil/spherical.h"
@ -257,6 +259,7 @@ __thread OptionDef *ffprobe_options = NULL;
/* FFprobe context */ /* FFprobe context */
__thread const char *input_filename; __thread const char *input_filename;
__thread const char *print_input_filename;
__thread AVInputFormat *iformat = NULL; __thread AVInputFormat *iformat = NULL;
__thread struct AVHashContext *hash; __thread struct AVHashContext *hash;
@ -1089,12 +1092,12 @@ typedef struct CompactContext {
#define OFFSET(x) offsetof(CompactContext, x) #define OFFSET(x) offsetof(CompactContext, x)
static const AVOption compact_options[]= { static const AVOption compact_options[]= {
{"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, CHAR_MIN, CHAR_MAX }, {"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, 0, 0 },
{"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, CHAR_MIN, CHAR_MAX }, {"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, 0, 0 },
{"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 }, {"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
{"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 }, {"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
{"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, CHAR_MIN, CHAR_MAX }, {"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, 0, 0 },
{"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, CHAR_MIN, CHAR_MAX }, {"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, 0, 0 },
{"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{NULL}, {NULL},
@ -1205,12 +1208,12 @@ static const Writer compact_writer = {
#define OFFSET(x) offsetof(CompactContext, x) #define OFFSET(x) offsetof(CompactContext, x)
static const AVOption csv_options[] = { static const AVOption csv_options[] = {
{"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, CHAR_MIN, CHAR_MAX }, {"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, 0, 0 },
{"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, CHAR_MIN, CHAR_MAX }, {"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, 0, 0 },
{"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, CHAR_MIN, CHAR_MAX }, {"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, 0, 0 },
{"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, CHAR_MIN, CHAR_MAX }, {"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, 0, 0 },
{"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{NULL}, {NULL},
@ -1243,8 +1246,8 @@ typedef struct FlatContext {
#define OFFSET(x) offsetof(FlatContext, x) #define OFFSET(x) offsetof(FlatContext, x)
static const AVOption flat_options[]= { static const AVOption flat_options[]= {
{"sep_char", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, CHAR_MIN, CHAR_MAX }, {"sep_char", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, 0, 0 },
{"s", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, CHAR_MIN, CHAR_MAX }, {"s", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, 0, 0 },
{"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"h", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"h", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{NULL}, {NULL},
@ -1859,6 +1862,105 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id
return ret; return ret;
} }
static void print_dynamic_hdr10_plus(WriterContext *w, const AVDynamicHDRPlus *metadata)
{
if (!metadata)
return;
print_int("application version", metadata->application_version);
print_int("num_windows", metadata->num_windows);
for (int n = 1; n < metadata->num_windows; n++) {
const AVHDRPlusColorTransformParams *params = &metadata->params[n];
print_q("window_upper_left_corner_x",
params->window_upper_left_corner_x,'/');
print_q("window_upper_left_corner_y",
params->window_upper_left_corner_y,'/');
print_q("window_lower_right_corner_x",
params->window_lower_right_corner_x,'/');
print_q("window_lower_right_corner_y",
params->window_lower_right_corner_y,'/');
print_q("window_upper_left_corner_x",
params->window_upper_left_corner_x,'/');
print_q("window_upper_left_corner_y",
params->window_upper_left_corner_y,'/');
print_int("center_of_ellipse_x",
params->center_of_ellipse_x ) ;
print_int("center_of_ellipse_y",
params->center_of_ellipse_y );
print_int("rotation_angle",
params->rotation_angle);
print_int("semimajor_axis_internal_ellipse",
params->semimajor_axis_internal_ellipse);
print_int("semimajor_axis_external_ellipse",
params->semimajor_axis_external_ellipse);
print_int("semiminor_axis_external_ellipse",
params->semiminor_axis_external_ellipse);
print_int("overlap_process_option",
params->overlap_process_option);
}
print_q("targeted_system_display_maximum_luminance",
metadata->targeted_system_display_maximum_luminance,'/');
if (metadata->targeted_system_display_actual_peak_luminance_flag) {
print_int("num_rows_targeted_system_display_actual_peak_luminance",
metadata->num_rows_targeted_system_display_actual_peak_luminance);
print_int("num_cols_targeted_system_display_actual_peak_luminance",
metadata->num_cols_targeted_system_display_actual_peak_luminance);
for (int i = 0; i < metadata->num_rows_targeted_system_display_actual_peak_luminance; i++) {
for (int j = 0; j < metadata->num_cols_targeted_system_display_actual_peak_luminance; j++) {
print_q("targeted_system_display_actual_peak_luminance",
metadata->targeted_system_display_actual_peak_luminance[i][j],'/');
}
}
}
for (int n = 0; n < metadata->num_windows; n++) {
const AVHDRPlusColorTransformParams *params = &metadata->params[n];
for (int i = 0; i < 3; i++) {
print_q("maxscl",params->maxscl[i],'/');
}
print_q("average_maxrgb",
params->average_maxrgb,'/');
print_int("num_distribution_maxrgb_percentiles",
params->num_distribution_maxrgb_percentiles);
for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
print_int("distribution_maxrgb_percentage",
params->distribution_maxrgb[i].percentage);
print_q("distribution_maxrgb_percentile",
params->distribution_maxrgb[i].percentile,'/');
}
print_q("fraction_bright_pixels",
params->fraction_bright_pixels,'/');
}
if (metadata->mastering_display_actual_peak_luminance_flag) {
print_int("num_rows_mastering_display_actual_peak_luminance",
metadata->num_rows_mastering_display_actual_peak_luminance);
print_int("num_cols_mastering_display_actual_peak_luminance",
metadata->num_cols_mastering_display_actual_peak_luminance);
for (int i = 0; i < metadata->num_rows_mastering_display_actual_peak_luminance; i++) {
for (int j = 0; j < metadata->num_cols_mastering_display_actual_peak_luminance; j++) {
print_q("mastering_display_actual_peak_luminance",
metadata->mastering_display_actual_peak_luminance[i][j],'/');
}
}
}
for (int n = 0; n < metadata->num_windows; n++) {
const AVHDRPlusColorTransformParams *params = &metadata->params[n];
if (params->tone_mapping_flag) {
print_q("knee_point_x", params->knee_point_x,'/');
print_q("knee_point_y", params->knee_point_y,'/');
print_int("num_bezier_curve_anchors",
params->num_bezier_curve_anchors );
for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
print_q("bezier_curve_anchors",
params->bezier_curve_anchors[i],'/');
}
}
if (params->color_saturation_mapping_flag) {
print_q("color_saturation_weight",
params->color_saturation_weight,'/');
}
}
}
static void print_pkt_side_data(WriterContext *w, static void print_pkt_side_data(WriterContext *w,
AVCodecParameters *par, AVCodecParameters *par,
const AVPacketSideData *side_data, const AVPacketSideData *side_data,
@ -1928,6 +2030,16 @@ static void print_pkt_side_data(WriterContext *w,
AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data;
print_int("max_content", metadata->MaxCLL); print_int("max_content", metadata->MaxCLL);
print_int("max_average", metadata->MaxFALL); print_int("max_average", metadata->MaxFALL);
} else if (sd->type == AV_PKT_DATA_DOVI_CONF) {
AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data;
print_int("dv_version_major", dovi->dv_version_major);
print_int("dv_version_minor", dovi->dv_version_minor);
print_int("dv_profile", dovi->dv_profile);
print_int("dv_level", dovi->dv_level);
print_int("rpu_present_flag", dovi->rpu_present_flag);
print_int("el_present_flag", dovi->el_present_flag);
print_int("bl_present_flag", dovi->bl_present_flag);
print_int("dv_bl_signal_compatibility_id", dovi->dv_bl_signal_compatibility_id);
} }
writer_print_section_footer(w); writer_print_section_footer(w);
} }
@ -2214,7 +2326,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST); writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST);
for (int j = 1; j <= m ; j++) { for (int j = 1; j <= m ; j++) {
char tcbuf[AV_TIMECODE_STR_SIZE]; char tcbuf[AV_TIMECODE_STR_SIZE];
av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); av_timecode_make_smpte_tc_string2(tcbuf, stream->avg_frame_rate, tc[j], 0, 0);
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE); writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE);
print_str("value", tcbuf); print_str("value", tcbuf);
writer_print_section_footer(w); writer_print_section_footer(w);
@ -2239,6 +2351,9 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
print_q("min_luminance", metadata->min_luminance, '/'); print_q("min_luminance", metadata->min_luminance, '/');
print_q("max_luminance", metadata->max_luminance, '/'); print_q("max_luminance", metadata->max_luminance, '/');
} }
} else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_PLUS) {
AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data;
print_dynamic_hdr10_plus(w, metadata);
} else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) { } else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) {
AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data;
print_int("max_content", metadata->MaxCLL); print_int("max_content", metadata->MaxCLL);
@ -2539,6 +2654,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
if (dec_ctx) { if (dec_ctx) {
print_int("coded_width", dec_ctx->coded_width); print_int("coded_width", dec_ctx->coded_width);
print_int("coded_height", dec_ctx->coded_height); print_int("coded_height", dec_ctx->coded_height);
print_int("closed_captions", !!(dec_ctx->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS));
} }
#endif #endif
print_int("has_b_frames", par->video_delay); print_int("has_b_frames", par->video_delay);
@ -2840,11 +2956,11 @@ static void show_error(WriterContext *w, int err)
writer_print_section_footer(w); writer_print_section_footer(w);
} }
static int open_input_file(InputFile *ifile, const char *filename) static int open_input_file(InputFile *ifile, const char *filename, const char *print_filename)
{ {
int err, i; int err, i;
AVFormatContext *fmt_ctx = NULL; AVFormatContext *fmt_ctx = NULL;
AVDictionaryEntry *t; AVDictionaryEntry *t = NULL;
int scan_all_pmts_set = 0; int scan_all_pmts_set = 0;
fmt_ctx = avformat_alloc_context(); fmt_ctx = avformat_alloc_context();
@ -2862,13 +2978,15 @@ static int open_input_file(InputFile *ifile, const char *filename)
print_error(filename, err); print_error(filename, err);
return err; return err;
} }
if (print_filename) {
av_freep(&fmt_ctx->url);
fmt_ctx->url = av_strdup(print_filename);
}
ifile->fmt_ctx = fmt_ctx; ifile->fmt_ctx = fmt_ctx;
if (scan_all_pmts_set) if (scan_all_pmts_set)
av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE); av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { while ((t = av_dict_get(format_opts, "", t, AV_DICT_IGNORE_SUFFIX)))
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); av_log(NULL, AV_LOG_WARNING, "Option %s skipped - not known to demuxer.\n", t->key);
return AVERROR_OPTION_NOT_FOUND;
}
if (find_stream_info) { if (find_stream_info) {
AVDictionary **opts = setup_find_stream_info_opts(fmt_ctx, codec_opts); AVDictionary **opts = setup_find_stream_info_opts(fmt_ctx, codec_opts);
@ -2938,6 +3056,7 @@ static int open_input_file(InputFile *ifile, const char *filename)
ist->dec_ctx->pkt_timebase = stream->time_base; ist->dec_ctx->pkt_timebase = stream->time_base;
ist->dec_ctx->framerate = stream->avg_frame_rate; ist->dec_ctx->framerate = stream->avg_frame_rate;
#if FF_API_LAVF_AVCTX #if FF_API_LAVF_AVCTX
ist->dec_ctx->properties = stream->codec->properties;
ist->dec_ctx->coded_width = stream->codec->coded_width; ist->dec_ctx->coded_width = stream->codec->coded_width;
ist->dec_ctx->coded_height = stream->codec->coded_height; ist->dec_ctx->coded_height = stream->codec->coded_height;
#endif #endif
@ -2975,7 +3094,8 @@ static void close_input_file(InputFile *ifile)
avformat_close_input(&ifile->fmt_ctx); avformat_close_input(&ifile->fmt_ctx);
} }
static int probe_file(WriterContext *wctx, const char *filename) static int probe_file(WriterContext *wctx, const char *filename,
const char *print_filename)
{ {
InputFile ifile = { 0 }; InputFile ifile = { 0 };
int ret, i; int ret, i;
@ -2984,7 +3104,7 @@ static int probe_file(WriterContext *wctx, const char *filename)
do_read_frames = do_show_frames || do_count_frames; do_read_frames = do_show_frames || do_count_frames;
do_read_packets = do_show_packets || do_count_packets; do_read_packets = do_show_packets || do_count_packets;
ret = open_input_file(&ifile, filename); ret = open_input_file(&ifile, filename, print_filename);
if (ret < 0) if (ret < 0)
goto end; goto end;
@ -3289,6 +3409,12 @@ static int opt_input_file_i(void *optctx, const char *opt, const char *arg)
return 0; return 0;
} }
static int opt_print_filename(void *optctx, const char *opt, const char *arg)
{
print_input_filename = arg;
return 0;
}
void show_help_default_ffprobe(const char *opt, const char *arg) void show_help_default_ffprobe(const char *opt, const char *arg)
{ {
show_usage(); show_usage();
@ -3563,10 +3689,12 @@ void ffprobe_var_cleanup() {
read_intervals = NULL; read_intervals = NULL;
read_intervals_nb = 0; read_intervals_nb = 0;
find_stream_info = 1;
ffprobe_options = NULL; ffprobe_options = NULL;
input_filename = NULL; input_filename = NULL;
print_input_filename = NULL;
iformat = NULL; iformat = NULL;
hash = NULL; hash = NULL;
@ -3633,13 +3761,13 @@ int ffprobe_execute(int argc, char **argv)
"use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" }, "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
{ "pretty", 0, {.func_arg = opt_pretty}, { "pretty", 0, {.func_arg = opt_pretty},
"prettify the format of displayed values, make it more human readable" }, "prettify the format of displayed values, make it more human readable" },
{ "print_format", OPT_STRING | HAS_ARG, {(void*)&print_format}, { "print_format", OPT_STRING | HAS_ARG, { &print_format },
"set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" }, "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" },
{ "of", OPT_STRING | HAS_ARG, {(void*)&print_format}, "alias for -print_format", "format" }, { "of", OPT_STRING | HAS_ARG, { &print_format }, "alias for -print_format", "format" },
{ "select_streams", OPT_STRING | HAS_ARG, {(void*)&stream_specifier}, "select the specified streams", "stream_specifier" }, { "select_streams", OPT_STRING | HAS_ARG, { &stream_specifier }, "select the specified streams", "stream_specifier" },
{ "sections", OPT_EXIT, {.func_arg = opt_sections}, "print sections structure and section information, and exit" }, { "sections", OPT_EXIT, {.func_arg = opt_sections}, "print sections structure and section information, and exit" },
{ "show_data", OPT_BOOL, {(void*)&do_show_data}, "show packets data" }, { "show_data", OPT_BOOL, { &do_show_data }, "show packets data" },
{ "show_data_hash", OPT_STRING | HAS_ARG, {(void*)&show_data_hash}, "show packets data hash" }, { "show_data_hash", OPT_STRING | HAS_ARG, { &show_data_hash }, "show packets data hash" },
{ "show_error", 0, { .func_arg = &opt_show_error }, "show probing error" }, { "show_error", 0, { .func_arg = &opt_show_error }, "show probing error" },
{ "show_format", 0, { .func_arg = &opt_show_format }, "show format/container info" }, { "show_format", 0, { .func_arg = &opt_show_format }, "show format/container info" },
{ "show_frames", 0, { .func_arg = &opt_show_frames }, "show frames info" }, { "show_frames", 0, { .func_arg = &opt_show_frames }, "show frames info" },
@ -3648,24 +3776,25 @@ int ffprobe_execute(int argc, char **argv)
{ "show_entries", HAS_ARG, {.func_arg = opt_show_entries}, { "show_entries", HAS_ARG, {.func_arg = opt_show_entries},
"show a set of specified entries", "entry_list" }, "show a set of specified entries", "entry_list" },
#if HAVE_THREADS #if HAVE_THREADS
{ "show_log", OPT_INT|HAS_ARG, {(void*)&do_show_log}, "show log" }, { "show_log", OPT_INT|HAS_ARG, { &do_show_log }, "show log" },
#endif #endif
{ "show_packets", 0, { .func_arg = &opt_show_packets }, "show packets info" }, { "show_packets", 0, { .func_arg = &opt_show_packets }, "show packets info" },
{ "show_programs", 0, { .func_arg = &opt_show_programs }, "show programs info" }, { "show_programs", 0, { .func_arg = &opt_show_programs }, "show programs info" },
{ "show_streams", 0, { .func_arg = &opt_show_streams }, "show streams info" }, { "show_streams", 0, { .func_arg = &opt_show_streams }, "show streams info" },
{ "show_chapters", 0, { .func_arg = &opt_show_chapters }, "show chapters info" }, { "show_chapters", 0, { .func_arg = &opt_show_chapters }, "show chapters info" },
{ "count_frames", OPT_BOOL, {(void*)&do_count_frames}, "count the number of frames per stream" }, { "count_frames", OPT_BOOL, { &do_count_frames }, "count the number of frames per stream" },
{ "count_packets", OPT_BOOL, {(void*)&do_count_packets}, "count the number of packets per stream" }, { "count_packets", OPT_BOOL, { &do_count_packets }, "count the number of packets per stream" },
{ "show_program_version", 0, { .func_arg = &opt_show_program_version }, "show ffprobe version" }, { "show_program_version", 0, { .func_arg = &opt_show_program_version }, "show ffprobe version" },
{ "show_library_versions", 0, { .func_arg = &opt_show_library_versions }, "show library versions" }, { "show_library_versions", 0, { .func_arg = &opt_show_library_versions }, "show library versions" },
{ "show_versions", 0, { .func_arg = &opt_show_versions }, "show program and library versions" }, { "show_versions", 0, { .func_arg = &opt_show_versions }, "show program and library versions" },
{ "show_pixel_formats", 0, { .func_arg = &opt_show_pixel_formats }, "show pixel format descriptions" }, { "show_pixel_formats", 0, { .func_arg = &opt_show_pixel_formats }, "show pixel format descriptions" },
{ "show_private_data", OPT_BOOL, {(void*)&show_private_data}, "show private data" }, { "show_private_data", OPT_BOOL, { &show_private_data }, "show private data" },
{ "private", OPT_BOOL, {(void*)&show_private_data}, "same as show_private_data" }, { "private", OPT_BOOL, { &show_private_data }, "same as show_private_data" },
{ "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" }, { "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" },
{ "read_intervals", HAS_ARG, {.func_arg = opt_read_intervals}, "set read intervals", "read_intervals" }, { "read_intervals", HAS_ARG, {.func_arg = opt_read_intervals}, "set read intervals", "read_intervals" },
{ "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" }, { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" },
{ "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"}, { "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"},
{ "print_filename", HAS_ARG, {.func_arg = opt_print_filename}, "override the printed input filename", "print_file"},
{ "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info }, { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
"read and decode the streams to fill missing information with heuristics" }, "read and decode the streams to fill missing information with heuristics" },
{ NULL, }, { NULL, },
@ -3800,7 +3929,7 @@ int ffprobe_execute(int argc, char **argv)
av_log(NULL, AV_LOG_ERROR, "Use -h to get full help or, even better, run 'man %s'.\n", program_name); av_log(NULL, AV_LOG_ERROR, "Use -h to get full help or, even better, run 'man %s'.\n", program_name);
ret = AVERROR(EINVAL); ret = AVERROR(EINVAL);
} else if (input_filename) { } else if (input_filename) {
ret = probe_file(wctx, input_filename); ret = probe_file(wctx, input_filename, print_input_filename);
if (ret < 0 && do_show_error) if (ret < 0 && do_show_error)
show_error(wctx, ret); show_error(wctx, ret);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020 Taner Sener * Copyright (c) 2020-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020 Taner Sener * Copyright (c) 2020-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020 Taner Sener * Copyright (c) 2020-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020 Taner Sener * Copyright (c) 2020-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020 Taner Sener * Copyright (c) 2020-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020 Taner Sener * Copyright (c) 2020-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020 Taner Sener * Copyright (c) 2020-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020 Taner Sener * Copyright (c) 2018-2021 Taner Sener
* *
* This file is part of FFmpegKit. * This file is part of FFmpegKit.
* *

View File

@ -30,17 +30,17 @@
* *
* CHANGES 08.2018 * CHANGES 08.2018
* -------------------------------------------------------- * --------------------------------------------------------
* - fftools_ prefix added to file name and parent header * - fftools_ prefix added to the file name and parent header
* *
* CHANGES 07.2018 * CHANGES 07.2018
* -------------------------------------------------------- * --------------------------------------------------------
* - Unused headers removed * - Unused headers removed
* - Parentheses placed around assignments in condition to prevent -Wparentheses warning * - Parentheses placed around assignments in conditions to prevent -Wparentheses warning
* - exit_program updated with longjmp, disabling exit * - exit_program updated with longjmp, disabling exit
* - longjmp_value added to store exit code * - longjmp_value added to store exit code
* - (optindex < argc) validation added before accessing argv[optindex] inside split_commandline() * - (optindex < argc) validation added before accessing argv[optindex] inside split_commandline()
* and parse_options() * and parse_options()
* - All av_log_set_callback invocations updated to set ffmpegkit_log_callback_function from Config.m. Unused * - All av_log_set_callback invocations updated to set ffmpegkit_log_callback_function from FFmpegKitConfig.m. Unused
* log_callback_help and log_callback_help methods removed * log_callback_help and log_callback_help methods removed
* - (idx + 1 < argc) validation added in parse_loglevel() * - (idx + 1 < argc) validation added in parse_loglevel()
*/ */
@ -80,9 +80,6 @@
#include "libavutil/ffversion.h" #include "libavutil/ffversion.h"
#include "libavutil/version.h" #include "libavutil/version.h"
#include "fftools_cmdutils.h" #include "fftools_cmdutils.h"
#if CONFIG_NETWORK
#include "libavformat/network.h"
#endif
#if HAVE_SYS_RESOURCE_H #if HAVE_SYS_RESOURCE_H
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
@ -149,7 +146,7 @@ void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
void init_dynload(void) void init_dynload(void)
{ {
#if HAVE_SETDLLDIRECTORY #if HAVE_SETDLLDIRECTORY && defined(_WIN32)
/* Calling SetDllDirectory with the empty string (but not NULL) removes the /* Calling SetDllDirectory with the empty string (but not NULL) removes the
* current working directory from the DLL search path as a security pre-caution. */ * current working directory from the DLL search path as a security pre-caution. */
SetDllDirectory(""); SetDllDirectory("");
@ -215,7 +212,7 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags,
first = 1; first = 1;
for (po = options; po->name; po++) { for (po = options; po->name; po++) {
char buf[64]; char buf[128];
if (((po->flags & req_flags) != req_flags) || if (((po->flags & req_flags) != req_flags) ||
(alt_flags && !(po->flags & alt_flags)) || (alt_flags && !(po->flags & alt_flags)) ||
@ -238,13 +235,14 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags,
void show_help_children(const AVClass *class, int flags) void show_help_children(const AVClass *class, int flags)
{ {
const AVClass *child = NULL; void *iter = NULL;
const AVClass *child;
if (class->option) { if (class->option) {
av_opt_show2(&class, NULL, flags, 0); av_opt_show2(&class, NULL, flags, 0);
av_log(NULL, AV_LOG_STDERR, "\n"); av_log(NULL, AV_LOG_STDERR, "\n");
} }
while ((child = av_opt_child_class_next(class, child))) while ((child = av_opt_child_class_iterate(class, &iter)))
show_help_children(child, flags); show_help_children(child, flags);
} }
@ -358,7 +356,7 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt,
} else if (po->flags & OPT_BOOL || po->flags & OPT_INT) { } else if (po->flags & OPT_BOOL || po->flags & OPT_INT) {
*(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); *(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
} else if (po->flags & OPT_INT64) { } else if (po->flags & OPT_INT64) {
*(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); *(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, (double)INT64_MAX);
} else if (po->flags & OPT_TIME) { } else if (po->flags & OPT_TIME) {
*(int64_t *)dst = parse_time_or_die(opt, arg, 1); *(int64_t *)dst = parse_time_or_die(opt, arg, 1);
} else if (po->flags & OPT_FLOAT) { } else if (po->flags & OPT_FLOAT) {
@ -507,7 +505,7 @@ int locate_option(int argc, char **argv, const OptionDef *options,
return 0; return 0;
} }
void dump_argument(const char *a) static void dump_argument(const char *a)
{ {
const unsigned char *p; const unsigned char *p;
@ -1017,7 +1015,7 @@ static void expand_filename_template(AVBPrint *bp, const char *template,
} }
} }
int init_report(const char *env) static int init_report(const char *env)
{ {
char *filename_template = NULL; char *filename_template = NULL;
char *key, *val; char *key, *val;
@ -1461,10 +1459,6 @@ static void print_codec(const AVCodec *c)
av_log(NULL, AV_LOG_STDERR, "threads "); av_log(NULL, AV_LOG_STDERR, "threads ");
if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING) if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)
av_log(NULL, AV_LOG_STDERR, "avoidprobe "); av_log(NULL, AV_LOG_STDERR, "avoidprobe ");
if (c->capabilities & AV_CODEC_CAP_INTRA_ONLY)
av_log(NULL, AV_LOG_STDERR, "intraonly ");
if (c->capabilities & AV_CODEC_CAP_LOSSLESS)
av_log(NULL, AV_LOG_STDERR, "lossless ");
if (c->capabilities & AV_CODEC_CAP_HARDWARE) if (c->capabilities & AV_CODEC_CAP_HARDWARE)
av_log(NULL, AV_LOG_STDERR, "hardware "); av_log(NULL, AV_LOG_STDERR, "hardware ");
if (c->capabilities & AV_CODEC_CAP_HYBRID) if (c->capabilities & AV_CODEC_CAP_HYBRID)
@ -1538,13 +1532,14 @@ static char get_media_type_char(enum AVMediaType type)
} }
} }
static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev, static const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,
int encoder) int encoder)
{ {
while ((prev = av_codec_next(prev))) { const AVCodec *c;
if (prev->id == id && while ((c = av_codec_iterate(iter))) {
(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev))) if (c->id == id &&
return prev; (encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c)))
return c;
} }
return NULL; return NULL;
} }
@ -1581,11 +1576,12 @@ static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
static void print_codecs_for_id(enum AVCodecID id, int encoder) static void print_codecs_for_id(enum AVCodecID id, int encoder)
{ {
const AVCodec *codec = NULL; void *iter = NULL;
const AVCodec *codec;
av_log(NULL, AV_LOG_STDERR, " (%s: ", encoder ? "encoders" : "decoders"); av_log(NULL, AV_LOG_STDERR, " (%s: ", encoder ? "encoders" : "decoders");
while ((codec = next_codec_for_id(id, codec, encoder))) while ((codec = next_codec_for_id(id, &iter, encoder)))
av_log(NULL, AV_LOG_STDERR, "%s ", codec->name); av_log(NULL, AV_LOG_STDERR, "%s ", codec->name);
av_log(NULL, AV_LOG_STDERR, ")"); av_log(NULL, AV_LOG_STDERR, ")");
@ -1608,7 +1604,8 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
" -------\n"); " -------\n");
for (i = 0; i < nb_codecs; i++) { for (i = 0; i < nb_codecs; i++) {
const AVCodecDescriptor *desc = codecs[i]; const AVCodecDescriptor *desc = codecs[i];
const AVCodec *codec = NULL; const AVCodec *codec;
void *iter = NULL;
if (strstr(desc->name, "_deprecated")) if (strstr(desc->name, "_deprecated"))
continue; continue;
@ -1626,14 +1623,14 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
/* print decoders/encoders when there's more than one or their /* print decoders/encoders when there's more than one or their
* names are different from codec name */ * names are different from codec name */
while ((codec = next_codec_for_id(desc->id, codec, 0))) { while ((codec = next_codec_for_id(desc->id, &iter, 0))) {
if (strcmp(codec->name, desc->name)) { if (strcmp(codec->name, desc->name)) {
print_codecs_for_id(desc->id, 0); print_codecs_for_id(desc->id, 0);
break; break;
} }
} }
codec = NULL; iter = NULL;
while ((codec = next_codec_for_id(desc->id, codec, 1))) { while ((codec = next_codec_for_id(desc->id, &iter, 1))) {
if (strcmp(codec->name, desc->name)) { if (strcmp(codec->name, desc->name)) {
print_codecs_for_id(desc->id, 1); print_codecs_for_id(desc->id, 1);
break; break;
@ -1664,9 +1661,10 @@ static void print_codecs(int encoder)
encoder ? "Encoders" : "Decoders"); encoder ? "Encoders" : "Decoders");
for (i = 0; i < nb_codecs; i++) { for (i = 0; i < nb_codecs; i++) {
const AVCodecDescriptor *desc = codecs[i]; const AVCodecDescriptor *desc = codecs[i];
const AVCodec *codec = NULL; const AVCodec *codec;
void *iter = NULL;
while ((codec = next_codec_for_id(desc->id, codec, encoder))) { while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
av_log(NULL, AV_LOG_STDERR, " %c", get_media_type_char(desc->type)); av_log(NULL, AV_LOG_STDERR, " %c", get_media_type_char(desc->type));
av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : "."); av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : "."); av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
@ -1871,9 +1869,10 @@ static void show_help_codec(const char *name, int encoder)
if (codec) if (codec)
print_codec(codec); print_codec(codec);
else if ((desc = avcodec_descriptor_get_by_name(name))) { else if ((desc = avcodec_descriptor_get_by_name(name))) {
void *iter = NULL;
int printed = 0; int printed = 0;
while ((codec = next_codec_for_id(desc->id, codec, encoder))) { while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
printed = 1; printed = 1;
print_codec(codec); print_codec(codec);
} }
@ -1908,6 +1907,24 @@ static void show_help_demuxer(const char *name)
show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM); 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) static void show_help_muxer(const char *name)
{ {
const AVCodecDescriptor *desc; const AVCodecDescriptor *desc;
@ -2041,6 +2058,8 @@ int show_help(void *optctx, const char *opt, const char *arg)
show_help_demuxer(par); show_help_demuxer(par);
} else if (!strcmp(topic, "muxer")) { } else if (!strcmp(topic, "muxer")) {
show_help_muxer(par); show_help_muxer(par);
} else if (!strcmp(topic, "protocol")) {
show_help_protocol(par);
#if CONFIG_AVFILTER #if CONFIG_AVFILTER
} else if (!strcmp(topic, "filter")) { } else if (!strcmp(topic, "filter")) {
show_help_filter(par); show_help_filter(par);
@ -2084,7 +2103,7 @@ FILE *get_preset_file(char *filename, size_t filename_size,
av_strlcpy(filename, preset_name, filename_size); av_strlcpy(filename, preset_name, filename_size);
f = fopen(filename, "r"); f = fopen(filename, "r");
} else { } else {
#if HAVE_GETMODULEHANDLE #if HAVE_GETMODULEHANDLE && defined(_WIN32)
char datadir[MAX_PATH], *ls; char datadir[MAX_PATH], *ls;
base[2] = NULL; base[2] = NULL;
@ -2237,7 +2256,7 @@ double get_rotation(AVStream *st)
if (fabs(theta - 90*round(theta/90)) > 2) if (fabs(theta - 90*round(theta/90)) > 2)
av_log(NULL, AV_LOG_WARNING, "Odd rotation angle.\n" av_log(NULL, AV_LOG_WARNING, "Odd rotation angle.\n"
"If you want to help, upload a sample " "If you want to help, upload a sample "
"of this file to ftp://upload.ffmpeg.org/incoming/ " "of this file to https://streams.videolan.org/upload/ "
"and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)"); "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)");
return theta; return theta;
@ -2334,7 +2353,7 @@ int show_sources(void *optctx, const char *opt, const char *arg)
int ret = 0; int ret = 0;
int error_level = av_log_get_level(); int error_level = av_log_get_level();
av_log_set_level(AV_LOG_ERROR); av_log_set_level(AV_LOG_WARNING);
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0) if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
goto fail; goto fail;
@ -2372,7 +2391,7 @@ int show_sinks(void *optctx, const char *opt, const char *arg)
int ret = 0; int ret = 0;
int error_level = av_log_get_level(); int error_level = av_log_get_level();
av_log_set_level(AV_LOG_ERROR); av_log_set_level(AV_LOG_WARNING);
if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0) if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
goto fail; goto fail;

File diff suppressed because it is too large Load Diff

View File

@ -84,7 +84,6 @@ enum HWAccelID {
HWACCEL_GENERIC, HWACCEL_GENERIC,
HWACCEL_VIDEOTOOLBOX, HWACCEL_VIDEOTOOLBOX,
HWACCEL_QSV, HWACCEL_QSV,
HWACCEL_CUVID,
}; };
typedef struct HWAccel { typedef struct HWAccel {
@ -239,6 +238,8 @@ typedef struct OptionsContext {
int nb_passlogfiles; int nb_passlogfiles;
SpecifierOpt *max_muxing_queue_size; SpecifierOpt *max_muxing_queue_size;
int nb_max_muxing_queue_size; int nb_max_muxing_queue_size;
SpecifierOpt *muxing_queue_data_threshold;
int nb_muxing_queue_data_threshold;
SpecifierOpt *guess_layout_max; SpecifierOpt *guess_layout_max;
int nb_guess_layout_max; int nb_guess_layout_max;
SpecifierOpt *apad; SpecifierOpt *apad;
@ -253,6 +254,8 @@ typedef struct OptionsContext {
int nb_time_bases; int nb_time_bases;
SpecifierOpt *enc_time_bases; SpecifierOpt *enc_time_bases;
int nb_enc_time_bases; int nb_enc_time_bases;
SpecifierOpt *autoscale;
int nb_autoscale;
} OptionsContext; } OptionsContext;
typedef struct InputFilter { typedef struct InputFilter {
@ -372,6 +375,7 @@ typedef struct InputStream {
AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init
AVFrame *frame; AVFrame *frame;
int w, h; int w, h;
unsigned int initialize; ///< marks if sub2video_update should force an initialization
} sub2video; } sub2video;
int dr1; int dr1;
@ -454,6 +458,7 @@ enum forced_keyframes_const {
}; };
#define ABORT_ON_FLAG_EMPTY_OUTPUT (1 << 0) #define ABORT_ON_FLAG_EMPTY_OUTPUT (1 << 0)
#define ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM (1 << 1)
extern const char *const forced_keyframes_const_names[]; extern const char *const forced_keyframes_const_names[];
@ -482,8 +487,7 @@ typedef struct OutputStream {
AVRational mux_timebase; AVRational mux_timebase;
AVRational enc_timebase; AVRational enc_timebase;
int nb_bitstream_filters; AVBSFContext *bsf_ctx;
AVBSFContext **bsf_ctx;
AVCodecContext *enc_ctx; AVCodecContext *enc_ctx;
AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */ AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */
@ -502,6 +506,7 @@ typedef struct OutputStream {
int force_fps; int force_fps;
int top_field_first; int top_field_first;
int rotate_overridden; int rotate_overridden;
int autoscale;
double rotate_override_value; double rotate_override_value;
AVRational frame_aspect_ratio; AVRational frame_aspect_ratio;
@ -567,6 +572,15 @@ typedef struct OutputStream {
/* the packets are buffered here until the muxer is ready to be initialized */ /* the packets are buffered here until the muxer is ready to be initialized */
AVFifoBuffer *muxing_queue; AVFifoBuffer *muxing_queue;
/*
* The size of the AVPackets' buffers in queue.
* Updated when a packet is either pushed or pulled from the queue.
*/
size_t muxing_queue_data_size;
/* Threshold after which max_muxing_queue_size will be in effect */
size_t muxing_queue_data_threshold;
/* packet picture type */ /* packet picture type */
int pict_type; int pict_type;
@ -623,6 +637,7 @@ extern __thread int debug_ts;
extern __thread int exit_on_error; extern __thread int exit_on_error;
extern __thread int abort_on_flags; extern __thread int abort_on_flags;
extern __thread int print_stats; extern __thread int print_stats;
extern __thread int64_t stats_period;
extern __thread int qp_hist; extern __thread int qp_hist;
extern __thread int stdin_interaction; extern __thread int stdin_interaction;
extern __thread int frame_bits_per_raw_sample; extern __thread int frame_bits_per_raw_sample;
@ -633,11 +648,11 @@ extern __thread char *videotoolbox_pixfmt;
extern __thread int filter_nbthreads; extern __thread int filter_nbthreads;
extern __thread int filter_complex_nbthreads; extern __thread int filter_complex_nbthreads;
extern __thread int vstats_version; extern __thread int vstats_version;
extern __thread int auto_conversion_filters;
extern __thread const AVIOInterruptCB int_cb; extern __thread const AVIOInterruptCB int_cb;
extern const HWAccel hwaccels[]; extern const HWAccel hwaccels[];
extern __thread AVBufferRef *hw_device_ctx;
#if CONFIG_QSV #if CONFIG_QSV
extern __thread char *qsv_device; extern __thread char *qsv_device;
#endif #endif
@ -656,8 +671,8 @@ void assert_avoptions(AVDictionary *m);
int guess_input_channel_layout(InputStream *ist); int guess_input_channel_layout(InputStream *ist);
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *avctx, AVCodec *codec, enum AVPixelFormat target); enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *avctx, const AVCodec *codec, enum AVPixelFormat target);
void choose_sample_fmt(AVStream *st, AVCodec *codec); void choose_sample_fmt(AVStream *st, const AVCodec *codec);
int configure_filtergraph(FilterGraph *fg); int configure_filtergraph(FilterGraph *fg);
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out); int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out);
@ -667,7 +682,7 @@ int filtergraph_is_simple(FilterGraph *fg);
int init_simple_filtergraph(InputStream *ist, OutputStream *ost); int init_simple_filtergraph(InputStream *ist, OutputStream *ost);
int init_complex_filtergraph(FilterGraph *fg); int init_complex_filtergraph(FilterGraph *fg);
void sub2video_update(InputStream *ist, AVSubtitle *sub); void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub);
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame); int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
@ -675,7 +690,6 @@ int ffmpeg_parse_options(int argc, char **argv);
int videotoolbox_init(AVCodecContext *s); int videotoolbox_init(AVCodecContext *s);
int qsv_init(AVCodecContext *s); int qsv_init(AVCodecContext *s);
int cuvid_init(AVCodecContext *s);
HWDevice *hw_device_get_by_name(const char *name); HWDevice *hw_device_get_by_name(const char *name);
int hw_device_init_from_string(const char *arg, HWDevice **dev); int hw_device_init_from_string(const char *arg, HWDevice **dev);
@ -683,6 +697,7 @@ void hw_device_free_all(void);
int hw_device_setup_for_decode(InputStream *ist); int hw_device_setup_for_decode(InputStream *ist);
int hw_device_setup_for_encode(OutputStream *ost); int hw_device_setup_for_encode(OutputStream *ost);
int hw_device_setup_for_filter(FilterGraph *fg);
int hwaccel_decode_init(AVCodecContext *avctx); int hwaccel_decode_init(AVCodecContext *avctx);
@ -698,6 +713,7 @@ int opt_progress(void *optctx, const char *opt, const char *arg);
int opt_target(void *optctx, const char *opt, const char *arg); int opt_target(void *optctx, const char *opt, const char *arg);
int opt_vsync(void *optctx, const char *opt, const char *arg); int opt_vsync(void *optctx, const char *opt, const char *arg);
int opt_abort_on(void *optctx, const char *opt, const char *arg); int opt_abort_on(void *optctx, const char *opt, const char *arg);
int opt_stats_period(void *optctx, const char *opt, const char *arg);
int opt_qscale(void *optctx, const char *opt, const char *arg); int opt_qscale(void *optctx, const char *opt, const char *arg);
int opt_profile(void *optctx, const char *opt, const char *arg); int opt_profile(void *optctx, const char *opt, const char *arg);
int opt_filter_complex(void *optctx, const char *opt, const char *arg); int opt_filter_complex(void *optctx, const char *opt, const char *arg);

View File

@ -68,7 +68,7 @@ static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum AVCodec
} }
} }
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCodec *codec, enum AVPixelFormat target) enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, const AVCodec *codec, enum AVPixelFormat target)
{ {
if (codec && codec->pix_fmts) { if (codec && codec->pix_fmts) {
const enum AVPixelFormat *p = codec->pix_fmts; const enum AVPixelFormat *p = codec->pix_fmts;
@ -98,7 +98,7 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, AVCod
return target; return target;
} }
void choose_sample_fmt(AVStream *st, AVCodec *codec) void choose_sample_fmt(AVStream *st, const AVCodec *codec)
{ {
if (codec && codec->sample_fmts) { if (codec && codec->sample_fmts) {
const enum AVSampleFormat *p = codec->sample_fmts; const enum AVSampleFormat *p = codec->sample_fmts;
@ -107,7 +107,8 @@ void choose_sample_fmt(AVStream *st, AVCodec *codec)
break; break;
} }
if (*p == -1) { if (*p == -1) {
if((codec->capabilities & AV_CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codecpar->format) > av_get_sample_fmt_name(codec->sample_fmts[0])) const AVCodecDescriptor *desc = avcodec_descriptor_get(codec->id);
if(desc && (desc->props & AV_CODEC_PROP_LOSSLESS) && av_get_sample_fmt_name(st->codecpar->format) > av_get_sample_fmt_name(codec->sample_fmts[0]))
av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n"); av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n");
if(av_get_sample_fmt_name(st->codecpar->format)) if(av_get_sample_fmt_name(st->codecpar->format))
av_log(NULL, AV_LOG_WARNING, av_log(NULL, AV_LOG_WARNING,
@ -477,7 +478,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ofilter->width || ofilter->height) { if ((ofilter->width || ofilter->height) && ofilter->ost->autoscale) {
char args[255]; char args[255];
AVFilterContext *filter; AVFilterContext *filter;
AVDictionaryEntry *e = NULL; AVDictionaryEntry *e = NULL;
@ -748,6 +749,12 @@ static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
ist->sub2video.last_pts = INT64_MIN; ist->sub2video.last_pts = INT64_MIN;
ist->sub2video.end_pts = INT64_MIN; ist->sub2video.end_pts = INT64_MIN;
/* sub2video structure has been (re-)initialized.
Mark it as such so that the system will be
initialized with the first received heartbeat. */
ist->sub2video.initialize = 1;
return 0; return 0;
} }
@ -794,10 +801,9 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC); av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
av_bprintf(&args, av_bprintf(&args,
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:" "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
"pixel_aspect=%d/%d:sws_param=flags=%d", "pixel_aspect=%d/%d",
ifilter->width, ifilter->height, ifilter->format, ifilter->width, ifilter->height, ifilter->format,
tb.num, tb.den, sar.num, sar.den, tb.num, tb.den, sar.num, sar.den);
SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
if (fr.num && fr.den) if (fr.num && fr.den)
av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den); av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index, snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
@ -1064,17 +1070,9 @@ int configure_filtergraph(FilterGraph *fg)
if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0) if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
goto fail; goto fail;
if (filter_hw_device || hw_device_ctx) { ret = hw_device_setup_for_filter(fg);
AVBufferRef *device = filter_hw_device ? filter_hw_device->device_ref if (ret < 0)
: hw_device_ctx;
for (i = 0; i < fg->graph->nb_filters; i++) {
fg->graph->filters[i]->hw_device_ctx = av_buffer_ref(device);
if (!fg->graph->filters[i]->hw_device_ctx) {
ret = AVERROR(ENOMEM);
goto fail; goto fail;
}
}
}
if (simple && (!inputs || inputs->next || !outputs || outputs->next)) { if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
const char *num_inputs; const char *num_inputs;
@ -1114,6 +1112,8 @@ int configure_filtergraph(FilterGraph *fg)
configure_output_filter(fg, fg->outputs[i], cur); configure_output_filter(fg, fg->outputs[i], cur);
avfilter_inout_free(&outputs); avfilter_inout_free(&outputs);
if (!auto_conversion_filters)
avfilter_graph_set_auto_convert(fg->graph, AVFILTER_AUTO_CONVERT_NONE);
if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0) if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
goto fail; goto fail;
@ -1177,7 +1177,7 @@ int configure_filtergraph(FilterGraph *fg)
while (av_fifo_size(ist->sub2video.sub_queue)) { while (av_fifo_size(ist->sub2video.sub_queue)) {
AVSubtitle tmp; AVSubtitle tmp;
av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL); av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
sub2video_update(ist, &tmp); sub2video_update(ist, INT64_MIN, &tmp);
avsubtitle_free(&tmp); avsubtitle_free(&tmp);
} }
} }

View File

@ -28,6 +28,8 @@
#include <string.h> #include <string.h>
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/pixdesc.h"
#include "libavfilter/buffersink.h"
#include "fftools_ffmpeg.h" #include "fftools_ffmpeg.h"
@ -425,18 +427,57 @@ int hw_device_setup_for_decode(InputStream *ist)
int hw_device_setup_for_encode(OutputStream *ost) int hw_device_setup_for_encode(OutputStream *ost)
{ {
HWDevice *dev; const AVCodecHWConfig *config;
HWDevice *dev = NULL;
AVBufferRef *frames_ref = NULL;
int i;
if (ost->filter) {
frames_ref = av_buffersink_get_hw_frames_ctx(ost->filter->filter);
if (frames_ref &&
((AVHWFramesContext*)frames_ref->data)->format ==
ost->enc_ctx->pix_fmt) {
// Matching format, will try to use hw_frames_ctx.
} else {
frames_ref = NULL;
}
}
for (i = 0;; i++) {
config = avcodec_get_hw_config(ost->enc, i);
if (!config)
break;
if (frames_ref &&
config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX &&
(config->pix_fmt == AV_PIX_FMT_NONE ||
config->pix_fmt == ost->enc_ctx->pix_fmt)) {
av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using input "
"frames context (format %s) with %s encoder.\n",
av_get_pix_fmt_name(ost->enc_ctx->pix_fmt),
ost->enc->name);
ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
if (!ost->enc_ctx->hw_frames_ctx)
return AVERROR(ENOMEM);
return 0;
}
if (!dev &&
config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)
dev = hw_device_get_by_type(config->device_type);
}
dev = hw_device_match_by_codec(ost->enc);
if (dev) { if (dev) {
av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using device %s "
"(type %s) with %s encoder.\n", dev->name,
av_hwdevice_get_type_name(dev->type), ost->enc->name);
ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref); ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
if (!ost->enc_ctx->hw_device_ctx) if (!ost->enc_ctx->hw_device_ctx)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
return 0;
} else { } else {
// No device required, or no device available. // No device required, or no device available.
return 0;
} }
return 0;
} }
static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input) static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input)
@ -489,3 +530,31 @@ int hwaccel_decode_init(AVCodecContext *avctx)
return 0; return 0;
} }
int hw_device_setup_for_filter(FilterGraph *fg)
{
HWDevice *dev;
int i;
// If the user has supplied exactly one hardware device then just
// give it straight to every filter for convenience. If more than
// one device is available then the user needs to pick one explcitly
// with the filter_hw_device option.
if (filter_hw_device)
dev = filter_hw_device;
else if (nb_hw_devices == 1)
dev = hw_devices[0];
else
dev = NULL;
if (dev) {
for (i = 0; i < fg->graph->nb_filters; i++) {
fg->graph->filters[i]->hw_device_ctx =
av_buffer_ref(dev->device_ref);
if (!fg->graph->filters[i]->hw_device_ctx)
return AVERROR(ENOMEM);
}
}
return 0;
}

View File

@ -59,16 +59,82 @@
#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass" #define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
#define SPECIFIER_OPT_FMT_str "%s"
#define SPECIFIER_OPT_FMT_i "%i"
#define SPECIFIER_OPT_FMT_i64 "%"PRId64
#define SPECIFIER_OPT_FMT_ui64 "%"PRIu64
#define SPECIFIER_OPT_FMT_f "%f"
#define SPECIFIER_OPT_FMT_dbl "%lf"
static const char *const opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL};
static const char *const opt_name_audio_channels[] = {"ac", NULL};
static const char *const opt_name_audio_sample_rate[] = {"ar", NULL};
static const char *const opt_name_frame_rates[] = {"r", NULL};
static const char *const opt_name_frame_sizes[] = {"s", NULL};
static const char *const opt_name_frame_pix_fmts[] = {"pix_fmt", NULL};
static const char *const opt_name_ts_scale[] = {"itsscale", NULL};
static const char *const opt_name_hwaccels[] = {"hwaccel", NULL};
static const char *const opt_name_hwaccel_devices[] = {"hwaccel_device", NULL};
static const char *const opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL};
static const char *const opt_name_autorotate[] = {"autorotate", NULL};
static const char *const opt_name_autoscale[] = {"autoscale", NULL};
static const char *const opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL};
static const char *const opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL};
static const char *const opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL};
static const char *const opt_name_sample_fmts[] = {"sample_fmt", NULL};
static const char *const opt_name_qscale[] = {"q", "qscale", NULL};
static const char *const opt_name_forced_key_frames[] = {"forced_key_frames", NULL};
static const char *const opt_name_force_fps[] = {"force_fps", NULL};
static const char *const opt_name_frame_aspect_ratios[] = {"aspect", NULL};
static const char *const opt_name_rc_overrides[] = {"rc_override", NULL};
static const char *const opt_name_intra_matrices[] = {"intra_matrix", NULL};
static const char *const opt_name_inter_matrices[] = {"inter_matrix", NULL};
static const char *const opt_name_chroma_intra_matrices[] = {"chroma_intra_matrix", NULL};
static const char *const opt_name_top_field_first[] = {"top", NULL};
static const char *const opt_name_presets[] = {"pre", "apre", "vpre", "spre", NULL};
static const char *const opt_name_copy_initial_nonkeyframes[] = {"copyinkfr", NULL};
static const char *const opt_name_copy_prior_start[] = {"copypriorss", NULL};
static const char *const opt_name_filters[] = {"filter", "af", "vf", NULL};
static const char *const opt_name_filter_scripts[] = {"filter_script", NULL};
static const char *const opt_name_reinit_filters[] = {"reinit_filter", NULL};
static const char *const opt_name_fix_sub_duration[] = {"fix_sub_duration", NULL};
static const char *const opt_name_canvas_sizes[] = {"canvas_size", NULL};
static const char *const opt_name_pass[] = {"pass", NULL};
static const char *const opt_name_passlogfiles[] = {"passlogfile", NULL};
static const char *const opt_name_max_muxing_queue_size[] = {"max_muxing_queue_size", NULL};
static const char *const opt_name_muxing_queue_data_threshold[] = {"muxing_queue_data_threshold", NULL};
static const char *const opt_name_guess_layout_max[] = {"guess_layout_max", NULL};
static const char *const opt_name_apad[] = {"apad", NULL};
static const char *const opt_name_discard[] = {"discard", NULL};
static const char *const opt_name_disposition[] = {"disposition", NULL};
static const char *const opt_name_time_bases[] = {"time_base", NULL};
static const char *const opt_name_enc_time_bases[] = {"enc_time_base", NULL};
#define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\
{\
char namestr[128] = "";\
const char *spec = so->specifier && so->specifier[0] ? so->specifier : "";\
for (i = 0; opt_name_##name[i]; i++)\
av_strlcatf(namestr, sizeof(namestr), "-%s%s", opt_name_##name[i], opt_name_##name[i+1] ? (opt_name_##name[i+2] ? ", " : " or ") : "");\
av_log(NULL, AV_LOG_WARNING, "Multiple %s options specified for stream %d, only the last option '-%s%s%s "SPECIFIER_OPT_FMT_##type"' will be used.\n",\
namestr, st->index, opt_name_##name[0], spec[0] ? ":" : "", spec, so->u.type);\
}
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\ #define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
{\ {\
int i, ret;\ int i, ret, matches = 0;\
SpecifierOpt *so;\
for (i = 0; i < o->nb_ ## name; i++) {\ for (i = 0; i < o->nb_ ## name; i++) {\
char *spec = o->name[i].specifier;\ char *spec = o->name[i].specifier;\
if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\ if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0) {\
outvar = o->name[i].u.type;\ outvar = o->name[i].u.type;\
else if (ret < 0)\ so = &o->name[i];\
matches++;\
} else if (ret < 0)\
exit_program(1);\ exit_program(1);\
}\ }\
if (matches > 1)\
WARN_MULTIPLE_OPT_USAGE(name, type, so, st);\
} }
#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\ #define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\
@ -87,13 +153,9 @@ const HWAccel hwaccels[] = {
#endif #endif
#if CONFIG_LIBMFX #if CONFIG_LIBMFX
{ "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV }, { "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV },
#endif
#if CONFIG_CUVID
{ "cuvid", cuvid_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA },
#endif #endif
{ 0 }, { 0 },
}; };
__thread AVBufferRef *hw_device_ctx;
__thread HWDevice *filter_hw_device; __thread HWDevice *filter_hw_device;
__thread char *vstats_filename; __thread char *vstats_filename;
@ -126,6 +188,8 @@ __thread float max_error_rate = 2.0/3;
__thread int filter_nbthreads = 0; __thread int filter_nbthreads = 0;
__thread int filter_complex_nbthreads = 0; __thread int filter_complex_nbthreads = 0;
__thread int vstats_version = 2; __thread int vstats_version = 2;
__thread int auto_conversion_filters = 1;
__thread int64_t stats_period = 500000;
__thread int intra_only = 0; __thread int intra_only = 0;
@ -184,19 +248,17 @@ void init_options(OptionsContext *o)
o->limit_filesize = UINT64_MAX; o->limit_filesize = UINT64_MAX;
o->chapters_input_file = INT_MAX; o->chapters_input_file = INT_MAX;
o->accurate_seek = 1; o->accurate_seek = 1;
o->thread_queue_size = -1;
} }
int show_hwaccels(void *optctx, const char *opt, const char *arg) int show_hwaccels(void *optctx, const char *opt, const char *arg)
{ {
enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE; enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
int i;
av_log(NULL, AV_LOG_STDERR, "Hardware acceleration methods:\n"); av_log(NULL, AV_LOG_STDERR, "Hardware acceleration methods:\n");
while ((type = av_hwdevice_iterate_types(type)) != while ((type = av_hwdevice_iterate_types(type)) !=
AV_HWDEVICE_TYPE_NONE) AV_HWDEVICE_TYPE_NONE)
av_log(NULL, AV_LOG_STDERR, "%s\n", av_hwdevice_get_type_name(type)); av_log(NULL, AV_LOG_STDERR, "%s\n", av_hwdevice_get_type_name(type));
for (i = 0; hwaccels[i].name; i++)
av_log(NULL, AV_LOG_STDERR, "%s\n", hwaccels[i].name);
av_log(NULL, AV_LOG_STDERR, "\n"); av_log(NULL, AV_LOG_STDERR, "\n");
return 0; return 0;
} }
@ -222,8 +284,9 @@ AVDictionary *strip_specifiers(AVDictionary *dict)
int opt_abort_on(void *optctx, const char *opt, const char *arg) int opt_abort_on(void *optctx, const char *opt, const char *arg)
{ {
const AVOption opts[] = { const AVOption opts[] = {
{ "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, { "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, (double)INT64_MAX, .unit = "flags" },
{ "empty_output" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT }, .unit = "flags" }, { "empty_output" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT }, .unit = "flags" },
{ "empty_output_stream", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM }, .unit = "flags" },
{ NULL }, { NULL },
}; };
const AVClass class = { const AVClass class = {
@ -237,6 +300,21 @@ int opt_abort_on(void *optctx, const char *opt, const char *arg)
return av_opt_eval_flags(&pclass, &opts[0], arg, &abort_on_flags); return av_opt_eval_flags(&pclass, &opts[0], arg, &abort_on_flags);
} }
int opt_stats_period(void *optctx, const char *opt, const char *arg)
{
int64_t user_stats_period = parse_time_or_die(opt, arg, 1);
if (user_stats_period <= 0) {
av_log(NULL, AV_LOG_ERROR, "stats_period %s must be positive.\n", arg);
return AVERROR(EINVAL);
}
stats_period = user_stats_period;
av_log(NULL, AV_LOG_INFO, "ffmpeg stats and -progress period set to %s.\n", arg);
return 0;
}
int opt_sameq(void *optctx, const char *opt, const char *arg) int opt_sameq(void *optctx, const char *opt, const char *arg)
{ {
av_log(NULL, AV_LOG_ERROR, "Option '%s' was removed. " av_log(NULL, AV_LOG_ERROR, "Option '%s' was removed. "
@ -495,21 +573,15 @@ int opt_sdp_file(void *optctx, const char *opt, const char *arg)
#if CONFIG_VAAPI #if CONFIG_VAAPI
int opt_vaapi_device(void *optctx, const char *opt, const char *arg) int opt_vaapi_device(void *optctx, const char *opt, const char *arg)
{ {
HWDevice *dev;
const char *prefix = "vaapi:"; const char *prefix = "vaapi:";
char *tmp; char *tmp;
int err; int err;
tmp = av_asprintf("%s%s", prefix, arg); tmp = av_asprintf("%s%s", prefix, arg);
if (!tmp) if (!tmp)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
err = hw_device_init_from_string(tmp, &dev); err = hw_device_init_from_string(tmp, NULL);
av_free(tmp); av_free(tmp);
if (err < 0)
return err; return err;
hw_device_ctx = av_buffer_ref(dev->device_ref);
if (!hw_device_ctx)
return AVERROR(ENOMEM);
return 0;
} }
#endif #endif
@ -812,15 +884,6 @@ void add_input_streams(OptionsContext *o, AVFormatContext *ic)
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
if(!ist->dec) if(!ist->dec)
ist->dec = avcodec_find_decoder(par->codec_id); ist->dec = avcodec_find_decoder(par->codec_id);
#if FF_API_LOWRES
if (st->codec->lowres) {
ist->dec_ctx->lowres = st->codec->lowres;
ist->dec_ctx->width = st->codec->width;
ist->dec_ctx->height = st->codec->height;
ist->dec_ctx->coded_width = st->codec->coded_width;
ist->dec_ctx->coded_height = st->codec->coded_height;
}
#endif
// avformat_find_stream_info() doesn't set this for us anymore. // avformat_find_stream_info() doesn't set this for us anymore.
ist->dec_ctx->framerate = st->avg_frame_rate; ist->dec_ctx->framerate = st->avg_frame_rate;
@ -837,9 +900,28 @@ void add_input_streams(OptionsContext *o, AVFormatContext *ic)
MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st); MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st); MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
hwaccel_output_format, ic, st);
if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "cuvid")) {
av_log(NULL, AV_LOG_WARNING,
"WARNING: defaulting hwaccel_output_format to cuda for compatibility "
"with old commandlines. This behaviour is DEPRECATED and will be removed "
"in the future. Please explicitly set \"-hwaccel_output_format cuda\".\n");
ist->hwaccel_output_format = AV_PIX_FMT_CUDA;
} else if (hwaccel_output_format) {
ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
"format: %s", hwaccel_output_format);
}
} else {
ist->hwaccel_output_format = AV_PIX_FMT_NONE;
}
if (hwaccel) { if (hwaccel) {
// The NVDEC hwaccels use a CUDA device, so remap the name here. // The NVDEC hwaccels use a CUDA device, so remap the name here.
if (!strcmp(hwaccel, "nvdec")) if (!strcmp(hwaccel, "nvdec") || !strcmp(hwaccel, "cuvid"))
hwaccel = "cuda"; hwaccel = "cuda";
if (!strcmp(hwaccel, "none")) if (!strcmp(hwaccel, "none"))
@ -873,8 +955,6 @@ void add_input_streams(OptionsContext *o, AVFormatContext *ic)
AV_HWDEVICE_TYPE_NONE) AV_HWDEVICE_TYPE_NONE)
av_log(NULL, AV_LOG_FATAL, "%s ", av_log(NULL, AV_LOG_FATAL, "%s ",
av_hwdevice_get_type_name(type)); av_hwdevice_get_type_name(type));
for (i = 0; hwaccels[i].name; i++)
av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
av_log(NULL, AV_LOG_FATAL, "\n"); av_log(NULL, AV_LOG_FATAL, "\n");
exit_program(1); exit_program(1);
} }
@ -888,18 +968,6 @@ void add_input_streams(OptionsContext *o, AVFormatContext *ic)
exit_program(1); exit_program(1);
} }
MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
hwaccel_output_format, ic, st);
if (hwaccel_output_format) {
ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
"format: %s", hwaccel_output_format);
}
} else {
ist->hwaccel_output_format = AV_PIX_FMT_NONE;
}
ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE; ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
break; break;
@ -1229,7 +1297,7 @@ int open_input_file(OptionsContext *o, const char *filename)
f->duration = 0; f->duration = 0;
f->time_base = (AVRational){ 1, 1 }; f->time_base = (AVRational){ 1, 1 };
#if HAVE_THREADS #if HAVE_THREADS
f->thread_queue_size = o->thread_queue_size > 0 ? o->thread_queue_size : 8; f->thread_queue_size = o->thread_queue_size;
#endif #endif
/* check if all codec options have been used */ /* check if all codec options have been used */
@ -1422,6 +1490,8 @@ OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVM
ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc); ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
ost->autoscale = 1;
MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st);
if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) { if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
do { do {
buf = get_line(s); buf = get_line(s);
@ -1489,54 +1559,12 @@ OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVM
MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st); MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st);
MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st); MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st);
while (bsfs && *bsfs) { if (bsfs && *bsfs) {
const AVBitStreamFilter *filter; ret = av_bsf_list_parse_str(bsfs, &ost->bsf_ctx);
char *bsf, *bsf_options_str, *bsf_name;
bsf = av_get_token(&bsfs, ",");
if (!bsf)
exit_program(1);
bsf_name = av_strtok(bsf, "=", &bsf_options_str);
if (!bsf_name)
exit_program(1);
filter = av_bsf_get_by_name(bsf_name);
if (!filter) {
av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf_name);
exit_program(1);
}
ost->bsf_ctx = av_realloc_array(ost->bsf_ctx,
ost->nb_bitstream_filters + 1,
sizeof(*ost->bsf_ctx));
if (!ost->bsf_ctx)
exit_program(1);
ret = av_bsf_alloc(filter, &ost->bsf_ctx[ost->nb_bitstream_filters]);
if (ret < 0) { if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n"); av_log(NULL, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret));
exit_program(1); exit_program(1);
} }
ost->nb_bitstream_filters++;
if (bsf_options_str && filter->priv_class) {
const AVOption *opt = av_opt_next(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, NULL);
const char * shorthand[2] = {NULL};
if (opt)
shorthand[0] = opt->name;
ret = av_opt_set_from_string(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, bsf_options_str, shorthand, "=", ":");
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error parsing options for bitstream filter %s\n", bsf_name);
exit_program(1);
}
}
av_freep(&bsf);
if (*bsfs)
bsfs++;
} }
MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st); MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
@ -1561,6 +1589,11 @@ OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVM
MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st); MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st);
ost->max_muxing_queue_size *= sizeof(AVPacket); ost->max_muxing_queue_size *= sizeof(AVPacket);
ost->muxing_queue_data_size = 0;
ost->muxing_queue_data_threshold = 50*1024*1024;
MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, ost->muxing_queue_data_threshold, oc, st);
if (oc->oformat->flags & AVFMT_GLOBALHEADER) if (oc->oformat->flags & AVFMT_GLOBALHEADER)
ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
@ -1699,8 +1732,6 @@ OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int sourc
MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st); MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st); MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
if (o->nb_filters > 1)
av_log(NULL, AV_LOG_ERROR, "Only '-vf %s' read, ignoring remaining -vf options: Use ',' to separate filters\n", ost->filters);
if (!ost->stream_copy) { if (!ost->stream_copy) {
const char *p = NULL; const char *p = NULL;
@ -1882,8 +1913,6 @@ OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int sourc
MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st); MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st); MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
if (o->nb_filters > 1)
av_log(NULL, AV_LOG_ERROR, "Only '-af %s' read, ignoring remaining -af options: Use ',' to separate filters\n", ost->filters);
if (!ost->stream_copy) { if (!ost->stream_copy) {
char *sample_fmt = NULL; char *sample_fmt = NULL;
@ -2211,22 +2240,23 @@ int open_output_file(OptionsContext *o, const char *filename)
/* video: highest resolution */ /* video: highest resolution */
if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) { if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {
int area = 0, idx = -1; int best_score = 0, idx = -1;
int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0); int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
for (i = 0; i < nb_input_streams; i++) { for (i = 0; i < nb_input_streams; i++) {
int new_area; int score;
ist = input_streams[i]; ist = input_streams[i];
new_area = ist->st->codecpar->width * ist->st->codecpar->height + 100000000*!!ist->st->codec_info_nb_frames score = ist->st->codecpar->width * ist->st->codecpar->height
+ 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
+ 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT); + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
if (ist->user_set_discard == AVDISCARD_ALL) if (ist->user_set_discard == AVDISCARD_ALL)
continue; continue;
if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
new_area = 1; score = 1;
if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
new_area > area) { score > best_score) {
if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
continue; continue;
area = new_area; best_score = score;
idx = i; idx = i;
} }
} }
@ -2390,12 +2420,14 @@ loop_end:
o->attachments[i]); o->attachments[i]);
exit_program(1); exit_program(1);
} }
if (!(attachment = av_malloc(len))) { if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n", !(attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) {
av_log(NULL, AV_LOG_FATAL, "Attachment %s too large.\n",
o->attachments[i]); o->attachments[i]);
exit_program(1); exit_program(1);
} }
avio_read(pb, attachment, len); avio_read(pb, attachment, len);
memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
ost = new_attachment_stream(o, oc, -1); ost = new_attachment_stream(o, oc, -1);
ost->stream_copy = 0; ost->stream_copy = 0;
@ -3214,7 +3246,7 @@ void show_help_default_ffmpeg(const char *opt, const char *arg)
" -h -- print basic options\n" " -h -- print basic options\n"
" -h long -- print more options\n" " -h long -- print more options\n"
" -h full -- print all options (including all format and codec specific options, very long)\n" " -h full -- print all options (including all format and codec specific options, very long)\n"
" -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf\n" " -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf/protocol\n"
" See man %s for detailed description of the options.\n" " See man %s for detailed description of the options.\n"
"\n", program_name); "\n", program_name);
@ -3222,7 +3254,7 @@ void show_help_default_ffmpeg(const char *opt, const char *arg)
OPT_EXIT, 0, 0); OPT_EXIT, 0, 0);
show_help_options(options, "Global options (affect whole program " show_help_options(options, "Global options (affect whole program "
"instead of just one file:", "instead of just one file):",
0, per_file | OPT_EXIT | OPT_EXPERT, 0); 0, per_file | OPT_EXIT | OPT_EXPERT, 0);
if (show_advanced) if (show_advanced)
show_help_options(options, "Advanced global options:", OPT_EXPERT, show_help_options(options, "Advanced global options:", OPT_EXPERT,
@ -3298,6 +3330,7 @@ int open_files(OptionGroupList *l, const char *inout,
if (ret < 0) { if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file " av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
"%s.\n", inout, g->arg); "%s.\n", inout, g->arg);
uninit_options(&o);
return ret; return ret;
} }

View File

@ -42,7 +42,9 @@
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
#include "libavutil/display.h" #include "libavutil/display.h"
#include "libavutil/hash.h" #include "libavutil/hash.h"
#include "libavutil/hdr_dynamic_metadata.h"
#include "libavutil/mastering_display_metadata.h" #include "libavutil/mastering_display_metadata.h"
#include "libavutil/dovi_meta.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
#include "libavutil/spherical.h" #include "libavutil/spherical.h"
@ -257,6 +259,7 @@ __thread OptionDef *ffprobe_options = NULL;
/* FFprobe context */ /* FFprobe context */
__thread const char *input_filename; __thread const char *input_filename;
__thread const char *print_input_filename;
__thread AVInputFormat *iformat = NULL; __thread AVInputFormat *iformat = NULL;
__thread struct AVHashContext *hash; __thread struct AVHashContext *hash;
@ -1089,12 +1092,12 @@ typedef struct CompactContext {
#define OFFSET(x) offsetof(CompactContext, x) #define OFFSET(x) offsetof(CompactContext, x)
static const AVOption compact_options[]= { static const AVOption compact_options[]= {
{"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, CHAR_MIN, CHAR_MAX }, {"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, 0, 0 },
{"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, CHAR_MIN, CHAR_MAX }, {"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, 0, 0 },
{"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 }, {"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
{"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 }, {"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
{"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, CHAR_MIN, CHAR_MAX }, {"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, 0, 0 },
{"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, CHAR_MIN, CHAR_MAX }, {"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, 0, 0 },
{"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{NULL}, {NULL},
@ -1205,12 +1208,12 @@ static const Writer compact_writer = {
#define OFFSET(x) offsetof(CompactContext, x) #define OFFSET(x) offsetof(CompactContext, x)
static const AVOption csv_options[] = { static const AVOption csv_options[] = {
{"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, CHAR_MIN, CHAR_MAX }, {"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, 0, 0 },
{"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, CHAR_MIN, CHAR_MAX }, {"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, 0, 0 },
{"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, CHAR_MIN, CHAR_MAX }, {"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, 0, 0 },
{"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, CHAR_MIN, CHAR_MAX }, {"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, 0, 0 },
{"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{NULL}, {NULL},
@ -1243,8 +1246,8 @@ typedef struct FlatContext {
#define OFFSET(x) offsetof(FlatContext, x) #define OFFSET(x) offsetof(FlatContext, x)
static const AVOption flat_options[]= { static const AVOption flat_options[]= {
{"sep_char", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, CHAR_MIN, CHAR_MAX }, {"sep_char", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, 0, 0 },
{"s", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, CHAR_MIN, CHAR_MAX }, {"s", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, 0, 0 },
{"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{"h", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 }, {"h", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
{NULL}, {NULL},
@ -1859,6 +1862,105 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id
return ret; return ret;
} }
static void print_dynamic_hdr10_plus(WriterContext *w, const AVDynamicHDRPlus *metadata)
{
if (!metadata)
return;
print_int("application version", metadata->application_version);
print_int("num_windows", metadata->num_windows);
for (int n = 1; n < metadata->num_windows; n++) {
const AVHDRPlusColorTransformParams *params = &metadata->params[n];
print_q("window_upper_left_corner_x",
params->window_upper_left_corner_x,'/');
print_q("window_upper_left_corner_y",
params->window_upper_left_corner_y,'/');
print_q("window_lower_right_corner_x",
params->window_lower_right_corner_x,'/');
print_q("window_lower_right_corner_y",
params->window_lower_right_corner_y,'/');
print_q("window_upper_left_corner_x",
params->window_upper_left_corner_x,'/');
print_q("window_upper_left_corner_y",
params->window_upper_left_corner_y,'/');
print_int("center_of_ellipse_x",
params->center_of_ellipse_x ) ;
print_int("center_of_ellipse_y",
params->center_of_ellipse_y );
print_int("rotation_angle",
params->rotation_angle);
print_int("semimajor_axis_internal_ellipse",
params->semimajor_axis_internal_ellipse);
print_int("semimajor_axis_external_ellipse",
params->semimajor_axis_external_ellipse);
print_int("semiminor_axis_external_ellipse",
params->semiminor_axis_external_ellipse);
print_int("overlap_process_option",
params->overlap_process_option);
}
print_q("targeted_system_display_maximum_luminance",
metadata->targeted_system_display_maximum_luminance,'/');
if (metadata->targeted_system_display_actual_peak_luminance_flag) {
print_int("num_rows_targeted_system_display_actual_peak_luminance",
metadata->num_rows_targeted_system_display_actual_peak_luminance);
print_int("num_cols_targeted_system_display_actual_peak_luminance",
metadata->num_cols_targeted_system_display_actual_peak_luminance);
for (int i = 0; i < metadata->num_rows_targeted_system_display_actual_peak_luminance; i++) {
for (int j = 0; j < metadata->num_cols_targeted_system_display_actual_peak_luminance; j++) {
print_q("targeted_system_display_actual_peak_luminance",
metadata->targeted_system_display_actual_peak_luminance[i][j],'/');
}
}
}
for (int n = 0; n < metadata->num_windows; n++) {
const AVHDRPlusColorTransformParams *params = &metadata->params[n];
for (int i = 0; i < 3; i++) {
print_q("maxscl",params->maxscl[i],'/');
}
print_q("average_maxrgb",
params->average_maxrgb,'/');
print_int("num_distribution_maxrgb_percentiles",
params->num_distribution_maxrgb_percentiles);
for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
print_int("distribution_maxrgb_percentage",
params->distribution_maxrgb[i].percentage);
print_q("distribution_maxrgb_percentile",
params->distribution_maxrgb[i].percentile,'/');
}
print_q("fraction_bright_pixels",
params->fraction_bright_pixels,'/');
}
if (metadata->mastering_display_actual_peak_luminance_flag) {
print_int("num_rows_mastering_display_actual_peak_luminance",
metadata->num_rows_mastering_display_actual_peak_luminance);
print_int("num_cols_mastering_display_actual_peak_luminance",
metadata->num_cols_mastering_display_actual_peak_luminance);
for (int i = 0; i < metadata->num_rows_mastering_display_actual_peak_luminance; i++) {
for (int j = 0; j < metadata->num_cols_mastering_display_actual_peak_luminance; j++) {
print_q("mastering_display_actual_peak_luminance",
metadata->mastering_display_actual_peak_luminance[i][j],'/');
}
}
}
for (int n = 0; n < metadata->num_windows; n++) {
const AVHDRPlusColorTransformParams *params = &metadata->params[n];
if (params->tone_mapping_flag) {
print_q("knee_point_x", params->knee_point_x,'/');
print_q("knee_point_y", params->knee_point_y,'/');
print_int("num_bezier_curve_anchors",
params->num_bezier_curve_anchors );
for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
print_q("bezier_curve_anchors",
params->bezier_curve_anchors[i],'/');
}
}
if (params->color_saturation_mapping_flag) {
print_q("color_saturation_weight",
params->color_saturation_weight,'/');
}
}
}
static void print_pkt_side_data(WriterContext *w, static void print_pkt_side_data(WriterContext *w,
AVCodecParameters *par, AVCodecParameters *par,
const AVPacketSideData *side_data, const AVPacketSideData *side_data,
@ -1928,6 +2030,16 @@ static void print_pkt_side_data(WriterContext *w,
AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data;
print_int("max_content", metadata->MaxCLL); print_int("max_content", metadata->MaxCLL);
print_int("max_average", metadata->MaxFALL); print_int("max_average", metadata->MaxFALL);
} else if (sd->type == AV_PKT_DATA_DOVI_CONF) {
AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data;
print_int("dv_version_major", dovi->dv_version_major);
print_int("dv_version_minor", dovi->dv_version_minor);
print_int("dv_profile", dovi->dv_profile);
print_int("dv_level", dovi->dv_level);
print_int("rpu_present_flag", dovi->rpu_present_flag);
print_int("el_present_flag", dovi->el_present_flag);
print_int("bl_present_flag", dovi->bl_present_flag);
print_int("dv_bl_signal_compatibility_id", dovi->dv_bl_signal_compatibility_id);
} }
writer_print_section_footer(w); writer_print_section_footer(w);
} }
@ -2214,7 +2326,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST); writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST);
for (int j = 1; j <= m ; j++) { for (int j = 1; j <= m ; j++) {
char tcbuf[AV_TIMECODE_STR_SIZE]; char tcbuf[AV_TIMECODE_STR_SIZE];
av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); av_timecode_make_smpte_tc_string2(tcbuf, stream->avg_frame_rate, tc[j], 0, 0);
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE); writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_TIMECODE);
print_str("value", tcbuf); print_str("value", tcbuf);
writer_print_section_footer(w); writer_print_section_footer(w);
@ -2239,6 +2351,9 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
print_q("min_luminance", metadata->min_luminance, '/'); print_q("min_luminance", metadata->min_luminance, '/');
print_q("max_luminance", metadata->max_luminance, '/'); print_q("max_luminance", metadata->max_luminance, '/');
} }
} else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_PLUS) {
AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data;
print_dynamic_hdr10_plus(w, metadata);
} else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) { } else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) {
AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data;
print_int("max_content", metadata->MaxCLL); print_int("max_content", metadata->MaxCLL);
@ -2539,6 +2654,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
if (dec_ctx) { if (dec_ctx) {
print_int("coded_width", dec_ctx->coded_width); print_int("coded_width", dec_ctx->coded_width);
print_int("coded_height", dec_ctx->coded_height); print_int("coded_height", dec_ctx->coded_height);
print_int("closed_captions", !!(dec_ctx->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS));
} }
#endif #endif
print_int("has_b_frames", par->video_delay); print_int("has_b_frames", par->video_delay);
@ -2840,11 +2956,11 @@ static void show_error(WriterContext *w, int err)
writer_print_section_footer(w); writer_print_section_footer(w);
} }
static int open_input_file(InputFile *ifile, const char *filename) static int open_input_file(InputFile *ifile, const char *filename, const char *print_filename)
{ {
int err, i; int err, i;
AVFormatContext *fmt_ctx = NULL; AVFormatContext *fmt_ctx = NULL;
AVDictionaryEntry *t; AVDictionaryEntry *t = NULL;
int scan_all_pmts_set = 0; int scan_all_pmts_set = 0;
fmt_ctx = avformat_alloc_context(); fmt_ctx = avformat_alloc_context();
@ -2862,13 +2978,15 @@ static int open_input_file(InputFile *ifile, const char *filename)
print_error(filename, err); print_error(filename, err);
return err; return err;
} }
if (print_filename) {
av_freep(&fmt_ctx->url);
fmt_ctx->url = av_strdup(print_filename);
}
ifile->fmt_ctx = fmt_ctx; ifile->fmt_ctx = fmt_ctx;
if (scan_all_pmts_set) if (scan_all_pmts_set)
av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE); av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { while ((t = av_dict_get(format_opts, "", t, AV_DICT_IGNORE_SUFFIX)))
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); av_log(NULL, AV_LOG_WARNING, "Option %s skipped - not known to demuxer.\n", t->key);
return AVERROR_OPTION_NOT_FOUND;
}
if (find_stream_info) { if (find_stream_info) {
AVDictionary **opts = setup_find_stream_info_opts(fmt_ctx, codec_opts); AVDictionary **opts = setup_find_stream_info_opts(fmt_ctx, codec_opts);
@ -2938,6 +3056,7 @@ static int open_input_file(InputFile *ifile, const char *filename)
ist->dec_ctx->pkt_timebase = stream->time_base; ist->dec_ctx->pkt_timebase = stream->time_base;
ist->dec_ctx->framerate = stream->avg_frame_rate; ist->dec_ctx->framerate = stream->avg_frame_rate;
#if FF_API_LAVF_AVCTX #if FF_API_LAVF_AVCTX
ist->dec_ctx->properties = stream->codec->properties;
ist->dec_ctx->coded_width = stream->codec->coded_width; ist->dec_ctx->coded_width = stream->codec->coded_width;
ist->dec_ctx->coded_height = stream->codec->coded_height; ist->dec_ctx->coded_height = stream->codec->coded_height;
#endif #endif
@ -2975,7 +3094,8 @@ static void close_input_file(InputFile *ifile)
avformat_close_input(&ifile->fmt_ctx); avformat_close_input(&ifile->fmt_ctx);
} }
static int probe_file(WriterContext *wctx, const char *filename) static int probe_file(WriterContext *wctx, const char *filename,
const char *print_filename)
{ {
InputFile ifile = { 0 }; InputFile ifile = { 0 };
int ret, i; int ret, i;
@ -2984,7 +3104,7 @@ static int probe_file(WriterContext *wctx, const char *filename)
do_read_frames = do_show_frames || do_count_frames; do_read_frames = do_show_frames || do_count_frames;
do_read_packets = do_show_packets || do_count_packets; do_read_packets = do_show_packets || do_count_packets;
ret = open_input_file(&ifile, filename); ret = open_input_file(&ifile, filename, print_filename);
if (ret < 0) if (ret < 0)
goto end; goto end;
@ -3289,6 +3409,12 @@ static int opt_input_file_i(void *optctx, const char *opt, const char *arg)
return 0; return 0;
} }
static int opt_print_filename(void *optctx, const char *opt, const char *arg)
{
print_input_filename = arg;
return 0;
}
void show_help_default_ffprobe(const char *opt, const char *arg) void show_help_default_ffprobe(const char *opt, const char *arg)
{ {
show_usage(); show_usage();
@ -3563,10 +3689,12 @@ void ffprobe_var_cleanup() {
read_intervals = NULL; read_intervals = NULL;
read_intervals_nb = 0; read_intervals_nb = 0;
find_stream_info = 1;
ffprobe_options = NULL; ffprobe_options = NULL;
input_filename = NULL; input_filename = NULL;
print_input_filename = NULL;
iformat = NULL; iformat = NULL;
hash = NULL; hash = NULL;
@ -3633,13 +3761,13 @@ int ffprobe_execute(int argc, char **argv)
"use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" }, "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
{ "pretty", 0, {.func_arg = opt_pretty}, { "pretty", 0, {.func_arg = opt_pretty},
"prettify the format of displayed values, make it more human readable" }, "prettify the format of displayed values, make it more human readable" },
{ "print_format", OPT_STRING | HAS_ARG, {(void*)&print_format}, { "print_format", OPT_STRING | HAS_ARG, { &print_format },
"set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" }, "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" },
{ "of", OPT_STRING | HAS_ARG, {(void*)&print_format}, "alias for -print_format", "format" }, { "of", OPT_STRING | HAS_ARG, { &print_format }, "alias for -print_format", "format" },
{ "select_streams", OPT_STRING | HAS_ARG, {(void*)&stream_specifier}, "select the specified streams", "stream_specifier" }, { "select_streams", OPT_STRING | HAS_ARG, { &stream_specifier }, "select the specified streams", "stream_specifier" },
{ "sections", OPT_EXIT, {.func_arg = opt_sections}, "print sections structure and section information, and exit" }, { "sections", OPT_EXIT, {.func_arg = opt_sections}, "print sections structure and section information, and exit" },
{ "show_data", OPT_BOOL, {(void*)&do_show_data}, "show packets data" }, { "show_data", OPT_BOOL, { &do_show_data }, "show packets data" },
{ "show_data_hash", OPT_STRING | HAS_ARG, {(void*)&show_data_hash}, "show packets data hash" }, { "show_data_hash", OPT_STRING | HAS_ARG, { &show_data_hash }, "show packets data hash" },
{ "show_error", 0, { .func_arg = &opt_show_error }, "show probing error" }, { "show_error", 0, { .func_arg = &opt_show_error }, "show probing error" },
{ "show_format", 0, { .func_arg = &opt_show_format }, "show format/container info" }, { "show_format", 0, { .func_arg = &opt_show_format }, "show format/container info" },
{ "show_frames", 0, { .func_arg = &opt_show_frames }, "show frames info" }, { "show_frames", 0, { .func_arg = &opt_show_frames }, "show frames info" },
@ -3648,24 +3776,25 @@ int ffprobe_execute(int argc, char **argv)
{ "show_entries", HAS_ARG, {.func_arg = opt_show_entries}, { "show_entries", HAS_ARG, {.func_arg = opt_show_entries},
"show a set of specified entries", "entry_list" }, "show a set of specified entries", "entry_list" },
#if HAVE_THREADS #if HAVE_THREADS
{ "show_log", OPT_INT|HAS_ARG, {(void*)&do_show_log}, "show log" }, { "show_log", OPT_INT|HAS_ARG, { &do_show_log }, "show log" },
#endif #endif
{ "show_packets", 0, { .func_arg = &opt_show_packets }, "show packets info" }, { "show_packets", 0, { .func_arg = &opt_show_packets }, "show packets info" },
{ "show_programs", 0, { .func_arg = &opt_show_programs }, "show programs info" }, { "show_programs", 0, { .func_arg = &opt_show_programs }, "show programs info" },
{ "show_streams", 0, { .func_arg = &opt_show_streams }, "show streams info" }, { "show_streams", 0, { .func_arg = &opt_show_streams }, "show streams info" },
{ "show_chapters", 0, { .func_arg = &opt_show_chapters }, "show chapters info" }, { "show_chapters", 0, { .func_arg = &opt_show_chapters }, "show chapters info" },
{ "count_frames", OPT_BOOL, {(void*)&do_count_frames}, "count the number of frames per stream" }, { "count_frames", OPT_BOOL, { &do_count_frames }, "count the number of frames per stream" },
{ "count_packets", OPT_BOOL, {(void*)&do_count_packets}, "count the number of packets per stream" }, { "count_packets", OPT_BOOL, { &do_count_packets }, "count the number of packets per stream" },
{ "show_program_version", 0, { .func_arg = &opt_show_program_version }, "show ffprobe version" }, { "show_program_version", 0, { .func_arg = &opt_show_program_version }, "show ffprobe version" },
{ "show_library_versions", 0, { .func_arg = &opt_show_library_versions }, "show library versions" }, { "show_library_versions", 0, { .func_arg = &opt_show_library_versions }, "show library versions" },
{ "show_versions", 0, { .func_arg = &opt_show_versions }, "show program and library versions" }, { "show_versions", 0, { .func_arg = &opt_show_versions }, "show program and library versions" },
{ "show_pixel_formats", 0, { .func_arg = &opt_show_pixel_formats }, "show pixel format descriptions" }, { "show_pixel_formats", 0, { .func_arg = &opt_show_pixel_formats }, "show pixel format descriptions" },
{ "show_private_data", OPT_BOOL, {(void*)&show_private_data}, "show private data" }, { "show_private_data", OPT_BOOL, { &show_private_data }, "show private data" },
{ "private", OPT_BOOL, {(void*)&show_private_data}, "same as show_private_data" }, { "private", OPT_BOOL, { &show_private_data }, "same as show_private_data" },
{ "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" }, { "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" },
{ "read_intervals", HAS_ARG, {.func_arg = opt_read_intervals}, "set read intervals", "read_intervals" }, { "read_intervals", HAS_ARG, {.func_arg = opt_read_intervals}, "set read intervals", "read_intervals" },
{ "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" }, { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" },
{ "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"}, { "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"},
{ "print_filename", HAS_ARG, {.func_arg = opt_print_filename}, "override the printed input filename", "print_file"},
{ "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info }, { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
"read and decode the streams to fill missing information with heuristics" }, "read and decode the streams to fill missing information with heuristics" },
{ NULL, }, { NULL, },
@ -3800,7 +3929,7 @@ int ffprobe_execute(int argc, char **argv)
av_log(NULL, AV_LOG_ERROR, "Use -h to get full help or, even better, run 'man %s'.\n", program_name); av_log(NULL, AV_LOG_ERROR, "Use -h to get full help or, even better, run 'man %s'.\n", program_name);
ret = AVERROR(EINVAL); ret = AVERROR(EINVAL);
} else if (input_filename) { } else if (input_filename) {
ret = probe_file(wctx, input_filename); ret = probe_file(wctx, input_filename, print_input_filename);
if (ret < 0 && do_show_error) if (ret < 0 && do_show_error)
show_error(wctx, ret); show_error(wctx, ret);
} }

View File

@ -354,6 +354,10 @@ ulimit -n 2048 1>>"${BASEDIR}"/build.log 2>&1
# 1. Use thread local log levels # 1. Use thread local log levels
${SED_INLINE} 's/static int av_log_level/__thread int av_log_level/g' "${BASEDIR}"/src/"${LIB_NAME}"/libavutil/log.c 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 ${SED_INLINE} 's/static int av_log_level/__thread int av_log_level/g' "${BASEDIR}"/src/"${LIB_NAME}"/libavutil/log.c 1>>"${BASEDIR}"/build.log 2>&1 || exit 1
# 2. Set friendly ffmpeg version
FFMPEG_VERSION="v$(get_user_friendly_ffmpeg_version)"
${SED_INLINE} "s/\$version/$FFMPEG_VERSION/g" "${BASEDIR}"/src/"${LIB_NAME}"/ffbuild/version.sh 1>>"${BASEDIR}"/build.log 2>&1 || exit 1
################################################################### ###################################################################
./configure \ ./configure \

View File

@ -20,7 +20,7 @@ fi
--host="${HOST}" || return 1 --host="${HOST}" || return 1
# WORKAROUND TO DISABLE BUILDING OF doc FOLDER (doc depends on c2man which is not available on all platforms) # WORKAROUND TO DISABLE BUILDING OF doc FOLDER (doc depends on c2man which is not available on all platforms)
$SED_INLINE 's/ doc / /g' "${BASEDIR}"/src/"${LIB_NAME}"/Makefile || return 1 ${SED_INLINE} 's/ doc / /g' "${BASEDIR}"/src/"${LIB_NAME}"/Makefile || return 1
make -j$(get_cpu_count) || return 1 make -j$(get_cpu_count) || return 1

View File

@ -14,7 +14,7 @@ make distclean 2>/dev/null 1>/dev/null
if [[ ! -f "${BASEDIR}"/src/"${LIB_NAME}"/configure ]] || [[ ${RECONF_libtheora} -eq 1 ]]; then if [[ ! -f "${BASEDIR}"/src/"${LIB_NAME}"/configure ]] || [[ ${RECONF_libtheora} -eq 1 ]]; then
# WORKAROUND NOT TO RUN CONFIGURE AT THE END OF autogen.sh # WORKAROUND NOT TO RUN CONFIGURE AT THE END OF autogen.sh
$SED_INLINE 's/$srcdir\/configure/#$srcdir\/configure/g' "${BASEDIR}"/src/"${LIB_NAME}"/autogen.sh || return 1 ${SED_INLINE} 's/$srcdir\/configure/#$srcdir\/configure/g' "${BASEDIR}"/src/"${LIB_NAME}"/autogen.sh || return 1
./autogen.sh || return 1 ./autogen.sh || return 1
fi fi

View File

@ -22,7 +22,7 @@ fi
--host="${HOST}" || return 1 --host="${HOST}" || return 1
# WORKAROUND TO DISABLE BUILDING OF DOCBOOK - BUILD SCRIPTS DO NOT GENERATE A TARGET FOR IT # WORKAROUND TO DISABLE BUILDING OF DOCBOOK - BUILD SCRIPTS DO NOT GENERATE A TARGET FOR IT
$SED_INLINE 's/dist_man_MANS = .*/dist_man_MANS =/g' "${BASEDIR}"/src/"${LIB_NAME}"/doc/Makefile || return 1 ${SED_INLINE} 's/dist_man_MANS = .*/dist_man_MANS =/g' "${BASEDIR}"/src/"${LIB_NAME}"/doc/Makefile || return 1
make -j$(get_cpu_count) || return 1 make -j$(get_cpu_count) || return 1

View File

@ -444,6 +444,10 @@ fi
# 3. Use thread local log levels # 3. Use thread local log levels
${SED_INLINE} 's/static int av_log_level/__thread int av_log_level/g' "${BASEDIR}"/src/${LIB_NAME}/libavutil/log.c 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 ${SED_INLINE} 's/static int av_log_level/__thread int av_log_level/g' "${BASEDIR}"/src/${LIB_NAME}/libavutil/log.c 1>>"${BASEDIR}"/build.log 2>&1 || exit 1
# 4. Set friendly ffmpeg version
FFMPEG_VERSION="v$(get_user_friendly_ffmpeg_version)"
${SED_INLINE} "s/\$version/$FFMPEG_VERSION/g" "${BASEDIR}"/src/"${LIB_NAME}"/ffbuild/version.sh 1>>"${BASEDIR}"/build.log 2>&1 || exit 1
################################################################### ###################################################################
./configure \ ./configure \

View File

@ -20,7 +20,7 @@ fi
--host="${HOST}" || return 1 --host="${HOST}" || return 1
# WORKAROUND TO DISABLE BUILDING OF doc FOLDER (doc depends on c2man which is not available on all platforms) # WORKAROUND TO DISABLE BUILDING OF doc FOLDER (doc depends on c2man which is not available on all platforms)
$SED_INLINE 's/ doc / /g' "${BASEDIR}"/src/"${LIB_NAME}"/Makefile || return 1 ${SED_INLINE} 's/ doc / /g' "${BASEDIR}"/src/"${LIB_NAME}"/Makefile || return 1
make -j$(get_cpu_count) || return 1 make -j$(get_cpu_count) || return 1

View File

@ -7,7 +7,7 @@ make distclean 2>/dev/null 1>/dev/null
if [[ ! -f "${BASEDIR}"/src/"${LIB_NAME}"/configure ]] || [[ ${RECONF_libtheora} -eq 1 ]]; then if [[ ! -f "${BASEDIR}"/src/"${LIB_NAME}"/configure ]] || [[ ${RECONF_libtheora} -eq 1 ]]; then
# WORKAROUND NOT TO RUN CONFIGURE AT THE END OF autogen.sh # WORKAROUND NOT TO RUN CONFIGURE AT THE END OF autogen.sh
$SED_INLINE 's/$srcdir\/configure/#$srcdir\/configure/g' "${BASEDIR}"/src/"${LIB_NAME}"/autogen.sh || return 1 ${SED_INLINE} 's/$srcdir\/configure/#$srcdir\/configure/g' "${BASEDIR}"/src/"${LIB_NAME}"/autogen.sh || return 1
./autogen.sh || return 1 ./autogen.sh || return 1
fi fi

View File

@ -22,7 +22,7 @@ fi
--host="${HOST}" || return 1 --host="${HOST}" || return 1
# WORKAROUND TO DISABLE BUILDING OF DOCBOOK - BUILD SCRIPTS DO NOT GENERATE A TARGET FOR IT # WORKAROUND TO DISABLE BUILDING OF DOCBOOK - BUILD SCRIPTS DO NOT GENERATE A TARGET FOR IT
$SED_INLINE 's/dist_man_MANS = .*/dist_man_MANS =/g' "${BASEDIR}"/src/"${LIB_NAME}"/doc/Makefile || return 1 ${SED_INLINE} 's/dist_man_MANS = .*/dist_man_MANS =/g' "${BASEDIR}"/src/"${LIB_NAME}"/doc/Makefile || return 1
make -j$(get_cpu_count) || return 1 make -j$(get_cpu_count) || return 1

0
scripts/function-apple.sh Normal file → Executable file
View File

View File

@ -246,7 +246,7 @@ from_library_name() {
is_library_supported_on_platform() { is_library_supported_on_platform() {
local library_index=$(from_library_name "$1") local library_index=$(from_library_name "$1")
case ${library_index} in case ${library_index} in
0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20) 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 19 | 20)
echo "0" echo "0"
;; ;;
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40) 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40)
@ -1616,6 +1616,11 @@ is_gnu_config_files_up_to_date() {
echo $(grep aarch64-apple-darwin config.guess | wc -l 2>>"${BASEDIR}"/build.log) echo $(grep aarch64-apple-darwin config.guess | wc -l 2>>"${BASEDIR}"/build.log)
} }
get_user_friendly_ffmpeg_version() {
local USER_FRIENDLY_NAME=$(get_library_source "ffmpeg" 4)
echo ${USER_FRIENDLY_NAME:1}
}
get_cpu_count() { get_cpu_count() {
if [ "$(uname)" == "Darwin" ]; then if [ "$(uname)" == "Darwin" ]; then
echo $(sysctl -n hw.logicalcpu) echo $(sysctl -n hw.logicalcpu)

View File

@ -28,8 +28,9 @@ get_library_source() {
;; ;;
ffmpeg) ffmpeg)
SOURCE_REPO_URL="https://github.com/tanersener/FFmpeg" SOURCE_REPO_URL="https://github.com/tanersener/FFmpeg"
SOURCE_ID="d222da435e63a2665b85c0305ad2cf8a07b1af6d" # COMMIT -> v4.4-dev-416 SOURCE_ID="9f38fac053010205806ece11e6aea9b7d3bde041"
SOURCE_TYPE="COMMIT" SOURCE_TYPE="COMMIT"
SOURCE_GIT_DESCRIBE="n4.4-dev-2765-g9f38fac053" # git describe --tags
;; ;;
fontconfig) fontconfig)
SOURCE_REPO_URL="https://github.com/tanersener/fontconfig" SOURCE_REPO_URL="https://github.com/tanersener/fontconfig"
@ -263,5 +264,8 @@ get_library_source() {
3) 3)
echo "${SOURCE_TYPE}" echo "${SOURCE_TYPE}"
;; ;;
4)
echo "${SOURCE_GIT_DESCRIBE}"
;;
esac esac
} }