ndk-r9d下ffmpeg-2.6.3的编译

环境:

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-r9d
PREBUILT=${NDK_ROOT}/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64
PLATFORM=${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.h
echo "#define restrict" >> config.h
echo "#undef HAVE_LRINT" >> config.h
echo "#define HAVE_LRINT 1" >> config.h
echo "#undef HAVE_LRINTF" >> config.h
echo "#define HAVE_LRINTF 1" >> config.h
echo "#undef HAVE_ROUND" >> config.h
echo "#define HAVE_ROUND 1" >> config.h
echo "#undef HAVE_ROUNDF" >> config.h
echo "#define HAVE_ROUNDF 1" >> config.h
echo "#undef HAVE_TRUNCF" >> config.h
echo "#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).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

ffmpeg-2目录下

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

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

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.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下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.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)
libavutil下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES :=        
LOCAL_C_INCLUDES += $(SYSROOT_INC)/usr/include
LOCAL_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.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)

注:这些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


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值