From patchwork Wed Jun 14 20:58:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tyler Jones X-Patchwork-Id: 3977 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.22.4 with SMTP id 4csp482166vsw; Wed, 14 Jun 2017 13:58:38 -0700 (PDT) X-Received: by 10.28.130.196 with SMTP id e187mr1268441wmd.24.1497473918210; Wed, 14 Jun 2017 13:58:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497473918; cv=none; d=google.com; s=arc-20160816; b=xo36nYyS/s58CZD/GvVSZeP9seVQhzyubkg83PV7RQE8gjRRJAvzFx/1lON6V96Bno 46CIKfWESWVEievkDqCSLW2KXeRLpSmmKvbbdeORpANr1p5iUoe/yjKRF7JyVQVOz5Vj GpQmE7dcBqoJnNFIaJwcGrkhp+s81TuxsJtL0ddof0gSq4/FrW33LpkNDXizhmpE1xtU L468ohrLB2IJigK5nyha6aJ0JeIMFwMxrn/cIIkN7SAjGoueI8QyGc0A5nHwBS1olT1D UOaC1ilNUD5IaH5oAzTd1UqzrLHYBrSy2hNDg7kNU7X717Qa53dfnnHXIhXpgpOb/XR4 73Rg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:user-agent :mime-version:message-id:to:from:date:dkim-signature:delivered-to :arc-authentication-results; bh=+QL8PUT5WGHTIbmou5cotIx6+PXcUuHNkrFgS2XCYuo=; b=LpxZ9luVETz5yKWs0shf/KBJhpx/PPJwT06wDKzaV9QqgT9IqSAKYT1g6md7dYDTYL fbdUjNfLTNdANved8it1j6m4ZcdJ6UB5yZc6NVdwfWohTGDioTLz9P3O7ozzMCDqkLiD 8gES2QzylV+TWvuGou6ruaEmZ2svztFeTtOqhz2GtLtRFBaGMlEyHEHQ6+zUX56KiPz7 ZzQbXWncaXHzpI8GPyFrOkpmJ7+JxKD2vhPqsGcKeX43GP04XjV4ocUBNuvMf+gvboiu 8xus95DvnpVH9EbAH7BnFj9ShRQFZjvKPu7qvMGnPOcA/oxX62wp5OeRum5wUGB0BiRJ 5ZjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.b=KVLybh5T; 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 o21si992112wro.277.2017.06.14.13.58.36; Wed, 14 Jun 2017 13:58:38 -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.b=KVLybh5T; 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 B45FA68A225; Wed, 14 Jun 2017 23:58:30 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-io0-f196.google.com (mail-io0-f196.google.com [209.85.223.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0983468A0DE for ; Wed, 14 Jun 2017 23:58:24 +0300 (EEST) Received: by mail-io0-f196.google.com with SMTP id a96so1138715ioj.1 for ; Wed, 14 Jun 2017 13:58:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=L42o7q4TdYdGvxlolaYNy6ZWIRiOp+EXJ+cl7D4V8Rk=; b=KVLybh5T+jsinzjRGucJ2mWZp4Is558LgpNbH4M6BISRB2qWCLJqXgzSugpaDPSGgh tyFHX/a7415HdkJklYo75OkGBcRQbBy3SVtpusKRM50cTBokaiyN2aeDcOrtwQKcxq8J raby2ApDZ0UGuh5JvRvo4tLZsl9G0aKmu6F2f4a//vjE1eKficG6TK+n0Vg8wFxDfav7 qd8IWvqXQI55uhCHnsjc2m6a/2iosoj0SnohrW8JjQzmMH3dYANYgzzrLSDH54wWCyrf cxSHPIZRG/YYgY3WtipWUAOVUyd5A2UvXhBJE/ESL6wAud0iolUsL6JDcZZf61OIby1q 2jFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=L42o7q4TdYdGvxlolaYNy6ZWIRiOp+EXJ+cl7D4V8Rk=; b=fXlC2P+2iozdJA81/8ykRcg6M+quAkWcyJLVlmnLoibjgQk+dNa+gDP9C7nIAQJc7j Mrv/Crzy6Vb3wSvrBO2yjwvky1U1c1CSx4a8tsZVxyzhPiQoIdmP2EWdPKCk+6C2TQrc OVljRhz/r7f+ZMcV6kmupN8f/XvNwmmqb84Ha8KeDxwmrro7E7RD7e2C/EqDqQqtJp1x yfgjIJQGLb04kUm59cG5trS11lxVp+lr1AxEXs7T5QSXbHZArZlQL7uzz5vyJnSfJdi+ bKXvds+odFHjR5FtReGYgULd9MD1EFUTkS2FGtLsX39suzo2+MzuyG1q4+Jjobk8ldec zwBA== X-Gm-Message-State: AKS2vOyOeZOaVeRBefcJkh7+RwT77ImIH4eZkGWI1Ik12/6CNRyK9cAb 0wAkvpvRwuwXYq8j X-Received: by 10.107.171.67 with SMTP id u64mr1924437ioe.125.1497473904957; Wed, 14 Jun 2017 13:58:24 -0700 (PDT) Received: from tdjones879 ([67.223.163.178]) by smtp.gmail.com with ESMTPSA id v22sm522920ioi.54.2017.06.14.13.58.23 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 14 Jun 2017 13:58:23 -0700 (PDT) Date: Wed, 14 Jun 2017 14:58:22 -0600 From: Tyler Jones To: ffmpeg-devel@ffmpeg.org Message-ID: <20170614205822.GA24166@tdjones879> MIME-Version: 1.0 User-Agent: Mutt/1.5.24 (2015-08-30) Subject: [FFmpeg-devel] [PATCH 1/3] avcodec/vorbisenc: Separate copying audio samples from windowing 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" Audio samples are shifted around when copying from the frame queue so that analysis can be done without negatively impacting calculation of the MDCT. Window coefficients are applied to the current two overlapped windows simultaneously instead of applying overlap for the next frame ahead of time. This improves readability when applying windows of varying lengths. Signed-off-by: Tyler Jones --- libavcodec/vorbisenc.c | 76 +++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index afded40..9b66d56 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -453,7 +453,7 @@ static int create_vorbis_context(vorbis_enc_context *venc, venc->samples = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1])); venc->floor = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2); venc->coeffs = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2); - venc->scratch = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2); + venc->scratch = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1])); if (!venc->saved || !venc->samples || !venc->floor || !venc->coeffs || !venc->scratch) return AVERROR(ENOMEM); @@ -994,8 +994,7 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, return 0; } -static int apply_window_and_mdct(vorbis_enc_context *venc, - float *audio, int samples) +static int apply_window_and_mdct(vorbis_enc_context *venc, int samples) { int channel; const float * win = venc->win[0]; @@ -1003,46 +1002,19 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, float n = (float)(1 << venc->log2_blocksize[0]) / 4.0; AVFloatDSPContext *fdsp = venc->fdsp; - if (!venc->have_saved && !samples) - return 0; + for (channel = 0; channel < venc->channels; channel++) { + float *offset = venc->samples + channel * window_len * 2; - if (venc->have_saved) { - for (channel = 0; channel < venc->channels; channel++) - memcpy(venc->samples + channel * window_len * 2, - venc->saved + channel * window_len, sizeof(float) * window_len); - } else { - for (channel = 0; channel < venc->channels; channel++) - memset(venc->samples + channel * window_len * 2, 0, - sizeof(float) * window_len); - } + fdsp->vector_fmul(offset, offset, win, samples); + fdsp->vector_fmul_scalar(offset, offset, 1/n, samples); - if (samples) { - for (channel = 0; channel < venc->channels; channel++) { - float *offset = venc->samples + channel * window_len * 2 + window_len; + offset += window_len; - fdsp->vector_fmul_reverse(offset, audio + channel * window_len, win, samples); - fdsp->vector_fmul_scalar(offset, offset, 1/n, samples); - } - } else { - for (channel = 0; channel < venc->channels; channel++) - memset(venc->samples + channel * window_len * 2 + window_len, - 0, sizeof(float) * window_len); - } + fdsp->vector_fmul_reverse(offset, offset, win, samples); + fdsp->vector_fmul_scalar(offset, offset, 1/n, samples); - for (channel = 0; channel < venc->channels; channel++) venc->mdct[0].mdct_calc(&venc->mdct[0], venc->coeffs + channel * window_len, venc->samples + channel * window_len * 2); - - if (samples) { - for (channel = 0; channel < venc->channels; channel++) { - float *offset = venc->saved + channel * window_len; - - fdsp->vector_fmul(offset, audio + channel * window_len, win, samples); - fdsp->vector_fmul_scalar(offset, offset, 1/n, samples); - } - venc->have_saved = 1; - } else { - venc->have_saved = 0; } return 1; } @@ -1071,24 +1043,40 @@ static AVFrame *spawn_empty_frame(AVCodecContext *avctx, int channels) return f; } -/* Concatenate audio frames into an appropriately sized array of samples */ -static void move_audio(vorbis_enc_context *venc, float *audio, int *samples, int sf_size) +/* Set up audio samples for psy analysis and window/mdct */ +static void move_audio(vorbis_enc_context *venc, int *samples, int sf_size) { AVFrame *cur = NULL; int frame_size = 1 << (venc->log2_blocksize[1] - 1); int subframes = frame_size / sf_size; + int sf, ch; - for (int sf = 0; sf < subframes; sf++) { + /* Copy samples from last frame into current frame */ + if (venc->have_saved) + for (ch = 0; ch < venc->channels; ch++) + memcpy(venc->samples + 2 * ch * frame_size, + venc->saved + ch * frame_size, sizeof(float) * frame_size); + else + for (ch = 0; ch < venc->channels; ch++) + memset(venc->samples + 2 * ch * frame_size, 0, sizeof(float) * frame_size); + + for (sf = 0; sf < subframes; sf++) { cur = ff_bufqueue_get(&venc->bufqueue); *samples += cur->nb_samples; - for (int ch = 0; ch < venc->channels; ch++) { + for (ch = 0; ch < venc->channels; ch++) { + float *offset = venc->samples + 2 * ch * frame_size + frame_size; + float *save = venc->saved + ch * frame_size; const float *input = (float *) cur->extended_data[ch]; const size_t len = cur->nb_samples * sizeof(float); - memcpy(audio + ch*frame_size + sf*sf_size, input, len); + + memcpy(offset + sf*sf_size, input, len); + memcpy(save + sf*sf_size, input, len); // Move samples for next frame } av_frame_free(&cur); } + venc->have_saved = 1; + memcpy(venc->scratch, venc->samples, 2 * venc->channels * frame_size); } static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, @@ -1129,9 +1117,9 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } } - move_audio(venc, venc->scratch, &samples, avctx->frame_size); + move_audio(venc, &samples, avctx->frame_size); - if (!apply_window_and_mdct(venc, venc->scratch, samples)) + if (!apply_window_and_mdct(venc, samples)) return 0; if ((ret = ff_alloc_packet2(avctx, avpkt, 8192, 0)) < 0)