前言
这两天折腾ffmpeg库的移植,好不容易成功生成libffmpeg.so, 准备验证此库是否可正常使用。 so库在android下的使用一般要通过jni调用来实现,可是我们哪里知道libffmpeg.so的jni native接口是怎么样的。 显然直接调用libffmpeg.so看此来是比较麻烦的,所以就想能不能像在linux下面直接简单的一个hello.c文件里面有个main主函数,函数里面有个avcodec_version(),用printf把avcodec_version()的值打印出来。就这样一个简单的小程序(hello),让它在Android下面跑(adb shell中./hello),我再看看是否可以正常输出。如果可以,意味着生成的libffmpeg.so在某种程度上是可用的。
废话不说了,直接开始。
环境
编译环境: Ubuntu 11.04 desktop 32bit
Android NDK :android-ndk-r6-crystax-2-linux-x86
FFMPEG : 1.2.1
Android Emulator: 4.0.3
我们的目标,创建一个如上所述的hello小程序。因为是要在Android跑的,自然要用上Android NDK。
先来看看要用上的文件:
创建一个文件夹hello,里面再创建一个jni文件夹,jni文件夹里面内容如上图: ffmpeg(ffmpeg源码)、Android.mk及hello.c 。
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg
LOCAL_C_INCLUDES += $(PATH_TO_FFMPEG_SOURCE)
LOCAL_LDLIBS := -L/home/minz/ffmpeg-1.2.1-transplant-singledynamic -lffmpeg
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
include $(BUILD_EXECUTABLE)
其中libffmpeg.so放在 /home/minz/ffmpeg-1.2.1-transplant-singledynamic 目录下,根据实际情况请自行修改
hello.c:
#include
#include "ffmpeg/libavcodec/avcodec.h"
int main() {
char str[50];
sprintf(str, "%d", avcodec_version());
printf("avcodec_version(): %s\n", str);
return 0;
}
终端下定位到hello目录中输入
# ~/android-ndk-r6-crystax-2/ndk-build
编译生成成功,到hello/libs/armeabi/下找到hello就是你要的东西。
直接试试 ./hello , 你会发现返回: bash: ./hello: cannot execute binary file 。 不要忘了这个东西是要的android上跑的,自然不能在这边跑了。
下面就是在android下面跑hello了。
PS: 我的Ubuntu是装在虚拟机的, 所以刚才生成的 hello 和 编译好的libffmpeg.so 我先拷贝出来到Windows上了。
先运行模拟器, cmd进入android sdk相应位置, adb shell , 返回 # 说明你目前是root权限。
然后,怎么运行呢?也许你会说随便把hello文件放进/sdcard某个位置,再./hello 。 但事实上/sdcard上是没有执行权限的,所以我们可以这样做。
把 hello 放进 /data/local/tmp , 因为这个目录下通过shell会有执行权限,即 adb push e:\hello /data/local/tmp/hello
然后
adb shell
# cd /data/loca/tmp
# ./hello
你会发现得到一个错误
./hello
link_image[1936]: 2641 could not load needed library 'libffmpeg.so' for './hell
o' (load_library[1091]: Library 'libffmpeg.so' not found)CANNOT LINK EXECUTABLE
那是因为我们libffmpeg.so还没有放进去。 libffmpeg.so需要放入/system/lib后,hello才可执行。可是,默认情况下,/system下是没有写权限,所以你直接 adb push e:\libffmpeg.so /system/lib/libffmpeg.so是不可行的, 需要重新挂载 /system才可以。 先来看看当前模拟中挂载的情况,
# mount
看到没有, 我们的/system 是ro , 只有读的权限。 而sdcard是没有执行权限的。
所以我们来重新挂载设备,# mount -o remount,rw -t yaffs2 /dev/block/mtdblock0 /system
再用mount看下可以发现/system现在是rw了, 即可读可写。 接着把我们的libffmpeg.so拷贝进去 adb push e:\libffmpeg.so /system/lib/libffmpeg.so
回到/data/local/tmp目录下, ./hello 看看结果 :
成功返回。 3563596是我们ffmpeg版本对应的整数 。
转载请注明出处: http://blog.csdn.net/oathevil/article/details/17043191