diff options
author | Anton Khirnov <anton@khirnov.net> | 2021-11-23 10:18:01 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2021-12-04 14:07:36 +0100 |
commit | 425889396137451ae30288c84122e28532b71596 (patch) | |
tree | 81cafc380027735076a86d6fc34185d4a3f4a217 | |
parent | b9c928a486fda3c0d79b153591ac86beb1c53708 (diff) | |
download | ffmpeg-425889396137451ae30288c84122e28532b71596.tar.gz |
ffmpeg: make -bits_per_raw_sample a per-output-stream option
Also, document it and make it apply to audio in addition to video.
-rw-r--r-- | doc/ffmpeg.texi | 7 | ||||
-rw-r--r-- | fftools/ffmpeg.c | 11 | ||||
-rw-r--r-- | fftools/ffmpeg.h | 3 | ||||
-rw-r--r-- | fftools/ffmpeg_opt.c | 11 |
4 files changed, 24 insertions, 8 deletions
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 082eba5f14..20a547381c 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1960,6 +1960,13 @@ filter (scale, aresample) in the graph. On by default, to explicitly disable it you need to specify @code{-noauto_conversion_filters}. +@item -bits_per_raw_sample[:@var{stream_specifier}] @var{value} (@emph{output,per-stream}) +Declare the number of bits per raw sample in the given output stream to be +@var{value}. Note that this option sets the information provided to the +encoder/muxer, it does not change the stream to conform to this value. Setting +values that do not match the stream properties may result in encoding failures +or invalid output files. + @end table @section Preset files diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index cfb04d5eff..03aec1af11 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3329,13 +3329,16 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) switch (enc_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: enc_ctx->sample_fmt = av_buffersink_get_format(ost->filter->filter); - if (dec_ctx) - enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample, - av_get_bytes_per_sample(enc_ctx->sample_fmt) << 3); enc_ctx->sample_rate = av_buffersink_get_sample_rate(ost->filter->filter); enc_ctx->channel_layout = av_buffersink_get_channel_layout(ost->filter->filter); enc_ctx->channels = av_buffersink_get_channels(ost->filter->filter); + if (ost->bits_per_raw_sample) + enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; + else if (dec_ctx) + enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample, + av_get_bytes_per_sample(enc_ctx->sample_fmt) << 3); + init_encoder_time_base(ost, av_make_q(1, enc_ctx->sample_rate)); break; @@ -3378,7 +3381,7 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) enc_ctx->width != dec_ctx->width || enc_ctx->height != dec_ctx->height || enc_ctx->pix_fmt != dec_ctx->pix_fmt) { - enc_ctx->bits_per_raw_sample = frame_bits_per_raw_sample; + enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample; } // Field order: autodetection diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index a20ca964fb..c14eed5643 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -228,6 +228,8 @@ typedef struct OptionsContext { int nb_enc_time_bases; SpecifierOpt *autoscale; int nb_autoscale; + SpecifierOpt *bits_per_raw_sample; + int nb_bits_per_raw_sample; } OptionsContext; typedef struct InputFilter { @@ -483,6 +485,7 @@ typedef struct OutputStream { int top_field_first; int rotate_overridden; int autoscale; + int bits_per_raw_sample; double rotate_override_value; AVRational frame_aspect_ratio; diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index a27263b879..6c2eb53290 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -96,6 +96,7 @@ 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}; +static const char *const opt_name_bits_per_raw_sample[] = {"bits_per_raw_sample", NULL}; #define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\ {\ @@ -160,7 +161,6 @@ int abort_on_flags = 0; int print_stats = -1; int qp_hist = 0; int stdin_interaction = 1; -int frame_bits_per_raw_sample = 0; float max_error_rate = 2.0/3; char *filter_nbthreads; int filter_complex_nbthreads = 0; @@ -1604,6 +1604,9 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->muxing_queue_data_threshold = 50*1024*1024; MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, ost->muxing_queue_data_threshold, oc, st); + MATCH_PER_STREAM_OPT(bits_per_raw_sample, i, ost->bits_per_raw_sample, + oc, st); + if (oc->oformat->flags & AVFMT_GLOBALHEADER) ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; @@ -1769,7 +1772,6 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in exit_program(1); } - video_enc->bits_per_raw_sample = frame_bits_per_raw_sample; MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st); if (frame_pix_fmt && *frame_pix_fmt == '+') { ost->keep_pix_fmt = 1; @@ -3681,6 +3683,9 @@ const OptionDef options[] = { "set the maximum number of queued packets from the demuxer" }, { "find_stream_info", OPT_BOOL | OPT_PERFILE | OPT_INPUT | OPT_EXPERT, { &find_stream_info }, "read and decode the streams to fill missing information with heuristics" }, + { "bits_per_raw_sample", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT, + { .off = OFFSET(bits_per_raw_sample) }, + "set the number of bits per raw sample", "number" }, /* video options */ { "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames }, @@ -3700,8 +3705,6 @@ const OptionDef options[] = { { "pix_fmt", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_pix_fmts) }, "set pixel format", "format" }, - { "bits_per_raw_sample", OPT_VIDEO | OPT_INT | HAS_ARG, { &frame_bits_per_raw_sample }, - "set the number of bits per raw sample", "number" }, { "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(video_disable) }, "disable video" }, { "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC | |