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

Update libavif #1381

Merged
merged 24 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
47f8746
Update libavif (v1.0.0-main)
aryanpingle Sep 14, 2023
f8804b1
Update libavif (v1.0.1-main)
aryanpingle Sep 15, 2023
82658c7
Refactor variable names for clarity
aryanpingle Sep 15, 2023
642ac6d
Update libaom (v3.7.0)
aryanpingle Sep 28, 2023
96da59f
Add checks for API return values
aryanpingle Oct 17, 2023
a5a3f63
Rename variables for readability
aryanpingle Oct 17, 2023
f1f4030
Minor patches in logic
aryanpingle Oct 17, 2023
3ed34e1
Minor patches in lossless calculation
aryanpingle Oct 18, 2023
625eee2
Add chroma subsampling options to AVIF
aryanpingle Oct 18, 2023
1b3f791
Add skeleton for sharp downsampling param
aryanpingle Oct 23, 2023
f27d524
Try to use libsharpyuv
surma Oct 23, 2023
47cd47e
Encoder working, decoder isnt
surma Oct 25, 2023
25ea8b9
Make sure sharpyuv is disabled for decoder
surma Oct 25, 2023
0413c66
Add AVIF_LOCAL flags for sharp yuv
aryanpingle Oct 27, 2023
ab79caf
Get AVIF sharp YUV working
aryanpingle Oct 27, 2023
41c4b30
Clean up AVIF makefiles
aryanpingle Oct 28, 2023
faa1467
AVIF: Make sharpyuv conditional on subsample
aryanpingle Oct 28, 2023
fd53823
AVIF: Flags to speed up sharpyuv build
aryanpingle Oct 30, 2023
aad51d3
AVIF: Minor refactoring in enc.cpp
aryanpingle Oct 30, 2023
699b9e0
AVIF: Minor refactoring & renaming
aryanpingle Oct 30, 2023
4cdc246
AVIF: Use smart pointers to prevent memory leaks
aryanpingle Oct 31, 2023
7099d5e
AVIF: Minor refactoring
aryanpingle Nov 3, 2023
aa89d7c
AVIF: Revert defaultoptions logic change
aryanpingle Nov 3, 2023
795e395
Merge branch 'dev' into avif-update
jakearchibald Jan 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 62 additions & 22 deletions codecs/avif/Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
# libavif and libaom versions are from
# google3/third_party/libavif/METADATA
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/647c3c208cf152395d777c1bf7240d2ecf7df5a9.tar.gz
CODEC_PACKAGE = node_modules/libavif.tar.gz
# using libavif from https://github.com/AOMediaCodec/libavif
LIBAVIF_URL = https://github.com/AOMediaCodec/libavif/archive/refs/tags/v1.0.1.tar.gz
LIBAVIF_PACKAGE = node_modules/libavif.tar.gz

LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v3.6.0.tar.gz
# using libaom from https://aomedia.googlesource.com/aom
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v3.7.0.tar.gz
LIBAOM_PACKAGE = node_modules/libaom.tar.gz

export CODEC_DIR = node_modules/libavif
export BUILD_DIR = node_modules/build
export LIBAOM_DIR = node_modules/libaom

override CFLAGS += "-Wno-unused-macros"
export

# We must build libsharpyuv from a specific libwebp commit
# See libavif/ext/libsharpyuv.cmd for more detail
LIBWEBP_URL_WITH_SHARPYUV = https://chromium.googlesource.com/webm/libwebp/+archive/e2c85878f6a33f29948b43d3492d9cdaf801aa54.tar.gz
LIBWEBP_DIR := $(CODEC_DIR)/ext/libwebp
export LIBSHARPYUV := $(LIBWEBP_DIR)/build/libsharpyuv.a

OUT_ENC_JS = enc/avif_enc.js
OUT_NODE_ENC_JS = enc/avif_node_enc.js
Expand All @@ -28,10 +33,10 @@ HELPER_MAKEFLAGS := -f helper.Makefile

.PHONY: all clean

all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS) $(OUT_NODE_ENC_JS) $(OUT_NODE_ENC_MT_JS) $(OUT_NODE_DEC_JS)
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS)

$(OUT_NODE_ENC_JS) $(OUT_NODE_ENC_MT_JS): ENVIRONMENT=node
$(OUT_NODE_ENC_JS) $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
# ST-Encoding
$(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV)
$(MAKE) \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed you pass -DCONFIG_AV1_HIGHBITDEPTH=0 to libaom (e.g., in line 47). Do you only support bit depth 8 when encoding AVIF?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, for all codecs on Squoosh.

$(HELPER_MAKEFLAGS) \
OUT_JS=$@ \
Expand All @@ -42,9 +47,10 @@ $(OUT_NODE_ENC_JS) $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(L
-DCONFIG_AV1_HIGHBITDEPTH=0 \
" \
ENVIRONMENT=$(ENVIRONMENT) \
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0"
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0 -DAVIF_LOCAL_LIBSHARPYUV=ON"

$(OUT_ENC_MT_JS) $(OUT_NODE_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
# MT-Encoding
$(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV)
$(MAKE) \
$(HELPER_MAKEFLAGS) \
OUT_JS=$@ \
Expand All @@ -54,11 +60,11 @@ $(OUT_ENC_MT_JS) $(OUT_NODE_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.t
-DCONFIG_AV1_HIGHBITDEPTH=0 \
" \
ENVIRONMENT=$(ENVIRONMENT) \
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0" \
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0 -DAVIF_LOCAL_LIBSHARPYUV=ON" \
OUT_FLAGS="-pthread"

$(OUT_NODE_DEC_JS): ENVIRONMENT=node
$(OUT_NODE_DEC_JS) $(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
# Decoding
$(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
$(MAKE) \
$(HELPER_MAKEFLAGS) \
OUT_JS=$@ \
Expand All @@ -68,24 +74,58 @@ $(OUT_NODE_DEC_JS) $(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(L
-DCONFIG_MULTITHREAD=0 \
" \
ENVIRONMENT=$(ENVIRONMENT) \
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_ENCODE=0"
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_ENCODE=0 -DAVIF_LOCAL_LIBSHARPYUV=ON"

aryanpingle marked this conversation as resolved.
Show resolved Hide resolved
$(CODEC_PACKAGE):
mkdir -p $(@D)
curl -sL $(CODEC_URL) -o $@
# LIBAOM EXTRACTION SECTION

# Download the libaom tarball
$(LIBAOM_PACKAGE):
mkdir -p $(@D)
curl -sL $(LIBAOM_URL) -o $@

$(CODEC_DIR)/CMakeLists.txt: $(CODEC_PACKAGE)
mkdir -p $(@D)
tar xzm --strip 1 -C $(@D) -f $(CODEC_PACKAGE)

# Extract libaom from the tarball
$(LIBAOM_DIR)/CMakeLists.txt: $(LIBAOM_PACKAGE)
mkdir -p $(@D)
tar xzm -C $(@D) -f $(LIBAOM_PACKAGE)

# LIBAVIF EXTRACTION SECTION

# Download the libavif tarball
$(LIBAVIF_PACKAGE):
mkdir -p $(@D)
curl -sL $(LIBAVIF_URL) -o $@

# Extract libavif from the tarball
$(CODEC_DIR)/CMakeLists.txt: $(LIBAVIF_PACKAGE)
mkdir -p $(@D)
tar xzm --strip 1 -C $(@D) -f $(LIBAVIF_PACKAGE)

# Create libavif/ext/libwebp
$(LIBWEBP_DIR)/CMakeLists.txt: $(CODEC_DIR)/CMakeLists.txt
mkdir -p $(LIBWEBP_DIR)
curl -sL $(LIBWEBP_URL_WITH_SHARPYUV) \
| tar xzm -C $(LIBWEBP_DIR)

# Make libsharpyuv.a
$(LIBSHARPYUV): $(LIBWEBP_DIR)/CMakeLists.txt
mkdir -p $(@D)
emcmake cmake \
-DWEBP_BUILD_ANIM_UTILS=OFF \
-DWEBP_BUILD_CWEBP=OFF \
-DWEBP_BUILD_DWEBP=OFF \
-DWEBP_BUILD_GIF2WEBP=OFF \
-DWEBP_BUILD_IMG2WEBP=OFF \
-DWEBP_BUILD_VWEBP=OFF \
-DWEBP_BUILD_WEBPINFO=OFF \
-DWEBP_BUILD_LIBWEBPMUX=OFF \
-DWEBP_BUILD_WEBPMUX=OFF \
-DWEBP_BUILD_EXTRAS=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_BUILD_TYPE=Release \
-S $(LIBWEBP_DIR) \
aryanpingle marked this conversation as resolved.
Show resolved Hide resolved
-B $(@D)
$(MAKE) -C $(@D) sharpyuv

clean:
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_JS) clean
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_MT_JS) clean
Expand Down
2 changes: 1 addition & 1 deletion codecs/avif/dec/avif_dec.js

Large diffs are not rendered by default.

Binary file modified codecs/avif/dec/avif_dec.wasm
Binary file not shown.
Binary file modified codecs/avif/dec/avif_node_dec.wasm
Binary file not shown.
105 changes: 66 additions & 39 deletions codecs/avif/enc/avif_enc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,31 @@
#include <emscripten/val.h>
#include "avif/avif.h"

#include <string>
aryanpingle marked this conversation as resolved.
Show resolved Hide resolved

#define RETURN_NULL_IF_NOT_EQUALS(val1, val2) \
do { \
if (val1 != val2) \
return val::null(); \
} while (false)
#define RETURN_NULL_IF_EQUALS(val1, val2) \
do { \
if (val1 == val2) \
return val::null(); \
} while (false)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: You can merge these two macros into RETURN_NULL_IF_FALSE that takes a conditional expression as the argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's so much better than the current macro LOL, thank you!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I probably would not use a macro that saves only one line. But some people like to use this kind of macro so that the main flow of the code is not cluttered with error handling code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep that was my line of thinking. I'm pretty sure we'll be repeating that line again for other optimizations, so it's better to just have a macro for it.


using namespace emscripten;

using AvifImagePtr = std::unique_ptr<avifImage, decltype(&avifImageDestroy)>;
using AvifEncoderPtr = std::unique_ptr<avifEncoder, decltype(&avifEncoderDestroy)>;

struct AvifOptions {
// [0 - 63]
// 0 = lossless
// 63 = worst quality
int cqLevel;
// As above, but -1 means 'use cqLevel'
int cqAlphaLevel;
// [0 - 100]
// 0 = worst quality
// 100 = lossless
aryanpingle marked this conversation as resolved.
Show resolved Hide resolved
aryanpingle marked this conversation as resolved.
Show resolved Hide resolved
aryanpingle marked this conversation as resolved.
Show resolved Hide resolved
aryanpingle marked this conversation as resolved.
Show resolved Hide resolved
int quality;
// As above, but -1 means 'use quality'
int qualityAlpha;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a follow-up pull request, we should look into using the new autoTiling option of the AVIF encoder.

I suggest Squoosh set autoTiling to AVIF_TRUE by default. (The default of autoTiling in libavif is AVIF_FALSE for backward compatibility.) The Squoosh UI can have a "manual tiling" box, which when checked, shows the tileRowsLog2 and tileColsLog2 fields (both default to 0, meaning no tiling).

Copy link
Contributor Author

@aryanpingle aryanpingle Nov 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, I'll try to add it to this PR or at least make raise an issue for it. I assume autoTiling automatically chooses the best tileRowsLog2 and tileColsLog2, is there any more documentation about it that I can link to?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless this requires just simple changes, I suggest filing an issue for this and implementing this in a follow-up pull request. The review of this pull request has been going on for a while. We need to watch out for "code review fatigue."

You understand autoTiling correctly. The autoTiling algorithm may be tweaked in the future, so we didn't document the current algorithm in the public header avif/avif.h. You can find the current algorithm in libavif/src/write.c:

    if (encoder->autoTiling) {
        // Use as many tiles as allowed by the minimum tile area requirement and impose a maximum
        // of 8 tiles.
        const int threads = 8;
        avifSetTileConfiguration(threads, firstCell->width, firstCell->height, &encoder->data->tileRowsLog2, &encoder->data->tileColsLog2);
    }

I do think all the automatic tiling algorithms have some common elements, such as imposing a minimum tile area or tile width and height, and potentially imposing a maximum number of tiles. But I am not sure if you need to mention this. You can, however, say that the use of tiles makes it easier for the decoder to decode an AVIF image with multiple threads in parallel.

// [0 - 6]
// Creates 2^n tiles in that dimension
int tileRowsLog2;
Expand All @@ -35,11 +51,15 @@ struct AvifOptions {
int tune;
// 0-50
int denoiseLevel;
// toggles AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV
bool enableSharpYUV;
};

thread_local const val Uint8Array = val::global("Uint8Array");

val encode(std::string buffer, int width, int height, AvifOptions options) {
avifResult status; // To check the return status for avif API's

avifRWData output = AVIF_DATA_EMPTY;
int depth = 8;
avifPixelFormat format;
Expand All @@ -58,11 +78,13 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
break;
}

bool lossless = options.cqLevel == AVIF_QUANTIZER_LOSSLESS &&
options.cqAlphaLevel <= AVIF_QUANTIZER_LOSSLESS &&
bool lossless = options.quality == AVIF_QUALITY_LOSSLESS &&
(options.qualityAlpha == -1 || options.qualityAlpha == AVIF_QUALITY_LOSSLESS) &&
format == AVIF_PIXEL_FORMAT_YUV444;

avifImage* image = avifImageCreate(width, height, depth, format);
// Smart pointer for the generated image
aryanpingle marked this conversation as resolved.
Show resolved Hide resolved
AvifImagePtr image(avifImageCreate(width, height, depth, format), avifImageDestroy);
RETURN_NULL_IF_EQUALS(image, nullptr);

if (lossless) {
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
Expand All @@ -73,74 +95,79 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
uint8_t* rgba = reinterpret_cast<uint8_t*>(const_cast<char*>(buffer.data()));

avifRGBImage srcRGB;
avifRGBImageSetDefaults(&srcRGB, image);
avifRGBImageSetDefaults(&srcRGB, image.get());
srcRGB.pixels = rgba;
srcRGB.rowBytes = width * 4;
avifImageRGBToYUV(image, &srcRGB);
if (options.enableSharpYUV) {
srcRGB.chromaDownsampling = AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV;
}
status = avifImageRGBToYUV(image.get(), &srcRGB);
RETURN_NULL_IF_NOT_EQUALS(status, AVIF_RESULT_OK);

avifEncoder* encoder = avifEncoderCreate();
// Create a smart pointer for the encoder
AvifEncoderPtr encoder(avifEncoderCreate(), avifEncoderDestroy);
RETURN_NULL_IF_EQUALS(encoder, nullptr);

if (lossless) {
encoder->minQuantizer = AVIF_QUANTIZER_LOSSLESS;
encoder->maxQuantizer = AVIF_QUANTIZER_LOSSLESS;
encoder->minQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
encoder->maxQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
encoder->quality = AVIF_QUALITY_LOSSLESS;
encoder->qualityAlpha = AVIF_QUALITY_LOSSLESS;
} else {
encoder->minQuantizer = AVIF_QUANTIZER_BEST_QUALITY;
encoder->maxQuantizer = AVIF_QUANTIZER_WORST_QUALITY;
encoder->minQuantizerAlpha = AVIF_QUANTIZER_BEST_QUALITY;
encoder->maxQuantizerAlpha = AVIF_QUANTIZER_WORST_QUALITY;
avifEncoderSetCodecSpecificOption(encoder, "end-usage", "q");
avifEncoderSetCodecSpecificOption(encoder, "cq-level", std::to_string(options.cqLevel).c_str());
avifEncoderSetCodecSpecificOption(encoder, "sharpness",
std::to_string(options.sharpness).c_str());

if (options.cqAlphaLevel != -1) {
avifEncoderSetCodecSpecificOption(encoder, "alpha:cq-level",
std::to_string(options.cqAlphaLevel).c_str());
status = avifEncoderSetCodecSpecificOption(encoder.get(), "sharpness",
std::to_string(options.sharpness).c_str());
aryanpingle marked this conversation as resolved.
Show resolved Hide resolved
RETURN_NULL_IF_NOT_EQUALS(status, AVIF_RESULT_OK);

// Set base quality
encoder->quality = options.quality;
// Conditionally set alpha quality
if (options.qualityAlpha == -1) {
encoder->qualityAlpha = options.quality;
} else {
encoder->qualityAlpha = options.qualityAlpha;
}

if (options.tune == 2 || (options.tune == 0 && options.cqLevel <= 32)) {
avifEncoderSetCodecSpecificOption(encoder, "tune", "ssim");
if (options.tune == 2 || (options.tune == 0 && options.quality >= 50)) {
status = avifEncoderSetCodecSpecificOption(encoder.get(), "tune", "ssim");
RETURN_NULL_IF_NOT_EQUALS(status, AVIF_RESULT_OK);
}

if (options.chromaDeltaQ) {
avifEncoderSetCodecSpecificOption(encoder, "enable-chroma-deltaq", "1");
status = avifEncoderSetCodecSpecificOption(encoder.get(), "color:enable-chroma-deltaq", "1");
RETURN_NULL_IF_NOT_EQUALS(status, AVIF_RESULT_OK);
}

avifEncoderSetCodecSpecificOption(encoder, "color:denoise-noise-level",
std::to_string(options.denoiseLevel).c_str());
status = avifEncoderSetCodecSpecificOption(encoder.get(), "color:denoise-noise-level",
std::to_string(options.denoiseLevel).c_str());
RETURN_NULL_IF_NOT_EQUALS(status, AVIF_RESULT_OK);
}

encoder->maxThreads = emscripten_num_logical_cores();
encoder->tileRowsLog2 = options.tileRowsLog2;
encoder->tileColsLog2 = options.tileColsLog2;
encoder->speed = options.speed;

avifResult encodeResult = avifEncoderWrite(encoder, image, &output);
avifResult encodeResult = avifEncoderWrite(encoder.get(), image.get(), &output);
aryanpingle marked this conversation as resolved.
Show resolved Hide resolved
auto js_result = val::null();
if (encodeResult == AVIF_RESULT_OK) {
js_result = Uint8Array.new_(typed_memory_view(output.size, output.data));
}

avifImageDestroy(image);
avifEncoderDestroy(encoder);
avifRWDataFree(&output);
return js_result;
}

EMSCRIPTEN_BINDINGS(my_module) {
value_object<AvifOptions>("AvifOptions")
.field("cqLevel", &AvifOptions::cqLevel)
.field("cqAlphaLevel", &AvifOptions::cqAlphaLevel)
.field("quality", &AvifOptions::quality)
.field("qualityAlpha", &AvifOptions::qualityAlpha)
.field("tileRowsLog2", &AvifOptions::tileRowsLog2)
.field("tileColsLog2", &AvifOptions::tileColsLog2)
.field("speed", &AvifOptions::speed)
.field("chromaDeltaQ", &AvifOptions::chromaDeltaQ)
.field("sharpness", &AvifOptions::sharpness)
.field("tune", &AvifOptions::tune)
.field("denoiseLevel", &AvifOptions::denoiseLevel)
.field("subsample", &AvifOptions::subsample);
.field("subsample", &AvifOptions::subsample)
.field("enableSharpYUV", &AvifOptions::enableSharpYUV);

function("encode", &encode);
}
5 changes: 3 additions & 2 deletions codecs/avif/enc/avif_enc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ export const enum AVIFTune {
}

export interface EncodeOptions {
cqLevel: number;
quality: number;
qualityAlpha: number;
denoiseLevel: number;
cqAlphaLevel: number;
tileRowsLog2: number;
tileColsLog2: number;
speed: number;
subsample: number;
chromaDeltaQ: boolean;
sharpness: number;
enableSharpYUV: boolean;
tune: AVIFTune;
}

Expand Down
2 changes: 1 addition & 1 deletion codecs/avif/enc/avif_enc.js

Large diffs are not rendered by default.

Binary file modified codecs/avif/enc/avif_enc.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion codecs/avif/enc/avif_enc_mt.js

Large diffs are not rendered by default.

Binary file modified codecs/avif/enc/avif_enc_mt.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion codecs/avif/enc/avif_enc_mt.worker.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion codecs/avif/enc/avif_node_enc.js

Large diffs are not rendered by default.

Binary file modified codecs/avif/enc/avif_node_enc.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion codecs/avif/enc/avif_node_enc_mt.js

Large diffs are not rendered by default.

Binary file modified codecs/avif/enc/avif_node_enc_mt.wasm
Binary file not shown.
12 changes: 12 additions & 0 deletions codecs/avif/helper.Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
# $(LIBAVIF_FLAGS)
# $(ENVIRONMENT)

# $(OUT_JS) is something like "enc/avif_enc.js" or "enc/avif_enc_mt.js"
# so $(OUT_BUILD_DIR) will be "node_modules/build/enc/avif_enc[_mt]"
OUT_BUILD_DIR := $(BUILD_DIR)/$(basename $(OUT_JS))

# We're making libavif and libaom for every node_modules/[enc|dec]/
CODEC_BUILD_DIR := $(OUT_BUILD_DIR)/libavif
CODEC_OUT := $(CODEC_BUILD_DIR)/libavif.a

Expand All @@ -25,20 +28,29 @@ OUT_WORKER=$(OUT_JS:.js=.worker.js)

all: $(OUT_JS)

# Only add libsharpyuv as a dependency for encoders.
# Yes, that if statement is true for encoders.
ifneq (,$(findstring enc/, $(OUT_JS)))
$(OUT_JS): $(LIBSHARPYUV)
$(CODEC_OUT): $(LIBSHARPYUV)
endif

$(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
$(CXX) \
-I $(CODEC_DIR)/include \
$(CXXFLAGS) \
$(LDFLAGS) \
$(OUT_FLAGS) \
--bind \
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
-s ENVIRONMENT=$(ENVIRONMENT) \
-s EXPORT_ES6=1 \
-o $@ \
$+

$(CODEC_OUT): $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_OUT)
emcmake cmake \
-DCMAKE_LIBRARY_PATH=$(LIBSHARPYUV_BUILD_DIR) \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=0 \
-DAVIF_CODEC_AOM=1 \
Expand Down
2 changes: 1 addition & 1 deletion codecs/cpp.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM emscripten/emsdk:2.0.23
FROM emscripten/emsdk:2.0.34
RUN apt-get update && apt-get install -qqy autoconf libtool pkg-config
ENV CFLAGS "-O3 -flto"
ENV CXXFLAGS "${CFLAGS} -std=c++17"
Expand Down
Loading
Loading