x264在通用linux平台上容易编译,但是如果想在Android平台上编译和使用,怎么做呢?
我修改了一份,上传到了这里,这几个文件放到你的x264源码包的根目录下,就可以编译。
说明几点:
1. 编译产物
共两个编译产物:libx264.so动态库和example测试demo
并没有编译出x264这个可执行文件,因为还要添加诸多文件,还有一个主要的原因是x264.c可读性差。
如果专门做编码器的,还可以做很多定制修改、编码参数精细控制,如果不是专门做这个领域的可能就要被搞晕。
软件这个东西,你提供给别人的接口,要尽可能少和简单(这很重要),别人可能并不关心你的实现方式,人家只是想方便使用。
2. config.h——配置信息
这个文件本是在普通Linux下利用configure的脚本文件生成的(同时还会得到Makefile),它会根据硬件平台得到相应的宏参数。
例如,如下几个:
#define ARCH_ARM 1
#define SYS_LINUX 1
#define HAVE_BITDEPTH8 1
#define HAVE_BITDEPTH10 0
这里我只是借用Linux下生成的,只是要稍微改动一下。
3. 是否使用汇编?
为了加速编码,不同的硬件平台有不同的指令集来加速,例如x86下有mmx指令集,arm下有neon指令集。
这份提供的Android.mk中,把调用硬件指令集的原文件都删除了,不参与编译。
因此,可以看到,example运行速度是比较慢的,在某个双核手机平台(cortex-A7)下,640x620分辨率图像,编码一帧耗时约1s,
该进程占用45%左右的cpu(没使用多线程,一个核的资源几乎都被这个编码器吃掉)。
4. 文件格式
从Linux平台下的Makefile中,可以看到:
SRCS = common/osdep.c common/base.c common/cpu.c common/tables.c \ encoder/api.c SRCS_X = common/mc.c common/predict.c common/pixel.c common/macroblock.c \ common/frame.c common/dct.c common/cabac.c \ common/common.c common/rectangle.c \ common/set.c common/quant.c common/deblock.c common/vlc.c \ common/mvpred.c common/bitstream.c \ encoder/analyse.c encoder/me.c encoder/ratecontrol.c \ encoder/set.c encoder/macroblock.c encoder/cabac.c \ encoder/cavlc.c encoder/encoder.c encoder/lookahead.c SRCS_8 = SRCCLI = x264.c autocomplete.c input/input.c input/timecode.c input/raw.c \ input/y4m.c output/raw.c output/matroska.c output/matroska_ebml.c \ output/flv.c output/flv_bytestream.c filters/filters.c \ filters/video/video.c filters/video/source.c filters/video/internal.c \ filters/video/resize.c filters/video/fix_vfr_pts.c \ filters/video/select_every.c filters/video/crop.c SRCCLI_X = filters/video/cache.c filters/video/depth.c
SRCCLI是参与编译x264这个bin文件的源码列表,
SRCS_X是编译出libx264.so这个动态库的源码列表。
CLI是client的缩写,因其是测试libx264.so这个动态库的,因此可称为client,这是行业术语。
在SRCCLI的源码列表中,可以看到flv/matroska的关键词,这是控制输出文件格式flv/mkv的。
针对mp4文件格式,需要依赖这两个库中的一个存在:
ifneq ($(findstring HAVE_GPAC 1, $(CONFIG)),) SRCCLI += output/mp4.c endif ifneq ($(findstring HAVE_LSMASH 1, $(CONFIG)),) SRCCLI += output/mp4_lsmash.c endif
一般来说,为减轻麻烦,我就让编码器出裸码流,方便测试,但需要注意一点,第一帧数据必须为sps/pps编码参数信息。