From patchwork Mon Feb 27 01:22:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JonHGee X-Patchwork-Id: 40529 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:5494:b0:bf:7b3a:fd32 with SMTP id i20csp3010634pzk; Sun, 26 Feb 2023 17:23:35 -0800 (PST) X-Google-Smtp-Source: AK7set+NmwGZf5jN8vFx99PL4IW/2Qb7gBkUzyq88NGjyJ5tWYtyY1+Y3+KfMPjyN+6tO5GJSsei X-Received: by 2002:a17:907:a801:b0:8aa:c0a4:2aa5 with SMTP id vo1-20020a170907a80100b008aac0a42aa5mr34666978ejc.16.1677461015426; Sun, 26 Feb 2023 17:23:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1677461015; cv=none; d=google.com; s=arc-20160816; b=G7JScG8V7a8ichA/2z+KA6lqBPlLo1NsleRKI1J79ycwSoDZLyq10+4677ZeMP2473 WOdeQdCvZt7cVPtuhEtMYhcVpzkEVGHlwihhouhDSAIxIwTtXOTi9ttHPzdRQ/HcFxnA OVF40I0NyoN1pgVF3nT0zHL4iZyuRpjwWzpoLRja5TJm6WZQmR7mtHSlE3Bw8aYHiOnb a8qKj2zt59OBu2FDe+pgyYx/GRjR8GhwHGAutv+OlrhdAQIbTQHrUsZoesR1TVDDIMAI PIMdrYKkT8jQVqIzY4N6KYEEsKhQtBVcd511izXm0wk9+lOcOgq1IZj4FDpWWBYt9l8n ZG6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc: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:dkim-signature:delivered-to; bh=twLf9vnMm2nKK3aPsLm3VRecNMQuXmBMD7XduSevtcc=; b=aIQGWOZgOJMN34bcwRM2i0FFlFAb6eWmhIqsZ7q8Jv+tCatQhNfr8oz+f/jkynLfnS 3jX2d7nFFk9DlA+5zkIRO25bla+dsagPpD4lG6fc3cZlocGidAZsFQw9a3v2XdjxsZMP 53HaDGe4p2Ry/TRCIps1O8r0Ny19UDJOdBirh9xPQQI0BaNgB9eNsB4v21SQULHCXC4Y mhAUZB9H32nLDrDk7Zt1DGit82+n5DaZ8Oe8qWWNzYRwdyH8xkOpzstXxIjQf9o5tflQ XIFUX7O2jKxcx8GSeHInJrzmSqHjw4d5HpRunzaMzMn39Nqmyjj2tsrPQy+cMx+NvMHI Rp2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=llItkwcX; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id d14-20020a170906344e00b008d606b1bbbcsi5297516ejb.311.2023.02.26.17.23.34; Sun, 26 Feb 2023 17:23:35 -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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=llItkwcX; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7C01D68971B; Mon, 27 Feb 2023 03:23:31 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 67DFC680BC0 for ; Mon, 27 Feb 2023 03:23:25 +0200 (EET) Received: by mail-pj1-f47.google.com with SMTP id kb15so4497178pjb.1 for ; Sun, 26 Feb 2023 17:23:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CVVTFKAuin8CdsLQ5BLq7IkhxmpJOrCqx9LA/rBthR4=; b=llItkwcXqhuj/q67rs3ekZBklPPpSmTwfefOuTNONzR3TPS66sGtn5wc7DyuuCDURU /2dlRh+AVknSZjsJObHygVnx5yxKowzYs3hpcdhmTD5GVlHIdF8kxFOvSAEHEA4DP2oQ GcS7HakgvQxleVv95C9aEMvjyB5teJK3mEPxykvU3EXDGo+/dL1FK4x6HPvBDrAoavVA k0p0uch8YciH2GaE8gKJtf7pe220FmioH6g11FgIgmcRmxtONg0VcjW4D8JNSigVK4kd YSZKssTF7u9GQWQf2eKihnLTdkfREexmfovJi8mURXAgeshm+XHNr8KX6y7zVCLknRq0 AWCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CVVTFKAuin8CdsLQ5BLq7IkhxmpJOrCqx9LA/rBthR4=; b=B1hoHfHQrhkMRHXyB5DrYeI77CqAqXrLMyqKXUx4zarO+340phIcPYvCT4sZLIk+hN c3IcUCzfBKlvuhFEeNYtCSuyrE4AuXhZGc7BAJR5yGlAneGPZ1znwORc4ICxfv5lGV5n ihxsgtkH/gRWekxjckqX4wJyQviP3wis67p+N4sl+oiXOrT+NN6Z81b0bEhFAXQtF92b evBeYjzM+qLPYHHSAHZVqO+AK9aR/u5APYb/GD3HxKnC7ImrXs6szn8EzYsMQxu+27H1 vgHuCOghBUuxqAukMEKDBqct79zAgfAWHJb7IuqrvkVTq0bfrPJGt2WFrWhSwPZieN1g rH0w== X-Gm-Message-State: AO0yUKWHlWElOTdlAW9E1IsRTD2MJK/k0RAFPlVwEKomIIq8j/PYh6e9 vi3PJy0xtrwAAvbh+hTQLpg6Fn8tLYs= X-Received: by 2002:a17:90a:190f:b0:237:659a:a44d with SMTP id 15-20020a17090a190f00b00237659aa44dmr13681834pjg.9.1677461003095; Sun, 26 Feb 2023 17:23:23 -0800 (PST) Received: from jongeegti.c.googlers.com.com (170.102.105.34.bc.googleusercontent.com. [34.105.102.170]) by smtp.gmail.com with ESMTPSA id f19-20020a17090aa79300b0023530b1e4a0sm3125112pjq.2.2023.02.26.17.23.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 Feb 2023 17:23:22 -0800 (PST) From: JonHGee X-Google-Original-From: JonHGee To: ffmpeg-devel@ffmpeg.org Date: Mon, 27 Feb 2023 01:22:48 +0000 Message-Id: <20230227012248.3548790-1-JonHGee@gmail.com> X-Mailer: git-send-email 2.39.2.637.g21b0678d19-goog In-Reply-To: <63F985BE.06260C.50083@loongson.cn> References: <63F985BE.06260C.50083@loongson.cn> MIME-Version: 1.0 Subject: [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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: BX9liBY3OpPO 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 }, + { "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) }; + 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; } 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; /* 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) { + 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 maximum packet size is 6144 bits aka 768 bytes per channel. */ ret = ff_alloc_packet(avctx, avpkt, FFMAX(8192, 768 * avctx->ch_layout.nb_channels));