linux下使用ndk編譯ffmpeg

來源:互聯網
上載者:User

我的環境:
OS: ubuntu 12.10
android-ndk-r7 ffmpeg: 0.8

下面是編譯步驟:
第一步:
安裝配置ndk
運行ndk-build,如果顯示如下資訊,則表示安裝成功

通過設定宏NDK_PROJECT_PATH來指定工程目錄
export NDK_PROJECT_PATH=/home/robin/Desktop/wshare/jni

第二步:下載ffmpeg源碼

第三步:
建立檔案夾jni,把ffmpeg源碼解壓至jni目錄下,用ndk編譯時間,jni目錄是必須的,否則編譯出錯。
這一步後目錄結構如下:

ndk-build 預設編譯jni下的檔案,如果它找不到該目錄,就要通過設定NDK_PROJECT_PATH來告訴它。
如果當前工作目錄是在jni目錄下或在jni的直接父目錄中,則不需要設定這個宏。

第四步:
在ffmpeg目錄下建立config_android.sh檔案,內容設定如下。需要根據原生ndk目錄做相應更改。有些參數是必須的,有些參數可以根據應用環境按需設定。

NDK_ROOT=/home/robin/Desktop/android-ndk-r7PREBUILT=${NDK_ROOT}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86PLATFORM=${NDK_ROOT}/platforms/android-14/arch-arm./configure --target-os=linux \--arch=arm \--enable-small \--enable-static \--disable-asm \--enable-armv5te \--enable-cross-compile \--disable-debug \--disable-doc \--disable-stripping \--disable-ffmpeg \--disable-ffplay \--disable-ffprobe \--disable-ffserver \--disable-encoders \--disable-muxers \--disable-devices \--disable-hwaccels \--disable-bsfs \--disable-protocols \--disable-avdevice \--disable-shared \--disable-filters \--disable-postproc \--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \--nm=$PREBUILT/bin/arm-linux-androideabi-nm \--extra-cflags="-fPIC -DANDROID" \--extra-ldflags='-L$PLATFORM/usr/lib -nostdlib' \echo "#undef restrict" >> config.hecho "#define restrict __restrict__" >> config.hecho "#undef HAVE_LRINT" >> config.hecho "#define HAVE_LRINT 1" >> config.hecho "#undef HAVE_LRINTF" >> config.hecho "#define HAVE_LRINTF 1" >> config.hecho "#undef HAVE_ROUND" >> config.hecho "#define HAVE_ROUND 1" >> config.hecho "#undef HAVE_ROUNDF" >> config.hecho "#define HAVE_ROUNDF 1" >> config.hecho "#undef HAVE_TRUNCF" >> config.hecho "#define HAVE_TRUNCF 1" >> config.h

 

第五步:
運行./config_android.sh開始進行配置
運行過程中如果出錯,可以參看config.log瞭解具體出錯原因,一般而言,出錯是由於相關目錄沒有配置正確。
configure完成後,編輯剛剛產生的config.h,找到這句
#define restrict restrict
Android的GCC不支援restrict關鍵字,於是修改成下面這樣
#define restrict
編輯libavutil/libm.h,把其中的static方法都刪除。
可以用
#if 0

#endif 注釋掉

第六步:
分別修改libavcodec、libavfilter、libavformat、libavutil、libpostproc和libswscale下的Makefile,把每個Makefile中的下面兩句刪除或注釋掉
include $(SUBDIR)../config.mak
include $(SRC_PATH)/subdir.mak

第七步:
在ffmpeg下添加一個檔案av.mk,內容如下

# LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).makinclude $(LOCAL_PATH)/../config.makOBJS :=OBJS-yes :=MMX-OBJS-yes :=include $(LOCAL_PATH)/Makefile# collect objectsOBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)OBJS += $(OBJS-yes)FFNAME := lib$(NAME)FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME))FFCFLAGS  = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch -Wno-pointer-signFFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\"ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S)ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES)))ifneq ($(ALL_S_FILES),)ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES))C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS))S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS))elseC_OBJS := $(OBJS)S_OBJS :=endifC_FILES := $(patsubst %.o,%.c,$(C_OBJS))S_FILES := $(patsubst %.o,%.S,$(S_OBJS))FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))

第八步:
添加一系列的Android.mk,在jni目錄下的內如如下:
include $(all-subdir-makefiles)
在ffmpeg目錄下,Android.mk內容如下

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscaleLOCAL_MODULE := ffmpeginclude $(BUILD_SHARED_LIBRARY)include $(call all-makefiles-under,$(LOCAL_PATH))

libavformat/Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindexLOCAL_LDLIBS := -lzLOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)

libavcodec/Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_LDLIBS := -lzLOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)

libavfilter、libavutil、libpostproc和libswscale下的Android.mk內容如下

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)

第九步:
運行ndk-build
編譯完成後,編譯器會在jni相同的目錄下建立兩個檔案夾libs, obj。編譯輸出會放在這兩個檔案夾中。

Android.mk中部分宏的說明
LOCAL_PATH := $(call my-dir)

一個Android.mk 檔案首先必須定義好LOCAL_PATH變數。它用於在開發樹中尋找源檔案。在這個例子中,宏函數’my-dir’,
由編譯系統提供,用於返回當前路徑(即包含Android.mk file檔案的目錄)。

include $( CLEAR_VARS)

CLEAR_VARS由編譯系統提供,指定讓GNU MAKEFILE為你清除許多LOCAL_XXX變數(例如 LOCAL_MODULE, LOCAL_SRC_FILES,
LOCAL_STATIC_LIBRARIES, 等等...),
除LOCAL_PATH 。這是必要的,因為所有的編譯控制檔案都在同一個GNU MAKE執行環境中,所有的變數都是全域的。

LOCAL_MODULE := hello-jni

編譯的目標對象,LOCAL_MODULE變數必須定義,以標識你在Android.mk檔案中描述的每個模組。名稱必須是唯一的,而且不包含任何空格。

注意:編譯系統會自動產生合適的首碼和尾碼,換句話說,一個被命名為'hello-jni'的共用庫模組,將會產生'libhello-jni.so'檔案。

重要注意事項:

如果你把庫命名為‘libhello-jni’,編譯系統將不會添加任何的lib首碼,也會產生 'libhello-jni.so',這是為了支援來源於Android平台的
原始碼的Android.mk檔案,如果你確實需要這麼做的話。

LOCAL_SRC_FILES := hello-jni.c

LOCAL_SRC_FILES變數必須包含將要編譯打包進模組中的C或C++原始碼檔案。注意,你不用在這裡列出標頭檔和包含檔案,因為編
譯系統將會自動為你找出依賴型的檔案;僅僅列出直接傳遞給編譯器的原始碼檔案就好。

注意,預設的C++源碼檔案的副檔名是’.cpp’. 指定一個不同的副檔名也是可能的,只要定義LOCAL_DEFAULT_CPP_EXTENSION變數,
不要忘記開始的小圓點(也就是’.cxx’,而不是’cxx’)

include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY表示編譯產生共用庫,是編譯系統提供的變數,指向一個GNU Makefile指令碼,負責收集自從上次調用
'include $(CLEAR_VARS)'以來,定義在LOCAL_XXX變數中的所有資訊,並且決定編譯什麼,如何正確地去做。還有
BUILD_STATIC_LIBRARY變數表示產生靜態庫:lib$(LOCAL_MODULE).a, BUILD_EXECUTABLE 表示產生可執行檔。

參考:
http://www.cnblogs.com/qq78292959/archive/2011/01/12/2076982.html
http://www.cnblogs.com/hibraincol/archive/2011/05/30/2063847.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.