William Seemann
William Seemann

Reputation: 3530

Using openssl with FFmpeg on Android with NDK

I cross compiled FFmpeg with openssl support using the scripts from the Guardian project however my code crashes whenever I execute the following:

System.loadLibrary("crypto");    // loads OK
System.loadLibrary("ssl");       // loads OK
System.loadLibrary("avformat");  // crashes

The error:

dlopen("/data/data/wseemann.media.demo/lib/libavformat.so") failed: dlopen failed: cannot locate symbol "SSL_library_init" referenced by "libavformat.so"...

I build libavformat with a toolchain and then run ndk-build using the following Android.mk file to create the .so files:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libswscale
LOCAL_SRC_FILES := ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavcodec
LOCAL_SRC_FILES := ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavformat
LOCAL_SRC_FILES := ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavutil
LOCAL_SRC_FILES := ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

LOCAL_PATH:= $(call my-dir)

It would seem that libavformat needs libcrypto and libssl when it is loaded but it can't find them or isn't loading them. Does anyone know how to fix this issue?

Upvotes: 0

Views: 1299

Answers (2)

Michael N
Michael N

Reputation: 559

This worked for me in FFmpegMediaPlayer.java line 614:

static {

    System.loadLibrary("crypto");    // loads OK
    System.loadLibrary("ssl");       // loads OK

    for (int i = 0; i < JNI_LIBRARIES.length; i++) {

        Log.d("TAG", JNI_LIBRARIES[i]);

        System.loadLibrary(JNI_LIBRARIES[i]);

    }

    native_init();

}

Upvotes: 0

Alex Cohn
Alex Cohn

Reputation: 57203

The problem is that there normally is libssl.so in /system/lib. The loader System.loadLibrary() prefers that path to your app lib directory (/data/data/your.package.name/lib), and this is what may cause confusion. The easiest fix is to use System.load("/data/data/your.package.name/lib/libssl.so") instead (there are correct ways to obtain the path, too).

Another fix could be to rename libssl.so that you prepared, to libavssl.so, and call System.loadLibrary("avssl"). Note that maybe you will be required to recompile libavformat so that it looks for libavssl.so.

Upvotes: 1

Related Questions