Ubuntu 下将VP9移植到Android

     

       最近想把VP9移植到Android手机上,折腾了很久,终于搞定,现在把方法和大家共享一下。


===========================================================================

准备工作:

1、操作系统Ubuntu 12.04

2、下载 android-ndk32-r10d-linux-x86_64.tar.bz2

3、安装yasm,安装方法可以网上搜索

4、下载源代码,可采用以下3种途径

      a  网站:http://www.webmproject.org/

      b  Linux平台

git clone https://github.com/webmproject/libvpx

      c  或者直接网上下载libvpx-1.4.0。(当前编译采用这个版本)


配置NDK环境


       采用的NDK的版本为android-ndk32-r10d-linux-x86_64

         打开profile文件

sudo gedit /etc/profile

在profile文件末尾加上如下参数:

export ARM_ROOT=/home/willman/Projects/android_tools/ndk
export PATH=$ARM_ROOT:$PATH
export ARM_INC=$ARM_ROOT/platforms/android-21/arch-arm/usr/include/
export ARM_LIB=$ARM_ROOT/platforms/android-21/arch-arm/usr/lib/
export ARM_TOOL=$ARM_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
export ARM_LIBO=$ARM_TOOL/lib/gcc/arm-linux-androideabi/4.9
export PATH=$ARM_TOOL/bin:$PATH
export ARM_PRE=arm-linux-androideabi

 
  

装载环境变量

source /etc/profile

验证是否装载成功

ndk-build -v

Ubuntu 下将VP9移植到Android_第1张图片


编译脚本

         进入libvpx-1.4.0文件夹后,cd build/ :

编译为Simple_encoder示例:     

../configure --target=armv7-android-gcc--sdk-path=$ARM_ROOT --prefix=/usr/local/android/ --extra-cflags="-mfloat-abi=softfp -mfpu=neon" –disable-runtime-cpu-detect

       如果没加 --extra-cflags="-mfloat-abi=softfp -mfpu=neon "  ,可能会出现下面错误:

[CC] vp8/common/arm/neon/bilinearpredict_neon.c.o
In file included from ../libvpx/vp8/common/arm/neon/bilinearpredict_neon.c:11:0: e:\source\android\android-ndk-r9\toolchains\arm-linuxandroideabi-4.6\prebuilt\windows\bin../lib/gcc/arm-linux-androideabi/4.6/include/arm_neon.h:32:2: error:#error You must enable NEON instructions (e.g. -mfloat-abi=softfp -mfpu=neon) to use arm_neon.h
../libvpx/vp8/common/arm/neon/bilinearpredict_neon.c:13:1: error: unknown type name ‘uint16_t’
../libvpx/vp8/common/arm/neon/bilinearpredict_neon.c: In function ‘vp8_bilinear_predict4x4_neon’:


          需要注意的是: –enable-runtime-cpu-detect(默认开启)会报错,所以如果不需要用到多线程时,可以禁用–disable-runtime-cpu-detect此外,如果直接默认–enable-examples会报错(如果采用–disable-examples,则不会编译示例,只编译libvpx.a库文件),所以不能直接用完整示例,所以采用simple_encoder和simple_decoder这两个示例。需要对examples.mk这个文件继续修改,即删除上述两个示例之外的所有工程,修改如下:

# List ofexamples to build. UTILS are tools meant for distribution

# whileEXAMPLES demonstrate specific portions of the API.

UTILS-$(CONFIG_DECODERS)    += vpxdec.c

vpxdec.SRCS                 += md5_utils.c md5_utils.h

vpxdec.SRCS                 += vpx_ports/mem_ops.h

vpxdec.SRCS                 += vpx_ports/mem_ops_aligned.h

vpxdec.SRCS                 += vpx_ports/vpx_timer.h

vpxdec.SRCS                 += vpx/vpx_integer.h

vpxdec.SRCS                 += args.c args.h

vpxdec.SRCS                 += ivfdec.c ivfdec.h

vpxdec.SRCS                 += tools_common.ctools_common.h

vpxdec.SRCS                 += y4menc.c y4menc.h

ifeq($(CONFIG_LIBYUV),yes)

  vpxdec.SRCS                 += $(LIBYUV_SRCS)

endif

ifeq($(CONFIG_WEBM_IO),yes)

  vpxdec.SRCS                 += $(LIBWEBM_PARSER_SRCS)

  vpxdec.SRCS                 += webmdec.cc webmdec.h

endif

vpxdec.GUID                  =BA5FE66F-38DD-E034-F542-B1578C5FB950

vpxdec.DESCRIPTION           = Full featured decoder

UTILS-$(CONFIG_ENCODERS)    += vpxenc.c

vpxenc.SRCS                 += args.c args.h y4minput.cy4minput.h vpxenc.h

vpxenc.SRCS                 += ivfdec.c ivfdec.h

vpxenc.SRCS                 += ivfenc.c ivfenc.h

vpxenc.SRCS                 += rate_hist.c rate_hist.h

vpxenc.SRCS                 += tools_common.ctools_common.h

vpxenc.SRCS                 += warnings.c warnings.h

vpxenc.SRCS                 += vpx_ports/mem_ops.h

vpxenc.SRCS                 += vpx_ports/mem_ops_aligned.h

vpxenc.SRCS                 += vpx_ports/vpx_timer.h

vpxenc.SRCS                 += vpxstats.c vpxstats.h

ifeq($(CONFIG_LIBYUV),yes)

  vpxenc.SRCS                 += $(LIBYUV_SRCS)

endif

ifeq($(CONFIG_WEBM_IO),yes)

  vpxenc.SRCS                 += $(LIBWEBM_MUXER_SRCS)

  vpxenc.SRCS                 += webmenc.cc webmenc.h

endif

vpxenc.GUID                  =548DEC74-7A15-4B2B-AFC3-AA102E7C25C1

vpxenc.DESCRIPTION           = Full featured encoder

ifeq($(CONFIG_SPATIAL_SVC),yes)

  EXAMPLES-$(CONFIG_VP9_ENCODER)      += vp9_spatial_svc_encoder.c

  vp9_spatial_svc_encoder.SRCS        += args.c args.h

  vp9_spatial_svc_encoder.SRCS        += ivfenc.c ivfenc.h

  vp9_spatial_svc_encoder.SRCS        += tools_common.c tools_common.h

  vp9_spatial_svc_encoder.SRCS        += video_common.h

  vp9_spatial_svc_encoder.SRCS        += video_writer.h video_writer.c

  vp9_spatial_svc_encoder.SRCS        += vpxstats.c vpxstats.h

  vp9_spatial_svc_encoder.GUID        = 4A38598D-627D-4505-9C7B-D4020C84100D

  vp9_spatial_svc_encoder.DESCRIPTION = VP9Spatial SVC Encoder

endif

 

ifneq($(CONFIG_SHARED),yes)

EXAMPLES-$(CONFIG_VP9_ENCODER)    += resize_util.c

endif

 

EXAMPLES-$(CONFIG_ENCODERS)          += vpx_temporal_svc_encoder.c

vpx_temporal_svc_encoder.SRCS        += ivfenc.c ivfenc.h

vpx_temporal_svc_encoder.SRCS        += tools_common.c tools_common.h

vpx_temporal_svc_encoder.SRCS        += video_common.h

vpx_temporal_svc_encoder.SRCS        += video_writer.h video_writer.c

vpx_temporal_svc_encoder.GUID        = B18C08F2-A439-4502-A78E-849BE3D60947

vpx_temporal_svc_encoder.DESCRIPTION= Temporal SVC Encoder

EXAMPLES-$(CONFIG_DECODERS)        += simple_decoder.c

simple_decoder.GUID                 =D3BBF1E9-2427-450D-BBFF-B2843C1D44CC

simple_decoder.SRCS                += ivfdec.h ivfdec.c

simple_decoder.SRCS                += tools_common.htools_common.c

simple_decoder.SRCS                += video_common.h

simple_decoder.SRCS                += video_reader.hvideo_reader.c

simple_decoder.SRCS                += vpx_ports/mem_ops.h

simple_decoder.SRCS                += vpx_ports/mem_ops_aligned.h

simple_decoder.DESCRIPTION          = Simplified decoder loop

EXAMPLES-$(CONFIG_DECODERS)        += postproc.c

postproc.SRCS                      += ivfdec.h ivfdec.c

postproc.SRCS                      += tools_common.htools_common.c

postproc.SRCS                      += video_common.h

postproc.SRCS                      += video_reader.hvideo_reader.c

postproc.SRCS                      += vpx_ports/mem_ops.h

postproc.SRCS                      +=vpx_ports/mem_ops_aligned.h

postproc.GUID                       =65E33355-F35E-4088-884D-3FD4905881D7

postproc.DESCRIPTION                = Decoder postprocessor control

EXAMPLES-$(CONFIG_DECODERS)        += decode_to_md5.c

decode_to_md5.SRCS                 += md5_utils.h md5_utils.c

decode_to_md5.SRCS                 += ivfdec.h ivfdec.c

decode_to_md5.SRCS                 += tools_common.h tools_common.c

decode_to_md5.SRCS                 += video_common.h

decode_to_md5.SRCS                 += video_reader.hvideo_reader.c

decode_to_md5.SRCS                 += vpx_ports/mem_ops.h

decode_to_md5.SRCS                 += vpx_ports/mem_ops_aligned.h

decode_to_md5.GUID                  =59120B9B-2735-4BFE-B022-146CA340FE42

decode_to_md5.DESCRIPTION           = Frame by frame MD5 checksum

EXAMPLES-$(CONFIG_ENCODERS)     += simple_encoder.c

simple_encoder.SRCS             += ivfenc.h ivfenc.c

simple_encoder.SRCS             += tools_common.h tools_common.c

simple_encoder.SRCS             += video_common.h

simple_encoder.SRCS             += video_writer.h video_writer.c

simple_encoder.GUID              =4607D299-8A71-4D2C-9B1D-071899B6FBFD

simple_encoder.DESCRIPTION       = Simplified encoder loop

EXAMPLES-$(CONFIG_VP9_ENCODER)  += vp9_lossless_encoder.c

vp9_lossless_encoder.SRCS       += ivfenc.h ivfenc.c

vp9_lossless_encoder.SRCS       += tools_common.h tools_common.c

vp9_lossless_encoder.SRCS       += video_common.h

vp9_lossless_encoder.SRCS       += video_writer.h video_writer.c

vp9_lossless_encoder.GUID        = B63C7C88-5348-46DC-A5A6-CC151EF93366

vp9_lossless_encoder.DESCRIPTION= Simplified lossless VP9 encoder

EXAMPLES-$(CONFIG_ENCODERS)     += twopass_encoder.c

twopass_encoder.SRCS            += ivfenc.h ivfenc.c

twopass_encoder.SRCS            += tools_common.h tools_common.c

twopass_encoder.SRCS            += video_common.h

twopass_encoder.SRCS            += video_writer.h video_writer.c

twopass_encoder.GUID             =73494FA6-4AF9-4763-8FBB-265C92402FD8

twopass_encoder.DESCRIPTION      = Two-pass encoder loop

EXAMPLES-$(CONFIG_DECODERS)     += decode_with_drops.c

decode_with_drops.SRCS          += ivfdec.h ivfdec.c

decode_with_drops.SRCS          += tools_common.h tools_common.c

decode_with_drops.SRCS          += video_common.h

decode_with_drops.SRCS          += video_reader.h video_reader.c

decode_with_drops.SRCS          += vpx_ports/mem_ops.h

decode_with_drops.SRCS          += vpx_ports/mem_ops_aligned.h

decode_with_drops.GUID           =CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26

decode_with_drops.DESCRIPTION    = Drops frames while decoding

EXAMPLES-$(CONFIG_ENCODERS)        += set_maps.c

set_maps.SRCS                      += ivfenc.h ivfenc.c

set_maps.SRCS                      += tools_common.htools_common.c

set_maps.SRCS                      += video_common.h

set_maps.SRCS                      += video_writer.hvideo_writer.c

set_maps.GUID                       =ECB2D24D-98B8-4015-A465-A4AF3DCC145F

set_maps.DESCRIPTION                = Set active and ROI maps

EXAMPLES-$(CONFIG_VP8_ENCODER)     += vp8cx_set_ref.c

vp8cx_set_ref.SRCS                 += ivfenc.h ivfenc.c

vp8cx_set_ref.SRCS                 += tools_common.h tools_common.c

vp8cx_set_ref.SRCS                 += video_common.h

vp8cx_set_ref.SRCS                 += video_writer.hvideo_writer.c

vp8cx_set_ref.GUID                  =C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A

vp8cx_set_ref.DESCRIPTION           = VP8 set encoder reference frame

 

 

ifeq($(CONFIG_MULTI_RES_ENCODING),yes)

ifeq($(CONFIG_LIBYUV),yes)

EXAMPLES-$(CONFIG_VP8_ENCODER)          += vp8_multi_resolution_encoder.c

vp8_multi_resolution_encoder.SRCS       += ivfenc.h ivfenc.c

vp8_multi_resolution_encoder.SRCS       += tools_common.h tools_common.c

vp8_multi_resolution_encoder.SRCS       += video_writer.h video_writer.c

vp8_multi_resolution_encoder.SRCS       += $(LIBYUV_SRCS)

vp8_multi_resolution_encoder.GUID        = 04f8738e-63c8-423b-90fa-7c2703a374de

vp8_multi_resolution_encoder.DESCRIPTION= VP8 Multiple-resolution Encoding

endif

endif

 

# Handle extra library flags depending on codecconfiguration


     configure成功后,然后再make。编译后成功后即可在build文件下出现libvpx.a、simple_encoder、simple_decoder等文件,而simple_encoder、simple_decoder是直接可以在手机上运行的可执行文件,可用adb工具利用shell进行调试,在手机上shell调试方法可以参考http://blog.csdn.net/u014006343/article/details/46619927


编译为完整examples示例:

../configure --target=armv7-android-gcc --sdk-path=$ARM_ROOT --prefix=/usr/local/android/ --extra-cflags="-mfloat-abi=softfp -mfpu=neon" –-disable-webm-io

在用libvpx库时会出现下面错误:undefined reference to `android_getCpuFeatures’:

这个错误是在加入examples时出现(但在单独编译libvpx时并没有出错),经过搜索,在ndk目录下的source目录下发现cpufeatures,该目录里的cpu-features就有android_getCpuFeatures的声明和定义,并且也说明了如何使用。这里采用比较原始的方式,就是自己编译了cpufeature的静态库,然后在需要的项目中在链接进去。


               编译libcpu-features.a 文件的方法可以参考http://blog.csdn.net/kl222/article/details/23101115 ,需要注意的是libcpu-features.a 静态库的链接方式,在此需要对examples.mk进行如下修改:

          在 CODEC_EXTRA_LIBS=$(sort $(call enabled,CODEC_EXTRA_LIBS))下面添加如下:

  CODEC_EXTRA_LIBS+=/home/willman/third-party/libcpu-feaures.a   (libcpu-features.a 静态库所在目录)

           configure成功后,然后再make。编译后成功后即可在build文件下出现libvpx.a、simple_encoder、simple_decoder、vpxenc、vpxdec等文件,而simple_encoder、simple_decoder、vpxenc、vpxdec是直接可以在手机上运行的可执行文件,可用adb工具利用shell进行调试。

   


你可能感兴趣的:(android,移植,视频编码)