windows下使用ndk9编译ffmpeg

折腾了2天,终于编译成功,不容易啊。

据说Linux下比windows的简单,windows下问题太多,会搞崩溃,真的是这样。在崩溃边缘尝试ubuntu下编译,果然轻松不少。最后不想放弃,还是坚持在windows下也编译通过。

我的编译环境:

win8.1,cygwin1.7,ndk-r9d,ffmpeg2.2.2


首先搭建环境

一、安装Cygwin:
NDK编译代码时要用到make和gcc,所以先搭建一个Linux环境。
cygwin是在Windows平台上运行的Unix模拟环境,通过它 就可以在不安装Linux的情况下使用NDK来编译C、C++代码。
1. 选择安装包列表
一开始只选择了需要的包,安装完成之后运行cygwin总报错,提示找不到cygintl-8.dll或者丢失cygwin1.dll,
解决办法:换个下载站点,重新安装Devel下所有包
2. 测试cygwin是否安装成功:
     cygcheck -c cygwin 打印当前cygwin的版本和运行状态
     make -v 和 gcc -v 打印出对应的版本信息,安装成功

二、下载安装NDK
http://developer.android.com/tools/sdk/ndk/index.html
下载解压到自己喜欢的路径就行

三、配置NDK
1. 在cygwin的安装目录下找到 home\用户名\.bash_profile文件,编辑
NDK=/cygdrive/android-ndk目录
例如
     NDK=/cygdrive/e/Tools/Java/android/android-ndk-r9d
     export NDK
NDK这个名字是随便取的

2. 打开cygwin,输入cd $NDK,输出上面配置的 /cygdrive/e/Tools/Java/android/android-ndk-r9d 信息,则环境变量设置成功


接下来就可以编译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下:

ffmpeg目录下Android.mk添加一行 LOCAL_LDLIBS := -L$(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm/usr/lib -L$(LOCAL_PATH) -llog -lz -ldl -lgcc


五、OK,编译完成,在mPlayer目录下生成了libs和obj,libs下有libffmpeg.so


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值