ndk-r9d下ffmpeg-2.6.3的编译

来源:互联网 发布:淘宝联盟用红包 编辑:程序博客网 时间:2024/05/18 21:43

环境:

OS: ubuntu 12.04.3

android-ndk-r9d

ffmpeg: 2.6.3

 

第一步:解压ffmpeg

                命令:tar jxvf ffmpeg-2.5.3.tar.bz2

第二步:在android-ndk-r9d/sources下新建ffmpeg-2/jni,复制解压后的ffmpeg-2.6.3至此文件夹。(放入sample文件夹下会报:./configure:no such file 错误)

              文件目录结构为:~/android-ndk-r9d/sources/ffmpeg-2/jni

第三步:修改替换ffmpeg文件夹中的configure文件,将以下四行

SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'

替换为

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_LINKS='$(SLIBNAME)'

第四步:在ffmpeg目录下创建build_android.sh文件,内容如下:

(6.29号更新如下,原因是后面使用时发现配置不合适导致无法解码,无法播放视频)

NDK_ROOT=/home/liulq/android-ndk-r9dPREBUILT=${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64PLATFORM=${NDK_ROOT}/platforms/android-9/arch-arm./configure --target-os=linux\      --arch=arm\      --enable-small\      --enable-static\      --disable-asm\      --enable-armv5te\      --enable-cross-compile\      --enable-muxers\      --enable-demuxers\      --enable-avfilter\      --enable-protocols\      --disable-debug\      --disable-doc\      --disable-stripping\      --disable-ffmpeg\      --disable-ffplay\      --disable-ffprobe\      --disable-ffserver\      --disable-encoders\      --disable-hwaccels\      --disable-bsfs\      --disable-avdevice\      --disable-shared\      --disable-postproc\      --cc=$PREBUILT/bin/arm-linux-androideabi-gcc\      --cross-prefix=$PREBUILT/bin/arm-linux-androideabi-\      --nm=$PREBUILT/bin/arm-linux-androideabi-nm\      --extra-cflags="-fPIC -DANDROID"\      --extra-ldflags='-L$PLATFORM/usr/lib -nostdlib'\echo "#undef restrict" >> config.hecho "#define restrict" >> config.hecho "#undef HAVE_LRINT" >> config.hecho "#define HAVE_LRINT 1" >> config.hecho "#undef HAVE_LRINTF" >> config.hecho "#define HAVE_LRINTF 1" >> config.hecho "#undef HAVE_ROUND" >> config.hecho "#define HAVE_ROUND 1" >> config.hecho "#undef HAVE_ROUNDF" >> config.hecho "#define HAVE_ROUNDF 1" >> config.hecho "#undef HAVE_TRUNCF" >> config.hecho "#define HAVE_TRUNCF 1" >> config.h

编辑好后依次执行命令:

chmod u+x build_android.sh

vi build_android.sh 删除每个“/”之前的空格

:setff=unix  修改文件格式

:wq 保存退出

./config_android.sh   执行sh文件

执行sh文件后生成了config.h文件,里面定义了很多解码类型。

第五步:编辑刚刚生成的config.h,找到这句

#define restrict restrict

Android的GCC不支持restrict关键字,于是修改成下面这样

#define restrict

并将

#define HAVE_GMTIME_R 0

改为

#define HAVE_GMTIME_R 1

#define HAVE_LOCALTIME_R 0

改为

#define HAVE_LOCALTIME_R 1

第六步:编辑libavutil/libm.h,把其中的static方法都删除。

可以用

#if 0

#endif 注释掉

第七步:分别修改libavcodec、libavfilter、libavformat、libavutil、libpostproc和libswscale,libswresample下的Makefile,把每个Makefile中的下面两句删除或注释掉

include $(SUBDIR)../config.mak

第八步:在ffmpeg下添加一个文件av.mk

# LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).makinclude $(LOCAL_PATH)/../config.makOBJS :=OBJS-yes :=MMX-OBJS-yes :=include $(LOCAL_PATH)/Makefile# collect objectsOBJS-$(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-signFFCFLAGS += -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))elseC_OBJS := $(OBJS)S_OBJS :=endifC_FILES := $(patsubst %.o,%.c,$(C_OBJS))S_FILES := $(patsubst %.o,%.S,$(S_OBJS))FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))

第九步:添加一系列的Android.mk

ffmpeg-2目录下

include $(all-subdir-makefiles)
jni目录下

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_WHOLE_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale libswresampleLOCAL_MODULE := ffmpeginclude $(BUILD_SHARED_LIBRARY)include $(call all-makefiles-under,$(LOCAL_PATH))
libavformat下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindexLOCAL_LDLIBS := -lzLOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)

libavcodec下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_LDLIBS := -lzLOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)
libavutil下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        LOCAL_C_INCLUDES += $(SYSROOT_INC)/usr/includeLOCAL_C_INCLUDES += \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)

libavfilter、libpostproc和libswscale,libswresample下

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)

注:这些mk文件都要修改为unix文件格式

第十步:运行:~/android-ndk-r9d/ndk-build

运行后会在ffmpeg目录下生成libs和obj目录

在libs/armeabi目录下有libffmpeg.so,大小约为5000多kb


错误处理:

报错:

/home/liulq/android-ndk-r9d/build/core/build-binary.mk:120:*** target file `clean' has both : and :: entries.  Stop.

解决:

修改libavfilter目录中的Makefile,它的末尾处多了 Clean 这个玩意儿 将其注释掉或者删掉就可以了

报错:

error: static declaration of 'localtime_r'follows non-static declaration

解决:找到这个文件,并不是未声明的错误,应该是configure的时候有错,所以修改config.h文件,如第五步所述。

在移植编译的过程中,遇到很多类似说未声明,少括号,没定义的错误,基本都不是真的,都是因为configure有错,一直改一直改一直试一直试就好了

报错:

生成的libffmpeg.so很小,只有5kb,肯定是不对的

解决:修改jni目录下的Android.mk,

LOCAL_STATIC_LIBRARIES 改为LOCAL_WHOLE_STATIC_LIBRARIES


最后可以测试一下生成的库是否可用,可以借鉴这篇博文

http://blog.sina.com.cn/s/blog_a000da9d01011lg8.html


整个流程参考了这篇博文,有一些改动,应该是由于平台和版本不同,谢谢博主!

http://www.cnblogs.com/uvsjoh/archive/2013/01/17/2864630.html


第一篇博文,也许也是唯一一篇,记录下,实在被这个东西折磨的够了!今天终于编出来了!吃好吃的去!

0 0