I'm working on a media processing SDK with a substantial C++ codebase that currently uses FFmpeg for video decoding on native platforms (Windows/Linux). I need to port this to browsers while preserving both the existing C++ architecture and performance characteristics. The WASM approach is critical for us because it allows leveraging our existing optimized C++ media processing pipeline without a complete JavaScript rewrite, while maintaining the performance benefits of compiled native code.
The Challenge: WebAssembly runs in a browser sandbox that typically doesn't allow direct GPU access, which conflicts with our hardware-accelerated video decoding requirements. Pure JavaScript solutions would require abandoning our mature C++ codebase and likely result in significant performance degradation.
My Questions:
Is it technically feasible to compile FFmpeg with hardware acceleration support (NVENC/VAAPI/VideoToolbox) for WASM targets? Additionally, can the underlying hardware acceleration dependencies (like CUDA runtime, Intel Media SDK, or platform-specific GPU drivers) be compiled as WASM modules, and would this approach serve the purpose of enabling hardware acceleration in the browser environment?
Are there any emerging browser APIs or proposals (like WebGPU, WebCodecs API) that could provide a pathway for hardware-accelerated video decoding in WASM modules while preserving our C++ architecture?
Has anyone successfully implemented hardware-accelerated video decoding in a browser environment using WASM, or are there alternative approaches that would allow us to maintain our existing C++ codebase and performance requirements?
Context:
- Extensive C++ media processing pipeline with FFmpeg 7.1.0
- Target streams: H.264 and HEVC
- Performance requirements make software-only decoding insufficient
- Rewriting the entire codebase in JavaScript is not feasible due to complexity and performance constraints
Any insights, experiences, or alternative architectural suggestions that preserve our C++ investment would be greatly appreciated!
I attempted to compile FFmpeg for WebAssembly using Emscripten with hardware acceleration enabled. My approach was to call the FFmpeg configure script from a Linux bash environment using:
emconfigure ./configure \
--target-os=none \
--arch=x86_32 \
--enable-cross-compile \
--disable-debug \
--disable-x86asm \
--disable-inline-asm \
--disable-stripping \
--disable-programs \
--disable-doc \
--disable-all \
--enable-avcodec \
--enable-gray \
--enable-avformat \
--enable-avfilter \
--enable-avdevice \
--enable-avutil \
--enable-swresample \
--enable-swscale \
--enable-filters \
--enable-protocol=file \
--enable-decoder=h264 \
--enable-vaapi \
--enable-hwaccel=h264_vaapi \
--enable-gpl \
--enable-pthreads \
--extra-cflags="-O3 -I$ffmpegIncludesDir -I$libvaIncludesDir" \
--extra-cxxflags="-O3 -I$ffmpegIncludesDir -I$libvaIncludesDir" \
--extra-ldflags="--initial-memory=33554432 --no-entry --relocatable -L$ffmpegLibrariesDir -L$libvaLibrariesDir" \
--nm="emnm -g" \
--ar=emar \
--as="$EMSDK/upstream/bin/wasm-as" \
--ranlib=emranlib \
--cc=emcc \
--cxx=em++ \
--objcc=emcc \
--dep-cc=emcc
Since I specified x86_32 architecture, I provided the i386 version of the libva (VAAPI) library to match the target architecture. However, the configuration failed with the error "unknown file type: /usr/lib/i386-linux-gnu/libva.so" in the resulting config.log file.
This error suggests that Emscripten's toolchain cannot process native Linux shared libraries (.so files), which makes sense since these are compiled for native execution rather than WebAssembly. The configuration specifically targets VAAPI hardware acceleration for H.264 decoding, but this approach appears fundamentally flawed since VAAPI requires direct hardware access that isn't available in the browser sandbox, and the native libraries cannot be linked into a WASM module.
This experience has led me to question whether the hardware acceleration dependencies can be meaningfully compiled for WASM, or if alternative approaches are needed.
already precompiledcode which runs still next to javascript. WebGPU (developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) seems like a possible path, but I doubt it would integrate of of the box with accelerated code from ffmpeg which uses different apis (like cuda) for delegating code to gpu.