以下所有操作均在Ubuntu 10.04 LTS OS上进行
Ubuntu下Android开发环境的搭建:
http://www.cnblogs.com/softman11/archive/2011/06/22/2086793.html
http://blog.csdn.net/jumping_android/article/details/7403322
本人JDK安装目录为:
/ipnc_dev/Android/jdk1.6.0_26
Adroid SDK安装目录为:
/ipnc_dev/Android/android-sdk-linux
NDK安装目录为:
/ipnc_dev/Android/android-ndk-r8c
~/.bashrc文件配置为
#for andriod developer export JAVA_HOME=/ipnc_dev/Android/jdk1.6.0_26 export JRE_HOME=/ipnc_dev/Android/jdk1.6.0_26/jre export PATH=/ipnc_dev/Android/jdk1.6.0_26/bin:$PATH export CLASSPATH=.:/ipnc_dev/Android/jdk1.6.0_26/lib:/ipnc_dev/Android/jdk1.6.0_26/jre/lib export PATH=/ipnc_dev/Android/android-ndk-r8c:$PATH
在/ipnc_dev/Andriod目录下创建文件夹Player,切换到Player目录下,使用下列命令创建一个标准的Android项目ipncPlayer
/ipnc_dev/Android/android-sdk-linux/platforms/tools/android create project -n ipncPlayer -t 8 -p ipncPlayer -k art.abitno.ipncplayer -a PlayerView然后在ipncPlayer目录里创建jni目录,切换到jni目录下,将Appro IPNC参考设计中的FFMPEG源码复制到该目录下(在原源码中,我自己做了很多修改,主要是内存泄漏相关的,经测试,使用新版本的ffmpeg时,MJPEG码流可以正常播放,但是H.264和MPEG4码流不能打开),该源码是使用经GoDB开发人员使用ffmpeg 0.52源码在windows上修改过的,所以要在移植到Android上,可以先在linux进行编译,看能否通过,之前本人在linux下修改编译通过,具体修改哪几部分源码忘记了,rtsp.c queue.c中修改的比较多,貌似都是关于线程方面的,在linux下使用pthread库函数替代即可.
此时的目录结构如下图所示
切换到FFMPEG目录下,新建一个andriod.config文件,内容如下
#!/bin/bash PREBUILT=/ipnc_dev/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86 PLATFORM=/ipnc_dev/Android/android-ndk-r8c/platforms/android-14/arch-arm ./configure --target-os=linux \ --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.6/crtbegin.o $PREBUILT/lib/gcc/arm-linux-androideabi/4.6/crtend.o -lc -lm -ldl" \ --arch=arm \ --enable-cross-compile \ --enable-armv5te \ --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \ --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \ --nm=$PREBUILT/bin/arm-linux-androideabi-nm \ --enable-version3 \ --enable-gpl \ --enable-nonfree \ --disable-stripping \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffserver \ --disable-asm \ --enable-neon \ --enable-shared \ --disable-debug \ --enable-small \ --enable-static \ --disable-muxers \ --enable-muxer=avi \ --enable-demuxer=avi \ --enable-demuxer=rtsp \ --enable-demuxer=http \ --disable-bsfs \ --disable-devices \ --disable-encoders \ --enable-encoder=h264 \ --enable-encoder=mpeg4 \ --enable-encoder=mjpeg \ --enable-encoder=pcm_mulaw \ --enable-encoder=aac \ --disable-decoders \ --enable-decoder=h264 \ --enable-decoder=mpeg4 \ --enable-decoder=mjpeg \ --enable-decoder=pcm_mulaw \ --enable-decoder=aac使用命令 chmod +x android.config添加文件执行权限,终端下运行./android.config进行ffmpeg编译配置,编译配置完成后,打开FFMPEG目录下config.h,
将代码
#define restrict restrict修改为
#define restrict据说是Android的GCC不支持restrict关键字,没有亲自测试过.
编辑libavutil/internal.h,把其中的static方法前的static关键字删除.
分别修改libavcodec、libavfilter、libavformat、libavutil、libpostproc和libswscale下的Makefile,把下面两句删除
include $(SUBDIR)../subdir.mak
include $(SUBDIR)../config.mak
注意这两行并不是连续的.
在FFMPEG目录下添加一个文件ffmpeg.mk,内容如下:
#LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale # #include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak include $(LOCAL_PATH)/../config.mak OBJS := OBJS-yes := MMX-OBJS-yes := include $(LOCAL_PATH)/Makefile #collect objects OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes) OBJS += $(OBJS-yes) FFNAME := lib$(NAME) FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME)) FFCFLAGS = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch -Wno-pointer-sign FFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\" ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S) ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES))) ifneq ($(ALL_S_FILES),) ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES)) C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS)) S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS)) else C_OBJS := $(OBJS) S_OBJS := endif C_FILES := $(patsubst %.o,%.c,$(C_OBJS)) S_FILES := $(patsubst %.o,%.S,$(S_OBJS)) FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))接下来添加一系列的Android.mk,在jni根目录下的内容如下:
include $(all-subdir-makefiles)FFMPEG目录下的Android.mk内容为:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale LOCAL_MODULE := ffmpeg include $(BUILD_SHARED_LIBRARY) include $(call all-makefiles-under,$(LOCAL_PATH))libavformat/Android.mk内容为:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) include $(LOCAL_PATH)/../ffmpeg.mk LOCAL_SRC_FILES := $(FFFILES) LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/.. LOCAL_CFLAGS += $(FFCFLAGS) LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex LOCAL_LDLIBS := -lz LOCAL_STATIC_LIBRARIES := $(FFLIBS) LOCAL_MODULE := $(FFNAME) include $(BUILD_STATIC_LIBRARY)libavcodec/Android.mk内容为:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) include $(LOCAL_PATH)/../ffmpeg.mk LOCAL_SRC_FILES := $(FFFILES) LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/.. LOCAL_CFLAGS += $(FFCFLAGS) LOCAL_LDLIBS := -lz LOCAL_STATIC_LIBRARIES := $(FFLIBS) LOCAL_MODULE := $(FFNAME) include $(BUILD_STATIC_LIBRARY)libavfilter、libavutil、libpostproc和libswscale下的Android.mk内容为:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) include $(LOCAL_PATH)/../ffmpeg.mk LOCAL_SRC_FILES := $(FFFILES) LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/.. LOCAL_CFLAGS += $(FFCFLAGS) LOCAL_STATIC_LIBRARIES := $(FFLIBS) LOCAL_MODULE := $(FFNAME) include $(BUILD_STATIC_LIBRARY)修改 NDK目录中/build/gmsl/ __gmsl文件的第512行 :
int_encode = $(__gmsl_tr1)$(wordlist 1, $1,$(__gmsl_input_int))修改为:
int_encode = $(__gmsl_tr1)$(wordlist 1,$(words $1),$(__gmsl_input_int))
否则ndk-build时出现"android-ndk-r8c/build/gmsl/__gmsl:512: *** non-numeric second argument to `wordlist' function: '"错误.
最后在jni目录下运行ndk-build进行编译.
本文主要参照blog:http://blog.sina.com.cn/s/blog_51396f890102dxdn.html