zoukankan      html  css  js  c++  java
  • ffmpeg2.2在ubuntu下使用NDK编译——并在android工程下测试使用

    作者: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 bison 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/bash
    SYSROOT=$NDK/platforms/android-9/arch-arm/
    TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64
    
    function 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=arm
    PREFIX=$(pwd)/android/$CPU
    ADDI_CFLAGS="-marm"
    build_one

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

    #!/bin/bash
    NDK=/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.so
    libavcodec-55.so
    libswresample-0.so
    libavformat-55.so
    libswscale-2.so
    libpostproc-52.so
    libavfilter-4.so
    libavdevice-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>
    
    
    jstring
    Java_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-ffmpeglib
    LOCAL_SRC_FILES := ffmpeglib/libavcodec-55.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := avdevice-55-ffmpeglib
    LOCAL_SRC_FILES := ffmpeglib/libavdevice-55.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := avfilter-4-ffmpeglib
    LOCAL_SRC_FILES := ffmpeglib/libavfilter-4.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := avformat-55-ffmpeglib
    LOCAL_SRC_FILES := ffmpeglib/libavformat-55.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE :=  avutil-52-ffmpeglib
    LOCAL_SRC_FILES := ffmpeglib/libavutil-52.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE :=  avswresample-0-ffmpeglib
    LOCAL_SRC_FILES := ffmpeglib/libswresample-0.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE :=  swscale-2-ffmpeglib
    LOCAL_SRC_FILES := ffmpeglib/libswscale-2.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE :=  postproc-52-ffmpeglib
    LOCAL_SRC_FILES := ffmpeglib/libpostproc-52.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := hello-jni   
    LOCAL_SRC_FILES := hello-jni.c
    
    LOCAL_LDLIBS := -llog -ljnigraphics -lz -landroid
    LOCAL_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-prebuilt
    
    include $(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/
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    线程运行boost库在工作(22)任务之二
    vi 帮助文档 man vi
    跳槽关系三国演义告诉我们的60条真理
    后台端口虚拟主机wdcp的相关问题以及解决方法
    格式化字符串android 格式化时间
    对象查询HQL多表联合查询的问题
    myeclipse8.6中svn插件的安装
    乱码解决方法
    Restfull风格是什么意思?
    poj3013
  • 原文地址:https://www.cnblogs.com/wainiwann/p/3785485.html
Copyright © 2011-2022 走看看