在Linux环境下编译Android下的最新版ffmpeg+x264单个动态库(.so)

最近在mac下用ndk交叉编译最ffmpeg出问题,总是显示用系统的gcc而不是ndk的toolchain的交叉编译gcc来编译的。之前明明没问题的,可能是由于最近升级macOS导致的。由于对这方面实在没太多经验,我试了下直接切到Android虚拟机下编译,编译通过。
记录一下步骤

x264和ffmpeg的目录平行放置,然后各自的脚本放在各自的文件夹里

1.编译x264

x264好久没更新了,用最新的版本编译即可

#!/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"

遇到的问题:

1.text reallocation

这个在ffmpeg 2014.12.9号有一个commit修正了,采用之后的版本即可
参考:http://stackoverflow.com/questions/34691970/ffmpeg-for-android-neon-build-has-text-relocations
x86的好像还是还有这个问题,但是Android用的都是Arm架构,我们就不多操心了

2.multiple definition

子问题1

libavcodec/log2_tab.o: multiple definition of'ff_log2_tab'解决办法
新增文件libavutil/log2_tab.h, 其内容如下

#ifndef AV_LOG2TAB_H
#define AV_LOG2TAB_H

#include 
extern const uint8_t ff_log2_tab[256];

#endif

将所有报上述类似错误的, 做如下修改

如:修改 libavcodec/log2_tab.c,将log2_tab.c改为log2_tab.h

// #include"libavutil/log2_tab.c"
#include "libavutil/log2_tab.h"
子问题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"
子问题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, 其内容如下

#ifndef AV_REVERSE_WR_H
#define AV_REVERSE_WR_H

#include 
extern const uint8_t ff_reverse[256];

#endif //AV_REVERSE_WR_H

将所有报上述类似错误的, 做如下修改

如:修改libavutil/reverse.c, reverse.reverse.h

// #include "libavutil/reverse.c"
#include "libavutil/reverse.h"
}
Note:

关于text reallocation,网上有流传的解法是加上--disable-asm,但是这种方法会给ffmpeg带来非常严重的性能损失(网上这么说的,我没测),所以不要考虑这种方法,而且貌似有人测过据说也不一定能解决text reallocation的问题

你可能感兴趣的