From patchwork Tue Aug 22 01:23:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tyler Jones X-Patchwork-Id: 4789 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.137.29 with SMTP id o29csp349380jaj; Mon, 21 Aug 2017 18:30:15 -0700 (PDT) X-Received: by 10.28.194.138 with SMTP id s132mr8588462wmf.29.1503365415183; Mon, 21 Aug 2017 18:30:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503365415; cv=none; d=google.com; s=arc-20160816; b=ZYjr8J2p//SFe4T6swN8UNaysbI7izj1a2VdiiTJko/9oA2rd5VvGt/l3DpTPc6SKa Kt+WQhgxi8Xy+YcTi78lsVfgmtxs/enweKZq5WAJjYWcu9oMhIlBTTK11ctgWduVl45T 1idbFYTnQWxzP0HeocPWFmQWx4OauBZFjq50me1VvenbO+eJ5HjzzNck1t3RyVIwwe9z dZOy1+V1mu9rbEJ7Z25gQwoBpQQIQVlytWL2iV/SfZu2GnWYf8VvChjmTzI9a7SwcK9f xqWOJHmua4jEYcP10eIYvq1Nbi65jrQ8NTjoqaJrogw5+9fHB7RknM6kaGLmX/+8aWEL 830w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=uiUpv6sDm5lon/VlfLQk8YzoTOhQnGO11WGFmoktwaI=; b=oHMgOCtaaEuR6ZykHusORxZgVdlDe8DJJo8OQDau7BnwP0ZTm4ii9Cmh7OcntcuIwq wDhzetYqPNLS96VHsI8q3/A9FJTauU6BG95ogRCvUZjHY+KmWZQt9vSDXX1HNuNlhPQI nhx2FNXl1ZE2ev4TVfvO7bMcvRVnrJ1yh7B4vOMlb+5NIwbuBeyVmKBhBLoGQ2UXnbAW zBzwrdCSl3GUychJI5kmBitS+xns/ZjmgV/j7KJtNRJgj6PB6kIgySYFnM2Cg/FiI9mn I1hOjTXKjzNo/7yaVu5cWjZW9AIDva5+egGXlBo9A6X/dI5dEFpYKDfvXWc5F2B1BKL2 nK7Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=Ligd1Ba3; 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=NONE 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 o20si7195061wrf.294.2017.08.21.18.30.14; Mon, 21 Aug 2017 18:30:15 -0700 (PDT) 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=20161025 header.b=Ligd1Ba3; 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=NONE 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 74AA26882C5; Tue, 22 Aug 2017 04:30:05 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-it0-f66.google.com (mail-it0-f66.google.com [209.85.214.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E8089689213 for ; Tue, 22 Aug 2017 04:29:58 +0300 (EEST) Received: by mail-it0-f66.google.com with SMTP id 76so10829735ith.2 for ; Mon, 21 Aug 2017 18:30:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=CzuiYcPrUI7EkR5rZyFHsF2TFbdATDd3L/Mww73UA+A=; b=Ligd1Ba3eSH4UXNPSnvKxIhoEOo1suMi14hoJ9kBYYIwLd5EWnBkwt4kbIiHizR/1h /yu3jJLz6MaTiZ/K7EgRhnPCh73XO6ZFoBcxweHcTm8VMI8jIB2iqFbvcYQkdqOrQkIb GxEQ2eP4h5E0W7BReaPwgXObKMdNAhKCbKL+DLBMN7sYRk5y+jX8PPiCJtAXsE/xJ3LZ 2j0TpqdjSFQmd5BBc3fb5M5aXTnOSEJYWapWHgcjeck2NdKXL400A2+4NZxA3qyHPMnr ONYXz7naa3lviwbUTjJ6l+xr63S5PbpNznPLKQ+3GPulu+8oM4pUwfQaFRrJ6xSkbhr3 yWhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=CzuiYcPrUI7EkR5rZyFHsF2TFbdATDd3L/Mww73UA+A=; b=HZmFIZ9orgKI0EJmOVxFkAasUKNwUiprV+PCzzPzPAyXA7acsClGHoMz19qx0uksr1 6TSlyBPoxdKuD9F+hG7j3rlD3GgBefZJAEo/MUJpYCtQEfB4mbXaoyrYYk7PQzUcMhFC ERx7vrpeeC2JAAqTxFvNZ/oRqc5e3qzBZf7dY3lPqHA+Et+55prrSzzMvuVB9Ea3FkZl Ifxmk7lpfama4k1g3017EmLVKoacE7hm9G+onmBmlqzMn1DdcN5igPgiLtdnsHrVndA2 +TdiUfKJ64QKdrqDAgiJCJAKS5hnJ1xAxsolR5vTWzNy0EdDoTkrY6yEcG4cND4J+rFy qb9A== X-Gm-Message-State: AHYfb5h3dOpKidKtfn4oVkMeT/2Cf6NExP8hh1SmWWhtRc2Tz8kZUZYy RnYpY2ZJmrTuPTLr X-Received: by 10.36.34.80 with SMTP id o77mr8612474ito.121.1503364988398; Mon, 21 Aug 2017 18:23:08 -0700 (PDT) Received: from tdjones.localdomain (host-184-167-177-46.csp-wy.client.bresnan.net. [184.167.177.46]) by smtp.gmail.com with ESMTPSA id v142sm4607256ita.35.2017.08.21.18.23.07 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Aug 2017 18:23:07 -0700 (PDT) From: Tyler Jones To: ffmpeg-devel@ffmpeg.org Date: Mon, 21 Aug 2017 19:23:04 -0600 Message-Id: <20170822012307.6019-4-tdjones879@gmail.com> In-Reply-To: <20170822012307.6019-1-tdjones879@gmail.com> References: <20170822012307.6019-1-tdjones879@gmail.com> Subject: [FFmpeg-devel] [PATCH 3/6] avcodec/vorbisenc: Add clipping avoidance X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Clipping is avoided by taking the maximum value of each frame before window application, and scaling down the entire frame by a scalar factor. Signed-off-by: Tyler Jones --- libavcodec/vorbisenc.c | 8 ++++---- libavcodec/vorbispsy.c | 17 +++++++++++++++++ libavcodec/vorbispsy.h | 10 ++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index c968956794..73182c6356 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -1037,10 +1037,10 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, * See Vorbis I spec Fig. 2, 3 for examples. */ static void apply_window(vorbis_enc_context *venc, const int *blockflags, - float *out, float* in) + float *out, float* in, const float clip_factor) { int prev_size, curr_size, next_size, bound; - float scale = 1.0f / (float) (1 << (venc->log2_blocksize[blockflags[1]] - 2)); + float scale = clip_factor / (float) (1 << (venc->log2_blocksize[blockflags[1]] - 2)); const float *prev_win, *next_win; AVFloatDSPContext *fdsp = venc->fdsp; @@ -1098,9 +1098,9 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, int next_type) for (channel = 0; channel < venc->channels; channel++) { float *out = venc->scratch; float *in = venc->samples + channel * 2 * long_len + transient_offset; + float clip_factor = ff_psy_vorbis_avoid_clip(in, curr_len, curr_type); - apply_window(venc, blockflags, out, in); - + apply_window(venc, blockflags, out, in, clip_factor); venc->mdct[curr_type].mdct_calc(&venc->mdct[curr_type], venc->coeffs + channel * curr_len, out); } diff --git a/libavcodec/vorbispsy.c b/libavcodec/vorbispsy.c index ab2d41f62f..56e23dea5e 100644 --- a/libavcodec/vorbispsy.c +++ b/libavcodec/vorbispsy.c @@ -140,6 +140,23 @@ int ff_psy_vorbis_block_frame(VorbisPsyContext *vpctx, float *audio, return block_flag; } +float ff_psy_vorbis_avoid_clip(float *audio, int window_len, int blockflag) +{ + int i; + float max = 0, clip = 1.0f; + /* Due to how the mdct scaling works in the vorbis encoder, short blocks are + * more likely to clip. This serves as more fine-grained control */ + const float avoidance_factor = blockflag ? 0.95f : 0.75f; + + for (i = 0; i < window_len; i++) + max = FFMAX(max, fabsf(audio[i])); + + if (max > avoidance_factor) + clip = avoidance_factor / max; + + return clip; +} + av_cold void ff_psy_vorbis_close(VorbisPsyContext *vpctx) { av_freep(&vpctx->filter_delay); diff --git a/libavcodec/vorbispsy.h b/libavcodec/vorbispsy.h index 93a03fd8ca..e632e8ad1d 100644 --- a/libavcodec/vorbispsy.h +++ b/libavcodec/vorbispsy.h @@ -75,6 +75,16 @@ av_cold int ff_psy_vorbis_init(VorbisPsyContext *vpctx, int sample_rate, */ int ff_psy_vorbis_block_frame(VorbisPsyContext *vpctx, float *audio, int ch, int frame_size, int block_size); + +/** + * Provide a scalar coefficient to avoid clipping. + * + * @param audio Raw audio sample input for one channel + * @param window_len Chosen window length for the given frame + * @return Coefficient to be applied alongside the window function + */ +float ff_psy_vorbis_avoid_clip(float *audio, int window_len, int blockflag); + /** * Closes and frees the memory used by the psychoacoustic model */