[FFmpeg-devel] [PATCH 3/4] ffmpeg: make -bits_per_raw_sample a per-output-stream option
Anton Khirnov
anton at khirnov.net
Tue Nov 23 12:30:00 EET 2021
Also, document it and make it apply to audio in addition to video.
---
doc/ffmpeg.texi | 7 +++++++
fftools/ffmpeg.c | 11 +++++++----
fftools/ffmpeg.h | 3 +++
fftools/ffmpeg_opt.c | 11 +++++++----
4 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 8418573618..5279a05b10 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -1945,6 +1945,13 @@ filter (scale, aresample) in the graph.
On by default, to explicitly disable it you need to specify
@code{-noauto_conversion_filters}.
+ at 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
+ at 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 7dfcfc13f5..55ad4e558e 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -3411,13 +3411,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;
@@ -3460,7 +3463,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 545ff1c8e7..3d9bb30e72 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -236,6 +236,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 {
@@ -493,6 +495,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 b423d0e59c..e839a830a6 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)\
{\
@@ -167,7 +168,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;
@@ -1636,6 +1636,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;
@@ -1801,7 +1804,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;
@@ -3743,6 +3745,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 },
@@ -3762,8 +3767,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" },
{ "intra", OPT_VIDEO | OPT_BOOL | OPT_EXPERT, { &intra_only },
"deprecated use -g 1" },
{ "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(video_disable) },
--
2.33.0
More information about the ffmpeg-devel
mailing list