折腾了2天,终于编译成功,不容易啊。
据说Linux下比windows的简单,windows下问题太多,会搞崩溃,真的是这样。在崩溃边缘尝试ubuntu下编译,果然轻松不少。最后不想放弃,还是坚持在windows下也编译通过。
我的编译环境:
win8.1,cygwin1.7,ndk-r9d,ffmpeg2.2.2
首先搭建环境
export NDK
接下来就可以编译ffmpeg了
编译过程网上很多,这里稍微简述下,主要是对碰到的问题及解决办法做个总结。
一、创建个人文件夹,底下再创建jni文件夹,把下载的ffmpeg源码解压至jni下,改个名,我的路径是E:\Android\mPlayer\jni\ffmpeg
二、创建config.sh和各个Android.mk,我是直接从网上down的,有坑,后面来填
三、cygwin下cd到ffmpeg,执行config.sh
报错:
/cygdrive/e/Tools/Java/android/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-gcc is unable to create an executable file.
C compiler test failed.
解决办法:
export TMPDIR=e:/Tools/cygwin64/tmp 设置临时目录,
还是报错,把config.sh里的PREBUILT和PLATFORM改成绝对路径:
PREBUILT=E:/Tools/Java/android/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64
PLATFORM=E:/Tools/Java/android/android-ndk-r9d/platforms/android-19/arch-arm
执行完成后,在ffmpeg目录下生成了config.h, config.mak
四、cd到mPlayer,执行${NDK}/ndk-build开始编译,${NDK}是之前配置的环境变量
下面是编译时的各种报错及最终的解决办法:
1. jni/ffmpeg/libavcodec/Makefile:1: ../config.mak: No such file or directory
jni/ffmpeg/libavfilter/Makefile:1: ../config.mak: No such file or directory
jni/ffmpeg/libavformat/Makefile:1: ../config.mak: No such file or directory
jni/ffmpeg/libavutil/Makefile:1: ../config.mak: No such file or directory
jni/ffmpeg/libpostproc/Makefile:1: ../config.mak: No such file or directory
jni/ffmpeg/libswscale/Makefile:1: ../config.mak: No such file or directory
处理方法:
将libavcodec, libavfilter, libavformat, libavutil, libpostproc, libswscale目录下Makefile的include $(SUBDIR)../config.mak注释掉
2. /cygdrive/e/Tools/Java/android/android-ndk-r9d/build/core/build-binary.mk:120: *** target file 'clean' has both : and :: entries。 停止。
处理方法:
ffmpeg/libavfilter/Makefile 最后面 clean:
$(RM) $(CLEANSUFFIXES:%=libavfilter/libmpcodecs/%) 去掉
3. jni/ffmpeg/libavformat/../libavutil/libm.h:52:32: error: static declaration of 'cbrt' follows non-static declaration
jni/ffmpeg/libavformat/../libavutil/libm.h:59:31: error: static declaration of 'cbrtf' follows non-static declaration
jni/ffmpeg/libavformat/../libavutil/libm.h:86:38: error: expected identifier or '(' before 'sizeof'
jni/ffmpeg/libavformat/../libavutil/libm.h:86:38: error: expected ')' before '?' token
jni/ffmpeg/libavformat/../libavutil/libm.h:96:38: error: expected identifier or '(' before 'sizeof'
jni/ffmpeg/libavformat/../libavutil/libm.h:96:38: error: expected ')' before '?' token
jni/ffmpeg/libavformat/../libavutil/libm.h:141:22: error: static declaration of 'rint' follows non-static declaration
jni/ffmpeg/libavformat/../libavutil/libm.h:148:43: error: static declaration of 'lrint' follows non-static declaration
jni/ffmpeg/libavformat/../libavutil/libm.h:155:43: error: static declaration of 'lrintf' follows non-static declaration
jni/ffmpeg/libavformat/../libavutil/libm.h:162:41: error: static declaration of 'round' follows non-static declaration
jni/ffmpeg/libavformat/../libavutil/libm.h:169:40: error: static declaration of 'roundf' follows non-static declaration
jni/ffmpeg/libavformat/../libavutil/libm.h:176:41: error: static declaration of 'trunc' follows non-static declaration
jni/ffmpeg/libavformat/../libavutil/libm.h:183:40: error: static declaration of 'truncf' follows non-static declaration
处理方法:
把ffmpeg/libavutil/libm.h 里的所有static方法全都注释掉
4. E:/Tools/Java/android/android-ndk-r9d/platforms/android-19/arch-arm/usr/include/stdlib.h:54:14: error: expected identifier or '(' before 'void'
E:/Tools/Java/android/android-ndk-r9d/platforms/android-19/arch-arm/usr/include/stdlib.h:54:14: error: expected ')' before numeric constant
处理方法:
修改config.sh ,--extra-cflags="-I${PLATFORM}/usr/include -fPIC -DANDROID -std=c99 " \
5. In file included from jni/ffmpeg/libavcodec/aacdec.c:84:0:
jni/ffmpeg/libavcodec/../libavutil/float_dsp.h:148:50: error: expected ';', ',' or ')' before 'v1'
jni/ffmpeg/libavcodec/aacdec.c: In function 'apply_mid_side_stereo':
jni/ffmpeg/libavcodec/aacdec.c:1982:29: error: 'AVFloatDSPContext' has no member named 'butterflies_float'
处理方法:
修改config.h #define av_restrict restrict改为#define av_restrict
6. jni/ffmpeg/libavutil/parseutils.c:555:15: error: storage size of 'dt' isn't known
jni/ffmpeg/libavutil/parseutils.c:650:20: error: variable 'dt2' has initializer but incomplete type
jni/ffmpeg/libavutil/parseutils.c:650:38: error: invalid type argument of unary '*' (have 'int')
jni/ffmpeg/libavutil/parseutils.c:650:54: error: invalid type argument of unary '*' (have 'int')
jni/ffmpeg/libavutil/parseutils.c:650:23: error: storage size of 'dt2' isn't known
处理方法:
libavutil下time.h改名为avtime.h,
libavcodec,libavforma,libavutil下所有调用了libavutil/time.h的.c文件里,把#include里的libavutil/time.h统统改为avtime.h。
7. in function id3v2_read_internal.part.0:jni/ffmpeg/libavformat/id3v2.c:838: error: undefined reference to 'uncompress'
in function matroska_decode_buffer:jni/ffmpeg/libavformat/matroskadec.c:1181: error: undefined reference to 'inflateInit_'
in function matroska_decode_buffer:jni/ffmpeg/libavformat/matroskadec.c:1189: error: undefined reference to 'inflateEnd'
in function matroska_decode_buffer:jni/ffmpeg/libavformat/matroskadec.c:1196: error: undefined reference to 'inflate'
in function matroska_decode_buffer:jni/ffmpeg/libavformat/matroskadec.c:1201: error: undefined reference to 'inflateEnd'
处理方法:
ffmpeg目录下Android.mk把LOCAL_WHOLE_STATIC_LIBRARIES改为LOCAL_SHARED_LIBRARIES,
即LOCAL_SHARED_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale libswresample
ubuntu下: