Description
I am having issues building ffmpeg after switching from emscripten 3.1.47 to 3.57.
With 3.1.47 I am able to build ffmpeg.wasm with aom and libpvx libraries, however with emscripten 3.1.57 I am fighting some errors.
When building ffmpeg with -O0
, the builds finishes ok, but there are runtime issues (in createModule() phase) when running .wasm in browser:
RuntimeError: Aborted(CompileError: WebAssembly.instantiate(): Compiling function #13387:"decoder_get_frame" failed: not enough arguments on the stack for call (need 4, got 3) @+13970659)
Following that, it does appears both aom and libvpx defines the same static decoder_get_frame
symbol:
- https://aomedia.googlesource.com/aom/+/refs/tags/v3.9.0/av1/av1_dx_iface.c#810
- https://chromium.googlesource.com/webm/libvpx/+/refs/tags/v1.14.0/vp9/vp9_dx_iface.c#410
But I do not think I will be able to convince aom / libvpx teams to rename all the conflicting symbols. Actually, I do not think these symbols are eventually needed or used in final .wasm.
When building with -O3
the build fails with
[parse exception: attempted pop from empty stack / beyond block start boundary at 7509472 (at 0:7509472)]
Fatal: error parsing wasm (try --debug for more info)
emcc: error: '/ffmpeg-wasm/modules/emsdk/upstream/bin/wasm-opt --strip-target-features --post-emscripten -O3 --low-memory-unused --zero-filled-memory --pass-arg=directize-initial-contents-immutable /ffmpeg-wasm/wasm/ffmpeg-lgpl-simd.wasm -o /ffmpeg-wasm/wasm/ffmpeg-lgpl-simd.wasm --mvp-features --enable-threads --enable-bulk-memory --enable-multivalue --enable-mutable-globals --enable-sign-ext --enable-simd' failed (returned 1)
running wasm-opt --debug
prints a huge log, ending with these lines:
<==
getInt8: 0 (at 7509465)
getS32LEB: 0 ==>
zz recurse from 2 at 7509466
zz recurse into 2 at 7509466
getInt8: 16 (at 7509466)
readExpression seeing 16
zz node: Call
<==
getInt8: 128 (at 7509467)
getInt8: 128 (at 7509468)
getInt8: 128 (at 7509469)
getInt8: 128 (at 7509470)
getInt8: 0 (at 7509471)
getU32LEB: 0 ==>
== popExpression
== popExpression
== popExpression
== popExpression
== popExpression
== popExpression
== popExpression
== popExpression
== popExpression
== popExpression
[parse exception: attempted pop from empty stack / beyond block start boundary at 7509472 (at 0:7509472)]
wasm-opt: /usr/local/google/home/dschuff/s/emr/emscripten-releases/binaryen/src/support/name.cpp:44: std::ostream &wasm::Name::print(std::ostream &) const: Assertion `*this && "Cannot print an empty name"' failed.
Aborted
Linking only single aom or vpx at a time, there is no error even with 3.1.57, so my thinking is the problem is some kind of conflict, and 57 being somehow less forgiving than 47.
I am not sure how to proceed from here, I want to stick to the latest emscripten version however:
- 3.1.47 builds working ffmpeg.wasm
- 3.1.48 to 3.1.56 are not available for mac M2
- 3.1.57 fails either in runtime or build time
- 3.1.58 and newer are not suitable
I wonder what is the breaking change between these versions (47 to 57) and if there is any magical build flag to use with emscripten so the build succeeds?
Both aom/libvpx are build with -DBUILD_SHARED_LIBS=0
or --disable-shared
respectively, and linked to final .wasm using these flags:
emcc
-laom
-lvpx
-lworkerfs.js
-msimd128
-s USE_PTHREADS=1 -pthread
-s USE_SDL=2
-s WASM_BIGINT
-s MALLOC=mimalloc
-s INVOKE_RUN=0
-s EXIT_RUNTIME=1
-s MODULARIZE=1
-s EXPORT_NAME="createFFmpeg"
-s EXPORTED_FUNCTIONS="[_main, ___wasm_init_memory_flag]"
-s EXPORTED_RUNTIME_METHODS="[callMain, FS, WORKERFS]"
-s INITIAL_MEMORY=128mb
-s ALLOW_MEMORY_GROWTH=1
-s MAXIMUM_MEMORY=4gb
-s ENVIRONMENT=worker
-s PROXY_TO_PTHREAD=1
-s STACK_SIZE=5MB
-s DEFAULT_PTHREAD_STACK_SIZE=2MB