Ubuntu 下用NDK编译移植 ffmpeg 2.0 (配置最新版x264) 到android平台

将x264配置到ffmpeg中需要先编译x264,生成静态库或动态库。因为264的静态库本身不大(我编译完成后是1.1M)且考虑到平台移植问题,这里选择的是编译生成静态库。


准备,新建工作空间 

(1)创建总目录FFmpeg-Android

eg: mkdir workspace --> cd workspace --> mkdir FFmpeg-Android --> cd FFmpeg-Android 

(2)创建保存x264静态库的目录 android-x264

(在FFmpeg-Android目录下)mkdir 264 --> cd 264


1、编译x264

(1)去官网:http://www.videolan.org/developers/x264.html 下载最新的264源代码。这里下载的是2013年10月份出的版本0.14。将压缩包解压缩到264FFmpeg-Android/264目录下,

(2)编写脚本文件:

[cpp]  view plain  copy
  1. export NDK=$NDK_HOME  
  2. export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt  
  3. export PLATFORM=$NDK/platforms/android-19/arch-arm   
  4. export PREFIX=../../android-x264  
  5.   
  6. ./configure --prefix=$PREFIX \  
  7. --enable-static \  
  8. --enable-pic \  
  9. --disable-asm \  
  10. --disable-cli \  
  11. --host=arm-linux \  
  12. --cross-prefix=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi- \  
  13. --sysroot=$PLATFORM  

注意:这里涉及到路径的变量需要根据你们自己的情况来调整。

PREBUILT 变量保存的是NDK交叉编译链的路径,

PLATFORM 变量保存的是NDK进行链接时查找库文件的路径(arch-arm目录下保存的是各种andorid平台下的c库头文件和静态以及动态库)

PREFIX 变量保存的是编译生成的静态库保存的路径

(3)运行脚本,结果如下图



(4)执行完刚才的脚本后,会在当前目录生成配置文件,这里还需要修改以下几个文件,原因是:编译成功后在eclipse下运行会出现 "cannot locate symbol 'log2f' " 的错误

修改1、config.h

---- #define HAVE_LOG2F 1

+++#define HAVE_LOG2F 0


修改2、encoder/encoder.c 、 encoder/ratecontrol.c 、encoder/analyse.c 、encoder/set.c

在文件开头处添加 

+++ #include <math.h>

+++  //<!-- add by chance_yin 2013.12.27
+++  #undef log2f(x) 
+++  #undef log2f
+++  #define log2f(x) (logf(x)*1.4426950408889634f)
+++  // end add by chance_yin-->


(5)在当前目录下执行: make , make install

完成后,就可以在FFmpeg-Android的android-x264目录下生成头文件和静态库文件了,至此,x264编译完成。



2、编译FFmpeg 2.0 ,下载地址:http://ffmpeg.org/olddownload.html  

(1)将压缩包解压缩到FFmpeg-Android的根目录下

(2)编写脚本,这里将配置和编译过程分成两个脚本来写,主要是配置脚本完成后,还要手动的去修改ffmpeg目录下的config.h文件

配置脚本:

[cpp]  view plain  copy
  1. #!/bin/bash  
  2.   
  3. DEST=`pwd`/build/ffmpeg && rm -rf $DEST  
  4. SOURCE=`pwd`/ffmpeg  
  5.   
  6.   
  7. if [ -d ffmpeg ]; then  
  8.   cd ffmpeg  
  9. else  
  10.   echo "can not find ffmpeg source code"  
  11.   exit 1  
  12. fi  
  13.   
  14. if [ "$PIPESTATUS" != "0" ] ; then  
  15.     echo "error in FFmpeg-Android.sh : 14 "  
  16. fi  
  17.   
  18.   
  19. TOOLCHAIN=/tmp/vplayer  
  20. SYSROOT=$TOOLCHAIN/sysroot/  
  21. $NDK_HOME/build/tools/make-standalone-toolchain.sh --platform=android-19 --install-dir=$TOOLCHAIN  
  22.   
  23. export PATH=$TOOLCHAIN/bin:$PATH  
  24. export CC="arm-linux-androideabi-gcc"  
  25. export LD=arm-linux-androideabi-ld  
  26. export AR=arm-linux-androideabi-ar  
  27.   
  28. #CFLAGS="-O3 -Wall -mthumb -pipe -fpic -fasm \  
  29. #  -finline-limit=300 -ffast-math \  
  30. #  -fstrict-aliasing \  
  31. #  -fmodulo-sched -fmodulo-sched-allow-regmoves \  
  32. #  -Wno-psabi -Wa,--noexecstack \  
  33. #  -DANDROID -DNDEBUG"  
  34.   
  35. CFLAGS="-Os -fPIC -marm"  
  36.   
  37. FFMPEG_FLAGS="--target-os=linux \  
  38.   --arch=arm \  
  39.   --sysroot=$SYSROOT \  
  40.   --enable-cross-compile \  
  41.   --cross-prefix=arm-linux-androideabi- \  
  42.   --enable-shared \  
  43.   --enable-static \  
  44.   --disable-symver \  
  45.   --disable-doc \  
  46.   --disable-ffplay \  
  47.   --disable-ffmpeg \  
  48.   --disable-ffprobe \  
  49.   --disable-ffserver \  
  50.   --disable-avdevice \  
  51.   --disable-avfilter \  
  52.   --disable-filters \  
  53.   --disable-devices \  
  54.   --disable-pthreads \  
  55.   --disable-everything \  
  56.   --enable-gpl \  
  57.   --enable-muxers \  
  58.   --enable-encoders \  
  59.   --enable-protocols  \  
  60.   --enable-parsers \  
  61.   --enable-demuxers \  
  62.   --enable-decoders \  
  63.   --enable-bsfs \  
  64.   --enable-network \  
  65.   --enable-swscale  \  
  66.   --enable-libx264 \  
  67.   --enable-encoder=libx264 \  
  68.   --enable-decoder=h264 \  
  69.   --enable-muxer=h264 \  
  70.   --enable-demuxer=h264 \  
  71.   --disable-demuxer=sbg \  
  72.   --disable-demuxer=dts \  
  73.   --disable-parser=dca \  
  74.   --disable-decoder=dca \  
  75.   --extra-libs=-lx264 \  
  76.   --enable-asm \  
  77.   --enable-version3"  
  78.   
  79. VERSION=armv7  
  80. cd $SOURCE  
  81.   
  82. EXTRA_CFLAGS="-I../android-x264/include -march=armv7-a"  
  83. EXTRA_LDFLAGS="-L../android-x264/lib"  
  84.   
  85. PREFIX="$DEST/$VERSION" && mkdir -p $PREFIX  
  86. FFMPEG_FLAGS="$FFMPEG_FLAGS --prefix=$PREFIX"  
  87.   
  88. sh  ./configure $FFMPEG_FLAGS --extra-cflags="$CFLAGS $EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" | tee $PREFIX/configuration.txt  
  89. if [ "$?" = "0" ] ; then   
  90.     echo "./configure success in shell-script"  
  91. else  
  92.     echo "./configure erroe in shell-script"  
  93.     exit 1  
  94. fi  
  95. cp config.* $PREFIX  


我们编译ffmpeg的过程是这样的,将交叉编译链拷贝整个拷贝一份到系统的临时目录下/tmp的vplayer中(交叉编译链的结构其实蛮有意思,我在另一篇博客中会好好分析)

DEST , 生成的ffmpeg共享库libffmpeg.so保存的路径

SOURCE, ffmpeg源代码的路径 

TOOLCHAIN ,用来保存交叉编译链的目录路径

SYSROOT ,    用来保存交叉编译练进行链接步骤时查找库文件的路径

EXTRA_CFLAGS,用来帮助我们将264集成到ffmpeg时,查找264头文件的路径

EXTRA_LDFLAGS,ffmpeg查找264静态库的路径

其他的变量估计都是见名知意的了,不明白的可以给我留言。


OK,编写完脚本后,先执行 config-ffmpeg-android.sh 脚本,对ffmpeg进行配置


PS. 如果执行配置脚本时,遇到诸如 ” c compiler failed ....“ 之类的错误,多半是你配置脚本中某个变量的路径错了。

配置脚本执行完后,会打印出ffmpeg的配置信息:如图

    


从encoders 或者decoders中可以看出来,我们的ffmepg已经成功配置上了264

编译完成后,会出现一个警告如下图,这个可以忽略。




(3)配置脚本config-ffmpeg-andorid.sh 执行完后,还需要修改ffmpeg目录下的config.h文件,同样是修改 HAVE_LOGx的宏值

----#define HAVE_LOG2 1

----#define HAVE_LOG2F 1

----#define HAVE_LOG10F 1


+++#define HAVE_LOG2 0

+++#define HAVE_LOG2F 0

+++#define HAVE_LOG10F 0

(4)修改完成后,执行编译脚本 ./make-ffmpeg-android.sh 脚本,脚本内容如下:

[cpp]  view plain  copy
  1. #!/bin/bash   
  2.   
  3. DEST=`pwd`/build/ffmpeg && rm -rf $DEST  
  4. SOURCE=`pwd`/ffmpeg  
  5.   
  6. TOOLCHAIN=/tmp/vplayer  
  7. SYSROOT=$TOOLCHAIN/sysroot/  
  8.   
  9. export PATH=$TOOLCHAIN/bin:$PATH  
  10. export CC="arm-linux-androideabi-gcc"  
  11. export LD=arm-linux-androideabi-ld  
  12. export AR=arm-linux-androideabi-ar  
  13.   
  14. CFLAGS="-Os -fPIC -marm"  
  15.   
  16. VERSION=armv7  
  17. cd $SOURCE  
  18.   
  19. PREFIX="$DEST/$VERSION" && mkdir -p $PREFIX  
  20.   
  21.   
  22. EXTRA_LDFLAGS="-L../android-x264/lib"  
  23.   
  24. make clean  
  25. make -j4 || exit 1  
  26. make install || exit 1  
  27.   
  28. $CC -llog -lm -lz -shared --sysroot=$SYSROOT -Wl,--no-undefined -Wl,-z,noexecstack $EXTRA_LDFLAGS libavutil/*.o libavutil/arm/*.o libavcodec/*.o libavcodec/arm/*.o libavformat/*.o libswresample/*.o libswscale/*.o -o $PREFIX/libffmpeg.so  -lx264 -L/home/yinjingyu/workspace/lab-project/ffmpegcpl/FFmpeg-Android/lib/-lx264  
  29.   
  30. cp $PREFIX/libffmpeg.so $PREFIX/libffmpeg-debug.so  
  31.   
  32. arm-linux-androideabi-strip --strip-unneeded $PREFIX/libffmpeg.so  
  33.   
  34. echo "build successfully!"   

注意,下载下来的ffmpeg源代码需要修改一些源文件才能顺利编译通过,不过这里为了方便给大家贴出来错误信息提供参考,我直接执行编译脚本,编译过程出现错误如下:



分析错误原因是类型冲突,具体我也没深究,直接想了个简单办法:

首先要知道 strtod 是C库函数,用来实现将字符串转化成double类型的数据。ffmpeg可能自己又重新实现了一套自己的函数叫做:avpriv_strtod,两种实现导致了类型冲突。

我的解决方法就是注释掉ffmpeg自己的实现,直接使用c库的函数。具体步骤如下:


步骤1:进入我们交叉编译链的目录,如果你的配置脚本和我一样,那就应该是 /tmp/vplayer(之前我们专门拷贝了一份编译链到该目录下)。在该目录下有一个sysroot目录(用来保存链接时用到的头文件和库),进入sysroot --> include 下,用vi 打开 stdlib.h 文件,添加如下内容:

+++//add by chance_yin 2013.12.27
+++#undef avpriv_strtod
+++#undef strtod
+++#define strtod strtod

步骤2:注释掉 ffmpeg/compat/strtod.c中的所有代码

步骤3:在如下文件: libavutil/eval.c、libavformat/rtmpproto.c 中的开头位置添加如下代码,

#include <stdlib.h>

#undef avpriv_strtod

#undef strtod

#define strtod strtod

步骤4:上面的文件修改完成后,再次执行编译脚本,又出现了下面的错误:


由于实验室的项目用不到语音,所以对于错误:swri_audio_convert_init_arm,我的处理办法是直接注释掉,

剩下的关于 log2_tab.o multiple definition 的错误,就好解决了,

用vi 打开: libavcodec/Makefile 、libavformat/Makefile 、libswresample/Makefile 文件,将其中的

OBJS-$(CONFIG_SHARED) += log2_tab.o  注释掉即可。


好了,源代码的编译算是告以段落了,贴出来编译成功的图,然后你就可以在FFmpeg-android/build/ffmpeg/armv7目录下找到编译完成的 libffmpeg.so 文件了,:





结束:

之前实验室项目一直用的是ffmpeg 0.x的版本,昨天把2.0版本的libffmpeg.so整合到项目中发现原来的代码在  avcodec_open2 报错,在ffmpeg相应源文件中打了log才发现是2.0之后,ffmpeg弃用了很多宏,比如:

项目老版本的程序执行到 avcodec_open2 出错, 在源代码此方法的实现中打log,

发现停在了“specific pixfmt not supported 。。。”,google一下,发现在ffmpeg2.0版本中,ffmpeg不再支持pCodecCtxEnc->pix_fmt = PIX_FMT_YUV420P;只要把该值设置成pCodecCtxEnc->pix_fmt = AV_PIX_FMT_YUV420P; 就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值