From patchwork Fri Sep 17 02:08:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 30303 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp1784536iov; Thu, 16 Sep 2021 19:09:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxtnlGZgkgHpjhbEyul5FaayqDoXwLA3YkofuBv4dXxlnbcrA6KYL/msuI4YJZEfMcPCtPg X-Received: by 2002:a17:907:995a:: with SMTP id kl26mr9691663ejc.6.1631844543118; Thu, 16 Sep 2021 19:09:03 -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 h4si69875ejo.291.2021.09.16.19.09.02; Thu, 16 Sep 2021 19:09:03 -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=IaKgoP9e; 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 0E3F968B104; Fri, 17 Sep 2021 05:08:35 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-oln040092075092.outbound.protection.outlook.com [40.92.75.92]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 49B3068B0FC for ; Fri, 17 Sep 2021 05:08:28 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PnFxGzmmUAXJ3POdrqbK6SIm9RHtslpSf+u9s/z8CYMfmE1y51+UL33EDQAH+OuaZJEsa3ncX1U6CcCQ4bO/sScd1xsGjKvGKZLpIuHgr7nfv/4DGclzwc8AuP0PvNBn3CjZYYkGZFhnHU0gcwPlRNcHpjgWlr4yiJFXI5dJgUJpuOW2Wq1xNrsC9tDnwQg6HzHAG09BVJAzVXsXbfVwqlz5gkB75/rKh4R85VcYLG0L5E36dVBBpFrP4sDopVudOC4U0TKuiIlLDV78rXS/xBjmQ5swcuJx/TXg4eTBmvTvoH6V/84ILxByT4Q+BuaXfTOJ/QLIeMmm9RT6zk967w== 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; bh=qB89A5jcHjScCHwjzAtd/3ZDmtxCyPlltLj5Rsxo5FU=; b=V/f9RZ3ZpWtv7W4vxo7Hc7d8XcxbgGqer/MccMmQcmbg7EisVrHR3w2w5RL1bHGtUYteV/sl8Ztd21CO8m2NAXZr2g00wgnDc7fzJ80tEVyi3gKOt8/+97ugcK/ndDoimSxtt9pDrRxDNvo812n1xZ1kq9rumhk6DZDd+62Zl4i1dWNSg07XDhA/gkecii40Yxy0fQOQ/Q8N1JRiKOLQwUqmi+s7zqgjQka70P28oi2w0dVOMCOZgrqbJP1s33zA4Bx0RkxEH7CXVajvRmMeFUxYWqabguQuXe5KalO+koiY7D06vb5hcV1PO8d3Q1r20zm1KcZ+bXFOVmxqY1WD+g== 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=qB89A5jcHjScCHwjzAtd/3ZDmtxCyPlltLj5Rsxo5FU=; b=IaKgoP9ekpClTCSbfnyrSQe2meqavzXbLCNTBg3YQd9IK8k0/ZzMrWh/cV35JhJqwhz9V4txxM45atY6uYwQR1AOTzlyq5AsrVgdcLqopBSm+z90/PFcqNubTflCcynPgXmVA+fZahYelZdTqzt0LUB1o+t6xRAZLu1T0Tr0qW+wT0AHmS2ykuhceR6hFq5OmJbJonrSNwrEmPpe1zJCB3YoF/siBfwY8GGYGdVKqHv71L5mY6rlWHlDBcf4Ap3npvrjN5sVdo/e5MlWvyNMRjivF2OrttAatPeH/gClij4UK7KzSFBRrz0nax5xQGVXTCGsgIIOXG8AntW/ND3WSQ== Received: from AM7PR03MB6660.eurprd03.prod.outlook.com (2603:10a6:20b:1c1::22) by AM6PR03MB5297.eurprd03.prod.outlook.com (2603:10a6:20b:c5::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4523.16; Fri, 17 Sep 2021 02:08:23 +0000 Received: from AM7PR03MB6660.eurprd03.prod.outlook.com ([fe80::787b:2156:ca99:fe00]) by AM7PR03MB6660.eurprd03.prod.outlook.com ([fe80::787b:2156:ca99:fe00%3]) with mapi id 15.20.4523.016; Fri, 17 Sep 2021 02:08:23 +0000 From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Fri, 17 Sep 2021 04:08:01 +0200 Message-ID: X-Mailer: git-send-email 2.30.2 In-Reply-To: References: X-TMN: [K/0CuXy1H9uxnfsVS4DqjYB58XFRAAoU] X-ClientProxiedBy: AM8P191CA0018.EURP191.PROD.OUTLOOK.COM (2603:10a6:20b:21a::23) To AM7PR03MB6660.eurprd03.prod.outlook.com (2603:10a6:20b:1c1::22) X-Microsoft-Original-Message-ID: <20210917020808.275498-5-andreas.rheinhardt@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from sblaptop.fritz.box (188.192.142.38) by AM8P191CA0018.EURP191.PROD.OUTLOOK.COM (2603:10a6:20b:21a::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4523.14 via Frontend Transport; Fri, 17 Sep 2021 02:08:22 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b76c03e1-9712-49a5-e385-08d9798006e7 X-MS-Exchange-SLBlob-MailProps: +LiGfBxqLEv5Hy0oNvS+VrPA90rn0AJxKAxqBJZZVlSolG+hvtU2A5Etpzr7MPJC3bXaHfO74gmRIAPIvhbsivia9WWz1tVHaG5V5xFqv8qYjROalmH+jdo4+FRcNdLCkIZM2CpfVVAoQ4LPxcB1iyR8AmtJ1usfUADnhQjbmPd5fO3zilu2KfRebtTBON+UEyL2mTIdvHn8yb5xsscfc5/qLc6ZGcsKMQuEXcfIip/7UEX0ze18nWg3CMh3jiqUjgbsOfYDvzJWOgpTzbUAHdIoWApPVynmfbZ85T8A3wR4YORo4AqT9E08yjNdNhigEVVOSVyOFOQxolKmNDnWbOMAAE5ElwGZMdZJTde267jwMkn61KULJWwmULIbXwC9Q/DeFzOTVzG1hcCAE+rQKlwWQDSxt1sxY9fWq1/DVZa13+XV3VP0ZhU3C6SiBiK2iJyh1i7Pfilyapq1Qxp4yKdwBY6qJxjL8eN5ZoSAzQwMQ44y8wOnOuNLGcIS39beYpMnz/VWdth7vwsVsRuSoo0RG1mVUoS6ytzrKWDKqLauAdK1k5pMq8zfBh49jPhtBjel2kErUoKyzFf9HrOjEucG6xKuP54RyHUATy9gCDKbAcDSNVZYb6nyE/KGBcV+dXqRepvrY3ey7bLVCRuQ/SY0Q1sxHaYWCyF+rDM6Wa5sa2lKo4fXQc2zWVQfCeSErVMCkv8TtPzMRNhdk0al+XaPfVdnO5FP5RhvgQmxlS/OQUoK1ZQmX572elTuV+pnZTLFP5sfW50mrY24Na+H5WC+Mhu3Fmmt X-MS-TrafficTypeDiagnostic: AM6PR03MB5297: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: bHis66cluk3WZE6LdqZxJk9RVKIXuFCbIwGKPp/lVvEfQ+zBNbMlJQ9XsqFUBymkFroJh2wJPr6FzWiqVAbPuZ122rnUeViZbcCa+7FSzEjdc8poky6PLGhOgnp2sKw3wFK8MHa/aNp77ky/EO2gzUkqFVMx48LSD+dMtvjj4Qle9lrKl/83Kv0TUMXlF3AFIsWHDuZ0W+c+yDkCWh/WZLnEXID+JVt36oJB4WWyAKPDjF9aIm3yf64RB8a7kw9w4jgQf/Tio/+tdP+C5d3aHNvQnPiJIw2gynPynn27sw/m9vQ0Yjx0cgvD2t1OZzR+MiCkj0IW4N4pN+EPbxzDPnWhCKUQEyi1lSfmOSko7P52RzoUPQCc24OiFoRNrVXbkEUaEDw51adCBKoGNwU0bb3rbWt9YAGBVEQONhgYD8sxKHKjfUBB6gE9WWy/DjAnC8kUJpkT63l68S+Ab4Jn2Lvxh5XbaXVEnIG4hsHgOBs= X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: t+7ta9/gKU5JuXlErq7SdHG3BoOiDsChFGTjL9dU5wingQjkTWstblmjmK7nLLcNoB/7rGdhwycFEymgZU66QC8nHwM/98FEc19anlU4MDzqfQ4aa+NRVYhK/eqRVpBcF72ltm08dk2ksVBw/bUvNQ== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: b76c03e1-9712-49a5-e385-08d9798006e7 X-MS-Exchange-CrossTenant-AuthSource: AM7PR03MB6660.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Sep 2021 02:08:23.0381 (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: AM6PR03MB5297 Subject: [FFmpeg-devel] [PATCH 06/13] avcodec/elbg: Add persistent ELBGContext 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: rUXNFyFn1tgz It will be used in future commits to avoid having to allocate and free all the buffers used. Signed-off-by: Andreas Rheinhardt --- libavcodec/a64multienc.c | 8 ++++++-- libavcodec/cinepakenc.c | 5 ++++- libavcodec/elbg.c | 12 +++++++++++- libavcodec/elbg.h | 16 +++++++++++++--- libavcodec/msvideo1enc.c | 12 +++++++++--- libavcodec/roqvideoenc.c | 7 +++++-- libavfilter/vf_elbg.c | 5 ++++- 7 files changed, 52 insertions(+), 13 deletions(-) diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index 9ee0b07463..71a620b4ff 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -43,6 +43,7 @@ typedef struct A64Context { /* variables for multicolor modes */ + struct ELBGContext *elbg; AVLFG randctx; int mc_lifetime; int mc_use_5col; @@ -195,6 +196,9 @@ static void render_charset(AVCodecContext *avctx, uint8_t *charset, static av_cold int a64multi_close_encoder(AVCodecContext *avctx) { A64Context *c = avctx->priv_data; + + avpriv_elbg_free(&c->elbg); + av_freep(&c->mc_meta_charset); av_freep(&c->mc_best_cb); av_freep(&c->mc_charmap); @@ -333,8 +337,8 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, buf = pkt->data; /* calc optimal new charset + charmaps */ - ret = avpriv_do_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb, - CHARSET_CHARS, 50, charmap, &c->randctx); + ret = avpriv_elbg_do(&c->elbg, meta, 32, 1000 * c->mc_lifetime, + best_cb, CHARSET_CHARS, 50, charmap, &c->randctx); if (ret < 0) return ret; diff --git a/libavcodec/cinepakenc.c b/libavcodec/cinepakenc.c index 8e8b73ce1d..2984b93de3 100644 --- a/libavcodec/cinepakenc.c +++ b/libavcodec/cinepakenc.c @@ -127,6 +127,7 @@ typedef struct CinepakEncContext { int min_min_strips; int max_max_strips; int strip_number_delta_range; + struct ELBGContext *elbg; } CinepakEncContext; #define OFFSET(x) offsetof(CinepakEncContext, x) @@ -761,7 +762,8 @@ static int quantize(CinepakEncContext *s, int h, uint8_t *data[4], if (i < size) size = i; - avpriv_do_elbg(s->codebook_input, entry_size, i, codebook, size, 1, s->codebook_closest, &s->randctx); + avpriv_elbg_do(&s->elbg, s->codebook_input, entry_size, i, codebook, + size, 1, s->codebook_closest, &s->randctx); // set up vq_data, which contains a single MB vq_data[0] = vq_pict_buf; @@ -1161,6 +1163,7 @@ static av_cold int cinepak_encode_end(AVCodecContext *avctx) CinepakEncContext *s = avctx->priv_data; int x; + avpriv_elbg_free(&s->elbg); av_frame_free(&s->last_frame); av_frame_free(&s->best_frame); av_frame_free(&s->scratch_frame); diff --git a/libavcodec/elbg.c b/libavcodec/elbg.c index ac5c53161d..9eac802688 100644 --- a/libavcodec/elbg.c +++ b/libavcodec/elbg.c @@ -466,12 +466,17 @@ static int init_elbg(int *points, int dim, int numpoints, int *codebook, return ret; } -int avpriv_do_elbg(int *points, int dim, int numpoints, +int avpriv_elbg_do(ELBGContext **elbgp, int *points, int dim, int numpoints, int *codebook, int num_cb, int max_steps, int *closest_cb, AVLFG *rand_state) { + ELBGContext *const elbg = *elbgp ? *elbgp : av_mallocz(sizeof(*elbg)); int ret; + if (!elbg) + return AVERROR(ENOMEM); + *elbgp = elbg; + ret = init_elbg(points, dim, numpoints, codebook, num_cb, max_steps, closest_cb, rand_state); if (ret < 0) @@ -479,3 +484,8 @@ int avpriv_do_elbg(int *points, int dim, int numpoints, return do_elbg (points, dim, numpoints, codebook, num_cb, max_steps, closest_cb, rand_state); } + +av_cold void avpriv_elbg_free(ELBGContext **elbgp) +{ + av_freep(elbgp); +} diff --git a/libavcodec/elbg.h b/libavcodec/elbg.h index a9a19aa5e4..abeeb4ff44 100644 --- a/libavcodec/elbg.h +++ b/libavcodec/elbg.h @@ -23,11 +23,16 @@ #include "libavutil/lfg.h" +struct ELBGContext; + /** * Implementation of the Enhanced LBG Algorithm * Based on the paper "Neural Networks 14:1219-1237" that can be found in * http://citeseer.ist.psu.edu/patan01enhanced.html . * + * @param ctx A pointer to a pointer to an already allocated ELBGContext + * or a pointer to NULL. In the latter case, this function + * will allocate an ELBGContext and put a pointer to it in `*ctx`. * @param points Input points. * @param dim Dimension of the points. * @param numpoints Num of points in **points. @@ -38,8 +43,13 @@ * @param rand_state A random number generator state. Should be already initialized by av_lfg_init(). * @return < 0 in case of error, 0 otherwise */ -int avpriv_do_elbg(int *points, int dim, int numpoints, int *codebook, - int num_cb, int num_steps, int *closest_cb, - AVLFG *rand_state); +int avpriv_elbg_do(struct ELBGContext **ctx, int *points, int dim, + int numpoints, int *codebook, int num_cb, int num_steps, + int *closest_cb, AVLFG *rand_state); + +/** + * Free an ELBGContext and reset the pointer to it. + */ +void avpriv_elbg_free(struct ELBGContext **ctx); #endif /* AVCODEC_ELBG_H */ diff --git a/libavcodec/msvideo1enc.c b/libavcodec/msvideo1enc.c index fa65a2fbc4..d43013ba5f 100644 --- a/libavcodec/msvideo1enc.c +++ b/libavcodec/msvideo1enc.c @@ -36,6 +36,7 @@ */ typedef struct Msvideo1EncContext { AVCodecContext *avctx; + struct ELBGContext *elbg; AVLFG rnd; uint8_t *prev; @@ -117,7 +118,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } // try to find optimal value to fill whole 4x4 block score = 0; - avpriv_do_elbg (c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd); + avpriv_elbg_do(&c->elbg, c->block, 3, 16, c->avg, + 1, 1, c->output, &c->rnd); if(c->avg[0] == 1) // red component = 1 will be written as skip code c->avg[0] = 0; for(j = 0; j < 4; j++){ @@ -136,7 +138,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } // search for optimal filling of 2-color block score = 0; - avpriv_do_elbg (c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd); + avpriv_elbg_do(&c->elbg, c->block, 3, 16, c->codebook, + 2, 1, c->output, &c->rnd); // last output value should be always 1, swap codebooks if needed if(!c->output[15]){ for(i = 0; i < 3; i++) @@ -161,7 +164,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, // search for optimal filling of 2-color 2x2 subblocks score = 0; for(i = 0; i < 4; i++){ - avpriv_do_elbg (c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd); + avpriv_elbg_do(&c->elbg, c->block2 + i * 4 * 3, 3, 4, + c->codebook2 + i * 2 * 3, 2, 1, + c->output2 + i*4, &c->rnd); } // last value should be always 1, swap codebooks if needed if(!c->output2[15]){ @@ -286,6 +291,7 @@ static av_cold int encode_end(AVCodecContext *avctx) Msvideo1EncContext * const c = avctx->priv_data; av_freep(&c->prev); + avpriv_elbg_free(&c->elbg); return 0; } diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index 167e6bc806..316adac45e 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -133,6 +133,7 @@ typedef struct CelEvaluation { typedef struct RoqEncContext { RoqContext common; + struct ELBGContext *elbg; AVLFG randctx; uint64_t lambda; @@ -824,8 +825,8 @@ static int generate_codebook(RoqEncContext *enc, int *codebook = enc->tmp_codebook_buf; int *closest_cb = enc->closest_cb; - ret = avpriv_do_elbg(points, 6 * c_size, inputCount, codebook, - cbsize, 1, closest_cb, &enc->randctx); + ret = avpriv_elbg_do(&enc->elbg, points, 6 * c_size, inputCount, codebook, + cbsize, 1, closest_cb, &enc->randctx); if (ret < 0) return ret; @@ -961,6 +962,8 @@ static av_cold int roq_encode_end(AVCodecContext *avctx) av_freep(&enc->this_motion8); av_freep(&enc->last_motion8); + avpriv_elbg_free(&enc->elbg); + return 0; } diff --git a/libavfilter/vf_elbg.c b/libavfilter/vf_elbg.c index 79797ee25f..2c9c861d02 100644 --- a/libavfilter/vf_elbg.c +++ b/libavfilter/vf_elbg.c @@ -35,6 +35,7 @@ typedef struct ELBGFilterContext { const AVClass *class; + struct ELBGContext *ctx; AVLFG lfg; int64_t lfg_seed; int max_steps_nb; @@ -163,7 +164,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) } /* compute the codebook */ - avpriv_do_elbg(elbg->codeword, NB_COMPONENTS, elbg->codeword_length, + avpriv_elbg_do(&elbg->ctx, elbg->codeword, NB_COMPONENTS, elbg->codeword_length, elbg->codebook, elbg->codebook_length, elbg->max_steps_nb, elbg->codeword_closest_codebook_idxs, &elbg->lfg); @@ -223,6 +224,8 @@ static av_cold void uninit(AVFilterContext *ctx) { ELBGFilterContext *const elbg = ctx->priv; + avpriv_elbg_free(&elbg->ctx); + av_freep(&elbg->codebook); av_freep(&elbg->codeword); av_freep(&elbg->codeword_closest_codebook_idxs);