2

It is an Android application related to video process. The library used is ffmpeg + x264, and compiled loosely based on the work of ffmpeg_vitamio

Compiling of ffmpeg is good, and libffmpeg.so is created according to the below:

$CC -lx264 -lm -lz -shared --sysroot=$SYSROOT -Wl,--no-undefined -Wl,-z,noexecstack $EXTRA_LDFLAGS libavutil/*.o libavutil/arm/*.o libavcodec/*.o libavcodec/arm/*.o libavformat/*.o libswresample/*.o libswresample/arm/*.o libswscale/*.o -o $PREFIX/libffmpeg.so

here libx264 to be included is a shared library, renamed from libx264.so.130

Then I put libffmpeg.so in my Android project. The compile is fine. But when running, the errors are:

05-21 13:17:45.066: E/AndroidRuntime(3973): FATAL EXCEPTION: main
05-21 13:17:45.066: E/AndroidRuntime(3973): java.lang.UnsatisfiedLinkError: Cannot load library: soinfo_link_image(linker.cpp:1635): could not load library "libx264.so.130" needed by "libffmpeg.so"; caused by load_library(linker.cpp:745): library "libx264.so.130" not found

I think when creating libffmpeg.so, I have used -lx264 I thought all link libraries will be included to the final output library.

But anyway, let me try to find out solutions. I put libx264.so or libx264.so.130 in several directories, such as in /jni, /libs, /obj etc.

Or I also tried to add -lx264 in Android.mk in the jni.

But the same error exist.

So my questions are: (1) when gcc creates a shared library, does the output .so library include the linked shared library, here libx264.so?

(2) What is wrong with my above project?

Nick Andriopoulos
  • 10,313
  • 6
  • 32
  • 56
user1914692
  • 3,033
  • 5
  • 36
  • 61

2 Answers2

3
  1. When GCC creates a shared library, the output.so will not include the linked libraries, that happens only for static libraries, although the output.so will have a dynamic section saying what all libraries are needed for it to be linked properly.if you run

    readelf -d libffmpeg.so

    it will show what all libraries are needed by it. Now the linker tries to link and load all the needed libraries. In your case it cant find libx264.so.130 because it is not included in your project.

  2. I have'nt tried what you are doing, but copying library to jni or lib folder won't help I believe, you will have to include it in you make file as PREBUILT_SHARED_LIBRARY. I think this link might have the solution to your problem. How can i link prebuilt shared Library to Android NDK project?

Community
  • 1
  • 1
digitizedx
  • 386
  • 5
  • 16
  • Where should add shared library finally?! PREBUILT_SHARED_LIBRARY ? LOCAL_JNI_SHARED_LIBRARIES ? LOCAL_SHARED_LIBRARIES ? – Dr.jacky Oct 14 '15 at 12:00
1

@digitzedx, I think your answer is very right. So I follow the instruction to add prebuild library for libx264.so, as I did for libffmpeg.so

include $(CLEAR_VARS)
LOCAL_MODULE := libx264_prebuilt
LOCAL_SRC_FILES := libx264.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

And then:

# Note: I have put commands for ffmpeg_prebuilt
LOCAL_SHARED_LIBRARIES := ffmpeg_prebuilt
LOCAL_SHARED_LIBRARIES += libx264_prebuilt
LOCAL_LDLIBS += -llog -ljnigraphics -lz -dl -lx264
include $(BUILD_SHARED_LIBRARY)

In the Android src, add

System.loadLibrary("x264")
System.loadLibrary("ffmpeg")
System.loadLibrary("native_sample")

Building the project shows on the Console that: Install libffmpeg.so, libnative_sample.so, libx264.so in libs/armeabi-v7a, where libnative_sample.so is my jni program.

Again, the same error exists: libx264.so.130 not found

I tried to use different orders of LOCAL_LDLIBS, it does not change.

Stuck here. Help!

I think maybe the problem is at: it is looking for libx264.so.130, but I can only name the library as libx264. But readelf -d shows that the SONAME in libx264.so is libx264.so.130 Not sure what the systme is looking for, the file name, or the SONAME in the file?

user1914692
  • 3,033
  • 5
  • 36
  • 61
  • OK, I find a simple workaround after looking at one post "Android JNI, how to load library with soname libxx.so.1.2.3". I copy the libx264.so.130 into the storage of the device, and use System.load("libx264.so.130"). Now it works! – user1914692 May 22 '13 at 22:52
  • I am thinking maybe I could also change the ELF of the libffmpeg.so, to change its dependent on libx264.so.130 to libx264.so. Is it plausible? I find solutions here: http://stackoverflow.com/questions/2759254/how-can-i-change-the-filename-of-a-shared-library-after-building-a-program-that But I haven' tried it. – user1914692 May 22 '13 at 23:24
  • Where should add shared library finally?! PREBUILT_SHARED_LIBRARY ? LOCAL_JNI_SHARED_LIBRARIES ? LOCAL_SHARED_LIBRARIES ? – Dr.jacky Oct 14 '15 at 12:00