用NDK编译FFmpeg
8 月前
416次访问
作者:
s980601 来源:
eoe开发者社区
关键词: NDK 编译 FFmpeg
导读:Android内置的编解码器实在太少,于是我们需要FFmpeg。Android提供了NDK,为我们使用FFmpeg这种C语言代码提供了方便。
首先创建一个标准的Android项目vPlayer
1 |
android create project -n vPlayer -t 8 -p vPlayer -k me.abitno.vplayer -a PlayerView |
然后在vPlayer目录里
3 |
tar xf ffmpeg- 0.6 .tar.bz2 && mv ffmpeg- 0.6 ffmpeg && cd ffmpeg |
在ffmpeg下新建一个config.sh,内容如下,注意把PREBUILT和PLATFORM设置正确。另外里面有些参数你也可以自行调整,我主要是为了配置一个播放器而这样设置的。
03 |
PREBUILT=/home/abitno/Android/android-ndk-r4/build/prebuilt/linux-x86/arm-eabi- 4.4 . 0 |
04 |
PLATFORM=/home/abitno/Android/android-ndk-r4/build/platforms/android- 8 /arch-arm |
06 |
./configure --target-os=linux \ |
20 |
--enable-protocol=file \ |
23 |
--disable-mpegaudio-hp \ |
25 |
--enable-cross-compile \ |
26 |
--cc=$PREBUILT/bin/arm-eabi-gcc \ |
27 |
--cross-prefix=$PREBUILT/bin/arm-eabi- \ |
28 |
--nm=$PREBUILT/bin/arm-eabi-nm \ |
29 |
--extra-cflags= "-fPIC -DANDROID" \ |
33 |
--extra-ldflags= "-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl" |
运行config.sh开始configure
configure完成后,编辑刚刚生成的config.h,找到这句
1 |
#define restrict restrict |
Android的GCC不支持restrict关键字,于是修改成下面这样
编辑libavutil/libm.h,把其中的static方法都删除。分别修改libavcodec、libavfilter、libavformat、libavutil、libpostproc和libswscale下的Makefile,把下面两句删除
1 |
include $(SUBDIR)../subdir.mak |
2 |
include $(SUBDIR)../config.mak |
在ffmpeg下添加一个文件av.mk,内容如下
01 |
# LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale |
03 |
#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak |
04 |
include $(LOCAL_PATH)/../config.mak |
09 |
include $(LOCAL_PATH)/Makefile |
12 |
OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes) |
16 |
FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME)) |
17 |
FFCFLAGS = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno- switch -Wno-pointer-sign |
18 |
FFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\" |
20 |
ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S) |
21 |
ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES))) |
23 |
ifneq ($(ALL_S_FILES),) |
24 |
ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES)) |
25 |
C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS)) |
26 |
S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS)) |
32 |
C_FILES := $(patsubst %.o,%.c,$(C_OBJS)) |
33 |
S_FILES := $(patsubst %.o,%.S,$(S_OBJS)) |
35 |
FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES)) |
接下来要添加一系列的Android.mk,在jni根目录下的内容如下
1 |
include $(all-subdir-makefiles) |
在ffmpeg目录下,Android.mk
1 |
LOCAL_PATH := $(call my-dir) |
3 |
LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale |
5 |
include $(BUILD_SHARED_LIBRARY) |
6 |
include $(call all-makefiles-under,$(LOCAL_PATH)) |
libavformat/Android.mk
01 |
LOCAL_PATH := $(call my-dir) |
03 |
include $(LOCAL_PATH)/../av.mk |
04 |
LOCAL_SRC_FILES := $(FFFILES) |
08 |
LOCAL_CFLAGS += $(FFCFLAGS) |
09 |
LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex |
11 |
LOCAL_STATIC_LIBRARIES := $(FFLIBS) |
12 |
LOCAL_MODULE := $(FFNAME) |
13 |
include $(BUILD_STATIC_LIBRARY) |
libavcodec/Android.mk
01 |
LOCAL_PATH := $(call my-dir) |
03 |
include $(LOCAL_PATH)/../av.mk |
04 |
LOCAL_SRC_FILES := $(FFFILES) |
08 |
LOCAL_CFLAGS += $(FFCFLAGS) |
10 |
LOCAL_STATIC_LIBRARIES := $(FFLIBS) |
11 |
LOCAL_MODULE := $(FFNAME) |
12 |
include $(BUILD_STATIC_LIBRARY) |
libavfilter、libavutil、libpostproc和libswscale下的Android.mk内容如下
01 |
LOCAL_PATH := $(call my-dir) |
03 |
include $(LOCAL_PATH)/../av.mk |
04 |
LOCAL_SRC_FILES := $(FFFILES) |
08 |
LOCAL_CFLAGS += $(FFCFLAGS) |
09 |
LOCAL_STATIC_LIBRARIES := $(FFLIBS) |
10 |
LOCAL_MODULE := $(FFNAME) |
11 |
include $(BUILD_STATIC_LIBRARY) |
最外层的jni/Android.mk和jni/ffmpeg/Android.mk只是随便这样写的,你应该根据自己的需求改写