最近在mac下用ndk交叉編譯最ffmpeg出問(wèn)題首有,總是顯示用系統(tǒng)的gcc而不是ndk的toolchain的交叉編譯gcc來(lái)編譯的贪嫂。之前明明沒(méi)問(wèn)題的胞皱,可能是由于最近升級(jí)macOS導(dǎo)致的舌界。由于對(duì)這方面實(shí)在沒(méi)太多經(jīng)驗(yàn),我試了下直接切到Android虛擬機(jī)下編譯忘蟹,編譯通過(guò)飒房。
記錄一下步驟
x264和ffmpeg的目錄平行放置,然后各自的腳本放在各自的文件夾里
1.編譯x264
x264好久沒(méi)更新了媚值,用最新的版本編譯即可
#!/bin/bash
NDK=$ANDROID_NDKPLATFORM=$NDK/platforms/android-8/arch-arm
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64
function build_one{
./configure --prefix=$PREFIX \
--enable-static \
--enable-shared \
--enable-pic \
--disable-asm \
--disable-cli \
--host=arm-linux \
--sysroot=$PLATFORM \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi-
make clean
make -j4
make install
}
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
build_one
2.編譯ffmpeg
a.修改一下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)'
參考:
http://linyehui.me/2014/05/09/how-to-build-ffmpeg-for-android-on-mac.html
b.腳本:
#!/bin/bash
# this is build file for linux
export NDK_9B="/vagrant_data/android-ndk-r9b"
echo "start building on linux..."
NDK=$NDK_9B
PLATFORM=$NDK/platforms/android-19/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64
X264_ANDROID=/vagrant_data/ffmpeg_build/yolo-ffmpeg-x264/x264/android
function build_one
{
./configure \
--prefix=$PREFIX \
--enable-static \
--enable-shared \
--disable-doc \
--disable-asm \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--enable-cross-compile \
--sysroot=$PLATFORM \
--enable-encoder=aac \
--enable-decoder=aac \
--enable-encoders \
--enable-decoder=h264 \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4
make install
}
CPU=arm
PREFIX=$(pwd)/android/$CPU/
ADDI_CFLAGS="-marm -I$X264_ANDROID/include" # -DANDROID
ADDI_LDFLAGS="-L$X264_ANDROID/lib"
# build_one
echo ""
echo "arm-linux-androideabi-ar ing..."
$TOOLCHAIN/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o
echo ""
echo "arm-linux-androideabi-ld ing..."
$TOOLCHAIN/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib \
-L$PLATFORM/usr/lib \
-L$PREFIX/lib \
-L$X264_ANDROID/arm/lib \
-soname libffmpeg.so \
-shared \
-nostdlib \
-z noexecstack \
-Bsymbolic\
--whole-archive \
--no-undefined \
-o $PREFIX/libffmpeg.so \
libavcodec/libavcodec.a \
libavformat/libavformat.a \
libavutil/libavutil.a \
libswscale/libswscale.a \
libswresample/libswresample.a \
$X264_ANDROID/arm/lib/libx264.a \
-lc -lm -lz -ldl -llog \
--dynamic-linker=/system/bin/linker $TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.8/libgcc.a
echo ""
echo "striping"
$TOOLCHAIN/bin/arm-linux-androideabi-strip --strip-unneeded $PREFIX/libffmpeg.so
echo ""
echo "strip over"
遇到的問(wèn)題:
1.text reallocation
這個(gè)在ffmpeg 2014.12.9號(hào)有一個(gè)commit修正了情屹,采用之后的版本即可
參考:http://stackoverflow.com/questions/34691970/ffmpeg-for-android-neon-build-has-text-relocations
x86的好像還是還有這個(gè)問(wèn)題,但是Android用的都是Arm架構(gòu)杂腰,我們就不多操心了
2.multiple definition
子問(wèn)題1
libavcodec/log2_tab.o: multiple definition of'ff_log2_tab'解決辦法
新增文件libavutil/log2_tab.h, 其內(nèi)容如下
#ifndef AV_LOG2TAB_H
#define AV_LOG2TAB_H
#include <stdint.h>
extern const uint8_t ff_log2_tab[256];
#endif
將所有報(bào)上述類似錯(cuò)誤的, 做如下修改
如:修改 libavcodec/log2_tab.c,將log2_tab.c改為log2_tab.h
// #include"libavutil/log2_tab.c"
#include "libavutil/log2_tab.h"
子問(wèn)題2
error: libavformat/golomb_tab.o: multipledefinition of 'ff_interleaved_dirac_golomb_vlc_code'解決方法
修改libavformat/golomb_tab.c, 如下:
// #include "libavcodec/golomb.c"
#include "libavcodec/golomb.h"
子問(wèn)題3
obj/local/armeabi-v7a/libavutil.a(reverse.o):multiple definition of 'ff_reverse'
/obj/local/armeabi-v7a/libavcodec.a(reverse.o):previous definition here 解決方法
新增文件libavutil/reverse.h, 其內(nèi)容如下
#ifndef AV_REVERSE_WR_H
#define AV_REVERSE_WR_H
#include <stdint.h>
extern const uint8_t ff_reverse[256];
#endif //AV_REVERSE_WR_H
將所有報(bào)上述類似錯(cuò)誤的椅文, 做如下修改
如:修改libavutil/reverse.c, reverse.reverse.h
// #include "libavutil/reverse.c"
#include "libavutil/reverse.h"
}
Note:
關(guān)于text reallocation喂很,網(wǎng)上有流傳的解法是加上--disable-asm,但是這種方法會(huì)給ffmpeg帶來(lái)非常嚴(yán)重的性能損失(網(wǎng)上這么說(shuō)的,我沒(méi)測(cè))皆刺,所以不要考慮這種方法少辣,而且貌似有人測(cè)過(guò)據(jù)說(shuō)也不一定能解決text reallocation的問(wèn)題