ffmpegwasm / ffmpeg.wasm

FFmpeg for browser, powered by WebAssembly
https://ffmpegwasm.netlify.app
MIT License
13.49k stars 775 forks source link

Multithreading is not working on any Chromium-based browser, but it's working perfectly on Firefox. #597

Open mhsayan opened 9 months ago

mhsayan commented 9 months ago

Describe the bug I was recently working on a practice project where my goal was to convert a webm video to mp4 format on the client side. Initially, I was able to achieve this using a single-threaded worker version. However, I later attempted to implement a multithreaded worker version, which unfortunately did not succeed. I spent some time troubleshooting to identify where I went wrong, but I couldn't pinpoint the issue.

To further investigate, I tested the conversion process in a playground environment, and I discovered that even the playground couldn't perform video conversion in multithreaded mode. Subsequently, I tried using different web browsers based on the Chromium engine, but they all failed in this aspect. Surprisingly, Firefox was the only browser that successfully executed the multithreaded video conversion.

To Reproduce Anyone can reproduce this scenario from FFMpeg PlayGround. Just need to enable the Use Multithreading flag. Transcoding process will be stuck at 0%.

Expected behavior The expected behavior involves the successful execution of multithreaded video conversion across various web browsers, including Chromium-based ones.

Some Screenshots about this issue Screenshot 2023-10-05 161717 Screenshot 2023-10-05 162000 Screenshot 2023-10-05 162202

Desktop

osl-masum commented 9 months ago

I have seen the same issue. It really performs very well in multithreaded mode at Mozilla. But I think Chrome is a more popular browser than Mozilla. So please fix this issue as soon as possible.

LostBeard commented 9 months ago

To Reproduce Anyone can reproduce this scenario from FFMpeg PlayGround. Just need to enable the Use Multithreading flag. Transcoding process will be stuck at 0%.

The Playground works fine (for me) with multi-threading on Chrome Version 117.0.5938.134 (Official Build) (64-bit) on Windows 10. Just tried it to verify your issue and it transcoded correctly without error. It doesn't seem to be as easy to reproduce as you suggest.

I have seen some issues that only arise when using the multi-threaded version where it fails, but the playground basic demo test isn't one of them.

So the question is, why is it working for some and not for others?

Could it be a browser extension issue?

LostBeard commented 9 months ago

Also working on Microsoft Edge Version 119.0.2141.0 (Official build) canary (64-bit) on Windows 10

LostBeard commented 9 months ago

WebAssembly browser code compatibility is not as clear cut as Javascript. I have a PC with a CPU that does not support SIMD and that prevents a number of WebAssembly libraries from working correctly (Blazor WASM is a notable example.) It is possible that the multi-threaded version uses some CPU instructions your CPU does not support.

If it was CPU related it would likely affect all browsers on that system, not just Chromium based ones though.

Kylmakalle commented 9 months ago

Duplicate #578, #532

mhsayan commented 9 months ago

@LostBeard Thanks a lot for your response, and I'm really sorry for the late reply. As you mentioned, the issue could be related to the CPU. My CPU configuration is: Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz Base speed: 2.90 GHz Sockets: 1 Cores: 8 Logical processors: 16 Virtualization: Enabled L1 cache: 512 KB L2 cache: 2.0 MB L3 cache: 16.0 MB

SvetlozarValchev commented 9 months ago

Exactly the same issue. Tested multi-threaded using Chrome 117.0.5938.150 and Microsoft Edge Version 117.0.2045.60 on Windows 11 Pro and it doesn't work. Works fine in Firefox 118.0.1. If it matters, my CPU is Intel i9-13900K. Single-threaded works fine in all browsers.

It hangs just before it starts the encoding process:


  built with emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)
  configuration: --target-os=none --arch=x86_32 --enable-cross-compile --disable-asm --disable-stripping --disable-programs --disable-doc --disable-debug --disable-runtime-cpudetect --disable-autodetect --nm=emnm --ar=emar --ranlib=emranlib --cc=emcc --cxx=em++ --objcc=emcc --dep-cc=emcc --extra-cflags='-I/opt/include -O3 -msimd128 -sUSE_PTHREADS -pthread' --extra-cxxflags='-I/opt/include -O3 -msimd128 -sUSE_PTHREADS -pthread' --enable-gpl --enable-libx264 --enable-libx265 --enable-libvpx --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libopus --enable-zlib --enable-libwebp --enable-libfreetype --enable-libfribidi --enable-libass --enable-libzimg
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
Input #0, matroska,webm, from 'video.webm':
  Metadata:
    title           : Big Buck Bunny, Sunflower version
    COMMENT         : Creative Commons Attribution 3.0 - http://bbb3d.renderfarming.net
    GENRE           : Animation
    MAJOR_BRAND     : isom
    MINOR_VERSION   : 1
    COMPATIBLE_BRANDS: isomavc1
    COMPOSER        : Sacha Goedegebure
    ARTIST          : Blender Foundation 2008, Janus Bager Kristensen 2013
    ENCODER         : Lavf60.3.100
  Duration: 00:00:10.00, start: 0.000000, bitrate: 180 kb/s
  Stream #0:0: Video: vp9 (Profile 0), yuv420p(tv, bt470bg/unknown/unknown, progressive), 320x180, SAR 1:1 DAR 16:9, 30 fps, 30 tbr, 1k tbn (default)
    Metadata:
      HANDLER_NAME    : GPAC ISO Video Handler
      ENCODER         : Lavc60.3.100 libvpx-vp9
      DURATION        : 00:00:10.000000000
Stream mapping:
  Stream #0:0 -> #0:0 (vp9 (native) -> h264 (libx264))```  
JakeRoyRandall commented 8 months ago

Same problem. Took too long beating my head against this before checking gh issues.

musarratChowdhury commented 8 months ago

I have also faced the same issue while testing on my chrome browser, As soon as i turn on the multi-threading on chrome, the same issue occurs, please look into this problem urgently.

SvetlozarValchev commented 7 months ago

Further testing makes me think that there is a fundamental problem with memory limitations. If you put the arg -threads X, it will work up to a specific number, after which it will silently stop responding. In my project that 'X' seems to be about 4 for the video I'm trying to convert, and in the FFMPEG Playground, that limit is 8. navigator.hardwareConcurrency reports 32 on my machine. If that's what the wasm uses to detect how many threads to use, then it may be running out of available memory for the wasm to work properly, especially with bigger media. It seems like Chrome has put some arbitrary limit, because it doesn't have problems on Firefox, and my machine's total RAM is definitely not reached.

If that really is the cause, it means that modern machines will hit that hidden limit way too easy for multi-threading to be a viable approach in a production environment.

diegoddox commented 6 months ago

Facing the same issue, in my case not even -threads X is helping

foureight84 commented 6 months ago

This seems to be the same issue as #654 and #530. It's working for me implemented on NextJS 14 with Firefox 121.0, but does not work on Chrome 120.0.6099.130.

foureight84 commented 6 months ago

Further testing makes me think that there is a fundamental problem with memory limitations. If you put the arg -threads X, it will work up to a specific number, after which it will silently stop responding. In my project that 'X' seems to be about 4 for the video I'm trying to convert, and in the FFMPEG Playground, that limit is 8. navigator.hardwareConcurrency reports 32 on my machine. If that's what the wasm uses to detect how many threads to use, then it may be running out of available memory for the wasm to work properly, especially with bigger media. It seems like Chrome has put some arbitrary limit, because it doesn't have problems on Firefox, and my machine's total RAM is definitely not reached.

If that really is the cause, it means that modern machines will hit that hidden limit way too easy for multi-threading to be a viable approach in a production environment.

That was really helpful. Setting it up -threads 4 works for me. Anything higher will hang. It also looks like transcoding the same video takes the same time on Firefox without the -threads flag.

iketiunn commented 4 months ago

Adding -threads 4 works for me on m3 max both chromium-based and safari.

aperture147 commented 3 months ago

I've tested on my Windows, Linux and Mac machines, on Safari and Chromium-based browsers, on both Intel and Apple CPU. It seems like -thread 4 or any -thread option (even -thread 1) is not always okay to handle all tasks, especially filters (which is a memory crunching job), when demuxed-concat works just fine and fast (because it only depends on filesystem speed). Only Firefox runs well with multithreading, which is sad since most of users now are using Chrome. In my case, I have to switch to single-threaded version.

I think this problem is worth a note on ffmpeg wasm document under Usage page because it's not a trivial problem and really confusing for developers since it just silently fails with no further explanation.