Re: [FFmpeg-devel] [PATCH 12/15] avfilter/palettegen: base split decision on a perceptual model

2022-12-27 Thread Clément Bœsch
On Sat, Nov 05, 2022 at 08:07:42PM +0100, Andreas Rheinhardt wrote:
[...]
> You are adding floating point to places where there was no floating
> point before (some other patches of this patchset do the same). Is this
> still bitexact across all supported arches?

It should be good with the last iteration I just submitted.

Regards,

-- 
Clément B.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 12/15] avfilter/palettegen: base split decision on a perceptual model

2022-11-08 Thread Clément Bœsch
On Sat, Nov 05, 2022 at 08:07:42PM +0100, Andreas Rheinhardt wrote:
[...]
> You are adding floating point to places where there was no floating
> point before (some other patches of this patchset do the same). Is this
> still bitexact across all supported arches?
> https://patchwork.ffmpeg.org/project/ffmpeg/patch/20221105152617.1809282-1...@pkh.me/
> makes me believe that the answer is no.

Oof I completely forgot about that, you're right. I'm working on a
bitexact version right now, we should be ready soon™. It may also address
partially the performance issue.

Thanks for pointing this out!

Regards,

-- 
Clément B.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 12/15] avfilter/palettegen: base split decision on a perceptual model

2022-11-05 Thread Andreas Rheinhardt
Clément Bœsch:
> 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| 79 --
>  tests/ref/fate/filter-palettegen-1 |  2 +-
>  tests/ref/fate/filter-palettegen-2 |  2 +-
>  4 files changed, 44 insertions(+), 41 deletions(-)
> 
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index e6b6d59d2d..0a31b76c6a 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -401,7 +401,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 b8e4463539..4c2bcba7f7 100644
> --- a/libavfilter/vf_palettegen.c
> +++ b/libavfilter/vf_palettegen.c
> @@ -23,6 +23,8 @@
>   * Generate one palette for a whole video stream.
>   */
>  
> +#include 
> +
>  #include "libavutil/avassert.h"
>  #include "libavutil/internal.h"
>  #include "libavutil/opt.h"
> @@ -35,13 +37,14 @@
>  /* Reference a color and how much it's used */
>  struct color_ref {
>  uint32_t color;
> +struct Lab lab;
>  uint64_t count;
>  };
>  
>  /* Store a range of colors */
>  struct range_box {
>  uint32_t color; // average color
> -int64_t variance;   // overall variance of the box (how much the colors 
> are spread)
> +double variance;// overall variance of the box (how much the colors 
> are spread)
>  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)
> @@ -109,20 +112,19 @@ static int query_formats(AVFilterContext *ctx)
>  
>  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_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(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};
>  
>  /**
>   * Simple color comparison for sorting the final palette
> @@ -134,19 +136,19 @@ 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)
> +static av_always_inline float 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;
> +const struct Lab lab0 = ff_srgb_u8_to_oklab(a);
> +const struct Lab lab1 = ff_srgb_u8_to_oklab(b);
> +const float dL = lab0.L - lab1.L;
> +const float da = lab0.a - lab1.a;
> +const float db = lab0.b - lab1.b;
> +return dL*dL + da*da + db*db;
>  }
>  
>  static void compute_box_variance(PaletteGenContext *s, struct range_box *box)
>  {
> -int64_t variance = 0;
> +double variance = 0.0;
>  
>  for (int i = 0; i < box->len; i++) {
>  const struct color_ref *ref = s->refs[box->start + i];
> @@ -179,7 +181,7 @@ static void compute_box_variance(PaletteGenContext *s, 
> struct range_box *box)
>  static int get_next_box_id_to_split(PaletteGenContext *s)
>  {
>  int box_id, best_box_id = -1;
> -int64_t max_variance = -1;
> +double max_variance = -1.0;
>  
>  if (s->nb_boxes == s->max_colors - s->reserve_transparent)
>  return -1;
> @@ -188,14 +190,14 @@ static int get_next_box_id_to_split(PaletteGenContext 
> *s)
>  struct range_box *box = >boxes[box_id];
>  
>  if