sharp icon indicating copy to clipboard operation
sharp copied to clipboard

How were the default AVIF quality and effort settings chosen?

Open eeeps opened this issue 1 year ago • 10 comments

Question about an existing feature

What are you trying to achieve?

I am trying to decide which AVIF quality settings to use when using https://github.com/11ty/eleventy-img/, and found that tool's defaults (which rely on Sharp's defaults) too low for my taste, for both quality and effort, in initial testing.

Before embarking on a bunch of tests, I'm looking for some context on how these scales work and how these values were chosen. For instance: is Sharp also just using libaom's defaults? (which are probably more appropriate for video than still images?).

When you searched for similar issues, what did you find that might be related?

I found a few issues where people are complaining about how expensive AVIF encoding is, and some information about how Sharp's settings map to libaom's, but nothing about how the scales work or how the defaults (which are both exactly in the middle of their range...) were chosen.

Please provide sample image(s) that help explain this question

Here's the image that caused me to want to increase the defaults when using eleventy-img (all of the texture in the dog's face-fur vanishes, and in this usage context, I care much less about build times than compression performance):

Original: https://o.img.rodeo/w_800/dogs/2.png Default settings (quality 50, effort 4): https://o.img.rodeo/w3fr2wrmmrf3pfrtmal7.avif – compared to original Custom settings (quality 70, effort 7): https://o.img.rodeo/vahj96nhy8xchvlodlbo.avif – compared to original

eeeps avatar Oct 02 '24 16:10 eeeps

Hi Eric, you've provided a great sample image here for comparing image codecs with all that fine, oblique line detail on the animal fur.

The AVIF quality value (0-100 range, worst to best) set via sharp is passed unaltered to libheif via its heif_encoder_set_lossy_quality function.

Within libheif this is mapped to libaom's "constant quality level" value (0-63 range, best to worst).

https://github.com/strukturag/libheif/blob/0a627a33d69cb5e93860536e841d23c8100f8065/libheif/plugins/encoder_aom.cc#L939

  int cq_level = ((100 - quality) * 63 + 50) / 100;

In terms of video vs still images, libheif always passes AOM_USAGE_ALL_INTRA as the "usage" preset so libaom should know it will be generating images (use intra-frame encoding, skip keyframe logic).

It's all rather CPU intensive so as you probably know AVIF remains very much a format suitable for encode-once decode-many scenarios, such as with the superb 11ty.

lovell avatar Oct 03 '24 11:10 lovell

Thank you for the prompt and super-helpful response!

Would it be accurate to say:

  1. Sharp's effort and quality defaults were chosen because they are in the middle of libheif’s exposed range for each parameter,
  2. those ranges map linearly to libaom's ranges, and
  3. libaom's ranges were designed for video use cases.

Given the existing complaints about Sharp's slow/expensive AVIF encoding, and the wide range of use cases that Sharp is used for, it probably doesn't make sense to bump Sharp's default effort parameter. It might (after some more testing) make sense to bump it downstream in eleventy-image, though.

However – if my understanding above is correct – it might make sense to bump Sharp's AVIF quality default, because still images are always going to show their artifacts more than than video frames that flash by in an instant. Or maybe the (single) image I tested with is an outlier, and the AVIFs Sharp outputs by default are mostly fine for most use cases most of the time.

eeeps avatar Oct 03 '24 14:10 eeeps

The default quality value of 50 was probably selected to match libheif's default quality value.

https://github.com/strukturag/libheif/blob/0a627a33d69cb5e93860536e841d23c8100f8065/libheif/plugins/encoder_aom.cc#L260

There was some research carried out a couple of years ago using sharp and dssim to calculate comparable "quality" settings for JPEG/WebP/AVIF.

https://www.industrialempathy.com/posts/avif-webp-quality-settings https://github.com/cramforce/avif-webp-quality-setting

Interestingly, its summary that a JPEG quality of 80 is equivalent to an AVIF quality of 64 happens to align with the "visually lossless" suggested AVIF cq-level of 23 in the ffmpeg docs at https://trac.ffmpeg.org/wiki/Encode/AV1#ConstantQuality

Given sharp's default JPEG quality is currently 80, I could definitely be persuaded to default AVIF quality to a more comparable 64. Are you able to test with some of your sample images to see if quality=64 produces results that are subjectively closer to quality=70 than quality=50?

lovell avatar Oct 03 '24 21:10 lovell

Are you able to test with some of your sample images to see if quality=64 produces results that are subjectively closer to quality=70 than quality=50?

Yes! But I'm about to leave for a week of vacation so not until I get back the week of October 14th.

eeeps avatar Oct 03 '24 21:10 eeeps

@eeeps Were you able to make any progress with this?

lovell avatar Oct 29 '24 09:10 lovell

@eeeps I'm considering a change in the default AVIF "quality" as part of the next release. Is there anything else from your research that you think might help?

lovell avatar Jan 06 '25 11:01 lovell

If you hadn't seen, libaom v3.12.0 has added a new ssimulacra2-based tuning method named iq ("image quality").

https://aomedia.googlesource.com/aom/+/refs/tags/v3.12.0

I tried using this locally to compare iq against the default ssim tuning with a few sample images and observed that iq at a "quality" of 50 produces images that are around same file size as ssim will produce with a "quality" in the 60-65 range.

It might be the case here that we leave the default "quality" at 50 but change the default tuning to the newer iq where available, which I hope could produce perceptively better images at comparable files sizes (for a given cq-level).

lovell avatar Feb 12 '25 10:02 lovell

Why don't you expose the tune parameter so users can choose it? It might be helpful in different situations.

adityapatadia avatar Feb 18 '25 09:02 adityapatadia

@lovell This is just to say,

  1. Apologies for letting this slip through the cracks
  2. ssimulacra2 is great (the author, Jon Sneyers is a colleague) and the AV1-SVT tuning for it also seems great. I was able to speak a couple of times to Gianni Rosato and Julio Barba as they developed it and it seems like they made some amazing improvements. Intuitively, and based on their tests, I would trust it to be more consistent and provide more performance than the ssim-tuning.

To check that with your own eyes, it sounds like a useful test right now would produce a couple dozen comparisons contrasting:

  1. libaom ssim tuning vs iq tuning at sharp-quality 50
  2. libaom ssim tuning vs iq tuning at sharp-quality 64

I'd probably use this set of lossless originals from Wikimedia to do it, although it's almost all photographic doesn't contain many synthetic images (screenshots, illustrations) which are also important. https://collection.cloudinary.com/eric-cloudinary/dedfc813424cc189902ce993d429f2db

eeeps avatar Mar 21 '25 23:03 eeeps

@lovell did we change the default tuning? If we want to change it, is there a way to achieve that?

adityapatadia avatar Jul 10 '25 20:07 adityapatadia