From patchwork Tue Nov 23 10:30:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 31560 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:d206:0:0:0:0:0 with SMTP id q6csp8445698iob; Tue, 23 Nov 2021 02:31:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJzh2F+RUEuilgV0qBNdRDcyV/wPk9Im2VW8BvyqOpKXoW1HS733MjZfiQfPjf2IVaMedF1N X-Received: by 2002:a17:906:3e83:: with SMTP id a3mr6267953ejj.383.1637663488963; Tue, 23 Nov 2021 02:31:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637663488; cv=none; d=google.com; s=arc-20160816; b=xf1s7soEYyonjPV38uRJx5U+iff5IK03eR/snfre8Id4JJzTdFEU8y+ogoqVCKUF6s UhSP1xlmBO6QpP3z/MiVMTdTaU/VdB8Rm4XNUrCSk15natTO2TRbpyAjq6jPbkgDAGjY da9ohVl0hhlSeHshWclY/jsF3woMYN+KnpTZarkrp6VV4ndA3siLWJPGYG6EtNDDP4a2 aeqiH1rnjhYIjX8t+h7u7w7Hqz053aoEcST2Mp8ZoZ8M3LzVlf4cQ6WWPRn6MC0YgwiR WfoOjlm8xPz6SGqNF89ii1gaDFcvvJJXVLLfJ4ICC71fjWsw7WnzGEJU0EyvEAWG5iJ0 j1uw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:delivered-to; bh=/ku1SwL9NHPUKBj8BknLnMiBZC/OnSNDvC7R+UASDYY=; b=JP1iDTynnfLUgnxN6aK2F4cpEKavK0AwcnGSmAFi20F29fRxoxUCv1E+D605ReJIVv wJJNOizl9zBebnLYT5MFmvH7LTNmOnPrM8VRBUbxZpUjGeN1Bh6Jq7zRSfrx4UfpaMCe JASt+qULXOtqFMZ9OmBpXtAC4WTLhDkqpmGawDA9s3V2TGFK3e1+2P/Fe0Ook1e0NGGa p1TusXekFpAMDV7bDFDaqhzgqDMJt6q/SKEMQjEsCl/CdiREDP96eVCYRC21lZLVZ685 VwA0XADuBNIlqAUJU6Ln+3yASIu/d2xnypb6gIuftcuoHU7+v4gdQY8zYuntK8gNh1mH rMmQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id cw18si36944557ejc.639.2021.11.23.02.31.28; Tue, 23 Nov 2021 02:31:28 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6CDEC68AEA3; Tue, 23 Nov 2021 12:31:14 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6774868A44C for ; Tue, 23 Nov 2021 12:31:07 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 16258240177 for ; Tue, 23 Nov 2021 11:31:07 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id qUiO-zCdgdMa for ; Tue, 23 Nov 2021 11:31:06 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail0.khirnov.net (Postfix) with ESMTPS id F415A24017C for ; Tue, 23 Nov 2021 11:31:05 +0100 (CET) Received: by libav.khirnov.net (Postfix, from userid 1000) id CFAC83A073E; Tue, 23 Nov 2021 11:31:05 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Tue, 23 Nov 2021 11:30:00 +0100 Message-Id: <20211123103001.12888-3-anton@khirnov.net> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211123103001.12888-1-anton@khirnov.net> References: <20211123103001.12888-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/4] ffmpeg: make -bits_per_raw_sample a per-output-stream option X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: aJT0a6YcHZdk 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}. +@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 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) },