finamp
finamp copied to clipboard
[0.9.8] [Android] Out of Memory with very large audio files
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)
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!
This should be quite easy to do for Android via https://pub.dev/documentation/just_audio/latest/just_audio/AndroidLoadControl/targetBufferBytes.html and https://pub.dev/documentation/just_audio/latest/just_audio/AndroidLoadControl/prioritizeTimeOverSizeThresholds.html
(Although it may be better to leave it to defaults at this point? Idk what they are though, so we might be able to be a bit more greedy)
@vimproved I've implemented this recently, there will be some new settings related to this, with a 50MB buffer size by default. Will land with the next beta update :)