Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 環境下編譯FFmpeg

Android 環境下編譯FFmpeg

編輯:關於Android編程

開發環境:Ubuntu 12.04.2 LTS , android-sdk-linux, android-ndk-r8e

一 、X264 編譯

1、 X264源碼下載

git clone git://git.videolan.org/x264.git

2、 環境配置

在X264根目錄下創建文件config.sh 內容如下

#!/bin/sh

ANDROID_NDK_ROOT=$NDK_HOME

PREBUILT=$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86

PLATFORM=$ANDROID_NDK_ROOT/platforms/android-9/arch-arm

ARM_INC=$PLATFORM/usr/include

ARM_LIB=$PLATFORM/usr/lib

ARM_LIBO=$PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3

 

./configure --disable-gpac --enable-pic --enable-strip \

--extra-cflags=" -I$ARM_INC -fPIC -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp -mfpu=neon -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -Wno-psabi -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wa,--noexecstack -MMD -MP " \

--extra-ldflags="-nostdlib -Bdynamic -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$ARM_LIB -nostdlib $ARM_LIB/crtbegin_dynamic.o $ARM_LIB/crtend_android.o -lc -lm -ldl -lgcc" \

--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \

--host=arm-linux \

--enable-static \

--prefix='dist'

 

運行config.sh文件

 

配置關鍵點1:指定使用的交叉編譯的編譯器、鏈接的頭文件及類庫所在

配置關鍵點2:-march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp -mfpu=neon -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ ,此處,針對armv7-a的CPU打開了NEON的優化運行指令。

配置關鍵點3:去掉--disable-asm選項。該選項的意思就是禁止neon的指令。

配置關鍵點4:添加--enable-static選項,生成靜態鏈接的庫供程序開發使用

 

3、 編譯

直接:make

然後:make install

 

說明:ffmpeg不支持H264編碼,這裡要添加X264庫,來支持H264編碼

 

參考:http://www.2cto.com/kf/201303/194658.html

二 、fdk-aac 編譯

1、 fdk-aac下載

a) http://sourceforge.net/projects/opencore-amr/files/fdk-aac/

b) fdk-aac-0.1.2.tar.gz

2、 fdk-aac 編譯環境配置

a) 解壓,在fdk-aac跟目錄下創建config.sh文件內容如下

#!/bin/sh

ANDROID_API=android-9

SYSROOT=$NDK_HOME/platforms/$ANDROID_API/arch-arm

ANDROID_BIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/

CROSS_COMPILE=${ANDROID_BIN}/arm-linux-androideabi-

#export PATH=$PATH:$ANDROID_SDK/tools:$ANDROID_SDK/platform-tools

 

ARM_INC=$SYSROOT/usr/include

ARM_LIB=$SYSROOT/usr/lib

 

LDFLAGS=" -nostdlib -Bdynamic -Wl,--whole-archive -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$NDK_HOME/sources/cxx-stl/gnu-libstdc++/libs/armeabi -L$NDK_HOME/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/arm-linux-androideabi/lib -L$ARM_LIB -lc -lgcc -lm -ldl "

FLAGS="--host=arm-androideabi-linux --enable-static --disable-shared"

 

export CXX="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}"

export LDFLAGS="$LDFLAGS"

export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"

 

./configure $FLAGS \

--prefix='/home/zhangcb/works/mediaeffectplayer/android/fdk-aac-0.1.2/dist'

運行config.sh文件

3、 編譯

直接:make

然後:make install

說明:

FFmpeg從2.0開始自帶的AAC編碼

需要的格式是sample_fmts = AV_SAMPLE_FMT_FLTP,不符合android音頻的格式

(AV_SAMPLE_FMT_S8, AV_SAMPLE_FMT_S16),所有我們用ffmpeg錄制的時候需要用

外部擴展的第三方庫文件來編碼,這裡綜合考慮用fdk-aac來編碼

 

參考:https://trac.ffmpeg.org/wiki/AACEncodingGuide

 

、ffmpeg 編碼

1. Ffmpeg 下載

a) http://www.ffmpeg.org/download.html 下載地址

b) 下載最新的ffmpeg-2.0.1.tar.gz

2. 在ffmpeg中添加Android編譯文件

1) 在ffmpeg目錄下添加文件av.mk 內容如下:

# LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale

 

#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak

include $(LOCAL_PATH)/../config.mak

 

OBJS :=

OBJS-yes :=

MMX-OBJS-yes :=

include $(LOCAL_PATH)/Makefile

 

# collect objects

OBJS-$(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-sign

FFCFLAGS += -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))

else

C_OBJS := $(OBJS)

S_OBJS :=

endif

 

C_FILES := $(patsubst %.o,%.c,$(C_OBJS))

S_FILES := $(patsubst %.o,%.S,$(S_OBJS))

 

FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))

2) 分別修改

libavdevice libpostproc libavfilter libavformat libswresample libavresample libswscale libavcodec libavutil 下的Makefile 文件

把下面一句刪除

include $(SUBDIR)../config.mak

 

3) 在ffmpeg目錄下,創建Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

 

#begin package so file

#LOCAL_WHOLE_STATIC_LIBRARIES := libavformat libavcodec libavutil libswscale

#LOCAL_MODULE := ffmpeg

 

#include $(BUILD_SHARED_LIBRARY)

#end package

 

include $(call all-makefiles-under,$(LOCAL_PATH))

 

創建libavformat/Android.mk

 

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES := \

$(LOCAL_PATH) \

$(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex

LOCAL_LDLIBS := -lz

LOCAL_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.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES := \

$(LOCAL_PATH) \

$(LOCAL_PATH)/arm \

$(LOCAL_PATH)/.. \

$(X264_HOME)/dist/include \

$(AAC_HOME)/dist/include

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_LDFLAGS += $(X264_HOME)/dist/lib/libx264.a -O2

LOCAL_LDFLAGS += $(AAC_HOME)/dist/lib/libfdk-aac.a -O2

LOCAL_LDLIBS := -lz

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

 

分別創建libpostproc libavfilter libswresample libavresample libswscale libavutil

下的Android.mk內容如下

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES := \

$(LOCAL_PATH) \

$(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

 

回到 jni 目錄 添加文件Android.mk

PROJECT_PATH = $(shell pwd)

X264_HOME = $(PROJECT_PATH)/../x264

AAC_HOME = $(PROJECT_PATH)/../fdk-aac-0.1.2

include $(all-subdir-makefiles)

4)

3. 編碼環境配置

在ffmpeg目錄下創建config.sh文件內容如下

#!/bin/bash

PROJECT_PATH=/home/zhangcb/works/mediaeffectplayer/android/CmmobiVideo

ANDROID_NDK_ROOT=$NDK_HOME

PREBUILT=$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86

PLATFORM=$ANDROID_NDK_ROOT/platforms/android-9/arch-arm

ARM_LIBO=$PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3

X264_HOME=$PROJECT_PATH/../x264

AAC_HOME=$PROJECT_PATH/../fdk-aac-0.1.2

 

./configure --target-os=linux \

--arch=arm \

--enable-version3 \

--enable-gpl \

--enable-nonfree \

--disable-shared \

--disable-stripping \

--disable-ffmpeg \

--disable-ffplay \

--disable-ffserver \

--disable-ffprobe \

--disable-protocols \

--enable-protocol=file \

--enable-protocol=udp \

--enable-protocol=tcp \

--enable-protocol=http \

--enable-network \

--enable-encoders \

--enable-decoders \

--enable-muxers \

--disable-avdevice \

--disable-indevs \

--disable-filters \

--disable-devices \

--disable-parsers \

--disable-postproc \

--disable-debug \

--enable-cross-compile \

--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \

--extra-cflags=" -fPIC -DANDROID -I$PLATFORM/usr/include -I$X264_HOME/dist/include -I$AAC_HOME/dist/include" \

--disable-asm \

--disable-yasm \

--enable-libx264 \

--enable-libfdk-aac \

--enable-neon \

--enable-armv5te \

--sysinclude=$PLATFORM/usr/include \

--extra-ldflags="-Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -L$ARM_LIBO -lc -lm -ldl -lgcc -L$X264_HOME/dist/lib -L$AAC_HOME/dist/lib" \

--extra-libs="-lgcc" \

 

sed -i 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.h

sed -i 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.h

sed -i 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.h

sed -i 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.h

sed -i 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.h

sed -i 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.h

sed -i 's/restrict restrict/restrict/g' config.h

sed -i 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.h

sed -i 's/HAVE_CBRTF 0/HAVE_CBRTF 1/g' config.h

sed -i 's/HAVE_ISINF 0/HAVE_ISINF 1/g' config.h

sed -i 's/HAVE_ISNAN 0/HAVE_ISNAN 1/g' config.h

sed -i 's/HAVE_SINF 0/HAVE_SINF 1/g' config.h

sed -i 's/HAVE_RINT 0/HAVE_RINT 1/g' config.h

 

運行config.sh生產文件

 

打開 libavutil/parseutils.h,把 #include <time.h> 替換為 #include <sys/../time.h> 不然會報錯

4. Ffmpeg編碼

運行:ndk-build 生成文件

 

libavcodec.a libavfilter.a libavutil.a libpostproc.a libswresample.a

libavdevice.a libavformat.a libswscale.a

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved