ffmpeg移植Android方法以及常见问题汇总
2014-08-02 17:49
344 查看
ffmpeg移植Android方法以及常见问题汇总:
1.在ffmpeg官网下载源码包,比如ffmpeg-2.3。在ffmpeg目录下增加Android.mk 和av.mk config.sh三个文件。
2.config.sh用于配置ffmpeg环境脚本,可键入
#!/bin/sh
PREBUILT=...android-ndk-r7b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
PLATFORM=...android-ndk-r7b/platforms/android-14/arch-arm
exportTMPDIR=.../ tmp
./configure--target-os=linux \
--arch=arm\
--enable-cross-compile\
--cc=$PREBUILT/bin/arm-linux-androideabi-gcc-4.4.3\
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi-\
--nm=$PREBUILT/bin/arm-linux-androideabi-nm\
--extra-cflags="-fPIC-DANDROID" \
--enable-static\
--disable-shared\
--disable-asm\
--disable-yasm\
--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"
PREBUILT、PLATFORM、TMPDIR是需要修改的,配置自己的ndk路径,通常这一步出错概率极高。TMPDIR路径一定要存在且可以访问。
常见错误:
arm-linux-androideabi-gccis unable to create an executable file,一般是tmp文件没有设置。
UnknownC compiler/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/ arm-linux-androideabi-gcc,一般是NDK配置错误。
./config.sh:line 8: --arch: command not found,./configure每一个参数后的转行符号\,注意后面不要有空格符,另外也有可能是字符格式错误,要转为unix,在vim里 :set ff=unix保存退出。
--cc、--cross-prefix、--nm、--extra-ldflags注意配置路径要正确,否则脚本执行失败。
./configure是配置ffmpeg选项的,可以按个人需求添加删减,不赘述。
执行该脚本,如果正确,大约数分钟后执行结束,会自动生成config.h和config.mak。如果执行出错,一般是配置问题。
3.av.mk文件键入
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))
即可。
4.在需要编译的目录(不同版本ffmpeg有区别),比如在libavcodec、ibavdevice、libavfilter、libavformat、libavutil、libpostproc、libswscale、libswresample目录下分别放入一个Android.mk文件,键入
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)
即可,这几个目录下的Android.mk是一样的。也可以自己配置LOCAL_MODULE和LOCAL_STATIC_LIBRARIES,不过上述脚本配置简单。
然后删除libavcodec、ibavdevice、libavfilter、libavformat、libavutil、libpostproc、libswscale、libswresample目录下的Makefile中的
include$(SUBDIR)../config.mak和include$(SUBDIR)../subdir.mak,后者在2.3版本中并不存在,确保自己的Makefile里没有这2句就可以了。
5.编写Android.mk,放置ffmpeg根目录,即av.mk、config.sh同级目录
这里有2个,一个是用于编译libffmpeg.so的脚本,如下:
LOCAL_PATH:= $(call my-dir)
include$(CLEAR_VARS)
LOCAL_STATIC_LIBRARIES:= libavformat libavcodec libavutil libpostproc libswscale libavfilterlibavdevice
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= libffmpeg
include$(BUILD_SHARED_LIBRARY)
include$(call all-makefiles-under,$(LOCAL_PATH))
也可以写一个生产ffmpeg的执行文件的mk脚本:
LOCAL_PATH:= $(call my-dir)
include$(CLEAR_VARS)
LOCAL_MODULE_TAGS:= optional
LOCAL_PRELINK_MODULE:= false
LOCAL_SRC_FILES:=\
cmdutils.c \
ffmpeg.c \
ffmpeg_opt.c \
ffmpeg_filter.c
LOCAL_SHARED_LIBRARIES:= \
libffmpeg
LOCAL_MODULE:= ffmpeg
#include$(BUILD_SHARED_LIBRARY)
include$(BUILD_EXECUTABLE)
include$(call all-makefiles-under,$(LOCAL_PATH))
其中,LOCAL_SRC_FILES具体文件视版本而定,至少包含cmdutils.c和ffmpeg.c,编译后根据错误依次添加对应的c文件即可。
6.常用的移植修改和编译报错
因为是移植,所以有些文件必须修改才能编译通过,对config.h修改:
老的ffmpeg是将#define restrict restrict改为#define restrict
新版本是#defineav_restrict av_restrict改为#define av_restrict
将ffmpeg/libavutil/libm.h中所有static的函数删除。然后编译,如果
报错/works/workspace/android-console/jni/ffmpeg.c:3636:19:error: storage size of 'rusage' isn't known
/works/workspace/android-console/jni/ffmpeg.c:3638:15:error: 'RUSAGE_SELF' undeclared (first use in this function)
将config.h 中
#define HAVE_GETRUSAGE 1修改为#define HAVE_GETRUSAGE 0
报错/works/workspace/android-console/jni/cmdutils.c:270:19:error: storage size of 'rl' isn't known
/works/workspace/android-console/jni/cmdutils.c:271:19:error: 'RLIMIT_CPU' undeclared (first use in this function)
将config.h 中
#define HAVE_SETRLIMIT 1修改为 #define HAVE_SETRLIMIT0
报错/works/workspace/android-console/jni/cmdutils.c:41:21:fatal error: version.h: No such file ordirectory
在ffmpeg根目录下运行./version.sh . version.h
报错android-ndk-r8d/build/core/build-binary.mk:41:*** target file
`clean' has both : and :: entries. Stop.
把libavfilter目录中的Makefile末尾的clean命令注释掉
报错.../platforms/android-18/arch-arm/usr/include/stdlib.h:54:14:error: expected identifier or '(' before 'void'
.../platforms/android-18/arch-arm/usr/include/stdlib.h:54:14:error: expected ')' before numeric constant
将config.h里面的#define getenv(x) NULL注释掉。注意:这个修改是查询很多方法无效后自己修改的,发现问题是getenv和stblib里面的函数冲突了,grep看了一下没有用到这个宏,基本都是用的stblib的getenv方法,所以把这个宏注释掉。
诸如for(int i;i<x;i++)不支持这种写法的编译器,把参数提出来声明即可。
以上包含我遇到的也是常见的错误。
1.在ffmpeg官网下载源码包,比如ffmpeg-2.3。在ffmpeg目录下增加Android.mk 和av.mk config.sh三个文件。
2.config.sh用于配置ffmpeg环境脚本,可键入
#!/bin/sh
PREBUILT=...android-ndk-r7b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
PLATFORM=...android-ndk-r7b/platforms/android-14/arch-arm
exportTMPDIR=.../ tmp
./configure--target-os=linux \
--arch=arm\
--enable-cross-compile\
--cc=$PREBUILT/bin/arm-linux-androideabi-gcc-4.4.3\
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi-\
--nm=$PREBUILT/bin/arm-linux-androideabi-nm\
--extra-cflags="-fPIC-DANDROID" \
--enable-static\
--disable-shared\
--disable-asm\
--disable-yasm\
--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"
PREBUILT、PLATFORM、TMPDIR是需要修改的,配置自己的ndk路径,通常这一步出错概率极高。TMPDIR路径一定要存在且可以访问。
常见错误:
arm-linux-androideabi-gccis unable to create an executable file,一般是tmp文件没有设置。
UnknownC compiler/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/ arm-linux-androideabi-gcc,一般是NDK配置错误。
./config.sh:line 8: --arch: command not found,./configure每一个参数后的转行符号\,注意后面不要有空格符,另外也有可能是字符格式错误,要转为unix,在vim里 :set ff=unix保存退出。
--cc、--cross-prefix、--nm、--extra-ldflags注意配置路径要正确,否则脚本执行失败。
./configure是配置ffmpeg选项的,可以按个人需求添加删减,不赘述。
执行该脚本,如果正确,大约数分钟后执行结束,会自动生成config.h和config.mak。如果执行出错,一般是配置问题。
3.av.mk文件键入
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))
即可。
4.在需要编译的目录(不同版本ffmpeg有区别),比如在libavcodec、ibavdevice、libavfilter、libavformat、libavutil、libpostproc、libswscale、libswresample目录下分别放入一个Android.mk文件,键入
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)
即可,这几个目录下的Android.mk是一样的。也可以自己配置LOCAL_MODULE和LOCAL_STATIC_LIBRARIES,不过上述脚本配置简单。
然后删除libavcodec、ibavdevice、libavfilter、libavformat、libavutil、libpostproc、libswscale、libswresample目录下的Makefile中的
include$(SUBDIR)../config.mak和include$(SUBDIR)../subdir.mak,后者在2.3版本中并不存在,确保自己的Makefile里没有这2句就可以了。
5.编写Android.mk,放置ffmpeg根目录,即av.mk、config.sh同级目录
这里有2个,一个是用于编译libffmpeg.so的脚本,如下:
LOCAL_PATH:= $(call my-dir)
include$(CLEAR_VARS)
LOCAL_STATIC_LIBRARIES:= libavformat libavcodec libavutil libpostproc libswscale libavfilterlibavdevice
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= libffmpeg
include$(BUILD_SHARED_LIBRARY)
include$(call all-makefiles-under,$(LOCAL_PATH))
也可以写一个生产ffmpeg的执行文件的mk脚本:
LOCAL_PATH:= $(call my-dir)
include$(CLEAR_VARS)
LOCAL_MODULE_TAGS:= optional
LOCAL_PRELINK_MODULE:= false
LOCAL_SRC_FILES:=\
cmdutils.c \
ffmpeg.c \
ffmpeg_opt.c \
ffmpeg_filter.c
LOCAL_SHARED_LIBRARIES:= \
libffmpeg
LOCAL_MODULE:= ffmpeg
#include$(BUILD_SHARED_LIBRARY)
include$(BUILD_EXECUTABLE)
include$(call all-makefiles-under,$(LOCAL_PATH))
其中,LOCAL_SRC_FILES具体文件视版本而定,至少包含cmdutils.c和ffmpeg.c,编译后根据错误依次添加对应的c文件即可。
6.常用的移植修改和编译报错
因为是移植,所以有些文件必须修改才能编译通过,对config.h修改:
老的ffmpeg是将#define restrict restrict改为#define restrict
新版本是#defineav_restrict av_restrict改为#define av_restrict
将ffmpeg/libavutil/libm.h中所有static的函数删除。然后编译,如果
报错/works/workspace/android-console/jni/ffmpeg.c:3636:19:error: storage size of 'rusage' isn't known
/works/workspace/android-console/jni/ffmpeg.c:3638:15:error: 'RUSAGE_SELF' undeclared (first use in this function)
将config.h 中
#define HAVE_GETRUSAGE 1修改为#define HAVE_GETRUSAGE 0
报错/works/workspace/android-console/jni/cmdutils.c:270:19:error: storage size of 'rl' isn't known
/works/workspace/android-console/jni/cmdutils.c:271:19:error: 'RLIMIT_CPU' undeclared (first use in this function)
将config.h 中
#define HAVE_SETRLIMIT 1修改为 #define HAVE_SETRLIMIT0
报错/works/workspace/android-console/jni/cmdutils.c:41:21:fatal error: version.h: No such file ordirectory
在ffmpeg根目录下运行./version.sh . version.h
报错android-ndk-r8d/build/core/build-binary.mk:41:*** target file
`clean' has both : and :: entries. Stop.
把libavfilter目录中的Makefile末尾的clean命令注释掉
报错.../platforms/android-18/arch-arm/usr/include/stdlib.h:54:14:error: expected identifier or '(' before 'void'
.../platforms/android-18/arch-arm/usr/include/stdlib.h:54:14:error: expected ')' before numeric constant
将config.h里面的#define getenv(x) NULL注释掉。注意:这个修改是查询很多方法无效后自己修改的,发现问题是getenv和stblib里面的函数冲突了,grep看了一下没有用到这个宏,基本都是用的stblib的getenv方法,所以把这个宏注释掉。
诸如for(int i;i<x;i++)不支持这种写法的编译器,把参数提出来声明即可。
以上包含我遇到的也是常见的错误。
相关文章推荐
- Linux系统网卡配置详解以及—常见问题的解决方法以及—硬盘移植后网卡的配置
- 联想yoga升级Win8.1系统教程以及常见问题解决方法汇总介绍
- Android笔记:常见错误问题及解决方法汇总 推荐
- Android WebView问题汇总以及解决方法
- Android调试技巧与常见问题解决方法汇总
- 编译Android源码时常见问题以及解决方法
- Android新建工程遇到问题汇总以及解决方法
- Android应用程序开发常见问题汇总
- 驱动版本移植常见问题 android2.3
- Android手机常见问题以及解决办法[非开发]
- Moss/SharePoint 常见问题以及解决方法(持续更新中)
- 在GNOME的ubuntu桌面环境中安装KDE的方法以及常见问题
- 解决Android平台移植ffmpeg的一揽子问题
- CETK测试原理/测试方法/测试结果分析以及常见WinCE Test Kit运行问题的排查
- Hadoop使用常见问题以及解决方法
- Android常见问题解决方法
- 解决Android平台移植ffmpeg的一揽子问题
- Hadoop常见问题与解决方法汇总
- Hadoop使用常见问题以及解决方法
- Helix android移植问题汇总