Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How were the default AVIF quality and effort settings chosen? #4227

Open
eeeps opened this issue Oct 2, 2024 · 5 comments
Open

How were the default AVIF quality and effort settings chosen? #4227

eeeps opened this issue Oct 2, 2024 · 5 comments
Labels

Comments

@eeeps
Copy link

eeeps commented Oct 2, 2024

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.avifcompared to original
Custom settings (quality 70, effort 7): https://o.img.rodeo/vahj96nhy8xchvlodlbo.avifcompared to original

@eeeps eeeps added the question label Oct 2, 2024
@eeeps eeeps changed the title How were the AVIF quality and effort settings chosen? How were the default AVIF quality and effort settings chosen? Oct 2, 2024
@lovell
Copy link
Owner

lovell commented Oct 3, 2024

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.

@eeeps
Copy link
Author

eeeps commented Oct 3, 2024

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.

@lovell
Copy link
Owner

lovell commented Oct 3, 2024

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?

@eeeps
Copy link
Author

eeeps commented Oct 3, 2024

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.

@lovell
Copy link
Owner

lovell commented Oct 29, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants
@lovell @eeeps and others