ffmpeg2.2在ubuntu下使用NDK編譯——並在android工程下測試使用

做者:wainiwann
出處: http://www.cnblogs.com/wainiwann/
本文版權歸做者全部,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利.
 

摘要:本文主要介紹將FFmpeg音視頻編解碼庫移植到Android平臺上的編譯和基本測試過程。java

 

環境準備:linux

Ubuntu12.04 TLSandroid

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

ffmpeg2.2windows

---------------------------------------------------------bash

第一步:下載ide

1.配置ubuntu12.04 TLS 系統環境。函數

2.下載ndk版本爲 r9d。post

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/
本文版權歸做者全部,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利.
相關文章
相關標籤/搜索