From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 2779945995 for ; Tue, 28 Feb 2023 14:10:44 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3CB7968A867; Tue, 28 Feb 2023 16:10:42 +0200 (EET) Received: from mail8.parnet.fi (mail8.parnet.fi [77.234.108.134]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8FE5F680D1D for ; Tue, 28 Feb 2023 16:10:35 +0200 (EET) Received: from mail9.parnet.fi (mail9.parnet.fi [77.234.108.21]) by mail8.parnet.fi with ESMTP id 31SEAYAH009645-31SEAYAI009645; Tue, 28 Feb 2023 16:10:34 +0200 Received: from foo.martin.st (host-97-187.parnet.fi [77.234.97.187]) by mail9.parnet.fi (Postfix) with ESMTPS id 7C8C7A143A; Tue, 28 Feb 2023 16:10:34 +0200 (EET) Date: Tue, 28 Feb 2023 16:10:34 +0200 (EET) From: =?ISO-8859-15?Q?Martin_Storsj=F6?= To: FFmpeg development discussions and patches In-Reply-To: <20230227012248.3548790-1-JonHGee@gmail.com> Message-ID: <826ff2b1-6de8-4811-5ad5-6f1c3b30662c@martin.st> References: <63F985BE.06260C.50083@loongson.cn> <20230227012248.3548790-1-JonHGee@gmail.com> MIME-Version: 1.0 X-FE-Policy-ID: 3:14:2:SYSTEM Subject: Re: [FFmpeg-devel] [PATCH] libavcodec/libfdk-aacenc: Enable writing DRC metadata 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 Cc: JonHGee Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii"; Format="flowed" Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: On Mon, 27 Feb 2023, JonHGee wrote: > Added basic DRC options and ref levels to AV options. > If any options are selected, metadata mode is set accordingly > and metadata is added to input buffer per FDK encoder API. > > --- > libavcodec/libfdk-aacenc.c | 72 ++++++++++++++++++++++++++++++-------- > 1 file changed, 58 insertions(+), 14 deletions(-) > > diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c > index 54549de473..4e67b1ece3 100644 > --- a/libavcodec/libfdk-aacenc.c > +++ b/libavcodec/libfdk-aacenc.c > @@ -46,6 +46,12 @@ typedef struct AACContext { > int latm; > int header_period; > int vbr; > + int drc_profile; > + int drc_target_ref; > + int comp_profile; > + int comp_target_ref; > + int prog_ref; > + AACENC_MetaData metaDataSetup; > > AudioFrameQueue afq; > } AACContext; > @@ -64,6 +70,11 @@ static const AVOption aac_enc_options[] = { > { "latm", "Output LATM/LOAS encapsulated data", offsetof(AACContext, latm), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, > { "header_period", "StreamMuxConfig and PCE repetition period (in frames)", offsetof(AACContext, header_period), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xffff, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, > { "vbr", "VBR mode (1-5)", offsetof(AACContext, vbr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 5, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, > + { "drc_profile", "The desired compression profile for AAC DRC", offsetof(AACContext, drc_profile), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 256, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, The indentation of this line is a bit off > + { "drc_target_ref", "Expected target reference level at decoder side in dB (for clipping prevention/limiter)", offsetof(AACContext, drc_target_ref), AV_OPT_TYPE_INT, { .i64 = 0.0 }, -31.75, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, > + { "comp_profile", "The desired compression profile for AAC DRC", offsetof(AACContext, comp_profile), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 256, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, > + { "comp_target_ref", "Expected target reference level at decoder side in dB (for clipping prevention/limiter)", offsetof(AACContext, comp_target_ref), AV_OPT_TYPE_INT, { .i64 = 0.0 }, -31.75, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, > + { "prog_ref", "The program reference level or dialog level in dB", offsetof(AACContext, prog_ref), AV_OPT_TYPE_INT, { .i64 = 0.0 }, -31.75, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, > FF_AAC_PROFILE_OPTS > { NULL } > }; > @@ -127,6 +138,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) > AACENC_ERROR err; > int aot = FF_PROFILE_AAC_LOW + 1; > int sce = 0, cpe = 0; > + int metadata_mode = 0; > > if ((err = aacEncOpen(&s->handle, 0, avctx->ch_layout.nb_channels)) != AACENC_OK) { > av_log(avctx, AV_LOG_ERROR, "Unable to open the encoder: %s\n", > @@ -319,6 +331,29 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) > } > } > > + if (s->prog_ref) { > + metadata_mode = 1; > + s->metaDataSetup.prog_ref_level_present = 1; > + s->metaDataSetup.prog_ref_level = s->prog_ref << 16; > + } > + if (s->drc_profile) { > + metadata_mode = 1; > + s->metaDataSetup.drc_profile = s->drc_profile; > + s->metaDataSetup.drc_TargetRefLevel = s->drc_target_ref << 16; > + if (s->comp_profile) { > + // Including the comp_profile means that we need to set the mode to ETSI > + metadata_mode = 2; > + s->metaDataSetup.comp_profile = s->comp_profile; > + s->metaDataSetup.comp_TargetRefLevel = s->comp_target_ref << 16; > + } > + } > + > + if ((err = aacEncoder_SetParam(s->handle, AACENC_METADATA_MODE, metadata_mode)) != AACENC_OK) { > + av_log(avctx, AV_LOG_ERROR, "Unable to set metadata mode to %d: %s\n", > + metadata_mode, aac_get_error(err)); > + goto error; > + } > + > if ((err = aacEncEncode(s->handle, NULL, NULL, NULL, NULL)) != AACENC_OK) { > av_log(avctx, AV_LOG_ERROR, "Unable to initialize the encoder: %s\n", > aac_get_error(err)); > @@ -363,11 +398,13 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, > AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 }; > AACENC_InArgs in_args = { 0 }; > AACENC_OutArgs out_args = { 0 }; > - int in_buffer_identifier = IN_AUDIO_DATA; > - int in_buffer_size, in_buffer_element_size; > + void* inBuffer[] = { 0, &s->metaDataSetup }; > + int in_buffer_identifiers[] = { IN_AUDIO_DATA, IN_METADATA_SETUP }; > + int in_buffer_element_sizes[] = { 2, sizeof(AACENC_MetaData) }; Weird extra whitespace here > + int in_buffer_sizes[] = { 0 , sizeof(s->metaDataSetup) }; > + void *out_ptr; > int out_buffer_identifier = OUT_BITSTREAM_DATA; > int out_buffer_size, out_buffer_element_size; > - void *in_ptr, *out_ptr; > int ret; > uint8_t dummy_buf[1]; > AACENC_ERROR err; > @@ -376,27 +413,34 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, > if (!frame) { > /* Must be a non-null pointer, even if it's a dummy. We could use > * the address of anything else on the stack as well. */ > - in_ptr = dummy_buf; > - in_buffer_size = 0; > + inBuffer[0] = dummy_buf; > > in_args.numInSamples = -1; The whitespace (for keeping the = vertically aligned) end up weird here, please remove whitespace to keep them aligned (or remove the extra whitespace altogether). > } else { > - in_ptr = frame->data[0]; > - in_buffer_size = 2 * avctx->ch_layout.nb_channels * frame->nb_samples; > + inBuffer[0] = frame->data[0]; > + in_buffer_sizes[0] = 2 * avctx->channels * frame->nb_samples; > > - in_args.numInSamples = avctx->ch_layout.nb_channels * frame->nb_samples; > + in_args.numInSamples = avctx->channels * frame->nb_samples; Your patch reverts the changes to the new channel layout API, which causes warnings when compiling, saying that the channels field is deprecated; please remove such unrelated changes from the patch. > > /* add current frame to the queue */ > if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) > return ret; > } > > - in_buffer_element_size = 2; > - in_buf.numBufs = 1; > - in_buf.bufs = &in_ptr; > - in_buf.bufferIdentifiers = &in_buffer_identifier; > - in_buf.bufSizes = &in_buffer_size; > - in_buf.bufElSizes = &in_buffer_element_size; > + // Only use audio input data if metadata mode is none. > + if (aacEncoder_GetParam(s->handle, AACENC_METADATA_MODE) == 0) { Is it better/more convenient to keep track of this value, what we set it to, in our context, instead of having to query the encoder library each time? Not sure, but maybe..? > + in_buf.numBufs = 1; > + in_buf.bufs = &inBuffer[0]; > + in_buf.bufferIdentifiers = &in_buffer_identifiers[0]; > + in_buf.bufSizes = &in_buffer_sizes[0]; > + in_buf.bufElSizes = &in_buffer_element_sizes[0]; > + } else { > + in_buf.numBufs = 2; > + in_buf.bufs = (void**)&inBuffer; > + in_buf.bufferIdentifiers = &in_buffer_identifiers; > + in_buf.bufSizes = &in_buffer_sizes; > + in_buf.bufElSizes = &in_buffer_element_sizes; > + } The & in e.g. &in_buffer_identifiers here, causes these compile warnings with Clang: src/libavcodec/libfdk-aacenc.c:440:34: warning: incompatible pointer types assigning to 'INT *' (aka 'int *') from 'int (*)[2]' [-Wincompatible-pointer-types] in_buf.bufferIdentifiers = &in_buffer_identifiers; ^ ~~~~~~~~~~~~~~~~~~~~~~ Additionally - &in_buffer_identifiers[0] and in_buffer_identifiers evaluate to essentially the same thing. So as long as the first element of the arrays have been initialized properly, there's no need to keep these assignments within the if/else - just set the same pointers to arrays in either case, and just set numBufs to 1 or 2 depending on the case. Apart from that, the change seems mostly reasonable from a functional point of view. // Martin _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".