jmonkeyengine: Can not play vorbis audio on Android API 31+

Apparently, JME Vorbis (Ogg) audio plugin is broken on the Android API 31+.

Here is the crash log:

02-17 11:49:41.417 I/com.jme3.audio.openal.ALAudioRenderer(3852): INFO Audio Renderer Information
02-17 11:49:41.417 I/com.jme3.audio.openal.ALAudioRenderer(3852):  * Device: OpenAL Soft
02-17 11:49:41.417 I/com.jme3.audio.openal.ALAudioRenderer(3852):  * Vendor: OpenAL Community
02-17 11:49:41.417 I/com.jme3.audio.openal.ALAudioRenderer(3852):  * Renderer: OpenAL Soft
02-17 11:49:41.417 I/com.jme3.audio.openal.ALAudioRenderer(3852):  * Version: 1.1 ALSOFT 1.21.1
02-17 11:49:41.417 I/com.jme3.audio.openal.ALAudioRenderer(3852):  * Supported channels: 64
02-17 11:49:41.417 I/com.jme3.audio.openal.ALAudioRenderer(3852):  * ALC extensions: ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context ALC_SOFT_device_clock ALC_SOFT_HRTF ALC_SOFT_loopback ALC_SOFT_loopback_bformat ALC_SOFT_output_limiter ALC_SOFT_pause_device
02-17 11:49:41.417 I/com.jme3.audio.openal.ALAudioRenderer(3852):  * AL extensions: AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES AL_LOKI_quadriphonic AL_SOFT_bformat_ex AL_SOFTX_bformat_hoa AL_SOFT_block_alignment AL_SOFTX_callback_buffer AL_SOFTX_convolution_reverb AL_SOFT_deferred_updates AL_SOFT_direct_channels AL_SOFT_direct_channels_remix AL_SOFT_effect_target AL_SOFT_events AL_SOFTX_filter_gain_ex AL_SOFT_gain_clamp_ex AL_SOFT_loop_points AL_SOFTX_map_buffer AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length AL_SOFT_source_resampler AL_SOFT_source_spatialize
02-17 11:49:41.428 I/com.jme3.audio.openal.ALAudioRenderer(3852): INFO Audio effect extension version: 1.0
02-17 11:49:41.430 I/com.jme3.audio.openal.ALAudioRenderer(3852): INFO Audio max auxiliary sends: 2
--------- beginning of crash
02-17 11:49:42.133 F/libc    (3852): fdsan: attempted to close file descriptor 96, expected to be unowned, actually owned by ParcelFileDescriptor 0xdfa250a
02-17 11:49:42.137 F/libc    (3852): Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 3873 (GLThread 56), pid 3852 (ycompany.mygame)
02-17 11:49:42.262 I/crash_dump64(3884): obtaining output fd from tombstoned, type: kDebuggerdTombstoneProto
02-17 11:49:42.274 I/tombstoned(238): received crash request for pid 3873
02-17 11:49:42.277 I/crash_dump64(3884): performing dump of process 3852 (target tid = 3873)
02-17 11:50:24.206 I/logd    (0): logdr: UID=10159 GID=10159 PID=3884 n tail=0 logMask=8 pid=3852 start=0ns deadline=0ns
02-17 11:50:24.213 I/logd    (0): logdr: UID=10159 GID=10159 PID=3884 n tail=0 logMask=1 pid=3852 start=0ns deadline=0ns
02-17 11:49:43.884 F/DEBUG   (3884): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
02-17 11:49:43.884 F/DEBUG   (3884): Build fingerprint: 'google/sdk_gphone64_x86_64/emu64x:13/TE1A.220922.012/9302419:userdebug/dev-keys'
02-17 11:49:43.884 F/DEBUG   (3884): Revision: '0'
02-17 11:49:43.884 F/DEBUG   (3884): ABI: 'x86_64'
02-17 11:49:43.885 F/DEBUG   (3884): Timestamp: 2023-02-17 11:49:42.297738142+0330
02-17 11:49:43.885 F/DEBUG   (3884): Process uptime: 4s
02-17 11:49:43.885 F/DEBUG   (3884): Cmdline: com.mycompany.mygame
02-17 11:49:43.885 F/DEBUG   (3884): pid: 3852, tid: 3873, name: GLThread 56  >>> com.mycompany.mygame <<<
02-17 11:49:43.885 F/DEBUG   (3884): uid: 10159
02-17 11:49:43.885 F/DEBUG   (3884): signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
02-17 11:49:43.885 F/DEBUG   (3884): Abort message: 'fdsan: attempted to close file descriptor 96, expected to be unowned, actually owned by ParcelFileDescriptor 0xdfa250a'
02-17 11:49:43.885 F/DEBUG   (3884):     rax 0000000000000000  rbx 0000000000000f0c  rcx 00007e5efa3d39a4  rdx 0000000000000006
02-17 11:49:43.885 F/DEBUG   (3884):     r8  0000000000000000  r9  0000000000000000  r10 00007e5bec6a8dd0  r11 0000000000000203
02-17 11:49:43.885 F/DEBUG   (3884):     r12 00007e5becd1df96  r13 00007e5bec6a8e90  r14 0000000000000f21  r15 00007e5f08ad8bd8
02-17 11:49:43.885 F/DEBUG   (3884):     rdi 0000000000000f0c  rsi 0000000000000f21
02-17 11:49:43.885 F/DEBUG   (3884):     rbp 0000000000000003  rsp 00007e5bec6a8b00  rip 00007e5efa3d39a4
02-17 11:49:43.885 F/DEBUG   (3884): backtrace:
02-17 11:49:43.885 F/DEBUG   (3884):       #00 pc 00000000000639a4  /apex/com.android.runtime/lib64/bionic/libc.so (fdsan_error(char const*, ...)+740) (BuildId: 007cb2313464df63debf8020e631c990)
02-17 11:49:43.885 F/DEBUG   (3884):       #01 pc 00000000000635ef  /apex/com.android.runtime/lib64/bionic/libc.so (android_fdsan_close_with_tag+671) (BuildId: 007cb2313464df63debf8020e631c990)
02-17 11:49:43.885 F/DEBUG   (3884):       #02 pc 0000000000063d5b  /apex/com.android.runtime/lib64/bionic/libc.so (close+11) (BuildId: 007cb2313464df63debf8020e631c990)
02-17 11:49:43.885 F/DEBUG   (3884):       #03 pc 0000000000022f0f  /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/lib/x86_64/libdecodejme.so (BuildId: acaf1ecb244bdebc5e5173b258b3fc2be97ed696)
02-17 11:49:43.885 F/DEBUG   (3884):       #04 pc 000000000001deb8  /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/lib/x86_64/libdecodejme.so (ov_clear+280) (BuildId: acaf1ecb244bdebc5e5173b258b3fc2be97ed696)
02-17 11:49:43.885 F/DEBUG   (3884):       #05 pc 0000000000022c4d  /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/lib/x86_64/libdecodejme.so (Java_com_jme3_audio_plugins_NativeVorbisFile_close+109) (BuildId: acaf1ecb244bdebc5e5173b258b3fc2be97ed696)
02-17 11:49:43.885 F/DEBUG   (3884):       #06 pc 000000000037d70b  /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+219) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.885 F/DEBUG   (3884):       #07 pc 0000000000369aed  /apex/com.android.art/lib64/libart.so (nterp_helper+3837) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.885 F/DEBUG   (3884):       #08 pc 0000000000194f96  [anon:dalvik-classes.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk] (com.jme3.audio.plugins.NativeVorbisLoader.loadBuffer+122)
02-17 11:49:43.885 F/DEBUG   (3884):       #09 pc 0000000000368c28  /apex/com.android.art/lib64/libart.so (nterp_helper+56) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.885 F/DEBUG   (3884):       #10 pc 00000000001950ce  [anon:dalvik-classes.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk] (com.jme3.audio.plugins.NativeVorbisLoader.load+42)
02-17 11:49:43.885 F/DEBUG   (3884):       #11 pc 000000000036a7e5  /apex/com.android.art/lib64/libart.so (nterp_helper+7157) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.885 F/DEBUG   (3884):       #12 pc 000000000018c3be  [anon:dalvik-classes.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk] (com.jme3.asset.DesktopAssetManager.loadLocatedAsset+22)
02-17 11:49:43.885 F/DEBUG   (3884):       #13 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.885 F/DEBUG   (3884):       #14 pc 000000000018c2cc  [anon:dalvik-classes.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk] (com.jme3.asset.DesktopAssetManager.loadAsset+216)
02-17 11:49:43.885 F/DEBUG   (3884):       #15 pc 000000000036a7e5  /apex/com.android.art/lib64/libart.so (nterp_helper+7157) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.885 F/DEBUG   (3884):       #16 pc 0000000000190632  [anon:dalvik-classes.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk] (com.jme3.audio.AudioNode.<init>+154)
02-17 11:49:43.885 F/DEBUG   (3884):       #17 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.885 F/DEBUG   (3884):       #18 pc 0000000000190664  [anon:dalvik-classes.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk] (com.jme3.audio.AudioNode.<init>+16)
02-17 11:49:43.885 F/DEBUG   (3884):       #19 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.885 F/DEBUG   (3884):       #20 pc 000000000000059c  [anon:dalvik-classes2.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk!classes2.dex] (mygame.Main.initAudio+16)
02-17 11:49:43.885 F/DEBUG   (3884):       #21 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.885 F/DEBUG   (3884):       #22 pc 000000000000067c  [anon:dalvik-classes2.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk!classes2.dex] (mygame.Main.simpleInitApp+88)
02-17 11:49:43.885 F/DEBUG   (3884):       #23 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.886 F/DEBUG   (3884):       #24 pc 0000000000187042  [anon:dalvik-classes.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk] (com.jme3.app.SimpleApplication.initialize+398)
02-17 11:49:43.886 F/DEBUG   (3884):       #25 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.886 F/DEBUG   (3884):       #26 pc 0000000000180888  [anon:dalvik-classes.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk] (com.jme3.app.AndroidHarnessFragment.initialize+4)
02-17 11:49:43.886 F/DEBUG   (3884):       #27 pc 000000000036a7e5  /apex/com.android.art/lib64/libart.so (nterp_helper+7157) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.886 F/DEBUG   (3884):       #28 pc 00000000002310be  [anon:dalvik-classes.dex extracted in memory from /data/app/~~XddJDkVqxYJIpdtJnuwGSw==/com.mycompany.mygame-2y8ean9Pk2rnWrn85Jl4uQ==/base.apk] (com.jme3.system.android.OGLESContext.onDrawFrame+74)
02-17 11:49:43.886 F/DEBUG   (3884):       #29 pc 000000000036a8a1  /apex/com.android.art/lib64/libart.so (nterp_helper+7345) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.886 F/DEBUG   (3884):       #30 pc 000000000044aef8  /system/framework/framework.jar (android.opengl.GLSurfaceView$GLThread.guardedRun+1096)
02-17 11:49:43.886 F/DEBUG   (3884):       #31 pc 0000000000369a88  /apex/com.android.art/lib64/libart.so (nterp_helper+3736) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.886 F/DEBUG   (3884):       #32 pc 000000000044b4fc  /system/framework/framework.jar (android.opengl.GLSurfaceView$GLThread.run+52)
02-17 11:49:43.886 F/DEBUG   (3884):       #33 pc 00000000003725c4  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+756) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.886 F/DEBUG   (3884):       #34 pc 00000000003f21a6  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+214) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.886 F/DEBUG   (3884):       #35 pc 00000000007e617e  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+478) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.886 F/DEBUG   (3884):       #36 pc 000000000083a91c  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1404) (BuildId: 44bc52550248fc712a381bef164b75c7)
02-17 11:49:43.886 F/DEBUG   (3884):       #37 pc 00000000000ccd2a  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+58) (BuildId: 007cb2313464df63debf8020e631c990)
02-17 11:49:43.886 F/DEBUG   (3884):       #38 pc 0000000000060d37  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+55) (BuildId: 007cb2313464df63debf8020e631c990)

Forum thread: https://hub.jmonkeyengine.org/t/jmesurfaceview-for-android-api-31-not-working-properly/46465

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 16 (16 by maintainers)

Commits related to this issue

Most upvoted comments

By the way, I excluded the jmf library coming with j-ogg-all and I can still play the ogg sound. Looks like jmf is not used for decoding ogg files so we may safely exclude it in jme3-jogg. (the jmf jar size is 1.8 MB!)

Edit: see #1958

I will merge your PR, I think, we should keep both.

I do not see how awt package may be useful in loading audio but for video loading yes it could be.

It is your choice then, to accept my PR to fix this issue, or create another PR to drop the whole native decode library and replace it with the jogg…i think we should do both 😁, replacing with jogg will not fix the current issue, it just a workaround for a better maintenance.

Well, this may be explained by the original source code of jmf that decode vorbis isn’t calling a java awt package classes…and so the NoClassDefFoundException is not thrown on the android dalvik…thanks for testing that.

Are you sure it was j-ogg and the run is not delegated to android-native ?

Yes

I replaced this

https://github.com/jMonkeyEngine/jmonkeyengine/blob/493195eae810c4a38744e6c34ea0e7e8c48542a9/jme3-android/src/main/resources/com/jme3/asset/Android.cfg#L9

with

LOADER com.jme3.audio.plugins.OGGLoader : ogg 

Also noticed when I removed the dependency to jme3-jogg it throws a class not found exception for com.jme3.audio.plugins.OGGLoader at runtime.

the jogg library relies on the javax.media from Java Media Framework API

Thanks for the API link.

I unpacked the javax.media “jmf” JAR. It consists entirely of Java classes and GIF images. There’s no native code. So if it’s unavailable on Android, there must be a different explanation.

In fact, this is an actual bug

True, but not all bugs are regressions.

Hmm, good point, is jme3-jogg a pure java implementation or does it contain native binaries? Maybe @Scrappers-glitch has an idea.

When hardware is involved, nothing is pure java, correct me if i am wrong, afaik the jogg library relies on the javax.media from Java Media Framework API, i don’t think it provides a build for android…

No regression on our side afaik, but it is more like a change on the android side.

In fact, this is an actual bug, the double resource closure is a bug, and fortunately the new android fdsan (file descriptor sanitizer) has discovered this bug and we should provide the fix for this…

Notice, on the GNU C side, the double closure doesn’t crash the program with a not owned state as android do, instead, it just throws [-1] as a return for the int close(int) function, however if you tried to use any previously allocated copies from a previously closed files, the system will throw a memory Segmentation fault with a program crash; because the close function from GNU libc doesnot only close the file stream, but it also deallocates the associated file descriptor and any unread data or queued read/write operations will be discarded…

Consider this case:

#include <stdio.h>
#include <unistd.h>

int main() {
    int res0 = fclose(stdin);
    int res1 = fclose(stdin);
    /* returns [0] for success */
    printf("Return of the first call: %d\n", res0); 
    /* returns [-1] for failure */
    printf("Return of the second call: %d\n", res1); 
    return 0;
}

And in this case (which is similar to the jme’s, but protected by the android fdsan):

#include <stdio.h>
#include <unistd.h>

static inline FILE* copy() {
    return dup(stdin);
}

int main() {
    FILE* file = copy();
    
    int res0 = fclose(stdin);
    /* returns [0] for success */
    printf("Return of the first call: %d\n", res0); 
    
    int res1 = fclose(file);
    /* returns a Segmentation fault associated with a crash */
    printf("Return of the second call: %d\n", res1); 

    return 0;
}

The double closure has also other problems like the premature closure of resources, interruption of the buffer read/write operations and etcetera, though those errors will never manifest in this case, because we aren’t exposing this API to the user, however, logical code errors should be fixed properly…