FFmpeg 移植 Android
?
近期项目需要解析苹果的HLS流媒体协议,而FFmpeg从0.11.1“Happiness”版本开始,才增加了对HLS协议的支持。目前网上关于FFmpeg编译移植的文章有很多,但大多都是对旧版本的说明。新版本的源码对很多地方做了改动,包括一些变量名、常量名、函数名、函数参数、结构体等,所以在用旧版本的JNI接口时,需要相应地做出改动。这个编译移植工作确实花了本人不少时间,现在总结一下,希望能给到大家一些帮助。说明一点,本文阐述的不一定都正确,大家在编译过程中,难免会遇到各种各样的错误,可以提出来,一起讨论。
?
编译环境:Ubuntu 12.04、Android NDK r8
?
一、下载源码、新建工程
下载地址:http://ffmpeg.org/download.html ,下载最新ffmpeg-0.11.1压缩包。
在$NDK_HOME/samples/目录下(我的是/root/Develop/android-ndk-r8/samples/)创建一个FFMPEG-0.11目录,在里面新建一个jni目录,然后把ffmpeg源码解压放在jni里面,源码的文件夹重命名为libffmpeg,所以最后源码的路径是:
#!/bin/bashFFCONFIG_COMMON='--enable-version3--disable-gpl--disable-nonfree--disable-debug--disable-ffmpeg--disable-ffplay--disable-ffserver--disable-ffprobe--disable-encoders--disable-muxers--disable-devices--disable-protocols--enable-protocol=file--disable-swscale--disable-avfilter--enable-network--disable-avdevice--enable-parsers--disable-decoders--disable-demuxers--enable-demuxer=matroska--disable-demuxer=rm--disable-demuxer=avi--disable-demuxer=flv--disable-demuxer=mov--enable-demuxer=mp3--enable-demuxer=mpegps--enable-demuxer=mpegvideo--enable-demuxer=asf--enable-decoder=aac--enable-decoder=ac3--enable-decoder=dca--enable-decoder=flv--disable-decoder=h263--disable-decoder=h264--enable-decoder=svq3--enable-decoder=amrnb--enable-decoder=nellymoser--enable-decoder=pcm_alaw--enable-decoder=pcm_dvd--enable-decoder=pcm_mulaw--enable-decoder=pcm_s16be--enable-decoder=pcm_s16le--enable-decoder=pcm_s16le_planar--enable-decoder=pcm_s24be--enable-decoder=pcm_s24daud--enable-decoder=pcm_s24le--enable-decoder=pcm_s32be--enable-decoder=pcm_s32le--enable-decoder=pcm_s8--enable-decoder=pcm_u16be--enable-decoder=pcm_u16le--enable-decoder=pcm_u24be--enable-decoder=pcm_u24le--enable-decoder=pcm_u32be--enable-decoder=pcm_u32le--enable-decoder=atrac3--enable-decoder=pcm_u8--enable-decoder=sipr--enable-decoder=mjpeg--enable-decoder=mp1--enable-decoder=mp2--enable-decoder=mp3--enable-decoder=tscc--enable-decoder=mpeg1video--enable-decoder=mpeg2video--enable-decoder=mpeg4--enable-decoder=ra_144--enable-decoder=ra_288--enable-decoder=cook--enable-decoder=rv10--enable-decoder=rv20--enable-decoder=rv30--enable-decoder=rv40--enable-decoder=wmav1--enable-decoder=wmav2--enable-decoder=wmapro--disable-decoder=wmv1--disable-decoder=wmv2--disable-decoder=wmv3--enable-decoder=vc1--enable-decoder=msmpeg4v1--enable-decoder=msmpeg4v2--enable-decoder=msmpeg4v3'??可以根据需要自行配置以上参数。
?
2.?创建config.sh脚本
在jni目录下创建一个config.sh,内容如下:
?
#!/bin/bashsource config_common.sh /*这里执行上面的config_common.sh脚本*/cd libffmpeg /*进入libffmpeg目录*/PREBUILT=/root/Develop/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86PLATFORM=/root/Develop/android-ndk-r8/platforms/android-14/arch-arm./configure --target-os=linux \--arch=arm \--enable-shared \--enable-cross-compile \--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \--strip=$PREBUILT/bin/arm-linux-androideabi-strip \--extra-cflags="-fPIC -DANDROID" \--extra-ldflags="-Wl,-T,$PREBUILT/arm-linux-androideabi/lib/ldscripts/armelf_linux_eabi.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/crtbegin.o $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/crtend.o -lc -lm -ldl" \$FFCONFIG_COMMONcd .. /*返回jni目录*/ndk-build clean??
3. ?执行config.sh脚本
然后打开终端,执行以下命令:
?
LOCAL_LDLIBS := -lzLOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
LOCAL_ARM_MODE := arm
include $(BUILD_STATIC_LIBRARY)???
在jni/libffmpeg/libavcodec目录下新建Android.mk:
?
SharedLibrary : libffmpeg-jni.so/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libavformat.a(matroskadec.o): In function `matroska_decode_buffer':/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavformat/matroskadec.c:1071: undefined reference to `inflateInit_'/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavformat/matroskadec.c:1086: undefined reference to `inflate'/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavformat/matroskadec.c:1079: undefined reference to `inflateEnd'/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavformat/matroskadec.c:1091: undefined reference to `inflateEnd'/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libavformat.a(id3v2.o): In function `ff_id3v2_parse':/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavformat/id3v2.c:683: undefined reference to `uncompress'/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libavcodec.a(svq3.o): In function `svq3_decode_init':/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavcodec/svq3.c:915: undefined reference to `uncompress'/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libavcodec.a(tscc.o): In function `decode_end':/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavcodec/tscc.c:201: undefined reference to `inflateEnd'/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libavcodec.a(tscc.o): In function `decode_frame':/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavcodec/tscc.c:92: undefined reference to `inflateReset'/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavcodec/tscc.c:101: undefined reference to `inflate'/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libavcodec.a(tscc.o): In function `decode_init':/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavcodec/tscc.c:177: undefined reference to `inflateInit_'/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libavcodec.a(dsputil_init_arm.o): In function `ff_dsputil_init_arm':/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavcodec/arm/dsputil_init_arm.c:122: undefined reference to `ff_dsputil_init_armv5te'/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libavcodec.a(mpegvideo_arm.o): In function `ff_MPV_common_init_arm':/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavcodec/arm/mpegvideo_arm.c:47: undefined reference to `ff_MPV_common_init_armv5te'/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libavutil.a(cpu.o): In function `av_get_cpu_flags':/home/boyce/project/android/freshui-palyer/ffmpeg-player/jni/libffmpeg/libavutil/cpu.c:35: undefined reference to `ff_get_cpu_flags_arm'collect2: ld returned 1 exit statusmake: *** [/home/boyce/project/android/freshui-palyer/ffmpeg-player/obj/local/armeabi/libffmpeg-jni.so] Error 1SharedLibrary : libffmpeg-jni.soobj/local/armeabi/libavformat.a(matroskadec.o): In function `matroska_decode_buffer':ffmpeg-jni/libffmpeg/libavformat/matroskadec.c:1071: undefined reference to `inflateInit_'jni/libffmpeg/libavformat/matroskadec.c:1086: undefined reference to `inflate'jni/libffmpeg/libavformat/matroskadec.c:1079: undefined reference to `inflateEnd'ffmpeg-jni/libffmpeg/libavformat/matroskadec.c:1091: undefined reference to `inflateEnd'ffmpeg-obj/local/armeabi/libavformat.a(id3v2.o): In function `ff_id3v2_parse':jni/libffmpeg/libavformat/id3v2.c:683: undefined reference to `uncompress'obj/local/armeabi/libavcodec.a(svq3.o): In function `svq3_decode_init':jni/libffmpeg/libavcodec/svq3.c:915: undefined reference to `uncompress'obj/local/armeabi/libavcodec.a(tscc.o): In function `decode_end':jni/libffmpeg/libavcodec/tscc.c:201: undefined reference to `inflateEnd'obj/local/armeabi/libavcodec.a(tscc.o): In function `decode_frame':jni/libffmpeg/libavcodec/tscc.c:92: undefined reference to `inflateReset'jni/libffmpeg/libavcodec/tscc.c:101: undefined reference to `inflate'obj/local/armeabi/libavcodec.a(tscc.o): In function `decode_init':jni/libffmpeg/libavcodec/tscc.c:177: undefined reference to `inflateInit_'obj/local/armeabi/libavcodec.a(dsputil_init_arm.o): In function `ff_dsputil_init_arm':libffmpeg/libavcodec/arm/dsputil_init_arm.c:122: undefined reference to `ff_dsputil_init_armv5te'ffmpeg-obj/local/armeabi/libavcodec.a(mpegvideo_arm.o): In function `ff_MPV_common_init_arm':ffmpeg-jni/libffmpeg/libavcodec/arm/mpegvideo_arm.c:47: undefined reference to `ff_MPV_common_init_armv5te'ffmpeg-obj/local/armeabi/libavutil.a(cpu.o): In function `av_get_cpu_flags':jni/libffmpeg/libavutil/cpu.c:35: undefined reference to `ff_get_cpu_flags_arm'collect2: ld returned 1 exit statusmake: *** [obj/local/armeabi/libffmpeg-jni.so] Error 1