From patchwork Fri Oct 7 20:25:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 38612 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:789c:b0:9c:c2cd:5584 with SMTP id bf28csp206128pzc; Fri, 7 Oct 2022 13:26:05 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5pNpNZsYXPdlZ4okbgKDB98fjPqiPnEExBjiX3abbjfOPvUl1My7w9RLlQdeQijJrPSVZr X-Received: by 2002:a05:6402:4003:b0:459:b859:ed09 with SMTP id d3-20020a056402400300b00459b859ed09mr6134054eda.135.1665174365748; Fri, 07 Oct 2022 13:26:05 -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 t10-20020a056402524a00b0043c19cd608dsi3480889edd.33.2022.10.07.13.26.05; Fri, 07 Oct 2022 13:26:05 -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=@outlook.com header.s=selector1 header.b=ihhSKN4T; arc=fail (body hash mismatch); 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=outlook.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A362B68BB63; Fri, 7 Oct 2022 23:25:36 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-oln040092072055.outbound.protection.outlook.com [40.92.72.55]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D6D8D68BBA7 for ; Fri, 7 Oct 2022 23:25:32 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ZtXBsJqtuRrSI/HDX9BXBDqDbDdUF7rdNwa0wv6mrM6FbGaEDqKJP4P+g+HSBWlB65F1pXHbo3L2S8qNE9vldpKmX6COdoCxLr0/v6O45Vooo6+tURmK0hhBybWMteNVNMscFmvryKvsp4ypp7EXDDUfrJsrOT5TB1IZbVN9+13dCFA3PazyZvo1rudNuovXUafvrCdkQa4cAAvyym/5+GRLfuj9nB6qzs1jvULSLo3fN4IEEYz79dw/+VaGk51+BY2Xmc7fO6pruLxMr9tXFa6SUbO9uOrgChVb1xfmeryl/ItWwdp92YnWBbC3dkj6DLGy8EgjAd/zYNcQL/7nbQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=P7NMgkcGJ7YsH/9H7oertYyx8jK4xWJS7IuQL3u3mF8=; b=DQS48O5VdFJ5EzbcRSHWFoFi4b4XmCFVk1Rq63M8wTgOy6quy94+5SsSnpgzCGSfYzTnhscgmpgVYcfje9FdCaBAySn7y6sN/i+OLrhlsyeyadpG9ZkcGgTf3Lk88tb+FnWQMfKkngIQrnpAgVlS1e8RXzzWz0zLl2VbMfqRwwm37yC/h2qc0qiS7T9GGC32+KcvY2+ArFNuShiGfMTLSZHHdfgzO5YD8ltHPdjyQO85t4ppgidGnI/tq1hd5r2ntf1DqKAT4F4EQESIWgDU0ea47AHj9tWiWdeNgR0kuUPoJl1nskUcSI6DKvZsJI6l3nVBP7E6rkx+6o2R0GodKA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=P7NMgkcGJ7YsH/9H7oertYyx8jK4xWJS7IuQL3u3mF8=; b=ihhSKN4Te2I882xKKODHvLdWUDPLcOYQDXqtGTI3qfYj3vEjI3kIn1hFLSxNkXP7IFPnFsLclenS/QU0gY127PDxRBoMyPcIa/pKnMHdjqtdKWBevjzL3I+XceQV3o4cROchorrWZCa31kLskRRCVGmY49iGnU/sMZGA7LkHYGQV86mrzVzHW3suVj4y3Vvnh9i0G7OMkfTPMFuHie2eNMrpcOiB7mdUH73ZYkgVgVbtguBmwojRlWdnjlK3h38kI1GqWm3Zl6CUdkSAb9j4OZX5OtIFl5XR6hTy7hSYGPOqYEIafNiadQObskAfKuQz64HELupQXD3/bsxhFr7jng== Received: from GV1P250MB0737.EURP250.PROD.OUTLOOK.COM (2603:10a6:150:8e::17) by DU2P250MB0285.EURP250.PROD.OUTLOOK.COM (2603:10a6:10:27a::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5709.15; Fri, 7 Oct 2022 20:25:28 +0000 Received: from GV1P250MB0737.EURP250.PROD.OUTLOOK.COM ([fe80::68bd:2fc7:ac52:38f8]) by GV1P250MB0737.EURP250.PROD.OUTLOOK.COM ([fe80::68bd:2fc7:ac52:38f8%9]) with mapi id 15.20.5676.028; Fri, 7 Oct 2022 20:25:28 +0000 From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Fri, 7 Oct 2022 22:25:06 +0200 Message-ID: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: X-TMN: [Ac5yFKmqiDKmoUeiu9+DguL+1MF2+rVsZ+6ykoutyX8=] X-ClientProxiedBy: ZR0P278CA0106.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:23::21) To GV1P250MB0737.EURP250.PROD.OUTLOOK.COM (2603:10a6:150:8e::17) X-Microsoft-Original-Message-ID: <20221007202508.4188148-6-andreas.rheinhardt@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV1P250MB0737:EE_|DU2P250MB0285:EE_ X-MS-Office365-Filtering-Correlation-Id: f01b748b-3ae7-456c-b5fb-08daa8a2130c X-MS-Exchange-SLBlob-MailProps: V85gaVfRD4+01U1U5L0H0p6VrfPRQyfW2BKY2hEq0iEmmggSmi8Hx4p0qeWuAntUmnrreAoRKYmCFCqw8q9cNfqcYcGwZeIufAF+a78UiagBXgT9ePpWzw1wGVXkJgLhu0sZ8ynWqmVEuPoijM78/zCMbDrBZwdVL6DcfBVkuzCVHS/7z0aVVDC0yh4bPKUmQp47XGkJABT0o4uoRlUK1kgjVKGCEcGEBpe3Ll2NCky7ORKLreWOMZoIjB1iITyVNIe5R1hYQpw3HZkxo2oasxxyAJvftxGWGQQoAO9sPqWBgyUkrKXGbQupiX3SoHtxFewDguCEkPkY/w4NP11n1IUxxDPP6KCUfuH2nsr3JwILiFq3ctlwauAGgTmX37Gh8QNJ6+AQgCVLm/1OplHUayrKgXuv9EXbejiXRKkHGrWqC+bNi0rGQ+dud9ce8wEcEAMKDg4HtRQWdtOx5I1dnvhFUl/8cXc0xhBa2iqLTkWS+3iV9UBbbz655rl/QP0TUUAhtM4JPzmYGhkZNinfvTQTCx6K6IMzsOkVz+w5tiDy+rUiuz64ocLw+9KOvJzsq6LBhDiKWD/BQuLaSYyZZcNZi2QnAf1aCLX7BaMDvR0KHVUOZtnfkn4IX4Wdcn82OjUFoZwgLpwSJmvxG27rHMyRGbIbM50jW+3/NLIlmSJSFtUZhDxnUhlRFjsEjP8KyIm/NLN45e78xYJcueBhhcwflvLGs/CW8wWBdP8h0DyYRrb1KwD83LbpM2BBRq6LeLFi6glkPE+crdpNTU+GD+sRXjRNwGAob9Bj5eY++8d/CBc8WJa5c2EcX8SV8T5SYtY3J+zDUye6w9Ec61K7NQ== X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Kg+RCSrFTER/BSU2sY1klt3dGWYZe0bBsEhg0DNIgJJ54P7HK2/Q7dE26no4/qT2+78T6o7PidwGpz+a62MNZ9x9T2j1oDCJ8RCNvuRNPlAC/zG5XgUXn7NDc0dTq+2SSaxUW/hgGnYG+yAEELmqFeDDgEDIPcGKarJ4HZ/zJKzRXf3cVklNfT2aMbkTfd8Z8SHsUALpmfqcJ6CiFn5C4qOxMSWzsSTt7u5EUIiHFtnnueomnn2qcwMb3qEJNbTzIzjF7EEzhiWRpYTlobRQ01byNbH2Y+H8ABlUC+Y9WjJgdkMnKaGHAefrryTiKRCrC8D+sH1MOLSqaq9R/NYVPtnmkqAg1/EpGlLMDbzwItlRvSJ4OF5/PveUZY3wXkU7rBYo12/HIpzN4IKa0vmlec+UFj8EHLKEkkUw11zuktTsOuiGCns2wq6x/GEM3WGLeYonQCWqCKFGfK2tBzhQOl2mv9+niLaNgOuseKjYqNK743RoO+9P8SeAb7frQNMY0nfu2cy2N1qMAsopBi9nZH/I3zzt5naQEsUChpEC+vaPxdstrXkfvBSIN/D53Ej9N8QqSd1c7twfEox0TVrKPmqpMjlO6mQkfLqB5b+wgl7ifD/IrbKlE98Fhk5QmAIN X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: C3IMjEkqLw9CostMpeO16+vhKBhVsSLTpVnvGdOKvbjFaiXL2SeGZFwW+pg+n/17UXizaZEMdGURa9KKpxEpBv2+FlJtCIs3yXtBv65B6mndVw92Wegv2dvXxZ6romMW2IyidmfeZOW5vDaV9GcM4K3IrsU1+/7Xf+ELM+qyAwI075wyDttetObUpNM84og78H0dth9XgFXc9NSjUsfS4k7ouE5ZYsLwr3FwwVMtzEXUjfgJjqMCPYzJlqgYaZOfR4Bd3sRf3oXOkLm43RosNjm0TQYHq6YoKhBsvs85BqMeUYYlQobg4XOENgw9m2DV/bJaJb8I4rXJ4YAVgypYIHAd/hRzliM2Rga0zpfD/W+XLI6AevdRGVWgTGxxtKdlS3H/XiiGez4TVPojzfLiGkU3njKkY/g2EUoKknFMFsXyipFQ/qwUdS+ZbgVEpOyh9z67oc62rkO8dKSaToKq9HydbN7RDtJo6TMOSq59K8Dy1biRSWQRp/mWv3LXox2zRz3EtCWSPnE8cvAw3Q7DnIAIv7UvbVrb30FXIf8pSfMYtQVMiC9RQyenzU27N80FkJbZpofV666vc1fIlLo+OXAAP4oweGf/NuF0WHUywRYuxZnaeb9Alz1ztz9aI2gQCuqPTWQb4n0myNp6DYdJlAt/Og34bEizvCD9B3PlAWuak0ns41Cxxx86uFLmSjmhSkgFBGTNBPxMl3NlAiQegZtokmuQWK+fzsaq31NwZJZVqWwr5FtU8Y6IOvfRv6Vbg+UPjkgp5y1hvuDEN5+/wLdM965V1O6NmVa5k8kGhNX7JN4UDYr2Eif/Ndk1jWHKpZFwMnWSqRwb9tY35DqYvmVMNbq2GKah33wslt21ByvLYNOAuO0mH7DQ46xW8hFulZdZTUu7oWRhrLK6DanljZA4B/y9AC+Vdtv0wdPxGX5aAJgNnCZBR5WZk4dvqIAVrQaK3J9DVq7X9+biUAQL7lTgsnIQeiaYr2+MZD7ofBmiEPv+NdrpX/qxe2p52oCVcne3MoQWGawpn6eOiHVC/m3pFqQQ3xpbq2NhJFo6TElDVWHcC5CfYjtHnHfhW4b4jfQ6Tea4/jPvNHfLdK7snHn2SYunbnXgNf2AZwLyidMNbLTPtE8dTeeezTRtns20yp/t9PMQ2tCT/eWkdQQpCb+15JDs9ylUaTwuvqou0W4I7G19eJM9jTtX53w8UIP45ALyszIaGcy6DNYs4hkBAmzJd/ivpGbb2k4hOvulbgxMD9lIwJYE1rc9kQN4FQ74wFE8BE4wqLjV119+G+iAVsTe3NlY6LF56eDDH8fKzys= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: f01b748b-3ae7-456c-b5fb-08daa8a2130c X-MS-Exchange-CrossTenant-AuthSource: GV1P250MB0737.EURP250.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Oct 2022 20:25:28.7082 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU2P250MB0285 Subject: [FFmpeg-devel] [PATCH 7/9] avcodec/opus_rc: Split de/encoder-only parts off OpusRangeContext 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: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: Ja6vWVv+B+WB The decoder currently only uses 72 bytes of 1376; furthermore, the GetBitContext in OpusRangeCoder is unused by the encoder, but its existence adds an unnecessary inclusion of get_bits.h to the encoder-only files. So split OpusRangeContext; also split opus_rc.c into an encoder- and a decoder-only part. This necessitated trivial changes in several other files. The only part where the changes where these changes were involved was opus_pvq.c, where the quant_band functions are now defined in a template file instead of being created via an av_always_inline function. Signed-off-by: Andreas Rheinhardt --- libavcodec/Makefile | 8 +- libavcodec/opus.c | 62 ++++- libavcodec/opus_celt.c | 39 +-- libavcodec/opus_celt.h | 3 +- libavcodec/opus_pvq.c | 456 +++------------------------------ libavcodec/opus_pvq_template.c | 432 +++++++++++++++++++++++++++++++ libavcodec/opus_rc.c | 409 ----------------------------- libavcodec/opus_rc.h | 66 ++--- libavcodec/opus_silk.c | 11 +- libavcodec/opus_silk.h | 4 +- libavcodec/opusdec.c | 11 +- libavcodec/opusdec_rc.c | 214 ++++++++++++++++ libavcodec/opusdec_rc.h | 53 ++++ libavcodec/opusenc.c | 39 +-- libavcodec/opusenc_psy.c | 14 +- libavcodec/opusenc_psy.h | 1 + libavcodec/opusenc_rc.c | 210 +++++++++++++++ libavcodec/opusenc_rc.h | 64 +++++ 18 files changed, 1139 insertions(+), 957 deletions(-) create mode 100644 libavcodec/opus_pvq_template.c delete mode 100644 libavcodec/opus_rc.c create mode 100644 libavcodec/opusdec_rc.c create mode 100644 libavcodec/opusdec_rc.h create mode 100644 libavcodec/opusenc_rc.c create mode 100644 libavcodec/opusenc_rc.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 592d9347f6..b7eb3b1e48 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -554,11 +554,11 @@ OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o OBJS-$(CONFIG_NOTCHLC_DECODER) += notchlc.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 \ +OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o \ opus_pvq.o opus_silk.o opustab.o vorbis_data.o \ - opusdsp.o opus_parse.o -OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus.o opus_rc.o opustab.o opus_pvq.o \ - opusenc_psy.o + opusdec_rc.o opusdsp.o opus_parse.o +OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus.o opusenc_psy.o \ + opusenc_rc.o opustab.o opus_pvq.o OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o diff --git a/libavcodec/opus.c b/libavcodec/opus.c index a24c38be52..8def5e6e34 100644 --- a/libavcodec/opus.c +++ b/libavcodec/opus.c @@ -21,9 +21,45 @@ #include +#include "config_components.h" #include "opus_celt.h" #include "opus_pvq.h" #include "opustab.h" +#include "opus_rc.h" +#include "opusdec_rc.h" +#include "opusenc_rc.h" + +#if !CONFIG_OPUS_ENCODER +#define ff_opus_rc_enc_log(...) +#define ff_opus_rc_enc_cdf(...) +#define ff_opus_rc_enc_uint(...) +#endif + +#if !CONFIG_OPUS_DECODER +#define ff_opus_rc_dec_log(...) 0 +#define ff_opus_rc_dec_cdf(...) 0 +#define ff_opus_rc_dec_uint(...) 0 +#endif + +static inline void opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits) +{ + ff_opus_rc_enc_log((OpusEncRangeCoder*)rc, val, bits); +} + +static inline uint32_t opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits) +{ + return ff_opus_rc_dec_log((OpusDecRangeCoder*)rc, bits); +} + +static inline void opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf) +{ + ff_opus_rc_enc_cdf((OpusEncRangeCoder*)rc, val, cdf); +} + +static inline uint32_t opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf) +{ + return ff_opus_rc_dec_cdf((OpusDecRangeCoder*)rc, cdf); +} void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc) { @@ -150,12 +186,14 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode) int bits1[CELT_MAX_BANDS]; int bits2[CELT_MAX_BANDS]; + if (!CONFIG_OPUS_DECODER || !CONFIG_OPUS_ENCODER) + encode = CONFIG_OPUS_ENCODER; /* Spread */ if (opus_rc_tell(rc) + 4 <= f->framebits) { if (encode) - ff_opus_rc_enc_cdf(rc, f->spread, ff_celt_model_spread); + opus_rc_enc_cdf(rc, f->spread, ff_celt_model_spread); else - f->spread = ff_opus_rc_dec_cdf(rc, ff_celt_model_spread); + f->spread = opus_rc_dec_cdf(rc, ff_celt_model_spread); } else { f->spread = CELT_SPREAD_NORMAL; } @@ -176,9 +214,9 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode) int is_boost; if (encode) { is_boost = boost_amount--; - ff_opus_rc_enc_log(rc, is_boost, b_dynalloc); + opus_rc_enc_log(rc, is_boost, b_dynalloc); } else { - is_boost = ff_opus_rc_dec_log(rc, b_dynalloc); + is_boost = opus_rc_dec_log(rc, b_dynalloc); } if (!is_boost) @@ -199,9 +237,9 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode) f->alloc_trim = 5; if (opus_rc_tell_frac(rc) + (6 << 3) <= tbits_8ths) if (encode) - ff_opus_rc_enc_cdf(rc, f->alloc_trim, ff_celt_model_alloc_trim); + opus_rc_enc_cdf(rc, f->alloc_trim, ff_celt_model_alloc_trim); else - f->alloc_trim = ff_opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim); + f->alloc_trim = opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim); /* Anti-collapse bit reservation */ tbits_8ths = (f->framebits << 3) - opus_rc_tell_frac(rc) - 1; @@ -358,9 +396,9 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode) int do_not_skip; if (encode) { do_not_skip = f->coded_bands <= f->skip_band_floor; - ff_opus_rc_enc_log(rc, do_not_skip, 1); + opus_rc_enc_log(rc, do_not_skip, 1); } else { - do_not_skip = ff_opus_rc_dec_log(rc, 1); + do_not_skip = opus_rc_dec_log(rc, 1); } if (do_not_skip) @@ -385,12 +423,12 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode) if (encode) { if (intensitystereo_bit) { f->intensity_stereo = FFMIN(f->intensity_stereo, f->coded_bands); - ff_opus_rc_enc_uint(rc, f->intensity_stereo, f->coded_bands + 1 - f->start_band); + ff_opus_rc_enc_uint((OpusEncRangeCoder*)rc, f->intensity_stereo, f->coded_bands + 1 - f->start_band); } } else { f->intensity_stereo = f->dual_stereo = 0; if (intensitystereo_bit) - f->intensity_stereo = f->start_band + ff_opus_rc_dec_uint(rc, f->coded_bands + 1 - f->start_band); + f->intensity_stereo = f->start_band + ff_opus_rc_dec_uint((OpusDecRangeCoder*)rc, f->coded_bands + 1 - f->start_band); } /* DS flag */ @@ -398,9 +436,9 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode) tbits_8ths += dualstereo_bit; /* no intensity stereo means no dual stereo */ else if (dualstereo_bit) if (encode) - ff_opus_rc_enc_log(rc, f->dual_stereo, 1); + opus_rc_enc_log(rc, f->dual_stereo, 1); else - f->dual_stereo = ff_opus_rc_dec_log(rc, 1); + f->dual_stereo = opus_rc_dec_log(rc, 1); /* Supply the remaining bits in this frame to lower bands */ remaining = tbits_8ths - total; diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c index c2904cc9e0..a14764ec18 100644 --- a/libavcodec/opus_celt.c +++ b/libavcodec/opus_celt.c @@ -28,12 +28,13 @@ #include #include "opus_celt.h" +#include "opusdec_rc.h" #include "opustab.h" #include "opus_pvq.h" /* Use the 2D z-transform to apply prediction in both the time domain (alpha) * and the frequency domain (beta) */ -static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc) +static void celt_decode_coarse_energy(CeltFrame *f, OpusDecRangeCoder *rc) { int i, j; float prev[2] = { 0 }; @@ -42,7 +43,7 @@ static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc) const uint8_t *model = ff_celt_coarse_energy_dist[f->size][0]; /* intra frame */ - if (opus_rc_tell(rc) + 3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) { + if (opus_rc_tell(&rc->c) + 3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) { alpha = 0.0f; beta = 1.0f - (4915.0f/32768.0f); model = ff_celt_coarse_energy_dist[f->size][1]; @@ -59,7 +60,7 @@ static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc) continue; } - available = f->framebits - opus_rc_tell(rc); + available = f->framebits - opus_rc_tell(&rc->c); if (available >= 15) { /* decode using a Laplace distribution */ int k = FFMIN(i, 20) << 1; @@ -77,7 +78,7 @@ static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc) } } -static void celt_decode_fine_energy(CeltFrame *f, OpusRangeCoder *rc) +static void celt_decode_fine_energy(CeltFrame *f, OpusDecRangeCoder *rc) { int i; for (i = f->start_band; i < f->end_band; i++) { @@ -96,10 +97,10 @@ static void celt_decode_fine_energy(CeltFrame *f, OpusRangeCoder *rc) } } -static void celt_decode_final_energy(CeltFrame *f, OpusRangeCoder *rc) +static void celt_decode_final_energy(CeltFrame *f, OpusDecRangeCoder *rc) { int priority, i, j; - int bits_left = f->framebits - opus_rc_tell(rc); + int bits_left = f->framebits - opus_rc_tell(&rc->c); for (priority = 0; priority < 2; priority++) { for (i = f->start_band; i < f->end_band && bits_left >= f->channels; i++) { @@ -118,18 +119,18 @@ static void celt_decode_final_energy(CeltFrame *f, OpusRangeCoder *rc) } } -static void celt_decode_tf_changes(CeltFrame *f, OpusRangeCoder *rc) +static void celt_decode_tf_changes(CeltFrame *f, OpusDecRangeCoder *rc) { int i, diff = 0, tf_select = 0, tf_changed = 0, tf_select_bit; int consumed, bits = f->transient ? 2 : 4; - consumed = opus_rc_tell(rc); + consumed = opus_rc_tell(&rc->c); tf_select_bit = (f->size != 0 && consumed+bits+1 <= f->framebits); for (i = f->start_band; i < f->end_band; i++) { if (consumed+bits+tf_select_bit <= f->framebits) { diff ^= ff_opus_rc_dec_log(rc, bits); - consumed = opus_rc_tell(rc); + consumed = opus_rc_tell(&rc->c); tf_changed |= diff; } f->tf_change[i] = diff; @@ -232,7 +233,7 @@ static void celt_postfilter(CeltFrame *f, CeltBlock *block) memmove(block->buf, block->buf + len, (1024 + CELT_OVERLAP / 2) * sizeof(float)); } -static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed) +static int parse_postfilter(CeltFrame *f, OpusDecRangeCoder *rc, int consumed) { int i; @@ -248,7 +249,7 @@ static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed) octave = ff_opus_rc_dec_uint(rc, 6); period = (16 << octave) + ff_opus_rc_get_raw(rc, 4 + octave) - 1; gain = 0.09375f * (ff_opus_rc_get_raw(rc, 3) + 1); - tapset = (opus_rc_tell(rc) + 2 <= f->framebits) ? + tapset = (opus_rc_tell(&rc->c) + 2 <= f->framebits) ? ff_opus_rc_dec_cdf(rc, ff_celt_model_tapset) : 0; for (i = 0; i < 2; i++) { @@ -261,7 +262,7 @@ static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed) } } - consumed = opus_rc_tell(rc); + consumed = opus_rc_tell(&rc->c); } return consumed; @@ -319,7 +320,7 @@ static void process_anticollapse(CeltFrame *f, CeltBlock *block, float *X) } } -int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, +int ff_celt_decode_frame(CeltFrame *f, OpusDecRangeCoder *rc, float **output, int channels, int frame_size, int start_band, int end_band) { @@ -346,7 +347,7 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, f->channels = channels; f->start_band = start_band; f->end_band = end_band; - f->framebits = rc->rb.bytes * 8; + f->framebits = rc->c.rb.bytes * 8; f->size = av_log2(frame_size / CELT_SHORT_BLOCKSIZE); if (f->size > CELT_MAX_LOG_BLOCKS || @@ -364,7 +365,7 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, memset(f->block[i].collapse_masks, 0, sizeof(f->block[i].collapse_masks)); } - consumed = opus_rc_tell(rc); + consumed = opus_rc_tell(&rc->c); /* obtain silence flag */ if (consumed >= f->framebits) @@ -375,7 +376,7 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, if (f->silence) { consumed = f->framebits; - rc->total_bits += f->framebits - opus_rc_tell(rc); + rc->c.total_bits += f->framebits - opus_rc_tell(&rc->c); } /* obtain post-filter options */ @@ -398,9 +399,9 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, celt_decode_coarse_energy(f, rc); celt_decode_tf_changes (f, rc); - ff_celt_bitalloc (f, rc, 0); + ff_celt_bitalloc (f, &rc->c, 0); celt_decode_fine_energy (f, rc); - ff_celt_quant_bands (f, rc); + ff_celt_quant_bands (f, &rc->c); if (f->anticollapse_needed) f->anticollapse = ff_opus_rc_get_raw(rc, 1); @@ -486,7 +487,7 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, } } - f->seed = rc->range; + f->seed = rc->c.range; return 0; } diff --git a/libavcodec/opus_celt.h b/libavcodec/opus_celt.h index 2dbb79be6c..beb6abd55d 100644 --- a/libavcodec/opus_celt.h +++ b/libavcodec/opus_celt.h @@ -171,7 +171,8 @@ void ff_celt_free(CeltFrame **f); void ff_celt_flush(CeltFrame *f); -int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, float **output, +struct OpusDecRangeCoder; +int ff_celt_decode_frame(CeltFrame *f, struct OpusDecRangeCoder *rc, float **output, int coded_channels, int frame_size, int startband, int endband); /* Encode or decode CELT bands */ diff --git a/libavcodec/opus_pvq.c b/libavcodec/opus_pvq.c index d08dcd7413..8ef0f85a81 100644 --- a/libavcodec/opus_pvq.c +++ b/libavcodec/opus_pvq.c @@ -30,6 +30,9 @@ #include "mathops.h" #include "opustab.h" #include "opus_pvq.h" +#include "opus_rc.h" +#include "opusdec_rc.h" +#include "opusenc_rc.h" #define ROUND_MUL16(a,b) ((MUL16(a, b) + 16384) >> 15) @@ -355,18 +358,12 @@ static inline uint64_t celt_cwrsi(uint32_t N, uint32_t K, uint32_t i, int *y) return norm; } -static inline void celt_encode_pulses(OpusRangeCoder *rc, int *y, uint32_t N, uint32_t K) +#if CONFIG_OPUS_ENCODER +static inline void celt_encode_pulses(OpusEncRangeCoder *rc, int *y, uint32_t N, uint32_t K) { ff_opus_rc_enc_uint(rc, celt_icwrsi(N, K, y), CELT_PVQ_V(N, K)); } -static inline float celt_decode_pulses(OpusRangeCoder *rc, int *y, uint32_t N, uint32_t K) -{ - const uint32_t idx = ff_opus_rc_dec_uint(rc, CELT_PVQ_V(N, K)); - return celt_cwrsi(N, K, idx, y); -} - -#if CONFIG_OPUS_ENCODER /* * Faster than libopus's search, operates entirely in the signed domain. * Slightly worse/better depending on N, K and the input vector. @@ -419,9 +416,8 @@ static float ppp_pvq_search_c(float *X, int *y, int K, int N) return (float)y_norm; } -#endif -static uint32_t celt_alg_quant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_t K, +static uint32_t celt_alg_quant(OpusEncRangeCoder *rc, float *X, uint32_t N, uint32_t K, enum CeltSpread spread, uint32_t blocks, float gain, CeltPVQ *pvq) { @@ -434,10 +430,18 @@ static uint32_t celt_alg_quant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_ celt_exp_rotation(X, N, blocks, K, spread, 0); return celt_extract_collapse_mask(y, N, blocks); } +#endif + +#if CONFIG_OPUS_DECODER +static inline float celt_decode_pulses(OpusDecRangeCoder *rc, int *y, uint32_t N, uint32_t K) +{ + const uint32_t idx = ff_opus_rc_dec_uint(rc, CELT_PVQ_V(N, K)); + return celt_cwrsi(N, K, idx, y); +} /** Decode pulse vector and combine the result with the pitch vector to produce the final normalised signal in the current band. */ -static uint32_t celt_alg_unquant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_t K, +static uint32_t celt_alg_unquant(OpusDecRangeCoder *rc, float *X, uint32_t N, uint32_t K, enum CeltSpread spread, uint32_t blocks, float gain, CeltPVQ *pvq) { @@ -448,6 +452,7 @@ static uint32_t celt_alg_unquant(OpusRangeCoder *rc, float *X, uint32_t N, uint3 celt_exp_rotation(X, N, blocks, K, spread, 0); return celt_extract_collapse_mask(y, N, blocks); } +#endif static int celt_calc_theta(const float *X, const float *Y, int coupling, int N) { @@ -467,6 +472,7 @@ static int celt_calc_theta(const float *X, const float *Y, int coupling, int N) return lrintf(32768.0f*atan2f(sqrtf(e[1]), sqrtf(e[0]))/M_PI); } +#if CONFIG_OPUS_ENCODER static void celt_stereo_is_decouple(float *X, float *Y, float e_l, float e_r, int N) { int i; @@ -487,421 +493,15 @@ static void celt_stereo_ms_decouple(float *X, float *Y, int N) } } -static av_always_inline uint32_t quant_band_template(CeltPVQ *pvq, CeltFrame *f, - OpusRangeCoder *rc, - const int band, float *X, - float *Y, int N, int b, - uint32_t blocks, float *lowband, - int duration, float *lowband_out, - int level, float gain, - float *lowband_scratch, - int fill, int quant) -{ - int i; - const uint8_t *cache; - int stereo = !!Y, split = stereo; - int imid = 0, iside = 0; - uint32_t N0 = N; - int N_B = N / blocks; - int N_B0 = N_B; - int B0 = blocks; - int time_divide = 0; - int recombine = 0; - int inv = 0; - float mid = 0, side = 0; - int longblocks = (B0 == 1); - uint32_t cm = 0; - - if (N == 1) { - float *x = X; - for (i = 0; i <= stereo; i++) { - int sign = 0; - if (f->remaining2 >= 1 << 3) { - if (quant) { - sign = x[0] < 0; - ff_opus_rc_put_raw(rc, sign, 1); - } else { - sign = ff_opus_rc_get_raw(rc, 1); - } - f->remaining2 -= 1 << 3; - } - x[0] = 1.0f - 2.0f*sign; - x = Y; - } - if (lowband_out) - lowband_out[0] = X[0]; - return 1; - } - - if (!stereo && level == 0) { - int tf_change = f->tf_change[band]; - int k; - if (tf_change > 0) - recombine = tf_change; - /* Band recombining to increase frequency resolution */ - - if (lowband && - (recombine || ((N_B & 1) == 0 && tf_change < 0) || B0 > 1)) { - for (i = 0; i < N; i++) - lowband_scratch[i] = lowband[i]; - lowband = lowband_scratch; - } - - for (k = 0; k < recombine; k++) { - if (quant || lowband) - celt_haar1(quant ? X : lowband, N >> k, 1 << k); - fill = ff_celt_bit_interleave[fill & 0xF] | ff_celt_bit_interleave[fill >> 4] << 2; - } - blocks >>= recombine; - N_B <<= recombine; - - /* Increasing the time resolution */ - while ((N_B & 1) == 0 && tf_change < 0) { - if (quant || lowband) - celt_haar1(quant ? X : lowband, N_B, blocks); - fill |= fill << blocks; - blocks <<= 1; - N_B >>= 1; - time_divide++; - tf_change++; - } - B0 = blocks; - N_B0 = N_B; - - /* Reorganize the samples in time order instead of frequency order */ - if (B0 > 1 && (quant || lowband)) - celt_deinterleave_hadamard(pvq->hadamard_tmp, quant ? X : lowband, - N_B >> recombine, B0 << recombine, - longblocks); - } - - /* If we need 1.5 more bit than we can produce, split the band in two. */ - cache = ff_celt_cache_bits + - ff_celt_cache_index[(duration + 1) * CELT_MAX_BANDS + band]; - if (!stereo && duration >= 0 && b > cache[cache[0]] + 12 && N > 2) { - N >>= 1; - Y = X + N; - split = 1; - duration -= 1; - if (blocks == 1) - fill = (fill & 1) | (fill << 1); - blocks = (blocks + 1) >> 1; - } - - if (split) { - int qn; - int itheta = quant ? celt_calc_theta(X, Y, stereo, N) : 0; - int mbits, sbits, delta; - int qalloc; - int pulse_cap; - int offset; - int orig_fill; - int tell; - - /* Decide on the resolution to give to the split parameter theta */ - pulse_cap = ff_celt_log_freq_range[band] + duration * 8; - offset = (pulse_cap >> 1) - (stereo && N == 2 ? CELT_QTHETA_OFFSET_TWOPHASE : - CELT_QTHETA_OFFSET); - qn = (stereo && band >= f->intensity_stereo) ? 1 : - celt_compute_qn(N, b, offset, pulse_cap, stereo); - tell = opus_rc_tell_frac(rc); - if (qn != 1) { - if (quant) - itheta = (itheta*qn + 8192) >> 14; - /* Entropy coding of the angle. We use a uniform pdf for the - * time split, a step for stereo, and a triangular one for the rest. */ - if (quant) { - if (stereo && N > 2) - ff_opus_rc_enc_uint_step(rc, itheta, qn / 2); - else if (stereo || B0 > 1) - ff_opus_rc_enc_uint(rc, itheta, qn + 1); - else - ff_opus_rc_enc_uint_tri(rc, itheta, qn); - itheta = itheta * 16384 / qn; - if (stereo) { - if (itheta == 0) - celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band], - f->block[1].lin_energy[band], N); - else - celt_stereo_ms_decouple(X, Y, N); - } - } else { - if (stereo && N > 2) - itheta = ff_opus_rc_dec_uint_step(rc, qn / 2); - else if (stereo || B0 > 1) - itheta = ff_opus_rc_dec_uint(rc, qn+1); - else - itheta = ff_opus_rc_dec_uint_tri(rc, qn); - itheta = itheta * 16384 / qn; - } - } else if (stereo) { - if (quant) { - inv = f->apply_phase_inv ? itheta > 8192 : 0; - if (inv) { - for (i = 0; i < N; i++) - Y[i] *= -1; - } - celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band], - f->block[1].lin_energy[band], N); - - if (b > 2 << 3 && f->remaining2 > 2 << 3) { - ff_opus_rc_enc_log(rc, inv, 2); - } else { - inv = 0; - } - } else { - inv = (b > 2 << 3 && f->remaining2 > 2 << 3) ? ff_opus_rc_dec_log(rc, 2) : 0; - inv = f->apply_phase_inv ? inv : 0; - } - itheta = 0; - } - qalloc = opus_rc_tell_frac(rc) - tell; - b -= qalloc; - - orig_fill = fill; - if (itheta == 0) { - imid = 32767; - iside = 0; - fill = av_mod_uintp2(fill, blocks); - delta = -16384; - } else if (itheta == 16384) { - imid = 0; - iside = 32767; - fill &= ((1 << blocks) - 1) << blocks; - delta = 16384; - } else { - imid = celt_cos(itheta); - iside = celt_cos(16384-itheta); - /* This is the mid vs side allocation that minimizes squared error - in that band. */ - delta = ROUND_MUL16((N - 1) << 7, celt_log2tan(iside, imid)); - } - - mid = imid / 32768.0f; - side = iside / 32768.0f; - - /* This is a special case for N=2 that only works for stereo and takes - advantage of the fact that mid and side are orthogonal to encode - the side with just one bit. */ - if (N == 2 && stereo) { - int c; - int sign = 0; - float tmp; - float *x2, *y2; - mbits = b; - /* Only need one bit for the side */ - sbits = (itheta != 0 && itheta != 16384) ? 1 << 3 : 0; - mbits -= sbits; - c = (itheta > 8192); - f->remaining2 -= qalloc+sbits; - - x2 = c ? Y : X; - y2 = c ? X : Y; - if (sbits) { - if (quant) { - sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; - ff_opus_rc_put_raw(rc, sign, 1); - } else { - sign = ff_opus_rc_get_raw(rc, 1); - } - } - sign = 1 - 2 * sign; - /* We use orig_fill here because we want to fold the side, but if - itheta==16384, we'll have cleared the low bits of fill. */ - cm = pvq->quant_band(pvq, f, rc, band, x2, NULL, N, mbits, blocks, lowband, duration, - lowband_out, level, gain, lowband_scratch, orig_fill); - /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), - and there's no need to worry about mixing with the other channel. */ - y2[0] = -sign * x2[1]; - y2[1] = sign * x2[0]; - X[0] *= mid; - X[1] *= mid; - Y[0] *= side; - Y[1] *= side; - tmp = X[0]; - X[0] = tmp - Y[0]; - Y[0] = tmp + Y[0]; - tmp = X[1]; - X[1] = tmp - Y[1]; - Y[1] = tmp + Y[1]; - } else { - /* "Normal" split code */ - float *next_lowband2 = NULL; - float *next_lowband_out1 = NULL; - int next_level = 0; - int rebalance; - uint32_t cmt; - - /* Give more bits to low-energy MDCTs than they would - * otherwise deserve */ - if (B0 > 1 && !stereo && (itheta & 0x3fff)) { - if (itheta > 8192) - /* Rough approximation for pre-echo masking */ - delta -= delta >> (4 - duration); - else - /* Corresponds to a forward-masking slope of - * 1.5 dB per 10 ms */ - delta = FFMIN(0, delta + (N << 3 >> (5 - duration))); - } - mbits = av_clip((b - delta) / 2, 0, b); - sbits = b - mbits; - f->remaining2 -= qalloc; - - if (lowband && !stereo) - next_lowband2 = lowband + N; /* >32-bit split case */ - - /* Only stereo needs to pass on lowband_out. - * Otherwise, it's handled at the end */ - if (stereo) - next_lowband_out1 = lowband_out; - else - next_level = level + 1; - - rebalance = f->remaining2; - if (mbits >= sbits) { - /* In stereo mode, we do not apply a scaling to the mid - * because we need the normalized mid for folding later */ - cm = pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks, - lowband, duration, next_lowband_out1, next_level, - stereo ? 1.0f : (gain * mid), lowband_scratch, fill); - rebalance = mbits - (rebalance - f->remaining2); - if (rebalance > 3 << 3 && itheta != 0) - sbits += rebalance - (3 << 3); - - /* For a stereo split, the high bits of fill are always zero, - * so no folding will be done to the side. */ - cmt = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks, - next_lowband2, duration, NULL, next_level, - gain * side, NULL, fill >> blocks); - cm |= cmt << ((B0 >> 1) & (stereo - 1)); - } else { - /* For a stereo split, the high bits of fill are always zero, - * so no folding will be done to the side. */ - cm = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks, - next_lowband2, duration, NULL, next_level, - gain * side, NULL, fill >> blocks); - cm <<= ((B0 >> 1) & (stereo - 1)); - rebalance = sbits - (rebalance - f->remaining2); - if (rebalance > 3 << 3 && itheta != 16384) - mbits += rebalance - (3 << 3); - - /* In stereo mode, we do not apply a scaling to the mid because - * we need the normalized mid for folding later */ - cm |= pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks, - lowband, duration, next_lowband_out1, next_level, - stereo ? 1.0f : (gain * mid), lowband_scratch, fill); - } - } - } else { - /* This is the basic no-split case */ - uint32_t q = celt_bits2pulses(cache, b); - uint32_t curr_bits = celt_pulses2bits(cache, q); - f->remaining2 -= curr_bits; - - /* Ensures we can never bust the budget */ - while (f->remaining2 < 0 && q > 0) { - f->remaining2 += curr_bits; - curr_bits = celt_pulses2bits(cache, --q); - f->remaining2 -= curr_bits; - } - - if (q != 0) { - /* Finally do the actual (de)quantization */ - if (quant) { - cm = celt_alg_quant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1), - f->spread, blocks, gain, pvq); - } else { - cm = celt_alg_unquant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1), - f->spread, blocks, gain, pvq); - } - } else { - /* If there's no pulse, fill the band anyway */ - uint32_t cm_mask = (1 << blocks) - 1; - fill &= cm_mask; - if (fill) { - if (!lowband) { - /* Noise */ - for (i = 0; i < N; i++) - X[i] = (((int32_t)celt_rng(f)) >> 20); - cm = cm_mask; - } else { - /* Folded spectrum */ - for (i = 0; i < N; i++) { - /* About 48 dB below the "normal" folding level */ - X[i] = lowband[i] + (((celt_rng(f)) & 0x8000) ? 1.0f / 256 : -1.0f / 256); - } - cm = fill; - } - celt_renormalize_vector(X, N, gain); - } else { - memset(X, 0, N*sizeof(float)); - } - } - } - - /* This code is used by the decoder and by the resynthesis-enabled encoder */ - if (stereo) { - if (N > 2) - celt_stereo_merge(X, Y, mid, N); - if (inv) { - for (i = 0; i < N; i++) - Y[i] *= -1; - } - } else if (level == 0) { - int k; - - /* Undo the sample reorganization going from time order to frequency order */ - if (B0 > 1) - celt_interleave_hadamard(pvq->hadamard_tmp, X, N_B >> recombine, - B0 << recombine, longblocks); - - /* Undo time-freq changes that we did earlier */ - N_B = N_B0; - blocks = B0; - for (k = 0; k < time_divide; k++) { - blocks >>= 1; - N_B <<= 1; - cm |= cm >> blocks; - celt_haar1(X, N_B, blocks); - } - - for (k = 0; k < recombine; k++) { - cm = ff_celt_bit_deinterleave[cm]; - celt_haar1(X, N0>>k, 1<quant_band = encode ? pvq_encode_band : pvq_decode_band; - #if CONFIG_OPUS_ENCODER +#if CONFIG_OPUS_DECODER + s->quant_band = encode ? pvq_quant_band_enc : pvq_quant_band_dec; +#else + s->quant_band = pvq_quant_band_enc; +#endif s->pvq_search = ppp_pvq_search_c; #if ARCH_X86 ff_celt_pvq_init_x86(s); #endif +#else + s->quant_band = pvq_quant_band_dec; + s->pvq_search = NULL; #endif *pvq = s; diff --git a/libavcodec/opus_pvq_template.c b/libavcodec/opus_pvq_template.c new file mode 100644 index 0000000000..5f03f3d415 --- /dev/null +++ b/libavcodec/opus_pvq_template.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2007-2008 CSIRO + * Copyright (c) 2007-2009 Xiph.Org Foundation + * Copyright (c) 2008-2009 Gregory Maxwell + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2017 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 + */ + +#undef FUNC + +#if ENCODING +#define FUNC(name) name ## _enc +#else +#define FUNC(name) name ## _dec +#endif + +static +uint32_t FUNC(pvq_quant_band)(CeltPVQ *const pvq, CeltFrame *const f, + OpusRangeCoder *const rc, + const int band, float *X, + float *Y, int N, int b, + uint32_t blocks, float *lowband, + int duration, float *lowband_out, + int level, float gain, + float *lowband_scratch, + int fill) +{ +#if ENCODING + OpusEncRangeCoder *const rce = (OpusEncRangeCoder*)rc; +#else + OpusDecRangeCoder *const rcd = (OpusDecRangeCoder*)rc; +#endif + const uint8_t *cache; + int stereo = !!Y, split = stereo; + uint32_t N0 = N; + int N_B = N / blocks; + int N_B0 = N_B; + int B0 = blocks; + int time_divide = 0; + int recombine = 0; + int inv = 0; + float mid = 0, side = 0; + int longblocks = (B0 == 1); + uint32_t cm = 0; + + if (N == 1) { + float *x = X; + for (int i = 0; i <= stereo; i++) { + int sign = 0; + if (f->remaining2 >= 1 << 3) { +#if ENCODING + sign = x[0] < 0; + ff_opus_rc_put_raw(rce, sign, 1); +#else + sign = ff_opus_rc_get_raw(rcd, 1); +#endif + f->remaining2 -= 1 << 3; + } + x[0] = 1.0f - 2.0f*sign; + x = Y; + } + if (lowband_out) + lowband_out[0] = X[0]; + return 1; + } + + if (!stereo && level == 0) { + int tf_change = f->tf_change[band]; + int k; + if (tf_change > 0) + recombine = tf_change; + /* Band recombining to increase frequency resolution */ + + if (lowband && + (recombine || ((N_B & 1) == 0 && tf_change < 0) || B0 > 1)) { + for (int i = 0; i < N; i++) + lowband_scratch[i] = lowband[i]; + lowband = lowband_scratch; + } + + for (k = 0; k < recombine; k++) { + if (ENCODING || lowband) + celt_haar1(ENCODING ? X : lowband, N >> k, 1 << k); + fill = ff_celt_bit_interleave[fill & 0xF] | ff_celt_bit_interleave[fill >> 4] << 2; + } + blocks >>= recombine; + N_B <<= recombine; + + /* Increasing the time resolution */ + while ((N_B & 1) == 0 && tf_change < 0) { + if (ENCODING || lowband) + celt_haar1(ENCODING ? X : lowband, N_B, blocks); + fill |= fill << blocks; + blocks <<= 1; + N_B >>= 1; + time_divide++; + tf_change++; + } + B0 = blocks; + N_B0 = N_B; + + /* Reorganize the samples in time order instead of frequency order */ + if (B0 > 1 && (ENCODING || lowband)) + celt_deinterleave_hadamard(pvq->hadamard_tmp, ENCODING ? X : lowband, + N_B >> recombine, B0 << recombine, + longblocks); + } + + /* If we need 1.5 more bit than we can produce, split the band in two. */ + cache = ff_celt_cache_bits + + ff_celt_cache_index[(duration + 1) * CELT_MAX_BANDS + band]; + if (!stereo && duration >= 0 && b > cache[cache[0]] + 12 && N > 2) { + N >>= 1; + Y = X + N; + split = 1; + duration -= 1; + if (blocks == 1) + fill = (fill & 1) | (fill << 1); + blocks = (blocks + 1) >> 1; + } + + if (split) { + int qn; + int itheta = ENCODING ? celt_calc_theta(X, Y, stereo, N) : 0; + int mbits, sbits, delta; + int imid = 0, iside = 0; + int qalloc; + int pulse_cap; + int offset; + int orig_fill; + int tell; + + /* Decide on the resolution to give to the split parameter theta */ + pulse_cap = ff_celt_log_freq_range[band] + duration * 8; + offset = (pulse_cap >> 1) - (stereo && N == 2 ? CELT_QTHETA_OFFSET_TWOPHASE : + CELT_QTHETA_OFFSET); + qn = (stereo && band >= f->intensity_stereo) ? 1 : + celt_compute_qn(N, b, offset, pulse_cap, stereo); + tell = opus_rc_tell_frac(rc); + if (qn != 1) { +#if ENCODING + itheta = (itheta * qn + 8192) >> 14; + /* Entropy coding of the angle. We use a uniform pdf for the + * time split, a step for stereo, and a triangular one for the rest. */ + if (stereo && N > 2) + ff_opus_rc_enc_uint_step(rce, itheta, qn / 2); + else if (stereo || B0 > 1) + ff_opus_rc_enc_uint(rce, itheta, qn + 1); + else + ff_opus_rc_enc_uint_tri(rce, itheta, qn); + itheta = itheta * 16384 / qn; + if (stereo) { + if (itheta == 0) + celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band], + f->block[1].lin_energy[band], N); + else + celt_stereo_ms_decouple(X, Y, N); + } +#else + if (stereo && N > 2) + itheta = ff_opus_rc_dec_uint_step(rcd, qn / 2); + else if (stereo || B0 > 1) + itheta = ff_opus_rc_dec_uint(rcd, qn+1); + else + itheta = ff_opus_rc_dec_uint_tri(rcd, qn); + itheta = itheta * 16384 / qn; +#endif + } else if (stereo) { +#if ENCODING + inv = f->apply_phase_inv ? itheta > 8192 : 0; + if (inv) { + for (int i = 0; i < N; i++) + Y[i] *= -1; + } + celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band], + f->block[1].lin_energy[band], N); + + if (b > 2 << 3 && f->remaining2 > 2 << 3) { + ff_opus_rc_enc_log(rce, inv, 2); + } else { + inv = 0; + } +#else + inv = (b > 2 << 3 && f->remaining2 > 2 << 3) ? ff_opus_rc_dec_log(rcd, 2) : 0; + inv = f->apply_phase_inv ? inv : 0; +#endif + itheta = 0; + } + qalloc = opus_rc_tell_frac(rc) - tell; + b -= qalloc; + + orig_fill = fill; + if (itheta == 0) { + imid = 32767; + iside = 0; + fill = av_mod_uintp2(fill, blocks); + delta = -16384; + } else if (itheta == 16384) { + imid = 0; + iside = 32767; + fill &= ((1 << blocks) - 1) << blocks; + delta = 16384; + } else { + imid = celt_cos(itheta); + iside = celt_cos(16384 - itheta); + /* This is the mid vs side allocation that minimizes squared error + in that band. */ + delta = ROUND_MUL16((N - 1) << 7, celt_log2tan(iside, imid)); + } + + mid = imid / 32768.0f; + side = iside / 32768.0f; + + /* This is a special case for N=2 that only works for stereo and takes + advantage of the fact that mid and side are orthogonal to encode + the side with just one bit. */ + if (N == 2 && stereo) { + int c; + int sign = 0; + float tmp; + float *x2, *y2; + mbits = b; + /* Only need one bit for the side */ + sbits = (itheta != 0 && itheta != 16384) ? 1 << 3 : 0; + mbits -= sbits; + c = (itheta > 8192); + f->remaining2 -= qalloc + sbits; + + x2 = c ? Y : X; + y2 = c ? X : Y; + if (sbits) { +#if ENCODING + sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; + ff_opus_rc_put_raw(rce, sign, 1); +#else + sign = ff_opus_rc_get_raw(rcd, 1); +#endif + } + sign = 1 - 2 * sign; + /* We use orig_fill here because we want to fold the side, but if + itheta==16384, we'll have cleared the low bits of fill. */ + cm = pvq->quant_band(pvq, f, rc, band, x2, NULL, N, mbits, blocks, lowband, duration, + lowband_out, level, gain, lowband_scratch, orig_fill); + /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), + and there's no need to worry about mixing with the other channel. */ + y2[0] = -sign * x2[1]; + y2[1] = sign * x2[0]; + X[0] *= mid; + X[1] *= mid; + Y[0] *= side; + Y[1] *= side; + tmp = X[0]; + X[0] = tmp - Y[0]; + Y[0] = tmp + Y[0]; + tmp = X[1]; + X[1] = tmp - Y[1]; + Y[1] = tmp + Y[1]; + } else { + /* "Normal" split code */ + float *next_lowband2 = NULL; + float *next_lowband_out1 = NULL; + int next_level = 0; + int rebalance; + uint32_t cmt; + + /* Give more bits to low-energy MDCTs than they would + * otherwise deserve */ + if (B0 > 1 && !stereo && (itheta & 0x3fff)) { + if (itheta > 8192) + /* Rough approximation for pre-echo masking */ + delta -= delta >> (4 - duration); + else + /* Corresponds to a forward-masking slope of + * 1.5 dB per 10 ms */ + delta = FFMIN(0, delta + (N << 3 >> (5 - duration))); + } + mbits = av_clip((b - delta) / 2, 0, b); + sbits = b - mbits; + f->remaining2 -= qalloc; + + if (lowband && !stereo) + next_lowband2 = lowband + N; /* >32-bit split case */ + + /* Only stereo needs to pass on lowband_out. + * Otherwise, it's handled at the end */ + if (stereo) + next_lowband_out1 = lowband_out; + else + next_level = level + 1; + + rebalance = f->remaining2; + if (mbits >= sbits) { + /* In stereo mode, we do not apply a scaling to the mid + * because we need the normalized mid for folding later */ + cm = pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks, + lowband, duration, next_lowband_out1, next_level, + stereo ? 1.0f : (gain * mid), lowband_scratch, fill); + rebalance = mbits - (rebalance - f->remaining2); + if (rebalance > 3 << 3 && itheta != 0) + sbits += rebalance - (3 << 3); + + /* For a stereo split, the high bits of fill are always zero, + * so no folding will be done to the side. */ + cmt = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks, + next_lowband2, duration, NULL, next_level, + gain * side, NULL, fill >> blocks); + cm |= cmt << ((B0 >> 1) & (stereo - 1)); + } else { + /* For a stereo split, the high bits of fill are always zero, + * so no folding will be done to the side. */ + cm = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks, + next_lowband2, duration, NULL, next_level, + gain * side, NULL, fill >> blocks); + cm <<= ((B0 >> 1) & (stereo - 1)); + rebalance = sbits - (rebalance - f->remaining2); + if (rebalance > 3 << 3 && itheta != 16384) + mbits += rebalance - (3 << 3); + + /* In stereo mode, we do not apply a scaling to the mid because + * we need the normalized mid for folding later */ + cm |= pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks, + lowband, duration, next_lowband_out1, next_level, + stereo ? 1.0f : (gain * mid), lowband_scratch, fill); + } + } + } else { + /* This is the basic no-split case */ + uint32_t q = celt_bits2pulses(cache, b); + uint32_t curr_bits = celt_pulses2bits(cache, q); + f->remaining2 -= curr_bits; + + /* Ensures we can never bust the budget */ + while (f->remaining2 < 0 && q > 0) { + f->remaining2 += curr_bits; + curr_bits = celt_pulses2bits(cache, --q); + f->remaining2 -= curr_bits; + } + + if (q != 0) { + /* Finally do the actual (de)quantization */ +#if ENCODING + cm = celt_alg_quant(rce, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1), + f->spread, blocks, gain, pvq); +#else + cm = celt_alg_unquant(rcd, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1), + f->spread, blocks, gain, pvq); +#endif + } else { + /* If there's no pulse, fill the band anyway */ + uint32_t cm_mask = (1 << blocks) - 1; + fill &= cm_mask; + if (fill) { + if (!lowband) { + /* Noise */ + for (int i = 0; i < N; i++) + X[i] = (((int32_t)celt_rng(f)) >> 20); + cm = cm_mask; + } else { + /* Folded spectrum */ + for (int i = 0; i < N; i++) { + /* About 48 dB below the "normal" folding level */ + X[i] = lowband[i] + (((celt_rng(f)) & 0x8000) ? 1.0f / 256 : -1.0f / 256); + } + cm = fill; + } + celt_renormalize_vector(X, N, gain); + } else { + memset(X, 0, N*sizeof(float)); + } + } + } + + /* This code is used by the decoder and by the resynthesis-enabled encoder */ + if (stereo) { + if (N > 2) + celt_stereo_merge(X, Y, mid, N); + if (inv) { + for (int i = 0; i < N; i++) + Y[i] *= -1; + } + } else if (level == 0) { + int k; + + /* Undo the sample reorganization going from time order to frequency order */ + if (B0 > 1) + celt_interleave_hadamard(pvq->hadamard_tmp, X, N_B >> recombine, + B0 << recombine, longblocks); + + /* Undo time-freq changes that we did earlier */ + N_B = N_B0; + blocks = B0; + for (k = 0; k < time_divide; k++) { + blocks >>= 1; + N_B <<= 1; + cm |= cm >> blocks; + celt_haar1(X, N_B, blocks); + } + + for (k = 0; k < recombine; k++) { + cm = ff_celt_bit_deinterleave[cm]; + celt_haar1(X, N0>>k, 1< - * - * 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 "opus_rc.h" - -#define OPUS_RC_BITS 32 -#define OPUS_RC_SYM 8 -#define OPUS_RC_CEIL ((1 << OPUS_RC_SYM) - 1) -#define OPUS_RC_TOP (1u << 31) -#define OPUS_RC_BOT (OPUS_RC_TOP >> OPUS_RC_SYM) -#define OPUS_RC_SHIFT (OPUS_RC_BITS - OPUS_RC_SYM - 1) - -static av_always_inline void opus_rc_enc_carryout(OpusRangeCoder *rc, int cbuf) -{ - const int cb = cbuf >> OPUS_RC_SYM, mb = (OPUS_RC_CEIL + cb) & OPUS_RC_CEIL; - if (cbuf == OPUS_RC_CEIL) { - rc->ext++; - return; - } - rc->rng_cur[0] = rc->rem + cb; - rc->rng_cur += (rc->rem >= 0); - for (; rc->ext > 0; rc->ext--) - *rc->rng_cur++ = mb; - av_assert0(rc->rng_cur < rc->rb.position); - rc->rem = cbuf & OPUS_RC_CEIL; /* Propagate */ -} - -static av_always_inline void opus_rc_dec_normalize(OpusRangeCoder *rc) -{ - while (rc->range <= OPUS_RC_BOT) { - rc->value = ((rc->value << OPUS_RC_SYM) | (get_bits(&rc->gb, OPUS_RC_SYM) ^ OPUS_RC_CEIL)) & (OPUS_RC_TOP - 1); - rc->range <<= OPUS_RC_SYM; - rc->total_bits += OPUS_RC_SYM; - } -} - -static av_always_inline void opus_rc_enc_normalize(OpusRangeCoder *rc) -{ - while (rc->range <= OPUS_RC_BOT) { - opus_rc_enc_carryout(rc, rc->value >> OPUS_RC_SHIFT); - rc->value = (rc->value << OPUS_RC_SYM) & (OPUS_RC_TOP - 1); - rc->range <<= OPUS_RC_SYM; - rc->total_bits += OPUS_RC_SYM; - } -} - -static av_always_inline void opus_rc_dec_update(OpusRangeCoder *rc, uint32_t scale, - uint32_t low, uint32_t high, - uint32_t total) -{ - rc->value -= scale * (total - high); - rc->range = low ? scale * (high - low) - : rc->range - scale * (total - high); - opus_rc_dec_normalize(rc); -} - -/* Main encoding function, this needs to go fast */ -static av_always_inline void opus_rc_enc_update(OpusRangeCoder *rc, uint32_t b, uint32_t p, - uint32_t p_tot, const int ptwo) -{ - uint32_t rscaled, cnd = !!b; - if (ptwo) /* Whole function is inlined so hopefully branch is optimized out */ - rscaled = rc->range >> ff_log2(p_tot); - else - rscaled = rc->range/p_tot; - rc->value += cnd*(rc->range - rscaled*(p_tot - b)); - rc->range = (!cnd)*(rc->range - rscaled*(p_tot - p)) + cnd*rscaled*(p - b); - opus_rc_enc_normalize(rc); -} - -uint32_t ff_opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf) -{ - unsigned int k, scale, total, symbol, low, high; - - total = *cdf++; - - scale = rc->range / total; - symbol = rc->value / scale + 1; - symbol = total - FFMIN(symbol, total); - - for (k = 0; cdf[k] <= symbol; k++); - high = cdf[k]; - low = k ? cdf[k-1] : 0; - - opus_rc_dec_update(rc, scale, low, high, total); - - return k; -} - -void ff_opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf) -{ - opus_rc_enc_update(rc, (!!val)*cdf[val], cdf[val + 1], cdf[0], 1); -} - -uint32_t ff_opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits) -{ - uint32_t k, scale; - scale = rc->range >> bits; // in this case, scale = symbol - - if (rc->value >= scale) { - rc->value -= scale; - rc->range -= scale; - k = 0; - } else { - rc->range = scale; - k = 1; - } - opus_rc_dec_normalize(rc); - return k; -} - -void ff_opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits) -{ - bits = (1 << bits) - 1; - opus_rc_enc_update(rc, (!!val)*bits, bits + !!val, bits + 1, 1); -} - -/** - * CELT: read 1-25 raw bits at the end of the frame, backwards byte-wise - */ -uint32_t ff_opus_rc_get_raw(OpusRangeCoder *rc, uint32_t count) -{ - uint32_t value = 0; - - while (rc->rb.bytes && rc->rb.cachelen < count) { - rc->rb.cacheval |= *--rc->rb.position << rc->rb.cachelen; - rc->rb.cachelen += 8; - rc->rb.bytes--; - } - - value = av_mod_uintp2(rc->rb.cacheval, count); - rc->rb.cacheval >>= count; - rc->rb.cachelen -= count; - rc->total_bits += count; - - return value; -} - -/** - * CELT: write 0 - 31 bits to the rawbits buffer - */ -void ff_opus_rc_put_raw(OpusRangeCoder *rc, uint32_t val, uint32_t count) -{ - const int to_write = FFMIN(32 - rc->rb.cachelen, count); - - rc->total_bits += count; - rc->rb.cacheval |= av_mod_uintp2(val, to_write) << rc->rb.cachelen; - rc->rb.cachelen = (rc->rb.cachelen + to_write) % 32; - - if (!rc->rb.cachelen && count) { - AV_WB32((uint8_t *)rc->rb.position, rc->rb.cacheval); - rc->rb.bytes += 4; - rc->rb.position -= 4; - rc->rb.cachelen = count - to_write; - rc->rb.cacheval = av_mod_uintp2(val >> to_write, rc->rb.cachelen); - av_assert0(rc->rng_cur < rc->rb.position); - } -} - -/** - * CELT: read a uniform distribution - */ -uint32_t ff_opus_rc_dec_uint(OpusRangeCoder *rc, uint32_t size) -{ - uint32_t bits, k, scale, total; - - bits = opus_ilog(size - 1); - total = (bits > 8) ? ((size - 1) >> (bits - 8)) + 1 : size; - - scale = rc->range / total; - k = rc->value / scale + 1; - k = total - FFMIN(k, total); - opus_rc_dec_update(rc, scale, k, k + 1, total); - - if (bits > 8) { - k = k << (bits - 8) | ff_opus_rc_get_raw(rc, bits - 8); - return FFMIN(k, size - 1); - } else - return k; -} - -/** - * CELT: write a uniformly distributed integer - */ -void ff_opus_rc_enc_uint(OpusRangeCoder *rc, uint32_t val, uint32_t size) -{ - const int ps = FFMAX(opus_ilog(size - 1) - 8, 0); - opus_rc_enc_update(rc, val >> ps, (val >> ps) + 1, ((size - 1) >> ps) + 1, 0); - ff_opus_rc_put_raw(rc, val, ps); -} - -uint32_t ff_opus_rc_dec_uint_step(OpusRangeCoder *rc, int k0) -{ - /* Use a probability of 3 up to itheta=8192 and then use 1 after */ - uint32_t k, scale, symbol, total = (k0+1)*3 + k0; - scale = rc->range / total; - symbol = rc->value / scale + 1; - symbol = total - FFMIN(symbol, total); - - k = (symbol < (k0+1)*3) ? symbol/3 : symbol - (k0+1)*2; - - opus_rc_dec_update(rc, scale, (k <= k0) ? 3*(k+0) : (k-1-k0) + 3*(k0+1), - (k <= k0) ? 3*(k+1) : (k-0-k0) + 3*(k0+1), total); - return k; -} - -void ff_opus_rc_enc_uint_step(OpusRangeCoder *rc, uint32_t val, int k0) -{ - const uint32_t a = val <= k0, b = 2*a + 1; - k0 = (k0 + 1) << 1; - val = b*(val + k0) - 3*a*k0; - opus_rc_enc_update(rc, val, val + b, (k0 << 1) - 1, 0); -} - -uint32_t ff_opus_rc_dec_uint_tri(OpusRangeCoder *rc, int qn) -{ - uint32_t k, scale, symbol, total, low, center; - - total = ((qn>>1) + 1) * ((qn>>1) + 1); - scale = rc->range / total; - center = rc->value / scale + 1; - center = total - FFMIN(center, total); - - if (center < total >> 1) { - k = (ff_sqrt(8 * center + 1) - 1) >> 1; - low = k * (k + 1) >> 1; - symbol = k + 1; - } else { - k = (2*(qn + 1) - ff_sqrt(8*(total - center - 1) + 1)) >> 1; - low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1); - symbol = qn + 1 - k; - } - - opus_rc_dec_update(rc, scale, low, low + symbol, total); - - return k; -} - -void ff_opus_rc_enc_uint_tri(OpusRangeCoder *rc, uint32_t k, int qn) -{ - uint32_t symbol, low, total; - - total = ((qn>>1) + 1) * ((qn>>1) + 1); - - if (k <= qn >> 1) { - low = k * (k + 1) >> 1; - symbol = k + 1; - } else { - low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1); - symbol = qn + 1 - k; - } - - opus_rc_enc_update(rc, low, low + symbol, total, 0); -} - -int ff_opus_rc_dec_laplace(OpusRangeCoder *rc, uint32_t symbol, int decay) -{ - /* extends the range coder to model a Laplace distribution */ - int value = 0; - uint32_t scale, low = 0, center; - - scale = rc->range >> 15; - center = rc->value / scale + 1; - center = (1 << 15) - FFMIN(center, 1 << 15); - - if (center >= symbol) { - value++; - low = symbol; - symbol = 1 + ((32768 - 32 - symbol) * (16384-decay) >> 15); - - while (symbol > 1 && center >= low + 2 * symbol) { - value++; - symbol *= 2; - low += symbol; - symbol = (((symbol - 2) * decay) >> 15) + 1; - } - - if (symbol <= 1) { - int distance = (center - low) >> 1; - value += distance; - low += 2 * distance; - } - - if (center < low + symbol) - value *= -1; - else - low += symbol; - } - - opus_rc_dec_update(rc, scale, low, FFMIN(low + symbol, 32768), 32768); - - return value; -} - -void ff_opus_rc_enc_laplace(OpusRangeCoder *rc, int *value, uint32_t symbol, int decay) -{ - uint32_t low = symbol; - int i = 1, val = FFABS(*value), pos = *value > 0; - if (!val) { - opus_rc_enc_update(rc, 0, symbol, 1 << 15, 1); - return; - } - symbol = ((32768 - 32 - symbol)*(16384 - decay)) >> 15; - for (; i < val && symbol; i++) { - low += (symbol << 1) + 2; - symbol = (symbol*decay) >> 14; - } - if (symbol) { - low += (++symbol)*pos; - } else { - const int distance = FFMIN(val - i, (((32768 - low) - !pos) >> 1) - 1); - low += pos + (distance << 1); - symbol = FFMIN(1, 32768 - low); - *value = FFSIGN(*value)*(distance + i); - } - opus_rc_enc_update(rc, low, low + symbol, 1 << 15, 1); -} - -int ff_opus_rc_dec_init(OpusRangeCoder *rc, const uint8_t *data, int size) -{ - int ret = init_get_bits8(&rc->gb, data, size); - if (ret < 0) - return ret; - - rc->range = 128; - rc->value = 127 - get_bits(&rc->gb, 7); - rc->total_bits = 9; - opus_rc_dec_normalize(rc); - - return 0; -} - -void ff_opus_rc_dec_raw_init(OpusRangeCoder *rc, const uint8_t *rightend, uint32_t bytes) -{ - rc->rb.position = rightend; - rc->rb.bytes = bytes; - rc->rb.cachelen = 0; - rc->rb.cacheval = 0; -} - -void ff_opus_rc_enc_end(OpusRangeCoder *rc, uint8_t *dst, int size) -{ - int rng_bytes, bits = OPUS_RC_BITS - opus_ilog(rc->range); - uint32_t mask = (OPUS_RC_TOP - 1) >> bits; - uint32_t end = (rc->value + mask) & ~mask; - - if ((end | mask) >= rc->value + rc->range) { - bits++; - mask >>= 1; - end = (rc->value + mask) & ~mask; - } - - /* Finish what's left */ - while (bits > 0) { - opus_rc_enc_carryout(rc, end >> OPUS_RC_SHIFT); - end = (end << OPUS_RC_SYM) & (OPUS_RC_TOP - 1); - bits -= OPUS_RC_SYM; - } - - /* Flush out anything left or marked */ - if (rc->rem >= 0 || rc->ext > 0) - opus_rc_enc_carryout(rc, 0); - - rng_bytes = rc->rng_cur - rc->buf; - memcpy(dst, rc->buf, rng_bytes); - - /* Put the rawbits part, if any */ - if (rc->rb.bytes || rc->rb.cachelen) { - int i, lap; - uint8_t *rb_src, *rb_dst; - ff_opus_rc_put_raw(rc, 0, 32 - rc->rb.cachelen); - rb_src = rc->buf + OPUS_MAX_FRAME_SIZE + 12 - rc->rb.bytes; - rb_dst = dst + FFMAX(size - rc->rb.bytes, 0); - lap = &dst[rng_bytes] - rb_dst; - for (i = 0; i < lap; i++) - rb_dst[i] |= rb_src[i]; - memcpy(&rb_dst[lap], &rb_src[lap], FFMAX(rc->rb.bytes - lap, 0)); - } -} - -void ff_opus_rc_enc_init(OpusRangeCoder *rc) -{ - rc->value = 0; - rc->range = OPUS_RC_TOP; - rc->total_bits = OPUS_RC_BITS + 1; - rc->rem = -1; - rc->ext = 0; - rc->rng_cur = rc->buf; - ff_opus_rc_dec_raw_init(rc, rc->buf + OPUS_MAX_FRAME_SIZE + 8, 0); -} diff --git a/libavcodec/opus_rc.h b/libavcodec/opus_rc.h index 72e683b075..332f3fa883 100644 --- a/libavcodec/opus_rc.h +++ b/libavcodec/opus_rc.h @@ -24,11 +24,16 @@ #define AVCODEC_OPUS_RC_H #include -#include "get_bits.h" -#include "opus.h" + +#include "libavutil/common.h" #define opus_ilog(i) (av_log2(i) + !!(i)) +#define OPUS_RC_SYM 8 +#define OPUS_RC_CEIL ((1 << OPUS_RC_SYM) - 1) +#define OPUS_RC_TOP (1u << 31) +#define OPUS_RC_BOT (OPUS_RC_TOP >> OPUS_RC_SYM) + typedef struct RawBitsContext { const uint8_t *position; uint32_t bytes; @@ -37,19 +42,21 @@ typedef struct RawBitsContext { } RawBitsContext; typedef struct OpusRangeCoder { - GetBitContext gb; RawBitsContext rb; uint32_t range; uint32_t value; uint32_t total_bits; - - /* Encoder */ - uint8_t buf[OPUS_MAX_FRAME_SIZE + 12]; /* memcpy vs (memmove + overreading) */ - uint8_t *rng_cur; /* Current range coded byte */ - int ext; /* Awaiting propagation */ - int rem; /* Carryout flag */ } OpusRangeCoder; +static inline void ff_opus_rc_raw_init(OpusRangeCoder *rc, const uint8_t *rightend, + uint32_t bytes) +{ + rc->rb.position = rightend; + rc->rb.bytes = bytes; + rc->rb.cachelen = 0; + rc->rb.cacheval = 0; +} + /** * CELT: estimate bits of entropy that have thus far been consumed for the * current CELT frame, to integer and fractional (1/8th bit) precision @@ -78,45 +85,4 @@ static av_always_inline uint32_t opus_rc_tell_frac(const OpusRangeCoder *rc) return total_bits - rcbuffer; } -uint32_t ff_opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf); -void ff_opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf); - -uint32_t ff_opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits); -void ff_opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits); - -uint32_t ff_opus_rc_dec_uint_step(OpusRangeCoder *rc, int k0); -void ff_opus_rc_enc_uint_step(OpusRangeCoder *rc, uint32_t val, int k0); - -uint32_t ff_opus_rc_dec_uint_tri(OpusRangeCoder *rc, int qn); -void ff_opus_rc_enc_uint_tri(OpusRangeCoder *rc, uint32_t k, int qn); - -uint32_t ff_opus_rc_dec_uint(OpusRangeCoder *rc, uint32_t size); -void ff_opus_rc_enc_uint(OpusRangeCoder *rc, uint32_t val, uint32_t size); - -uint32_t ff_opus_rc_get_raw(OpusRangeCoder *rc, uint32_t count); -void ff_opus_rc_put_raw(OpusRangeCoder *rc, uint32_t val, uint32_t count); - -int ff_opus_rc_dec_laplace(OpusRangeCoder *rc, uint32_t symbol, int decay); -void ff_opus_rc_enc_laplace(OpusRangeCoder *rc, int *value, uint32_t symbol, int decay); - -int ff_opus_rc_dec_init(OpusRangeCoder *rc, const uint8_t *data, int size); -void ff_opus_rc_dec_raw_init(OpusRangeCoder *rc, const uint8_t *rightend, uint32_t bytes); - -void ff_opus_rc_enc_end(OpusRangeCoder *rc, uint8_t *dst, int size); -void ff_opus_rc_enc_init(OpusRangeCoder *rc); - -#define OPUS_RC_CHECKPOINT_UPDATE(rc) \ - rc_rollback_bits = opus_rc_tell_frac(rc); \ - rc_rollback_ctx = *rc - -#define OPUS_RC_CHECKPOINT_SPAWN(rc) \ - uint32_t rc_rollback_bits = opus_rc_tell_frac(rc); \ - OpusRangeCoder rc_rollback_ctx = *rc \ - -#define OPUS_RC_CHECKPOINT_BITS(rc) \ - (opus_rc_tell_frac(rc) - rc_rollback_bits) - -#define OPUS_RC_CHECKPOINT_ROLLBACK(rc) \ - memcpy(rc, &rc_rollback_ctx, sizeof(OpusRangeCoder)); \ - #endif /* AVCODEC_OPUS_RC_H */ diff --git a/libavcodec/opus_silk.c b/libavcodec/opus_silk.c index cf8b16acff..99696e26d2 100644 --- a/libavcodec/opus_silk.c +++ b/libavcodec/opus_silk.c @@ -29,6 +29,7 @@ #include "mathops.h" #include "opus.h" #include "opus_rc.h" +#include "opusdec_rc.h" #include "opus_silk.h" #include "opustab.h" @@ -308,7 +309,7 @@ static void silk_lsf2lpc(const int16_t nlsf[16], float lpcf[16], int order) } static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame, - OpusRangeCoder *rc, + OpusDecRangeCoder *rc, float lpc_leadin[16], float lpc[16], int *lpc_order, int *has_lpc_leadin, int voiced) { @@ -404,7 +405,7 @@ static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame, memcpy(frame->lpc, lpc, order * sizeof(lpc[0])); } -static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t total, +static inline void silk_count_children(OpusDecRangeCoder *rc, int model, int32_t total, int32_t child[2]) { if (total != 0) { @@ -417,7 +418,7 @@ static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t to } } -static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc, +static inline void silk_decode_excitation(SilkContext *s, OpusDecRangeCoder *rc, float* excitationf, int qoffset_high, int active, int voiced) { @@ -511,7 +512,7 @@ static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc, /** Order of the LTP filter */ #define LTP_ORDER 5 -static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc, +static void silk_decode_frame(SilkContext *s, OpusDecRangeCoder *rc, int frame_num, int channel, int coded_channels, int active, int active1, int redundant) { @@ -788,7 +789,7 @@ static void silk_flush_frame(SilkFrame *frame) frame->coded = 0; } -int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc, +int ff_silk_decode_superframe(SilkContext *s, OpusDecRangeCoder *rc, float *output[2], enum OpusBandwidth bandwidth, int coded_channels, diff --git a/libavcodec/opus_silk.h b/libavcodec/opus_silk.h index 6552c166a4..cd6920920e 100644 --- a/libavcodec/opus_silk.h +++ b/libavcodec/opus_silk.h @@ -25,7 +25,7 @@ #include "avcodec.h" #include "opus.h" -#include "opus_rc.h" +#include "opusdec_rc.h" #define SILK_HISTORY 322 #define SILK_MAX_LPC 16 @@ -40,7 +40,7 @@ void ff_silk_flush(SilkContext *s); * Decode the LP layer of one Opus frame (which may correspond to several SILK * frames). */ -int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc, +int ff_silk_decode_superframe(SilkContext *s, OpusDecRangeCoder *rc, float *output[2], enum OpusBandwidth bandwidth, int coded_channels, int duration_ms); diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c index c5f06e0600..468bc6ddff 100644 --- a/libavcodec/opusdec.c +++ b/libavcodec/opusdec.c @@ -54,6 +54,7 @@ #include "opus_celt.h" #include "opus_parse.h" #include "opus_rc.h" +#include "opusdec_rc.h" #include "opus_silk.h" static const uint16_t silk_frame_duration_ms[16] = { @@ -83,8 +84,8 @@ typedef struct OpusStreamContext { * the streams when they have different resampling delays */ AVAudioFifo *sync_buffer; - OpusRangeCoder rc; - OpusRangeCoder redundancy_rc; + OpusDecRangeCoder rc; + OpusDecRangeCoder redundancy_rc; SilkContext *silk; CeltFrame *celt; AVFloatDSPContext *fdsp; @@ -218,7 +219,7 @@ static int opus_decode_redundancy(OpusStreamContext *s, const uint8_t *data, int int ret = ff_opus_rc_dec_init(&s->redundancy_rc, data, size); if (ret < 0) goto fail; - ff_opus_rc_dec_raw_init(&s->redundancy_rc, data + size, size); + ff_opus_rc_raw_init(&s->redundancy_rc.c, data + size, size); ret = ff_celt_decode_frame(s->celt, &s->redundancy_rc, s->redundancy_output, @@ -274,7 +275,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size ff_silk_flush(s->silk); // decode redundancy information - consumed = opus_rc_tell(&s->rc); + consumed = opus_rc_tell(&s->rc.c); if (s->packet.mode == OPUS_MODE_HYBRID && consumed + 37 <= size * 8) redundancy = ff_opus_rc_dec_log(&s->rc, 12); else if (s->packet.mode == OPUS_MODE_SILK && consumed + 17 <= size * 8) @@ -328,7 +329,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size } } - ff_opus_rc_dec_raw_init(&s->rc, data + size, size); + ff_opus_rc_raw_init(&s->rc.c, data + size, size); ret = ff_celt_decode_frame(s->celt, &s->rc, dst, s->packet.stereo + 1, diff --git a/libavcodec/opusdec_rc.c b/libavcodec/opusdec_rc.c new file mode 100644 index 0000000000..fb2bce0b72 --- /dev/null +++ b/libavcodec/opusdec_rc.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2017 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 "opus_rc.h" +#include "opusdec_rc.h" + +static av_always_inline void opus_rc_dec_normalize(OpusDecRangeCoder *rc) +{ + while (rc->c.range <= OPUS_RC_BOT) { + rc->c.value = ((rc->c.value << OPUS_RC_SYM) | (get_bits(&rc->gb, OPUS_RC_SYM) ^ OPUS_RC_CEIL)) & (OPUS_RC_TOP - 1); + rc->c.range <<= OPUS_RC_SYM; + rc->c.total_bits += OPUS_RC_SYM; + } +} + +static av_always_inline void opus_rc_dec_update(OpusDecRangeCoder *rc, uint32_t scale, + uint32_t low, uint32_t high, + uint32_t total) +{ + rc->c.value -= scale * (total - high); + rc->c.range = low ? scale * (high - low) + : rc->c.range - scale * (total - high); + opus_rc_dec_normalize(rc); +} + +uint32_t ff_opus_rc_dec_cdf(OpusDecRangeCoder *rc, const uint16_t *cdf) +{ + unsigned int k, scale, total, symbol, low, high; + + total = *cdf++; + + scale = rc->c.range / total; + symbol = rc->c.value / scale + 1; + symbol = total - FFMIN(symbol, total); + + for (k = 0; cdf[k] <= symbol; k++); + high = cdf[k]; + low = k ? cdf[k-1] : 0; + + opus_rc_dec_update(rc, scale, low, high, total); + + return k; +} + +uint32_t ff_opus_rc_dec_log(OpusDecRangeCoder *rc, uint32_t bits) +{ + uint32_t k, scale; + scale = rc->c.range >> bits; // in this case, scale = symbol + + if (rc->c.value >= scale) { + rc->c.value -= scale; + rc->c.range -= scale; + k = 0; + } else { + rc->c.range = scale; + k = 1; + } + opus_rc_dec_normalize(rc); + return k; +} + +/** + * CELT: read 1-25 raw bits at the end of the frame, backwards byte-wise + */ +uint32_t ff_opus_rc_get_raw(OpusDecRangeCoder *rc, uint32_t count) +{ + uint32_t value = 0; + + while (rc->c.rb.bytes && rc->c.rb.cachelen < count) { + rc->c.rb.cacheval |= *--rc->c.rb.position << rc->c.rb.cachelen; + rc->c.rb.cachelen += 8; + rc->c.rb.bytes--; + } + + value = av_mod_uintp2(rc->c.rb.cacheval, count); + rc->c.rb.cacheval >>= count; + rc->c.rb.cachelen -= count; + rc->c.total_bits += count; + + return value; +} + +/** + * CELT: read a uniform distribution + */ +uint32_t ff_opus_rc_dec_uint(OpusDecRangeCoder *rc, uint32_t size) +{ + uint32_t bits, k, scale, total; + + bits = opus_ilog(size - 1); + total = (bits > 8) ? ((size - 1) >> (bits - 8)) + 1 : size; + + scale = rc->c.range / total; + k = rc->c.value / scale + 1; + k = total - FFMIN(k, total); + opus_rc_dec_update(rc, scale, k, k + 1, total); + + if (bits > 8) { + k = k << (bits - 8) | ff_opus_rc_get_raw(rc, bits - 8); + return FFMIN(k, size - 1); + } else + return k; +} + +uint32_t ff_opus_rc_dec_uint_step(OpusDecRangeCoder *rc, int k0) +{ + /* Use a probability of 3 up to itheta=8192 and then use 1 after */ + uint32_t k, scale, symbol, total = (k0+1)*3 + k0; + scale = rc->c.range / total; + symbol = rc->c.value / scale + 1; + symbol = total - FFMIN(symbol, total); + + k = (symbol < (k0+1)*3) ? symbol/3 : symbol - (k0+1)*2; + + opus_rc_dec_update(rc, scale, (k <= k0) ? 3*(k+0) : (k-1-k0) + 3*(k0+1), + (k <= k0) ? 3*(k+1) : (k-0-k0) + 3*(k0+1), total); + return k; +} + +uint32_t ff_opus_rc_dec_uint_tri(OpusDecRangeCoder *rc, int qn) +{ + uint32_t k, scale, symbol, total, low, center; + + total = ((qn>>1) + 1) * ((qn>>1) + 1); + scale = rc->c.range / total; + center = rc->c.value / scale + 1; + center = total - FFMIN(center, total); + + if (center < total >> 1) { + k = (ff_sqrt(8 * center + 1) - 1) >> 1; + low = k * (k + 1) >> 1; + symbol = k + 1; + } else { + k = (2*(qn + 1) - ff_sqrt(8*(total - center - 1) + 1)) >> 1; + low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1); + symbol = qn + 1 - k; + } + + opus_rc_dec_update(rc, scale, low, low + symbol, total); + + return k; +} + +int ff_opus_rc_dec_laplace(OpusDecRangeCoder *rc, uint32_t symbol, int decay) +{ + /* extends the range coder to model a Laplace distribution */ + int value = 0; + uint32_t scale, low = 0, center; + + scale = rc->c.range >> 15; + center = rc->c.value / scale + 1; + center = (1 << 15) - FFMIN(center, 1 << 15); + + if (center >= symbol) { + value++; + low = symbol; + symbol = 1 + ((32768 - 32 - symbol) * (16384-decay) >> 15); + + while (symbol > 1 && center >= low + 2 * symbol) { + value++; + symbol *= 2; + low += symbol; + symbol = (((symbol - 2) * decay) >> 15) + 1; + } + + if (symbol <= 1) { + int distance = (center - low) >> 1; + value += distance; + low += 2 * distance; + } + + if (center < low + symbol) + value *= -1; + else + low += symbol; + } + + opus_rc_dec_update(rc, scale, low, FFMIN(low + symbol, 32768), 32768); + + return value; +} + +int ff_opus_rc_dec_init(OpusDecRangeCoder *rc, const uint8_t *data, int size) +{ + int ret = init_get_bits8(&rc->gb, data, size); + if (ret < 0) + return ret; + + rc->c.range = 128; + rc->c.value = 127 - get_bits(&rc->gb, 7); + rc->c.total_bits = 9; + opus_rc_dec_normalize(rc); + + return 0; +} diff --git a/libavcodec/opusdec_rc.h b/libavcodec/opusdec_rc.h new file mode 100644 index 0000000000..96889e3d7f --- /dev/null +++ b/libavcodec/opusdec_rc.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2017 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 + */ + +#ifndef AVCODEC_OPUSDEC_RC_H +#define AVCODEC_OPUSDEC_RC_H + +#include + +#include "get_bits.h" +#include "opus_rc.h" + +typedef struct OpusDecRangeCoder { + OpusRangeCoder c; + + GetBitContext gb; +} OpusDecRangeCoder; + +uint32_t ff_opus_rc_dec_cdf(OpusDecRangeCoder *rc, const uint16_t *cdf); + +uint32_t ff_opus_rc_dec_log(OpusDecRangeCoder *rc, uint32_t bits); + +uint32_t ff_opus_rc_dec_uint_step(OpusDecRangeCoder *rc, int k0); + +uint32_t ff_opus_rc_dec_uint_tri(OpusDecRangeCoder *rc, int qn); + +uint32_t ff_opus_rc_dec_uint(OpusDecRangeCoder *rc, uint32_t size); + +uint32_t ff_opus_rc_get_raw(OpusDecRangeCoder *rc, uint32_t count); + +int ff_opus_rc_dec_laplace(OpusDecRangeCoder *rc, uint32_t symbol, int decay); + +int ff_opus_rc_dec_init(OpusDecRangeCoder *rc, const uint8_t *data, int size); + +#endif /* AVCODEC_OPUSDEC_RC_H */ diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c index 280425c74f..f1283827b7 100644 --- a/libavcodec/opusenc.c +++ b/libavcodec/opusenc.c @@ -25,6 +25,7 @@ #include "opusenc.h" #include "opus_pvq.h" #include "opusenc_psy.h" +#include "opusenc_rc.h" #include "opustab.h" #include "libavutil/channel_layout.h" @@ -55,7 +56,7 @@ typedef struct OpusEncContext { int channels; CeltFrame *frame; - OpusRangeCoder *rc; + OpusEncRangeCoder *rc; /* Actual energy the decoder will have */ float last_quantized_energy[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; @@ -258,15 +259,15 @@ static void celt_frame_mdct(OpusEncContext *s, CeltFrame *f) } } -static void celt_enc_tf(CeltFrame *f, OpusRangeCoder *rc) +static void celt_enc_tf(CeltFrame *f, OpusEncRangeCoder *rc) { int tf_select = 0, diff = 0, tf_changed = 0, tf_select_needed; int bits = f->transient ? 2 : 4; - tf_select_needed = ((f->size && (opus_rc_tell(rc) + bits + 1) <= f->framebits)); + tf_select_needed = ((f->size && (opus_rc_tell(&rc->c) + bits + 1) <= f->framebits)); for (int i = f->start_band; i < f->end_band; i++) { - if ((opus_rc_tell(rc) + bits + tf_select_needed) <= f->framebits) { + if ((opus_rc_tell(&rc->c) + bits + tf_select_needed) <= f->framebits) { const int tbit = (diff ^ 1) == f->tf_change[i]; ff_opus_rc_enc_log(rc, tbit, bits); diff ^= tbit; @@ -285,7 +286,7 @@ static void celt_enc_tf(CeltFrame *f, OpusRangeCoder *rc) f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]]; } -static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f) +static void celt_enc_quant_pfilter(OpusEncRangeCoder *rc, CeltFrame *f) { float gain = f->pf_gain; int txval, octave = f->pf_octave, period = f->pf_period, tapset = f->pf_tapset; @@ -307,7 +308,7 @@ static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f) ff_opus_rc_put_raw(rc, txval, 3); gain = 0.09375f * (txval + 1); /* Tapset */ - if ((opus_rc_tell(rc) + 2) <= f->framebits) + if ((opus_rc_tell(&rc->c) + 2) <= f->framebits) ff_opus_rc_enc_cdf(rc, tapset, ff_celt_model_tapset); else tapset = 0; @@ -322,14 +323,14 @@ static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f) } } -static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f, +static void exp_quant_coarse(OpusEncRangeCoder *rc, CeltFrame *f, float last_energy[][CELT_MAX_BANDS], int intra) { float alpha, beta, prev[2] = { 0, 0 }; const uint8_t *pmod = ff_celt_coarse_energy_dist[f->size][intra]; /* Inter is really just differential coding */ - if (opus_rc_tell(rc) + 3 <= f->framebits) + if (opus_rc_tell(&rc->c) + 3 <= f->framebits) ff_opus_rc_enc_log(rc, intra, 3); else intra = 0; @@ -345,7 +346,7 @@ static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f, for (int i = f->start_band; i < f->end_band; i++) { for (int ch = 0; ch < f->channels; ch++) { CeltBlock *block = &f->block[ch]; - const int left = f->framebits - opus_rc_tell(rc); + const int left = f->framebits - opus_rc_tell(&rc->c); const float last = FFMAX(-9.0f, last_energy[ch][i]); float diff = block->energy[i] - prev[ch] - last*alpha; int q_en = lrintf(diff); @@ -365,7 +366,7 @@ static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f, } } -static void celt_quant_coarse(CeltFrame *f, OpusRangeCoder *rc, +static void celt_quant_coarse(CeltFrame *f, OpusEncRangeCoder *rc, float last_energy[][CELT_MAX_BANDS]) { uint32_t inter, intra; @@ -385,7 +386,7 @@ static void celt_quant_coarse(CeltFrame *f, OpusRangeCoder *rc, } } -static void celt_quant_fine(CeltFrame *f, OpusRangeCoder *rc) +static void celt_quant_fine(CeltFrame *f, OpusEncRangeCoder *rc) { for (int i = f->start_band; i < f->end_band; i++) { if (!f->fine_bits[i]) @@ -402,10 +403,10 @@ static void celt_quant_fine(CeltFrame *f, OpusRangeCoder *rc) } } -static void celt_quant_final(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame *f) +static void celt_quant_final(OpusEncContext *s, OpusEncRangeCoder *rc, CeltFrame *f) { for (int priority = 0; priority < 2; priority++) { - for (int i = f->start_band; i < f->end_band && (f->framebits - opus_rc_tell(rc)) >= f->channels; i++) { + for (int i = f->start_band; i < f->end_band && (f->framebits - opus_rc_tell(&rc->c)) >= f->channels; i++) { if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS) continue; for (int ch = 0; ch < f->channels; ch++) { @@ -420,7 +421,7 @@ static void celt_quant_final(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame *f } } -static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc, +static void celt_encode_frame(OpusEncContext *s, OpusEncRangeCoder *rc, CeltFrame *f, int index) { ff_opus_rc_enc_init(rc); @@ -457,19 +458,19 @@ static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc, ff_opus_rc_enc_log(rc, 0, 15); /* Pitch filter */ - if (!f->start_band && opus_rc_tell(rc) + 16 <= f->framebits) + if (!f->start_band && opus_rc_tell(&rc->c) + 16 <= f->framebits) celt_enc_quant_pfilter(rc, f); /* Transient flag */ - if (f->size && opus_rc_tell(rc) + 3 <= f->framebits) + if (f->size && opus_rc_tell(&rc->c) + 3 <= f->framebits) ff_opus_rc_enc_log(rc, f->transient, 3); /* Main encoding */ celt_quant_coarse (f, rc, s->last_quantized_energy); celt_enc_tf (f, rc); - ff_celt_bitalloc (f, rc, 1); + ff_celt_bitalloc (f, &rc->c, 1); celt_quant_fine (f, rc); - ff_celt_quant_bands(f, rc); + ff_celt_quant_bands(f, &rc->c); /* Anticollapse bit */ if (f->anticollapse_needed) @@ -694,7 +695,7 @@ static av_cold int opus_encode_init(AVCodecContext *avctx) s->frame = av_malloc(max_frames*sizeof(CeltFrame)); if (!s->frame) return AVERROR(ENOMEM); - s->rc = av_malloc(max_frames*sizeof(OpusRangeCoder)); + s->rc = av_malloc_array(max_frames, sizeof(*s->rc)); if (!s->rc) return AVERROR(ENOMEM); diff --git a/libavcodec/opusenc_psy.c b/libavcodec/opusenc_psy.c index 48ccd2ebd0..17a2efd8d5 100644 --- a/libavcodec/opusenc_psy.c +++ b/libavcodec/opusenc_psy.c @@ -22,12 +22,13 @@ #include #include "opusenc_psy.h" +#include "opusenc_rc.h" #include "opus_celt.h" #include "opus_pvq.h" #include "opustab.h" #include "libavfilter/window_func.h" -static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int band, +static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusEncRangeCoder *rce, int band, float *bits, float lambda) { int i, b = 0; @@ -39,7 +40,8 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b float *X_orig = f->block[0].coeffs + (ff_celt_freq_bands[band] << f->size); float *Y = (f->channels == 2) ? &buf[176] : NULL; float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] << f->size); - OPUS_RC_CHECKPOINT_SPAWN(rc); + OpusRangeCoder *const rc = &rce->c; + OPUS_RC_CHECKPOINT_SPAWN(rce); memcpy(X, X_orig, band_size*sizeof(float)); if (Y) @@ -69,10 +71,10 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b } dist = sqrtf(err_x) + sqrtf(err_y); - cost = OPUS_RC_CHECKPOINT_BITS(rc)/8.0f; + cost = OPUS_RC_CHECKPOINT_BITS(rce)/8.0f; *bits += cost; - OPUS_RC_CHECKPOINT_ROLLBACK(rc); + OPUS_RC_CHECKPOINT_ROLLBACK(rce); return lambda*dist*cost; } @@ -366,10 +368,10 @@ static void celt_gauge_psy_weight(OpusPsyContext *s, OpusPsyStep **start, static int bands_dist(OpusPsyContext *s, CeltFrame *f, float *total_dist) { int i, tdist = 0.0f; - OpusRangeCoder dump; + OpusEncRangeCoder dump; ff_opus_rc_enc_init(&dump); - ff_celt_bitalloc(f, &dump, 1); + ff_celt_bitalloc(f, &dump.c, 1); for (i = 0; i < CELT_MAX_BANDS; i++) { float bits = 0.0f; diff --git a/libavcodec/opusenc_psy.h b/libavcodec/opusenc_psy.h index bc1a88c03d..2d35e76d2c 100644 --- a/libavcodec/opusenc_psy.h +++ b/libavcodec/opusenc_psy.h @@ -26,6 +26,7 @@ #include "libavutil/mem_internal.h" #include "opusenc.h" +#include "opusenc_rc.h" #include "opus_celt.h" #include "opusenc_utils.h" diff --git a/libavcodec/opusenc_rc.c b/libavcodec/opusenc_rc.c new file mode 100644 index 0000000000..6c749c3a34 --- /dev/null +++ b/libavcodec/opusenc_rc.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2017 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/avassert.h" +#include "libavutil/intreadwrite.h" + +#include "opusenc_rc.h" + +#define OPUS_RC_BITS 32 +#define OPUS_RC_SHIFT (OPUS_RC_BITS - OPUS_RC_SYM - 1) + +static av_always_inline void opus_rc_enc_carryout(OpusEncRangeCoder *rc, int cbuf) +{ + const int cb = cbuf >> OPUS_RC_SYM, mb = (OPUS_RC_CEIL + cb) & OPUS_RC_CEIL; + if (cbuf == OPUS_RC_CEIL) { + rc->ext++; + return; + } + rc->rng_cur[0] = rc->rem + cb; + rc->rng_cur += (rc->rem >= 0); + for (; rc->ext > 0; rc->ext--) + *rc->rng_cur++ = mb; + av_assert0(rc->rng_cur < rc->c.rb.position); + rc->rem = cbuf & OPUS_RC_CEIL; /* Propagate */ +} + +static av_always_inline void opus_rc_enc_normalize(OpusEncRangeCoder *rc) +{ + while (rc->c.range <= OPUS_RC_BOT) { + opus_rc_enc_carryout(rc, rc->c.value >> OPUS_RC_SHIFT); + rc->c.value = (rc->c.value << OPUS_RC_SYM) & (OPUS_RC_TOP - 1); + rc->c.range <<= OPUS_RC_SYM; + rc->c.total_bits += OPUS_RC_SYM; + } +} + +/* Main encoding function, this needs to go fast */ +static av_always_inline void opus_rc_enc_update(OpusEncRangeCoder *rc, uint32_t b, uint32_t p, + uint32_t p_tot, const int ptwo) +{ + uint32_t rscaled, cnd = !!b; + if (ptwo) /* Whole function is inlined so hopefully branch is optimized out */ + rscaled = rc->c.range >> ff_log2(p_tot); + else + rscaled = rc->c.range/p_tot; + rc->c.value += cnd*(rc->c.range - rscaled*(p_tot - b)); + rc->c.range = (!cnd)*(rc->c.range - rscaled*(p_tot - p)) + cnd*rscaled*(p - b); + opus_rc_enc_normalize(rc); +} + +void ff_opus_rc_enc_cdf(OpusEncRangeCoder *rc, int val, const uint16_t *cdf) +{ + opus_rc_enc_update(rc, (!!val)*cdf[val], cdf[val + 1], cdf[0], 1); +} + +void ff_opus_rc_enc_log(OpusEncRangeCoder *rc, int val, uint32_t bits) +{ + bits = (1 << bits) - 1; + opus_rc_enc_update(rc, (!!val)*bits, bits + !!val, bits + 1, 1); +} + +/** + * CELT: write 0 - 31 bits to the rawbits buffer + */ +void ff_opus_rc_put_raw(OpusEncRangeCoder *rc, uint32_t val, uint32_t count) +{ + const int to_write = FFMIN(32 - rc->c.rb.cachelen, count); + + rc->c.total_bits += count; + rc->c.rb.cacheval |= av_mod_uintp2(val, to_write) << rc->c.rb.cachelen; + rc->c.rb.cachelen = (rc->c.rb.cachelen + to_write) % 32; + + if (!rc->c.rb.cachelen && count) { + AV_WB32((uint8_t *)rc->c.rb.position, rc->c.rb.cacheval); + rc->c.rb.bytes += 4; + rc->c.rb.position -= 4; + rc->c.rb.cachelen = count - to_write; + rc->c.rb.cacheval = av_mod_uintp2(val >> to_write, rc->c.rb.cachelen); + av_assert0(rc->rng_cur < rc->c.rb.position); + } +} + +/** + * CELT: write a uniformly distributed integer + */ +void ff_opus_rc_enc_uint(OpusEncRangeCoder *rc, uint32_t val, uint32_t size) +{ + const int ps = FFMAX(opus_ilog(size - 1) - 8, 0); + opus_rc_enc_update(rc, val >> ps, (val >> ps) + 1, ((size - 1) >> ps) + 1, 0); + ff_opus_rc_put_raw(rc, val, ps); +} + +void ff_opus_rc_enc_uint_step(OpusEncRangeCoder *rc, uint32_t val, int k0) +{ + const uint32_t a = val <= k0, b = 2*a + 1; + k0 = (k0 + 1) << 1; + val = b*(val + k0) - 3*a*k0; + opus_rc_enc_update(rc, val, val + b, (k0 << 1) - 1, 0); +} + +void ff_opus_rc_enc_uint_tri(OpusEncRangeCoder *rc, uint32_t k, int qn) +{ + uint32_t symbol, low, total; + + total = ((qn>>1) + 1) * ((qn>>1) + 1); + + if (k <= qn >> 1) { + low = k * (k + 1) >> 1; + symbol = k + 1; + } else { + low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1); + symbol = qn + 1 - k; + } + + opus_rc_enc_update(rc, low, low + symbol, total, 0); +} + +void ff_opus_rc_enc_laplace(OpusEncRangeCoder *rc, int *value, uint32_t symbol, int decay) +{ + uint32_t low = symbol; + int i = 1, val = FFABS(*value), pos = *value > 0; + if (!val) { + opus_rc_enc_update(rc, 0, symbol, 1 << 15, 1); + return; + } + symbol = ((32768 - 32 - symbol)*(16384 - decay)) >> 15; + for (; i < val && symbol; i++) { + low += (symbol << 1) + 2; + symbol = (symbol*decay) >> 14; + } + if (symbol) { + low += (++symbol)*pos; + } else { + const int distance = FFMIN(val - i, (((32768 - low) - !pos) >> 1) - 1); + low += pos + (distance << 1); + symbol = FFMIN(1, 32768 - low); + *value = FFSIGN(*value)*(distance + i); + } + opus_rc_enc_update(rc, low, low + symbol, 1 << 15, 1); +} + +void ff_opus_rc_enc_end(OpusEncRangeCoder *rc, uint8_t *dst, int size) +{ + int rng_bytes, bits = OPUS_RC_BITS - opus_ilog(rc->c.range); + uint32_t mask = (OPUS_RC_TOP - 1) >> bits; + uint32_t end = (rc->c.value + mask) & ~mask; + + if ((end | mask) >= rc->c.value + rc->c.range) { + bits++; + mask >>= 1; + end = (rc->c.value + mask) & ~mask; + } + + /* Finish what's left */ + while (bits > 0) { + opus_rc_enc_carryout(rc, end >> OPUS_RC_SHIFT); + end = (end << OPUS_RC_SYM) & (OPUS_RC_TOP - 1); + bits -= OPUS_RC_SYM; + } + + /* Flush out anything left or marked */ + if (rc->rem >= 0 || rc->ext > 0) + opus_rc_enc_carryout(rc, 0); + + rng_bytes = rc->rng_cur - rc->buf; + memcpy(dst, rc->buf, rng_bytes); + + /* Put the rawbits part, if any */ + if (rc->c.rb.bytes || rc->c.rb.cachelen) { + int lap; + uint8_t *rb_src, *rb_dst; + ff_opus_rc_put_raw(rc, 0, 32 - rc->c.rb.cachelen); + rb_src = rc->buf + OPUS_MAX_FRAME_SIZE + 12 - rc->c.rb.bytes; + rb_dst = dst + FFMAX(size - rc->c.rb.bytes, 0); + lap = &dst[rng_bytes] - rb_dst; + for (int i = 0; i < lap; i++) + rb_dst[i] |= rb_src[i]; + memcpy(&rb_dst[lap], &rb_src[lap], FFMAX(rc->c.rb.bytes - lap, 0)); + } +} + +void ff_opus_rc_enc_init(OpusEncRangeCoder *rc) +{ + rc->c.value = 0; + rc->c.range = OPUS_RC_TOP; + rc->c.total_bits = OPUS_RC_BITS + 1; + rc->rem = -1; + rc->ext = 0; + rc->rng_cur = rc->buf; + ff_opus_rc_raw_init(&rc->c, rc->buf + OPUS_MAX_FRAME_SIZE + 8, 0); +} diff --git a/libavcodec/opusenc_rc.h b/libavcodec/opusenc_rc.h new file mode 100644 index 0000000000..40c48d04f0 --- /dev/null +++ b/libavcodec/opusenc_rc.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2017 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 + */ + +#ifndef AVCODEC_OPUSENC_RC_H +#define AVCODEC_OPUSENC_RC_H + +#include + +#include "opus.h" +#include "opus_rc.h" + +typedef struct OpusEncRangeCoder { + OpusRangeCoder c; + + uint8_t *rng_cur; /* Current range coded byte */ + int ext; /* Awaiting propagation */ + int rem; /* Carryout flag */ + uint8_t buf[OPUS_MAX_FRAME_SIZE + 12]; /* memcpy vs (memmove + overreading) */ +} OpusEncRangeCoder; + +void ff_opus_rc_enc_cdf(OpusEncRangeCoder *rc, int val, const uint16_t *cdf); +void ff_opus_rc_enc_log(OpusEncRangeCoder *rc, int val, uint32_t bits); +void ff_opus_rc_enc_uint_step(OpusEncRangeCoder *rc, uint32_t val, int k0); +void ff_opus_rc_enc_uint_tri(OpusEncRangeCoder *rc, uint32_t k, int qn); +void ff_opus_rc_enc_uint(OpusEncRangeCoder *rc, uint32_t val, uint32_t size); +void ff_opus_rc_put_raw(OpusEncRangeCoder *rc, uint32_t val, uint32_t count); +void ff_opus_rc_enc_laplace(OpusEncRangeCoder *rc, int *value, uint32_t symbol, int decay); +void ff_opus_rc_enc_end(OpusEncRangeCoder *rc, uint8_t *dst, int size); +void ff_opus_rc_enc_init(OpusEncRangeCoder *rc); + +#define OPUS_RC_CHECKPOINT_UPDATE(rc) \ + rc_rollback_bits = opus_rc_tell_frac(&rc->c); \ + rc_rollback_ctx = *rc + +#define OPUS_RC_CHECKPOINT_SPAWN(rc) \ + uint32_t rc_rollback_bits = opus_rc_tell_frac(&rc->c); \ + OpusEncRangeCoder rc_rollback_ctx = *rc \ + +#define OPUS_RC_CHECKPOINT_BITS(rc) \ + (opus_rc_tell_frac(&rc->c) - rc_rollback_bits) + +#define OPUS_RC_CHECKPOINT_ROLLBACK(rc) \ + memcpy(rc, &rc_rollback_ctx, sizeof(*rc)); \ + +#endif /* AVCODEC_OPUSENC_RC_H */