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



編譯腳本

         進入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進行調試。

   


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章