假設已經裝好Android SDK + NDK, 我的版本是r7b
1.下載ffmpeg
我是用git clone下來的, 也可以下載ffmpeg下載頁面下面的snapshot
http://www.ffmpeg.org/download.html
2.建立build script
網路上有很多種方法, 最後我是用build script(from rockplayer)來建立.
一來可以選擇想要的功能, 二來這真的挺方便, 推薦! 記得把build script放在ffmpeg的目錄裡.
參考的build script: http://roman10.net/src/build_android_r5b.txt
我的build script
#!/bin/bash ###################################################### # Usage: # put this script in top of FFmpeg source tree # ./build_android # It generates binary for following architectures: # ARMv6 # ARMv6+VFP # ARMv7+VFPv3-d16 (Tegra2) # ARMv7+Neon (Cortex-A8) # Customizing: # 1. Feel free to change ./configure parameters for more features # 2. To adapt other ARM variants # set $CPU and $OPTIMIZE_CFLAGS # call build_one ###################################################### NDK=/home/shaw/work/Android/android-sdk-linux/android-ndk-r7b PLATFORM=$NDK/platforms/android-8/arch-arm/ PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86 function build_one { ./configure --target-os=linux \ --prefix=$PREFIX \ --enable-cross-compile \ --enable-shared \ --enable-static \ --extra-libs="-lgcc" \ --arch=arm \ --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \ --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \ --nm=$PREBUILT/bin/arm-linux-androideabi-nm \ --sysroot=$PLATFORM \ --extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS -I/usr/local/include" \ --extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L $PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog -L/usr/local/lib " \ --enable-gpl \ --disable-everything \ --enable-demuxer=mov \ --enable-demuxer=h264 \ --enable-muxer=h264 \ --enable-muxer=mp4 \ --enable-muxer=flv \ --enable-muxer=mov \ --disable-ffplay \ --enable-protocol=file \ --enable-avformat \ --enable-avcodec \ --enable-decoder=rawvideo \ --enable-decoder=mjpeg \ --enable-decoder=h263 \ --enable-decoder=h264 \ --enable-decoder=mpeg4 \ --enable-encoder=mjpeg \ --enable-encoder=h263 \ --enable-encoder=mpeg4 \ --enable-encoder=h264 \ --enable-parser=h264 \ --disable-network \ --enable-zlib \ --disable-avfilter \ --disable-avdevice \ $ADDITIONAL_CONFIGURE_FLAG # --enable-libx264 \ make clean make -j4 install $PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o $PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -soname libffmpeg.so -shared -nostdlib -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc -lm -lz -ldl -llog --warn-once --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a } #CPU=armv7-a #OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU " #PREFIX=./android/$CPU #ADDITIONAL_CONFIGURE_FLAG= #build_one #arm v6 #CPU=armv6 #OPTIMIZE_CFLAGS="-marm -march=$CPU" #PREFIX=./android/$CPU #ADDITIONAL_CONFIGURE_FLAG= #build_one #arm v7vfpv3 #CPU=armv7-a #OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU " #PREFIX=./android/$CPU #ADDITIONAL_CONFIGURE_FLAG= #build_one #arm v7vfp CPU=armv7-a OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU " PREFIX=/home/shaw/work/Android/ffmpeg/android/$CPU ADDITIONAL_CONFIGURE_FLAG= build_one #arm v7n #CPU=armv7-a #OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=neon -marm -march=$CPU -mtune=cortex-a8" #PREFIX=/home/shaw/work/Android/ffmpeg/android/$CPU #ADDITIONAL_CONFIGURE_FLAG=--enable-neon #build_one #arm v6+vfp #CPU=armv6 #OPTIMIZE_CFLAGS="-DCMP_HAVE_VFP -mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU" #PREFIX=./android/${CPU}_vfp #ADDITIONAL_CONFIGURE_FLAG= #build_one
要注意的地方有幾個:
<1>前面三個變數的path要設到相對應的位置.
<2>configure要選好相關的功能, 我打算用到muxer的功能, 所以有把muxer的功能打開.
<3>要選對cpu的版本, 不然在跑app時會說找不到.so, 其實是因為.so的loader讀取時產生錯誤, 所以沒辦法執行.
<4>如果想編armv7+neon的版本, 記得加上--enable-mdct和--enable-fft, 因為開了這兩個選項才會去編譯一些跟neon有關的最佳化函式, 不然編譯到最後會跳出找不到function的error.
3.build ffmpeg
執行剛剛的build script後, 會在ffmpeg目錄裡產生android目錄, 裡面有libffmpeg.so. 這個.so檔就是我們要的ffmpeg library. ffmpeg for android已經編譯完成了!
4.寫個簡單測試程式
我是直接從ndk的samples/hello-jni拿來改, 在改之前記得先用eclipse把範例import進來, 沒import的話jni會build fail, 目前還沒去研究為何, 不過我想有可能是在import時eclipse有幫忙去寫一些相關的環境變數吧.
先改一下hello-jni.c的內容
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include#include #include #include #include /* This is a trivial JNI example where we use a native method * to return a new VM String. See the corresponding Java source * file located at: * * apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java */ jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ) { char str[25]; sprintf(str, "av codec version is %d", avcodec_version()); return (*env)->NewStringUTF(env, str); }
Android.mk:
# Copyright (C) 2009 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) PATH_TO_FFMPEG_SOURCE := $(LOCAL_PATH)/ffmpeg LOCAL_C_INCLUDES += $(PATH_TO_FFMPEG_SOURCE) LOCAL_LDLIBS := -lffmpeg LOCAL_MODULE := hello-jni LOCAL_SRC_FILES := hello-jni.c include $(BUILD_SHARED_LIBRARY)
# The ARMv7 is significanly faster due to the use of the hardware FPU APP_ABI := armeabi-v7a APP_PLATFORM := android-8
接下來把剛剛build ffmpeg的source tree整個搬進jni目錄裡, 目錄名字記得換成ffmpeg
5.ndk-build
全部設定完之後, 在hello-jni的目錄下輸入ndk-build, 編譯完成後會產生libs目錄, 裡面會有libhello-jni.so, 把我們剛剛build好的libffmpeg.so也放進這個目錄.
6.test
上面步驟都完成後, 接下來就是在device上執行. 執行成功的話畫面上會出現一段數字, 這樣就完成基本測試了!
目前先測試到這裡, 等有空再繼續往下作.
沒有留言:
張貼留言