From: "Clément Bœsch" <u@pkh.me> To: ffmpeg-devel@ffmpeg.org Cc: "Clément Bœsch" <u@pkh.me> Subject: [FFmpeg-devel] [PATCH v2 22/32] avfilter/palettegen: make refs order deterministic Date: Wed, 28 Dec 2022 00:18:04 +0100 Message-ID: <20221227231814.2520181-23-u@pkh.me> (raw) In-Reply-To: <20221227231814.2520181-1-u@pkh.me> 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 -- 2.39.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2022-12-27 23:21 UTC|newest] Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-11-05 15:26 [FFmpeg-devel] Rework color quantization in palette{gen,use} Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 01/15] Revert "avfilter/vf_palette(gen|use): support palettes with alpha" Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 02/15] avfilter: add palette utils Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 03/15] avfilter/palette{use, gen}: simplify a few alpha masks Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 04/15] avfilter/paletteuse: switch from u8[4] to u32 for color code Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 05/15] avfilter/paletteuse: name target color arg consistently in colormap functions Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 06/15] avfilter/paletteuse: remove unused alpha split dimension Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 07/15] avfilter/paletteuse: remove redundant alpha condition Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 08/15] avfilter/paletteuse: switch to a perceptual model Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 09/15] avfilter/palettegen: average color in linear space Clément Bœsch 2022-11-05 15:39 ` Paul B Mahol 2022-11-05 18:50 ` Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 10/15] avfilter/palettegen: move box variance computation in a dedicated function Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 11/15] avfilter/palettegen: comment on the unnormalized variance Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 12/15] avfilter/palettegen: base split decision on a perceptual model Clément Bœsch 2022-11-05 19:07 ` Andreas Rheinhardt 2022-11-08 21:09 ` Clément Bœsch 2022-12-27 23:20 ` Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 13/15] avfilter/palettegen: use variance per-axis instead of the range Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 14/15] avfilter/palettegen: rename longest to split_axis Clément Bœsch 2022-11-05 15:26 ` [FFmpeg-devel] [PATCH 15/15] avfilter/palette{use, gen}: update Copyright after recent changes Clément Bœsch 2022-11-05 15:44 ` [FFmpeg-devel] Rework color quantization in palette{gen,use} Paul B Mahol 2022-11-05 18:54 ` Clément Bœsch 2022-11-06 13:19 ` Ronald S. Bultje 2022-11-08 21:22 ` Clément Bœsch 2022-11-05 21:52 ` Soft Works 2022-11-06 17:09 ` Michael Niedermayer 2022-11-06 17:30 ` Michael Niedermayer 2022-11-08 21:14 ` Clément Bœsch 2022-12-31 12:11 ` Clément Bœsch 2023-01-02 21:57 ` Michael Niedermayer 2023-01-02 23:05 ` Clément Bœsch 2023-01-03 18:50 ` Michael Niedermayer 2022-11-06 19:46 ` Soft Works 2022-11-08 21:07 ` Clément Bœsch 2022-11-08 22:37 ` Soft Works 2022-12-27 23:31 ` Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] New iteration for the color quantization in palette{gen, use} Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 01/32] avfilter/palettegen: allow a minimum of 2 colors Clément Bœsch 2022-12-28 21:04 ` Tomas Härdin 2022-12-28 21:23 ` Clément Bœsch 2023-01-03 18:59 ` Tomas Härdin 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 02/32] avfilter/palette{gen, use}: revert support palettes with alpha Clément Bœsch 2023-01-03 19:11 ` Paul B Mahol 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 03/32] avfilter/palette{gen, use}: simplify a few alpha masks Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 04/32] avfilter/palette{gen, use}: add palette utils Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 05/32] avfilter/paletteuse: switch from u8[4] to u32 for color code Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 06/32] avfilter/paletteuse: name target color arg consistently in colormap functions Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 07/32] avfilter/paletteuse: remove unused alpha split dimension Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 08/32] avfilter/paletteuse: remove redundant alpha condition Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 09/32] avfilter/paletteuse: switch to a perceptual model Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 10/32] avfilter/palettegen: move box stats computation to a dedicated function Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 11/32] avfilter/palettegen: define the best axis to cut using the squared error Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 12/32] avfilter/palettegen: use box->major_axis without intermediate variable Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 13/32] avfilter/palettegen: always compute the box variance Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 14/32] avfilter/palettegen: rename variance to cut_score Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 15/32] avfilter/palettegen: change cut score from ∑e² to max e² Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 16/32] avfilter/palettegen: compute average color within compute_box_stats() Clément Bœsch 2022-12-27 23:17 ` [FFmpeg-devel] [PATCH v2 17/32] avfilter/palettegen: misc cosmetics Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 18/32] avfilter/palettegen: rename local variable box_weight to weight Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 19/32] avfilter/palettegen: switch to signed arithmetic Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 20/32] avfilter/palettegen: base box split decision on a perceptual model Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 21/32] avfilter/palettegen: add a warning about supporting only sRGB Clément Bœsch 2022-12-27 23:18 ` Clément Bœsch [this message] 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 23/32] avfilter/palettegen: use libc qsort Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 24/32] avfilter/palette{gen, use}: update Copyright after recent changes Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 25/32] avfilter/palette: add lowbias32 hashing Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 26/32] avfilter/palettegen: use lowbias32 for color hashing Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 27/32] avfilter/paletteuse: " Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 28/32] avfilter/paletteuse: switch to recursive method Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 29/32] avfilter/paletteuse: remove alternative search methods Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 30/32] avfilter/paletteuse: remove mean error tool Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 31/32] avfilter/paletteuse: move r, g, b computation in a more local scope Clément Bœsch 2022-12-27 23:18 ` [FFmpeg-devel] [PATCH v2 32/32] avfilter/palette{gen, use}: misc for-loop cosmetics Clément Bœsch 2023-01-03 16:28 ` [FFmpeg-devel] New iteration for the color quantization in palette{gen, use} Clément Bœsch
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20221227231814.2520181-23-u@pkh.me \ --to=u@pkh.me \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git