You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
ffmpeg: make -bits_per_raw_sample a per-output-stream option
Also, document it and make it apply to audio in addition to video.
This commit is contained in:
@@ -1960,6 +1960,13 @@ filter (scale, aresample) in the graph.
|
|||||||
On by default, to explicitly disable it you need to specify
|
On by default, to explicitly disable it you need to specify
|
||||||
@code{-noauto_conversion_filters}.
|
@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
|
@end table
|
||||||
|
|
||||||
@section Preset files
|
@section Preset files
|
||||||
|
@@ -3329,13 +3329,16 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
|
|||||||
switch (enc_ctx->codec_type) {
|
switch (enc_ctx->codec_type) {
|
||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
enc_ctx->sample_fmt = av_buffersink_get_format(ost->filter->filter);
|
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->sample_rate = av_buffersink_get_sample_rate(ost->filter->filter);
|
||||||
enc_ctx->channel_layout = av_buffersink_get_channel_layout(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);
|
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));
|
init_encoder_time_base(ost, av_make_q(1, enc_ctx->sample_rate));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -3378,7 +3381,7 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
|
|||||||
enc_ctx->width != dec_ctx->width ||
|
enc_ctx->width != dec_ctx->width ||
|
||||||
enc_ctx->height != dec_ctx->height ||
|
enc_ctx->height != dec_ctx->height ||
|
||||||
enc_ctx->pix_fmt != dec_ctx->pix_fmt) {
|
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
|
// Field order: autodetection
|
||||||
|
@@ -228,6 +228,8 @@ typedef struct OptionsContext {
|
|||||||
int nb_enc_time_bases;
|
int nb_enc_time_bases;
|
||||||
SpecifierOpt *autoscale;
|
SpecifierOpt *autoscale;
|
||||||
int nb_autoscale;
|
int nb_autoscale;
|
||||||
|
SpecifierOpt *bits_per_raw_sample;
|
||||||
|
int nb_bits_per_raw_sample;
|
||||||
} OptionsContext;
|
} OptionsContext;
|
||||||
|
|
||||||
typedef struct InputFilter {
|
typedef struct InputFilter {
|
||||||
@@ -483,6 +485,7 @@ typedef struct OutputStream {
|
|||||||
int top_field_first;
|
int top_field_first;
|
||||||
int rotate_overridden;
|
int rotate_overridden;
|
||||||
int autoscale;
|
int autoscale;
|
||||||
|
int bits_per_raw_sample;
|
||||||
double rotate_override_value;
|
double rotate_override_value;
|
||||||
|
|
||||||
AVRational frame_aspect_ratio;
|
AVRational frame_aspect_ratio;
|
||||||
|
@@ -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_disposition[] = {"disposition", NULL};
|
||||||
static const char *const opt_name_time_bases[] = {"time_base", 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_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)\
|
#define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\
|
||||||
{\
|
{\
|
||||||
@@ -160,7 +161,6 @@ int abort_on_flags = 0;
|
|||||||
int print_stats = -1;
|
int print_stats = -1;
|
||||||
int qp_hist = 0;
|
int qp_hist = 0;
|
||||||
int stdin_interaction = 1;
|
int stdin_interaction = 1;
|
||||||
int frame_bits_per_raw_sample = 0;
|
|
||||||
float max_error_rate = 2.0/3;
|
float max_error_rate = 2.0/3;
|
||||||
char *filter_nbthreads;
|
char *filter_nbthreads;
|
||||||
int filter_complex_nbthreads = 0;
|
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;
|
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(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)
|
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||||
ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
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);
|
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);
|
MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
|
||||||
if (frame_pix_fmt && *frame_pix_fmt == '+') {
|
if (frame_pix_fmt && *frame_pix_fmt == '+') {
|
||||||
ost->keep_pix_fmt = 1;
|
ost->keep_pix_fmt = 1;
|
||||||
@@ -3681,6 +3683,9 @@ const OptionDef options[] = {
|
|||||||
"set the maximum number of queued packets from the demuxer" },
|
"set the maximum number of queued packets from the demuxer" },
|
||||||
{ "find_stream_info", OPT_BOOL | OPT_PERFILE | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
|
{ "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" },
|
"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 */
|
/* video options */
|
||||||
{ "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
|
{ "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 |
|
{ "pix_fmt", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
|
||||||
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_pix_fmts) },
|
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_pix_fmts) },
|
||||||
"set pixel format", "format" },
|
"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) },
|
{ "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(video_disable) },
|
||||||
"disable video" },
|
"disable video" },
|
||||||
{ "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
|
{ "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
|
||||||
|
Reference in New Issue
Block a user