From patchwork Tue Dec 27 23:17:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39766 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3760925pzb; Tue, 27 Dec 2022 15:18:38 -0800 (PST) X-Google-Smtp-Source: AMrXdXthWQRMr2xDbCN1587BSZWxpjglziBfyfmPm+qfQdpUAbr7zeRtl68L2ZKLF24PGGoDOivP X-Received: by 2002:a17:906:7254:b0:7ad:bc7e:3ffd with SMTP id n20-20020a170906725400b007adbc7e3ffdmr21625539ejk.42.1672183117997; Tue, 27 Dec 2022 15:18:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183117; cv=none; d=google.com; s=arc-20160816; b=z+NbPH5KyyKTGIuY7uf+xbkJtEBaTmW02LMms+TcC2GJeakhWt7Y2F3jiktckkaiWK +slN7+SW8iZECwY9hNBwppfcAqbAlIX37paMZ4qH3UfkXDu+Ey4Ro1Bg/WNFmHV/3OBN bboaLQDM5LT8iRc8PW0LVZQRF7xhiSNiaHvdqx2Nk1Xg/FZhtGoCdGTF9BmkPFptJ33c 3k2TBShn+/pjJKN4k34LVoUAiaO2OaBSoq7UXkE3D2Glbb9V59w69ckvCF/DTf0TwWA5 KJthvLB77crxU9CmasJ2LUtlfxdfRrJWSlDqGdMCpVN6OBeAKLbtmtuNhUyY9tuR/4Yk h9ug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=mapuzmOHRX8Bj4zdO6+MxSMWn0BhG7fDxc1JWjIX0xk=; b=PKAgLTree7iv61uyD7FjHUqLAsKLdxNcn627N7P2NMrr3dCmQkoDUmr0GqwXibHfKf T1xky+lMoisKTAUC5xWdaR7efa+vuSffZTKlZqD+0U/+2Rlz5iz1WE0C/+z8MyhOLQV3 GQ/4HVtErlWuBthj84q05Eif2I9GO5EYC/Ea9dHF9Vk3YL1QZl3y0RWbvFMtcMytwmFH Z+idxYc+0brvMqanO1lqza/f/LOd5YIiilYhtZK3rRQJWbSPvZcCg7KBvpP4mCH8rdV3 Fr0w6HSCfRhl6T+gbit1rD9bUsnqAopdl1hrhgXhtJ5g0WWSpRvbYhJ1IL3PsAoLI4Xc dMUg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=GzBjqvbB; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id dd20-20020a1709069b9400b007c175331850si10603555ejc.428.2022.12.27.15.18.37; Tue, 27 Dec 2022 15:18:37 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=GzBjqvbB; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0DF4E68BC53; Wed, 28 Dec 2022 01:18:29 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 88E5A68BC53 for ; Wed, 28 Dec 2022 01:18:21 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Oy5zcOG5G18oWEjAEA13JG/XUChDvPy0RptZ0dY5Mog=; b=GzBjqvbBJmZcxSJJAJBm4+4YjV5xYAW8g2iLt2VmJajRFde8JUtuAJIvDIcgd98/yaQ14M Wp23NFYyJ9KQXB6XQ8FGCbX9PrSuG4ec6EO17kYKpRVtCOM5irVPiZzRJ46SNUzjXfLUpZ KlxX/8unWl+x1AgpMG03GucnMjDgR4Y= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 2bda8894; Tue, 27 Dec 2022 23:18:16 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:43 +0100 Message-Id: <20221227231814.2520181-2-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 01/32] avfilter/palettegen: allow a minimum of 2 colors 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: n/2hJxGrS1n4 --- libavfilter/vf_palettegen.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 27f74fd147..c03f62b942 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -82,7 +82,7 @@ typedef struct PaletteGenContext { #define OFFSET(x) offsetof(PaletteGenContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM static const AVOption palettegen_options[] = { - { "max_colors", "set the maximum number of colors to use in the palette", OFFSET(max_colors), AV_OPT_TYPE_INT, {.i64=256}, 4, 256, FLAGS }, + { "max_colors", "set the maximum number of colors to use in the palette", OFFSET(max_colors), AV_OPT_TYPE_INT, {.i64=256}, 2, 256, FLAGS }, { "reserve_transparent", "reserve a palette entry for transparency", OFFSET(reserve_transparent), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { "transparency_color", "set a background color for transparency", OFFSET(transparency_color), AV_OPT_TYPE_COLOR, {.str="lime"}, 0, 0, FLAGS }, { "stats_mode", "set statistics mode", OFFSET(stats_mode), AV_OPT_TYPE_INT, {.i64=STATS_MODE_ALL_FRAMES}, 0, NB_STATS_MODE-1, FLAGS, "mode" }, @@ -586,6 +586,11 @@ static int init(AVFilterContext *ctx) if (s->use_alpha && s->reserve_transparent) s->reserve_transparent = 0; + if (s->max_colors - s->reserve_transparent < 2) { + av_log(ctx, AV_LOG_ERROR, "max_colors=2 is only allowed without reserving a transparent color slot\n"); + return AVERROR(EINVAL); + } + return 0; } From patchwork Tue Dec 27 23:17:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39769 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761002pzb; Tue, 27 Dec 2022 15:18:47 -0800 (PST) X-Google-Smtp-Source: AMrXdXtY5ek4XURVDRS4eynb3f6Q/Ue6gBLcBFKT4Bj5jW2atrtTUUpJg9NpUAwKV7VD9JSXK+Dy X-Received: by 2002:a17:907:d311:b0:829:5e3f:3c92 with SMTP id vg17-20020a170907d31100b008295e3f3c92mr27473995ejc.73.1672183127451; Tue, 27 Dec 2022 15:18:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183127; cv=none; d=google.com; s=arc-20160816; b=WZAf9cjaqB/MPUP3I9bSXyahbEapCSa6I1gjoTbv7kxw4BGKpXJywUym+8dzOoVF4t 4Kegv40znGAF2dlwSQK1uHHK0SfU4oVQEMfJqICPYbRNHKrZEWZNc4YUQK2dXlmromuC VukiIFADcHI8HehDLshwyk9NqfCMVv1++SGu49yKk0qPz5+kW3fbhwX4xsbqz3F7g6Me dg9m1lDp1H7XL90irCEKdjBvfJyT2/s9UWzBHuLTz5jz9dU4cqBBsuQJCuUymHKeB3op CCnIqf+gIwuFqhg9tv4LS8OSLmebwVKhoMCQGVl40rWc8LOLb+AR/LL3aA/gA2bGQDEh x9dA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=kDTa+HVoBAwHTNgQJcQaGOEQPxNUpRoC7HIPokmoy6w=; b=RTR0LpgzAZ1NhCKHiW7xx7xhYKmNtuZlhMRqg8ud0NUPoZJRcoPHp4m+HlrGzYJ1zw HdTlINIs1cBzJuDPgtgOcZHSMEoRK6KgWwLJU461x2APm5mVQsKOVBptZY3dsbNd4VSx Oy4g13LkSJ3BlExoY4oX/4DaqupYRk0J6LcDnwBGPvC4VB6dRFYbSZEhtE7EJnpb60W+ 1juhw284ZAJOPSKXO5GGr5G5R7wbvEEpOulDlw4BSl710tukorkZlJtgRXyK7KvXPMT0 UHR8x3a47a7cADZgg3mQOnWBqVolKYSh2sOTv4eKX2GZokGb3xj8zDYEv+bbc698tvPM 3QWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=AX+jsVNI; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id nc17-20020a1709071c1100b007ae83c51922si13010899ejc.45.2022.12.27.15.18.46; Tue, 27 Dec 2022 15:18:47 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=AX+jsVNI; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id F353968BC91; Wed, 28 Dec 2022 01:18:29 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0E23168BC53 for ; Wed, 28 Dec 2022 01:18:22 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1+tyxww0RaTfULpCwUFELdjRAhuGW7huVzYR3K6O0F0=; b=AX+jsVNI8cI7qPGHlyS9gpYrz8ESy5Ud6A8MKbhSAhHoaA3RvODK/c2ZfUZ/6GijEBKclL ZuTZaIeCxx5mKcZaRwjhyxP/fa3xlSmbeuAO76F3ta+akENzKtAoV6aHswgjlM49YPN3hX 0nCjTkZXr0m37YQWGtxK4GJS+IzJo+c= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id d93a32c1; Tue, 27 Dec 2022 23:18:16 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:44 +0100 Message-Id: <20221227231814.2520181-3-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 02/32] avfilter/palette{gen, use}: revert support palettes with alpha 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: qhsPJowUHSzB This reverts commit dea673d0d548c864ec85f9260d8900d944ef7a2a. This change cannot work for several reasons, the most obvious ones are: - the alpha is being part of the scoring of the color difference, even though we can not interpret the alpha as part of the perception of the color (we don't even know if it's premultiplied or postmultiplied) - the colors are averaged with their alpha value which simply cannot work The command proposed in the original thread of the patch actually produces a completely broken file: ffmpeg -y -loglevel verbose -i fate-suite/apng/o_sample.png -filter_complex "split[split1][split2];[split1]palettegen=max_colors=254:use_alpha=1[pal1];[split2][pal1]paletteuse=use_alpha=1" -frames:v 1 out.png We can see that many color pixels are off, but more importantly some colors have a random alpha value: https://imgur.com/eFQ2UK7 I don't see any easy fix for this unfortunately, the approach appears to be flawed by design. --- doc/filters.texi | 8 -- libavfilter/vf_palettegen.c | 127 +++++++------------- libavfilter/vf_paletteuse.c | 225 +++++++++++++++--------------------- 3 files changed, 138 insertions(+), 222 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 9b866de5ae..f51623d16a 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -18474,9 +18474,6 @@ Compute new histogram for each frame. @end table Default value is @var{full}. -@item use_alpha -Create a palette of colors with alpha components. -Setting this, will automatically disable 'reserve_transparent'. @end table The filter also exports the frame metadata @code{lavfi.color_quant_ratio} @@ -18555,11 +18552,6 @@ will be treated as completely opaque, and values below this threshold will be treated as completely transparent. The option must be an integer value in the range [0,255]. Default is @var{128}. - -@item use_alpha -Apply the palette by taking alpha values into account. Only useful with -palettes that are containing multiple colors with alpha components. -Setting this will automatically disable 'alpha_treshold'. @end table @subsection Examples diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index c03f62b942..bea3292796 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -59,7 +59,7 @@ enum { }; #define NBITS 5 -#define HIST_SIZE (1<<(4*NBITS)) +#define HIST_SIZE (1<<(3*NBITS)) typedef struct PaletteGenContext { const AVClass *class; @@ -67,7 +67,6 @@ typedef struct PaletteGenContext { int max_colors; int reserve_transparent; int stats_mode; - int use_alpha; AVFrame *prev_frame; // previous frame used for the diff stats_mode struct hist_node histogram[HIST_SIZE]; // histogram/hashtable of the colors @@ -89,7 +88,6 @@ static const AVOption palettegen_options[] = { { "full", "compute full frame histograms", 0, AV_OPT_TYPE_CONST, {.i64=STATS_MODE_ALL_FRAMES}, INT_MIN, INT_MAX, FLAGS, "mode" }, { "diff", "compute histograms only for the part that differs from previous frame", 0, AV_OPT_TYPE_CONST, {.i64=STATS_MODE_DIFF_FRAMES}, INT_MIN, INT_MAX, FLAGS, "mode" }, { "single", "compute new histogram for each frame", 0, AV_OPT_TYPE_CONST, {.i64=STATS_MODE_SINGLE_FRAMES}, INT_MIN, INT_MAX, FLAGS, "mode" }, - { "use_alpha", "create a palette including alpha values", OFFSET(use_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS }, { NULL } }; @@ -115,16 +113,15 @@ static int cmp_##name(const void *pa, const void *pb) \ { \ const struct color_ref * const *a = pa; \ const struct color_ref * const *b = pb; \ - return (int)((*a)->color >> (8 * (3 - (pos))) & 0xff) \ - - (int)((*b)->color >> (8 * (3 - (pos))) & 0xff); \ + return (int)((*a)->color >> (8 * (2 - (pos))) & 0xff) \ + - (int)((*b)->color >> (8 * (2 - (pos))) & 0xff); \ } -DECLARE_CMP_FUNC(a, 0) -DECLARE_CMP_FUNC(r, 1) -DECLARE_CMP_FUNC(g, 2) -DECLARE_CMP_FUNC(b, 3) +DECLARE_CMP_FUNC(r, 0) +DECLARE_CMP_FUNC(g, 1) +DECLARE_CMP_FUNC(b, 2) -static const cmp_func cmp_funcs[] = {cmp_a, cmp_r, cmp_g, cmp_b}; +static const cmp_func cmp_funcs[] = {cmp_r, cmp_g, cmp_b}; /** * Simple color comparison for sorting the final palette @@ -146,17 +143,6 @@ static av_always_inline int diff(const uint32_t a, const uint32_t b) return dr*dr + dg*dg + db*db; } -static av_always_inline int diff_alpha(const uint32_t a, const uint32_t b) -{ - const uint8_t c1[] = {a >> 24 & 0xff, a >> 16 & 0xff, a >> 8 & 0xff, a & 0xff}; - const uint8_t c2[] = {b >> 24 & 0xff, b >> 16 & 0xff, b >> 8 & 0xff, b & 0xff}; - const int da = c1[0] - c2[0]; - const int dr = c1[1] - c2[1]; - const int dg = c1[2] - c2[2]; - const int db = c1[3] - c2[3]; - return da*da + dr*dr + dg*dg + db*db; -} - /** * Find the next box to split: pick the one with the highest variance */ @@ -178,10 +164,7 @@ static int get_next_box_id_to_split(PaletteGenContext *s) for (i = 0; i < box->len; i++) { const struct color_ref *ref = s->refs[box->start + i]; - if (s->use_alpha) - variance += (int64_t)diff_alpha(ref->color, box->color) * ref->count; - else - variance += (int64_t)diff(ref->color, box->color) * ref->count; + variance += diff(ref->color, box->color) * ref->count; } box->variance = variance; } @@ -201,31 +184,24 @@ static int get_next_box_id_to_split(PaletteGenContext *s) * specified box. Takes into account the weight of each color. */ static uint32_t get_avg_color(struct color_ref * const *refs, - const struct range_box *box, int use_alpha) + const struct range_box *box) { int i; const int n = box->len; - uint64_t a = 0, r = 0, g = 0, b = 0, div = 0; + uint64_t r = 0, g = 0, b = 0, div = 0; for (i = 0; i < n; i++) { const struct color_ref *ref = refs[box->start + i]; - if (use_alpha) - a += (ref->color >> 24 & 0xff) * ref->count; - r += (ref->color >> 16 & 0xff) * ref->count; - g += (ref->color >> 8 & 0xff) * ref->count; - b += (ref->color & 0xff) * ref->count; + r += (ref->color >> 16 & 0xff) * ref->count; + g += (ref->color >> 8 & 0xff) * ref->count; + b += (ref->color & 0xff) * ref->count; div += ref->count; } - if (use_alpha) - a = a / div; r = r / div; g = g / div; b = b / div; - if (use_alpha) - return a<<24 | r<<16 | g<<8 | b; - return 0xffU<<24 | r<<16 | g<<8 | b; } @@ -244,8 +220,8 @@ static void split_box(PaletteGenContext *s, struct range_box *box, int n) av_assert0(box->len >= 1); av_assert0(new_box->len >= 1); - box->color = get_avg_color(s->refs, box, s->use_alpha); - new_box->color = get_avg_color(s->refs, new_box, s->use_alpha); + box->color = get_avg_color(s->refs, box); + new_box->color = get_avg_color(s->refs, new_box); box->variance = -1; new_box->variance = -1; } @@ -275,7 +251,7 @@ static void write_palette(AVFilterContext *ctx, AVFrame *out) pal += pal_linesize; } - if (s->reserve_transparent && !s->use_alpha) { + if (s->reserve_transparent) { av_assert0(s->nb_boxes < 256); pal[out->width - pal_linesize - 1] = AV_RB32(&s->transparency_color) >> 8; } @@ -343,49 +319,40 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) box = &s->boxes[box_id]; box->len = s->nb_refs; box->sorted_by = -1; - box->color = get_avg_color(s->refs, box, s->use_alpha); + box->color = get_avg_color(s->refs, box); box->variance = -1; s->nb_boxes = 1; while (box && box->len > 1) { - int i, ar, rr, gr, br, longest; + int i, rr, gr, br, longest; uint64_t median, box_weight = 0; /* compute the box weight (sum all the weights of the colors in the * range) and its boundings */ - uint8_t min[4] = {0xff, 0xff, 0xff, 0xff}; - uint8_t max[4] = {0x00, 0x00, 0x00, 0x00}; + uint8_t min[3] = {0xff, 0xff, 0xff}; + uint8_t max[3] = {0x00, 0x00, 0x00}; for (i = box->start; i < box->start + box->len; i++) { const struct color_ref *ref = s->refs[i]; const uint32_t rgb = ref->color; - const uint8_t a = rgb >> 24 & 0xff, r = rgb >> 16 & 0xff, g = rgb >> 8 & 0xff, b = rgb & 0xff; - min[0] = FFMIN(a, min[0]); max[0] = FFMAX(a, max[0]); - min[1] = FFMIN(r, min[1]); max[1] = FFMAX(r, max[1]); - min[2] = FFMIN(g, min[2]); max[2] = FFMAX(g, max[2]); - min[3] = FFMIN(b, min[3]); max[3] = FFMAX(b, max[3]); + const uint8_t r = rgb >> 16 & 0xff, g = rgb >> 8 & 0xff, b = rgb & 0xff; + min[0] = FFMIN(r, min[0]), max[0] = FFMAX(r, max[0]); + min[1] = FFMIN(g, min[1]), max[1] = FFMAX(g, max[1]); + min[2] = FFMIN(b, min[2]), max[2] = FFMAX(b, max[2]); box_weight += ref->count; } /* define the axis to sort by according to the widest range of colors */ - ar = max[0] - min[0]; - rr = max[1] - min[1]; - gr = max[2] - min[2]; - br = max[3] - min[3]; - longest = 2; // pick green by default (the color the eye is the most sensitive to) - if (s->use_alpha) { - if (ar >= rr && ar >= br && ar >= gr) longest = 0; - if (br >= rr && br >= gr && br >= ar) longest = 3; - if (rr >= gr && rr >= br && rr >= ar) longest = 1; - if (gr >= rr && gr >= br && gr >= ar) longest = 2; // prefer green again - } else { - if (br >= rr && br >= gr) longest = 3; - if (rr >= gr && rr >= br) longest = 1; - if (gr >= rr && gr >= br) longest = 2; // prefer green again - } - - ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" ranges:[%2x %2x %2x %2x] sort by %c (already sorted:%c) ", + rr = max[0] - min[0]; + gr = max[1] - min[1]; + br = max[2] - min[2]; + longest = 1; // pick green by default (the color the eye is the most sensitive to) + if (br >= rr && br >= gr) longest = 2; + if (rr >= gr && rr >= br) longest = 0; + if (gr >= rr && gr >= br) longest = 1; // prefer green again + + ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" ranges:[%2x %2x %2x] sort by %c (already sorted:%c) ", box_id, box->start, box->start + box->len - 1, box->len, box_weight, - ar, rr, gr, br, "argb"[longest], box->sorted_by == longest ? 'y' : 'n'); + rr, gr, br, "rgb"[longest], box->sorted_by == longest ? 'y':'n'); /* sort the range by its longest axis if it's not already sorted */ if (box->sorted_by != longest) { @@ -427,27 +394,22 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) * It keeps the NBITS least significant bit of each component to make it * "random" even if the scene doesn't have much different colors. */ -static inline unsigned color_hash(uint32_t color, int use_alpha) +static inline unsigned color_hash(uint32_t color) { const uint8_t r = color >> 16 & ((1<> 8 & ((1<> 24 & ((1 << NBITS) - 1); - return a << (NBITS * 3) | r << (NBITS * 2) | g << NBITS | b; - } - return r << (NBITS * 2) | g << NBITS | b; } /** * Locate the color in the hash table and increment its counter. */ -static int color_inc(struct hist_node *hist, uint32_t color, int use_alpha) +static int color_inc(struct hist_node *hist, uint32_t color) { int i; - const unsigned hash = color_hash(color, use_alpha); + const unsigned hash = color_hash(color); struct hist_node *node = &hist[hash]; struct color_ref *e; @@ -472,7 +434,7 @@ static int color_inc(struct hist_node *hist, uint32_t color, int use_alpha) * Update histogram when pixels differ from previous frame. */ static int update_histogram_diff(struct hist_node *hist, - const AVFrame *f1, const AVFrame *f2, int use_alpha) + const AVFrame *f1, const AVFrame *f2) { int x, y, ret, nb_diff_colors = 0; @@ -483,7 +445,7 @@ static int update_histogram_diff(struct hist_node *hist, for (x = 0; x < f1->width; x++) { if (p[x] == q[x]) continue; - ret = color_inc(hist, p[x], use_alpha); + ret = color_inc(hist, p[x]); if (ret < 0) return ret; nb_diff_colors += ret; @@ -495,7 +457,7 @@ static int update_histogram_diff(struct hist_node *hist, /** * Simple histogram of the frame. */ -static int update_histogram_frame(struct hist_node *hist, const AVFrame *f, int use_alpha) +static int update_histogram_frame(struct hist_node *hist, const AVFrame *f) { int x, y, ret, nb_diff_colors = 0; @@ -503,7 +465,7 @@ static int update_histogram_frame(struct hist_node *hist, const AVFrame *f, int const uint32_t *p = (const uint32_t *)(f->data[0] + y*f->linesize[0]); for (x = 0; x < f->width; x++) { - ret = color_inc(hist, p[x], use_alpha); + ret = color_inc(hist, p[x]); if (ret < 0) return ret; nb_diff_colors += ret; @@ -519,8 +481,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; PaletteGenContext *s = ctx->priv; - int ret = s->prev_frame ? update_histogram_diff(s->histogram, s->prev_frame, in, s->use_alpha) - : update_histogram_frame(s->histogram, in, s->use_alpha); + int ret = s->prev_frame ? update_histogram_diff(s->histogram, s->prev_frame, in) + : update_histogram_frame(s->histogram, in); if (ret > 0) s->nb_refs += ret; @@ -583,9 +545,6 @@ static int init(AVFilterContext *ctx) { PaletteGenContext* s = ctx->priv; - if (s->use_alpha && s->reserve_transparent) - s->reserve_transparent = 0; - if (s->max_colors - s->reserve_transparent < 2) { av_log(ctx, AV_LOG_ERROR, "max_colors=2 is only allowed without reserving a transparent color slot\n"); return AVERROR(EINVAL); diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index a6b5d5a5fa..cb18329bb7 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -29,6 +29,7 @@ #include "libavutil/opt.h" #include "libavutil/qsort.h" #include "avfilter.h" +#include "filters.h" #include "framesync.h" #include "internal.h" @@ -63,7 +64,7 @@ struct color_node { }; #define NBITS 5 -#define CACHE_SIZE (1<<(4*NBITS)) +#define CACHE_SIZE (1<<(3*NBITS)) struct cached_color { uint32_t color; @@ -88,7 +89,6 @@ typedef struct PaletteUseContext { uint32_t palette[AVPALETTE_COUNT]; int transparency_index; /* index in the palette of transparency. -1 if there is no transparency in the palette. */ int trans_thresh; - int use_alpha; int palette_loaded; int dither; int new; @@ -108,7 +108,7 @@ typedef struct PaletteUseContext { } PaletteUseContext; #define OFFSET(x) offsetof(PaletteUseContext, x) -#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM static const AVOption paletteuse_options[] = { { "dither", "select dithering mode", OFFSET(dither), AV_OPT_TYPE_INT, {.i64=DITHERING_SIERRA2_4A}, 0, NB_DITHERING-1, FLAGS, "dithering_mode" }, { "bayer", "ordered 8x8 bayer dithering (deterministic)", 0, AV_OPT_TYPE_CONST, {.i64=DITHERING_BAYER}, INT_MIN, INT_MAX, FLAGS, "dithering_mode" }, @@ -121,7 +121,6 @@ static const AVOption paletteuse_options[] = { { "rectangle", "process smallest different rectangle", 0, AV_OPT_TYPE_CONST, {.i64=DIFF_MODE_RECTANGLE}, INT_MIN, INT_MAX, FLAGS, "diff_mode" }, { "new", "take new palette for each output frame", OFFSET(new), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { "alpha_threshold", "set the alpha threshold for transparency", OFFSET(trans_thresh), AV_OPT_TYPE_INT, {.i64=128}, 0, 255, FLAGS }, - { "use_alpha", "use alpha channel for mapping", OFFSET(use_alpha), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, /* following are the debug options, not part of the official API */ { "debug_kdtree", "save Graphviz graph of the kdtree in specified file", OFFSET(dot_filename), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, @@ -163,41 +162,37 @@ static av_always_inline uint32_t dither_color(uint32_t px, int er, int eg, | av_clip_uint8((px & 0xff) + ((eb * scale) / (1<use_alpha) - return da*da + dr*dr + dg*dg + db*db; - - if (c1[0] < s->trans_thresh && c2[0] < s->trans_thresh) { + if (c1[0] < trans_thresh && c2[0] < trans_thresh) { return 0; - } else if (c1[0] >= s->trans_thresh && c2[0] >= s->trans_thresh) { + } else if (c1[0] >= trans_thresh && c2[0] >= trans_thresh) { return dr*dr + dg*dg + db*db; } else { return 255*255 + 255*255 + 255*255; } } -static av_always_inline uint8_t colormap_nearest_bruteforce(const PaletteUseContext *s, const uint8_t *argb) +static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *palette, const uint8_t *argb, const int trans_thresh) { int i, pal_id = -1, min_dist = INT_MAX; for (i = 0; i < AVPALETTE_COUNT; i++) { - const uint32_t c = s->palette[i]; + const uint32_t c = palette[i]; - if (s->use_alpha || c >> 24 >= s->trans_thresh) { // ignore transparent entry + if (c >> 24 >= trans_thresh) { // ignore transparent entry const uint8_t palargb[] = { - s->palette[i]>>24 & 0xff, - s->palette[i]>>16 & 0xff, - s->palette[i]>> 8 & 0xff, - s->palette[i] & 0xff, + palette[i]>>24 & 0xff, + palette[i]>>16 & 0xff, + palette[i]>> 8 & 0xff, + palette[i] & 0xff, }; - const int d = diff(palargb, argb, s); + const int d = diff(palargb, argb, trans_thresh); if (d < min_dist) { pal_id = i; min_dist = d; @@ -213,17 +208,17 @@ struct nearest_color { int dist_sqd; }; -static void colormap_nearest_node(const PaletteUseContext *s, - const struct color_node *map, +static void colormap_nearest_node(const struct color_node *map, const int node_pos, const uint8_t *target, + const int trans_thresh, struct nearest_color *nearest) { const struct color_node *kd = map + node_pos; - const int split = kd->split; + const int s = kd->split; int dx, nearer_kd_id, further_kd_id; const uint8_t *current = kd->val; - const int current_to_target = diff(target, current, s); + const int current_to_target = diff(target, current, trans_thresh); if (current_to_target < nearest->dist_sqd) { nearest->node_pos = node_pos; @@ -231,23 +226,23 @@ static void colormap_nearest_node(const PaletteUseContext *s, } if (kd->left_id != -1 || kd->right_id != -1) { - dx = target[split] - current[split]; + dx = target[s] - current[s]; if (dx <= 0) nearer_kd_id = kd->left_id, further_kd_id = kd->right_id; else nearer_kd_id = kd->right_id, further_kd_id = kd->left_id; if (nearer_kd_id != -1) - colormap_nearest_node(s, map, nearer_kd_id, target, nearest); + colormap_nearest_node(map, nearer_kd_id, target, trans_thresh, nearest); if (further_kd_id != -1 && dx*dx < nearest->dist_sqd) - colormap_nearest_node(s, map, further_kd_id, target, nearest); + colormap_nearest_node(map, further_kd_id, target, trans_thresh, nearest); } } -static av_always_inline uint8_t colormap_nearest_recursive(const PaletteUseContext *s, const struct color_node *node, const uint8_t *rgb) +static av_always_inline uint8_t colormap_nearest_recursive(const struct color_node *node, const uint8_t *rgb, const int trans_thresh) { struct nearest_color res = {.dist_sqd = INT_MAX, .node_pos = -1}; - colormap_nearest_node(s, node, 0, rgb, &res); + colormap_nearest_node(node, 0, rgb, trans_thresh, &res); return node[res.node_pos].palette_id; } @@ -256,7 +251,7 @@ struct stack_node { int dx2; }; -static av_always_inline uint8_t colormap_nearest_iterative(const PaletteUseContext *s, const struct color_node *root, const uint8_t *target) +static av_always_inline uint8_t colormap_nearest_iterative(const struct color_node *root, const uint8_t *target, const int trans_thresh) { int pos = 0, best_node_id = -1, best_dist = INT_MAX, cur_color_id = 0; struct stack_node nodes[16]; @@ -266,7 +261,7 @@ static av_always_inline uint8_t colormap_nearest_iterative(const PaletteUseConte const struct color_node *kd = &root[cur_color_id]; const uint8_t *current = kd->val; - const int current_to_target = diff(target, current, s); + const int current_to_target = diff(target, current, trans_thresh); /* Compare current color node to the target and update our best node if * it's actually better. */ @@ -328,10 +323,10 @@ end: return root[best_node_id].palette_id; } -#define COLORMAP_NEAREST(s, search, root, target) \ - search == COLOR_SEARCH_NNS_ITERATIVE ? colormap_nearest_iterative(s, root, target) : \ - search == COLOR_SEARCH_NNS_RECURSIVE ? colormap_nearest_recursive(s, root, target) : \ - colormap_nearest_bruteforce(s, target) +#define COLORMAP_NEAREST(search, palette, root, target, trans_thresh) \ + search == COLOR_SEARCH_NNS_ITERATIVE ? colormap_nearest_iterative(root, target, trans_thresh) : \ + search == COLOR_SEARCH_NNS_RECURSIVE ? colormap_nearest_recursive(root, target, trans_thresh) : \ + colormap_nearest_bruteforce(palette, target, trans_thresh) /** * Check if the requested color is in the cache already. If not, find it in the @@ -368,13 +363,13 @@ static av_always_inline int color_get(PaletteUseContext *s, uint32_t color, if (!e) return AVERROR(ENOMEM); e->color = color; - e->pal_entry = COLORMAP_NEAREST(s, search_method, s->map, argb_elts); + e->pal_entry = COLORMAP_NEAREST(search_method, s->palette, s->map, argb_elts, s->trans_thresh); return e->pal_entry; } static av_always_inline int get_dst_color_err(PaletteUseContext *s, - uint32_t c, int *ea, int *er, int *eg, int *eb, + uint32_t c, int *er, int *eg, int *eb, const enum color_search_method search_method) { const uint8_t a = c >> 24 & 0xff; @@ -387,9 +382,8 @@ static av_always_inline int get_dst_color_err(PaletteUseContext *s, return dstx; dstc = s->palette[dstx]; if (dstx == s->transparency_index) { - *ea =*er = *eg = *eb = 0; + *er = *eg = *eb = 0; } else { - *ea = (int)a - (int)(dstc >> 24 & 0xff); *er = (int)r - (int)(dstc >> 16 & 0xff); *eg = (int)g - (int)(dstc >> 8 & 0xff); *eb = (int)b - (int)(dstc & 0xff); @@ -413,7 +407,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram for (y = y_start; y < h; y++) { for (x = x_start; x < w; x++) { - int ea, er, eg, eb; + int er, eg, eb; if (dither == DITHERING_BAYER) { const int d = s->ordered_dither[(y & 7)<<3 | (x & 7)]; @@ -433,7 +427,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram } else if (dither == DITHERING_HECKBERT) { const int right = x < w - 1, down = y < h - 1; - const int color = get_dst_color_err(s, src[x], &ea, &er, &eg, &eb, search_method); + const int color = get_dst_color_err(s, src[x], &er, &eg, &eb, search_method); if (color < 0) return color; @@ -445,7 +439,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram } else if (dither == DITHERING_FLOYD_STEINBERG) { const int right = x < w - 1, down = y < h - 1, left = x > x_start; - const int color = get_dst_color_err(s, src[x], &ea, &er, &eg, &eb, search_method); + const int color = get_dst_color_err(s, src[x], &er, &eg, &eb, search_method); if (color < 0) return color; @@ -459,7 +453,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram } else if (dither == DITHERING_SIERRA2) { const int right = x < w - 1, down = y < h - 1, left = x > x_start; const int right2 = x < w - 2, left2 = x > x_start + 1; - const int color = get_dst_color_err(s, src[x], &ea, &er, &eg, &eb, search_method); + const int color = get_dst_color_err(s, src[x], &er, &eg, &eb, search_method); if (color < 0) return color; @@ -478,7 +472,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram } else if (dither == DITHERING_SIERRA2_4A) { const int right = x < w - 1, down = y < h - 1, left = x > x_start; - const int color = get_dst_color_err(s, src[x], &ea, &er, &eg, &eb, search_method); + const int color = get_dst_color_err(s, src[x], &er, &eg, &eb, search_method); if (color < 0) return color; @@ -561,7 +555,8 @@ static int disp_tree(const struct color_node *node, const char *fname) return 0; } -static int debug_accuracy(const PaletteUseContext *s) +static int debug_accuracy(const struct color_node *node, const uint32_t *palette, const int trans_thresh, + const enum color_search_method search_method) { int r, g, b, ret = 0; @@ -569,26 +564,19 @@ static int debug_accuracy(const PaletteUseContext *s) for (g = 0; g < 256; g++) { for (b = 0; b < 256; b++) { const uint8_t argb[] = {0xff, r, g, b}; - const int r1 = COLORMAP_NEAREST(s, s->color_search_method, s->map, argb); - const int r2 = colormap_nearest_bruteforce(s, argb); + const int r1 = COLORMAP_NEAREST(search_method, palette, node, argb, trans_thresh); + const int r2 = colormap_nearest_bruteforce(palette, argb, trans_thresh); if (r1 != r2) { - const uint32_t c1 = s->palette[r1]; - const uint32_t c2 = s->palette[r2]; - const uint8_t a1 = s->use_alpha ? c1>>24 & 0xff : 0xff; - const uint8_t a2 = s->use_alpha ? c2>>24 & 0xff : 0xff; - const uint8_t palargb1[] = { a1, c1>>16 & 0xff, c1>> 8 & 0xff, c1 & 0xff }; - const uint8_t palargb2[] = { a2, c2>>16 & 0xff, c2>> 8 & 0xff, c2 & 0xff }; - const int d1 = diff(palargb1, argb, s); - const int d2 = diff(palargb2, argb, s); + const uint32_t c1 = palette[r1]; + const uint32_t c2 = palette[r2]; + const uint8_t palargb1[] = { 0xff, c1>>16 & 0xff, c1>> 8 & 0xff, c1 & 0xff }; + const uint8_t palargb2[] = { 0xff, c2>>16 & 0xff, c2>> 8 & 0xff, c2 & 0xff }; + const int d1 = diff(palargb1, argb, trans_thresh); + const int d2 = diff(palargb2, argb, trans_thresh); if (d1 != d2) { - if (s->use_alpha) - av_log(NULL, AV_LOG_ERROR, - "/!\\ %02X%02X%02X: %d ! %d (%08"PRIX32" ! %08"PRIX32") / dist: %d ! %d\n", - r, g, b, r1, r2, c1, c2, d1, d2); - else - av_log(NULL, AV_LOG_ERROR, - "/!\\ %02X%02X%02X: %d ! %d (%06"PRIX32" ! %06"PRIX32") / dist: %d ! %d\n", - r, g, b, r1, r2, c1 & 0xffffff, c2 & 0xffffff, d1, d2); + av_log(NULL, AV_LOG_ERROR, + "/!\\ %02X%02X%02X: %d ! %d (%06"PRIX32" ! %06"PRIX32") / dist: %d ! %d\n", + r, g, b, r1, r2, c1 & 0xffffff, c2 & 0xffffff, d1, d2); ret = 1; } } @@ -604,8 +592,8 @@ struct color { }; struct color_rect { - uint8_t min[4]; - uint8_t max[4]; + uint8_t min[3]; + uint8_t max[3]; }; typedef int (*cmp_func)(const void *, const void *); @@ -626,47 +614,43 @@ DECLARE_CMP_FUNC(b, 3) static const cmp_func cmp_funcs[] = {cmp_a, cmp_r, cmp_g, cmp_b}; -static int get_next_color(const uint8_t *color_used, const PaletteUseContext *s, +static int get_next_color(const uint8_t *color_used, const uint32_t *palette, + const int trans_thresh, int *component, const struct color_rect *box) { - int wa, wr, wg, wb; + int wr, wg, wb; int i, longest = 0; unsigned nb_color = 0; struct color_rect ranges; struct color tmp_pal[256]; cmp_func cmpf; - ranges.min[0] = ranges.min[1] = ranges.min[2] = ranges.min[3]= 0xff; - ranges.max[0] = ranges.max[1] = ranges.max[2] = ranges.max[3]= 0x00; + ranges.min[0] = ranges.min[1] = ranges.min[2] = 0xff; + ranges.max[0] = ranges.max[1] = ranges.max[2] = 0x00; for (i = 0; i < AVPALETTE_COUNT; i++) { - const uint32_t c = s->palette[i]; + const uint32_t c = palette[i]; const uint8_t a = c >> 24 & 0xff; const uint8_t r = c >> 16 & 0xff; const uint8_t g = c >> 8 & 0xff; const uint8_t b = c & 0xff; - if (!s->use_alpha && a < s->trans_thresh) { + if (a < trans_thresh) { continue; } - if (color_used[i] || (a != 0xff && !s->use_alpha) || - r < box->min[1] || g < box->min[2] || b < box->min[3] || - r > box->max[1] || g > box->max[2] || b > box->max[3]) + if (color_used[i] || (a != 0xff) || + r < box->min[0] || g < box->min[1] || b < box->min[2] || + r > box->max[0] || g > box->max[1] || b > box->max[2]) continue; - if (s->use_alpha && (a < box->min[0] || a > box->max[0])) - continue; - - if (a < ranges.min[0]) ranges.min[0] = a; - if (r < ranges.min[1]) ranges.min[1] = r; - if (g < ranges.min[2]) ranges.min[2] = g; - if (b < ranges.min[3]) ranges.min[3] = b; + if (r < ranges.min[0]) ranges.min[0] = r; + if (g < ranges.min[1]) ranges.min[1] = g; + if (b < ranges.min[2]) ranges.min[2] = b; - if (a > ranges.max[0]) ranges.max[0] = a; - if (r > ranges.max[1]) ranges.max[1] = r; - if (g > ranges.max[2]) ranges.max[2] = g; - if (b > ranges.max[3]) ranges.max[3] = b; + if (r > ranges.max[0]) ranges.max[0] = r; + if (g > ranges.max[1]) ranges.max[1] = g; + if (b > ranges.max[2]) ranges.max[2] = b; tmp_pal[nb_color].value = c; tmp_pal[nb_color].pal_id = i; @@ -678,22 +662,12 @@ static int get_next_color(const uint8_t *color_used, const PaletteUseContext *s, return -1; /* define longest axis that will be the split component */ - wa = ranges.max[0] - ranges.min[0]; - wr = ranges.max[1] - ranges.min[1]; - wg = ranges.max[2] - ranges.min[2]; - wb = ranges.max[3] - ranges.min[3]; - - if (s->use_alpha) { - if (wa >= wr && wa >= wb && wa >= wg) longest = 0; - if (wr >= wg && wr >= wb && wr >= wa) longest = 1; - if (wg >= wr && wg >= wb && wg >= wa) longest = 2; - if (wb >= wr && wb >= wg && wb >= wa) longest = 3; - } else { - if (wr >= wg && wr >= wb) longest = 1; - if (wg >= wr && wg >= wb) longest = 2; - if (wb >= wr && wb >= wg) longest = 3; - } - + wr = ranges.max[0] - ranges.min[0]; + wg = ranges.max[1] - ranges.min[1]; + wb = ranges.max[2] - ranges.min[2]; + if (wr >= wg && wr >= wb) longest = 1; + if (wg >= wr && wg >= wb) longest = 2; + if (wb >= wr && wb >= wg) longest = 3; cmpf = cmp_funcs[longest]; *component = longest; @@ -706,7 +680,8 @@ static int get_next_color(const uint8_t *color_used, const PaletteUseContext *s, static int colormap_insert(struct color_node *map, uint8_t *color_used, int *nb_used, - const PaletteUseContext *s, + const uint32_t *palette, + const int trans_thresh, const struct color_rect *box) { uint32_t c; @@ -714,14 +689,14 @@ static int colormap_insert(struct color_node *map, int node_left_id = -1, node_right_id = -1; struct color_node *node; struct color_rect box1, box2; - const int pal_id = get_next_color(color_used, s, &component, box); + const int pal_id = get_next_color(color_used, palette, trans_thresh, &component, box); if (pal_id < 0) return -1; /* create new node with that color */ cur_id = (*nb_used)++; - c = s->palette[pal_id]; + c = palette[pal_id]; node = &map[cur_id]; node->split = component; node->palette_id = pal_id; @@ -734,13 +709,13 @@ static int colormap_insert(struct color_node *map, /* get the two boxes this node creates */ box1 = box2 = *box; - box1.max[component] = node->val[component]; - box2.min[component] = FFMIN(node->val[component] + 1, 255); + box1.max[component-1] = node->val[component]; + box2.min[component-1] = FFMIN(node->val[component] + 1, 255); - node_left_id = colormap_insert(map, color_used, nb_used, s, &box1); + node_left_id = colormap_insert(map, color_used, nb_used, palette, trans_thresh, &box1); - if (box2.min[component] <= box2.max[component]) - node_right_id = colormap_insert(map, color_used, nb_used, s, &box2); + if (box2.min[component-1] <= box2.max[component-1]) + node_right_id = colormap_insert(map, color_used, nb_used, palette, trans_thresh, &box2); node->left_id = node_left_id; node->right_id = node_right_id; @@ -755,13 +730,6 @@ static int cmp_pal_entry(const void *a, const void *b) return c1 - c2; } -static int cmp_pal_entry_alpha(const void *a, const void *b) -{ - const int c1 = *(const uint32_t *)a; - const int c2 = *(const uint32_t *)b; - return c1 - c2; -} - static void load_colormap(PaletteUseContext *s) { int i, nb_used = 0; @@ -769,13 +737,12 @@ static void load_colormap(PaletteUseContext *s) uint32_t last_color = 0; struct color_rect box; - if (!s->use_alpha && s->transparency_index >= 0) { + if (s->transparency_index >= 0) { FFSWAP(uint32_t, s->palette[s->transparency_index], s->palette[255]); } /* disable transparent colors and dups */ - qsort(s->palette, AVPALETTE_COUNT-(s->transparency_index >= 0), sizeof(*s->palette), - s->use_alpha ? cmp_pal_entry_alpha : cmp_pal_entry); + qsort(s->palette, AVPALETTE_COUNT-(s->transparency_index >= 0), sizeof(*s->palette), cmp_pal_entry); for (i = 0; i < AVPALETTE_COUNT; i++) { const uint32_t c = s->palette[i]; @@ -784,22 +751,22 @@ static void load_colormap(PaletteUseContext *s) continue; } last_color = c; - if (!s->use_alpha && c >> 24 < s->trans_thresh) { + if (c >> 24 < s->trans_thresh) { color_used[i] = 1; // ignore transparent color(s) continue; } } - box.min[0] = box.min[1] = box.min[2] = box.min[3] = 0x00; - box.max[0] = box.max[1] = box.max[2] = box.max[3] = 0xff; + box.min[0] = box.min[1] = box.min[2] = 0x00; + box.max[0] = box.max[1] = box.max[2] = 0xff; - colormap_insert(s->map, color_used, &nb_used, s, &box); + colormap_insert(s->map, color_used, &nb_used, s->palette, s->trans_thresh, &box); if (s->dot_filename) disp_tree(s->map, s->dot_filename); if (s->debug_accuracy) { - if (!debug_accuracy(s)) + if (!debug_accuracy(s->map, s->palette, s->trans_thresh, s->color_search_method)) av_log(NULL, AV_LOG_INFO, "Accuracy check passed\n"); } } @@ -813,18 +780,16 @@ static void debug_mean_error(PaletteUseContext *s, const AVFrame *in1, uint8_t *src2 = in2->data[0]; const int src1_linesize = in1->linesize[0] >> 2; const int src2_linesize = in2->linesize[0]; - const float div = in1->width * in1->height * (s->use_alpha ? 4 : 3); + const float div = in1->width * in1->height * 3; unsigned mean_err = 0; for (y = 0; y < in1->height; y++) { for (x = 0; x < in1->width; x++) { const uint32_t c1 = src1[x]; const uint32_t c2 = palette[src2[x]]; - const uint8_t a1 = s->use_alpha ? c1>>24 & 0xff : 0xff; - const uint8_t a2 = s->use_alpha ? c2>>24 & 0xff : 0xff; - const uint8_t argb1[] = {a1, c1 >> 16 & 0xff, c1 >> 8 & 0xff, c1 & 0xff}; - const uint8_t argb2[] = {a2, c2 >> 16 & 0xff, c2 >> 8 & 0xff, c2 & 0xff}; - mean_err += diff(argb1, argb2, s); + const uint8_t argb1[] = {0xff, c1 >> 16 & 0xff, c1 >> 8 & 0xff, c1 & 0xff}; + const uint8_t argb2[] = {0xff, c2 >> 16 & 0xff, c2 >> 8 & 0xff, c2 & 0xff}; + mean_err += diff(argb1, argb2, s->trans_thresh); } src1 += src1_linesize; src2 += src2_linesize; @@ -1024,7 +989,7 @@ static void load_palette(PaletteUseContext *s, const AVFrame *palette_frame) for (y = 0; y < palette_frame->height; y++) { for (x = 0; x < palette_frame->width; x++) { s->palette[i] = p[x]; - if (!s->use_alpha && p[x]>>24 < s->trans_thresh) { + if (p[x]>>24 < s->trans_thresh) { s->transparency_index = i; // we are assuming at most one transparent color in palette } i++; From patchwork Tue Dec 27 23:17:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39770 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761068pzb; Tue, 27 Dec 2022 15:18:57 -0800 (PST) X-Google-Smtp-Source: AMrXdXtnz3nFDdzb/tJE9VMnWjm/9nW1UBLiZgdI6gdtAtfhlWDBXaVQkUDQYcjPMjP2WFZ3AhdJ X-Received: by 2002:a05:6402:206c:b0:47c:30aa:ae0e with SMTP id bd12-20020a056402206c00b0047c30aaae0emr19271351edb.11.1672183137215; Tue, 27 Dec 2022 15:18:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183137; cv=none; d=google.com; s=arc-20160816; b=HzxfoVgnEV0gRjyLWbUGNFHYKHLpGKC8zctk2FUgBO889sJuiL97BeXtPYmvFQ/S6l Ea9c23qqMq1qjiSG7UkkdY5WW91kiBKrUTBBvZJB3fRm8pBbiaYW8GaJINYrw1LFWZRP RkATX+ucGChtBDSmRjgWQCuOejjAQYgjxij6QbviWC0qoni02Yali9NiPzl8NO1B9o3m S+XtA2HDC/cyNYVt5OgbkujhFcXb+IbE7gEsbaa+NBPNSs7A4OAQfWSsaeTQOkvaFbtE JjjErgn2vBAb2LruODFrfmM4p2mp8lsBato/DzroN18HonLMbamEnwz35xZUfoE31bul MwqQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=Lh9uFblgkeBHytamrKunLUTAy3NnGtH+jqBfgjrAVtk=; b=eZVSvGIvUPXocdYLOGXX9dxhJZXPsGPnqd0NnH/MY9zfnuZvsorBTDyKFKOW7a99E5 FdPgPPP//CIyB5J8hqF0Q+5M7aqcSaZ1t9WC9HjCAi4YJCOUDLuNKrS4+kP798TDcEwY SftjDrFmbMOokJGEPrluQqIFXJvNudJ6XG+Wyha2PpSj1sl2pufbp9uTt6HaynAcTKJb P7zLfIA87ma1Dd32DdhGHh0TkQaOMurDZNNgl5qcS2m8+a+zCptu98zICwCM70Q/0kA+ QZ+JjHGmnkKyyvEKdzNiW9HQ5deiTSgFC8AaCWylFUmVCRr/HOxdZQKN6MmdgzEElSgk hRMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b="A2f/SBcj"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id hz2-20020a1709072ce200b007c0db556798si12714408ejc.994.2022.12.27.15.18.56; Tue, 27 Dec 2022 15:18:57 -0800 (PST) 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=@pkh.me header.s=selector1 header.b="A2f/SBcj"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id F1C7568BC88; Wed, 28 Dec 2022 01:18:32 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8706268BC71 for ; Wed, 28 Dec 2022 01:18:26 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Lt3jaQNk+00moqJ7nySfGL74CJdayCR4kxvNEsJL4+M=; b=A2f/SBcj2JIPmfVXOGjDEMU4pDna8mv2j1iGCo8Ir8QvS5i7eEPZOaj+2dIa1mecBmIB2s 7A/+M5n43V4mPYFSTJSZLP2ZViHFljtXrxJjtbIWYV9QXxmtJ9e6O3H7ywIq9XZ+S2LYfq 7zurgUoIvIPGYIMMBEVnUWuOATke5g8= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id c7d52716; Tue, 27 Dec 2022 23:18:16 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:45 +0100 Message-Id: <20221227231814.2520181-4-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 03/32] avfilter/palette{gen, use}: simplify a few alpha masks 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: cK1Lm8GodenI --- libavfilter/vf_paletteuse.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index cb18329bb7..f9d8a1cdfc 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -156,7 +156,7 @@ static int query_formats(AVFilterContext *ctx) static av_always_inline uint32_t dither_color(uint32_t px, int er, int eg, int eb, int scale, int shift) { - return px >> 24 << 24 + return (px & 0xff000000) | av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<> 8 & 0xff) + ((eg * scale) / (1<> 24 >= trans_thresh) { // ignore transparent entry const uint8_t palargb[] = { - palette[i]>>24 & 0xff, + palette[i]>>24, palette[i]>>16 & 0xff, palette[i]>> 8 & 0xff, palette[i] & 0xff, @@ -372,7 +372,7 @@ static av_always_inline int get_dst_color_err(PaletteUseContext *s, uint32_t c, int *er, int *eg, int *eb, const enum color_search_method search_method) { - const uint8_t a = c >> 24 & 0xff; + const uint8_t a = c >> 24; const uint8_t r = c >> 16 & 0xff; const uint8_t g = c >> 8 & 0xff; const uint8_t b = c & 0xff; @@ -411,7 +411,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram if (dither == DITHERING_BAYER) { const int d = s->ordered_dither[(y & 7)<<3 | (x & 7)]; - const uint8_t a8 = src[x] >> 24 & 0xff; + const uint8_t a8 = src[x] >> 24; const uint8_t r8 = src[x] >> 16 & 0xff; const uint8_t g8 = src[x] >> 8 & 0xff; const uint8_t b8 = src[x] & 0xff; @@ -483,7 +483,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram if ( down) src[src_linesize + x ] = dither_color(src[src_linesize + x ], er, eg, eb, 1, 2); } else { - const uint8_t a = src[x] >> 24 & 0xff; + const uint8_t a = src[x] >> 24; const uint8_t r = src[x] >> 16 & 0xff; const uint8_t g = src[x] >> 8 & 0xff; const uint8_t b = src[x] & 0xff; @@ -630,7 +630,7 @@ static int get_next_color(const uint8_t *color_used, const uint32_t *palette, for (i = 0; i < AVPALETTE_COUNT; i++) { const uint32_t c = palette[i]; - const uint8_t a = c >> 24 & 0xff; + const uint8_t a = c >> 24; const uint8_t r = c >> 16 & 0xff; const uint8_t g = c >> 8 & 0xff; const uint8_t b = c & 0xff; @@ -700,7 +700,7 @@ static int colormap_insert(struct color_node *map, node = &map[cur_id]; node->split = component; node->palette_id = pal_id; - node->val[0] = c>>24 & 0xff; + node->val[0] = c>>24; node->val[1] = c>>16 & 0xff; node->val[2] = c>> 8 & 0xff; node->val[3] = c & 0xff; From patchwork Tue Dec 27 23:17:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39771 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761143pzb; Tue, 27 Dec 2022 15:19:07 -0800 (PST) X-Google-Smtp-Source: AMrXdXuHmUTssYU8NEYyele4cGulyTwQv2RamGWgZJmqDvWxKvWT+HvexG9XNZjHgWL01XvyxSMu X-Received: by 2002:a05:6402:6c9:b0:46c:2c94:d30b with SMTP id n9-20020a05640206c900b0046c2c94d30bmr26772443edy.33.1672183146857; Tue, 27 Dec 2022 15:19:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183146; cv=none; d=google.com; s=arc-20160816; b=awyjpoZQE/vO/qOJGpZen2P4nXptc+eN2+cErRtt9vdwA05Rm5uSZInIsltpltgq/F 9mlIhjaD/sMOF9RSEsi60v7wSeqmTSu/2rOQH30/qHOlJG6pl/AviVIi3ZBuCAkFd7xj vgmuCueiZ7jrJO6s10T2h0Zhp6zN3Cj1FT93dj/0TA0Nkbc9WEZcx++R8BAUkHrf5PVl NCe7uqQv+mUfrDGEKFyHcbZ4rAkIALk5flx9KcfQSpPWeqF+HM4XLlHHFFYpAGpPDiY+ 68qICMwWf587bjULV28zh2rFrYgNcDIMHf5XOX3PV561fnT+9C+lHQrW4BBFCLbHQAc/ U87w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=fDB/mt7va+gjNHdfFIPtDVf+7xn+eiKEKHp3FDgYSNg=; b=lYgvbsu6l9LltrkUDYZbEXZ8iEKGZ03hJx2/zeHCe9XpZEiR3txHt2L4cP8YRZaWPi aMK2HCxNBYWSWkS42CoQUMmFrygHAxpW70CFcuWs0u74JwdjAWnHs4TWbfQAqrjkCnO+ waYvfeAiq2tyqs1F0qdq8YhcazqKcsNlJo5A92pAkcY4Ep2B5P8g9n0CFap0QZQ/WCrS r6tau97jjYu2oaumRASymzcb3Kj43fwXskVVCftYC1DD13J9QIBK50o7nlU6tYwgQTP8 HaEM2vmksOK9KHBUylClVE35SSj8FN+iDUexf2yRXJppokibTMaR6a75YLo5CQo9+z6D i6bA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=U1OC7daX; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id v12-20020a056402348c00b004639a46d725si13861259edc.31.2022.12.27.15.19.06; Tue, 27 Dec 2022 15:19:06 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=U1OC7daX; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0BC5568BCC2; Wed, 28 Dec 2022 01:18:34 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B1D2068BC9A for ; Wed, 28 Dec 2022 01:18:26 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WcErPaO7Q9cDOvterFZ60wYQJexR1JN8exf4X2WtHaQ=; b=U1OC7daX7nhRkLvaUiLs7VRBy4wIoTj6KqiyChlKHKWAyksa1nSqWj/fu1odYSbYU8yblw VaBRRDXDdK1F+L84q0WTDuOL2pwbOswQI3mNrU8l6kxbFrXa6BNO/Dw85VLnlmFWT+jtdh cZd815YyX5Qj8Kuxh6DDY6iLOyh8g3I= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 283b3d4e; Tue, 27 Dec 2022 23:18:16 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:46 +0100 Message-Id: <20221227231814.2520181-5-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 04/32] avfilter/palette{gen, use}: add palette utils 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: G6h4LoicsI4K These color management helpers will be shared by palettegen and paletteuse in the following commits. Note that it probably makes sense to share at least the sRGB/linear functions with other filters at some point. More information on OkLab can be found here: https://bottosson.github.io/posts/oklab/ For the arithmetic integer version, see: http://blog.pkh.me/p/38-porting-oklab-colorspace-to-integer-arithmetic.html and https://github.com/ubitux/oklab-int --- libavfilter/palette.c | 210 ++++++++++++++++++++++++++++++++++++++++++ libavfilter/palette.h | 58 ++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 libavfilter/palette.c create mode 100644 libavfilter/palette.h diff --git a/libavfilter/palette.c b/libavfilter/palette.c new file mode 100644 index 0000000000..03e48fc71e --- /dev/null +++ b/libavfilter/palette.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2020 Björn Ottosson + * Copyright (c) 2022 Clément Bœsch + * + * 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/common.h" +#include "palette.h" + +#define K ((1 << 16) - 1) +#define K2 ((int64_t)K*K) +#define P ((1 << 9) - 1) + +/** + * Table mapping formula: + * f(x) = x < 0.04045 ? x/12.92 : ((x+0.055)/1.055)^2.4 (sRGB EOTF) + * Where x is the normalized index in the table and f(x) the value in the table. + * f(x) is remapped to [0;K] and rounded. + */ +static const uint16_t srgb2linear[256] = { + 0x0000, 0x0014, 0x0028, 0x003c, 0x0050, 0x0063, 0x0077, 0x008b, + 0x009f, 0x00b3, 0x00c7, 0x00db, 0x00f1, 0x0108, 0x0120, 0x0139, + 0x0154, 0x016f, 0x018c, 0x01ab, 0x01ca, 0x01eb, 0x020e, 0x0232, + 0x0257, 0x027d, 0x02a5, 0x02ce, 0x02f9, 0x0325, 0x0353, 0x0382, + 0x03b3, 0x03e5, 0x0418, 0x044d, 0x0484, 0x04bc, 0x04f6, 0x0532, + 0x056f, 0x05ad, 0x05ed, 0x062f, 0x0673, 0x06b8, 0x06fe, 0x0747, + 0x0791, 0x07dd, 0x082a, 0x087a, 0x08ca, 0x091d, 0x0972, 0x09c8, + 0x0a20, 0x0a79, 0x0ad5, 0x0b32, 0x0b91, 0x0bf2, 0x0c55, 0x0cba, + 0x0d20, 0x0d88, 0x0df2, 0x0e5e, 0x0ecc, 0x0f3c, 0x0fae, 0x1021, + 0x1097, 0x110e, 0x1188, 0x1203, 0x1280, 0x1300, 0x1381, 0x1404, + 0x1489, 0x1510, 0x159a, 0x1625, 0x16b2, 0x1741, 0x17d3, 0x1866, + 0x18fb, 0x1993, 0x1a2c, 0x1ac8, 0x1b66, 0x1c06, 0x1ca7, 0x1d4c, + 0x1df2, 0x1e9a, 0x1f44, 0x1ff1, 0x20a0, 0x2150, 0x2204, 0x22b9, + 0x2370, 0x242a, 0x24e5, 0x25a3, 0x2664, 0x2726, 0x27eb, 0x28b1, + 0x297b, 0x2a46, 0x2b14, 0x2be3, 0x2cb6, 0x2d8a, 0x2e61, 0x2f3a, + 0x3015, 0x30f2, 0x31d2, 0x32b4, 0x3399, 0x3480, 0x3569, 0x3655, + 0x3742, 0x3833, 0x3925, 0x3a1a, 0x3b12, 0x3c0b, 0x3d07, 0x3e06, + 0x3f07, 0x400a, 0x4110, 0x4218, 0x4323, 0x4430, 0x453f, 0x4651, + 0x4765, 0x487c, 0x4995, 0x4ab1, 0x4bcf, 0x4cf0, 0x4e13, 0x4f39, + 0x5061, 0x518c, 0x52b9, 0x53e9, 0x551b, 0x5650, 0x5787, 0x58c1, + 0x59fe, 0x5b3d, 0x5c7e, 0x5dc2, 0x5f09, 0x6052, 0x619e, 0x62ed, + 0x643e, 0x6591, 0x66e8, 0x6840, 0x699c, 0x6afa, 0x6c5b, 0x6dbe, + 0x6f24, 0x708d, 0x71f8, 0x7366, 0x74d7, 0x764a, 0x77c0, 0x7939, + 0x7ab4, 0x7c32, 0x7db3, 0x7f37, 0x80bd, 0x8246, 0x83d1, 0x855f, + 0x86f0, 0x8884, 0x8a1b, 0x8bb4, 0x8d50, 0x8eef, 0x9090, 0x9235, + 0x93dc, 0x9586, 0x9732, 0x98e2, 0x9a94, 0x9c49, 0x9e01, 0x9fbb, + 0xa179, 0xa339, 0xa4fc, 0xa6c2, 0xa88b, 0xaa56, 0xac25, 0xadf6, + 0xafca, 0xb1a1, 0xb37b, 0xb557, 0xb737, 0xb919, 0xbaff, 0xbce7, + 0xbed2, 0xc0c0, 0xc2b1, 0xc4a5, 0xc69c, 0xc895, 0xca92, 0xcc91, + 0xce94, 0xd099, 0xd2a1, 0xd4ad, 0xd6bb, 0xd8cc, 0xdae0, 0xdcf7, + 0xdf11, 0xe12e, 0xe34e, 0xe571, 0xe797, 0xe9c0, 0xebec, 0xee1b, + 0xf04d, 0xf282, 0xf4ba, 0xf6f5, 0xf933, 0xfb74, 0xfdb8, 0xffff, +}; + +/** + * Table mapping formula: + * f(x) = x < 0.0031308 ? x*12.92 : 1.055*x^(1/2.4)-0.055 (sRGB OETF) + * Where x is the normalized index in the table and f(x) the value in the table. + * f(x) is remapped to [0;0xff] and rounded. + * + * Since a 16-bit table is too large, we reduce its precision to 9-bit. + */ +static const uint8_t linear2srgb[P + 1] = { + 0x00, 0x06, 0x0d, 0x12, 0x16, 0x19, 0x1c, 0x1f, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, + 0x32, 0x33, 0x35, 0x36, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x42, 0x43, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x5f, 0x60, 0x61, 0x62, 0x62, + 0x63, 0x64, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6b, 0x6c, 0x6c, 0x6d, 0x6e, + 0x6e, 0x6f, 0x6f, 0x70, 0x71, 0x71, 0x72, 0x73, 0x73, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x77, + 0x78, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x80, + 0x81, 0x81, 0x82, 0x82, 0x83, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, + 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x90, 0x90, + 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, 0x93, 0x94, 0x94, 0x95, 0x95, 0x96, 0x96, 0x97, 0x97, 0x97, + 0x98, 0x98, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, + 0x9f, 0x9f, 0x9f, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, + 0xa5, 0xa5, 0xa6, 0xa6, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xaa, 0xaa, 0xab, + 0xab, 0xab, 0xac, 0xac, 0xac, 0xad, 0xad, 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, + 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb6, 0xb6, + 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, + 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc1, + 0xc1, 0xc1, 0xc1, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc8, 0xc8, 0xc8, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, + 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, + 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, + 0xd4, 0xd4, 0xd4, 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, + 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, + 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, + 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, + 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, + 0xe9, 0xe9, 0xe9, 0xea, 0xea, 0xea, 0xea, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xed, + 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf1, 0xf1, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, + 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, +}; + +int32_t ff_srgb_u8_to_linear_int(uint8_t x) +{ + return (int32_t)srgb2linear[x]; +} + +uint8_t ff_linear_int_to_srgb_u8(int32_t x) +{ + if (x <= 0) { + return 0; + } else if (x >= K) { + return 0xff; + } else { + const int32_t xP = x * P; + const int32_t i = xP / K; + const int32_t m = xP % K; + const int32_t y0 = linear2srgb[i]; + const int32_t y1 = linear2srgb[i + 1]; + return (m * (y1 - y0) + K/2) / K + y0; + } +} + +/* Integer cube root, working only within [0;1] */ +static int32_t cbrt01_int(int32_t x) +{ + int64_t u; + + /* Approximation curve is for the [0;1] range */ + if (x <= 0) return 0; + if (x >= K) return K; + + /* + * Initial approximation: x³ - 2.19893x² + 2.01593x + 0.219407 + * + * We are not using any rounding here since the precision is not important + * at this stage and it would require the more expensive rounding function + * that deals with negative numbers. + */ + u = x*(x*(x + -144107LL) / K + 132114LL) / K + 14379LL; + + /* + * Refine with 2 Halley iterations: + * uₙ₊₁ = uₙ-2f(uₙ)f'(uₙ)/(2f'(uₙ)²-f(uₙ)f"(uₙ)) + * = uₙ(2x+uₙ³)/(x+2uₙ³) + * + * Note: u is not expected to be < 0, so we can use the (a+b/2)/b rounding. + */ + for (int i = 0; i < 2; i++) { + const int64_t u3 = u*u*u; + const int64_t den = x + (2*u3 + K2/2) / K2; + u = (u * (2*x + (u3 + K2/2) / K2) + den/2) / den; + } + + return u; +} + +static int64_t div_round64(int64_t a, int64_t b) { return (a^b)<0 ? (a-b/2)/b : (a+b/2)/b; } + +struct Lab ff_srgb_u8_to_oklab_int(uint32_t srgb) +{ + const int32_t r = (int32_t)srgb2linear[srgb >> 16 & 0xff]; + const int32_t g = (int32_t)srgb2linear[srgb >> 8 & 0xff]; + const int32_t b = (int32_t)srgb2linear[srgb & 0xff]; + + // Note: lms can actually be slightly over K due to rounded coefficients + const int32_t l = (27015LL*r + 35149LL*g + 3372LL*b + K/2) / K; + const int32_t m = (13887LL*r + 44610LL*g + 7038LL*b + K/2) / K; + const int32_t s = ( 5787LL*r + 18462LL*g + 41286LL*b + K/2) / K; + + const int32_t l_ = cbrt01_int(l); + const int32_t m_ = cbrt01_int(m); + const int32_t s_ = cbrt01_int(s); + + const struct Lab ret = { + .L = div_round64( 13792LL*l_ + 52010LL*m_ - 267LL*s_, K), + .a = div_round64(129628LL*l_ - 159158LL*m_ + 29530LL*s_, K), + .b = div_round64( 1698LL*l_ + 51299LL*m_ - 52997LL*s_, K), + }; + + return ret; +} + +uint32_t ff_oklab_int_to_srgb_u8(struct Lab c) +{ + const int64_t l_ = c.L + div_round64(25974LL * c.a, K) + div_round64(14143LL * c.b, K); + const int64_t m_ = c.L + div_round64(-6918LL * c.a, K) + div_round64(-4185LL * c.b, K); + const int64_t s_ = c.L + div_round64(-5864LL * c.a, K) + div_round64(-84638LL * c.b, K); + + const int32_t l = l_*l_*l_ / K2; + const int32_t m = m_*m_*m_ / K2; + const int32_t s = s_*s_*s_ / K2; + + const uint8_t r = ff_linear_int_to_srgb_u8((267169LL * l + -216771LL * m + 15137LL * s + K/2) / K); + const uint8_t g = ff_linear_int_to_srgb_u8((-83127LL * l + 171030LL * m + -22368LL * s + K/2) / K); + const uint8_t b = ff_linear_int_to_srgb_u8((-275LL * l + -46099LL * m + 111909LL * s + K/2) / K); + + return r<<16 | g<<8 | b; +} diff --git a/libavfilter/palette.h b/libavfilter/palette.h new file mode 100644 index 0000000000..6839bf6fc6 --- /dev/null +++ b/libavfilter/palette.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 Björn Ottosson + * Copyright (c) 2022 Clément Bœsch + * + * 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 AVFILTER_PALETTE_H +#define AVFILTER_PALETTE_H + +#include +#include + +#include "libavutil/attributes.h" + +struct Lab { + int32_t L, a, b; +}; + +/** + * Map sRGB 8-bit color component to a 16-bit linear value (gamma + * expand from electrical to optical value). + */ +int32_t ff_srgb_u8_to_linear_int(uint8_t x); + +/** + * Map a 16-bit linear value to a sRGB 8-bit color component (gamma + * compressed from optical to electrical value). + */ +uint8_t ff_linear_int_to_srgb_u8(int32_t x); + +/** + * sRGB (non-linear) to OkLab conversion + * @see https://bottosson.github.io/posts/oklab/ + */ +struct Lab ff_srgb_u8_to_oklab_int(uint32_t srgb); + +/** + * OkLab to sRGB (non-linear) conversion + * @see https://bottosson.github.io/posts/oklab/ + */ +uint32_t ff_oklab_int_to_srgb_u8(struct Lab c); + +#endif /* AVFILTER_PALETTE_H */ From patchwork Tue Dec 27 23:17:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39772 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761218pzb; Tue, 27 Dec 2022 15:19:16 -0800 (PST) X-Google-Smtp-Source: AMrXdXu17Pgp67LkklKsCfHXk9pc4BbjMTUBfjhXSayyF2RSXbbbM6k0teWoepVUwasmv0Oi3kiE X-Received: by 2002:a17:906:915:b0:7c0:e98d:b27 with SMTP id i21-20020a170906091500b007c0e98d0b27mr19035504ejd.58.1672183156608; Tue, 27 Dec 2022 15:19:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183156; cv=none; d=google.com; s=arc-20160816; b=M4w2jaAO8VuahApwY7UWsE77EYTU+y1bFTEeNTrS10rWQos4LsNRy86K8SD7/gRrNu oxYnrVSkRu9IJjb54xSFuJhXV6zf4zNQvCyMG9/S1+iDNVqpdtjC8qKvr6vA2fZq1R5M tkPWeuQvmkx9m7kDI4dXXxAjZKzfeHJZkCJeLHu6Qey3XVp5msQEB49kQlDcTrcYa6nA PPfx2cWohCcEQNWp/+DGMrD4Gi1Gj4nzVNTdyrg4S7MmIFYmAZIDsl6g7k/fWk0QEMGH ojN+mf+sdp0DHsvH1FpyTNiQoaCHda4fcl/+RkFEEBW5fEMis7zVjF+Nw9j595Xeo4Or Unlw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=qhJe05ExZ4eBqSKuhR1Bb1x78lNc5yxD8qy6Da+b5iI=; b=nm/SQJ5p/Au1h4Np4DzcXMJVvOrQU6CPwFa7f5JLg2cqcTAytMPMXvbsQKcjChRDJh k+cRWkL0U7zVdHGw5xtQWcJB4W4JZRLFRzxuyX5+Nzz2HDzwOhsMayCvs3q+YbYJUmnK 6YAbsKe4lRJ+XnYAb2hul6ixQeOAG+8IgNLioTv1DrXtVeOZL3FRApMqcHnz4IHPhKtd r5LJVmX46jnf7Ka/GU3dc6xsIWEy7L09drTxc92wx+L9wEETdpudTsMUGTyIlK5gvE28 ZDchryboe7frhYoqsZvAPyxRpouxGyxTXfnbfs5zwgIZsfcmv2B/TLpusXqWsO2T6iia i5Nw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=ogrJIpyJ; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id gb13-20020a170907960d00b007fcfcf3b89esi13610163ejc.368.2022.12.27.15.19.16; Tue, 27 Dec 2022 15:19:16 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=ogrJIpyJ; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E072A68BCCD; Wed, 28 Dec 2022 01:18:34 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 434CC68BC75 for ; Wed, 28 Dec 2022 01:18:27 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dJoys2wa6i7bzOAh1TjuuVfHgqVbWnCHD57qB8LEGmU=; b=ogrJIpyJDYVST8M9RIBsE08KdjGtY6tEH9Ly/lh4jlh9GiQ/7roN2pCygYbmgfxFilhEqw fWDUtWE1IxkyhXqktoUMkgFH4bo4Jo68aZxd+XKI4bjkgRd2Lt0D41AqeU96LoigYPrY1N dum0XASfkM/Owvk29aiQMgbOwgJGqgA= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id ca496f4a; Tue, 27 Dec 2022 23:18:17 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:47 +0100 Message-Id: <20221227231814.2520181-6-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 05/32] avfilter/paletteuse: switch from u8[4] to u32 for color code 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: pJaI6aviL1lL This change simplifies the code quite a bit and make it consistent with how it's done in palettegen. --- libavfilter/vf_paletteuse.c | 98 ++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 57 deletions(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index f9d8a1cdfc..fb4016b11c 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -57,7 +57,7 @@ enum diff_mode { }; struct color_node { - uint8_t val[4]; + uint32_t val; uint8_t palette_id; int split; int left_id, right_id; @@ -162,9 +162,11 @@ static av_always_inline uint32_t dither_color(uint32_t px, int er, int eg, | av_clip_uint8((px & 0xff) + ((eb * scale) / (1<> 24, a >> 16 & 0xff, a >> 8 & 0xff, a & 0xff}; + const uint8_t c2[] = {b >> 24, b >> 16 & 0xff, b >> 8 & 0xff, b & 0xff}; const int dr = c1[1] - c2[1]; const int dg = c1[2] - c2[2]; const int db = c1[3] - c2[3]; @@ -178,7 +180,7 @@ static av_always_inline int diff(const uint8_t *c1, const uint8_t *c2, const int } } -static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *palette, const uint8_t *argb, const int trans_thresh) +static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *palette, const uint32_t argb, const int trans_thresh) { int i, pal_id = -1, min_dist = INT_MAX; @@ -186,13 +188,7 @@ static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *pale const uint32_t c = palette[i]; if (c >> 24 >= trans_thresh) { // ignore transparent entry - const uint8_t palargb[] = { - palette[i]>>24, - palette[i]>>16 & 0xff, - palette[i]>> 8 & 0xff, - palette[i] & 0xff, - }; - const int d = diff(palargb, argb, trans_thresh); + const int d = diff(palette[i], argb, trans_thresh); if (d < min_dist) { pal_id = i; min_dist = d; @@ -210,14 +206,14 @@ struct nearest_color { static void colormap_nearest_node(const struct color_node *map, const int node_pos, - const uint8_t *target, + const uint32_t target, const int trans_thresh, struct nearest_color *nearest) { const struct color_node *kd = map + node_pos; - const int s = kd->split; + const int shift = (3 - kd->split) * 8; int dx, nearer_kd_id, further_kd_id; - const uint8_t *current = kd->val; + const uint32_t current = kd->val; const int current_to_target = diff(target, current, trans_thresh); if (current_to_target < nearest->dist_sqd) { @@ -226,7 +222,7 @@ static void colormap_nearest_node(const struct color_node *map, } if (kd->left_id != -1 || kd->right_id != -1) { - dx = target[s] - current[s]; + dx = (int)(target>>shift & 0xff) - (int)(current>>shift & 0xff); if (dx <= 0) nearer_kd_id = kd->left_id, further_kd_id = kd->right_id; else nearer_kd_id = kd->right_id, further_kd_id = kd->left_id; @@ -239,7 +235,7 @@ static void colormap_nearest_node(const struct color_node *map, } } -static av_always_inline uint8_t colormap_nearest_recursive(const struct color_node *node, const uint8_t *rgb, const int trans_thresh) +static av_always_inline uint8_t colormap_nearest_recursive(const struct color_node *node, const uint8_t rgb, const int trans_thresh) { struct nearest_color res = {.dist_sqd = INT_MAX, .node_pos = -1}; colormap_nearest_node(node, 0, rgb, trans_thresh, &res); @@ -251,7 +247,7 @@ struct stack_node { int dx2; }; -static av_always_inline uint8_t colormap_nearest_iterative(const struct color_node *root, const uint8_t *target, const int trans_thresh) +static av_always_inline uint8_t colormap_nearest_iterative(const struct color_node *root, const uint32_t target, const int trans_thresh) { int pos = 0, best_node_id = -1, best_dist = INT_MAX, cur_color_id = 0; struct stack_node nodes[16]; @@ -260,7 +256,7 @@ static av_always_inline uint8_t colormap_nearest_iterative(const struct color_no for (;;) { const struct color_node *kd = &root[cur_color_id]; - const uint8_t *current = kd->val; + const uint32_t current = kd->val; const int current_to_target = diff(target, current, trans_thresh); /* Compare current color node to the target and update our best node if @@ -274,8 +270,8 @@ static av_always_inline uint8_t colormap_nearest_iterative(const struct color_no /* Check if it's not a leaf */ if (kd->left_id != -1 || kd->right_id != -1) { - const int split = kd->split; - const int dx = target[split] - current[split]; + const int shift = (3 - kd->split) * 8; + const int dx = (target>>shift & 0xff) - (current>>shift & 0xff); int nearer_kd_id, further_kd_id; /* Define which side is the most interesting. */ @@ -331,24 +327,20 @@ end: /** * Check if the requested color is in the cache already. If not, find it in the * color tree and cache it. - * Note: a, r, g, and b are the components of color, but are passed as well to avoid - * recomputing them (they are generally computed by the caller for other uses). */ static av_always_inline int color_get(PaletteUseContext *s, uint32_t color, - uint8_t a, uint8_t r, uint8_t g, uint8_t b, const enum color_search_method search_method) { int i; - const uint8_t argb_elts[] = {a, r, g, b}; - const uint8_t rhash = r & ((1<>16) & ((1<> 8) & ((1<cache[hash]; struct cached_color *e; // first, check for transparency - if (a < s->trans_thresh && s->transparency_index >= 0) { + if (color>>24 < s->trans_thresh && s->transparency_index >= 0) { return s->transparency_index; } @@ -363,7 +355,7 @@ static av_always_inline int color_get(PaletteUseContext *s, uint32_t color, if (!e) return AVERROR(ENOMEM); e->color = color; - e->pal_entry = COLORMAP_NEAREST(search_method, s->palette, s->map, argb_elts, s->trans_thresh); + e->pal_entry = COLORMAP_NEAREST(search_method, s->palette, s->map, color, s->trans_thresh); return e->pal_entry; } @@ -372,12 +364,11 @@ static av_always_inline int get_dst_color_err(PaletteUseContext *s, uint32_t c, int *er, int *eg, int *eb, const enum color_search_method search_method) { - const uint8_t a = c >> 24; const uint8_t r = c >> 16 & 0xff; const uint8_t g = c >> 8 & 0xff; const uint8_t b = c & 0xff; uint32_t dstc; - const int dstx = color_get(s, c, a, r, g, b, search_method); + const int dstx = color_get(s, c, search_method); if (dstx < 0) return dstx; dstc = s->palette[dstx]; @@ -419,7 +410,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram const uint8_t g = av_clip_uint8(g8 + d); const uint8_t b = av_clip_uint8(b8 + d); const uint32_t color_new = (unsigned)(a8) << 24 | r << 16 | g << 8 | b; - const int color = color_get(s, color_new, a8, r, g, b, search_method); + const int color = color_get(s, color_new, search_method); if (color < 0) return color; @@ -483,11 +474,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram if ( down) src[src_linesize + x ] = dither_color(src[src_linesize + x ], er, eg, eb, 1, 2); } else { - const uint8_t a = src[x] >> 24; - const uint8_t r = src[x] >> 16 & 0xff; - const uint8_t g = src[x] >> 8 & 0xff; - const uint8_t b = src[x] & 0xff; - const int color = color_get(s, src[x], a, r, g, b, search_method); + const int color = color_get(s, src[x], search_method); if (color < 0) return color; @@ -507,20 +494,20 @@ static void disp_node(AVBPrint *buf, int depth) { const struct color_node *node = &map[node_id]; - const uint32_t fontcolor = node->val[1] > 0x50 && - node->val[2] > 0x50 && - node->val[3] > 0x50 ? 0 : 0xffffff; + const uint32_t fontcolor = (node->val>>16 & 0xff) > 0x50 && + (node->val>> 8 & 0xff) > 0x50 && + (node->val & 0xff) > 0x50 ? 0 : 0xffffff; const int rgb_comp = node->split - 1; av_bprintf(buf, "%*cnode%d [" "label=\"%c%02X%c%02X%c%02X%c\" " - "fillcolor=\"#%02x%02x%02x\" " + "fillcolor=\"#%06"PRIX32"\" " "fontcolor=\"#%06"PRIX32"\"]\n", depth*INDENT, ' ', node->palette_id, - "[ "[rgb_comp], node->val[1], - "][ "[rgb_comp], node->val[2], - " ]["[rgb_comp], node->val[3], + "[ "[rgb_comp], node->val>>16 & 0xff, + "][ "[rgb_comp], node->val>> 8 & 0xff, + " ]["[rgb_comp], node->val & 0xff, " ]"[rgb_comp], - node->val[1], node->val[2], node->val[3], + node->val & 0xffffff, fontcolor); if (parent_id != -1) av_bprintf(buf, "%*cnode%d -> node%d\n", depth*INDENT, ' ', @@ -563,16 +550,14 @@ static int debug_accuracy(const struct color_node *node, const uint32_t *palette for (r = 0; r < 256; r++) { for (g = 0; g < 256; g++) { for (b = 0; b < 256; b++) { - const uint8_t argb[] = {0xff, r, g, b}; + const uint32_t argb = 0xff000000 | r<<16 | g<<8 | b; const int r1 = COLORMAP_NEAREST(search_method, palette, node, argb, trans_thresh); const int r2 = colormap_nearest_bruteforce(palette, argb, trans_thresh); if (r1 != r2) { const uint32_t c1 = palette[r1]; const uint32_t c2 = palette[r2]; - const uint8_t palargb1[] = { 0xff, c1>>16 & 0xff, c1>> 8 & 0xff, c1 & 0xff }; - const uint8_t palargb2[] = { 0xff, c2>>16 & 0xff, c2>> 8 & 0xff, c2 & 0xff }; - const int d1 = diff(palargb1, argb, trans_thresh); - const int d2 = diff(palargb2, argb, trans_thresh); + const int d1 = diff(0xff000000 | c1, argb, trans_thresh); + const int d2 = diff(0xff000000 | c2, argb, trans_thresh); if (d1 != d2) { av_log(NULL, AV_LOG_ERROR, "/!\\ %02X%02X%02X: %d ! %d (%06"PRIX32" ! %06"PRIX32") / dist: %d ! %d\n", @@ -686,6 +671,7 @@ static int colormap_insert(struct color_node *map, { uint32_t c; int component, cur_id; + uint8_t comp_value; int node_left_id = -1, node_right_id = -1; struct color_node *node; struct color_rect box1, box2; @@ -700,17 +686,15 @@ static int colormap_insert(struct color_node *map, node = &map[cur_id]; node->split = component; node->palette_id = pal_id; - node->val[0] = c>>24; - node->val[1] = c>>16 & 0xff; - node->val[2] = c>> 8 & 0xff; - node->val[3] = c & 0xff; + node->val = c; color_used[pal_id] = 1; /* get the two boxes this node creates */ box1 = box2 = *box; - box1.max[component-1] = node->val[component]; - box2.min[component-1] = FFMIN(node->val[component] + 1, 255); + comp_value = node->val >> ((3 - component) * 8) & 0xff; + box1.max[component-1] = comp_value; + box2.min[component-1] = FFMIN(comp_value + 1, 255); node_left_id = colormap_insert(map, color_used, nb_used, palette, trans_thresh, &box1); @@ -787,8 +771,8 @@ static void debug_mean_error(PaletteUseContext *s, const AVFrame *in1, for (x = 0; x < in1->width; x++) { const uint32_t c1 = src1[x]; const uint32_t c2 = palette[src2[x]]; - const uint8_t argb1[] = {0xff, c1 >> 16 & 0xff, c1 >> 8 & 0xff, c1 & 0xff}; - const uint8_t argb2[] = {0xff, c2 >> 16 & 0xff, c2 >> 8 & 0xff, c2 & 0xff}; + const uint32_t argb1 = 0xff000000 | c1; + const uint32_t argb2 = 0xff000000 | c2; mean_err += diff(argb1, argb2, s->trans_thresh); } src1 += src1_linesize; From patchwork Tue Dec 27 23:17:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39793 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762682pzb; Tue, 27 Dec 2022 15:22:23 -0800 (PST) X-Google-Smtp-Source: AMrXdXu0FqatR7z6rFY9Ok2jMOx+gBuRSbO6yBp/zgHa6TBa9R0DLD8sgdm+B3fJvxCbEkiaeQgK X-Received: by 2002:a17:906:c2cb:b0:842:32e9:f1e9 with SMTP id ch11-20020a170906c2cb00b0084232e9f1e9mr15492139ejb.69.1672183342672; Tue, 27 Dec 2022 15:22:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183342; cv=none; d=google.com; s=arc-20160816; b=QviLVOysnvP2SAtLgZHO2pQndBifEoPd2vlENZeltqoCqsAMkYjAR5uMtGE5d/Km7E junUUo6pO7CIQ81nZyUjN7o9yzHWSiVU6phSW3KsiT9bxOZTyOztjhZ7qIZltuVcQfts cAyGZ5degRrVwBupYe8i/VnJReV5i5u7A1NodbvV1HGimDjyquR5P5niyTgVf09ploCP RimY8N95PxcEkmbjUz8L+CKS3hq2oCEcaCnMbZH5zMU340zPwX9epZaXBHvMS4YsuFg4 Hw1tIH+lYRYNV+UlaZpzPb8KvxHzYb7hJfacE9GHZ2Sow6sKHRC7Rlbg8X6+s+gtxmYs ziDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=KQwaQGYCBnZWzB91v1DdBaxVOV2Zq83CvKQoDBIRmXQ=; b=MIz6mSQaCgKsQpGogWsJ7JppJGHORE9p3m2xmjkl8tLt3O3v+vpGna8hE5dPY4Nt9S V/TWh5MN+UML5g4uLPZTLeG0x5BTWWqg1UG+J0JjEW67vPqNu0PPblD3oAKNcdIAsJEB +hN0XY15kgHagB2G9TrRtFvMztgVXWFDa4xKZtaRJ1zoeorvXXF2P/CKOcxfWyWUUj7M PRu6uS4ex5hPCpqqDEj6mx2EjL1TEnG4Mq6QKR81tX0dMKwKtv7jm31IrEDgCVKNs42J /VMsL8T7Hc7O5s5MBsgn3FT2rk1IFdE74H+xpz565xELTh2jgMPJhao9BzpFaRKbIeec FfIw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=jmwtxRYD; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id va28-20020a17090711dc00b007ba713e241dsi9683210ejb.894.2022.12.27.15.22.22; Tue, 27 Dec 2022 15:22:22 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=jmwtxRYD; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D14C168BCD3; Wed, 28 Dec 2022 01:18:55 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8D08B68BD08 for ; Wed, 28 Dec 2022 01:18:31 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gftig9AtoI+N9WP5jPYT6YVzxLXOU1+I/WgnPjw0S78=; b=jmwtxRYDyWvSYk7QqKvp6qNPhZswKV58PGco7xm7e74XBWgCcTR64Jb0vIZCNFGRiqd6UA Y5AhL+Tu2R2FTcnj13WNZzi1YX0dXPy374LF5pPQyRCU0OWhSrtQTiAQNExkw9FCbonOg3 oh6O1u4Un4Yzo6768UD+rf1+yjMmXos= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 1cfd3f3c; Tue, 27 Dec 2022 23:18:17 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:48 +0100 Message-Id: <20221227231814.2520181-7-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 06/32] avfilter/paletteuse: name target color arg consistently in colormap functions 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: DzvC48yFgXTS --- libavfilter/vf_paletteuse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index fb4016b11c..f43f077454 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -180,7 +180,7 @@ static av_always_inline int diff(const uint32_t a, const uint32_t b, const int t } } -static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *palette, const uint32_t argb, const int trans_thresh) +static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *palette, const uint32_t target, const int trans_thresh) { int i, pal_id = -1, min_dist = INT_MAX; @@ -188,7 +188,7 @@ static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *pale const uint32_t c = palette[i]; if (c >> 24 >= trans_thresh) { // ignore transparent entry - const int d = diff(palette[i], argb, trans_thresh); + const int d = diff(palette[i], target, trans_thresh); if (d < min_dist) { pal_id = i; min_dist = d; @@ -235,10 +235,10 @@ static void colormap_nearest_node(const struct color_node *map, } } -static av_always_inline uint8_t colormap_nearest_recursive(const struct color_node *node, const uint8_t rgb, const int trans_thresh) +static av_always_inline uint8_t colormap_nearest_recursive(const struct color_node *node, const uint8_t target, const int trans_thresh) { struct nearest_color res = {.dist_sqd = INT_MAX, .node_pos = -1}; - colormap_nearest_node(node, 0, rgb, trans_thresh, &res); + colormap_nearest_node(node, 0, target, trans_thresh, &res); return node[res.node_pos].palette_id; } From patchwork Tue Dec 27 23:17:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39795 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762823pzb; Tue, 27 Dec 2022 15:22:40 -0800 (PST) X-Google-Smtp-Source: AMrXdXtvaBkU9BJbBdAGxpq2kw350Yq7iKuUVYEcHsJGB/nlfZhgzw92UMEIB5hoYOyBW2Q5tHGD X-Received: by 2002:a17:906:6693:b0:7c1:8ba7:3182 with SMTP id z19-20020a170906669300b007c18ba73182mr24129861ejo.69.1672183360302; Tue, 27 Dec 2022 15:22:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183360; cv=none; d=google.com; s=arc-20160816; b=fguN6RQEQHLmp1Hqk9NAGXuJHMGyBt7uCPU/MDXFv6sjYpjdJ3lqXiYf83ZaeE++7z 70nUG7wJSqgoSG66yQb763fxsm10/+uP3KZAvuDxJ+e6oWZVHWp01Kq4rymetgwfiUns 7Fit3Wh1Lhgn7q8TueTk/HpFoomE+M4iKWNP1WEgPegu6bx0q5+VLX9kHUqf29nkjJoy X8Y0582UzHAvnwZudCsIdNHx1PhJXgzP+SjNlysrPzuqWhtJz0/Fhp9oA/ujOXPHCZi9 Ni8uMjCFeVla2iPmhuDVJWWIkxdRroytj9VmtM3b6qOlhLwhKmR/h459w0Ru3oJ3NY7p G4KQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=rar6+Kx829HYvY367a5c2TsMgWjZp8nWgiFcoYcuGrs=; b=D2gdEcnWLzCYuYEs4jSxGgvWmmRGB+UkuFyIj+y6SmM/yWQ5QPxoY9tbhzN2rbiANs eewMWgzal0iSwu/zRoR8XLiVuJdWgArCEnQfZVr6XpUCqCfcyHmPp32LhMJ/IugO53Lx q0d32oYe3b7XE749dgyMhnv3QX6wNlaTIQUgvOi9PXaiYu42bM0UOegJezuS8yqui6O9 FntgjKHV78oFStqWdGwQUUWlJZd50pgaMrv9onvte4cFcAaN9z/FSaDWZqCkmjuj1YyG gLj8IsPBA3EELvQzXhivLaeLWpenJoG/92jfC6mTBl9NVj6P0nQyyVNixNcMhxBcWE67 9ZAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=o01wV9PM; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id sh39-20020a1709076ea700b00782ff2649a7si11293239ejc.346.2022.12.27.15.22.39; Tue, 27 Dec 2022 15:22:40 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=o01wV9PM; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id ECBC668BC9F; Wed, 28 Dec 2022 01:18:57 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B0DF368BCAA for ; Wed, 28 Dec 2022 01:18:31 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Gw8qnUlaZAyt0LgcetFYrBzl10bG++umd1kmFuGXSY4=; b=o01wV9PMMxOc3Dwlu9SV7BTEXIxXjm0zB9daD9MXjJBrGCuTwwyzNQJYI97SMcrjvZ7/lu Nr62G/VQmCIXiTbh/U4kpoOkwswtdkukHuoY3P9U5S6R+4DdahY6P7ImTxZh1VfOWAtZaD 8KZp2fp9ca70oTDmLI+pykodhLshPfI= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id b095be1a; Tue, 27 Dec 2022 23:18:17 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:49 +0100 Message-Id: <20221227231814.2520181-8-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 07/32] avfilter/paletteuse: remove unused alpha split dimension 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 1neZ0rBA2bzZ The equalities in the w{r,g,b} range checks make sure longest is never 0. Even if the alpha ended up being selected in get_next_color() it would cause underread memory accesses in its caller (colormap_insert). --- libavfilter/vf_paletteuse.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index f43f077454..8954a02524 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -211,7 +211,7 @@ static void colormap_nearest_node(const struct color_node *map, struct nearest_color *nearest) { const struct color_node *kd = map + node_pos; - const int shift = (3 - kd->split) * 8; + const int shift = (2 - kd->split) * 8; int dx, nearer_kd_id, further_kd_id; const uint32_t current = kd->val; const int current_to_target = diff(target, current, trans_thresh); @@ -270,7 +270,7 @@ static av_always_inline uint8_t colormap_nearest_iterative(const struct color_no /* Check if it's not a leaf */ if (kd->left_id != -1 || kd->right_id != -1) { - const int shift = (3 - kd->split) * 8; + const int shift = (2 - kd->split) * 8; const int dx = (target>>shift & 0xff) - (current>>shift & 0xff); int nearer_kd_id, further_kd_id; @@ -497,7 +497,7 @@ static void disp_node(AVBPrint *buf, const uint32_t fontcolor = (node->val>>16 & 0xff) > 0x50 && (node->val>> 8 & 0xff) > 0x50 && (node->val & 0xff) > 0x50 ? 0 : 0xffffff; - const int rgb_comp = node->split - 1; + const int rgb_comp = node->split; av_bprintf(buf, "%*cnode%d [" "label=\"%c%02X%c%02X%c%02X%c\" " "fillcolor=\"#%06"PRIX32"\" " @@ -588,16 +588,15 @@ static int cmp_##name(const void *pa, const void *pb) \ { \ const struct color *a = pa; \ const struct color *b = pb; \ - return (int)(a->value >> (8 * (3 - (pos))) & 0xff) \ - - (int)(b->value >> (8 * (3 - (pos))) & 0xff); \ + return (int)(a->value >> (8 * (2 - (pos))) & 0xff) \ + - (int)(b->value >> (8 * (2 - (pos))) & 0xff); \ } -DECLARE_CMP_FUNC(a, 0) -DECLARE_CMP_FUNC(r, 1) -DECLARE_CMP_FUNC(g, 2) -DECLARE_CMP_FUNC(b, 3) +DECLARE_CMP_FUNC(r, 0) +DECLARE_CMP_FUNC(g, 1) +DECLARE_CMP_FUNC(b, 2) -static const cmp_func cmp_funcs[] = {cmp_a, cmp_r, cmp_g, cmp_b}; +static const cmp_func cmp_funcs[] = {cmp_r, cmp_g, cmp_b}; static int get_next_color(const uint8_t *color_used, const uint32_t *palette, const int trans_thresh, @@ -650,9 +649,9 @@ static int get_next_color(const uint8_t *color_used, const uint32_t *palette, wr = ranges.max[0] - ranges.min[0]; wg = ranges.max[1] - ranges.min[1]; wb = ranges.max[2] - ranges.min[2]; - if (wr >= wg && wr >= wb) longest = 1; - if (wg >= wr && wg >= wb) longest = 2; - if (wb >= wr && wb >= wg) longest = 3; + if (wr >= wg && wr >= wb) longest = 0; + if (wg >= wr && wg >= wb) longest = 1; + if (wb >= wr && wb >= wg) longest = 2; cmpf = cmp_funcs[longest]; *component = longest; @@ -692,13 +691,13 @@ static int colormap_insert(struct color_node *map, /* get the two boxes this node creates */ box1 = box2 = *box; - comp_value = node->val >> ((3 - component) * 8) & 0xff; - box1.max[component-1] = comp_value; - box2.min[component-1] = FFMIN(comp_value + 1, 255); + comp_value = node->val >> ((2 - component) * 8) & 0xff; + box1.max[component] = comp_value; + box2.min[component] = FFMIN(comp_value + 1, 255); node_left_id = colormap_insert(map, color_used, nb_used, palette, trans_thresh, &box1); - if (box2.min[component-1] <= box2.max[component-1]) + if (box2.min[component] <= box2.max[component]) node_right_id = colormap_insert(map, color_used, nb_used, palette, trans_thresh, &box2); node->left_id = node_left_id; From patchwork Tue Dec 27 23:17:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39797 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3763005pzb; Tue, 27 Dec 2022 15:23:06 -0800 (PST) X-Google-Smtp-Source: AMrXdXuXoUCOD+sWi5I/mtthdQ72hpLr5aUqI6ecfK7H+n/DYKBaoa5MJGlOw6Ln9ztaq3ACRYYW X-Received: by 2002:a05:6402:25c6:b0:46c:d2a3:76b3 with SMTP id x6-20020a05640225c600b0046cd2a376b3mr21456708edb.14.1672183385998; Tue, 27 Dec 2022 15:23:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183385; cv=none; d=google.com; s=arc-20160816; b=dkQy0qsid2xCWMSgCicoisYibGPV21HewZnGiWeNRBFCE/ZdPsQ/ejiz23DI57M4M5 /dcnQgs7vBpyJB+cB05zbh0ba6fN9kPmv1VobXQnqRcQy1nhnK42aRFS9STFwkB/v7cO wAk1zAT2XA0p/O8GdDq1g/L9rx48xkRd9CDSJcHNNkcJR0aLakEnQYNNWXyDgv+TlB6l 3Fl3xPa8jZWfbOBLfw/8Aif9g5nmoPCjSYNukNY9JsF3rfoO1SRtaiqVPZe5tmC1pM2m dzy7ZAOfHqBOVdnGkkN9H9HNHXwPPhQ4aqKxgs1TQ0XqIGfMcLbNlySn6pH5jd2zZGlY VPiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=98xDDPMwVKXXGhNyw3GKGdlK3U01dpN6ksjRHPOiCzA=; b=GCYS77UlOYc5NID6wzIeKjkJVS4XWGssKZJsd2ZEZsFeT3ZoujQMNZ0yATIRaNfHv8 oqPawO1I5FJ7HjtvC6sF//2eviHTMkL8Q1dzSOHEE9m0597RP6yI7pNFRRKw5p9mtn2k mIyOWDSbmlJrroY7Wbty3f7rIkZ2M2mqaQchSZ51Pk5rBXy50JWVNl0eyY9sqo0FPLen xnuz6h90HpKQbCfOdgzTAWiB4EkJixwbOuzorPuxxOgdg1ZtDXKXCr9IS9c6ahwujc+h gnevm8TlXKzM3mEQ52Zt9ms8SCN6u6sqYrtiupkS6uV4dZJslpGWN/2ZKfqYVpvH698r 4bCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b="bHcdkHw/"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id f16-20020a0564021e9000b00478c8cfd5bbsi13433177edf.16.2022.12.27.15.23.05; Tue, 27 Dec 2022 15:23:05 -0800 (PST) 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=@pkh.me header.s=selector1 header.b="bHcdkHw/"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 021CB68BDE9; Wed, 28 Dec 2022 01:19:01 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E461768BD11 for ; Wed, 28 Dec 2022 01:18:31 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NXFVRFlsU5rTzmv83u4zXVPOLYxggriaqXmbNfYASgg=; b=bHcdkHw/AMXGLeKZaxVi24duwjyTNTVuYZ51O9cgBX8HPnDcUM+ab2nkIjfrfxnUUMs6pL fptLtShOwGaX2NARqcbUAxzgB/Ip7/5nDsCMKCdpZT0bKMqs84dppYTR1EraykNDa8nC62 TFi0b/wlJHW7CPpFzUP8jHloAsr73bk= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id f7df6e34; Tue, 27 Dec 2022 23:18:17 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:50 +0100 Message-Id: <20221227231814.2520181-9-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 08/32] avfilter/paletteuse: remove redundant alpha condition 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: TsImoiuevPfm This is redundant with a != 0xff below. --- libavfilter/vf_paletteuse.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index 8954a02524..0861a70a0b 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -599,7 +599,6 @@ DECLARE_CMP_FUNC(b, 2) static const cmp_func cmp_funcs[] = {cmp_r, cmp_g, cmp_b}; static int get_next_color(const uint8_t *color_used, const uint32_t *palette, - const int trans_thresh, int *component, const struct color_rect *box) { int wr, wg, wb; @@ -619,10 +618,6 @@ static int get_next_color(const uint8_t *color_used, const uint32_t *palette, const uint8_t g = c >> 8 & 0xff; const uint8_t b = c & 0xff; - if (a < trans_thresh) { - continue; - } - if (color_used[i] || (a != 0xff) || r < box->min[0] || g < box->min[1] || b < box->min[2] || r > box->max[0] || g > box->max[1] || b > box->max[2]) @@ -674,7 +669,7 @@ static int colormap_insert(struct color_node *map, int node_left_id = -1, node_right_id = -1; struct color_node *node; struct color_rect box1, box2; - const int pal_id = get_next_color(color_used, palette, trans_thresh, &component, box); + const int pal_id = get_next_color(color_used, palette, &component, box); if (pal_id < 0) return -1; From patchwork Tue Dec 27 23:17:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39773 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761288pzb; Tue, 27 Dec 2022 15:19:26 -0800 (PST) X-Google-Smtp-Source: AMrXdXsBc8HH8BkfixKcfmxR6vVD7h9lhQrasem1sA7/Iapma7yvb+gfPSDJS5hmXQrLwomNzG7i X-Received: by 2002:a17:906:684b:b0:7c1:ff4:d0c6 with SMTP id a11-20020a170906684b00b007c10ff4d0c6mr20620848ejs.36.1672183166319; Tue, 27 Dec 2022 15:19:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183166; cv=none; d=google.com; s=arc-20160816; b=HkisEQ7u/tfsPd9+K8dTMqG3cSx5FFg+RzJlgD3qjjAto3lhgOnUns7gN91ja5+vPW vF/ktOHIRTGTF+3F0zjnBEAR17UTLp47OhzCqfSiJZXz/C46YkVGyJeosSWPq9O1G7qN uzsTTPgm5ge2gOB3IAIEURY99GJ7KGkkID9CaYkJsxHYUeOf+Wm5prPZVk3G7/feMvFH qTfaFGZoF5s4s50VXZJuQ4oJNf6QNqxVvdCAH4DbjdUZpOlw6vUCykV+p/ZPRQweD7HS I9GigNVdEwekHIDxhm+548EWvoF8UodXY7cZCTyUAvfTBJc7PiGeOA0gsB9jdk1YCfTS Q2tg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=V0POJob8OtISDwKsHI1Z8AJ3SVLJGbd0YEWacxqiNIk=; b=toPPLIIrpcG6pWyFPIE4Xn3LDdCGBfu9+yMohAkF7zDb8spa5MqMgU6Qo65fEl7se0 fw2nvyMTC7C1UpE2gFZ2WyN62OqvbSbVyluzvcGqCyZsM1Cq8XGO6T6bJt0VrfV+9YVq Zbf9heimmkGA78cS5J2520sXhPdHnx+9U+3TMQKmK7N9RekOnMwUzisJ++kBb/gvdUp5 NZnKjhBNTePvHjqvyB5lTa3EOc46cAaAOleEWkEe8mBktvE2JqkIp+/dyzTVWJIhwWlT Eyqu4UEqZ/6g68mDBcTz7ZKA1KqDJWOtB+yZJL1V0yF0YAjeX94Yz/2ahVRDbz8XKtuG SH0A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b="cRLlOw5/"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id b12-20020a05640202cc00b00483347f1b8esi8403239edx.402.2022.12.27.15.19.25; Tue, 27 Dec 2022 15:19:26 -0800 (PST) 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=@pkh.me header.s=selector1 header.b="cRLlOw5/"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B55E468BCE7; Wed, 28 Dec 2022 01:18:35 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 86ED668BC75 for ; Wed, 28 Dec 2022 01:18:32 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oEZVw8RO3eyctQj2Ar1BS6iGMY6IOanDE4h4T+PaBuo=; b=cRLlOw5/DYlIKRPmY30IIIv772rRn0Ps3PdiF1LuRCtg6cfx1KHTJzZC1SmY+sK7XkZjWX 9RuOLTEHWNuC9qbEqgeSpnOJV+WK4NaxLEIvUPft8e0erYvoLWkcsJEGRk/rswTs2VKsRK 6YhEXxlOdrML8WhJx98lGSnUUdZYpwY= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 66551c0b; Tue, 27 Dec 2022 23:18:17 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:51 +0100 Message-Id: <20221227231814.2520181-10-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 09/32] avfilter/paletteuse: switch to a perceptual model 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: nt8S1lWNV8AN Now the selection of the color is based on a distance built around human perception of color instead of the unreliable sRGB triplet one. --- libavfilter/Makefile | 2 +- libavfilter/vf_paletteuse.c | 181 ++++++++++---------- tests/ref/fate/filter-paletteuse-bayer | 142 +++++++-------- tests/ref/fate/filter-paletteuse-bayer0 | 142 +++++++-------- tests/ref/fate/filter-paletteuse-nodither | 142 +++++++-------- tests/ref/fate/filter-paletteuse-sierra2_4a | 142 +++++++-------- 6 files changed, 378 insertions(+), 373 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index cb41ccc622..c3d13e5a26 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -404,7 +404,7 @@ OBJS-$(CONFIG_OWDENOISE_FILTER) += vf_owdenoise.o OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o OBJS-$(CONFIG_PAD_OPENCL_FILTER) += vf_pad_opencl.o opencl.o opencl/pad.o OBJS-$(CONFIG_PALETTEGEN_FILTER) += vf_palettegen.o -OBJS-$(CONFIG_PALETTEUSE_FILTER) += vf_paletteuse.o framesync.o +OBJS-$(CONFIG_PALETTEUSE_FILTER) += vf_paletteuse.o framesync.o palette.o OBJS-$(CONFIG_PERMS_FILTER) += f_perms.o OBJS-$(CONFIG_PERSPECTIVE_FILTER) += vf_perspective.o OBJS-$(CONFIG_PHASE_FILTER) += vf_phase.o diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index 0861a70a0b..3af121b1eb 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -32,6 +32,7 @@ #include "filters.h" #include "framesync.h" #include "internal.h" +#include "palette.h" enum dithering_mode { DITHERING_NONE, @@ -56,8 +57,13 @@ enum diff_mode { NB_DIFF_MODE }; +struct color_info { + uint32_t srgb; + int32_t lab[3]; +}; + struct color_node { - uint32_t val; + struct color_info c; uint8_t palette_id; int split; int left_id, right_id; @@ -162,25 +168,32 @@ static av_always_inline uint32_t dither_color(uint32_t px, int er, int eg, | av_clip_uint8((px & 0xff) + ((eb * scale) / (1<> 24, a >> 16 & 0xff, a >> 8 & 0xff, a & 0xff}; - const uint8_t c2[] = {b >> 24, b >> 16 & 0xff, b >> 8 & 0xff, b & 0xff}; - const int dr = c1[1] - c2[1]; - const int dg = c1[2] - c2[2]; - const int db = c1[3] - c2[3]; - - if (c1[0] < trans_thresh && c2[0] < trans_thresh) { + const uint8_t alpha_a = a->srgb >> 24; + const uint8_t alpha_b = b->srgb >> 24; + + if (alpha_a < trans_thresh && alpha_b < trans_thresh) { return 0; - } else if (c1[0] >= trans_thresh && c2[0] >= trans_thresh) { - return dr*dr + dg*dg + db*db; + } else if (alpha_a >= trans_thresh && alpha_b >= trans_thresh) { + const int64_t dL = a->lab[0] - b->lab[0]; + const int64_t da = a->lab[1] - b->lab[1]; + const int64_t db = a->lab[2] - b->lab[2]; + const int64_t ret = dL*dL + da*da + db*db; + return FFMIN(ret, INT32_MAX - 1); } else { - return 255*255 + 255*255 + 255*255; + return INT32_MAX - 1; } } -static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *palette, const uint32_t target, const int trans_thresh) +static struct color_info get_color_from_srgb(uint32_t srgb) +{ + const struct Lab lab = ff_srgb_u8_to_oklab_int(srgb); + struct color_info ret = {.srgb=srgb, .lab={lab.L, lab.a, lab.b}}; + return ret; +} + +static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *palette, const struct color_info *target, const int trans_thresh) { int i, pal_id = -1, min_dist = INT_MAX; @@ -188,7 +201,8 @@ static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *pale const uint32_t c = palette[i]; if (c >> 24 >= trans_thresh) { // ignore transparent entry - const int d = diff(palette[i], target, trans_thresh); + const struct color_info pal_color = get_color_from_srgb(palette[i]); + const int d = diff(&pal_color, target, trans_thresh); if (d < min_dist) { pal_id = i; min_dist = d; @@ -206,14 +220,13 @@ struct nearest_color { static void colormap_nearest_node(const struct color_node *map, const int node_pos, - const uint32_t target, + const struct color_info *target, const int trans_thresh, struct nearest_color *nearest) { const struct color_node *kd = map + node_pos; - const int shift = (2 - kd->split) * 8; - int dx, nearer_kd_id, further_kd_id; - const uint32_t current = kd->val; + int nearer_kd_id, further_kd_id; + const struct color_info *current = &kd->c; const int current_to_target = diff(target, current, trans_thresh); if (current_to_target < nearest->dist_sqd) { @@ -222,7 +235,7 @@ static void colormap_nearest_node(const struct color_node *map, } if (kd->left_id != -1 || kd->right_id != -1) { - dx = (int)(target>>shift & 0xff) - (int)(current>>shift & 0xff); + const int dx = target->lab[kd->split] - current->lab[kd->split]; if (dx <= 0) nearer_kd_id = kd->left_id, further_kd_id = kd->right_id; else nearer_kd_id = kd->right_id, further_kd_id = kd->left_id; @@ -235,9 +248,9 @@ static void colormap_nearest_node(const struct color_node *map, } } -static av_always_inline uint8_t colormap_nearest_recursive(const struct color_node *node, const uint8_t target, const int trans_thresh) +static av_always_inline uint8_t colormap_nearest_recursive(const struct color_node *node, const struct color_info *target, const int trans_thresh) { - struct nearest_color res = {.dist_sqd = INT_MAX, .node_pos = -1}; + struct nearest_color res = {.dist_sqd = INT32_MAX, .node_pos = -1}; colormap_nearest_node(node, 0, target, trans_thresh, &res); return node[res.node_pos].palette_id; } @@ -247,7 +260,7 @@ struct stack_node { int dx2; }; -static av_always_inline uint8_t colormap_nearest_iterative(const struct color_node *root, const uint32_t target, const int trans_thresh) +static av_always_inline uint8_t colormap_nearest_iterative(const struct color_node *root, const struct color_info *target, const int trans_thresh) { int pos = 0, best_node_id = -1, best_dist = INT_MAX, cur_color_id = 0; struct stack_node nodes[16]; @@ -256,7 +269,7 @@ static av_always_inline uint8_t colormap_nearest_iterative(const struct color_no for (;;) { const struct color_node *kd = &root[cur_color_id]; - const uint32_t current = kd->val; + const struct color_info *current = &kd->c; const int current_to_target = diff(target, current, trans_thresh); /* Compare current color node to the target and update our best node if @@ -270,8 +283,7 @@ static av_always_inline uint8_t colormap_nearest_iterative(const struct color_no /* Check if it's not a leaf */ if (kd->left_id != -1 || kd->right_id != -1) { - const int shift = (2 - kd->split) * 8; - const int dx = (target>>shift & 0xff) - (current>>shift & 0xff); + const int dx = target->lab[kd->split] - current->lab[kd->split]; int nearer_kd_id, further_kd_id; /* Define which side is the most interesting. */ @@ -332,6 +344,7 @@ static av_always_inline int color_get(PaletteUseContext *s, uint32_t color, const enum color_search_method search_method) { int i; + struct color_info clrinfo; const uint8_t rhash = (color>>16) & ((1<> 8) & ((1<color = color; - e->pal_entry = COLORMAP_NEAREST(search_method, s->palette, s->map, color, s->trans_thresh); + clrinfo = get_color_from_srgb(color); + e->pal_entry = COLORMAP_NEAREST(search_method, s->palette, s->map, &clrinfo, s->trans_thresh); return e->pal_entry; } @@ -494,20 +508,18 @@ static void disp_node(AVBPrint *buf, int depth) { const struct color_node *node = &map[node_id]; - const uint32_t fontcolor = (node->val>>16 & 0xff) > 0x50 && - (node->val>> 8 & 0xff) > 0x50 && - (node->val & 0xff) > 0x50 ? 0 : 0xffffff; - const int rgb_comp = node->split; + const uint32_t fontcolor = node->c.lab[0] > 0x7fff ? 0 : 0xffffff; + const int lab_comp = node->split; av_bprintf(buf, "%*cnode%d [" - "label=\"%c%02X%c%02X%c%02X%c\" " + "label=\"%c%d%c%d%c%d%c\" " "fillcolor=\"#%06"PRIX32"\" " "fontcolor=\"#%06"PRIX32"\"]\n", depth*INDENT, ' ', node->palette_id, - "[ "[rgb_comp], node->val>>16 & 0xff, - "][ "[rgb_comp], node->val>> 8 & 0xff, - " ]["[rgb_comp], node->val & 0xff, - " ]"[rgb_comp], - node->val & 0xffffff, + "[ "[lab_comp], node->c.lab[0], + "][ "[lab_comp], node->c.lab[1], + " ]["[lab_comp], node->c.lab[2], + " ]"[lab_comp], + node->c.srgb & 0xffffff, fontcolor); if (parent_id != -1) av_bprintf(buf, "%*cnode%d -> node%d\n", depth*INDENT, ' ', @@ -550,18 +562,18 @@ static int debug_accuracy(const struct color_node *node, const uint32_t *palette for (r = 0; r < 256; r++) { for (g = 0; g < 256; g++) { for (b = 0; b < 256; b++) { - const uint32_t argb = 0xff000000 | r<<16 | g<<8 | b; - const int r1 = COLORMAP_NEAREST(search_method, palette, node, argb, trans_thresh); - const int r2 = colormap_nearest_bruteforce(palette, argb, trans_thresh); + const struct color_info target = get_color_from_srgb(0xff000000 | r<<16 | g<<8 | b); + const int r1 = COLORMAP_NEAREST(search_method, palette, node, &target, trans_thresh); + const int r2 = colormap_nearest_bruteforce(palette, &target, trans_thresh); if (r1 != r2) { - const uint32_t c1 = palette[r1]; - const uint32_t c2 = palette[r2]; - const int d1 = diff(0xff000000 | c1, argb, trans_thresh); - const int d2 = diff(0xff000000 | c2, argb, trans_thresh); + const struct color_info pal_c1 = get_color_from_srgb(0xff000000 | palette[r1]); + const struct color_info pal_c2 = get_color_from_srgb(0xff000000 | palette[r2]); + const int d1 = diff(&pal_c1, &target, trans_thresh); + const int d2 = diff(&pal_c2, &target, trans_thresh); if (d1 != d2) { av_log(NULL, AV_LOG_ERROR, "/!\\ %02X%02X%02X: %d ! %d (%06"PRIX32" ! %06"PRIX32") / dist: %d ! %d\n", - r, g, b, r1, r2, c1 & 0xffffff, c2 & 0xffffff, d1, d2); + r, g, b, r1, r2, pal_c1.srgb & 0xffffff, pal_c2.srgb & 0xffffff, d1, d2); ret = 1; } } @@ -572,66 +584,63 @@ static int debug_accuracy(const struct color_node *node, const uint32_t *palette } struct color { - uint32_t value; + struct Lab value; uint8_t pal_id; }; struct color_rect { - uint8_t min[3]; - uint8_t max[3]; + int min[3]; + int max[3]; }; typedef int (*cmp_func)(const void *, const void *); -#define DECLARE_CMP_FUNC(name, pos) \ +#define DECLARE_CMP_FUNC(name) \ static int cmp_##name(const void *pa, const void *pb) \ { \ const struct color *a = pa; \ const struct color *b = pb; \ - return (int)(a->value >> (8 * (2 - (pos))) & 0xff) \ - - (int)(b->value >> (8 * (2 - (pos))) & 0xff); \ + return FFDIFFSIGN(a->value.name, b->value.name); \ } -DECLARE_CMP_FUNC(r, 0) -DECLARE_CMP_FUNC(g, 1) -DECLARE_CMP_FUNC(b, 2) +DECLARE_CMP_FUNC(L) +DECLARE_CMP_FUNC(a) +DECLARE_CMP_FUNC(b) -static const cmp_func cmp_funcs[] = {cmp_r, cmp_g, cmp_b}; +static const cmp_func cmp_funcs[] = {cmp_L, cmp_a, cmp_b}; static int get_next_color(const uint8_t *color_used, const uint32_t *palette, int *component, const struct color_rect *box) { - int wr, wg, wb; + int wL, wa, wb; int i, longest = 0; unsigned nb_color = 0; struct color_rect ranges; struct color tmp_pal[256]; cmp_func cmpf; - ranges.min[0] = ranges.min[1] = ranges.min[2] = 0xff; - ranges.max[0] = ranges.max[1] = ranges.max[2] = 0x00; + ranges.min[0] = ranges.min[1] = ranges.min[2] = 0xffff; + ranges.max[0] = ranges.max[1] = ranges.max[2] = -0xffff; for (i = 0; i < AVPALETTE_COUNT; i++) { const uint32_t c = palette[i]; const uint8_t a = c >> 24; - const uint8_t r = c >> 16 & 0xff; - const uint8_t g = c >> 8 & 0xff; - const uint8_t b = c & 0xff; + const struct Lab lab = ff_srgb_u8_to_oklab_int(c); if (color_used[i] || (a != 0xff) || - r < box->min[0] || g < box->min[1] || b < box->min[2] || - r > box->max[0] || g > box->max[1] || b > box->max[2]) + lab.L < box->min[0] || lab.a < box->min[1] || lab.b < box->min[2] || + lab.L > box->max[0] || lab.a > box->max[1] || lab.b > box->max[2]) continue; - if (r < ranges.min[0]) ranges.min[0] = r; - if (g < ranges.min[1]) ranges.min[1] = g; - if (b < ranges.min[2]) ranges.min[2] = b; + if (lab.L < ranges.min[0]) ranges.min[0] = lab.L; + if (lab.a < ranges.min[1]) ranges.min[1] = lab.a; + if (lab.b < ranges.min[2]) ranges.min[2] = lab.b; - if (r > ranges.max[0]) ranges.max[0] = r; - if (g > ranges.max[1]) ranges.max[1] = g; - if (b > ranges.max[2]) ranges.max[2] = b; + if (lab.L > ranges.max[0]) ranges.max[0] = lab.L; + if (lab.a > ranges.max[1]) ranges.max[1] = lab.a; + if (lab.b > ranges.max[2]) ranges.max[2] = lab.b; - tmp_pal[nb_color].value = c; + tmp_pal[nb_color].value = lab; tmp_pal[nb_color].pal_id = i; nb_color++; @@ -641,12 +650,12 @@ static int get_next_color(const uint8_t *color_used, const uint32_t *palette, return -1; /* define longest axis that will be the split component */ - wr = ranges.max[0] - ranges.min[0]; - wg = ranges.max[1] - ranges.min[1]; + wL = ranges.max[0] - ranges.min[0]; + wa = ranges.max[1] - ranges.min[1]; wb = ranges.max[2] - ranges.min[2]; - if (wr >= wg && wr >= wb) longest = 0; - if (wg >= wr && wg >= wb) longest = 1; - if (wb >= wr && wb >= wg) longest = 2; + if (wb >= wL && wb >= wa) longest = 2; + if (wa >= wL && wa >= wb) longest = 1; + if (wL >= wa && wL >= wb) longest = 0; cmpf = cmp_funcs[longest]; *component = longest; @@ -663,9 +672,8 @@ static int colormap_insert(struct color_node *map, const int trans_thresh, const struct color_rect *box) { - uint32_t c; int component, cur_id; - uint8_t comp_value; + int comp_value; int node_left_id = -1, node_right_id = -1; struct color_node *node; struct color_rect box1, box2; @@ -676,19 +684,18 @@ static int colormap_insert(struct color_node *map, /* create new node with that color */ cur_id = (*nb_used)++; - c = palette[pal_id]; node = &map[cur_id]; node->split = component; node->palette_id = pal_id; - node->val = c; + node->c = get_color_from_srgb(palette[pal_id]); color_used[pal_id] = 1; /* get the two boxes this node creates */ box1 = box2 = *box; - comp_value = node->val >> ((2 - component) * 8) & 0xff; + comp_value = node->c.lab[component]; box1.max[component] = comp_value; - box2.min[component] = FFMIN(comp_value + 1, 255); + box2.min[component] = FFMIN(comp_value + 1, 0xffff); node_left_id = colormap_insert(map, color_used, nb_used, palette, trans_thresh, &box1); @@ -735,8 +742,8 @@ static void load_colormap(PaletteUseContext *s) } } - box.min[0] = box.min[1] = box.min[2] = 0x00; - box.max[0] = box.max[1] = box.max[2] = 0xff; + box.min[0] = box.min[1] = box.min[2] = -0xffff; + box.max[0] = box.max[1] = box.max[2] = 0xffff; colormap_insert(s->map, color_used, &nb_used, s->palette, s->trans_thresh, &box); @@ -763,11 +770,9 @@ static void debug_mean_error(PaletteUseContext *s, const AVFrame *in1, for (y = 0; y < in1->height; y++) { for (x = 0; x < in1->width; x++) { - const uint32_t c1 = src1[x]; - const uint32_t c2 = palette[src2[x]]; - const uint32_t argb1 = 0xff000000 | c1; - const uint32_t argb2 = 0xff000000 | c2; - mean_err += diff(argb1, argb2, s->trans_thresh); + const struct color_info c1 = get_color_from_srgb(0xff000000 | src1[x]); + const struct color_info c2 = get_color_from_srgb(0xff000000 | palette[src2[x]]); + mean_err += diff(&c1, &c2, s->trans_thresh); } src1 += src1_linesize; src2 += src2_linesize; diff --git a/tests/ref/fate/filter-paletteuse-bayer b/tests/ref/fate/filter-paletteuse-bayer index 5ca0115053..fa1778a1bb 100644 --- a/tests/ref/fate/filter-paletteuse-bayer +++ b/tests/ref/fate/filter-paletteuse-bayer @@ -3,74 +3,74 @@ #codec_id 0: rawvideo #dimensions 0: 320x180 #sar 0: 1/1 -0, 0, 0, 1, 230400, 0x7b259d08 -0, 1, 1, 1, 230400, 0xf04095e0 -0, 2, 2, 1, 230400, 0x84d49cd5 -0, 3, 3, 1, 230400, 0xd7a29aaf -0, 4, 4, 1, 230400, 0x9047947c -0, 5, 5, 1, 230400, 0xfeb990e7 -0, 6, 6, 1, 230400, 0x51ee9295 -0, 7, 7, 1, 230400, 0x66fd4833 -0, 8, 8, 1, 230400, 0x4c0948f0 -0, 9, 9, 1, 230400, 0x632b4776 -0, 10, 10, 1, 230400, 0x7a3c87e2 -0, 11, 11, 1, 230400, 0x4a9286ba -0, 12, 12, 1, 230400, 0x54dc8649 -0, 13, 13, 1, 230400, 0x92628944 -0, 14, 14, 1, 230400, 0x80f9899f -0, 15, 15, 1, 230400, 0x5cd78bd8 -0, 16, 16, 1, 230400, 0x4b4ca390 -0, 17, 17, 1, 230400, 0x82cca153 -0, 18, 18, 1, 230400, 0x65f1a2d0 -0, 19, 19, 1, 230400, 0x7df6ae4c -0, 20, 20, 1, 230400, 0x909baccc -0, 21, 21, 1, 230400, 0x1892ac65 -0, 22, 22, 1, 230400, 0x3247bb32 -0, 23, 23, 1, 230400, 0x592fbbe5 -0, 24, 24, 1, 230400, 0x189db9d5 -0, 25, 25, 1, 230400, 0x1a38b8da -0, 26, 26, 1, 230400, 0xccd6bd07 -0, 27, 27, 1, 230400, 0xd4a2bc53 -0, 28, 28, 1, 230400, 0x9ce3bb4e -0, 29, 29, 1, 230400, 0x5ffdc4db -0, 30, 30, 1, 230400, 0xc885c7c9 -0, 31, 31, 1, 230400, 0xe27b9d33 -0, 32, 32, 1, 230400, 0xac03a256 -0, 33, 33, 1, 230400, 0xa2c73929 -0, 34, 34, 1, 230400, 0x33793b73 -0, 35, 35, 1, 230400, 0x1e400add -0, 36, 36, 1, 230400, 0x98e50c6e -0, 37, 37, 1, 230400, 0x68ed226d -0, 38, 38, 1, 230400, 0x569e23cb -0, 39, 39, 1, 230400, 0x82bf3fc0 -0, 40, 40, 1, 230400, 0x2b202e86 -0, 41, 41, 1, 230400, 0x7acd2dee -0, 42, 42, 1, 230400, 0xfe872e42 -0, 43, 43, 1, 230400, 0x026c12e5 -0, 44, 44, 1, 230400, 0x81561399 -0, 45, 45, 1, 230400, 0xa08c13b6 -0, 46, 46, 1, 230400, 0x89e712f5 -0, 47, 47, 1, 230400, 0x569011ac -0, 48, 48, 1, 230400, 0xd4691112 -0, 49, 49, 1, 230400, 0x2e50165a -0, 50, 50, 1, 230400, 0x0a1215b6 -0, 51, 51, 1, 230400, 0x3c5316e3 -0, 52, 52, 1, 230400, 0x079c1393 -0, 53, 53, 1, 230400, 0x39ca1c48 -0, 54, 54, 1, 230400, 0xe27f199c -0, 55, 55, 1, 230400, 0x10ab1bab -0, 56, 56, 1, 230400, 0xeab017c3 -0, 57, 57, 1, 230400, 0x5f701f77 -0, 58, 58, 1, 230400, 0x01371d7d -0, 59, 59, 1, 230400, 0x22751e99 -0, 60, 60, 1, 230400, 0xaee91a97 -0, 61, 61, 1, 230400, 0x27b41f32 -0, 62, 62, 1, 230400, 0x4ff32bb1 -0, 63, 63, 1, 230400, 0x86e02864 -0, 64, 64, 1, 230400, 0x5eb52b3e -0, 65, 65, 1, 230400, 0xd9252ba8 -0, 66, 66, 1, 230400, 0x72232d9b -0, 67, 67, 1, 230400, 0x599a206f -0, 68, 68, 1, 230400, 0x4d2c1ca5 -0, 69, 69, 1, 230400, 0x9166293b -0, 70, 70, 1, 230400, 0x00992453 +0, 0, 0, 1, 230400, 0x10a99774 +0, 1, 1, 1, 230400, 0xa18b90f8 +0, 2, 2, 1, 230400, 0x837a95f9 +0, 3, 3, 1, 230400, 0xc50d948b +0, 4, 4, 1, 230400, 0xdefc8eca +0, 5, 5, 1, 230400, 0x00498bdb +0, 6, 6, 1, 230400, 0x22458cdc +0, 7, 7, 1, 230400, 0xfad1418c +0, 8, 8, 1, 230400, 0xf09341dd +0, 9, 9, 1, 230400, 0x5ef141ac +0, 10, 10, 1, 230400, 0x6f2d815f +0, 11, 11, 1, 230400, 0x960880c2 +0, 12, 12, 1, 230400, 0x4ba37f8f +0, 13, 13, 1, 230400, 0x3e678082 +0, 14, 14, 1, 230400, 0x4f1c80da +0, 15, 15, 1, 230400, 0x69be82fd +0, 16, 16, 1, 230400, 0x81d29b80 +0, 17, 17, 1, 230400, 0x5fdc9af7 +0, 18, 18, 1, 230400, 0xb8969c2b +0, 19, 19, 1, 230400, 0xdb37a691 +0, 20, 20, 1, 230400, 0xdeb6a645 +0, 21, 21, 1, 230400, 0xf5c6a606 +0, 22, 22, 1, 230400, 0x110ab482 +0, 23, 23, 1, 230400, 0x5bddb45b +0, 24, 24, 1, 230400, 0xc18ab32a +0, 25, 25, 1, 230400, 0x22c1b2be +0, 26, 26, 1, 230400, 0xaa7cb5c3 +0, 27, 27, 1, 230400, 0x5e8fb50f +0, 28, 28, 1, 230400, 0x20e1b42a +0, 29, 29, 1, 230400, 0x0c94c158 +0, 30, 30, 1, 230400, 0x41adc2a3 +0, 31, 31, 1, 230400, 0xbc359983 +0, 32, 32, 1, 230400, 0x19bb9eea +0, 33, 33, 1, 230400, 0xfecd2f06 +0, 34, 34, 1, 230400, 0x26ba3110 +0, 35, 35, 1, 230400, 0xfdbcff0f +0, 36, 36, 1, 230400, 0x1f030028 +0, 37, 37, 1, 230400, 0xccca1b0b +0, 38, 38, 1, 230400, 0x66f91b1f +0, 39, 39, 1, 230400, 0x0ef4366b +0, 40, 40, 1, 230400, 0x2fac271c +0, 41, 41, 1, 230400, 0xbef026a9 +0, 42, 42, 1, 230400, 0x775726f5 +0, 43, 43, 1, 230400, 0x35210966 +0, 44, 44, 1, 230400, 0x0c36099a +0, 45, 45, 1, 230400, 0xc4f00a24 +0, 46, 46, 1, 230400, 0xa7c409b9 +0, 47, 47, 1, 230400, 0xa92d082b +0, 48, 48, 1, 230400, 0xfc49442e +0, 49, 49, 1, 230400, 0xb7de4997 +0, 50, 50, 1, 230400, 0x16d24877 +0, 51, 51, 1, 230400, 0xb0954a17 +0, 52, 52, 1, 230400, 0x709f4766 +0, 53, 53, 1, 230400, 0xe0dc4e4f +0, 54, 54, 1, 230400, 0xfa844b09 +0, 55, 55, 1, 230400, 0xa62a4cf2 +0, 56, 56, 1, 230400, 0x078d4a76 +0, 57, 57, 1, 230400, 0x64c4505c +0, 58, 58, 1, 230400, 0xe8604f13 +0, 59, 59, 1, 230400, 0x39a3503c +0, 60, 60, 1, 230400, 0x915a4cf1 +0, 61, 61, 1, 230400, 0x495a5176 +0, 62, 62, 1, 230400, 0xc0a75b2b +0, 63, 63, 1, 230400, 0x1a385761 +0, 64, 64, 1, 230400, 0x9a245984 +0, 65, 65, 1, 230400, 0xbe475ad9 +0, 66, 66, 1, 230400, 0x8e275c85 +0, 67, 67, 1, 230400, 0x5ba45436 +0, 68, 68, 1, 230400, 0x80285097 +0, 69, 69, 1, 230400, 0xbb1c5bfd +0, 70, 70, 1, 230400, 0x273a5890 diff --git a/tests/ref/fate/filter-paletteuse-bayer0 b/tests/ref/fate/filter-paletteuse-bayer0 index 85b3832f19..44cd09a6a9 100644 --- a/tests/ref/fate/filter-paletteuse-bayer0 +++ b/tests/ref/fate/filter-paletteuse-bayer0 @@ -3,74 +3,74 @@ #codec_id 0: rawvideo #dimensions 0: 320x180 #sar 0: 1/1 -0, 0, 0, 1, 230400, 0xfb6042d2 -0, 1, 1, 1, 230400, 0x1c193c09 -0, 2, 2, 1, 230400, 0x183442f8 -0, 3, 3, 1, 230400, 0xa9634084 -0, 4, 4, 1, 230400, 0x90df3d2f -0, 5, 5, 1, 230400, 0x59d7389f -0, 6, 6, 1, 230400, 0xb9bd3a30 -0, 7, 7, 1, 230400, 0x9874ee38 -0, 8, 8, 1, 230400, 0xf661f01f -0, 9, 9, 1, 230400, 0xacbcedbd -0, 10, 10, 1, 230400, 0x05f02d59 -0, 11, 11, 1, 230400, 0xc54c2cc8 -0, 12, 12, 1, 230400, 0x19c92d61 -0, 13, 13, 1, 230400, 0x14902fb2 -0, 14, 14, 1, 230400, 0x99b62fb6 -0, 15, 15, 1, 230400, 0x3fc63293 -0, 16, 16, 1, 230400, 0x1eed4b38 -0, 17, 17, 1, 230400, 0xe9d747e0 -0, 18, 18, 1, 230400, 0x9825496f -0, 19, 19, 1, 230400, 0x94625411 -0, 20, 20, 1, 230400, 0xed7052a3 -0, 21, 21, 1, 230400, 0x80d552dc -0, 22, 22, 1, 230400, 0x89b360bb -0, 23, 23, 1, 230400, 0xee9a616a -0, 24, 24, 1, 230400, 0x30bb5f86 -0, 25, 25, 1, 230400, 0x5ec15eae -0, 26, 26, 1, 230400, 0x0956633e -0, 27, 27, 1, 230400, 0x72df62fa -0, 28, 28, 1, 230400, 0xbafd61d0 -0, 29, 29, 1, 230400, 0x393f81f3 -0, 30, 30, 1, 230400, 0xba6a848c -0, 31, 31, 1, 230400, 0x502ba0d9 -0, 32, 32, 1, 230400, 0xc81ba71d -0, 33, 33, 1, 230400, 0x54cdf270 -0, 34, 34, 1, 230400, 0xe951f3e2 -0, 35, 35, 1, 230400, 0xbf15baa1 -0, 36, 36, 1, 230400, 0xbf96bb12 -0, 37, 37, 1, 230400, 0xcdd5cafe -0, 38, 38, 1, 230400, 0x97b1cbb4 -0, 39, 39, 1, 230400, 0x955ae28f -0, 40, 40, 1, 230400, 0x6a8dd28f -0, 41, 41, 1, 230400, 0x8f02d268 -0, 42, 42, 1, 230400, 0x3075d269 -0, 43, 43, 1, 230400, 0x29e8b910 -0, 44, 44, 1, 230400, 0xb35ab888 -0, 45, 45, 1, 230400, 0xc3afb942 -0, 46, 46, 1, 230400, 0xeba8b860 -0, 47, 47, 1, 230400, 0x5de8b7ab -0, 48, 48, 1, 230400, 0x90233679 -0, 49, 49, 1, 230400, 0x5fbc3abb -0, 50, 50, 1, 230400, 0xeaa73b87 -0, 51, 51, 1, 230400, 0xbd0a3c4b -0, 52, 52, 1, 230400, 0xeddb39ba -0, 53, 53, 1, 230400, 0x269d4131 -0, 54, 54, 1, 230400, 0xae3e3e8c -0, 55, 55, 1, 230400, 0x65f54056 -0, 56, 56, 1, 230400, 0xf2173c5b -0, 57, 57, 1, 230400, 0xbd714477 -0, 58, 58, 1, 230400, 0xb60c42ed -0, 59, 59, 1, 230400, 0x8def43a5 -0, 60, 60, 1, 230400, 0xe6a73f05 -0, 61, 61, 1, 230400, 0xedfe4430 -0, 62, 62, 1, 230400, 0x76c5505a -0, 63, 63, 1, 230400, 0xf48d4d04 -0, 64, 64, 1, 230400, 0xa49950b5 -0, 65, 65, 1, 230400, 0xc64d51d8 -0, 66, 66, 1, 230400, 0xa08253ec -0, 67, 67, 1, 230400, 0xd6ef4609 -0, 68, 68, 1, 230400, 0x27a241e7 -0, 69, 69, 1, 230400, 0xe5f74b4a -0, 70, 70, 1, 230400, 0xb0194751 +0, 0, 0, 1, 230400, 0x9f192d87 +0, 1, 1, 1, 230400, 0x49db27f5 +0, 2, 2, 1, 230400, 0x8f8f2cb0 +0, 3, 3, 1, 230400, 0x33a82b14 +0, 4, 4, 1, 230400, 0x6f03275f +0, 5, 5, 1, 230400, 0x1fce2453 +0, 6, 6, 1, 230400, 0x932925b3 +0, 7, 7, 1, 230400, 0x9987dba9 +0, 8, 8, 1, 230400, 0x9ba2dd04 +0, 9, 9, 1, 230400, 0x37eadc31 +0, 10, 10, 1, 230400, 0xda0518e2 +0, 11, 11, 1, 230400, 0xb96718b5 +0, 12, 12, 1, 230400, 0x0d63191e +0, 13, 13, 1, 230400, 0xfc561af0 +0, 14, 14, 1, 230400, 0x22fd1b68 +0, 15, 15, 1, 230400, 0xef631dc5 +0, 16, 16, 1, 230400, 0xc0673745 +0, 17, 17, 1, 230400, 0x56c933f6 +0, 18, 18, 1, 230400, 0x3790359a +0, 19, 19, 1, 230400, 0xd3293d02 +0, 20, 20, 1, 230400, 0xee513caa +0, 21, 21, 1, 230400, 0x0fc33c17 +0, 22, 22, 1, 230400, 0x00c74991 +0, 23, 23, 1, 230400, 0xa7de49f5 +0, 24, 24, 1, 230400, 0xd99b485a +0, 25, 25, 1, 230400, 0x6aab47d2 +0, 26, 26, 1, 230400, 0x2e434bf7 +0, 27, 27, 1, 230400, 0x46a04b1d +0, 28, 28, 1, 230400, 0x135f49f8 +0, 29, 29, 1, 230400, 0x50566b86 +0, 30, 30, 1, 230400, 0xb0416d84 +0, 31, 31, 1, 230400, 0x8f20840c +0, 32, 32, 1, 230400, 0xedbf8857 +0, 33, 33, 1, 230400, 0x30d6d698 +0, 34, 34, 1, 230400, 0xbc88d7a7 +0, 35, 35, 1, 230400, 0xce869fa3 +0, 36, 36, 1, 230400, 0xa973a0b1 +0, 37, 37, 1, 230400, 0x4c93b3a5 +0, 38, 38, 1, 230400, 0x3574b473 +0, 39, 39, 1, 230400, 0xa96bc936 +0, 40, 40, 1, 230400, 0x4a83b86d +0, 41, 41, 1, 230400, 0x3b68b7cb +0, 42, 42, 1, 230400, 0xc0feb869 +0, 43, 43, 1, 230400, 0x1a7d9ed8 +0, 44, 44, 1, 230400, 0xc32e9f12 +0, 45, 45, 1, 230400, 0x30f29fa4 +0, 46, 46, 1, 230400, 0x7b369f80 +0, 47, 47, 1, 230400, 0x28249e03 +0, 48, 48, 1, 230400, 0xf5c67eee +0, 49, 49, 1, 230400, 0x40728404 +0, 50, 50, 1, 230400, 0xbf7383b0 +0, 51, 51, 1, 230400, 0x446d84c9 +0, 52, 52, 1, 230400, 0x5f678279 +0, 53, 53, 1, 230400, 0x4d1d891d +0, 54, 54, 1, 230400, 0x173c866c +0, 55, 55, 1, 230400, 0x045988a6 +0, 56, 56, 1, 230400, 0xf25f848f +0, 57, 57, 1, 230400, 0xd61c8d71 +0, 58, 58, 1, 230400, 0x86428b1e +0, 59, 59, 1, 230400, 0xc6268c08 +0, 60, 60, 1, 230400, 0xed9787e3 +0, 61, 61, 1, 230400, 0xe7ef8a27 +0, 62, 62, 1, 230400, 0x5dc09497 +0, 63, 63, 1, 230400, 0x8ec490b6 +0, 64, 64, 1, 230400, 0xc01d92e4 +0, 65, 65, 1, 230400, 0xbf6a941d +0, 66, 66, 1, 230400, 0x53fd966a +0, 67, 67, 1, 230400, 0xa2138be9 +0, 68, 68, 1, 230400, 0x2b868967 +0, 69, 69, 1, 230400, 0x4c889564 +0, 70, 70, 1, 230400, 0x6d8491ed diff --git a/tests/ref/fate/filter-paletteuse-nodither b/tests/ref/fate/filter-paletteuse-nodither index a2e61c3690..1535777547 100644 --- a/tests/ref/fate/filter-paletteuse-nodither +++ b/tests/ref/fate/filter-paletteuse-nodither @@ -3,74 +3,74 @@ #codec_id 0: rawvideo #dimensions 0: 320x180 #sar 0: 1/1 -0, 0, 0, 1, 230400, 0x690560cb -0, 1, 1, 1, 230400, 0x197a5a54 -0, 2, 2, 1, 230400, 0x665961db -0, 3, 3, 1, 230400, 0xce0b5fa8 -0, 4, 4, 1, 230400, 0xa40e5cb0 -0, 5, 5, 1, 230400, 0xa5aa58da -0, 6, 6, 1, 230400, 0x8e0259bb -0, 7, 7, 1, 230400, 0x476d0dba -0, 8, 8, 1, 230400, 0xfb1b0e8c -0, 9, 9, 1, 230400, 0x50f60d3b -0, 10, 10, 1, 230400, 0x12cd4bab -0, 11, 11, 1, 230400, 0x4c274b13 -0, 12, 12, 1, 230400, 0xea494b0a -0, 13, 13, 1, 230400, 0x118c4cc1 -0, 14, 14, 1, 230400, 0xd4224db7 -0, 15, 15, 1, 230400, 0xc3014f88 -0, 16, 16, 1, 230400, 0xe07a6838 -0, 17, 17, 1, 230400, 0x1b97659a -0, 18, 18, 1, 230400, 0xf104670c -0, 19, 19, 1, 230400, 0x7b63733d -0, 20, 20, 1, 230400, 0x2c237200 -0, 21, 21, 1, 230400, 0x775d7248 -0, 22, 22, 1, 230400, 0xcaee7f9e -0, 23, 23, 1, 230400, 0x4e4680a1 -0, 24, 24, 1, 230400, 0x21fb7e53 -0, 25, 25, 1, 230400, 0xf0297db6 -0, 26, 26, 1, 230400, 0x79a9829d -0, 27, 27, 1, 230400, 0x8ccb80f7 -0, 28, 28, 1, 230400, 0xf4dd807f -0, 29, 29, 1, 230400, 0xb6cc8696 -0, 30, 30, 1, 230400, 0x6c8a8917 -0, 31, 31, 1, 230400, 0x9e08615a -0, 32, 32, 1, 230400, 0xc098685b -0, 33, 33, 1, 230400, 0x5c09e710 -0, 34, 34, 1, 230400, 0xe4c4e9be -0, 35, 35, 1, 230400, 0xac59c150 -0, 36, 36, 1, 230400, 0x6045c272 -0, 37, 37, 1, 230400, 0xf71ee6dc -0, 38, 38, 1, 230400, 0xc82ce6f6 -0, 39, 39, 1, 230400, 0xb7ed039a -0, 40, 40, 1, 230400, 0xda93f241 -0, 41, 41, 1, 230400, 0x194bf23b -0, 42, 42, 1, 230400, 0xe7e6f2e2 -0, 43, 43, 1, 230400, 0xe479d834 -0, 44, 44, 1, 230400, 0xefdfd87e -0, 45, 45, 1, 230400, 0xec66d8c0 -0, 46, 46, 1, 230400, 0x3a6bd81b -0, 47, 47, 1, 230400, 0xb5d1d700 -0, 48, 48, 1, 230400, 0x3bc69e8b -0, 49, 49, 1, 230400, 0x723fa455 -0, 50, 50, 1, 230400, 0x7c49a392 -0, 51, 51, 1, 230400, 0x272ea4b7 -0, 52, 52, 1, 230400, 0xebdda081 -0, 53, 53, 1, 230400, 0xfd26ab99 -0, 54, 54, 1, 230400, 0xfa02a891 -0, 55, 55, 1, 230400, 0xda2caa7f -0, 56, 56, 1, 230400, 0x2360a611 -0, 57, 57, 1, 230400, 0xaa3baefd -0, 58, 58, 1, 230400, 0x0961ad5c -0, 59, 59, 1, 230400, 0x48d2ae47 -0, 60, 60, 1, 230400, 0x20eda81b -0, 61, 61, 1, 230400, 0x8821adbb -0, 62, 62, 1, 230400, 0x1150b810 -0, 63, 63, 1, 230400, 0x08dab596 -0, 64, 64, 1, 230400, 0x4731b7a5 -0, 65, 65, 1, 230400, 0xf382b87e -0, 66, 66, 1, 230400, 0xdba7bac2 -0, 67, 67, 1, 230400, 0xf569acf9 -0, 68, 68, 1, 230400, 0x22d8a95d -0, 69, 69, 1, 230400, 0xed0bb4fb -0, 70, 70, 1, 230400, 0x2dccb218 +0, 0, 0, 1, 230400, 0xf7976830 +0, 1, 1, 1, 230400, 0xfb756340 +0, 2, 2, 1, 230400, 0x2199687e +0, 3, 3, 1, 230400, 0xd8186657 +0, 4, 4, 1, 230400, 0xd33a6319 +0, 5, 5, 1, 230400, 0x704c603b +0, 6, 6, 1, 230400, 0x9e6c6146 +0, 7, 7, 1, 230400, 0x63ee15f1 +0, 8, 8, 1, 230400, 0x8b201716 +0, 9, 9, 1, 230400, 0xac8e1602 +0, 10, 10, 1, 230400, 0xd97e53b6 +0, 11, 11, 1, 230400, 0x8ecc5304 +0, 12, 12, 1, 230400, 0x0ea25368 +0, 13, 13, 1, 230400, 0x78c7555e +0, 14, 14, 1, 230400, 0x96e3562d +0, 15, 15, 1, 230400, 0xecc75867 +0, 16, 16, 1, 230400, 0x56e26feb +0, 17, 17, 1, 230400, 0xf65d6fac +0, 18, 18, 1, 230400, 0x5597709e +0, 19, 19, 1, 230400, 0xeb077c34 +0, 20, 20, 1, 230400, 0xce997afa +0, 21, 21, 1, 230400, 0xbec37abd +0, 22, 22, 1, 230400, 0xb01688c4 +0, 23, 23, 1, 230400, 0x0c828927 +0, 24, 24, 1, 230400, 0xa6308757 +0, 25, 25, 1, 230400, 0x90e68727 +0, 26, 26, 1, 230400, 0xe3258ae5 +0, 27, 27, 1, 230400, 0x988e8993 +0, 28, 28, 1, 230400, 0xc13688b0 +0, 29, 29, 1, 230400, 0xcc528fa1 +0, 30, 30, 1, 230400, 0x28c691a9 +0, 31, 31, 1, 230400, 0x7de96ae9 +0, 32, 32, 1, 230400, 0x47946fa5 +0, 33, 33, 1, 230400, 0x1c3efa7c +0, 34, 34, 1, 230400, 0x7fc6fc80 +0, 35, 35, 1, 230400, 0x0509c853 +0, 36, 36, 1, 230400, 0x691bca43 +0, 37, 37, 1, 230400, 0xadb5eafd +0, 38, 38, 1, 230400, 0x559feafa +0, 39, 39, 1, 230400, 0xa17906da +0, 40, 40, 1, 230400, 0x6091f838 +0, 41, 41, 1, 230400, 0x9640f6fa +0, 42, 42, 1, 230400, 0xa73af817 +0, 43, 43, 1, 230400, 0x255fde90 +0, 44, 44, 1, 230400, 0x7284deac +0, 45, 45, 1, 230400, 0xf603df3f +0, 46, 46, 1, 230400, 0x435cde3a +0, 47, 47, 1, 230400, 0x825add61 +0, 48, 48, 1, 230400, 0x13b6bc0e +0, 49, 49, 1, 230400, 0x72e7c13d +0, 50, 50, 1, 230400, 0x2bcdc061 +0, 51, 51, 1, 230400, 0xb2e7c189 +0, 52, 52, 1, 230400, 0xb4eabe46 +0, 53, 53, 1, 230400, 0x0108c777 +0, 54, 54, 1, 230400, 0xae5cc3b3 +0, 55, 55, 1, 230400, 0xdd8ec4da +0, 56, 56, 1, 230400, 0x0ec5c1d0 +0, 57, 57, 1, 230400, 0x3ad7cab8 +0, 58, 58, 1, 230400, 0xa9b0c95b +0, 59, 59, 1, 230400, 0xe98ec9a0 +0, 60, 60, 1, 230400, 0x07d9c42e +0, 61, 61, 1, 230400, 0x23b8c94e +0, 62, 62, 1, 230400, 0xd3a9d25d +0, 63, 63, 1, 230400, 0x3154cf78 +0, 64, 64, 1, 230400, 0x163ad234 +0, 65, 65, 1, 230400, 0x3ce2d276 +0, 66, 66, 1, 230400, 0x6f0bd556 +0, 67, 67, 1, 230400, 0xd982cb24 +0, 68, 68, 1, 230400, 0xd04ac7ab +0, 69, 69, 1, 230400, 0x5302d29a +0, 70, 70, 1, 230400, 0xd989d0dc diff --git a/tests/ref/fate/filter-paletteuse-sierra2_4a b/tests/ref/fate/filter-paletteuse-sierra2_4a index d257820a32..75115066e1 100644 --- a/tests/ref/fate/filter-paletteuse-sierra2_4a +++ b/tests/ref/fate/filter-paletteuse-sierra2_4a @@ -3,74 +3,74 @@ #codec_id 0: rawvideo #dimensions 0: 320x180 #sar 0: 1/1 -0, 0, 0, 1, 230400, 0xa4f85758 -0, 1, 1, 1, 230400, 0xbe83505c -0, 2, 2, 1, 230400, 0x0a09584e -0, 3, 3, 1, 230400, 0xd2065629 -0, 4, 4, 1, 230400, 0x11eb5319 -0, 5, 5, 1, 230400, 0x61024f4c -0, 6, 6, 1, 230400, 0xd5384faa -0, 7, 7, 1, 230400, 0xdeae0343 -0, 8, 8, 1, 230400, 0xcb640541 -0, 9, 9, 1, 230400, 0xea2602c3 -0, 10, 10, 1, 230400, 0xa7974293 -0, 11, 11, 1, 230400, 0x67cd4287 -0, 12, 12, 1, 230400, 0x83fa437a -0, 13, 13, 1, 230400, 0x852b42bf -0, 14, 14, 1, 230400, 0x6d2d434c -0, 15, 15, 1, 230400, 0x20c44629 -0, 16, 16, 1, 230400, 0xf2a35f57 -0, 17, 17, 1, 230400, 0x232959ec -0, 18, 18, 1, 230400, 0x1f8e5c48 -0, 19, 19, 1, 230400, 0x88dc69bd -0, 20, 20, 1, 230400, 0x4b6866f3 -0, 21, 21, 1, 230400, 0xe8f966dc -0, 22, 22, 1, 230400, 0xe0877466 -0, 23, 23, 1, 230400, 0x8799748c -0, 24, 24, 1, 230400, 0xcab871bc -0, 25, 25, 1, 230400, 0x2e0372b4 -0, 26, 26, 1, 230400, 0x15fb77d5 -0, 27, 27, 1, 230400, 0xbadf75fc -0, 28, 28, 1, 230400, 0xa4977626 -0, 29, 29, 1, 230400, 0x5b987943 -0, 30, 30, 1, 230400, 0x9ed57c09 -0, 31, 31, 1, 230400, 0x565d5105 -0, 32, 32, 1, 230400, 0x901b5a07 -0, 33, 33, 1, 230400, 0x8dc4e9a8 -0, 34, 34, 1, 230400, 0x0b9cee1c -0, 35, 35, 1, 230400, 0x2bcdbe37 -0, 36, 36, 1, 230400, 0xf3e2bf71 -0, 37, 37, 1, 230400, 0xb718da67 -0, 38, 38, 1, 230400, 0x8f59da64 -0, 39, 39, 1, 230400, 0x8812f9aa -0, 40, 40, 1, 230400, 0xe0dae6a3 -0, 41, 41, 1, 230400, 0xd2c7e5b7 -0, 42, 42, 1, 230400, 0xea2ae5d2 -0, 43, 43, 1, 230400, 0x2d66ca25 -0, 44, 44, 1, 230400, 0xf0d3cac6 -0, 45, 45, 1, 230400, 0xb9acccac -0, 46, 46, 1, 230400, 0x8523ca4a -0, 47, 47, 1, 230400, 0x92b9c9ef -0, 48, 48, 1, 230400, 0x0a88946e -0, 49, 49, 1, 230400, 0xe33699b8 -0, 50, 50, 1, 230400, 0x5e7b9917 -0, 51, 51, 1, 230400, 0xdac99998 -0, 52, 52, 1, 230400, 0xb5c995fc -0, 53, 53, 1, 230400, 0x908b9f50 -0, 54, 54, 1, 230400, 0x60d59ced -0, 55, 55, 1, 230400, 0x212e9f55 -0, 56, 56, 1, 230400, 0x95e69b2a -0, 57, 57, 1, 230400, 0x6c38a34a -0, 58, 58, 1, 230400, 0xeb32a103 -0, 59, 59, 1, 230400, 0x0131a1b7 -0, 60, 60, 1, 230400, 0xd59b9c4e -0, 61, 61, 1, 230400, 0x2fc0a13f -0, 62, 62, 1, 230400, 0x7a40adf9 -0, 63, 63, 1, 230400, 0x5cdbab2f -0, 64, 64, 1, 230400, 0xcdc0ada8 -0, 65, 65, 1, 230400, 0x2f5faf32 -0, 66, 66, 1, 230400, 0xd463b224 -0, 67, 67, 1, 230400, 0xe337a2d5 -0, 68, 68, 1, 230400, 0xe775a0c1 -0, 69, 69, 1, 230400, 0x726aab49 -0, 70, 70, 1, 230400, 0x74dda81e +0, 0, 0, 1, 230400, 0xa40645e7 +0, 1, 1, 1, 230400, 0x72b63e5e +0, 2, 2, 1, 230400, 0x030344b2 +0, 3, 3, 1, 230400, 0xab8c42b8 +0, 4, 4, 1, 230400, 0x1fcd3f00 +0, 5, 5, 1, 230400, 0x371f3c27 +0, 6, 6, 1, 230400, 0x0cfe3dff +0, 7, 7, 1, 230400, 0x0c64f102 +0, 8, 8, 1, 230400, 0xbca2f2f7 +0, 9, 9, 1, 230400, 0x5198f134 +0, 10, 10, 1, 230400, 0xee02305e +0, 11, 11, 1, 230400, 0x22592ff1 +0, 12, 12, 1, 230400, 0xa230311d +0, 13, 13, 1, 230400, 0x66453278 +0, 14, 14, 1, 230400, 0x68c63165 +0, 15, 15, 1, 230400, 0xded434ae +0, 16, 16, 1, 230400, 0xff1a4e51 +0, 17, 17, 1, 230400, 0x31064c7b +0, 18, 18, 1, 230400, 0x3d374e74 +0, 19, 19, 1, 230400, 0x58ec59d5 +0, 20, 20, 1, 230400, 0x8c02570f +0, 21, 21, 1, 230400, 0x5f6b56ac +0, 22, 22, 1, 230400, 0x781f6408 +0, 23, 23, 1, 230400, 0x1c0165d2 +0, 24, 24, 1, 230400, 0xc6e66311 +0, 25, 25, 1, 230400, 0x0375635d +0, 26, 26, 1, 230400, 0x00756822 +0, 27, 27, 1, 230400, 0xb4276753 +0, 28, 28, 1, 230400, 0x8b826638 +0, 29, 29, 1, 230400, 0x201066e2 +0, 30, 30, 1, 230400, 0x4acc6ab8 +0, 31, 31, 1, 230400, 0xa78741fe +0, 32, 32, 1, 230400, 0xfe85481e +0, 33, 33, 1, 230400, 0x7153dae0 +0, 34, 34, 1, 230400, 0x9b7ede62 +0, 35, 35, 1, 230400, 0x785cad21 +0, 36, 36, 1, 230400, 0x4c81ac20 +0, 37, 37, 1, 230400, 0x2e9cc57c +0, 38, 38, 1, 230400, 0x0043c629 +0, 39, 39, 1, 230400, 0xccb1e72d +0, 40, 40, 1, 230400, 0xf800d4d9 +0, 41, 41, 1, 230400, 0xb40ad374 +0, 42, 42, 1, 230400, 0xa94bd3eb +0, 43, 43, 1, 230400, 0xefa8b85f +0, 44, 44, 1, 230400, 0xa32ab85d +0, 45, 45, 1, 230400, 0xbb89b941 +0, 46, 46, 1, 230400, 0x6556b8f0 +0, 47, 47, 1, 230400, 0x3d5ab7ab +0, 48, 48, 1, 230400, 0x7b68afd9 +0, 49, 49, 1, 230400, 0x7518b560 +0, 50, 50, 1, 230400, 0x4d6bb43f +0, 51, 51, 1, 230400, 0xafe7b5a0 +0, 52, 52, 1, 230400, 0x5211b1c0 +0, 53, 53, 1, 230400, 0x4ababa33 +0, 54, 54, 1, 230400, 0x90f7b7fc +0, 55, 55, 1, 230400, 0x0b0dba13 +0, 56, 56, 1, 230400, 0xc9b6b5b4 +0, 57, 57, 1, 230400, 0xa1c5bfcd +0, 58, 58, 1, 230400, 0xde30bdaf +0, 59, 59, 1, 230400, 0x6ae5bc07 +0, 60, 60, 1, 230400, 0x9845b936 +0, 61, 61, 1, 230400, 0xcad4bf41 +0, 62, 62, 1, 230400, 0x90abca33 +0, 63, 63, 1, 230400, 0x2c12c614 +0, 64, 64, 1, 230400, 0x2d65c7ea +0, 65, 65, 1, 230400, 0x1949c8f3 +0, 66, 66, 1, 230400, 0xe5adcb22 +0, 67, 67, 1, 230400, 0xa87bc06c +0, 68, 68, 1, 230400, 0x4c43baeb +0, 69, 69, 1, 230400, 0xbf66c7f9 +0, 70, 70, 1, 230400, 0x9883c62d From patchwork Tue Dec 27 23:17:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39774 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761355pzb; Tue, 27 Dec 2022 15:19:36 -0800 (PST) X-Google-Smtp-Source: AMrXdXttQqIv1tPnd73fh7wnm2mIlDIw4qNk1I7UFqLNWDZGAsb42SlhHLedB8fNDMya0R9GmoWB X-Received: by 2002:a17:906:2349:b0:837:3ddb:7e97 with SMTP id m9-20020a170906234900b008373ddb7e97mr24705050eja.61.1672183176026; Tue, 27 Dec 2022 15:19:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183176; cv=none; d=google.com; s=arc-20160816; b=LXhshzZJl9CKGmPYOcb6I0s59sfGSPuz8FyK43mDyH4IL2J/cSykogLy/PU4GrQwM3 sHRJEXVs47PRL17Aic29EDqrm2A65f+33piaBCT4FRb1oA/ZKZkYf9itT1QKQsraocPJ 5ZQfP+HKDK3zmlW4gr04KdUiWOz7yFjbampB+PVnneadXn7IPitsP7NmhGX7LAqBw6gm JVXYe/20kxwEEcraiuN8RK+xej2a/HkQfkBReR3Pe0KcfBOJrkCDf5VyI5vqVhO7enib zWF21ue9zetzRzWzHvC0qya6+hBO4SMykeGK9/VKBPqGyKsapzIQH+6YPgO7JfscHrek GRwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=8KMfBIeGkJV+p5RzdmPFQu2ZnMaJjIeXFDSlrlThGBc=; b=MM5W2KCJO5mIFzPeS2XaBgv04EsCE2rMseoBFcIj/dbFwZ1KVc6huITot+MFoXfh9h bjsaRJ7pGgMBgfY4Byv0F65sC0zjEP0X47gxSxg1NGvyhjcOSj7+leWb1Hs7QFqyk9in 7fR4IE1Cvm6Dh1bWIXolL4gLRGFPTEcD9tRKAJRQ608OUM8J1V2SCQSsbtTvHFSvf1sb bsv0kZyLkIPtYaI51J6cVdR0+K60bay62S3ndt9/iaJg4RXIzrtzpwI+2aPD3gPDLrBp /2TwrQX+Swlyd/670TKKCVtiqoPzLyioby679IT3YjMngGu6F1ZvD+NNSaTdmaKB5jE0 //5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=qa2UT8cB; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id q17-20020a170906679100b007c4fcbfaf8esi9205211ejp.954.2022.12.27.15.19.35; Tue, 27 Dec 2022 15:19:36 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=qa2UT8cB; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C1CE368BD0F; Wed, 28 Dec 2022 01:18:36 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BA15468BCA6 for ; Wed, 28 Dec 2022 01:18:32 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8nwyPurxtq2m1JGNlCh68RfQlDs3V9MH54q6So7iq+Y=; b=qa2UT8cBYaX0E/OdOevP5onaFQKUh/NsV/2Nm5teGsh9AFIawC3rDTPwa8sjtphuzMfYLZ MUVoyJZ8pmCnkfoC0tPoWLeMsIEZCouYckgsUFcQWvagOOFoiyUesTXdQnSoXtvIUUnU6g f/rzLG96kOzaw7NxeVOdP94Ot95h+rY= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id c99eb23c; Tue, 27 Dec 2022 23:18:17 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:52 +0100 Message-Id: <20221227231814.2520181-11-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 10/32] avfilter/palettegen: move box stats computation to a dedicated function 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 5gj5+p30pUe4 --- libavfilter/vf_palettegen.c | 64 ++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index bea3292796..a047c75599 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -40,6 +40,8 @@ struct color_ref { /* Store a range of colors */ struct range_box { uint32_t color; // average color + int major_axis; // best axis candidate for cutting the box + uint64_t weight; // sum of all the weights of the colors int64_t variance; // overall variance of the box (how much the colors are spread) int start; // index in PaletteGenContext->refs int len; // number of referenced colors @@ -143,6 +145,35 @@ static av_always_inline int diff(const uint32_t a, const uint32_t b) return dr*dr + dg*dg + db*db; } +static void compute_box_stats(PaletteGenContext *s, struct range_box *box) +{ + int rr, gr, br; + + /* compute the box weight (sum all the weights of the colors in the + * range) and its boundings */ + uint8_t min[3] = {0xff, 0xff, 0xff}; + uint8_t max[3] = {0x00, 0x00, 0x00}; + box->weight = 0; + for (int i = box->start; i < box->start + box->len; i++) { + const struct color_ref *ref = s->refs[i]; + const uint32_t rgb = ref->color; + const uint8_t r = rgb >> 16 & 0xff, g = rgb >> 8 & 0xff, b = rgb & 0xff; + min[0] = FFMIN(r, min[0]), max[0] = FFMAX(r, max[0]); + min[1] = FFMIN(g, min[1]), max[1] = FFMAX(g, max[1]); + min[2] = FFMIN(b, min[2]), max[2] = FFMAX(b, max[2]); + box->weight += ref->count; + } + + /* define the axis to sort by according to the widest range of colors */ + rr = max[0] - min[0]; + gr = max[1] - min[1]; + br = max[2] - min[2]; + box->major_axis = 1; // pick green by default (the color the eye is the most sensitive to) + if (br >= rr && br >= gr) box->major_axis = 2; + if (rr >= gr && rr >= br) box->major_axis = 0; + if (gr >= rr && gr >= br) box->major_axis = 1; // prefer green again +} + /** * Find the next box to split: pick the one with the highest variance */ @@ -324,35 +355,16 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) s->nb_boxes = 1; while (box && box->len > 1) { - int i, rr, gr, br, longest; - uint64_t median, box_weight = 0; - - /* compute the box weight (sum all the weights of the colors in the - * range) and its boundings */ - uint8_t min[3] = {0xff, 0xff, 0xff}; - uint8_t max[3] = {0x00, 0x00, 0x00}; - for (i = box->start; i < box->start + box->len; i++) { - const struct color_ref *ref = s->refs[i]; - const uint32_t rgb = ref->color; - const uint8_t r = rgb >> 16 & 0xff, g = rgb >> 8 & 0xff, b = rgb & 0xff; - min[0] = FFMIN(r, min[0]), max[0] = FFMAX(r, max[0]); - min[1] = FFMIN(g, min[1]), max[1] = FFMAX(g, max[1]); - min[2] = FFMIN(b, min[2]), max[2] = FFMAX(b, max[2]); - box_weight += ref->count; - } + int i, longest; + uint64_t median, box_weight; - /* define the axis to sort by according to the widest range of colors */ - rr = max[0] - min[0]; - gr = max[1] - min[1]; - br = max[2] - min[2]; - longest = 1; // pick green by default (the color the eye is the most sensitive to) - if (br >= rr && br >= gr) longest = 2; - if (rr >= gr && rr >= br) longest = 0; - if (gr >= rr && gr >= br) longest = 1; // prefer green again + compute_box_stats(s, box); + longest = box->major_axis; + box_weight = box->weight; - ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" ranges:[%2x %2x %2x] sort by %c (already sorted:%c) ", + ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ", box_id, box->start, box->start + box->len - 1, box->len, box_weight, - rr, gr, br, "rgb"[longest], box->sorted_by == longest ? 'y':'n'); + "rgb"[longest], box->sorted_by == longest ? 'y':'n'); /* sort the range by its longest axis if it's not already sorted */ if (box->sorted_by != longest) { From patchwork Tue Dec 27 23:17:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39768 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761414pzb; Tue, 27 Dec 2022 15:19:44 -0800 (PST) X-Google-Smtp-Source: AMrXdXsyvFf9faoG2PSkWxY7tCSjn6V85zAkxnal4ua/elKL2K6b2F8zmRiUZJuCfFUivMJIK6GV X-Received: by 2002:a05:6402:3784:b0:46d:cead:4eab with SMTP id et4-20020a056402378400b0046dcead4eabmr20843482edb.6.1672183184054; Tue, 27 Dec 2022 15:19:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183184; cv=none; d=google.com; s=arc-20160816; b=rJa28a56IqJWMm7SplP6uad4XVvkckEdCl0ANtE8qBvRyZcGYM0T8oxxFHC6xY7rFI BkJOsLGHqPZOmZA3bmj0guRhgfrMWbsbCo59M40vCzblrLm5SUGdUP//ew6CPU0OLbIJ Nuv4me+e/FaWqXTj8n1I7zVoNv6FkVOdTG6TuxCnHh/M1khyxAsQXrm55SCWcuSZqiw6 BfOU0cO8pvqN905gDZyJ27FOs8CmAnjgGWANBP890BKJedBjVPgh6D6TrFvkxbyCHdxZ pB+GXJLkbojDlQ2aybxju2liC50RwZEFCiK6fkRwaryDFE4vX6jJ/1G4MvRYMWGdagQR EXeg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=APkXuceIschghsprzNmLI7y5/OhoQLYMcr6soI45q2g=; b=eYMnjJXuOZN+f6JergEDWrvQJZqYL2TANAYtp7vYtIxEjOj4gQQc6CSGHk4Vyl9QF7 0ilLCrfBMjx8AVGpivmHq01cHo5UB1hcxuTp8ym5Tr9tS25ZCpb3Wp9FGScFzR+SNljI eQEYyZ0ZCPXOVBuG7CTRGg5MWHb/c074LKmxvgqDPwIYAGLTLDd65RoOgG3rLGNT+yZb DaB1RnS4aipxGGwTMaXZ7GnFuyMGhuKhQxvI8gQksUT/umeyOtshGPkEx50BHx2npcqK K0W6V8Z9RQ9edmCS2AnpepeagkU5TWMmL2Ta0T1xnEIIafZXlqD1GqvGUAW+HGFTYql3 KVRQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=gOkAtnwn; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id r20-20020aa7c154000000b0048254d95382si9664870edp.342.2022.12.27.15.19.43; Tue, 27 Dec 2022 15:19:44 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=gOkAtnwn; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A360668BC75; Wed, 28 Dec 2022 01:18:37 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E17CF68BCAB for ; Wed, 28 Dec 2022 01:18:32 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cR82zIx+RektCK5Q2UTsk6Dg2g2Cnqw8Siad9rvETFY=; b=gOkAtnwnw1VO0UmTSkA070HgkfWJvxi+yY2wJ5WsLT3pjEvAMkb8tlIBBcpLMltYmm7yq4 lejerUCFmKy8rDy81BujGl/Y00pNLGpkpEyr616rLSkYqzmktZkFVHaGEUr0sLDIU1ymC/ 3ttPPVPJD60lkfZTccuvcGaaWCE4D/c= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 9a45f9ba; Tue, 27 Dec 2022 23:18:18 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:53 +0100 Message-Id: <20221227231814.2520181-12-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 11/32] avfilter/palettegen: define the best axis to cut using the squared error 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: X0Mf219C1oM/ This is following the results from personal research¹. ¹: https://github.com/ubitux/research/tree/main/color-quantization#results --- libavfilter/vf_palettegen.c | 42 ++++++++++++++++++------------ tests/ref/fate/filter-palettegen-1 | 2 +- tests/ref/fate/filter-palettegen-2 | 2 +- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index a047c75599..ed1448755c 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -147,31 +147,39 @@ static av_always_inline int diff(const uint32_t a, const uint32_t b) static void compute_box_stats(PaletteGenContext *s, struct range_box *box) { - int rr, gr, br; + int avg[3]; + int64_t er2[3] = {0}; - /* compute the box weight (sum all the weights of the colors in the - * range) and its boundings */ - uint8_t min[3] = {0xff, 0xff, 0xff}; - uint8_t max[3] = {0x00, 0x00, 0x00}; + /* Compute average color */ + uint64_t sr = 0, sg = 0, sb = 0; box->weight = 0; for (int i = box->start; i < box->start + box->len; i++) { const struct color_ref *ref = s->refs[i]; - const uint32_t rgb = ref->color; - const uint8_t r = rgb >> 16 & 0xff, g = rgb >> 8 & 0xff, b = rgb & 0xff; - min[0] = FFMIN(r, min[0]), max[0] = FFMAX(r, max[0]); - min[1] = FFMIN(g, min[1]), max[1] = FFMAX(g, max[1]); - min[2] = FFMIN(b, min[2]), max[2] = FFMAX(b, max[2]); + sr += (ref->color >> 16 & 0xff) * ref->count; + sg += (ref->color >> 8 & 0xff) * ref->count; + sb += (ref->color & 0xff) * ref->count; box->weight += ref->count; } + avg[0] = sr / box->weight; + avg[1] = sg / box->weight; + avg[2] = sb / box->weight; - /* define the axis to sort by according to the widest range of colors */ - rr = max[0] - min[0]; - gr = max[1] - min[1]; - br = max[2] - min[2]; + /* Compute squared error of each color channel */ + for (int i = box->start; i < box->start + box->len; i++) { + const struct color_ref *ref = s->refs[i]; + const int64_t dr = (int)(ref->color >> 16 & 0xff) - avg[0]; + const int64_t dg = (int)(ref->color >> 8 & 0xff) - avg[1]; + const int64_t db = (int)(ref->color & 0xff) - avg[2]; + er2[0] += dr * dr * ref->count; + er2[1] += dg * dg * ref->count; + er2[2] += db * db * ref->count; + } + + /* Define the best axis candidate for cutting the box */ box->major_axis = 1; // pick green by default (the color the eye is the most sensitive to) - if (br >= rr && br >= gr) box->major_axis = 2; - if (rr >= gr && rr >= br) box->major_axis = 0; - if (gr >= rr && gr >= br) box->major_axis = 1; // prefer green again + if (er2[2] >= er2[0] && er2[2] >= er2[1]) box->major_axis = 2; + if (er2[0] >= er2[1] && er2[0] >= er2[2]) box->major_axis = 0; + if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; // prefer green again } /** diff --git a/tests/ref/fate/filter-palettegen-1 b/tests/ref/fate/filter-palettegen-1 index bebfd24e19..278d831846 100644 --- a/tests/ref/fate/filter-palettegen-1 +++ b/tests/ref/fate/filter-palettegen-1 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 16x16 #sar 0: 1/1 -0, 0, 0, 1, 1024, 0x3395ef5a +0, 0, 0, 1, 1024, 0x394ee723 diff --git a/tests/ref/fate/filter-palettegen-2 b/tests/ref/fate/filter-palettegen-2 index 9abec0fe8e..e9bc635c81 100644 --- a/tests/ref/fate/filter-palettegen-2 +++ b/tests/ref/fate/filter-palettegen-2 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 16x16 #sar 0: 1/1 -0, 0, 0, 1, 1024, 0x23e072c8 +0, 0, 0, 1, 1024, 0xc54d773d From patchwork Tue Dec 27 23:17:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39776 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761482pzb; Tue, 27 Dec 2022 15:19:52 -0800 (PST) X-Google-Smtp-Source: AMrXdXvIKIsC+WM3RhCXBcP08Ws3zPqXGWR5sYMFcGMnpG8d8vwzSkmlYr+XXtMXhF+ddROYnISH X-Received: by 2002:a17:907:8c86:b0:7c1:1adc:46fd with SMTP id td6-20020a1709078c8600b007c11adc46fdmr20670211ejc.34.1672183192086; Tue, 27 Dec 2022 15:19:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183192; cv=none; d=google.com; s=arc-20160816; b=HL6T/d75JT47W2s9TSqpz6ZvlK5l/kuSP2nxmIqEIXMC9iTTL28OJnb9mXoFU8yimZ 0n8bwkaE9Gg3dAJWYebNE7KeU3pgkoJfTc63HKdNTAHNZurL/f+qzokeDRx+YlSQmU/k SiuS859YTtq99hukOO6J494haINb1XrOwFpOghZ/aH4qtr3AtWNAiSv5IfG5dGSoiaTF RHgXhG404ZduwPwdIxBnm3Mk9Hp1mSS/P5wAOEb6TybgPvibd9Aj8zdF/NHYmGEWFyLw TQ9Tyu0l4malehJLQLXxKVySVf4tLMainIsig3ANccMrAY9g0li8a0E6UYbyhyYTXC2P uvXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=VEbk1mCudzep47/eJR3N07s3IGoPCsLZKunv74FNZvo=; b=svLgXuWpHZpkOfbhs6+szHXNm3ylDaZfXP8yI3i/1IireG+9O26k4xbUSsRxudVC3p VQmSWixYIW56t7C37vgEl8hCGv/HxCmNpvMaME4UJub1N13NQaD4QMRoYNiC//GTPP7S czL7C302OP1uE33sG/fGflsdzlgt6cI9jdpug3XOrwHlXldWmvYkka+1/g+2Mi281CsW k6595mZ4YPYDUAYfeGrASHkOFEMkIJTmp/f/lmqMkv4zUmMKGQQ7F+g/Ck4/DLK4t4sD YuwkSt8YSADetxBdPFalTM1yT+6+zcM3VtTjq3vdfs1g900UISKbGlbG+4iB4AoDpmoC Dx7w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=LPh+G8HG; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id hb16-20020a170907161000b00839f873bf5asi11550181ejc.217.2022.12.27.15.19.51; Tue, 27 Dec 2022 15:19:52 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=LPh+G8HG; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 737E468BCE9; Wed, 28 Dec 2022 01:18:38 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2619B68BCAB for ; Wed, 28 Dec 2022 01:18:33 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=POT4QO3NFT7zwPFKrGNpvdtkmGnt/sBuLuMkraWmHDM=; b=LPh+G8HGLQGf07WS9dq7tTMhDZZatKtKhvcyrsAyA7NsZDpVuxgoXSAYu1nN2Bh5VMpuBK I6TCqKAklRqzjjVM5nz45dKZplwaUBz3o0gvqKjHJDPIWbrtxMYfk4bnCnsmAbbPB/QLbW YxdZBYS1ZwQXGvzoCrSFUsSg8LCmJMI= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 8ec0a9aa; Tue, 27 Dec 2022 23:18:18 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:54 +0100 Message-Id: <20221227231814.2520181-13-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 12/32] avfilter/palettegen: use box->major_axis without intermediate variable 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: tuyBvpqQ76GV --- libavfilter/vf_palettegen.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index ed1448755c..aa0c8fdc5b 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -363,22 +363,21 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) s->nb_boxes = 1; while (box && box->len > 1) { - int i, longest; + int i; uint64_t median, box_weight; compute_box_stats(s, box); - longest = box->major_axis; box_weight = box->weight; ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ", box_id, box->start, box->start + box->len - 1, box->len, box_weight, - "rgb"[longest], box->sorted_by == longest ? 'y':'n'); + "rgb"[box->major_axis], box->sorted_by == box->major_axis ? 'y':'n'); - /* sort the range by its longest axis if it's not already sorted */ - if (box->sorted_by != longest) { - cmp_func cmpf = cmp_funcs[longest]; + /* sort the range by its major axis if it's not already sorted */ + if (box->sorted_by != box->major_axis) { + cmp_func cmpf = cmp_funcs[box->major_axis]; AV_QSORT(&s->refs[box->start], box->len, const struct color_ref *, cmpf); - box->sorted_by = longest; + box->sorted_by = box->major_axis; } /* locate the median where to split */ From patchwork Tue Dec 27 23:17:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39777 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761556pzb; Tue, 27 Dec 2022 15:20:00 -0800 (PST) X-Google-Smtp-Source: AMrXdXvgqNkMtD1tlODendMgwByOIvrBPOAY9h4jvyAClLWDcGaqzza6+A8rSPE471PUASl7TAzT X-Received: by 2002:aa7:d448:0:b0:467:b851:6066 with SMTP id q8-20020aa7d448000000b00467b8516066mr26298523edr.6.1672183199489; Tue, 27 Dec 2022 15:19:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183199; cv=none; d=google.com; s=arc-20160816; b=ajLBeuoKU3T6Shf4OoULsHBi/U3MO7UG+bP91efqfvqhMqtubjqj/+OA6pI2+fihHj fTzsAEoDxGNP+1sQcPNV2hCXTMZHGsb1W8AOHmS4WXb6cab2HcZnTd5nT3ijz0uFj7ff H5D9qPEX13Z9FaTFKPJiWxQpN124Ukn1JkAqUWdYaI9wtYEhvDcSRFmCt6s051NqLkb1 XKaD5YtvQcrDG3ylcCgHBgf35d8yIAMBXapgOmK3fJAmv3Rad8dzqkUtpiyXHP10zGVY A1S+7XBWAYnn2qT9/jyKG7uniJ9eYOC6k73ATkuLtMPoNqMDeeFo3MCsd+a8365EuN3z 1VEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=YE8SZaTcSLPCpihJP8w7z/Uu4TtWETy+nYzXve0XJFE=; b=0pZC5EPSYi08JqybcLSL6cPHUgrV5Yk1xMgWhJkaJnTuhN0GKhxCMUM4zJ+qJcvkon Jk4BEhwlANAIr7f4CvrrnXswisidBDzIkBo5Xkj3FWneYHmmebME+Zc3II0xvSo3FaN4 i3Cf0QHthk04MXFJslomhLPhsI4HpRZHc9r7c6unjHBGbsTpJpKZlYl73iJgSHtIjJhf BCSj1X5RGiLIFGVuCZfMuYlzvH67URbEYyXEfBUJkSM0D9v2QscVlxiO0acItgNdb2t/ P93MV+4a4QISZ5aZ8DCFTVGAhAo79unnKIym3u4EX2wjBoUvwlGAYopkR3pSZ8E5NVKV Az5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=Jwad3Exm; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id sb25-20020a1709076d9900b007c4f78e6104si11805003ejc.408.2022.12.27.15.19.59; Tue, 27 Dec 2022 15:19:59 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=Jwad3Exm; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4509F68BCC1; Wed, 28 Dec 2022 01:18:39 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5716D68BCB9 for ; Wed, 28 Dec 2022 01:18:33 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aK7EU/6HgPSE+H00gmAjOInHxXg8YH0aBja11/B5Lp0=; b=Jwad3Exm1D3jnHcd54MrlDuLSa3BfGQ3TNpbyiB87bpARc+yyT/i+89C9bWNARc25Exa8+ t3JMlO0qoczA5Wlz5guBuwkxstupNb5/qirCikI9aj5esMc3ioYB2nl+UXVRdBdR99R4A1 jFqip57+3QaYv6lfZmXwFkA4WO9igEU= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id e8f4c611; Tue, 27 Dec 2022 23:18:18 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:55 +0100 Message-Id: <20221227231814.2520181-14-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 13/32] avfilter/palettegen: always compute the box variance 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: vfR7Kw5TV1Z6 The variance computation is simple enough now (since we can use the axis squared errors) that it doesn't need to have a complex lazy computation logic. --- libavfilter/vf_palettegen.c | 42 ++++++++----------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index aa0c8fdc5b..ca1e02444c 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -135,16 +135,6 @@ static int cmp_color(const void *a, const void *b) return FFDIFFSIGN(box1->color , box2->color); } -static av_always_inline int diff(const uint32_t a, const uint32_t b) -{ - const uint8_t c1[] = {a >> 16 & 0xff, a >> 8 & 0xff, a & 0xff}; - const uint8_t c2[] = {b >> 16 & 0xff, b >> 8 & 0xff, b & 0xff}; - const int dr = c1[0] - c2[0]; - const int dg = c1[1] - c2[1]; - const int db = c1[2] - c2[2]; - return dr*dr + dg*dg + db*db; -} - static void compute_box_stats(PaletteGenContext *s, struct range_box *box) { int avg[3]; @@ -180,6 +170,8 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) if (er2[2] >= er2[0] && er2[2] >= er2[1]) box->major_axis = 2; if (er2[0] >= er2[1] && er2[0] >= er2[2]) box->major_axis = 0; if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; // prefer green again + + box->variance = er2[0] + er2[1] + er2[2]; } /** @@ -187,7 +179,7 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) */ static int get_next_box_id_to_split(PaletteGenContext *s) { - int box_id, i, best_box_id = -1; + int box_id, best_box_id = -1; int64_t max_variance = -1; if (s->nb_boxes == s->max_colors - s->reserve_transparent) @@ -195,24 +187,9 @@ static int get_next_box_id_to_split(PaletteGenContext *s) for (box_id = 0; box_id < s->nb_boxes; box_id++) { struct range_box *box = &s->boxes[box_id]; - - if (s->boxes[box_id].len >= 2) { - - if (box->variance == -1) { - int64_t variance = 0; - - for (i = 0; i < box->len; i++) { - const struct color_ref *ref = s->refs[box->start + i]; - variance += diff(ref->color, box->color) * ref->count; - } - box->variance = variance; - } - if (box->variance > max_variance) { - best_box_id = box_id; - max_variance = box->variance; - } - } else { - box->variance = -1; + if (s->boxes[box_id].len >= 2 && box->variance > max_variance) { + best_box_id = box_id; + max_variance = box->variance; } } return best_box_id; @@ -261,8 +238,8 @@ static void split_box(PaletteGenContext *s, struct range_box *box, int n) box->color = get_avg_color(s->refs, box); new_box->color = get_avg_color(s->refs, new_box); - box->variance = -1; - new_box->variance = -1; + compute_box_stats(s, box); + compute_box_stats(s, new_box); } /** @@ -359,14 +336,13 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) box->len = s->nb_refs; box->sorted_by = -1; box->color = get_avg_color(s->refs, box); - box->variance = -1; + compute_box_stats(s, box); s->nb_boxes = 1; while (box && box->len > 1) { int i; uint64_t median, box_weight; - compute_box_stats(s, box); box_weight = box->weight; ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ", From patchwork Tue Dec 27 23:17:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39778 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761618pzb; Tue, 27 Dec 2022 15:20:07 -0800 (PST) X-Google-Smtp-Source: AMrXdXvFJaRxgWOMsAwfX5vIYLteJFzr3tD+vMW4lzEDo5mXSlWeI1hkaM6KST5ZAtwuXNnew5pP X-Received: by 2002:a05:6402:e83:b0:45c:a5f2:ffea with SMTP id h3-20020a0564020e8300b0045ca5f2ffeamr29443510eda.7.1672183207630; Tue, 27 Dec 2022 15:20:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183207; cv=none; d=google.com; s=arc-20160816; b=onSMUNmX3bOgQ7ntlae3QFQzwdMzCMLK9LI28jdrb+ncaXia4TFfy5ynVUtd6XZ1oG Li1MiTTiv/vte14UTnfsKwL+ZT3V3Ha+IxyvVOVydGnfhcvi48pMinGD7lD/yR184hbD xVJbJwGZB1ATa7IBY6aDvunibOAjJM9GM8CiJiYKW4mP6c268IRnxEAgPN5ie9dWvdxm XvhNGCtkTZzqZgPQntjez4qUWnA374/gTVfJilJD/uZBwjmDYDFJgjbNPFjJkHZgr77F Kp2njR2YtIzmnMeBX24aSriqgf5kRPRqul3p4wFUZ3FOH/0uG8YdtpCrmKlivCgFxLFV mvLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=fvYgTztcq/P5YvE0IHjbHRZdFNfhcvbwPL98Q+4mlHQ=; b=eiZEd2h3zZyoZmISiTFMSvk7Nq8tNdT/RDROYtbTGfuLU19I3TPuCxWfsHhz6PNivR 7YhjjRnUy1c5EUx/yaiDJsVf2tiHC9LU53mPmTJhnx5NZfgLm7C7EzSLfg7lhHZj3VWp VfbJKgP6QwyBGBRVAoGT9ALsiqDv+TLyDjr4TW8H7R+MXUozJTnuzC515OxdkTYWTd6u WedRNl+iMvF34tyvZcaZkOL+M+O9q240vya/1W5IGEfwDSiuj5ADUUzzhyQRs0oKzrR7 BAWRNbh6BnJG/BdiMTJbEvrKZIFC2In+yfKx9/TVDK8OUB1CvpZcXKix9hxS+t5CG2V2 OvjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=P7BzlXT6; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id q17-20020a056402519100b00462848f0cdbsi13717772edd.299.2022.12.27.15.20.07; Tue, 27 Dec 2022 15:20:07 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=P7BzlXT6; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1A52868BD23; Wed, 28 Dec 2022 01:18:40 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7EC5168BCAB for ; Wed, 28 Dec 2022 01:18:33 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Om0KPh4Ov3l3YG/fnc7SkoXe9javK+0NuCRnIW31IZ0=; b=P7BzlXT63pFvXeN2qyIgqj2llvjIJF/1X9aaSiGDYtnUpGDVzqrUSj9l8cQ4SVsV0wCKIJ bT4/Q1XqIfxvGiBfXViWSHCtEWLAZNu8OT+zcM11Z9qJ333EzvSDdGbc04N7B1TJ9jPhtg LQUdc7UyCHqoq1EDKMfPhk+Ff9MPwaY= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id e90a3119; Tue, 27 Dec 2022 23:18:18 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:56 +0100 Message-Id: <20221227231814.2520181-15-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 14/32] avfilter/palettegen: rename variance to cut_score 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: EYLXL8C34z8X "Variance" wasn't exactly the correct word; "cut score" is more agnostic, which will be useful when changing the algorithm in the next commit. --- libavfilter/vf_palettegen.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index ca1e02444c..7ecb1211ba 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -42,7 +42,7 @@ struct range_box { uint32_t color; // average color int major_axis; // best axis candidate for cutting the box uint64_t weight; // sum of all the weights of the colors - int64_t variance; // overall variance of the box (how much the colors are spread) + int64_t cut_score; // how likely the box is to be cut down (higher implying more likely) int start; // index in PaletteGenContext->refs int len; // number of referenced colors int sorted_by; // whether range of colors is sorted by red (0), green (1) or blue (2) @@ -171,25 +171,25 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) if (er2[0] >= er2[1] && er2[0] >= er2[2]) box->major_axis = 0; if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; // prefer green again - box->variance = er2[0] + er2[1] + er2[2]; + box->cut_score = er2[0] + er2[1] + er2[2]; } /** - * Find the next box to split: pick the one with the highest variance + * Find the next box to split: pick the one with the highest cut score */ static int get_next_box_id_to_split(PaletteGenContext *s) { int box_id, best_box_id = -1; - int64_t max_variance = -1; + int64_t max_score = -1; if (s->nb_boxes == s->max_colors - s->reserve_transparent) return -1; for (box_id = 0; box_id < s->nb_boxes; box_id++) { struct range_box *box = &s->boxes[box_id]; - if (s->boxes[box_id].len >= 2 && box->variance > max_variance) { + if (s->boxes[box_id].len >= 2 && box->cut_score > max_score) { best_box_id = box_id; - max_variance = box->variance; + max_score = box->cut_score; } } return best_box_id; From patchwork Tue Dec 27 23:17:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39779 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761671pzb; Tue, 27 Dec 2022 15:20:15 -0800 (PST) X-Google-Smtp-Source: AMrXdXtmoGe3MNCLHmYzFWf5GUPyId2+efr9b8RxsR5DIoXVeVVA1LyaO36BakHCio9j9BNH1BHA X-Received: by 2002:a17:906:8447:b0:7c8:9f04:ae7e with SMTP id e7-20020a170906844700b007c89f04ae7emr21246025ejy.22.1672183215210; Tue, 27 Dec 2022 15:20:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183215; cv=none; d=google.com; s=arc-20160816; b=upJxaGW+FEySFjQ7C3Ryi/rN13Cffp+jOpPleVEOv+NWa7UgsX5GxOsCWiJzSxIpFo 2RCHRVqjuM3I0qTokNBk1diZBuWlyhS26jlJ4Nd5kzXMZOhE/usyh9O2UP4ctEHy6caq Q6D2nuBBzpKaeYM3hvkkzt7b1/GD6hm4QyEokjSR2Vczh6FUTBkrh2SGwMt4IJwsf80j RDKUDcezsWU8RRyef1i397BTGt+OpHVH+AaR1tkjOsOkU6mdFRaCP1QRlA7crVvSTN0h y9+FpHnagoTxq71KPkqGJ6ede+xawC8Ad+85CTxFJ73KlCR1Hl/D9fn6WDnKhaHFwQAA tSDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=23IQNqQDYAxFydKYDLQI8i4Nq4wVQbTm6Hc+OkRlb24=; b=ofl0t4VAnx4v8IWI175lrfuyQfgTKU/88/NoXudBItenRhUshGnMB44lQye7u0fagt i4ndOlG/9VzDS7Qg9Vqtif1cph8r4R96tDJ9Dca9qA9azC9MLWh5z0H0+GEzvD24Q7J4 lauTjiFdlxiCqVCrYOt5zQjsmtMEyfp/iije9uvg2NeIpbShbG+8CpfCf3re8S/4gbPV 8oCTuXlW3PSBAHKZWA6jxZL0QudfV9BetuucBGfw/Kbk1b5PPTPwkiZCboyYgDIIweog tKaX3Ugwxj6CQeQKriqZBm2+LWhdUNo4LqpSTTEQaw1kqv+/1CN6u0YKxcZWJ0qJPaqw 0pdQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=Fu1juKhW; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id xa8-20020a170906fd8800b007c1fa1e907csi11951520ejb.992.2022.12.27.15.20.14; Tue, 27 Dec 2022 15:20:15 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=Fu1juKhW; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CE70568BD26; Wed, 28 Dec 2022 01:18:40 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A625468BCAE for ; Wed, 28 Dec 2022 01:18:33 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ED6TFr6VSQnIOD3d1aLtzbT4foGYfrfvVw4J0CsGYyE=; b=Fu1juKhWXcARJA+D1JxZOKQvjdXef0LwVslI793Mr7jyss+gyw2mjEIQ/RJGtFdB3/Jyn4 G+QmbMAJVUf59RbnV9LQGum2Bg154yErUpsAkHp16wUoJJv7TenJnDnW+h63ev3tCye5Yk z+1RGCQaFMrvCro9UNUtK6ecob89YFE= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id ec643d7b; Tue, 27 Dec 2022 23:18:18 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:57 +0100 Message-Id: <20221227231814.2520181-16-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] =?utf-8?q?=5BPATCH_v2_15/32=5D_avfilter/palettegen?= =?utf-8?q?=3A_change_cut_score_from_=E2=88=91e=C2=B2_to_max_e=C2=B2?= 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 0NzkbwyyUOTr This is following the results from personal research¹. ¹: https://github.com/ubitux/research/tree/main/color-quantization#results --- libavfilter/vf_palettegen.c | 3 ++- tests/ref/fate/filter-palettegen-1 | 2 +- tests/ref/fate/filter-palettegen-2 | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 7ecb1211ba..00b5f88c49 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -171,7 +171,8 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) if (er2[0] >= er2[1] && er2[0] >= er2[2]) box->major_axis = 0; if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; // prefer green again - box->cut_score = er2[0] + er2[1] + er2[2]; + /* The box that has the axis with the biggest error amongst all boxes will but cut down */ + box->cut_score = FFMAX3(er2[0], er2[1], er2[2]); } /** diff --git a/tests/ref/fate/filter-palettegen-1 b/tests/ref/fate/filter-palettegen-1 index 278d831846..57be338b42 100644 --- a/tests/ref/fate/filter-palettegen-1 +++ b/tests/ref/fate/filter-palettegen-1 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 16x16 #sar 0: 1/1 -0, 0, 0, 1, 1024, 0x394ee723 +0, 0, 0, 1, 1024, 0x21c6e6c4 diff --git a/tests/ref/fate/filter-palettegen-2 b/tests/ref/fate/filter-palettegen-2 index e9bc635c81..bcdf54af95 100644 --- a/tests/ref/fate/filter-palettegen-2 +++ b/tests/ref/fate/filter-palettegen-2 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 16x16 #sar 0: 1/1 -0, 0, 0, 1, 1024, 0xc54d773d +0, 0, 0, 1, 1024, 0x630d76b1 From patchwork Tue Dec 27 23:17:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39780 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761732pzb; Tue, 27 Dec 2022 15:20:23 -0800 (PST) X-Google-Smtp-Source: AMrXdXsQex9SaHRVc6EmxzhZsNAzZfEts5D8cLYpMuD/ONxm7I6Ka6+kMst50wXCZplTA1MFwJbA X-Received: by 2002:a17:906:374e:b0:7c1:f64:61f1 with SMTP id e14-20020a170906374e00b007c10f6461f1mr24223830ejc.45.1672183223345; Tue, 27 Dec 2022 15:20:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183223; cv=none; d=google.com; s=arc-20160816; b=Hexnpq4btEbANTIZlhzcnQqoPUCK8cGrJ6sSW/ZYUmYbS8GGXD8MFB3InlyYPBtRaV UgKHDdZ/gZU7pqexMValVc18XlTKeUJiTGOUJyDEkvHZq+ki1f9A9dOcCkuiNkFTWsHG hpleOz6zXS1rhUH+BlOPAx9d3s7bUdwonhTFKR5v47scSahKv2ajWnjWrYAH896Fk89/ GzZ9G+nPjVc/O/Gn9jU8iGAVvU3Ar9/oIv0ltta9c/eF+xVvjpAP4iDscedrHWI+PUud AOIujYgCTHi6GDzejrNjUu88WOzXQ+I5iVhtZmq3cJEeoQQPIapxDoZCXsXg1jmEkhLB WUDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=m/PaDYYi+W9HX6WvGWCh7YcOmyWqSBEB9yfLkT5UMz4=; b=tstygglx9jLUkTcd/mf/ruayfz0nEnX4+nNtKL/wj6XuClpia1lbmgMCH8nAUM8g1i an30RDgD7Yxyd5yVa5a4nX6FvR1r1s4vDc894I3VtgtqT+mXs9noGZWJ1UBLOT2h1FP7 8DklI2z8tiUeC4tB8RhG8+kRmkORbEjsMyPI5wkBM68leTFxvxXfktC73FVN86ovkYEB RqoCtbWVdQ2sELacetP0iqw37to3N1yM3kk7l/rzRZ5sb8oB3JDAgIOSoppsDOcTJP+H uKndPAcWgxOmZ+Jns9g6aC5EwK0/FUk0YApyGd3f3Kl8OQuV9UXkCMzhascwxYoiXYpm Mkxw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=hWFtBdOj; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id ji20-20020a170907981400b007adfe2889efsi12276044ejc.607.2022.12.27.15.20.23; Tue, 27 Dec 2022 15:20:23 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=hWFtBdOj; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9A4BD68BCDA; Wed, 28 Dec 2022 01:18:41 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CD69568BCBE for ; Wed, 28 Dec 2022 01:18:33 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=C9dR0R/CH1U22B4W3i+Me/usr2Lt/Vp9sPq3ldzy8Og=; b=hWFtBdOjzAKuQUizD+5fylY0qRPSIFZB0bUTdL7epJJBo7c4s5Bcy0xRuFtdMF7zMLTWrB n93Gb58nQYx6dMtAPy3KbLY74V5Jki6oHa8PFZyiZoxW3kfNfBkT9mErTEZ7fLxfCUnkmb uf0LKXL9w9QT7/Hg+ZhNLU0/I8mbc/w= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 37f47f9a; Tue, 27 Dec 2022 23:18:18 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:58 +0100 Message-Id: <20221227231814.2520181-17-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 16/32] avfilter/palettegen: compute average color within compute_box_stats() 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 3ydRnv7nHMLH --- libavfilter/vf_palettegen.c | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 00b5f88c49..36f0a976d9 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -153,6 +153,7 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) avg[0] = sr / box->weight; avg[1] = sg / box->weight; avg[2] = sb / box->weight; + box->color = 0xffU<<24 | avg[0]<<16 | avg[1]<<8 | avg[2]; /* Compute squared error of each color channel */ for (int i = box->start; i < box->start + box->len; i++) { @@ -196,32 +197,6 @@ static int get_next_box_id_to_split(PaletteGenContext *s) return best_box_id; } -/** - * Get the 32-bit average color for the range of RGB colors enclosed in the - * specified box. Takes into account the weight of each color. - */ -static uint32_t get_avg_color(struct color_ref * const *refs, - const struct range_box *box) -{ - int i; - const int n = box->len; - uint64_t r = 0, g = 0, b = 0, div = 0; - - for (i = 0; i < n; i++) { - const struct color_ref *ref = refs[box->start + i]; - r += (ref->color >> 16 & 0xff) * ref->count; - g += (ref->color >> 8 & 0xff) * ref->count; - b += (ref->color & 0xff) * ref->count; - div += ref->count; - } - - r = r / div; - g = g / div; - b = b / div; - - return 0xffU<<24 | r<<16 | g<<8 | b; -} - /** * Split given box in two at position n. The original box becomes the left part * of the split, and the new index box is the right part. @@ -237,8 +212,6 @@ static void split_box(PaletteGenContext *s, struct range_box *box, int n) av_assert0(box->len >= 1); av_assert0(new_box->len >= 1); - box->color = get_avg_color(s->refs, box); - new_box->color = get_avg_color(s->refs, new_box); compute_box_stats(s, box); compute_box_stats(s, new_box); } @@ -336,7 +309,6 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) box = &s->boxes[box_id]; box->len = s->nb_refs; box->sorted_by = -1; - box->color = get_avg_color(s->refs, box); compute_box_stats(s, box); s->nb_boxes = 1; From patchwork Tue Dec 27 23:17:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39781 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761809pzb; Tue, 27 Dec 2022 15:20:33 -0800 (PST) X-Google-Smtp-Source: AMrXdXvRXpuTCxrPyUad4vI6YKSQ1+tOm8ruzijAMFBx4lAKYdAQUki3c3O85ZN7eUmdwIHHsJMG X-Received: by 2002:a17:906:27d4:b0:7c1:337e:575b with SMTP id k20-20020a17090627d400b007c1337e575bmr19274548ejc.66.1672183233521; Tue, 27 Dec 2022 15:20:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183233; cv=none; d=google.com; s=arc-20160816; b=RrBGqVzSjTFuscFw+OYAA0Y4LpouIaTS3Q8Uh7LG+AE5lbSLI3S8in8m3KJ3bDpGzp 5Y1V6sw73Oo4yt3HVQIB+NTDDeMwRRBu8Dh82L8/eFZP00hcus/KArTyFM3D7r9l0iiO 7JBG0HWwu49Roj7fhr1ncIegCVGo+1WDgQ2GMLUUopbUzBW7Gb9Cmy1IdOUF5YlNgcca jP3bmuBgfQjMaRMzkYmdUg7EoADTaz4fKql1dwPerh9K9bSHkZF827psWMv42iHCvKmV +jm+kErf2dmpjMwObDqUrMwecZ+ECi6QKruYBNuEl1q2XQ5+fYPUGxgjMUo72voGIQMY PlpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=y+UTD+0TcGJJbSldLfvFPG34Bm7nn57FaNOihp3PNNI=; b=QKkgWK3bH9qHAnfpITqSOMnVFLyw3uYNXL30/H4A73fhVriDZb/lKHKv3Lv3LM4ehB fnD8yoFH1ak+Xts49+5O1z5pB8AqJT0798NsoIcIdPtzZ2HfsLtncVWgWwqkBK0yoJlt KEB9Xi4PpV145y93JT6i3BElNh37ln0cr91w5aCvxhyX2WgUefWcejfTzSYUiIw/6paq q5yogIOvHJSFwxpV9cn9gFUxZ2bBSZaM78+rI/13hjymf8SNf/7XrVRxosJmEb3gVppH N/pjzrjrVUVmhkvFHB2xsCBELl0WiA07CvXVlM0S1QJkB6+rNhHKKXLh3Vox5Uq32UWg yyAw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=cbqccFOl; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id t13-20020a170906178d00b007c16fb7f178si9587872eje.962.2022.12.27.15.20.31; Tue, 27 Dec 2022 15:20:33 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=cbqccFOl; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6844D68BCED; Wed, 28 Dec 2022 01:18:42 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 023B468BCAE for ; Wed, 28 Dec 2022 01:18:33 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uR/wyUp3SI+vW5fHSm2ada1US7CyTXxxgZfuXSxataI=; b=cbqccFOlHcuFssEaWJ3UT1210ysWQmadkiLZguoyDNCbn5JgFZObPbL5SA1MBwfhMnrfa/ qC3/+Q6eDdwr6EOM/1lJ+lqp3Cz/H9ov1arA/1C/XoN22ww6C7Qn3gsuFxe5IwPTTmKVAR WjutYWVzpNtBioPMf3fORdrlTd+2b/E= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id c9e45249; Tue, 27 Dec 2022 23:18:18 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:17:59 +0100 Message-Id: <20221227231814.2520181-18-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 17/32] avfilter/palettegen: misc cosmetics 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: gMIMEMYxbhCO --- libavfilter/vf_palettegen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 36f0a976d9..ad21882df3 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -132,7 +132,7 @@ static int cmp_color(const void *a, const void *b) { const struct range_box *box1 = a; const struct range_box *box2 = b; - return FFDIFFSIGN(box1->color , box2->color); + return FFDIFFSIGN(box1->color, box2->color); } static void compute_box_stats(PaletteGenContext *s, struct range_box *box) @@ -188,7 +188,7 @@ static int get_next_box_id_to_split(PaletteGenContext *s) return -1; for (box_id = 0; box_id < s->nb_boxes; box_id++) { - struct range_box *box = &s->boxes[box_id]; + const struct range_box *box = &s->boxes[box_id]; if (s->boxes[box_id].len >= 2 && box->cut_score > max_score) { best_box_id = box_id; max_score = box->cut_score; From patchwork Tue Dec 27 23:18:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39782 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761868pzb; Tue, 27 Dec 2022 15:20:40 -0800 (PST) X-Google-Smtp-Source: AMrXdXvXgRR9RsPVeRrF0CIM2gX2ik3ixQfv74PoMYQHBUYtfkdsrnBL6A42OdVVup4dJYhEsZxo X-Received: by 2002:a17:907:6d98:b0:7c1:12b0:7d5d with SMTP id sb24-20020a1709076d9800b007c112b07d5dmr25281813ejc.4.1672183240224; Tue, 27 Dec 2022 15:20:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183240; cv=none; d=google.com; s=arc-20160816; b=w9QqktazohZ6e4kob3CImvYS8f8ZAGgi40MAygiRwtj3dPyk/xv0iJeeDvbUU7sPBt J0X30/6TdxGa7qms/V8wx5UxcD+hKPtpzAY/0hVcxieg5GaclxdzKf5ow9Y5IkpshkGy VVUca2DC6CFsEsUJNDRwi4l0HOnFPXWcf/Sb6J9PUK5iGHQpObxNe8+WSjIpTrxP6jGE 1De62XxIfiFd3Bu1puS0E+RNMmbZkobndUEWndP+WWSAbv2oJzptCnn8GvFnVuWfW87v 2KcFEvpSMHK6YwDXYaTB2CcxKCgI7dB9SYOJKcO4gMqFe8kf+mG4eK/GVcoAFEwydh8u 6p+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=zoT5J2CY/PTMbhSD38h4W8dOl/3scdqi7Be48tRNJRY=; b=AQMng3BoFp/70jSD2Je6hTx/l3b6W5MY3o04XWjqxl7aAvX/lTmJ8c9cLY/KyV9/EC EX/m0hE5n4OytlgGrRfnIOwTZ7U4Zdjl5l6VVROPNNuTRQ8aFBSCraCtuEvh44N1tUfn jL+e5V5VeVtFtuEq/3P11TcS6GiBj/zpOx8pI/m3TFLZyTFC6Y0w/JKiNtUsv31kgO76 gLEFrobHFaYC+7txqmdka6ZEMiZx+UjXMxcq+Fxf08Daz+3b7a8u3em8XzJA4hannnWB q4fpUb6W/1SaiiRLo6Gq9/2u+CjvZL2Uk+mHqzyEcWilxUSHqMvwGhSNojtkuVcgyaP/ Qm6g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=RRLCbMor; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id l2-20020a170906a40200b0082ad5e78975si9694589ejz.803.2022.12.27.15.20.39; Tue, 27 Dec 2022 15:20:40 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=RRLCbMor; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 47AA368BCAB; Wed, 28 Dec 2022 01:18:43 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4312768BCC5 for ; Wed, 28 Dec 2022 01:18:34 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sXTFNx5WIocPLQUmoJvSZZ9xDxtR9zcSHc8EyBbqWY0=; b=RRLCbMorVMHI9FwktF4cloiej4/ct5uV0nlnMWH/FEnGkwgKNU8VYcxTRzscsHoz0+lIM4 EAdSYjd51c/5YXwbkuCb41FB12PFA5lEIR5WSHkfcFWbXic2jl4GnuCE0f6tkyfKkuLjMw CYpmkXwA1JFT9iy2FZuBAicNb1fFwWI= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 206d4a69; Tue, 27 Dec 2022 23:18:19 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:00 +0100 Message-Id: <20221227231814.2520181-19-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 18/32] avfilter/palettegen: rename local variable box_weight to weight 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: NOmun1Eqv3gQ This variable is used only for the running weight (used to reach the target median). The places where we actually need the box weight are changed to use box->weight. --- libavfilter/vf_palettegen.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index ad21882df3..b8db234fef 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -314,12 +314,10 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) while (box && box->len > 1) { int i; - uint64_t median, box_weight; - - box_weight = box->weight; + uint64_t median, weight; ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ", - box_id, box->start, box->start + box->len - 1, box->len, box_weight, + box_id, box->start, box->start + box->len - 1, box->len, box->weight, "rgb"[box->major_axis], box->sorted_by == box->major_axis ? 'y':'n'); /* sort the range by its major axis if it's not already sorted */ @@ -330,16 +328,16 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) } /* locate the median where to split */ - median = (box_weight + 1) >> 1; - box_weight = 0; + median = (box->weight + 1) >> 1; + weight = 0; /* if you have 2 boxes, the maximum is actually #0: you must have at * least 1 color on each side of the split, hence the -2 */ for (i = box->start; i < box->start + box->len - 2; i++) { - box_weight += s->refs[i]->count; - if (box_weight > median) + weight += s->refs[i]->count; + if (weight > median) break; } - ff_dlog(ctx, "split @ i=%-6d with w=%-6"PRIu64" (target=%6"PRIu64")\n", i, box_weight, median); + ff_dlog(ctx, "split @ i=%-6d with w=%-6"PRIu64" (target=%6"PRIu64")\n", i, weight, median); split_box(s, box, i); box_id = get_next_box_id_to_split(s); From patchwork Tue Dec 27 23:18:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39767 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3761939pzb; Tue, 27 Dec 2022 15:20:49 -0800 (PST) X-Google-Smtp-Source: AMrXdXviI8StwO99HR8qsPyCavlVeE3sSlf4/bv/1jB52EBWzcZT9DVH7hZqbJgnPX7/v8d28YSV X-Received: by 2002:a17:907:a708:b0:82e:a59a:5c3e with SMTP id vw8-20020a170907a70800b0082ea59a5c3emr27893126ejc.10.1672183248617; Tue, 27 Dec 2022 15:20:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183248; cv=none; d=google.com; s=arc-20160816; b=vl9rbL8G58tTFUEE0fhWSDGwMWBJnYNBKfTM5mZol2W1SBudOiV0JmeQttb7EOznPu XSn2rqfNHGGMiESySQPQJA6geY2kHNcvy5cAh7rbbOZAfdf09J5fclpTLrDwd75BxhBV GqzfvFH/d0sylz23iEiSU+hhDxEiD4l4TrAvVv60fgYi4HEjX12mP2ChpZIeBshDYEDl eWkuWqP4oBVJ0resSB0rHYtUTUOiKKUWniLgYBf6KajOCsjYR+cQ+Yj8slYaUhY/6Zlg KGLKTBeROAJQobQ95d312wG7OVVoCoTe8l1j/apdHCKhg42wx+Io9yjcn3x8gil0HbG3 f3Bw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=KHv1Dsw01L1q8Etp9hcKSvKL+wIIG1HsGT3POgAIHxw=; b=cNeaA7R0v2QG1jcLCobll4E2x3A7mHrHtABmw2LCOLKFt7K3xHsYTppCr2G1jF7kxk RoZDSmdAOIsvqChCuH/QiT5tcl2JIF1EILObNxW/pW2zz1Arejmqpj3zu8p6gLPQDGu8 Q+MGlYmvCE624C6/DCD0XREjhEE3lAqBj7vLvM3kyIOYI19DlhN4jQveMaU7PzSfO/SQ +MX2qn5EIxCj0DruIiVxge/Qhydb6ZBKpD/ooQWLIaqrmJojbixx72qRTmMreKIVZRuv iaR0KArpleCVaPGizbz0Q31O4F3t1U5MZzHI4mSkiPKjHtqJPC3UNbxamFmFd3QC6wsC w//g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=T7iiQuGP; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id ne34-20020a1709077ba200b007c12fc0bd81si10900127ejc.362.2022.12.27.15.20.48; Tue, 27 Dec 2022 15:20:48 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=T7iiQuGP; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 43B2968BD38; Wed, 28 Dec 2022 01:18:44 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6A37A68BCAF for ; Wed, 28 Dec 2022 01:18:34 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wQ2XHgYCfowomGLd0GpmUXYVv+XX1Db/W0EOpR9BRW0=; b=T7iiQuGPpT86oOCtvH6pVPk9VqWDZSkCvYcB2+qVbINJm7b0zLEv7DAF6gUIiTwl1mcbt4 WBtOhZbOI6avR/ZsKLyUZmW3AejDCEy1A6az/rJffB/UuLbdCSo0DijSBeutMun+oXH9jo OT4yKbIololA9pThw36ragZQbvraBvs= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id e35ab9aa; Tue, 27 Dec 2022 23:18:19 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:01 +0100 Message-Id: <20221227231814.2520181-20-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 19/32] avfilter/palettegen: switch to signed arithmetic 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: Cu7uE+i2A3M4 This prevents mixed sign arithmetic (typically because we have signed color channel differences), which has nasty side effects in C. --- libavfilter/vf_palettegen.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index b8db234fef..99e4512e52 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -34,14 +34,14 @@ /* Reference a color and how much it's used */ struct color_ref { uint32_t color; - uint64_t count; + int64_t count; }; /* Store a range of colors */ struct range_box { uint32_t color; // average color int major_axis; // best axis candidate for cutting the box - uint64_t weight; // sum of all the weights of the colors + int64_t weight; // sum of all the weights of the colors int64_t cut_score; // how likely the box is to be cut down (higher implying more likely) int start; // index in PaletteGenContext->refs int len; // number of referenced colors @@ -141,7 +141,7 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) int64_t er2[3] = {0}; /* Compute average color */ - uint64_t sr = 0, sg = 0, sb = 0; + int64_t sr = 0, sg = 0, sb = 0; box->weight = 0; for (int i = box->start; i < box->start + box->len; i++) { const struct color_ref *ref = s->refs[i]; @@ -314,7 +314,7 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) while (box && box->len > 1) { int i; - uint64_t median, weight; + int64_t median, weight; ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ", box_id, box->start, box->start + box->len - 1, box->len, box->weight, From patchwork Tue Dec 27 23:18:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39783 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762011pzb; Tue, 27 Dec 2022 15:20:57 -0800 (PST) X-Google-Smtp-Source: AMrXdXvlmuHR2lbDdXElbrtbgQPAQRGEkGPSLlLIK9QPfmgD2ijO+l4L1X3QxmGXNCu6oQNeVdop X-Received: by 2002:a05:6402:f21:b0:482:8495:f919 with SMTP id i33-20020a0564020f2100b004828495f919mr14015110eda.27.1672183257323; Tue, 27 Dec 2022 15:20:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183257; cv=none; d=google.com; s=arc-20160816; b=vGqnwfqA6Pm3aAfk0PqTmbawD7XBY+hhPrFqbkTRXEatiIiUla6iQp5vp5gwn+0lY5 rAg/7hEJ36t8DHEFvROxPCFrnhp/ZNUROinP5zBOEqBgZoNy13FTM88D5sk9PSCITI+2 RlTh43jr8svn27ENIyBk2quXY6/OJjtU69FoQzImaA0evpE+jP7uzsjCNsOXpltJhicy MmtW1MMBCXb3PpIrlIeSejlbQVIQZEvOaiVtjJ95SoftuSjo79YssKKab/BAnxLG2lBW uxBg5wm540uiPP6olymO5gBRc9oCYZ21DsLBTRQWRrtyVWTgBepMOl6u9nbWpNFPcRyx a2Dg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=az9Pg9KcHhASkfVQkaSayEWusAP/ubWXcopSDbXEOHo=; b=0FrOClIDaruhAMlA57qT1tf4VQm2x/zJYeS6VZnIu7lh14zwhgKgCoQ5ooG3WoKvcD xAbK6qXbki7ORAiuBkac9+KiR94XkF3tdN+UZkGQV1wAqul3zLM1bm9DbWOjeUzPKfJP EVUsS9FIMrRbXw6yC//OtzOPtmcB9Ep/KE5vNkJVjYzeakhF5kMAAvGgAZIPnLtw1jek jA6j63DpO3F7JnCX8BqB46rjwRvyS91pKqpDXDO0CoOmgrYSBAOjT1SSBl2QJa9VZQy/ oOrjrAdUf4qUrEWX6AwQOHvSTWYFSHKA+Zm+Cbk2PFQPrjFs8AaNXKAT0b58OyJZUuEt myBg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b="cd6m8/MC"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id l18-20020a056402029200b0046af5c0f32asi10868802edv.37.2022.12.27.15.20.57; Tue, 27 Dec 2022 15:20:57 -0800 (PST) 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=@pkh.me header.s=selector1 header.b="cd6m8/MC"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2DE9B68BCE0; Wed, 28 Dec 2022 01:18:45 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9A50F68BCCD for ; Wed, 28 Dec 2022 01:18:34 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=q0M/xYcAzoaKegqp7TSteK5NgYOvz0TFunNXdTWny0k=; b=cd6m8/MC14mQ6pzPJr6VtogC33hiXsTxaBq19y+k1LmMU17/Q56eFTyaoeHd9BGbXmQQ6N FU8o3nGT2ieJGH3xLu0GSxEaK07QtwgcD5Ie7PnsJAGJOO9AzzHYpq4ugBlpmnJRuvWRof zDnT8uyCEj//13x57b9kx+olZHFuxcw= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 530d25f9; Tue, 27 Dec 2022 23:18:19 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:02 +0100 Message-Id: <20221227231814.2520181-21-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 20/32] avfilter/palettegen: base box split decision on a perceptual model 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: aQ5HR72VMOOm Similar to the change in paletteuse, we rely on a perceptual model to decide how and where to split the box. --- libavfilter/Makefile | 2 +- libavfilter/vf_palettegen.c | 48 ++++++++++++++++-------------- tests/ref/fate/filter-palettegen-1 | 2 +- tests/ref/fate/filter-palettegen-2 | 2 +- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index c3d13e5a26..5783be281d 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -403,7 +403,7 @@ OBJS-$(CONFIG_OVERLAY_VULKAN_FILTER) += vf_overlay_vulkan.o vulkan.o vul OBJS-$(CONFIG_OWDENOISE_FILTER) += vf_owdenoise.o OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o OBJS-$(CONFIG_PAD_OPENCL_FILTER) += vf_pad_opencl.o opencl.o opencl/pad.o -OBJS-$(CONFIG_PALETTEGEN_FILTER) += vf_palettegen.o +OBJS-$(CONFIG_PALETTEGEN_FILTER) += vf_palettegen.o palette.o OBJS-$(CONFIG_PALETTEUSE_FILTER) += vf_paletteuse.o framesync.o palette.o OBJS-$(CONFIG_PERMS_FILTER) += f_perms.o OBJS-$(CONFIG_PERSPECTIVE_FILTER) += vf_perspective.o diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 99e4512e52..3178c43ab9 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -30,16 +30,19 @@ #include "libavutil/intreadwrite.h" #include "avfilter.h" #include "internal.h" +#include "palette.h" /* Reference a color and how much it's used */ struct color_ref { uint32_t color; + struct Lab lab; int64_t count; }; /* Store a range of colors */ struct range_box { uint32_t color; // average color + struct Lab avg; // average color in perceptual OkLab space int major_axis; // best axis candidate for cutting the box int64_t weight; // sum of all the weights of the colors int64_t cut_score; // how likely the box is to be cut down (higher implying more likely) @@ -115,15 +118,14 @@ static int cmp_##name(const void *pa, const void *pb) \ { \ const struct color_ref * const *a = pa; \ const struct color_ref * const *b = pb; \ - return (int)((*a)->color >> (8 * (2 - (pos))) & 0xff) \ - - (int)((*b)->color >> (8 * (2 - (pos))) & 0xff); \ + return FFDIFFSIGN((*a)->lab.name, (*b)->lab.name); \ } -DECLARE_CMP_FUNC(r, 0) -DECLARE_CMP_FUNC(g, 1) +DECLARE_CMP_FUNC(L, 0) +DECLARE_CMP_FUNC(a, 1) DECLARE_CMP_FUNC(b, 2) -static const cmp_func cmp_funcs[] = {cmp_r, cmp_g, cmp_b}; +static const cmp_func cmp_funcs[] = {cmp_L, cmp_a, cmp_b}; /** * Simple color comparison for sorting the final palette @@ -137,40 +139,38 @@ static int cmp_color(const void *a, const void *b) static void compute_box_stats(PaletteGenContext *s, struct range_box *box) { - int avg[3]; int64_t er2[3] = {0}; /* Compute average color */ - int64_t sr = 0, sg = 0, sb = 0; + int64_t sL = 0, sa = 0, sb = 0; box->weight = 0; for (int i = box->start; i < box->start + box->len; i++) { const struct color_ref *ref = s->refs[i]; - sr += (ref->color >> 16 & 0xff) * ref->count; - sg += (ref->color >> 8 & 0xff) * ref->count; - sb += (ref->color & 0xff) * ref->count; + sL += ref->lab.L * ref->count; + sa += ref->lab.a * ref->count; + sb += ref->lab.b * ref->count; box->weight += ref->count; } - avg[0] = sr / box->weight; - avg[1] = sg / box->weight; - avg[2] = sb / box->weight; - box->color = 0xffU<<24 | avg[0]<<16 | avg[1]<<8 | avg[2]; + box->avg.L = sL / box->weight; + box->avg.a = sa / box->weight; + box->avg.b = sb / box->weight; /* Compute squared error of each color channel */ for (int i = box->start; i < box->start + box->len; i++) { const struct color_ref *ref = s->refs[i]; - const int64_t dr = (int)(ref->color >> 16 & 0xff) - avg[0]; - const int64_t dg = (int)(ref->color >> 8 & 0xff) - avg[1]; - const int64_t db = (int)(ref->color & 0xff) - avg[2]; - er2[0] += dr * dr * ref->count; - er2[1] += dg * dg * ref->count; + const int64_t dL = ref->lab.L - box->avg.L; + const int64_t da = ref->lab.a - box->avg.a; + const int64_t db = ref->lab.b - box->avg.b; + er2[0] += dL * dL * ref->count; + er2[1] += da * da * ref->count; er2[2] += db * db * ref->count; } /* Define the best axis candidate for cutting the box */ - box->major_axis = 1; // pick green by default (the color the eye is the most sensitive to) + box->major_axis = 0; if (er2[2] >= er2[0] && er2[2] >= er2[1]) box->major_axis = 2; + if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; if (er2[0] >= er2[1] && er2[0] >= er2[2]) box->major_axis = 0; - if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; // prefer green again /* The box that has the axis with the biggest error amongst all boxes will but cut down */ box->cut_score = FFMAX3(er2[0], er2[1], er2[2]); @@ -318,7 +318,7 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ", box_id, box->start, box->start + box->len - 1, box->len, box->weight, - "rgb"[box->major_axis], box->sorted_by == box->major_axis ? 'y':'n'); + "Lab"[box->major_axis], box->sorted_by == box->major_axis ? 'y':'n'); /* sort the range by its major axis if it's not already sorted */ if (box->sorted_by != box->major_axis) { @@ -348,6 +348,9 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) av_log(ctx, AV_LOG_INFO, "%d%s colors generated out of %d colors; ratio=%f\n", s->nb_boxes, s->reserve_transparent ? "(+1)" : "", s->nb_refs, ratio); + for (int i = 0; i < s->nb_boxes; i++) + s->boxes[i].color = 0xffU<<24 | ff_oklab_int_to_srgb_u8(s->boxes[i].avg); + qsort(s->boxes, s->nb_boxes, sizeof(*s->boxes), cmp_color); write_palette(ctx, out); @@ -392,6 +395,7 @@ static int color_inc(struct hist_node *hist, uint32_t color) if (!e) return AVERROR(ENOMEM); e->color = color; + e->lab = ff_srgb_u8_to_oklab_int(color); e->count = 1; return 1; } diff --git a/tests/ref/fate/filter-palettegen-1 b/tests/ref/fate/filter-palettegen-1 index 57be338b42..bae6b7064b 100644 --- a/tests/ref/fate/filter-palettegen-1 +++ b/tests/ref/fate/filter-palettegen-1 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 16x16 #sar 0: 1/1 -0, 0, 0, 1, 1024, 0x21c6e6c4 +0, 0, 0, 1, 1024, 0xbb5cde01 diff --git a/tests/ref/fate/filter-palettegen-2 b/tests/ref/fate/filter-palettegen-2 index bcdf54af95..7217de3a92 100644 --- a/tests/ref/fate/filter-palettegen-2 +++ b/tests/ref/fate/filter-palettegen-2 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 16x16 #sar 0: 1/1 -0, 0, 0, 1, 1024, 0x630d76b1 +0, 0, 0, 1, 1024, 0xfbf66e70 From patchwork Tue Dec 27 23:18:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39784 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762076pzb; Tue, 27 Dec 2022 15:21:06 -0800 (PST) X-Google-Smtp-Source: AMrXdXvXv3h4sLjHbxuXFC04rNf7Ejd8FNs30W+DuBkyw9LgTIGgKH9Mq5oR3ta3l3hZmywvFmh3 X-Received: by 2002:a17:907:d38c:b0:83c:1a1e:1efe with SMTP id vh12-20020a170907d38c00b0083c1a1e1efemr19180339ejc.6.1672183266478; Tue, 27 Dec 2022 15:21:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183266; cv=none; d=google.com; s=arc-20160816; b=0sVI/lkOIuDQkk3zQ/tP5H2d2T3VSXgJFeRaToNB0+SvuulWziPrI4wlH+DXewIcSb Jp4GPr7cXoYyVYO1RIyOJfS0AkCn0atF79ftNOJwYP73XLxTd6i8SO+buddgRxwu+r4Q xhvxnOuFap3UTwH/jq4A2TJHQuW8OodBcBv+EOyEXov42O/qa3WHDad/mNkJVsSjB+7A Q/UrtOgEAVR9Lrw5AFTdN5qLvPHF1yqwwVKc+xjoyQZgz08tEFagvWblDbEBpTahEWUL g+LuhRhtNCSJHtNwcImyPTSfz2a7ed/nGCSsv8QVGBDmMsyXOKDj5UfCLnRxdEBKj9R7 Zffg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=j+CPXKTyIG0Ra+HUFyWCyOhc2aAING3ZNkLp1zNFmqo=; b=PmGtnS5RQ6Iy+cLo9y3GxtqLUeGihKgMYVVdzQ64vHg4LjUdVFF/qpNQJPVL7X6FzR v0VTjrhjB9nvAU0YZJuhBtU/3ldcNhx8HKTYIf4WRYv+n6AKZJptLByDReONV3+zvyEd y1ZA0ALltNc0cQxkoimgh9MBo7l1upxHbrsI7S4JLijmC7dGfgV8/1+ZDTnGLHoagRQ8 LUGa52subjvTVs67t5JGlDSAzQN+ApunTaiggKFz7Z4my0N02USDh7iHjiUG044L+T51 7AvkrAyHJnkwi8bEeO5fbjrXPLFP1w/SOsDOoM3iTSLMGz+GFRHRo1vFa+zp3q2FrOv0 qRwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=BKsZHilj; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id dr7-20020a170907720700b007c101c9237asi11547678ejc.668.2022.12.27.15.21.05; Tue, 27 Dec 2022 15:21:06 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=BKsZHilj; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2517968BD0B; Wed, 28 Dec 2022 01:18:46 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C1BC468BCBC for ; Wed, 28 Dec 2022 01:18:34 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6+jJRaL9uc4WE2jdDxzAn//5MAFVDY/6RmFhKMhd9Jc=; b=BKsZHiljv749D6ls2bLeYeryHqfcRD1Ntq5XEDpORRq+U9GE5JDL14tgzdGnlqKqMcepYU VFDa8mdOMqa4R2mG8aqv3uyrDDqbMtwMCOjbqunRwLYV49vRO9TcGXb9HhSXX5nKEF3eOT o2WbhRMcTMM8BXfZ0I/DzZrDHQq2cnI= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id db9254cb; Tue, 27 Dec 2022 23:18:19 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:03 +0100 Message-Id: <20221227231814.2520181-22-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 21/32] avfilter/palettegen: add a warning about supporting only sRGB 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: gJQTj3iO2u4F --- libavfilter/vf_palettegen.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 3178c43ab9..ba81739d27 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -451,9 +451,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; PaletteGenContext *s = ctx->priv; - int ret = s->prev_frame ? update_histogram_diff(s->histogram, s->prev_frame, in) - : update_histogram_frame(s->histogram, in); + int ret; + + if (in->color_trc != AVCOL_TRC_UNSPECIFIED && in->color_trc != AVCOL_TRC_IEC61966_2_1) + av_log(ctx, AV_LOG_WARNING, "The input frame is not in sRGB, colors may be off\n"); + ret = s->prev_frame ? update_histogram_diff(s->histogram, s->prev_frame, in) + : update_histogram_frame(s->histogram, in); if (ret > 0) s->nb_refs += ret; From patchwork Tue Dec 27 23:18:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39785 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762145pzb; Tue, 27 Dec 2022 15:21:14 -0800 (PST) X-Google-Smtp-Source: AMrXdXv59DSJRmpt1cU7aZjpdKtfgsXsmrIR7bYQfKYIj83ZbNv8rkd++6dWYSSonvNC1y3Z9Mr0 X-Received: by 2002:a05:6402:a55:b0:475:9918:37ce with SMTP id bt21-20020a0564020a5500b00475991837cemr19961703edb.13.1672183274320; Tue, 27 Dec 2022 15:21:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183274; cv=none; d=google.com; s=arc-20160816; b=X+vX5Kz9ik09mkl8KpU9kzl4e1qMZeOjaBEPJFGWoB4rhN/NH62o/pIBE13uA1omla YJC5jrPwfQO8guuTQ/LQ2qfCJ51/FbmkcUei0BlvEuM0W+EAglxCnSFQmI3Ff7uPyUTJ KvQS8ZKuM5P+A4iC360kvu+PBqSKiiNHBxMrsvYNmcb+SswXzbsSrxFlCvIwBhL7xG4d 8K+ab1tSeplgtyuAWc5N0GBSo6wRKyRDOxpvo3Zg5PpSstMHYN5UJhDUzRy0R9RlakzZ WdJhw5dRUjQn+V90/y49LnasB5096WUvL7zwXTK2/ko/HdKzvqa+gNUsRImoyvAY0r6g LPFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=8RJV+BPAU4hhGaiq+rOtVxirtviExoJq94QH/3JQET0=; b=nvujhSqph5ad3qHUiSBJdoYcUNFMhMGK00ilvX3zL5ZHbLkNMlH/o0A/a2EsemkLgl FVv9qElDKa53T/I1IGjMjhiP9NTSQ/9kC9gZ1RIm/AP3i7qVh8QO+YaNCi2+OlJrvpmy VMcvqU6CaZoN42fJbvezdXFzwPKEGccGidaVF8VCpbqzV2iZ9zHVDc6m6r/+El8n4AVY m9hvSVAiVV9I2w5r22kJNsEQaqVjWn0FwiPW38qV2WmAAEVAVY6kno+fdq57xt81a00z dAexYI/aYEX6/Fh0uVCflT5E0QwDaFUIzFjabWHtSw3s0S4l3Z2R5OI3NjAG39gR+ELZ mcqg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=qin8OV1n; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id f8-20020a056402194800b004838856a8dasi7807644edz.568.2022.12.27.15.21.14; Tue, 27 Dec 2022 15:21:14 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=qin8OV1n; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 310A268BD4D; Wed, 28 Dec 2022 01:18:47 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F1C2968BCD2 for ; Wed, 28 Dec 2022 01:18:34 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MP8qLHNnIPfx+eYMMHi45KrmAqo6FfJYPQitNhEjlY4=; b=qin8OV1n7Wwi98u8ZXAv0LBP9ONaD2mGMyyqvtGL57+unKJ8e4qAbhTH3AaAVxnAxdVH8i 64wibGV1kVR28vx42ZH28z46WLxoipWK3wm7PC2bh3lvkKBvBACFHhOtCE+FbpUWcjCcz5 FFdAn84MXZ1XCpYj9DSarbvmgMywLns= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 5ddc06c0; Tue, 27 Dec 2022 23:18:19 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:04 +0100 Message-Id: <20221227231814.2520181-23-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 22/32] avfilter/palettegen: make refs order deterministic 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: WzZZKLWkANeL Currently, in case of equality on the first color channel, the order of the ref colors is defined by the hashing function. This commit makes the sorting deterministic and improve the hierarchical ordering. --- libavfilter/vf_palettegen.c | 61 ++++++++++++++++++++++-------- tests/ref/fate/filter-palettegen-1 | 2 +- tests/ref/fate/filter-palettegen-2 | 2 +- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index ba81739d27..784e81b875 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -113,19 +113,51 @@ static int query_formats(AVFilterContext *ctx) typedef int (*cmp_func)(const void *, const void *); -#define DECLARE_CMP_FUNC(name, pos) \ -static int cmp_##name(const void *pa, const void *pb) \ -{ \ - const struct color_ref * const *a = pa; \ - const struct color_ref * const *b = pb; \ - return FFDIFFSIGN((*a)->lab.name, (*b)->lab.name); \ +#define DECLARE_CMP_FUNC(k0, k1, k2) \ +static int cmp_##k0##k1##k2(const void *pa, const void *pb) \ +{ \ + const struct color_ref * const *a = pa; \ + const struct color_ref * const *b = pb; \ + const int c0 = FFDIFFSIGN((*a)->lab.k0, (*b)->lab.k0); \ + const int c1 = FFDIFFSIGN((*a)->lab.k1, (*b)->lab.k1); \ + const int c2 = FFDIFFSIGN((*a)->lab.k2, (*b)->lab.k2); \ + return c0 ? c0 : c1 ? c1 : c2; \ } -DECLARE_CMP_FUNC(L, 0) -DECLARE_CMP_FUNC(a, 1) -DECLARE_CMP_FUNC(b, 2) +DECLARE_CMP_FUNC(L, a, b) +DECLARE_CMP_FUNC(L, b, a) +DECLARE_CMP_FUNC(a, L, b) +DECLARE_CMP_FUNC(a, b, L) +DECLARE_CMP_FUNC(b, L, a) +DECLARE_CMP_FUNC(b, a, L) + +enum { ID_XYZ, ID_XZY, ID_ZXY, ID_YXZ, ID_ZYX, ID_YZX }; +static const char * const sortstr[] = { "Lab", "Lba", "bLa", "aLb", "baL", "abL" }; + +static const cmp_func cmp_funcs[] = { + [ID_XYZ] = cmp_Lab, + [ID_XZY] = cmp_Lba, + [ID_ZXY] = cmp_bLa, + [ID_YXZ] = cmp_aLb, + [ID_ZYX] = cmp_baL, + [ID_YZX] = cmp_abL, +}; -static const cmp_func cmp_funcs[] = {cmp_L, cmp_a, cmp_b}; +/* + * Return an identifier for the order of x, y, z (from higher to lower), + * preferring x over y and y over z in case of equality. + */ +static int sort3id(int64_t x, int64_t y, int64_t z) +{ + if (x >= y) { + if (y >= z) return ID_XYZ; + if (x >= z) return ID_XZY; + return ID_ZXY; + } + if (x >= z) return ID_YXZ; + if (y >= z) return ID_YZX; + return ID_ZYX; +} /** * Simple color comparison for sorting the final palette @@ -167,10 +199,7 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) } /* Define the best axis candidate for cutting the box */ - box->major_axis = 0; - if (er2[2] >= er2[0] && er2[2] >= er2[1]) box->major_axis = 2; - if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; - if (er2[0] >= er2[1] && er2[0] >= er2[2]) box->major_axis = 0; + box->major_axis = sort3id(er2[0], er2[1], er2[2]); /* The box that has the axis with the biggest error amongst all boxes will but cut down */ box->cut_score = FFMAX3(er2[0], er2[1], er2[2]); @@ -316,9 +345,9 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) int i; int64_t median, weight; - ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ", + ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %s (already sorted:%c) ", box_id, box->start, box->start + box->len - 1, box->len, box->weight, - "Lab"[box->major_axis], box->sorted_by == box->major_axis ? 'y':'n'); + sortstr[box->major_axis], box->sorted_by == box->major_axis ? 'y':'n'); /* sort the range by its major axis if it's not already sorted */ if (box->sorted_by != box->major_axis) { diff --git a/tests/ref/fate/filter-palettegen-1 b/tests/ref/fate/filter-palettegen-1 index bae6b7064b..1e5c9ee002 100644 --- a/tests/ref/fate/filter-palettegen-1 +++ b/tests/ref/fate/filter-palettegen-1 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 16x16 #sar 0: 1/1 -0, 0, 0, 1, 1024, 0xbb5cde01 +0, 0, 0, 1, 1024, 0xa285dd77 diff --git a/tests/ref/fate/filter-palettegen-2 b/tests/ref/fate/filter-palettegen-2 index 7217de3a92..c1fc64e13d 100644 --- a/tests/ref/fate/filter-palettegen-2 +++ b/tests/ref/fate/filter-palettegen-2 @@ -3,4 +3,4 @@ #codec_id 0: rawvideo #dimensions 0: 16x16 #sar 0: 1/1 -0, 0, 0, 1, 1024, 0xfbf66e70 +0, 0, 0, 1, 1024, 0xf2286e18 From patchwork Tue Dec 27 23:18:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39786 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762220pzb; Tue, 27 Dec 2022 15:21:22 -0800 (PST) X-Google-Smtp-Source: AMrXdXti7Qc3Tu8o6Qe8oBsqL/p+1qu08kUPIMwxL+6JNbOwqKAVVH4iTZNfA0t5C2SNS9/InmML X-Received: by 2002:a17:906:b087:b0:846:8c9a:68a0 with SMTP id x7-20020a170906b08700b008468c9a68a0mr15363877ejy.30.1672183282414; Tue, 27 Dec 2022 15:21:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183282; cv=none; d=google.com; s=arc-20160816; b=HYyW9EnEfgf3uXMyTfVK6XYggRrAyRSGp56KHpjlWQJKHxkGNQ9dX8AeBZDqW0J4/5 Ad6aYm0IT+V28MNmKObySOvic2PKaFb2VkiYwDdJzyfJFSvD1FWTe62hwyRj06Yzijid NuYUckRN+DEFPsvnJm1c+PDaR5u770es47GFONIoYGNl0X5b6vIiwg5RDNIfLck3UXcG u4mSZL9LzU1d76BDL8xQx8lWg/CJzLPw5AgOcrxAC0+hZexSULitgBZ82S3U226MdcHz /+0NCAj8aKRWZeycD3f0qrY5yY6fgKQXOS2ZgN1WtKkXZqRxO05Lge6FIRgku5GGng8j 6MIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=aaVVLKdk4PZRjhTlLgbRISiCWJCV47kVhTtYcC6pVHQ=; b=nhgDhPk6LGkDeKrVQe1cFS/l52JvkJzEYtpmptCyLLMGvbGFU0rkTDMP3eSKSF7n0W phck0KIm1zVAngbGhUuYIsTTVorYmFXU6LpauouFeITLkNfXIfeEHp4feab6Y19bTG+N 8KfzKWMAzO8+6jn8A9cJkCnbGpgFPqwv95TkZECZLK8K5x7BTNLpWWUAGN0lIpzp3BFh +7D+XmrfikxOulfGR/HEbOfp/pUIXL3US6YJV7rb+LXCuA9W63PKgV3HUSxPjnkV5eca UP7eQi/Syv7NuCu/JWi/5dTs3o13pXFxHEYUgywaM7KBw9WzxUx/PSyHQLoXBP/4SKc3 9keg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b="mC/qWIQ0"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id g23-20020a170906349700b007813b1924ccsi9676357ejb.934.2022.12.27.15.21.22; Tue, 27 Dec 2022 15:21:22 -0800 (PST) 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=@pkh.me header.s=selector1 header.b="mC/qWIQ0"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4449B68BD55; Wed, 28 Dec 2022 01:18:48 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 35CBF68BCD2 for ; Wed, 28 Dec 2022 01:18:35 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=irF1oucIe8S+m0golIOo1RhXyEjB6k+XySF6SpqeZss=; b=mC/qWIQ0VQISbHsjUAClXUFux8PVVExiuXAVK5HXF2u1V/V1T2Hsur1MrFXbLg0aEAcR6Y D2HvsvBCoSSP52LmvM9F4Eg9vOlwgU/cfYTGJn7/2Dy4W+pX+Jm4jFuqTj0PwLVyhw3Axf dc+omY2ScYFba3SuHLJoOszaXeFWqrE= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id e1129265; Tue, 27 Dec 2022 23:18:19 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:05 +0100 Message-Id: <20221227231814.2520181-24-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 23/32] avfilter/palettegen: use libc qsort 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 1v9sQM4JCvEa Now that the sort function is deterministic, we can rely on the libc sorting function. --- libavfilter/vf_palettegen.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 784e81b875..507690fa82 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -26,7 +26,6 @@ #include "libavutil/avassert.h" #include "libavutil/internal.h" #include "libavutil/opt.h" -#include "libavutil/qsort.h" #include "libavutil/intreadwrite.h" #include "avfilter.h" #include "internal.h" @@ -352,7 +351,7 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) /* sort the range by its major axis if it's not already sorted */ if (box->sorted_by != box->major_axis) { cmp_func cmpf = cmp_funcs[box->major_axis]; - AV_QSORT(&s->refs[box->start], box->len, const struct color_ref *, cmpf); + qsort(&s->refs[box->start], box->len, sizeof(struct color_ref *), cmpf); box->sorted_by = box->major_axis; } From patchwork Tue Dec 27 23:18:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39787 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762281pzb; Tue, 27 Dec 2022 15:21:30 -0800 (PST) X-Google-Smtp-Source: AMrXdXuH6CvyBLv20aeoYfA1+7uYGjplXatZu09OCvd8zh8cyY8IbTCgUFLNVpOb9wliYCg6pIVC X-Received: by 2002:a17:906:2509:b0:7c0:f2c5:ac3f with SMTP id i9-20020a170906250900b007c0f2c5ac3fmr18251256ejb.58.1672183290288; Tue, 27 Dec 2022 15:21:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183290; cv=none; d=google.com; s=arc-20160816; b=YMiMPAWjmKifaWmW8WuQnICUQwbBsuzKPFb1ASOplgzf9GslCCt+oHRZsz932wCbbr Ql0kGs1RJgmPq5ccpBS/ZwxDltTAelSEefUP3Fdm2IgAX6K2QNR9x4X9ylbIIfmHP4Sf +xWU7sH3Zi2ACIwD3h/LUNDWdnJ/UzdH6QtM3PKkf3YqVpGyGo3K9jkhksR/QfClSDzP oYCJxb3kAA36AD5uSY5FY7dxu9eVXUXF2+Psr66XxXRpXybRgp8s8rdXVjcEHnkjGF0s rG/jhN4wBTMqbnmE0IMdHhHexNAzjzzXTscWu7YAvJdEA2DjQoiLHvokjp0qcYrCzOfZ H0cA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=wqQL4oXjkSQ2dtNW+KsDYEnBQZ5UcaIHXqXi76sBukk=; b=oNNH7ym7o8WWhLZYEVQBPHXeaPfV9gWJO1/3BpFa/z+9e1ce0DatAifyLwP4FNyT+2 LxWcWOmZYJkN7uV7vNpnJHLAiylgBacPmhXfOCfLsYHiDzEtL/suUBsfcj0EE2rEiXQB 7DTO8niPF35UewrXOdLvv5JNyoTtq1Awu/M1Lafmfjrjx8fWDGbfimAUFwUg67W93w/s 0O4ROQ/ivIGg/xtRIlFlZoPx7SaCm8T7mR6LZ/Rz0DFy5XqdSA3Fc8me/fpS4vehUEUR 5ibT4mW1Uc7dh9guj2Jojf9fKUEmoW+uJS9XLputnG679FKyOIM8jeMcKr/LgtGCV2Jv enhA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=mT3xZWaF; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id t6-20020a170906608600b0084c3ce2f3e1si6223505ejj.714.2022.12.27.15.21.30; Tue, 27 Dec 2022 15:21:30 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=mT3xZWaF; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8046868BD5E; Wed, 28 Dec 2022 01:18:49 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 674B168BCD7 for ; Wed, 28 Dec 2022 01:18:35 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mYtPdOCjze0bbfU0avlxJnBfKq9B0h1g9h+Afg8BSno=; b=mT3xZWaFmpwt65L0zoEQFRFf6/3WbytJUy176br9bwt9GPuuwLOo/7L9+kZTg7Oipj7tDT zVk7g3NgVUq7ypNGabFkQZTFu8W7tkhu9rPJPifd1rasxdvqX/aHm2SM7qXIO4GBBfQvZd FhOqP1ZjbKnQ6QLoBjUmIcAJ7fRdGC4= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 19cfea87; Tue, 27 Dec 2022 23:18:19 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:06 +0100 Message-Id: <20221227231814.2520181-25-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 24/32] avfilter/palette{gen, use}: update Copyright after recent changes 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: aXXQvbgm0Iwv --- libavfilter/vf_palettegen.c | 1 + libavfilter/vf_paletteuse.c | 1 + 2 files changed, 2 insertions(+) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 507690fa82..6301cf6358 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015 Stupeflix + * Copyright (c) 2022 Clément Bœsch * * This file is part of FFmpeg. * diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index 3af121b1eb..c32b73ab9a 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015 Stupeflix + * Copyright (c) 2022 Clément Bœsch * * This file is part of FFmpeg. * From patchwork Tue Dec 27 23:18:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39788 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762340pzb; Tue, 27 Dec 2022 15:21:39 -0800 (PST) X-Google-Smtp-Source: AMrXdXvCswqnOs9qicsplwgu/9PP3/xby6UaDlTMJcnXendSUDP+XX9x9OREEZ5K5E9YBsk+rMoJ X-Received: by 2002:a17:906:12c7:b0:7c1:639:6b42 with SMTP id l7-20020a17090612c700b007c106396b42mr24898735ejb.62.1672183299102; Tue, 27 Dec 2022 15:21:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183299; cv=none; d=google.com; s=arc-20160816; b=j4kzCLS80MBPGTb7URoFhw/9UvSBHzRUgPOVdMsQ6IcAolP0guvMEIeHotwsdVpoTf cX1wEEYenL+muGMLq5sWbNmboIge2Mgk2E6rG5pX05gqenc0dfz9aZm/HaohfAVNVIIk gDodRkd6wbLo+innmpw0cxVVNzdLbHvdg3L0aAts3f8YXh4SW0KzgEvq9Tm7bx7jvtQr UzvgTpjVDroZqx6hzYHgrTseTNm3qaUHtZ4Dn2f8FX1B099ECghMCXCbEx7vLNPmyPsJ WDnbLqYgCGnPJWLVH8kYtu5nlhU9QTrC7jYsdPol40SeKaSTd9rdjeCPhg33o8C1RdSu E+hA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=pnMK7fKOQiph0F1dVLVS7i1nW2h6jGecfRuv5y+7xBA=; b=z67hX8tn/LPghWySimq9tQiUeGFm/jrPbIV979Jxk7RPHjyKVtgIPKfs/VmX8GysuX AMKxLa2GCQTBDnZWY4G5iis37yP00rR/zOpkpbAPT6rppPEIwAmAxDZD1PGl8rncNhlb vOHTw2ZafiLvKJoI73ZE5N1ZbZe0MhmmuBcdqndI+SD+6oekHB6NNuTluulYFbFhTl0N 465lsoa/gm9FnRq9o3rPLzZ/yUBBm8DwyuS/MbZ9itjpumtevAXtu4tPld9bAluFNJF7 QireXnLOxDNtEyS7oR8TP3VEk4laPHTNyvHxiluikJI2kybAOmC0t+B5eW9/S7ZPPYrF N1Jg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b="Az6mR/ID"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id be4-20020a1709070a4400b007c189b2939fsi12274821ejc.482.2022.12.27.15.21.38; Tue, 27 Dec 2022 15:21:39 -0800 (PST) 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=@pkh.me header.s=selector1 header.b="Az6mR/ID"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CE6F268BCFB; Wed, 28 Dec 2022 01:18:50 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9799B68BC7B for ; Wed, 28 Dec 2022 01:18:35 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cHkfus3J1yRc4KQa6wqTZ4JXNvgqCDU5Nx77+aV5JSA=; b=Az6mR/ID8Mr0LKM2BC0JTKNEtC71pfPC4RM3byNVVpuEYZp4L2OsW3J34UtsjzbW9xeXtG OiGiJen5/lgOjKla63wj0yl+R754a9UirvYO9jv6U00ntONr4qO6xUrMMr0V77Lwxu7bli +UIwIDFlolEO9vGrSo9tMrCHDJ1gRH8= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id b3c90244; Tue, 27 Dec 2022 23:18:19 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:07 +0100 Message-Id: <20221227231814.2520181-26-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 25/32] avfilter/palette: add lowbias32 hashing 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: LCkeweYje0IN --- libavfilter/palette.c | 10 ++++++++++ libavfilter/palette.h | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/libavfilter/palette.c b/libavfilter/palette.c index 03e48fc71e..e21ab6ff4d 100644 --- a/libavfilter/palette.c +++ b/libavfilter/palette.c @@ -208,3 +208,13 @@ uint32_t ff_oklab_int_to_srgb_u8(struct Lab c) return r<<16 | g<<8 | b; } + +uint32_t ff_lowbias32(uint32_t x) +{ + x ^= x >> 16; + x *= 0x7feb352d; + x ^= x >> 15; + x *= 0x846ca68b; + x ^= x >> 16; + return x; +} diff --git a/libavfilter/palette.h b/libavfilter/palette.h index 6839bf6fc6..d3acc854ba 100644 --- a/libavfilter/palette.h +++ b/libavfilter/palette.h @@ -55,4 +55,9 @@ struct Lab ff_srgb_u8_to_oklab_int(uint32_t srgb); */ uint32_t ff_oklab_int_to_srgb_u8(struct Lab c); +/* + * lowbias32 hashing from https://nullprogram.com/blog/2018/07/31/ + */ +uint32_t ff_lowbias32(uint32_t x); + #endif /* AVFILTER_PALETTE_H */ From patchwork Tue Dec 27 23:18:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39789 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762407pzb; Tue, 27 Dec 2022 15:21:48 -0800 (PST) X-Google-Smtp-Source: AMrXdXvtr7q4wYjXQ5T5SJjaqeiWT1qocH//p1ut3qUgsb59ppcjRGPlwOoPqcUiPjUo7qSeb8yc X-Received: by 2002:a17:906:a18c:b0:7c1:5467:39b1 with SMTP id s12-20020a170906a18c00b007c1546739b1mr21212667ejy.72.1672183307661; Tue, 27 Dec 2022 15:21:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183307; cv=none; d=google.com; s=arc-20160816; b=tOcqzjIENNCrQ/0c48Z8HpsXqoqC0VNuHN1NGoIOibVgCZtMDihJ+KYhYbwwnCRYR1 CSvZmMszllwMz6H6hT68kSkPeK/1fYvddD+stz/hMeNb7nEUzL95aYn8unxVMYlQK+Ep QN5Lj1a8e/mHKINcHVY5Bw0LDY237ZwP5yL9Ea/Z7//LP2sB/Vn/cYRDKlNqH72co6x2 xumgRqBSRfNWIYtdzxDNNHA2bkjGeXvHrlRUajTEviKL03tHx+ZbxrrEXnXMlGkjhOel HHYKniuBJgptg0kgL9Btb50ko/EpW11l5rj0YE10YpdtcFT7u2oNK9AE/bI7m33yxQRK F56Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=QVJk+kbGRqoMEiPSSffV2dE6ssp8Q7yle8F+NMf4KCg=; b=b1y3/VoTQzJ3WPyDOW/eJWtEfWD5wBZQwBHZNPhL6+CBf00HwUXc/l+sPmNbC+Ts0w VFjJB6dq1DS0ABfGEaf9XDjhFyYCTqmtUE34EtwiSKeVYNvt+xCftgEfQuwYIzW5tgwh 7k0GbamB5pCIXiHw278K8RKlRnEKF97aldVoJZIFF9vnGqQvhJWiEK+v6HjTrFGVECMX YuBBrNOWc2HwQFvvNh8JVg/BvXaN/oO1Jr5rJ39tc5X3Vw8okRbL4IyJrRCR4fj5w9QE efnQsTG6bTIp6BdcQtqwiZhJ+EuMcs8YUM5TmJQSOiUaBb3S7CL5DIoxc3sOzn2TMvpQ dfHw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=Wjxb9v45; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id qa35-20020a17090786a300b007813594dc31si11702862ejc.523.2022.12.27.15.21.47; Tue, 27 Dec 2022 15:21:47 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=Wjxb9v45; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B9A6268BD65; Wed, 28 Dec 2022 01:18:51 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C7E5A68BC9D for ; Wed, 28 Dec 2022 01:18:35 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ou4MJHzF7K8lH+/EeTZULSIRbyDezN+OcHzUTOywVM0=; b=Wjxb9v45eg8pJAfYD4OPU5r00ts/dYIjrewxl92zjTiZBnn+x7BNp+9h4aKVvOUd4Rew5k TSs7R7rvhQ+Ek2vR7pdJUOSJ/nBaFHkdSXLUxiU4x7ayyamJp5aBHCXW47emIniVISK0AR 0OiTtfU70wHB3MUD0oZ1z1u8ePlhptY= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 78164afd; Tue, 27 Dec 2022 23:18:20 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:08 +0100 Message-Id: <20221227231814.2520181-27-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 26/32] avfilter/palettegen: use lowbias32 for color hashing 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: n5fF/OSgx1Ou 1.12x faster overall in palettegen on my machine. --- libavfilter/vf_palettegen.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 6301cf6358..97e12f7274 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -63,8 +63,7 @@ enum { NB_STATS_MODE }; -#define NBITS 5 -#define HIST_SIZE (1<<(3*NBITS)) +#define HIST_SIZE (1<<15) typedef struct PaletteGenContext { const AVClass *class; @@ -387,27 +386,13 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) return out; } -/** - * Hashing function for the color. - * It keeps the NBITS least significant bit of each component to make it - * "random" even if the scene doesn't have much different colors. - */ -static inline unsigned color_hash(uint32_t color) -{ - const uint8_t r = color >> 16 & ((1<> 8 & ((1< X-Patchwork-Id: 39790 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762469pzb; Tue, 27 Dec 2022 15:21:56 -0800 (PST) X-Google-Smtp-Source: AMrXdXuP7Z3qsCUAIVoWQHIauzDheJQsLYkJ0CPqa/JBYHaSvC1Kogr2OlCj8+a7DLzx9bu2VHAP X-Received: by 2002:a17:906:99d1:b0:7c1:12ef:bf52 with SMTP id s17-20020a17090699d100b007c112efbf52mr17852526ejn.3.1672183316634; Tue, 27 Dec 2022 15:21:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183316; cv=none; d=google.com; s=arc-20160816; b=RFqWGk7VMY82tJQdoinw/JCgGEBfmNwwhAkuLHMXkyjaUZMKo0uXAhIZ2hYVBwt0sv u2eqjNdFnNrs3BymfXcWU0gAyPh9Ehi2qkvxhLqng5BbEqXhoHjcuG4Q3fu//2qBK8AT 1m8d1wB2rg96yJY1Ye++HwVIAct6Iq+fGYu0VpRywTxu+WubC5l78FFkTr7Ve8ljXj0l VmdR12Kq7mlzr/kZ/EleW8+08EatQ1xt1fXjs0RpTwzY6T3vZRavId06XfKimVh7zKE/ S6VJuD4GnyE0G8slmsYi+eV8gAEG8ASyx00Iu0zgnRRL+sB+Cc+DG1/DJNvJ1kmCbyw1 fanQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=1PQaiORBM2bO8I774YZTkiGzVVz6MU1l87KlQQrQKdU=; b=zdQOzzFrs1ZfbCHWgMJOgfcetq2i3lisbIVdk03xdqt/cS+eLr7NHxY7I0854lQ1GH vQupdospC5i66Vjai1AEFGjMcPqC1O1b5ki0k+yHNYwydK9b+a9crkb8IY15wH6UWxl3 Kq2mWAaGOTgxYCmSf9U1FgHK0iqf+7i3sXdLOVGh/+YaYoC2Q9GTtbLXx/XNdvyynfYz IM+NROvIclK/jQf50fqMuqLZm4sAJ5MU/U6a3vT6zC5xqTFTaxwKInuddU+u6aUgGTA7 aETxmqDxySw4V/v/atHS2qveEqM0YV0pnPYCbDz68aghoTSKcj4NSFxJo3hd+fv4ENf4 CuMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=FAP+yYI9; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id qf11-20020a1709077f0b00b008401cc1a665si12372819ejc.259.2022.12.27.15.21.56; Tue, 27 Dec 2022 15:21:56 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=FAP+yYI9; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BF70168BD6C; Wed, 28 Dec 2022 01:18:52 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 15E8E68BCED for ; Wed, 28 Dec 2022 01:18:35 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+i6c1mpDBqWgOFXfXqk9MntXEdBWRDilgE9W/QB/8lQ=; b=FAP+yYI94kn9G5pAdhzKpeOzwQjoPoIz4a619HVRM0vp/ZqDVCSE9gVuK8/Cn+a4ZX34AN 34DENKwXEv4oOlhyKijo/M4uZrQXC4D8SfmM/lMcws3oscZ3qli/Ojb6x7uzBMdyeyJkBL yUXEKld6IwynOFBBLHd8U/bn5VK0yCY= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 43a41611; Tue, 27 Dec 2022 23:18:20 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:09 +0100 Message-Id: <20221227231814.2520181-28-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 27/32] avfilter/paletteuse: use lowbias32 for color hashing 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: aIMOciY40ILj Impact is more negligible than previous commit but still faster (1.02x). --- libavfilter/vf_paletteuse.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index c32b73ab9a..c2d6333662 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -70,8 +70,7 @@ struct color_node { int left_id, right_id; }; -#define NBITS 5 -#define CACHE_SIZE (1<<(3*NBITS)) +#define CACHE_SIZE (1<<15) struct cached_color { uint32_t color; @@ -346,10 +345,7 @@ static av_always_inline int color_get(PaletteUseContext *s, uint32_t color, { int i; struct color_info clrinfo; - const uint8_t rhash = (color>>16) & ((1<> 8) & ((1<cache[hash]; struct cached_color *e; From patchwork Tue Dec 27 23:18:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39791 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762540pzb; Tue, 27 Dec 2022 15:22:04 -0800 (PST) X-Google-Smtp-Source: AMrXdXtfxepq5M53MNWcWEqw/Is3+xhVZhEsTmoGY6Yl0B76TjaPuYiGbK1fGC3gqtR74X9aPYpO X-Received: by 2002:a17:906:264c:b0:7cf:bae0:9cd5 with SMTP id i12-20020a170906264c00b007cfbae09cd5mr19264275ejc.40.1672183324713; Tue, 27 Dec 2022 15:22:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183324; cv=none; d=google.com; s=arc-20160816; b=NJw7NLiS2NRF/AVLFuLfExD/QN2GGpCRNxeIfX37rR5q9n3RfnHR96JPRtJpjfKd1o BVzRXkpuGsebB2Z58NSBypRuuMajhiOyKJuM0ouJSNyF5x1HGAchBogeyztaxo/Gvys5 QCO88ggJ7Uy3FhGESMS3VQacP/8GZdY1w0VmKhgpeNqfCYnP10U/6ja4Q5yL5U86rona 3VKiU92IzujnQ7L5baiitFP2KrjiV6NwM+F9ocuRfFkZyQjUpXAmFr4pAeJCLzJtU3El Awb9VOgWxtIYYQRmBZWpDF4yp/Ev4Z56iIVkrF8ZZOvo6F7nJ2l8bud2ufOSYI+oWPd2 SaBg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=HKMPLcWquCsqv4RByuXbVGsmuTRDth7n0171dJXzm3Y=; b=BuOy/2ZoPjdXK53C91B0OqIwwYDJUc2nnAQzxKYq085R6vF9d9vL8ZVyBVbDR0e/nx eQGM7x9iCULZd5aI2WKYd6L1aL0+MrlgWValoNCSlF/Gy4oDSOxncF6sx2aKCz6ZlPru 9msH/VyrNoXqzSIh3o82nGY6GETqlCvv9QoXMqhH7IU1u4RxzO1Uljs9bZrKPYJUT5Iw udWF+i05szCom5QJ3JIm9LQJiuph/sGJ1aQcn3pG68AHIssr1tJUZ2vwPAEkWeeK9bct IXkcxztLpWcTJ7vEJNLFYFAZbCGoFUk6zZhgqay2Ib7sHVj7tr0wmn43Nsdr19W9CMXX Kfow== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=g1N5JSos; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id cf20-20020a170906b2d400b007c12c63d1f4si9748252ejb.813.2022.12.27.15.22.04; Tue, 27 Dec 2022 15:22:04 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=g1N5JSos; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B079468BCEE; Wed, 28 Dec 2022 01:18:53 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 483BC68BCE4 for ; Wed, 28 Dec 2022 01:18:36 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MNj4ybO0hORcnI3Pr5pRWDRraiTub+AWnJDoEgDrOk8=; b=g1N5JSosxTxkmIL+A4FlGN6X/llbNQURj0ejd3qbfvpGO6j3PUg7NdHpmz6HVyyATImasJ U1VTkfJDm7sNItBaurhT4I3MSiqq7sGzmH48OxnJDI/KDzye/ADR3F16NBP7KaSWSJ4pKh vmaymtc9aR6THfRmWPGyyDfbD/Q46sA= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 1d80621c; Tue, 27 Dec 2022 23:18:20 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:10 +0100 Message-Id: <20221227231814.2520181-29-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 28/32] avfilter/paletteuse: switch to recursive method 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: JpelwhEY+nwV It appears faster than the iterative method on my machine (1.06x faster), so I'm guessing compilers improved over time (the iterative version was slightly faster in the past). --- libavfilter/vf_paletteuse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index c2d6333662..0342002b15 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -130,7 +130,7 @@ static const AVOption paletteuse_options[] = { /* following are the debug options, not part of the official API */ { "debug_kdtree", "save Graphviz graph of the kdtree in specified file", OFFSET(dot_filename), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, - { "color_search", "set reverse colormap color search method", OFFSET(color_search_method), AV_OPT_TYPE_INT, {.i64=COLOR_SEARCH_NNS_ITERATIVE}, 0, NB_COLOR_SEARCHES-1, FLAGS, "search" }, + { "color_search", "set reverse colormap color search method", OFFSET(color_search_method), AV_OPT_TYPE_INT, {.i64=COLOR_SEARCH_NNS_RECURSIVE}, 0, NB_COLOR_SEARCHES-1, FLAGS, "search" }, { "nns_iterative", "iterative search", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_SEARCH_NNS_ITERATIVE}, INT_MIN, INT_MAX, FLAGS, "search" }, { "nns_recursive", "recursive search", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_SEARCH_NNS_RECURSIVE}, INT_MIN, INT_MAX, FLAGS, "search" }, { "bruteforce", "brute-force into the palette", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_SEARCH_BRUTEFORCE}, INT_MIN, INT_MAX, FLAGS, "search" }, From patchwork Tue Dec 27 23:18:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39792 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762607pzb; Tue, 27 Dec 2022 15:22:13 -0800 (PST) X-Google-Smtp-Source: AMrXdXtPs95ZMo6BIG/ioaim7FmL7INj4VndRrdWQGlhUdbwsW2GkUGJSwV3aAIm11iCArP8Q3U3 X-Received: by 2002:a17:906:bc47:b0:78d:f455:3110 with SMTP id s7-20020a170906bc4700b0078df4553110mr17472597ejv.56.1672183333641; Tue, 27 Dec 2022 15:22:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183333; cv=none; d=google.com; s=arc-20160816; b=b9QrXearOt1Fc8VUW+r+3s1lURoSYugeKq3H59lVp2KVRlhjJGaODs8treKxdY7VOY e8vIsZcizQEr+/tu0TnD9k4Pu+suP9qFK41LdXL65wjma0lju1WvvMWLl1QitrEUg6Gy IAYMheQWhPbL3sCC7/+qzUnQh6O+/sznsJCYpCGW6qH8MoCdWXBggJujA7o4WNkZaz1g 1f2h+4jEzL8zHv4le6JRwQ7a9VczTWHhaQJ4irE6kkDtjH/yu7d6vPhRvU6aWuwPpIuE 2PYxgZEQwrRNZJfqCIkZWCK1237uyWPGilMZSe06gPHduFdz5fZbgav83nWgXO96u0Ca 9SGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=W/ptnjwGNqIk/cX4RNZ5e4nxSHALPVlFlGUqgLGzOj4=; b=R7I+e2R0/QPFbauch1JvLsiQmwTmE+txR6Ey1coLwVurPf2RMAzrul505b9doPW2rQ F36XCA+6hvAAny8eOakvbtVhL8lFnWHgLFlSrLcoxyheiYroRbAB8lztK3crFEKv6vQV crNTmfbEkblp95OVz0MxB1WjtLOJ8BgyFB8Pt75wG2gHUdzcJYeD5JBR3A2NutitMabn zy+pzkr6Jk+EfLDAItIB9lRoyYAmVvKjJFbJYb4H3Lm7YU5KoNE8NXi1xX7UXP7V+tTU 33+Xb1DvpLyKyXLKolRUoRzPy8TMBam8fzJjydtl8qYgxti9vn29d7zd8e2FenXM1GZr Q18g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=KGuW+AVV; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id o22-20020a170906975600b007c4f75345e1si13042415ejy.443.2022.12.27.15.22.13; Tue, 27 Dec 2022 15:22:13 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=KGuW+AVV; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CD9EC68BCFA; Wed, 28 Dec 2022 01:18:54 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7818168BCAA for ; Wed, 28 Dec 2022 01:18:36 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XPkYZ/bpHbaZoEDxUkZIaXL9j6n7q+v/ZMxVF4OvPZM=; b=KGuW+AVVO+RxuCp7ZaCsCadi5ovahc9LLQaKf2tmpDYbXHG7xTXvaynJ5NITcEqh0Bpzox 7+QPJJp7EbpLYDnA0ZXRSvvWL6Mrzz6A06CltaZyEmodqwr5XjEUeMjj6jVxBCOYT7s+3U sbJUwaIR/+D81pKDuVbCbFrqxxE1wO0= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id e62d72ec; Tue, 27 Dec 2022 23:18:20 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:11 +0100 Message-Id: <20221227231814.2520181-30-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 29/32] avfilter/paletteuse: remove alternative search methods 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: zVTu87uycaoD This is a maintenance pain more than anything. It appears to make the code slightly faster as a side effect. --- libavfilter/vf_paletteuse.c | 220 +++++------------------------------- 1 file changed, 31 insertions(+), 189 deletions(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index 0342002b15..690422a842 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -45,13 +45,6 @@ enum dithering_mode { NB_DITHERING }; -enum color_search_method { - COLOR_SEARCH_NNS_ITERATIVE, - COLOR_SEARCH_NNS_RECURSIVE, - COLOR_SEARCH_BRUTEFORCE, - NB_COLOR_SEARCHES -}; - enum diff_mode { DIFF_MODE_NONE, DIFF_MODE_RECTANGLE, @@ -107,10 +100,8 @@ typedef struct PaletteUseContext { /* debug options */ char *dot_filename; - int color_search_method; int calc_mean_err; uint64_t total_mean_err; - int debug_accuracy; } PaletteUseContext; #define OFFSET(x) offsetof(PaletteUseContext, x) @@ -130,12 +121,7 @@ static const AVOption paletteuse_options[] = { /* following are the debug options, not part of the official API */ { "debug_kdtree", "save Graphviz graph of the kdtree in specified file", OFFSET(dot_filename), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, - { "color_search", "set reverse colormap color search method", OFFSET(color_search_method), AV_OPT_TYPE_INT, {.i64=COLOR_SEARCH_NNS_RECURSIVE}, 0, NB_COLOR_SEARCHES-1, FLAGS, "search" }, - { "nns_iterative", "iterative search", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_SEARCH_NNS_ITERATIVE}, INT_MIN, INT_MAX, FLAGS, "search" }, - { "nns_recursive", "recursive search", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_SEARCH_NNS_RECURSIVE}, INT_MIN, INT_MAX, FLAGS, "search" }, - { "bruteforce", "brute-force into the palette", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_SEARCH_BRUTEFORCE}, INT_MIN, INT_MAX, FLAGS, "search" }, { "mean_err", "compute and print mean error", OFFSET(calc_mean_err), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, - { "debug_accuracy", "test color search accuracy", OFFSET(debug_accuracy), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { NULL } }; @@ -193,26 +179,6 @@ static struct color_info get_color_from_srgb(uint32_t srgb) return ret; } -static av_always_inline uint8_t colormap_nearest_bruteforce(const uint32_t *palette, const struct color_info *target, const int trans_thresh) -{ - int i, pal_id = -1, min_dist = INT_MAX; - - for (i = 0; i < AVPALETTE_COUNT; i++) { - const uint32_t c = palette[i]; - - if (c >> 24 >= trans_thresh) { // ignore transparent entry - const struct color_info pal_color = get_color_from_srgb(palette[i]); - const int d = diff(&pal_color, target, trans_thresh); - if (d < min_dist) { - pal_id = i; - min_dist = d; - } - } - } - return pal_id; -} - -/* Recursive form, simpler but a bit slower. Kept for reference. */ struct nearest_color { int node_pos; int dist_sqd; @@ -248,7 +214,7 @@ static void colormap_nearest_node(const struct color_node *map, } } -static av_always_inline uint8_t colormap_nearest_recursive(const struct color_node *node, const struct color_info *target, const int trans_thresh) +static av_always_inline uint8_t colormap_nearest(const struct color_node *node, const struct color_info *target, const int trans_thresh) { struct nearest_color res = {.dist_sqd = INT32_MAX, .node_pos = -1}; colormap_nearest_node(node, 0, target, trans_thresh, &res); @@ -260,88 +226,11 @@ struct stack_node { int dx2; }; -static av_always_inline uint8_t colormap_nearest_iterative(const struct color_node *root, const struct color_info *target, const int trans_thresh) -{ - int pos = 0, best_node_id = -1, best_dist = INT_MAX, cur_color_id = 0; - struct stack_node nodes[16]; - struct stack_node *node = &nodes[0]; - - for (;;) { - - const struct color_node *kd = &root[cur_color_id]; - const struct color_info *current = &kd->c; - const int current_to_target = diff(target, current, trans_thresh); - - /* Compare current color node to the target and update our best node if - * it's actually better. */ - if (current_to_target < best_dist) { - best_node_id = cur_color_id; - if (!current_to_target) - goto end; // exact match, we can return immediately - best_dist = current_to_target; - } - - /* Check if it's not a leaf */ - if (kd->left_id != -1 || kd->right_id != -1) { - const int dx = target->lab[kd->split] - current->lab[kd->split]; - int nearer_kd_id, further_kd_id; - - /* Define which side is the most interesting. */ - if (dx <= 0) nearer_kd_id = kd->left_id, further_kd_id = kd->right_id; - else nearer_kd_id = kd->right_id, further_kd_id = kd->left_id; - - if (nearer_kd_id != -1) { - if (further_kd_id != -1) { - /* Here, both paths are defined, so we push a state for - * when we are going back. */ - node->color_id = further_kd_id; - node->dx2 = dx*dx; - pos++; - node++; - } - /* We can now update current color with the most probable path - * (no need to create a state since there is nothing to save - * anymore). */ - cur_color_id = nearer_kd_id; - continue; - } else if (dx*dx < best_dist) { - /* The nearest path isn't available, so there is only one path - * possible and it's the least probable. We enter it only if the - * distance from the current point to the hyper rectangle is - * less than our best distance. */ - cur_color_id = further_kd_id; - continue; - } - } - - /* Unstack as much as we can, typically as long as the least probable - * branch aren't actually probable. */ - do { - if (--pos < 0) - goto end; - node--; - } while (node->dx2 >= best_dist); - - /* We got a node where the least probable branch might actually contain - * a relevant color. */ - cur_color_id = node->color_id; - } - -end: - return root[best_node_id].palette_id; -} - -#define COLORMAP_NEAREST(search, palette, root, target, trans_thresh) \ - search == COLOR_SEARCH_NNS_ITERATIVE ? colormap_nearest_iterative(root, target, trans_thresh) : \ - search == COLOR_SEARCH_NNS_RECURSIVE ? colormap_nearest_recursive(root, target, trans_thresh) : \ - colormap_nearest_bruteforce(palette, target, trans_thresh) - /** * Check if the requested color is in the cache already. If not, find it in the * color tree and cache it. */ -static av_always_inline int color_get(PaletteUseContext *s, uint32_t color, - const enum color_search_method search_method) +static av_always_inline int color_get(PaletteUseContext *s, uint32_t color) { int i; struct color_info clrinfo; @@ -366,20 +255,19 @@ static av_always_inline int color_get(PaletteUseContext *s, uint32_t color, return AVERROR(ENOMEM); e->color = color; clrinfo = get_color_from_srgb(color); - e->pal_entry = COLORMAP_NEAREST(search_method, s->palette, s->map, &clrinfo, s->trans_thresh); + e->pal_entry = colormap_nearest(s->map, &clrinfo, s->trans_thresh); return e->pal_entry; } static av_always_inline int get_dst_color_err(PaletteUseContext *s, - uint32_t c, int *er, int *eg, int *eb, - const enum color_search_method search_method) + uint32_t c, int *er, int *eg, int *eb) { const uint8_t r = c >> 16 & 0xff; const uint8_t g = c >> 8 & 0xff; const uint8_t b = c & 0xff; uint32_t dstc; - const int dstx = color_get(s, c, search_method); + const int dstx = color_get(s, c); if (dstx < 0) return dstx; dstc = s->palette[dstx]; @@ -395,8 +283,7 @@ static av_always_inline int get_dst_color_err(PaletteUseContext *s, static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFrame *in, int x_start, int y_start, int w, int h, - enum dithering_mode dither, - const enum color_search_method search_method) + enum dithering_mode dither) { int x, y; const int src_linesize = in ->linesize[0] >> 2; @@ -421,7 +308,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram const uint8_t g = av_clip_uint8(g8 + d); const uint8_t b = av_clip_uint8(b8 + d); const uint32_t color_new = (unsigned)(a8) << 24 | r << 16 | g << 8 | b; - const int color = color_get(s, color_new, search_method); + const int color = color_get(s, color_new); if (color < 0) return color; @@ -429,7 +316,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram } else if (dither == DITHERING_HECKBERT) { const int right = x < w - 1, down = y < h - 1; - const int color = get_dst_color_err(s, src[x], &er, &eg, &eb, search_method); + const int color = get_dst_color_err(s, src[x], &er, &eg, &eb); if (color < 0) return color; @@ -441,7 +328,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram } else if (dither == DITHERING_FLOYD_STEINBERG) { const int right = x < w - 1, down = y < h - 1, left = x > x_start; - const int color = get_dst_color_err(s, src[x], &er, &eg, &eb, search_method); + const int color = get_dst_color_err(s, src[x], &er, &eg, &eb); if (color < 0) return color; @@ -455,7 +342,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram } else if (dither == DITHERING_SIERRA2) { const int right = x < w - 1, down = y < h - 1, left = x > x_start; const int right2 = x < w - 2, left2 = x > x_start + 1; - const int color = get_dst_color_err(s, src[x], &er, &eg, &eb, search_method); + const int color = get_dst_color_err(s, src[x], &er, &eg, &eb); if (color < 0) return color; @@ -474,7 +361,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram } else if (dither == DITHERING_SIERRA2_4A) { const int right = x < w - 1, down = y < h - 1, left = x > x_start; - const int color = get_dst_color_err(s, src[x], &er, &eg, &eb, search_method); + const int color = get_dst_color_err(s, src[x], &er, &eg, &eb); if (color < 0) return color; @@ -485,7 +372,7 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram if ( down) src[src_linesize + x ] = dither_color(src[src_linesize + x ], er, eg, eb, 1, 2); } else { - const int color = color_get(s, src[x], search_method); + const int color = color_get(s, src[x]); if (color < 0) return color; @@ -551,35 +438,6 @@ static int disp_tree(const struct color_node *node, const char *fname) return 0; } -static int debug_accuracy(const struct color_node *node, const uint32_t *palette, const int trans_thresh, - const enum color_search_method search_method) -{ - int r, g, b, ret = 0; - - for (r = 0; r < 256; r++) { - for (g = 0; g < 256; g++) { - for (b = 0; b < 256; b++) { - const struct color_info target = get_color_from_srgb(0xff000000 | r<<16 | g<<8 | b); - const int r1 = COLORMAP_NEAREST(search_method, palette, node, &target, trans_thresh); - const int r2 = colormap_nearest_bruteforce(palette, &target, trans_thresh); - if (r1 != r2) { - const struct color_info pal_c1 = get_color_from_srgb(0xff000000 | palette[r1]); - const struct color_info pal_c2 = get_color_from_srgb(0xff000000 | palette[r2]); - const int d1 = diff(&pal_c1, &target, trans_thresh); - const int d2 = diff(&pal_c2, &target, trans_thresh); - if (d1 != d2) { - av_log(NULL, AV_LOG_ERROR, - "/!\\ %02X%02X%02X: %d ! %d (%06"PRIX32" ! %06"PRIX32") / dist: %d ! %d\n", - r, g, b, r1, r2, pal_c1.srgb & 0xffffff, pal_c2.srgb & 0xffffff, d1, d2); - ret = 1; - } - } - } - } - } - return ret; -} - struct color { struct Lab value; uint8_t pal_id; @@ -746,11 +604,6 @@ static void load_colormap(PaletteUseContext *s) if (s->dot_filename) disp_tree(s->map, s->dot_filename); - - if (s->debug_accuracy) { - if (!debug_accuracy(s->map, s->palette, s->trans_thresh, s->color_search_method)) - av_log(NULL, AV_LOG_INFO, "Accuracy check passed\n"); - } } static void debug_mean_error(PaletteUseContext *s, const AVFrame *in1, @@ -1009,38 +862,27 @@ static int load_apply_palette(FFFrameSync *fs) return ff_filter_frame(ctx->outputs[0], out); } -#define DEFINE_SET_FRAME(color_search, name, value) \ +#define DEFINE_SET_FRAME(name, value) \ static int set_frame_##name(PaletteUseContext *s, AVFrame *out, AVFrame *in, \ int x_start, int y_start, int w, int h) \ { \ - return set_frame(s, out, in, x_start, y_start, w, h, value, color_search); \ -} - -#define DEFINE_SET_FRAME_COLOR_SEARCH(color_search, color_search_macro) \ - DEFINE_SET_FRAME(color_search_macro, color_search##_##none, DITHERING_NONE) \ - DEFINE_SET_FRAME(color_search_macro, color_search##_##bayer, DITHERING_BAYER) \ - DEFINE_SET_FRAME(color_search_macro, color_search##_##heckbert, DITHERING_HECKBERT) \ - DEFINE_SET_FRAME(color_search_macro, color_search##_##floyd_steinberg, DITHERING_FLOYD_STEINBERG) \ - DEFINE_SET_FRAME(color_search_macro, color_search##_##sierra2, DITHERING_SIERRA2) \ - DEFINE_SET_FRAME(color_search_macro, color_search##_##sierra2_4a, DITHERING_SIERRA2_4A) \ - -DEFINE_SET_FRAME_COLOR_SEARCH(nns_iterative, COLOR_SEARCH_NNS_ITERATIVE) -DEFINE_SET_FRAME_COLOR_SEARCH(nns_recursive, COLOR_SEARCH_NNS_RECURSIVE) -DEFINE_SET_FRAME_COLOR_SEARCH(bruteforce, COLOR_SEARCH_BRUTEFORCE) - -#define DITHERING_ENTRIES(color_search) { \ - set_frame_##color_search##_none, \ - set_frame_##color_search##_bayer, \ - set_frame_##color_search##_heckbert, \ - set_frame_##color_search##_floyd_steinberg, \ - set_frame_##color_search##_sierra2, \ - set_frame_##color_search##_sierra2_4a, \ -} - -static const set_frame_func set_frame_lut[NB_COLOR_SEARCHES][NB_DITHERING] = { - DITHERING_ENTRIES(nns_iterative), - DITHERING_ENTRIES(nns_recursive), - DITHERING_ENTRIES(bruteforce), + return set_frame(s, out, in, x_start, y_start, w, h, value); \ +} + +DEFINE_SET_FRAME(none, DITHERING_NONE) +DEFINE_SET_FRAME(bayer, DITHERING_BAYER) +DEFINE_SET_FRAME(heckbert, DITHERING_HECKBERT) +DEFINE_SET_FRAME(floyd_steinberg, DITHERING_FLOYD_STEINBERG) +DEFINE_SET_FRAME(sierra2, DITHERING_SIERRA2) +DEFINE_SET_FRAME(sierra2_4a, DITHERING_SIERRA2_4A) + +static const set_frame_func set_frame_lut[NB_DITHERING] = { + set_frame_none, + set_frame_bayer, + set_frame_heckbert, + set_frame_floyd_steinberg, + set_frame_sierra2, + set_frame_sierra2_4a, }; static int dither_value(int p) @@ -1060,7 +902,7 @@ static av_cold int init(AVFilterContext *ctx) if (!s->last_in || !s->last_out) return AVERROR(ENOMEM); - s->set_frame = set_frame_lut[s->color_search_method][s->dither]; + s->set_frame = set_frame_lut[s->dither]; if (s->dither == DITHERING_BAYER) { int i; From patchwork Tue Dec 27 23:18:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39794 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762754pzb; Tue, 27 Dec 2022 15:22:31 -0800 (PST) X-Google-Smtp-Source: AMrXdXu78Vurz82QtBZQ+CmtO7PG4fzDLhWVXcpci1T3REeM1nidmPlN85ECSnX6QEPwsAT46rKU X-Received: by 2002:a17:906:2b16:b0:81b:f931:cb08 with SMTP id a22-20020a1709062b1600b0081bf931cb08mr24316403ejg.47.1672183351131; Tue, 27 Dec 2022 15:22:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183351; cv=none; d=google.com; s=arc-20160816; b=f0sbH4vtF9l6oDfDnxf9QqxXMwlYMqerGos9as4LwvQ+DZeNM12ivXAxhLwlSIC3wp V936lxJMuAXxk0VPa+uwQHCja3qYBDqRqgeXy2NQI9jGFKKUfHA2xk90qCFjItM76ogW RmFLT6vmVuTHqUvnNFFfPW4vrwYfe+0SjyiZx2kKPHhWt7fdCttR9am1TZWuc9f4j+OA Bb11ZgXnx6OtMIefx0/mb3mH2Fkg7phJ/I96+N3n0lt9Pm73MwthFqZiCwgiir+nAQMA y5XQ1x31hJvubDwClmNH5OHxDl6cuNdDEAABWb1lIwBcvTgffh1VV3dBWt+LVBAr+Y1d 9d4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=6pUNsUhNj91/8nIBK/fFvorcn7o5evfbRKEf7k6USwA=; b=0mibwYycmW85OrqwonYAWeblUPgC09E4a02pUeF74cGtQAY5+pGH9svVEkhQ9nS3lw 1Kivc1Kjm2HzXqoh2QIY0x2nxjajuW0QDCwbe+hDQRj5zsXa3tz+GHs2ZfRVB6y8ShqJ c9nVt4xAmFjWR/MeKxzeyqRmA+6vllW8qdls+T5nGTkqYC2mXeyuZyCt+o5rEaoE8Uyj Uia7hrMtzwDD1aEkrzRbxbmP7V18r+7lJlLB1/XZgDYnsHMtOAnI/AIZRYvKSzBdVw46 1kkYGKTUo+N3Vw+1UtWkyIVqes7mSanqYRo/zFkbgJ1+eSayW9pZsuQQlu7CzqUUMMIt r5+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=LLqTrkLI; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id be3-20020a1709070a4300b007c0b79e51casi11384617ejc.726.2022.12.27.15.22.30; Tue, 27 Dec 2022 15:22:31 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=LLqTrkLI; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D328168BD8F; Wed, 28 Dec 2022 01:18:56 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AC0AE68BD0B for ; Wed, 28 Dec 2022 01:18:36 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3X3jlcSGUzRdsa6pkJ5inX3PHHvgXXbK88whrheEd2s=; b=LLqTrkLI+zqB/I9hXL+6bkuu6FzXGM6Y6L9w+Uc56M7079j7FUKnGIVqxapNYDuY1q7I7J aMG7UqecKjZBNWxTfLVEk5oAoJ4m4gurf55IwYoezB5eX2GQTB+WrdgsZBTso0j9a5G2UJ JZDoFXMNuGGP6APWgsxzirLNMhhOWjM= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id edf66a03; Tue, 27 Dec 2022 23:18:20 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:12 +0100 Message-Id: <20221227231814.2520181-31-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 30/32] avfilter/paletteuse: remove mean error tool 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: wQNlVk1kNKar This belongs in another filter. --- libavfilter/vf_paletteuse.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index 690422a842..33b8e70293 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -121,7 +121,6 @@ static const AVOption paletteuse_options[] = { /* following are the debug options, not part of the official API */ { "debug_kdtree", "save Graphviz graph of the kdtree in specified file", OFFSET(dot_filename), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS }, - { "mean_err", "compute and print mean error", OFFSET(calc_mean_err), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { NULL } }; @@ -606,34 +605,6 @@ static void load_colormap(PaletteUseContext *s) disp_tree(s->map, s->dot_filename); } -static void debug_mean_error(PaletteUseContext *s, const AVFrame *in1, - const AVFrame *in2, int frame_count) -{ - int x, y; - const uint32_t *palette = s->palette; - uint32_t *src1 = (uint32_t *)in1->data[0]; - uint8_t *src2 = in2->data[0]; - const int src1_linesize = in1->linesize[0] >> 2; - const int src2_linesize = in2->linesize[0]; - const float div = in1->width * in1->height * 3; - unsigned mean_err = 0; - - for (y = 0; y < in1->height; y++) { - for (x = 0; x < in1->width; x++) { - const struct color_info c1 = get_color_from_srgb(0xff000000 | src1[x]); - const struct color_info c2 = get_color_from_srgb(0xff000000 | palette[src2[x]]); - mean_err += diff(&c1, &c2, s->trans_thresh); - } - src1 += src1_linesize; - src2 += src2_linesize; - } - - s->total_mean_err += mean_err; - - av_log(NULL, AV_LOG_INFO, "MEP:%.3f TotalMEP:%.3f\n", - mean_err / div, s->total_mean_err / (div * frame_count)); -} - static void set_processing_window(enum diff_mode diff_mode, const AVFrame *prv_src, const AVFrame *cur_src, const AVFrame *prv_dst, AVFrame *cur_dst, @@ -759,8 +730,6 @@ static int apply_palette(AVFilterLink *inlink, AVFrame *in, AVFrame **outf) return ret; } memcpy(out->data[1], s->palette, AVPALETTE_SIZE); - if (s->calc_mean_err) - debug_mean_error(s, in, out, inlink->frame_count_out); *outf = out; return 0; } From patchwork Tue Dec 27 23:18:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39775 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762867pzb; Tue, 27 Dec 2022 15:22:48 -0800 (PST) X-Google-Smtp-Source: AMrXdXtMPHVNeeHuNliZRH26lWqSj5uMkj0mHiKPQzYI8OhefQJCBpHdwLjSd5+IcuIlcFUrVXfq X-Received: by 2002:a05:6402:28cd:b0:46c:fabc:5897 with SMTP id ef13-20020a05640228cd00b0046cfabc5897mr19003475edb.7.1672183368373; Tue, 27 Dec 2022 15:22:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183368; cv=none; d=google.com; s=arc-20160816; b=xpVaF1OWfIkVff0+KauKix08UOs3ifRBgXmWB5TJ4poP6NDWJqhJlJrO+QV098L6Rl 4Wq0xVKPvvJRn/a0O9ZPkW+iLWLe+pXQ4IrcTN3VtmWd2l6Bqnvsl/4BoY65XueDxI/2 TEUVfSSCbSGzH1RQN8VrgLwNUdkrphoXDVph+B/EM/6VVDPjlf6HkPewqjYMDg02UuXT VBJZTV9PQoyZdpjXuK0AE6VkE4XS5i1JuSrmDfZDy/07TJ3s4+xUOuYzyxe4bFSF+hLL p98djapMReN5S6gNfFP6jHiMTvTH5YdLc7J7zcRm5YD39c6iLUG1hMQZTah/8msRK9Ur P8fw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=FVjsjh6r4uOuZxLnQ49ZtYX/c7Xp73lgXkNHFnlOqLc=; b=FCxNE5N/FkAUEIa7ZKboOUlF0PhEQ8JDUsjMdLMkHtInK+mryY7CBUe4teyX3hT5/n MnXhjaZSNRh6yI5AACLgmpWC3tCPhC150UvwsjACYpSCPD0MlWKWHcVg75j7cFTEmov1 DpnssRcOEQ6YFsp8OIrJlSZ4aRinDzvXZI6fy4hQvBy7+syJP7bWNt688Ga96U44q1Zt yJvZlDibb0jXbeZkQeLl6Q/Qst8H5P1tlnjHrSIeA9XA1kS+84/G8axZK3x2K3ycNoRN 6LUcCrWY3tFV5xFCshYhoc7elEWoc7JzWR8sZ+Q/DEWHvQf4yqpRJqGaTx6SaQDICWhk R6FA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=rjhhaG5B; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id b8-20020aa7d488000000b00473d8c56c90si10571685edr.139.2022.12.27.15.22.48; Tue, 27 Dec 2022 15:22:48 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=rjhhaG5B; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 01CE668BDCA; Wed, 28 Dec 2022 01:18:59 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B93BA68BD08 for ; Wed, 28 Dec 2022 01:18:36 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MUKAZyh05rPS/aWwUSGl1sssz/Jezjhn2fajvPihBNY=; b=rjhhaG5B823cU98XjczWbvAALJOCtZbNjBx+QGKYfZ6aKz3tOCoSW+jnAiPZ9DbrLEZheY d5FacvWp0ylXQlDhqEI914HN60ORDODoF3YGJTsBDbVnQYXb4+jFpOLVLNggU+uNUVUkRn xblwzRQ0vpyNPpnJG3z9oFj6AJupLzo= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 38e30e2a; Tue, 27 Dec 2022 23:18:20 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:13 +0100 Message-Id: <20221227231814.2520181-32-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 31/32] avfilter/paletteuse: move r, g, b computation in a more local scope 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: D3KUc/dvEaWJ --- libavfilter/vf_paletteuse.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index 33b8e70293..e3462b4abb 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -262,9 +262,6 @@ static av_always_inline int color_get(PaletteUseContext *s, uint32_t color) static av_always_inline int get_dst_color_err(PaletteUseContext *s, uint32_t c, int *er, int *eg, int *eb) { - const uint8_t r = c >> 16 & 0xff; - const uint8_t g = c >> 8 & 0xff; - const uint8_t b = c & 0xff; uint32_t dstc; const int dstx = color_get(s, c); if (dstx < 0) @@ -273,6 +270,9 @@ static av_always_inline int get_dst_color_err(PaletteUseContext *s, if (dstx == s->transparency_index) { *er = *eg = *eb = 0; } else { + const uint8_t r = c >> 16 & 0xff; + const uint8_t g = c >> 8 & 0xff; + const uint8_t b = c & 0xff; *er = (int)r - (int)(dstc >> 16 & 0xff); *eg = (int)g - (int)(dstc >> 8 & 0xff); *eb = (int)b - (int)(dstc & 0xff); From patchwork Tue Dec 27 23:18:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 39796 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bc95:b0:ad:ade2:bfd2 with SMTP id fx21csp3762933pzb; Tue, 27 Dec 2022 15:22:57 -0800 (PST) X-Google-Smtp-Source: AMrXdXvQqOz5LurAHqypi1kSUnCW4CORXraAbp+OCtQ6qeIBymfmpta08rrnD0sJtm46TEExmziA X-Received: by 2002:a17:906:3095:b0:809:c1f4:ea09 with SMTP id 21-20020a170906309500b00809c1f4ea09mr18170370ejv.69.1672183377437; Tue, 27 Dec 2022 15:22:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672183377; cv=none; d=google.com; s=arc-20160816; b=QIALeRBWcWJZoa2VWY7WVEU/nDjXtMEEOrpbcuNeVnIRHYqK9tugk7U5Ka5XZj1L0Y AOd+iQYCKnFA+N7B1IgymoaFOYCBAVqBLXlDimeKA2QhJpcr8jmGqvZH2hPJIemJX+fr N/WebVH/PA2VDmJGCy98KsftAApG0LAyInpV2HaSqcFCs1TjvrZwhhfOCyk5zAr0jxk1 gM/uXeTez7SUWJ69kLiEXCJcV3+seoKLNICP36YnmFUAVRsxs+cJ9XqaArrGtz36T6+N YFYWNd5GKl1fdGBdghS/T69X66F+unESCyF9+2AxuaMSW+4hoZ2bZ3fVg1dS8YbdytL5 wQqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=bEM/JstIKpxmq+1PAjjlDWtTuo4Pl3s5BhGjjlR3L4Q=; b=GeU+4Kiqs4K6ULSBmEKJKjgD9EcYpP0Z21GxgzUnw982qP8FMn7oTi7r8EjsnMtIqU LceXthc7QnKdFDrF8y/H6HNuV0s/naHbY/yXbXTrEaN8/QreXXT/qJFAm8vSmPjo9841 7lc3QWYZKu0bDmWjqaCeFvFAakhCd0JHIG1TpjSdIvBF3Xv7wE9++rbi3BTJ5/4XQkMy iNBRA5ggA51w6anHaeIS9bCAfonPEA0ZQ1Z66Vw0wZPaFND5rx5yvmyBGO+7Z0lxU3+0 Zp8L5zcbOUa6c4mM1kcQ9mnjobzNUkWlw2b5KgLZqaeO0D6DnThu8JyfdFjTTcqAMECa xtdg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=BWM2BQ3+; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id hb8-20020a170907160800b007c1727f7c57si13021903ejc.243.2022.12.27.15.22.57; Tue, 27 Dec 2022 15:22:57 -0800 (PST) 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=@pkh.me header.s=selector1 header.b=BWM2BQ3+; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=pkh.me Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id EE62368BA11; Wed, 28 Dec 2022 01:18:59 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from ssq0.pkh.me (laubervilliers-656-1-228-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D914D68BCF1 for ; Wed, 28 Dec 2022 01:18:36 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pkh.me; s=selector1; t=1672183100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9RzDh/0Y74liWzPxY2YrTZMoNOPKNh4vBarV2+2E5Z8=; b=BWM2BQ3+5+o1CROs9+kETFz0vDj1kGIJLcU3VhgeloS7WsFC9dUjxdyEf3qeAaqivNvF8z mGlCA44rbn3Wg2HzMyxxN4NlpoaU5qt3TsmuSrYHAy/82fjJwaVRdTxPwwNLfgCuNos6XV Jcoy1d1jcCWi/qOHP1bjnsKmoEgCu4M= Received: from localhost (ssq0.pkh.me [local]) by ssq0.pkh.me (OpenSMTPD) with ESMTPA id 94b2c0f3; Tue, 27 Dec 2022 23:18:20 +0000 (UTC) From: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 28 Dec 2022 00:18:14 +0100 Message-Id: <20221227231814.2520181-33-u@pkh.me> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221227231814.2520181-1-u@pkh.me> References: <20221105152617.1809282-1-u@pkh.me> <20221227231814.2520181-1-u@pkh.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 32/32] avfilter/palette{gen, use}: misc for-loop cosmetics 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: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: hqyhbVp9/kGI --- libavfilter/vf_palettegen.c | 19 +++++++++---------- libavfilter/vf_paletteuse.c | 22 +++++++++------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c index 97e12f7274..4b69d3c63b 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -209,13 +209,13 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) */ static int get_next_box_id_to_split(PaletteGenContext *s) { - int box_id, best_box_id = -1; + int best_box_id = -1; int64_t max_score = -1; if (s->nb_boxes == s->max_colors - s->reserve_transparent) return -1; - for (box_id = 0; box_id < s->nb_boxes; box_id++) { + for (int box_id = 0; box_id < s->nb_boxes; box_id++) { const struct range_box *box = &s->boxes[box_id]; if (s->boxes[box_id].len >= 2 && box->cut_score > max_score) { best_box_id = box_id; @@ -250,13 +250,13 @@ static void split_box(PaletteGenContext *s, struct range_box *box, int n) static void write_palette(AVFilterContext *ctx, AVFrame *out) { const PaletteGenContext *s = ctx->priv; - int x, y, box_id = 0; + int box_id = 0; uint32_t *pal = (uint32_t *)out->data[0]; const int pal_linesize = out->linesize[0] >> 2; uint32_t last_color = 0; - for (y = 0; y < out->height; y++) { - for (x = 0; x < out->width; x++) { + for (int y = 0; y < out->height; y++) { + for (int x = 0; x < out->width; x++) { if (box_id < s->nb_boxes) { pal[x] = s->boxes[box_id++].color; if ((x || y) && pal[x] == last_color) @@ -282,16 +282,16 @@ static void write_palette(AVFilterContext *ctx, AVFrame *out) */ static struct color_ref **load_color_refs(const struct hist_node *hist, int nb_refs) { - int i, j, k = 0; + int k = 0; struct color_ref **refs = av_malloc_array(nb_refs, sizeof(*refs)); if (!refs) return NULL; - for (j = 0; j < HIST_SIZE; j++) { + for (int j = 0; j < HIST_SIZE; j++) { const struct hist_node *node = &hist[j]; - for (i = 0; i < node->nb_entries; i++) + for (int i = 0; i < node->nb_entries; i++) refs[k++] = &node->entries[i]; } @@ -391,12 +391,11 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) */ static int color_inc(struct hist_node *hist, uint32_t color) { - int i; const uint32_t hash = ff_lowbias32(color) & (HIST_SIZE - 1); struct hist_node *node = &hist[hash]; struct color_ref *e; - for (i = 0; i < node->nb_entries; i++) { + for (int i = 0; i < node->nb_entries; i++) { e = &node->entries[i]; if (e->color == color) { e->count++; diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index e3462b4abb..33d0b0e722 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -231,7 +231,6 @@ struct stack_node { */ static av_always_inline int color_get(PaletteUseContext *s, uint32_t color) { - int i; struct color_info clrinfo; const uint32_t hash = ff_lowbias32(color) & (CACHE_SIZE - 1); struct cache_node *node = &s->cache[hash]; @@ -242,7 +241,7 @@ static av_always_inline int color_get(PaletteUseContext *s, uint32_t color) return s->transparency_index; } - for (i = 0; i < node->nb_entries; i++) { + for (int i = 0; i < node->nb_entries; i++) { e = &node->entries[i]; if (e->color == color) return e->pal_entry; @@ -284,7 +283,6 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram int x_start, int y_start, int w, int h, enum dithering_mode dither) { - int x, y; const int src_linesize = in ->linesize[0] >> 2; const int dst_linesize = out->linesize[0]; uint32_t *src = ((uint32_t *)in ->data[0]) + y_start*src_linesize; @@ -293,8 +291,8 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram w += x_start; h += y_start; - for (y = y_start; y < h; y++) { - for (x = x_start; x < w; x++) { + for (int y = y_start; y < h; y++) { + for (int x = x_start; x < w; x++) { int er, eg, eb; if (dither == DITHERING_BAYER) { @@ -467,7 +465,7 @@ static int get_next_color(const uint8_t *color_used, const uint32_t *palette, int *component, const struct color_rect *box) { int wL, wa, wb; - int i, longest = 0; + int longest = 0; unsigned nb_color = 0; struct color_rect ranges; struct color tmp_pal[256]; @@ -476,7 +474,7 @@ static int get_next_color(const uint8_t *color_used, const uint32_t *palette, ranges.min[0] = ranges.min[1] = ranges.min[2] = 0xffff; ranges.max[0] = ranges.max[1] = ranges.max[2] = -0xffff; - for (i = 0; i < AVPALETTE_COUNT; i++) { + for (int i = 0; i < AVPALETTE_COUNT; i++) { const uint32_t c = palette[i]; const uint8_t a = c >> 24; const struct Lab lab = ff_srgb_u8_to_oklab_int(c); @@ -571,7 +569,7 @@ static int cmp_pal_entry(const void *a, const void *b) static void load_colormap(PaletteUseContext *s) { - int i, nb_used = 0; + int nb_used = 0; uint8_t color_used[AVPALETTE_COUNT] = {0}; uint32_t last_color = 0; struct color_rect box; @@ -583,7 +581,7 @@ static void load_colormap(PaletteUseContext *s) /* disable transparent colors and dups */ qsort(s->palette, AVPALETTE_COUNT-(s->transparency_index >= 0), sizeof(*s->palette), cmp_pal_entry); - for (i = 0; i < AVPALETTE_COUNT; i++) { + for (int i = 0; i < AVPALETTE_COUNT; i++) { const uint32_t c = s->palette[i]; if (i != 0 && c == last_color) { color_used[i] = 1; @@ -874,10 +872,9 @@ static av_cold int init(AVFilterContext *ctx) s->set_frame = set_frame_lut[s->dither]; if (s->dither == DITHERING_BAYER) { - int i; const int delta = 1 << (5 - s->bayer_scale); // to avoid too much luma - for (i = 0; i < FF_ARRAY_ELEMS(s->ordered_dither); i++) + for (int i = 0; i < FF_ARRAY_ELEMS(s->ordered_dither); i++) s->ordered_dither[i] = (dither_value(i) >> s->bayer_scale) - delta; } @@ -892,11 +889,10 @@ static int activate(AVFilterContext *ctx) static av_cold void uninit(AVFilterContext *ctx) { - int i; PaletteUseContext *s = ctx->priv; ff_framesync_uninit(&s->fs); - for (i = 0; i < CACHE_SIZE; i++) + for (int i = 0; i < CACHE_SIZE; i++) av_freep(&s->cache[i].entries); av_frame_free(&s->last_in); av_frame_free(&s->last_out);