From patchwork Sun Oct 9 12:15:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rostislav Pehlivanov X-Patchwork-Id: 926 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.66 with SMTP id o63csp2065292vsd; Sun, 9 Oct 2016 05:34:27 -0700 (PDT) X-Received: by 10.194.119.2 with SMTP id kq2mr17314544wjb.217.1476016467815; Sun, 09 Oct 2016 05:34:27 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id ih4si31212274wjb.124.2016.10.09.05.34.26; Sun, 09 Oct 2016 05:34:27 -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; 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 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 86411689B19; Sun, 9 Oct 2016 15:34:08 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf0-f67.google.com (mail-lf0-f67.google.com [209.85.215.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 037E0689AF8 for ; Sun, 9 Oct 2016 15:34:02 +0300 (EEST) Received: by mail-lf0-f67.google.com with SMTP id l131so5310773lfl.0 for ; Sun, 09 Oct 2016 05:34:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=vMcPUo8EztS3pXjohriC3qKj0L7a8dLy5dFIfsIZpaI=; b=DwrIIiJ0Vz8j3QwRZL+Vbz4aGaTL+j5xzp0bvOM5nheUOFA+qu3um9p2M1BOb0LVo7 /AIiH1K+0EXpZ+DLlsoXC9F9w82FFnuDVIAH4b5z2kIvF3kewp7UcKtev/PI0eeku4UZ YoOeA3U+3YOJ5d7cVWzeuHv0PvlCeJP6SNV7PKfIJOtvY12s4poUHxzQ34WzSJ6+jlBY 9siL4/afeFgDSGE8FGNYBz3teN4W79JHaOUNRl9E9pqrhUvphOOIo2eohrvlY/CC3o9D R74yD6wXR9QIMxGUMIqmUm40wUKWFKrjLOF5qVIWZW/AYt4nVnczU//3cmPE+Nr3S0uR 2RPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=vMcPUo8EztS3pXjohriC3qKj0L7a8dLy5dFIfsIZpaI=; b=k6AgucDfFxdjw5EIWv8rflWlwUtb7fJ/BZGK0cUDG/Akc4o8n0lGhlfGWUbYbSqROp Q/T3wpVollZ4ZkG8biwZm8p0ih/EvkRLQQ+Oe5zqNyRrR+KQQ6fBPFcKilm1KF+sdWtu oVcIWcxPL7ZrSvSSwq0cvLs/CMrou16WE+exd+tWO8qY3iByNeuGyaFzfS1uBGOk7E6J HIMf5pXf9jZ/Wut40q7E6Q69vg6Wsf4JJSKNFxP/tRpFo9RRSBK5lcXl1S4tzpq4Y0y3 RS0/zj76WEvRop4skxOGPOyChPL7BEAHoNS1GRZJ29A26ZxlYt/F/FKiuk67HAmNve+y 3OTA== X-Gm-Message-State: AA6/9RmSJvq7fxEtYUeJkLnh0mZIVK2Ltk2z2TTBRW63wSxs+8SQZ4qLh5biuV0w3l6va1PbewZycZ6FiVhSIw== X-Received: by 10.25.21.12 with SMTP id l12mr5518158lfi.152.1476015345246; Sun, 09 Oct 2016 05:15:45 -0700 (PDT) MIME-Version: 1.0 Received: by 10.114.2.201 with HTTP; Sun, 9 Oct 2016 05:15:44 -0700 (PDT) In-Reply-To: <20161009021843.GS5270@nb4> References: <20161008174228.21750-1-atomnuker@gmail.com> <20161009021843.GS5270@nb4> From: Rostislav Pehlivanov Date: Sun, 9 Oct 2016 13:15:44 +0100 Message-ID: To: FFmpeg development discussions and patches X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: Re: [FFmpeg-devel] [PATCH v2] aacenc: add SIMD optimizations for abs_pow34 and quantization 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" On 9 October 2016 at 03:18, Michael Niedermayer wrote: > On Sat, Oct 08, 2016 at 06:42:28PM +0100, Rostislav Pehlivanov wrote: > > Performance improvements: > > > > quant_bands: > > with: 681 decicycles in quant_bands, 8388453 runs, 155 skips > > without: 1190 decicycles in quant_bands, 8388386 runs, 222 skips > > Around 42% for the function > > > > Twoloop coder: > > > > abs_pow34: > > with/without: 7.82s/8.17s > > Around 4% for the entire encoder > > > > Both: > > with/without: 7.15s/8.17s > > Around 12% for the entire encoder > > > > Fast coder: > > > > abs_pow34: > > with/without: 3.40s/3.77s > > Around 10% for the entire encoder > > > > Both: > > with/without: 3.02s/3.77s > > Around 20% faster for the entire encoder > > > > Signed-off-by: Rostislav Pehlivanov > > --- > > libavcodec/aaccoder.c | 22 ++++---- > > libavcodec/aaccoder_trellis.h | 2 +- > > libavcodec/aaccoder_twoloop.h | 2 +- > > libavcodec/aacenc.c | 4 ++ > > libavcodec/aacenc.h | 6 +++ > > libavcodec/aacenc_is.c | 6 +-- > > libavcodec/aacenc_ltp.c | 4 +- > > libavcodec/aacenc_pred.c | 6 +-- > > libavcodec/aacenc_quantization.h | 4 +- > > libavcodec/aacenc_utils.h | 4 +- > > libavcodec/x86/Makefile | 2 + > > libavcodec/x86/aacencdsp.asm | 108 ++++++++++++++++++++++++++++++ > +++++++++ > > libavcodec/x86/aacencdsp_init.c | 42 +++++++++++++++ > > 13 files changed, 187 insertions(+), 25 deletions(-) > > create mode 100644 libavcodec/x86/aacencdsp.asm > > create mode 100644 libavcodec/x86/aacencdsp_init.c > > libavcodec/x86/aacencdsp.asm:67: error: expression syntax error > libavcodec/x86/aacencdsp.asm:79: warning: (RUN_AVX_INSTR:22) use of > ``movd'' sse2 instruction in sse function: ff_aac_quantize_bands_sse > libavcodec/x86/aacencdsp.asm:99: warning: (RUN_AVX_INSTR:22) use of > ``pand'' sse2 instruction in sse function: ff_aac_quantize_bands_sse > libavcodec/x86/aacencdsp.asm:103: warning: (RUN_AVX_INSTR:20) use of > ``cvttps2dq'' sse2 instruction in sse function: ff_aac_quantize_bands_sse > > yasm 1.2.0 > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > Breaking DRM is a little like attempting to break through a door even > though the window is wide open and the only thing in the house is a bunch > of things you dont want and which you would get tomorrow for free anyway > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > Yes, discussed on IRC, fixed that yesterday. Attached the patch if you want to test. I'll push it tonight unless confirmed to not work on Windows (haven't tested but it should work according to what nevcairiel said). From 3bc5622e5be67698d099a191ebfd297bf1eda7cd Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Sat, 8 Oct 2016 15:59:14 +0100 Subject: [PATCH] aacenc: add SIMD optimizations for abs_pow34 and quantization Performance improvements: quant_bands: with: 681 decicycles in quant_bands, 8388453 runs, 155 skips without: 1190 decicycles in quant_bands, 8388386 runs, 222 skips Around 42% for the function Twoloop coder: abs_pow34: with/without: 7.82s/8.17s Around 4% for the entire encoder Both: with/without: 7.15s/8.17s Around 12% for the entire encoder Fast coder: abs_pow34: with/without: 3.40s/3.77s Around 10% for the entire encoder Both: with/without: 3.02s/3.77s Around 20% faster for the entire encoder Signed-off-by: Rostislav Pehlivanov --- libavcodec/aaccoder.c | 22 +++++----- libavcodec/aaccoder_trellis.h | 2 +- libavcodec/aaccoder_twoloop.h | 2 +- libavcodec/aacenc.c | 4 ++ libavcodec/aacenc.h | 6 +++ libavcodec/aacenc_is.c | 6 +-- libavcodec/aacenc_ltp.c | 4 +- libavcodec/aacenc_pred.c | 6 +-- libavcodec/aacenc_quantization.h | 4 +- libavcodec/aacenc_utils.h | 4 +- libavcodec/x86/Makefile | 2 + libavcodec/x86/aacencdsp.asm | 87 ++++++++++++++++++++++++++++++++++++++++ libavcodec/x86/aacencdsp_init.c | 43 ++++++++++++++++++++ 13 files changed, 167 insertions(+), 25 deletions(-) create mode 100644 libavcodec/x86/aacencdsp.asm create mode 100644 libavcodec/x86/aacencdsp_init.c diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index 35787e8..6760a70 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -88,7 +88,7 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce float next_minrd = INFINITY; int next_mincb = 0; - abs_pow34_v(s->scoefs, sce->coeffs, 1024); + s->abs_pow34(s->scoefs, sce->coeffs, 1024); start = win*128; for (cb = 0; cb < CB_TOT_ALL; cb++) { path[0][cb].cost = 0.0f; @@ -299,7 +299,7 @@ static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s, } } idx = 1; - abs_pow34_v(s->scoefs, sce->coeffs, 1024); + s->abs_pow34(s->scoefs, sce->coeffs, 1024); for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { start = w*128; for (g = 0; g < sce->ics.num_swb; g++) { @@ -446,7 +446,7 @@ static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s, if (!allz) return; - abs_pow34_v(s->scoefs, sce->coeffs, 1024); + s->abs_pow34(s->scoefs, sce->coeffs, 1024); ff_quantize_band_cost_cache_init(s); for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { @@ -652,8 +652,8 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne s->fdsp->vector_fmul_scalar(PNS, PNS, scale, sce->ics.swb_sizes[g]); pns_senergy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]); pns_energy += pns_senergy; - abs_pow34_v(NOR34, &sce->coeffs[start_c], sce->ics.swb_sizes[g]); - abs_pow34_v(PNS34, PNS, sce->ics.swb_sizes[g]); + s->abs_pow34(NOR34, &sce->coeffs[start_c], sce->ics.swb_sizes[g]); + s->abs_pow34(PNS34, PNS, sce->ics.swb_sizes[g]); dist1 += quantize_band_cost(s, &sce->coeffs[start_c], NOR34, sce->ics.swb_sizes[g], @@ -789,8 +789,8 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe) S[i] = M[i] - sce1->coeffs[start+(w+w2)*128+i]; } - abs_pow34_v(M34, M, sce0->ics.swb_sizes[g]); - abs_pow34_v(S34, S, sce0->ics.swb_sizes[g]); + s->abs_pow34(M34, M, sce0->ics.swb_sizes[g]); + s->abs_pow34(S34, S, sce0->ics.swb_sizes[g]); for (i = 0; i < sce0->ics.swb_sizes[g]; i++ ) { Mmax = FFMAX(Mmax, M34[i]); Smax = FFMAX(Smax, S34[i]); @@ -833,10 +833,10 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe) - sce1->coeffs[start+(w+w2)*128+i]; } - abs_pow34_v(L34, sce0->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); - abs_pow34_v(R34, sce1->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); - abs_pow34_v(M34, M, sce0->ics.swb_sizes[g]); - abs_pow34_v(S34, S, sce0->ics.swb_sizes[g]); + s->abs_pow34(L34, sce0->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); + s->abs_pow34(R34, sce1->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); + s->abs_pow34(M34, M, sce0->ics.swb_sizes[g]); + s->abs_pow34(S34, S, sce0->ics.swb_sizes[g]); dist1 += quantize_band_cost(s, &sce0->coeffs[start + (w+w2)*128], L34, sce0->ics.swb_sizes[g], diff --git a/libavcodec/aaccoder_trellis.h b/libavcodec/aaccoder_trellis.h index 0230052..940ebf0 100644 --- a/libavcodec/aaccoder_trellis.h +++ b/libavcodec/aaccoder_trellis.h @@ -70,7 +70,7 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce, float next_minbits = INFINITY; int next_mincb = 0; - abs_pow34_v(s->scoefs, sce->coeffs, 1024); + s->abs_pow34(s->scoefs, sce->coeffs, 1024); start = win*128; for (cb = 0; cb < CB_TOT_ALL; cb++) { path[0][cb].cost = run_bits+4; diff --git a/libavcodec/aaccoder_twoloop.h b/libavcodec/aaccoder_twoloop.h index 42aea52..fb9849e 100644 --- a/libavcodec/aaccoder_twoloop.h +++ b/libavcodec/aaccoder_twoloop.h @@ -291,7 +291,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, if (!allz) return; - abs_pow34_v(s->scoefs, sce->coeffs, 1024); + s->abs_pow34(s->scoefs, sce->coeffs, 1024); ff_quantize_band_cost_cache_init(s); for (i = 0; i < sizeof(minsf) / sizeof(minsf[0]); ++i) diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index ee3cbf8..f30691a 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -1033,6 +1033,10 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON); s->random_state = 0x1f2e3d4c; + s->abs_pow34 = &abs_pow34_v; + s->quant_bands = &quantize_bands; + ff_aac_dsp_init_x86(s); + if (HAVE_MIPSDSP) ff_aac_coder_init_mips(s); diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h index 1ace00d..8682867 100644 --- a/libavcodec/aacenc.h +++ b/libavcodec/aacenc.h @@ -127,11 +127,17 @@ typedef struct AACEncContext { uint16_t quantize_band_cost_cache_generation; AACQuantizeBandCostCacheEntry quantize_band_cost_cache[256][128]; ///< memoization area for quantize_band_cost + void (*abs_pow34)(float *out, const float *in, const int64_t size); + void (*quant_bands)(int *out, const float *in, const float *scaled, + int size, int is_signed, int maxval, const float Q34, + const float rounding); + struct { float *samples; } buffer; } AACEncContext; +void ff_aac_dsp_init_x86(AACEncContext *s); void ff_aac_coder_init_mips(AACEncContext *c); void ff_quantize_band_cost_cache_init(struct AACEncContext *s); diff --git a/libavcodec/aacenc_is.c b/libavcodec/aacenc_is.c index 473897b..2f5b7eb 100644 --- a/libavcodec/aacenc_is.c +++ b/libavcodec/aacenc_is.c @@ -59,9 +59,9 @@ struct AACISError ff_aac_is_encoding_err(AACEncContext *s, ChannelElement *cpe, float minthr = FFMIN(band0->threshold, band1->threshold); for (i = 0; i < sce0->ics.swb_sizes[g]; i++) IS[i] = (L[start+(w+w2)*128+i] + phase*R[start+(w+w2)*128+i])*sqrt(ener0/ener01); - abs_pow34_v(L34, &L[start+(w+w2)*128], sce0->ics.swb_sizes[g]); - abs_pow34_v(R34, &R[start+(w+w2)*128], sce0->ics.swb_sizes[g]); - abs_pow34_v(I34, IS, sce0->ics.swb_sizes[g]); + s->abs_pow34(L34, &L[start+(w+w2)*128], sce0->ics.swb_sizes[g]); + s->abs_pow34(R34, &R[start+(w+w2)*128], sce0->ics.swb_sizes[g]); + s->abs_pow34(I34, IS, sce0->ics.swb_sizes[g]); maxval = find_max_val(1, sce0->ics.swb_sizes[g], I34); is_band_type = find_min_book(maxval, is_sf_idx); dist1 += quantize_band_cost(s, &L[start + (w+w2)*128], L34, diff --git a/libavcodec/aacenc_ltp.c b/libavcodec/aacenc_ltp.c index b9d43b4..1bec85b 100644 --- a/libavcodec/aacenc_ltp.c +++ b/libavcodec/aacenc_ltp.c @@ -190,8 +190,8 @@ void ff_aac_search_for_ltp(AACEncContext *s, SingleChannelElement *sce, FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; for (i = 0; i < sce->ics.swb_sizes[g]; i++) PCD[i] = sce->coeffs[start+(w+w2)*128+i] - sce->lcoeffs[start+(w+w2)*128+i]; - abs_pow34_v(C34, &sce->coeffs[start+(w+w2)*128], sce->ics.swb_sizes[g]); - abs_pow34_v(PCD34, PCD, sce->ics.swb_sizes[g]); + s->abs_pow34(C34, &sce->coeffs[start+(w+w2)*128], sce->ics.swb_sizes[g]); + s->abs_pow34(PCD34, PCD, sce->ics.swb_sizes[g]); dist1 += quantize_band_cost(s, &sce->coeffs[start+(w+w2)*128], C34, sce->ics.swb_sizes[g], sce->sf_idx[(w+w2)*16+g], sce->band_type[(w+w2)*16+g], s->lambda/band->threshold, INFINITY, &bits_tmp1, NULL, 0); diff --git a/libavcodec/aacenc_pred.c b/libavcodec/aacenc_pred.c index e77a3de..d111192 100644 --- a/libavcodec/aacenc_pred.c +++ b/libavcodec/aacenc_pred.c @@ -270,7 +270,7 @@ void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce) continue; /* Normal coefficients */ - abs_pow34_v(O34, &sce->coeffs[start_coef], num_coeffs); + s->abs_pow34(O34, &sce->coeffs[start_coef], num_coeffs); dist1 = quantize_and_encode_band_cost(s, NULL, &sce->coeffs[start_coef], NULL, O34, num_coeffs, sce->sf_idx[sfb], cb_n, s->lambda / band->threshold, INFINITY, &cost1, NULL, 0); @@ -279,7 +279,7 @@ void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce) /* Encoded coefficients - needed for #bits, band type and quant. error */ for (i = 0; i < num_coeffs; i++) SENT[i] = sce->coeffs[start_coef + i] - sce->prcoeffs[start_coef + i]; - abs_pow34_v(S34, SENT, num_coeffs); + s->abs_pow34(S34, SENT, num_coeffs); if (cb_n < RESERVED_BT) cb_p = av_clip(find_min_book(find_max_val(1, num_coeffs, S34), sce->sf_idx[sfb]), cb_min, cb_max); else @@ -291,7 +291,7 @@ void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce) /* Reconstructed coefficients - needed for distortion measurements */ for (i = 0; i < num_coeffs; i++) sce->prcoeffs[start_coef + i] += QERR[i] != 0.0f ? (sce->prcoeffs[start_coef + i] - QERR[i]) : 0.0f; - abs_pow34_v(P34, &sce->prcoeffs[start_coef], num_coeffs); + s->abs_pow34(P34, &sce->prcoeffs[start_coef], num_coeffs); if (cb_n < RESERVED_BT) cb_p = av_clip(find_min_book(find_max_val(1, num_coeffs, P34), sce->sf_idx[sfb]), cb_min, cb_max); else diff --git a/libavcodec/aacenc_quantization.h b/libavcodec/aacenc_quantization.h index 4250407..fc5a46b 100644 --- a/libavcodec/aacenc_quantization.h +++ b/libavcodec/aacenc_quantization.h @@ -74,10 +74,10 @@ static av_always_inline float quantize_and_encode_band_cost_template( return cost * lambda; } if (!scaled) { - abs_pow34_v(s->scoefs, in, size); + s->abs_pow34(s->scoefs, in, size); scaled = s->scoefs; } - quantize_bands(s->qcoefs, in, scaled, size, Q34, !BT_UNSIGNED, aac_cb_maxval[cb], ROUNDING); + s->quant_bands(s->qcoefs, in, scaled, size, !BT_UNSIGNED, aac_cb_maxval[cb], Q34, ROUNDING); if (BT_UNSIGNED) { off = 0; } else { diff --git a/libavcodec/aacenc_utils.h b/libavcodec/aacenc_utils.h index ff9188a..f5cf77d 100644 --- a/libavcodec/aacenc_utils.h +++ b/libavcodec/aacenc_utils.h @@ -37,7 +37,7 @@ #define ROUND_TO_ZERO 0.1054f #define C_QUANT 0.4054f -static inline void abs_pow34_v(float *out, const float *in, const int size) +static inline void abs_pow34_v(float *out, const float *in, const int64_t size) { int i; for (i = 0; i < size; i++) { @@ -63,7 +63,7 @@ static inline int quant(float coef, const float Q, const float rounding) } static inline void quantize_bands(int *out, const float *in, const float *scaled, - int size, float Q34, int is_signed, int maxval, + int size, int is_signed, int maxval, const float Q34, const float rounding) { int i; diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 522b6c2..1db1137 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -42,6 +42,7 @@ OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o # decoders/encoders OBJS-$(CONFIG_AAC_DECODER) += x86/aacpsdsp_init.o \ x86/sbrdsp_init.o +OBJS-$(CONFIG_AAC_ENCODER) += x86/aacencdsp_init.o OBJS-$(CONFIG_ADPCM_G722_DECODER) += x86/g722dsp_init.o OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp_init.o OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp_init.o @@ -132,6 +133,7 @@ YASM-OBJS-$(CONFIG_VP8DSP) += x86/vp8dsp.o \ # decoders/encoders YASM-OBJS-$(CONFIG_AAC_DECODER) += x86/aacpsdsp.o \ x86/sbrdsp.o +YASM-OBJS-$(CONFIG_AAC_ENCODER) += x86/aacencdsp.o YASM-OBJS-$(CONFIG_ADPCM_G722_DECODER) += x86/g722dsp.o YASM-OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp.o YASM-OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp.o diff --git a/libavcodec/x86/aacencdsp.asm b/libavcodec/x86/aacencdsp.asm new file mode 100644 index 0000000..ff4019f --- /dev/null +++ b/libavcodec/x86/aacencdsp.asm @@ -0,0 +1,87 @@ +;****************************************************************************** +;* SIMD optimized AAC encoder DSP functions +;* +;* Copyright (C) 2016 Rostislav Pehlivanov +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +float_abs_mask: times 4 dd 0x7fffffff + +SECTION .text + +;******************************************************************* +;void ff_abs_pow34_sse(float *out, const float *in, const int64_t size); +;******************************************************************* +INIT_XMM sse +cglobal abs_pow34, 3, 3, 3, out, in, size + mova m2, [float_abs_mask] + shl sizeq, 2 + add inq, sizeq + add outq, sizeq + neg sizeq +.loop: + mova m0, [inq+sizeq] + andps m0, m2 + sqrtps m1, m0 + mulps m0, m1 + sqrtps m0, m0 + mova [outq+sizeq], m0 + add sizeq, mmsize + jl .loop + RET + +;******************************************************************* +;void ff_aac_quantize_bands_sse2(int *out, const float *in, const float *scaled, +; int size, int is_signed, int maxval, const float Q34, +; const float rounding) +;******************************************************************* +INIT_XMM sse2 +cglobal aac_quantize_bands, 6, 6, 6, out, in, scaled, size, is_signed, maxval, Q34, rounding +%if UNIX64 == 0 + movss m0, Q34m + movss m1, roundingm +%endif + SPLATD m0 + SPLATD m1 + cvtsi2ss m3, maxvald + SPLATD m3 + shl is_signedd, 31 + movd m4, is_signedd + SPLATD m4 + shl sizeq, 2 + add inq, sizeq + add outq, sizeq + add scaledq, sizeq + neg sizeq +.loop: + mova m2, [scaledq+sizeq] + mulps m2, m0 + addps m2, m1 + minps m2, m3 + mova m5, [inq+sizeq] + pand m5, m4 + orps m2, m5 + cvttps2dq m2, m2 + mova [outq+sizeq], m2 + add sizeq, mmsize + jl .loop + RET diff --git a/libavcodec/x86/aacencdsp_init.c b/libavcodec/x86/aacencdsp_init.c new file mode 100644 index 0000000..4b88ea6 --- /dev/null +++ b/libavcodec/x86/aacencdsp_init.c @@ -0,0 +1,43 @@ +/* + * AAC encoder assembly optimizations + * Copyright (C) 2016 Rostislav Pehlivanov + * + * 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 "config.h" + +#include "libavutil/float_dsp.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/aacenc.h" + +void ff_abs_pow34_sse(float *out, const float *in, const int64_t size); + +void ff_aac_quantize_bands_sse2(int *out, const float *in, const float *scaled, + int size, int is_signed, int maxval, const float Q34, + const float rounding); + +av_cold void ff_aac_dsp_init_x86(AACEncContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) + s->abs_pow34 = &ff_abs_pow34_sse; + + if (EXTERNAL_SSE2(cpu_flags)) + s->quant_bands = &ff_aac_quantize_bands_sse2; +} -- 2.9.3