jmshrv / finamp

A Jellyfin music client for mobile
Mozilla Public License 2.0
1.83k stars 121 forks source link

[0.9.8] [Android] Out of Memory with very large audio files #817

Open vimproved opened 2 months ago

vimproved commented 2 months ago

Hi! I'm fully aware this is a rather niche case, but it seems like when presented with a very large audio file (my example here and how I ran into this is the 192khz recording of Close to the Edge by Yes, the first track of which clocks in at a very beefy 770MiB). This seems to only happen on Android (could not reproduce it on Linux at least, not sure about iOS), and it only happens when Finamp is about 2/3 of the way through loading the file, so I'm guessing that the limit is about 500MiB. Here is the log produced by adb logcat -b crash whenever it OoMs:

07-19 20:06:48.143 12910 13238 E AndroidRuntime: FATAL EXCEPTION: ExoPlayer:Playback
07-19 20:06:48.143 12910 13238 E AndroidRuntime: Process: com.unicornsonlsd.finamp, PID: 12910
07-19 20:06:48.143 12910 13238 E AndroidRuntime: java.lang.OutOfMemoryError: Failed to allocate a 64 byte allocation with 136480 free bytes and 133KB until OOM, target footprint 268435456, growth limit 268435456; giving up on allocation because <1% of heap free after GC.
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at android.media.MediaCodec.getBuffer(Native Method)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at android.media.MediaCodec.getOutputBuffer(MediaCodec.java:4607)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at v1.d.m(Unknown Source:2)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at v1.u.i0(Unknown Source:106)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at v1.u.r(Unknown Source:71)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at e1.o1.p(Unknown Source:97)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at e1.o1.handleMessage(Unknown Source:220)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:103)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at android.os.Looper.loopOnce(Looper.java:232)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:317)
07-19 20:06:48.143 12910 13238 E AndroidRuntime:    at android.os.HandlerThread.run(HandlerThread.java:85)
Chaphasilor commented 1 month ago

Hey, yeah so this is probably because Finamp always pre-caches a certain duration as opposed to size, which might be just a tiny amount for LQ audio but leads to issues in cases like yours.
I think we can configure both a maximum duration and maximum buffer size for Android. On iOS we can set a target duration, but I'm not sure if the OS handles the maximum memory by itself, since we cannot set a limit there.

I'll see what I can do!