Skip to content

Commit

Permalink
perf: add a SIMD build [35% faster blur render]
Browse files Browse the repository at this point in the history
fix: handle edge case when video resized before worker finished loading
feat: allow for custom worker and WASM URLs
  • Loading branch information
ThaUnknown committed May 17, 2023
1 parent cf44af6 commit ec53846
Show file tree
Hide file tree
Showing 18 changed files with 432 additions and 361 deletions.
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ RUN apt-get update && \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /code
CMD ["bash", "-c", "make; sudo npm i; sudo node vite.build.js"]
CMD ["bash", "-c", "sudo rm -rf dist/libraries; sudo rm -rf build/lib; make; sudo rm -rf dist/libraries; sudo rm -rf build/lib; env MODERN=1 make; sudo npm i; sudo node vite.build.js"]

123 changes: 82 additions & 41 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@ export CXXFLAGS = $(CFLAGS)
export PKG_CONFIG_PATH = $(DIST_DIR)/lib/pkgconfig
export EM_PKG_CONFIG_PATH = $(PKG_CONFIG_PATH)

SIMD_ARGS = \
-msimd128 \
-msse \
-msse2 \
-msse3 \
-mssse3 \
-msse4 \
-msse4.1 \
-msse4.2 \
-mavx \
-mavx2 \
-matomics \
-mnontrapping-fptoint

ifeq (${MODERN},1)
WORKER_NAME = jassub-worker-modern
WORKER_ARGS = \
-s WASM=1 \
$(SIMD_ARGS)

override CFLAGS += $(SIMD_ARGS)
override CXXFLAGS += $(SIMD_ARGS)

else
WORKER_NAME = jassub-worker
WORKER_ARGS = \
-s WASM=2

endif

all: jassub
jassub: dist

Expand Down Expand Up @@ -127,13 +157,12 @@ build/lib/libass/configured: lib/libass
$(DIST_DIR)/lib/libass.a: $(DIST_DIR)/lib/libfontconfig.a $(DIST_DIR)/lib/libharfbuzz.a $(DIST_DIR)/lib/libexpat.a $(DIST_DIR)/lib/libfribidi.a $(DIST_DIR)/lib/libfreetype.a $(DIST_DIR)/lib/libbrotlidec.a build/lib/libass/configured
cd build/lib/libass && \
$(call CONFIGURE_AUTO,../../../lib/libass) \
--disable-asm \
--enable-large-tiles \
--enable-fontconfig \
&& \
$(JSO_MAKE) install

# JASSUB.js
OCTP_DEPS = \
LIBASS_DEPS = \
$(DIST_DIR)/lib/libfribidi.a \
$(DIST_DIR)/lib/libbrotlicommon.a \
$(DIST_DIR)/lib/libbrotlidec.a \
Expand All @@ -143,47 +172,59 @@ OCTP_DEPS = \
$(DIST_DIR)/lib/libfontconfig.a \
$(DIST_DIR)/lib/libass.a


dist: $(LIBASS_DEPS) dist/js/$(WORKER_NAME).js dist/js/jassub.js

# Dist Files https://github.com/emscripten-core/emscripten/blob/3.1.38/src/settings.js

# args for increasing performance
# https://github.com/emscripten-core/emscripten/issues/13899
EMCC_COMMON_ARGS = \
-s ENVIRONMENT=worker \
-s NO_EXIT_RUNTIME=1 \
-lembind \
-s ALLOW_MEMORY_GROWTH=1 \
-s FILESYSTEM=0 \
-s AUTO_JS_LIBRARIES=0 \
-s AUTO_NATIVE_LIBRARIES=0 \
-s HTML5_SUPPORT_DEFERRING_USER_SENSITIVE_REQUESTS=0 \
-s USE_SDL=0 \
-s INVOKE_RUN=0 \
-s STRICT_JS=1 \
-s DISABLE_EXCEPTION_CATCHING=1 \
-s EXPORTED_FUNCTIONS="['_malloc']" \
-s MINIMAL_RUNTIME=1 \
-s MINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION=1 \
-s POLYFILL=0 \
-s BINARYEN_EXTRA_PASSES=--one-caller-inline-max-function-size=19306 \
-s INCOMING_MODULE_JS_API="[]" \
--no-heap-copy \
-flto \
-fno-exceptions \
-o $@

dist: $(OCTP_DEPS) dist/js/jassub-worker.js dist/js/jassub.js

dist/js/jassub-worker.js: src/JASSUB.cpp src/worker.js src/polyfill.js
mkdir -p dist/js
emcc src/JASSUB.cpp $(OCTP_DEPS) \
--pre-js src/polyfill.js \
--pre-js src/worker.js \
-O3 \
PERFORMANCE_ARGS = \
-s BINARYEN_EXTRA_PASSES=--one-caller-inline-max-function-size=19306 \
-s INVOKE_RUN=0 \
-s DISABLE_EXCEPTION_CATCHING=1 \
-s TEXTDECODER=1 \
-s WASM=2 \
--memory-init-file 0 \
--closure=0 \
-s MIN_CHROME_VERSION=27 \
-s MIN_SAFARI_VERSION=60005 \
$(EMCC_COMMON_ARGS)
-s MINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION=1 \
--no-heap-copy \
-flto \
-fno-exceptions \
-O3

# args for reducing size
SIZE_ARGS = \
-s POLYFILL=0 \
-s FILESYSTEM=0 \
-s AUTO_JS_LIBRARIES=0 \
-s AUTO_NATIVE_LIBRARIES=0 \
-s HTML5_SUPPORT_DEFERRING_USER_SENSITIVE_REQUESTS=0 \
-s INCOMING_MODULE_JS_API="[]" \
-s USE_SDL=0 \
-s MINIMAL_RUNTIME=1

# args that are required for this to even work at all
COMPAT_ARGS = \
-s EXPORTED_FUNCTIONS="['_malloc']" \
-s EXPORT_KEEPALIVE=1 \
-s EXPORTED_RUNTIME_METHODS="['getTempRet0', 'setTempRet0']" \
-s IMPORTED_MEMORY=1 \
-mbulk-memory \
--memory-init-file 0

dist/js/$(WORKER_NAME).js: src/JASSUB.cpp src/worker.js src/pre-worker.js
mkdir -p dist/js
emcc src/JASSUB.cpp $(LIBASS_DEPS) \
$(WORKER_ARGS) \
$(PERFORMANCE_ARGS) \
$(SIZE_ARGS) \
$(COMPAT_ARGS) \
--pre-js src/pre-worker.js \
-s ENVIRONMENT=worker \
-s EXIT_RUNTIME=0 \
-s ALLOW_MEMORY_GROWTH=1 \
-s MODULARIZE=1 \
-s EXPORT_ES6=1 \
-lembind \
-o $@

dist/js/jassub.js: src/jassub.js
mkdir -p dist/js
Expand Down
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ npm i jassub
```js
import JASSUB from 'jassub'
import workerUrl from 'jassub/dist/jassub-worker.js?url'
import 'jassub/dist/jassub-worker.wasm?url'
import wasmUrl from 'jassub/dist/jassub-worker.wasm?url'

const renderer = new JASSUB({
video: document.querySelector('video'),
subContent: subtitleString,
workerUrl // you can also use: `new URL('jassub/dist/jassub-worker.js', import.meta.url)` instead of importing it as an url
workerUrl, // you can also use: `new URL('jassub/dist/jassub-worker.js', import.meta.url)` instead of importing it as an url
wasmUrl
})
```
## Using only with canvas
Expand Down Expand Up @@ -99,8 +100,11 @@ The default options are best, and automatically fallback to the next fastest opt
- `{Number} options.prescaleHeightLimit` { Optional = 1080 } The height in pixels beyond which the subtitles canvas won't be prescaled.
- `{Number} options.maxRenderHeight` { Optional = 0 } The maximum rendering height in pixels of the subtitles canvas. Beyond this subtitles will be upscaled by the browser.
- `{Boolean} options.dropAllAnimations` { Optional = false } Attempt to discard all animated tags. Enabling this may severly mangle complex subtitles and should only be considered as an last ditch effort of uncertain success for hardware otherwise incapable of displaing anything. Will not reliably work with manually edited or allocated events.
- `{Boolean} options.dropAllBlur` { Optional = false } The holy grail of performance gains. If heavy TS lags a lot, disabling this will make it ~x10 faster. This drops blur from all added subtitle tracks making most text and backgrounds look sharper, this is way less intrusive than dropping all animations, while still offering major performance gains.
- `{String} options.workerUrl` { Optional = 'jassub-worker.js' } The URL of the worker.
- `{String} options.legacyWorkerUrl` { Optional = 'jassub-worker-legacy.js' } The URL of the legacy worker. Only loaded if the browser doesn't support WASM.
- `{String} options.wasmUrl` { Optional = 'jassub-worker.wasm' } The URL of the worker WASM.
- `{String} options.legacyWasmUrl` { Optional = 'jassub-worker.wasm.js' } The URL of the legacy worker WASM. Only loaded if the browser doesn't support WASM.
- `{String} options.modernWasmUrl` { Optional } The URL of the modern worker WASM. This includes faster ASM instructions, but is only supported by newer browsers, disabled if the URL isn't defined.
- `{String} [options.subUrl=options.subContent]` The URL of the subtitle file to play.
- `{String} [options.subContent=options.subUrl]` The content of the subtitle file to play.
- `{String[]|Uint8Array[]} options.fonts` { Optional } An array of links or Uint8Arrays to the fonts used in the subtitle. If Uint8Array is used the array is copied, not referenced. This forces all the fonts in this array to be loaded by the renderer, regardless of if they are used.
Expand All @@ -121,11 +125,12 @@ This library has a lot of methods and properties, however many aren't made for m
- `busy` - Boolean which specifies if the renderer is currently busy.
- `timeOffset` - -||-
### List of methods:
- `resize(width = 0, height = 0, top = 0, left = 0)` - Resize the canvas to given parameters. Auto-generated if values are ommited.
- `resize(width = 0, height = 0, top = 0, left = 0, force)` - Resize the canvas to given parameters. Auto-generated if values are ommited.
- {Number} [width=0]
- {Number} [height=0]
- {Number} [top=0]
- {Number} [left=0]
- {Boolean} force
- `setVideo(video)` - Change the video to use as target for event listeners.
- {HTMLVideoElement} video
- `setTrackByUrl(url)` - Overwrites the current subtitle content.
Expand Down
Binary file added dist/jassub-worker-modern.wasm
Binary file not shown.
Loading

0 comments on commit ec53846

Please sign in to comment.