1. 程式人生 > >FFmpeg的Android平臺移植—編譯篇

FFmpeg的Android平臺移植—編譯篇

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

環境準備:

Ubuntu12.04 TLS

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

ffmpeg3.0

第一步:下載

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

2.下載ndk版本為 r9d。

3.下載ffmpeg3.0版本。

第二步:在ubuntu下編譯環境設定

1. 安裝好ubuntu12.04 TLS 32位linux系統之後,可以選擇安裝一下內容:

32位ubuntu下還需要下載 gcc-multilib 和g++-multilib:

檢視系統是否安裝

gcc-multilib 和g++-multilib dpkg -l|grep gcc 和  dpkg -l|grep g++

終端命令:" sudo apt-get install bison gcc-multilib g++-multilib "

2.下載ndk之後解壓後目錄:/home/tan/work/android/tools/android-ndk-r9d

3.解壓ffmpeg-3.0原始碼

將ffmpeg-3.0.tar.gz解壓後拷貝到任意目錄,本例是拷貝到.../android-ndk-r9d/sample/ffmpeg3.0 目錄內。

拷貝之後新增" 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 的前幾行是這樣寫的:

修改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 32位下進行編譯ffmpeg原始碼以得到android平臺 arm下能使用的那幾個so庫

1.給build_android.sh 和 configure 增加可執行許可權:

終端執行:

“ $chmod+x ./build_android.sh ”

 $chmod+x ./configure ”

2.最後編譯:

終端執行:

“ $ ./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 完成。