7

I'm building an android application. Encode and decode using Opus codec. I'm using native code from here http://www.opus-codec.org/ and the wrapper from here https://github.com/jitsi/libjitsi/tree/master/src/native/opus . In Android 4.0+, I created .so file and run, everything is OK. but in Android 5.0, It crash when I call native method. Here is the detail of crash:

 java.lang.UnsatisfiedLinkError: No implementation found for long my.package.name.codec.Opus.encoder_create(int, int) (tried Java_my_package_name_codec_Opus_encoder_1create and Java_my_package_name_codec_Opus_encoder_1create__II)

I also search a lot but can't find the root cause and nobody has a same problem with me. below is my mk file, I think it useful.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

MY_MODULE_DIR       := opus

LOCAL_MODULE        := $(MY_MODULE_DIR)
LOCAL_SRC_FILES     := $(wildcard ( libopus/src/*.c \
    libopus/celt/*.c \
    libopus/celt/arm/*.c \
    libopus/silk/*.c \
    libopus/silk/arm/*.c \
    libopus/include/*.c \
    libopus/silk/fixed/*.c \
    my_package_name_codec_Opus.c ))

LOCAL_C_INCLUDES    := \
    libopus/src \
    libopus/include \
    libopus/silk \
    libopus/silk/fixed \
    libopus/silk/arm \
    libopus/celt \
    libopus/celt/arm \
    libopus \

LOCAL_CFLAGS        := -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
LOCAL_CFLAGS    += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
LOCAL_CPPFLAGS      := -DBSD=1 
LOCAL_CPPFLAGS          += -ffast-math -O3 -funroll-loops

include $(BUILD_SHARED_LIBRARY)

PS: if you need more files, please let me know.

Phu Tang
  • 415
  • 6
  • 16

1 Answers1

8

After spending a ridiculous amount of time debugging the same issue myself, enabling checkjni, running javah in order to make sure my headers match my java code, compiling with PIE - I eventually found the issue.

Android 5.0 has added opus support. This means the system already comes with a libopus.so file. When you run loadlibrary - it isn't your compiled version that's loaded, but rather the libopus.so that was bundled with Android.

Just change your library name to libmyopus.so, and this should solve your problem. MY_MODULE_DIR := myopus and ofcourse update your System.loadlibrary call as well.

  • 2
    So after a week of doing pretty much what you did, what with the check jni, using javah etc...I stumble upon this question and tried what you did. IT WORKED! Dang, man. This is a great catch! I was just about to try `System.load()` and give it an absolute path to load the library. I don't have to try that now. Ha! – praneetloke Feb 03 '15 at 02:02