From patchwork Sat Mar 16 16:31:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lynne X-Patchwork-Id: 12328 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id EAE72449715 for ; Sat, 16 Mar 2019 18:32:04 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CA4AF68989D; Sat, 16 Mar 2019 18:32:04 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from w4.tutanota.de (w4.tutanota.de [81.3.6.165]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F412868089A for ; Sat, 16 Mar 2019 18:31:57 +0200 (EET) Received: from w2.tutanota.de (unknown [192.168.1.163]) by w4.tutanota.de (Postfix) with ESMTP id 764B81060237 for ; Sat, 16 Mar 2019 16:31:57 +0000 (UTC) Date: Sat, 16 Mar 2019 17:31:57 +0100 (CET) From: Lynne To: FFmpeg development discussions and patches Message-ID: In-Reply-To: References: MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/5] opusdsp: create and move deemphasis and postfiltering from opus_celt 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Nothing else changed. From 5bf6dc93339a231bd82f09cc6a2b9becb5af0f4a Mon Sep 17 00:00:00 2001 From: Lynne Date: Fri, 15 Mar 2019 14:35:03 +0000 Subject: [PATCH 3/5] opusdsp: create and move deemphasis and postfiltering from opus_celt --- libavcodec/Makefile | 3 ++- libavcodec/opus_celt.c | 53 ++++++++---------------------------- libavcodec/opus_celt.h | 3 ++- libavcodec/opusdsp.c | 61 ++++++++++++++++++++++++++++++++++++++++++ libavcodec/opusdsp.h | 33 +++++++++++++++++++++++ 5 files changed, 109 insertions(+), 44 deletions(-) create mode 100644 libavcodec/opusdsp.c create mode 100644 libavcodec/opusdsp.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 15c43a8a6a..d13eef8a20 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -495,7 +495,8 @@ OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o opus_rc.o \ - opus_pvq.o opus_silk.o opustab.o vorbis_data.o + opus_pvq.o opus_silk.o opustab.o vorbis_data.o \ + opusdsp.o OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus.o opus_rc.o opustab.o opus_pvq.o \ opusenc_psy.o OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c index 115dd8c63e..4655172b09 100644 --- a/libavcodec/opus_celt.c +++ b/libavcodec/opus_celt.c @@ -202,40 +202,10 @@ static void celt_postfilter_apply_transition(CeltBlock *block, float *data) } } -static void celt_postfilter_apply(CeltBlock *block, float *data, int len) -{ - const int T = block->pf_period; - float g0, g1, g2; - float x0, x1, x2, x3, x4; - int i; - - if (block->pf_gains[0] == 0.0 || len <= 0) - return; - - g0 = block->pf_gains[0]; - g1 = block->pf_gains[1]; - g2 = block->pf_gains[2]; - - x4 = data[-T - 2]; - x3 = data[-T - 1]; - x2 = data[-T]; - x1 = data[-T + 1]; - - for (i = 0; i < len; i++) { - x0 = data[i - T + 2]; - data[i] += g0 * x2 + - g1 * (x1 + x3) + - g2 * (x0 + x4); - x4 = x3; - x3 = x2; - x2 = x1; - x1 = x0; - } -} - static void celt_postfilter(CeltFrame *f, CeltBlock *block) { int len = f->blocksize * f->blocks; + const int filter_len = len - 2 * CELT_OVERLAP; celt_postfilter_apply_transition(block, block->buf + 1024); @@ -247,8 +217,11 @@ static void celt_postfilter(CeltFrame *f, CeltBlock *block) if (len > CELT_OVERLAP) { celt_postfilter_apply_transition(block, block->buf + 1024 + CELT_OVERLAP); - celt_postfilter_apply(block, block->buf + 1024 + 2 * CELT_OVERLAP, - len - 2 * CELT_OVERLAP); + + if (block->pf_gains[0] > FLT_EPSILON && filter_len > 0) + f->opusdsp.postfilter(block->buf + 1024 + 2 * CELT_OVERLAP, + block->pf_period, block->pf_gains, + filter_len); block->pf_period_old = block->pf_period; memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains)); @@ -462,7 +435,6 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, /* transform and output for each output channel */ for (i = 0; i < f->output_channels; i++) { CeltBlock *block = &f->block[i]; - float m = block->emph_coeff; /* iMDCT and overlap-add */ for (j = 0; j < f->blocks; j++) { @@ -480,14 +452,10 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, /* postfilter */ celt_postfilter(f, block); - /* deemphasis and output scaling */ - for (j = 0; j < frame_size; j++) { - const float tmp = block->buf[1024 - frame_size + j] + m; - m = tmp * CELT_EMPH_COEFF; - output[i][j] = tmp; - } - - block->emph_coeff = m; + /* deemphasis */ + block->emph_coeff = f->opusdsp.deemphasis(output[i], + &block->buf[1024 - frame_size], + block->emph_coeff, frame_size); } if (channels == 1) @@ -596,6 +564,7 @@ int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels, goto fail; } + ff_opus_dsp_init(&frm->opusdsp); ff_celt_flush(frm); *f = frm; diff --git a/libavcodec/opus_celt.h b/libavcodec/opus_celt.h index 9289a1867a..7c1c5316b9 100644 --- a/libavcodec/opus_celt.h +++ b/libavcodec/opus_celt.h @@ -28,6 +28,7 @@ #include "opus.h" #include "opus_pvq.h" +#include "opusdsp.h" #include "mdct15.h" #include "libavutil/float_dsp.h" @@ -40,7 +41,6 @@ #define CELT_NORM_SCALE 16384 #define CELT_QTHETA_OFFSET 4 #define CELT_QTHETA_OFFSET_TWOPHASE 16 -#define CELT_EMPH_COEFF 0.85000610f #define CELT_POSTFILTER_MINPERIOD 15 #define CELT_ENERGY_SILENCE (-28.0f) @@ -96,6 +96,7 @@ struct CeltFrame { AVFloatDSPContext *dsp; CeltBlock block[2]; CeltPVQ *pvq; + OpusDSP opusdsp; int channels; int output_channels; int apply_phase_inv; diff --git a/libavcodec/opusdsp.c b/libavcodec/opusdsp.c new file mode 100644 index 0000000000..615e7d6816 --- /dev/null +++ b/libavcodec/opusdsp.c @@ -0,0 +1,61 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "opusdsp.h" + +static void postfilter_c(float *data, int period, float *gains, int len) +{ + const float g0 = gains[0]; + const float g1 = gains[1]; + const float g2 = gains[2]; + + float x4 = data[-period - 2]; + float x3 = data[-period - 1]; + float x2 = data[-period + 0]; + float x1 = data[-period + 1]; + + for (int i = 0; i < len; i++) { + float x0 = data[i - period + 2]; + data[i] += g0 * x2 + + g1 * (x1 + x3) + + g2 * (x0 + x4); + x4 = x3; + x3 = x2; + x2 = x1; + x1 = x0; + } +} + +static float deemphasis_c(float *y, float *x, float coeff, int len) +{ + float state = coeff; + + for (int i = 0; i < len; i++) { + const float tmp = x[i] + state; + state = tmp * CELT_EMPH_COEFF; + y[i] = tmp; + } + + return state; +} + +av_cold void ff_opus_dsp_init(OpusDSP *ctx) +{ + ctx->postfilter = postfilter_c; + ctx->deemphasis = deemphasis_c; +} diff --git a/libavcodec/opusdsp.h b/libavcodec/opusdsp.h new file mode 100644 index 0000000000..74adfe6859 --- /dev/null +++ b/libavcodec/opusdsp.h @@ -0,0 +1,33 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUS_DSP_H +#define AVCODEC_OPUS_DSP_H + +#include "libavutil/common.h" + +#define CELT_EMPH_COEFF 0.8500061035f + +typedef struct OpusDSP { + void (*postfilter)(float *data, int period, float *gains, int len); + float (*deemphasis)(float *out, float *in, float coeff, int len); +} OpusDSP; + +void ff_opus_dsp_init(OpusDSP *ctx); + +#endif /* AVCODEC_OPUS_DSP_H */ -- 2.21.0