SDL_image icon indicating copy to clipboard operation
SDL_image copied to clipboard

Build libavif with encoding support on Windows

Open slouken opened this issue 1 year ago • 33 comments

I'd like to add support for saving images as AVIF. Could you rebuild libavif with encoder support?

slouken avatar Jan 24 '24 04:01 slouken

You have to choose an encoder backend:

  • rav1e: https://github.com/xiph/rav1e, encoder-only, BSD 2-Clause License, requires rust compiler which I don't have
  • aom: encoder and decoder, https://aomedia.googlesource.com/aom, , BSD 2-Clause License
  • svt-av1: encoder and decoder, https://gitlab.com/AOMediaCodec/SVT-AV1, BSD-3-clause clear license

EDIT: I guess aom should be the choice, but you decide.

Either way, the dlls will noticeably increase in size

Apart from them, do you require libyuv support in libavif? (https://chromium.googlesource.com/libyuv/libyuv/, C++)

sezero avatar Jan 24 '24 05:01 sezero

I think aom is the way to go. The HDR cases are not in the libyuv fast path, but it would be a shame for us to always use the slow path.

I’ve built it here statically linked with Visual Studio and libsharpyuv and the other bells and whistles. We can use that instead, if you want.

slouken avatar Jan 24 '24 05:01 slouken

I think aom is the way to go.

OK, aom it is. We'll need to vendor it too, and drop dav1d support.

Will this be for SDL3 only?

The HDR cases are not in the libyuv fast path, but it would be a shame for us to always use the slow path.

Hmph.. Static libstdc++ bloat will be there. Will need to vendor libyuv too

I’ve built it here statically linked with Visual Studio and libsharpyuv and the other bells and whistles. We can use that instead, if you want.

In the interim maybe: those dlls will have all MSVC runtime and Win10 dll dependencies, no?

I'll try to build something using mingw later these days.

sezero avatar Jan 24 '24 05:01 sezero

Yes, SDL3 only. The static linking with VC means we don’t have runtime dependencies.

I’ll go ahead and drop in the VC libs for now. @madebr, do you want to help with the vendoringand non-Windows builds?

slouken avatar Jan 24 '24 05:01 slouken

If I remember correctly, dav1d is a faster decoder. Do we want both back ends configured?

slouken avatar Jan 24 '24 05:01 slouken

If I remember correctly, dav1d is a faster decoder. Do we want both back ends configured?

libavif allows multiple backends, don't know how it prioritizes codecs though.

sezero avatar Jan 24 '24 05:01 sezero

Here are the initial libavif dll builds with encoder support: dlls.tar.gz

Included: dav1d 1.2.1 as decoder, aom 3.6.1 as encoder, libsharpyuv from libwebp HEAD.

aom was configured without decoder support, like this:

-DENABLE_DOCS=0 -DENABLE_EXAMPLES=0 \
 -DENABLE_TESTDATA=0 -DENABLE_TESTS=0 -DENABLE_TOOLS=0 \
 -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release \
 -DCONFIG_AV1_DECODER=0 -DAOM_TARGET_CPU=x86

IIRC, the cpu target needed explicit speciying for x86 - replace with x86_64 for x86_64

I didn't bother including libyuv yet: if you want I can do that too.

The dlls are large in size even after stripping.

sezero avatar Jan 25 '24 17:01 sezero

avif has 2 configuration options to control encoding/decoding with aom: AVIF_CODEC_AOM_ENCODE and AVIF_CODEC_AOM_DECODE. Both are enabled by default. I suppose we want AVIF_CODEC_AOM_DECODE=OFF instead?

Inside avif.c, the priority is dav1d > libgav1 > aom > rav1e > svg > avm

madebr avatar Jan 25 '24 17:01 madebr

AVIF_CODEC_AOM_DECODE=OFF

Will try and get back immediately

sezero avatar Jan 25 '24 18:01 sezero

AVIF_CODEC_AOM_DECODE=OFF

Will try and get back immediately

Oops, noticed that I already disabled that option. So, these libavif builds use libaom really only for encoding

sezero avatar Jan 25 '24 18:01 sezero

Isn't that good? dav1d for decoding and aom for encoding?

madebr avatar Jan 25 '24 18:01 madebr

Isn't that good? dav1d for decoding and aom for encoding?

Yes it is, and it was the intention.

Only that I didn't expect these large dll sizes only because of aom encoder inclusion (8.9M x86 dll and 13.4M x64 dll)

sezero avatar Jan 25 '24 18:01 sezero

Off-topic: I don't seem to have write permissions to our aom fork at https://github.com/libsdl-org/aom.git

sezero avatar Jan 25 '24 18:01 sezero

Off-topic: I don't seem to have write permissions to our aom fork at https://github.com/libsdl-org/aom.git

Fixed!

slouken avatar Jan 25 '24 18:01 slouken

Only that I didn't expect these large dll sizes only because of aom encoder inclusion (8.9M x86 dll and 13.4M x64 dll)

I'm not surprised, the size of the aom encoder is pretty big. Remember these are optional DLLs, so users who don't want to include them in their project can leave them out.

slouken avatar Jan 25 '24 18:01 slouken

Only that I didn't expect these large dll sizes only because of aom encoder inclusion (8.9M x86 dll and 13.4M x64 dll)

I'm not surprised, the size of the aom encoder is pretty big. Remember these are optional DLLs, so users who don't want to include them in their project can leave them out.

OK then

sezero avatar Jan 25 '24 18:01 sezero

P.S.: We are currently vendoring aom 3.6.1, however 3.7.1+ has at least one CVE fix. I suggest upgrading to aom 3.7.2 or 3.8.1

sezero avatar Jan 25 '24 22:01 sezero

When finished, it would also be useful to test storing avif in the test. https://github.com/libsdl-org/SDL_image/blob/c9c809b3d488afbcc9d33228f0c50cc04ce4611c/test/main.c#L153

madebr avatar Jan 25 '24 23:01 madebr

P.S.: We are currently vendoring aom 3.6.1, however 3.7.1+ has at least one CVE fix. I suggest upgrading to aom 3.7.2 or 3.8.1

I used 3.6.1 because that is the version that is recommended with the libavif we're using. However, it looks like the API is pretty stable, we should be able to bump to a newer aom if we want.

slouken avatar Jan 26 '24 01:01 slouken

Now that avif save commit https://github.com/libsdl-org/SDL_image/commit/c1600c4764c39fc15d1e1a4ffabe21919ac237a7 is in, should I push the new dlls to msvc project I you aren't doing that yourself already?

sezero avatar Jan 26 '24 03:01 sezero

Sure, go for it. However I'm going to ask @madebr's help with these:

-- libavif: libyuv not found; libyuv-based fast paths disabled.
-- libavif: libsharpyuv not found

slouken avatar Jan 26 '24 03:01 slouken

Pushed https://github.com/libsdl-org/SDL_image/commit/5d95dc17826a12aa6d5ec784b3f10a1643fe7388

sezero avatar Jan 26 '24 04:01 sezero

Sure, go for it. However I'm going to ask @madebr's help with these:

-- libavif: libyuv not found; libyuv-based fast paths disabled.
-- libavif: libsharpyuv not found

libavif is looking for libyuv. Unless we force disable it, should we vendor it? It's c++ with lots of intrinsics.

madebr avatar Jan 26 '24 20:01 madebr

I think we can vendor it. We already have libsharpyuv in webp.

slouken avatar Jan 26 '24 20:01 slouken

libavif HEAD has inlined a very crippled version of libyuv under their 3rdparty directory without any cpu optimizations: We can do something similar if necessary with cpu optimizations included? And as a matter of fact most of libyuv can actually be built as C-only, at least the parts that are of interest to us: libavif's own vendored version is C-only for example.

sezero avatar Jan 26 '24 21:01 sezero

The patch looks very straightforward. For libsdl-org's fork, I would just unconditionally use the "crippled version", to avoid any dependency on a system libyuv.

madebr avatar Jan 26 '24 21:01 madebr

This is done in 1d91d7e39d918b34cc540309dec18e6df578a7dd

madebr avatar Jan 26 '24 22:01 madebr

I made a libyuv fork and created a branch for C-only build -- here if interested: https://github.com/sezero/libyuv/tree/sezero

sezero avatar Jan 27 '24 11:01 sezero

Untested, but with set_source_files_properties(${sources} PROPERTIES LANGUAGE C), you can override CMake's automatic language detection.

madebr avatar Jan 27 '24 11:01 madebr

Untested, but with set_source_files_properties(${sources} PROPERTIES LANGUAGE C), you can override CMake's automatic language detection.

OK, learnt something new about cmake - thanks.

sezero avatar Jan 27 '24 12:01 sezero