一、环境:
1. 虚拟机:ubuntu12.04
2. 目标板:DaVinci DM6467
3. 交叉编译器:arm_v5t_le-gcc mv_pro5.0
注:DaVinci使用的是montavista的linux系统,不能用通用的arm编译器
二、各个组件:
OpenCV
|--------zlib
|--------jpeg
|--------libpng
|--------zlib
|--------tiff
|--------zlib
|--------ffmpeg
|--------x264
|--------xvidcore
X264:x264-snapshot-20060805-2245.tar
Xvidcore:xvidcore-1.1.3.tar
Ffmpeg:ffmpeg-0.4.9-p20051120.tar
Opencv:opencv-1.0.0.tar
Yasm:yasm-0.7.2.tar
注意四个组件的版本号,因为四个包是独立的程序,版本配合问题很关键,请高度关注,否则会出现各个组件不兼容导致的问题。
三、移植过程:
1. 编译x264组件需要先安装汇编编译器yasm
./configure --enable-shared --prefix=/usr/local/dm6467/ --host=arm-linux
make; make install
2. 交叉编译x264
由于x264版本较低,不能用./configure完成其全部的配置,需要分下面几步完成:
A../configure --prefix=/usr/local/dm6467/ --enable-shared //配置交叉编译后安装的路径
B.修改config.mak文件:改ARCH=ARM,CC=arm_v5t_le-gcc,并删除-DHAVE_MMXEXT –DHAVE_SSE2 –DARCH_X86
C. 修改makefile,改编译器的ar和ranlib为arm_v5t_le的前缀
make; make install
3.交叉编译xvidcore
./configure --prefix=/usr/local/dm6467/ --disable-assembly 还需要修改platform.inc中的CC,将其改为arm_v5t_le-gcc
Make; make install
4.交叉编译ffmpeg
在configure文件中改prefix,cross_prefix和cpu,再进行configure
./configure --cpu=arm --enable-shared --disable-ffserver --enable-xvid --enable-x264 --enable-gpl --enable-pthreads --disable-strip --extra-cflags=-I/usr/local/dm6467/include --extra-ldflags=-L/usr/local/dm6467/lib
问题1:
/libm.h:62: error: static declaration of 'lrint' follows non-static declaration
../libavutil/libm.h:69: error: static declaration of 'lrintf' follows non-static declaration
../libavutil/libm.h:76: error: static declaration of 'round' follows non-static declaration
../libavutil/libm.h:83: error: static declaration of 'roundf' follows non-static declaration
解决方法:在config.h中添加:
#define HAVE_LLRINT 1
#define HAVE_LLRINTF 1
#define HAVE_LRINT 1
#define HAVE_LRINTF 1
#define HAVE_ROUND 1
#define HAVE_ROUNDF 1
问题2:编译libavcodec/x264.c文件时出现:
. x264.c: In function `X264_init':
x264.c:140: error: structure has no member named `b_cbr'
解决方法:把这两句注释掉
5.交叉编译opencv
./configure --host=arm --without-gtk --without-carbon --without-quicktime --without-1394libs --with-ffmpeg --without-python --without-swig --enable-static--enable-shared --disable-apps CXX=arm_v5t_le-g++ CC=arm_v5t_le-gcc CPPFLAGS=-I/usr/local/dm6467/include LDFLAGS=-L/usr/local/dm6467/lib --with-v4l --prefix=/usr/local/dm6467/opencv --libdir=/usr/local/dm6467/lib --includedir=/usr/local/dm6467/include
遇到的问题:配置ffmpeg编译,但无法加载ffmpeg,在配置的输出信息中ffmpeg这一项总为 NO,查看config.log,发现:
configure:21296: checking for avcodec_decode_video in -lavcodec
configure:21326: arm_v5t_le-gcc -o conftest -DNDEBUG -I/usr/local/dm6467/include -L/usr/local/dm6467/lib conftest.c -lavcodec -lpthread -ldl -lm >&5
/opt/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/bin/../lib/gcc/armv5tl-montavista-linux-gnueabi/4.2.0/../../../../armv5tl-montavista-linux-gnueabi/bin/ld: warning: libx264.so.49, needed by /usr/local/dm6467/lib/libavcodec.so, not found (try using -rpath or -rpath-link)
/opt/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/bin/../lib/gcc/armv5tl-montavista-linux-gnueabi/4.2.0/../../../../armv5tl-montavista-linux-gnueabi/bin/ld: warning: libavutil.so, needed by /usr/local/dm6467/lib/libavcodec.so, not found (try using -rpath or -rpath-link)
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `x264_nal_encode'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `av_d2q'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `x264_encoder_encode'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `ff_log2_tab'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `x264_param_default'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `av_reduce'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `ff_gcd'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `x264_encoder_close'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `x264_encoder_open'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `ff_sqrt_tab'
/usr/local/dm6467/lib/libavcodec.so: undefined reference to `av_div_q'
我最初的分析是libavcodec中没有上面报出undefined的各个函数,所以就自己写了个test.c测了下,如下:并用编译器编译 arm_v5t_le-gcc test.c –lxxx –L. –o test
extern int x264_nal_encode();
//extern int av_d2q();
//extern int x264_encoder_encode();
//extern int ff_log2_tab();
//extern int x264_param_default();
int main(void)
{ x264_nal_encode();
//av_d2q();
//x264_encoder_encode();
//ff_log2_tab();
//x264_param_default();
}
测试的结果是:在libavcodec中是没有上面的那些函数的,但是在libx264和libavutil里面却有。我得出的分析是:libx264和libavutil是没有问题的,但是经过一次封装编程libavcodec就有问题了,所以就认为是ffmpeg和x264的衔接有问题,转而下载不同版本的组件(x264和ffmpeg),屡次编译后测试,还是会出现上面的错误。后来想了想,应该是这样:在checking for avcodec_decode_video in –lavcodec时,avcodec_decode_video函数会调用到许多libx264和libavutil里面的东西,而这两个库在这时找不到,所以说编译器报出/usr/local/dm6467/lib/libavcodec.so: undefined reference to `x264_encoder_close',这种错误,而不是说在libavcodec中必须生成x264_encoder_close函数才对。方向转移到寻找为什么找不到libx264和libavutil的原因上,这时一篇文章给我了思路:http://www.opencv.org.cn/forum.php?mod=viewthread&tid=17878&highlight=opencv+ffmpeg 。他的方法是在configure时添加LIBS配置项,把那两个库加进去,但他移植的是opencv2.0.0,configure中有LIBS这一项,而我的opencv1.0.0没有啊,我又一次被耍了。回头想,可以看看configure的源码,其中有LIBS变量,而每次进行configure时,生成的config.log中有LIBS=”-lpthread”等东西,那么,不妨试试手动修改configure来加入我的lib。好,就这么整,在configure中,加入LIBS="-lx264 -lavutil",注意加入的位置,别太靠前就行。重新配置,终于功夫不负有心人,ffmpeg变成yes了,大功告成。接着就按部就班的make make install即可。