作者:wainiwann 出处: http://www.cnblogs.com/wainiwann/ 本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

摘要:本文主要介绍将FFmpeg音视频编解码库移植到Android平台上的编译和基本测试过程。

环境准备:

Ubuntu12.04 TLS

android-ndk-r9d-linux-x86_64.tar.bz2

ffmpeg2.2

---------------------------------------------------------

第一步:下载

1.配置ubuntu12.04 TLS 系统环境。

2.下载ndk版本为 r9d。

3.下载ffmpeg2.2版本。

第二步:在ubuntu下编译环境设置

1. 安装好ubuntu12.04 TLS 64位linux系统之后,可以选择安装一下内容:

在在参考一些其他有关linux下NDK环境搭建资料上看到64位ubuntu 安装之后需要再下载 bison

64位ubuntu下还需要下载 gcc-multilibg++-multilib:

终端命令:" sudo apt-get install biosn gcc-multilib g++-multilib "

2.下载ndk之后解压后目录:/home/admin/develop/android-ndk-r9d

配置NDK环境变量:

(2.) 配置NDK的环境变量:

终端内执行:“ gedit ~/.bashrc

在打开的文件末尾添加如下内容:

NDK=/home/admin/develop/android-ndk-r9d

export NDK

(3.)在当前bash环境下读取并执行 ~/.bashrc 中的命令:

终端执行:" source ~/.bashrc "

(4.)查看是否生效:

终端执行: " echo $NDK "

结果:/home/test/develop/android-ndk-r9d

(5.)测试NDK编译JNI工程:

到android-ndk-r9d 的sample目录的hello-jni 目录里

终端执行:“ $NDK/ndk-build

如果环境配置成功会生成so库的。

3.解压ffmpeg-2.2源码

将ffmpeg-2.2.tar.gz解压后拷贝到任意目录,本例是拷贝到.../android-ndk-r9d/sample/ffmpeg2.2 目录内。

拷贝之后添加" build_android.sh "文件:

#!/bin/bashSYSROOT=$NDK/platforms/android-9/arch-arm/TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64function build_one{./configure \    --prefix=$PREFIX \    --enable-shared \    --disable-static \    --disable-doc \    --disable-ffserver \    --enable-cross-compile \    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \    --target-os=linux \    --arch=arm \    --sysroot=$SYSROOT \    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \    --extra-ldflags="$ADDI_LDFLAGS" \    $ADDITIONAL_CONFIGURE_FLAG}CPU=armPREFIX=$(pwd)/android/$CPUADDI_CFLAGS="-marm"build_one

有的资料上面 build_android.sh 的前几行是这样写的:

#!/bin/bashNDK=/home/admin/develop/android-ndk-r9d SYSROOT=$NDK/platforms/android-9/arch-arm/TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64..........

因为之前已经在linux下设置NDK的环境路径,所以就不需要在build_android.sh里指定NDK的路径了。

在编译ffmpeg的时候推荐先设置NDK的环境路径到系统环境中,因为如果不设置的话,使用" NDK=/home/admin/... " 个人感觉是非常恶心的,尤其是在windows下使用cygwin编译的时候经常出现NDK路径找不到的问题,所以windows下编译最好也配置好NDK环境路径。

修改configure文件:

很多ffmpeg编译资料上面说要修改configure文件 ,说的原因是 如果不修改的话,在android上 System.loadLibrary("xxx"); 的时候个别so库无法加载的问题。

打开 ffmpeg源码内 configure 文件进行如下修改:

SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)' 替换为: SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_LINKS='$(SLIBNAME)'

第三步:在ubuntu 64位下进行编译ffmpeg源码以得到android平台 arm下能使用的那几个so库

1.给build_android.sh 和 configure 增加可执行权限:

终端执行:

$chmod+x ./build_android.sh

$chmod+x ./configure

2.给build_android.sh 和 configure 转换格式:

终端执行:(需要先安装 dos2unix)

$dos2unix ./build_android.sh

$dos2unix ./configure

3.最后编译:

终端执行:

$ ./build_android.sh

$ make

$ make install

----------------------

编译成功会在ffmpeg源码目录下生成一个“android”目录里面有编译好的 so库和 需要的头文件等等。

其中so库应该是一下几个:

libavutil-52.solibavcodec-55.solibswresample-0.solibavformat-55.solibswscale-2.solibpostproc-52.solibavfilter-4.solibavdevice-55.so

第四步:android下使用这几个库:

----------------------------------------------------

1.使用NDK里sample目录下的hello-jni 工程进行使用这几个库:

(a.)在hello-jni 源码的JNI目录下新建ffmpeglib目录,把那几个库全部拷贝到 /hello-jni/jni/ffmpeglib/ 目录下。

(b.)然后把编译好的ffmpeg的头文件全部拷贝到 /hello-jni/jni/ 目录下。

(c.)在 hello-jni.c 文件内进行使用ffmpeg:

#include <string.h>#include <jni.h>#include <libavcodec/avcodec.h>jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,                                                  jobject thiz ){    char str[25];    sprintf(str, "%d", avcodec_version());    return (*env)->NewStringUTF(env, str);}

(d.)在 HelloJni.java 文件加载so库进行调用JNI内的测试函数:

static     {                System.loadLibrary("avutil-52");        System.loadLibrary("avcodec-55");        System.loadLibrary("swresample-0");        System.loadLibrary("avformat-55");        System.loadLibrary("swscale-2");        System.loadLibrary("postproc-52");        System.loadLibrary("avfilter-4");        System.loadLibrary("avdevice-55");        System.loadLibrary("hello-jni");                }        public native String  stringFromJNI();

(e.)修改 hello-jni 源码中jni目录下的 Android.mk 文件:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := avcodec-55-ffmpeglibLOCAL_SRC_FILES := ffmpeglib/libavcodec-55.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := avdevice-55-ffmpeglibLOCAL_SRC_FILES := ffmpeglib/libavdevice-55.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := avfilter-4-ffmpeglibLOCAL_SRC_FILES := ffmpeglib/libavfilter-4.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := avformat-55-ffmpeglibLOCAL_SRC_FILES := ffmpeglib/libavformat-55.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE :=  avutil-52-ffmpeglibLOCAL_SRC_FILES := ffmpeglib/libavutil-52.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE :=  avswresample-0-ffmpeglibLOCAL_SRC_FILES := ffmpeglib/libswresample-0.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE :=  swscale-2-ffmpeglibLOCAL_SRC_FILES := ffmpeglib/libswscale-2.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE :=  postproc-52-ffmpeglibLOCAL_SRC_FILES := ffmpeglib/libpostproc-52.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := hello-jni   LOCAL_SRC_FILES := hello-jni.cLOCAL_LDLIBS := -llog -ljnigraphics -lz -landroidLOCAL_SHARED_LIBRARIES := avcodec-55-prebuilt avdevice-55-prebuilt avfilter-4-prebuilt avformat-55-prebuilt avutil-52-prebuilt swscale-2-prebuilt postproc-52-prebuilt avswresample-0-prebuiltinclude $(BUILD_SHARED_LIBRARY)

(f.)windows下使用cygwin编译hello-jni工程:

" $NDK/ndk-build "

生成 libhello-jni.so 完成。

----------------------------------------

附上ubuntu下编译好的所有so库和头文件:

http://download.csdn.net/detail/wain163/7494547

!!!==========================================

针对之前有的小伙伴说使用hello-jni测试 NDK-r9编译好的最新的FFmpeg2.2的所有so库和头文件 的时候。

在使用cygwin编译jni的时候会报错:”undefined reference to 'avcodec_version'“ 的问题,所以现在把本人在hello-jni的程序弄上来,供大家参考。

hello-jni工程地址:

http://download.csdn.net/detail/wain163/8859195

备注:

此demo需要在 HelloJni.java 中加上:

 static {                System.loadLibrary("avutil-52");        System.loadLibrary("avcodec-55");        System.loadLibrary("swresample-0");        System.loadLibrary("avformat-55");        System.loadLibrary("swscale-2");        System.loadLibrary("postproc-52");        System.loadLibrary("avfilter-4");        System.loadLibrary("avdevice-55");        System.loadLibrary("hello-jni");    }

并且需要cygwin 对jni进行编译 出so才能运行。

==========================================

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

参考资料:

http://blog.csdn.net/gobitan/article/details/22750719

作者:wainiwann 出处: http://www.cnblogs.com/wainiwann/ 本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

更多相关文章

  1. [转载]Android实现更换皮肤功能
  2. APK反编译软件以及方法
  3. Android热修复之Tinker
  4. Android数据库的操作之存储和获取
  5. Android逆向之旅---解析编译之后的AndroidManifest文件格式
  6. 网络配置 - 定制APN
  7. 收藏老罗的----------Android应用程序组件Content Provider简要
  8. Android(安卓)8.0 SystemUI下拉状态栏快捷开关
  9. 自定义属性时TypedArray的使用方法

随机推荐

  1. Python操作MySQL存储,这些你都会了吗?
  2. Scrapy框架的使用之Spider Middleware的
  3. 【SQL刷题系列】:leetcode180 Consecutive
  4. 【机器学习笔记】:大话线性回归(三)
  5. 破冰行动:敢拍好看。
  6. 别再问我Python打包成exe了!(终极版)
  7. Scrapy框架的使用之Item Pipeline的用法
  8. 【SQL刷题系列】:leetcode177 Nth Highest
  9. 【机器学习笔记】:从零开始学会逻辑回归(一
  10. 5、Shell命令脚本