Windows下用ndk编译ffmpeg
第一步:创建一个android工程,然后将ffmpeg整体放到jni下,并创建Android.mk和Application.mk
Android.mk:
{
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#include $(all-subdir-makefiles)
include $(LOCAL_PATH)/ffmpeg/Android.mk
LOCAL_SHORT_COMMANDS :=true
}
Application.mk:
{
# The ARMv7 issignificanly faster due to the use of the hardware FPU
APP_ABI := armeabi-v7a
APP_PLATFORM :=android-9
#APP_MODULES := libffmpeg
APP_BUILD_SCRIPT :=$(call my-dir)/Android.mk
APP_PROJECT_PATH :=$(call my-dir)
APP_SHORT_COMMANDS := true
}
第二步:在ffmpeg下新建一个android_config.sh,然后运行android_config.sh
android_config.sh :
{
#!/bin/bash
E:/research_workspace/FFmpeg/jni/ffmpeg/configure --disable-static --enable-shared --enable-gpl --enable-version3 --enable-nonfree --enable-doc --enable-ffmpeg --enable-ffplay --enable-ffprobe --enable-ffserver --enable-avdevice --enable-avfilter --enable-postproc --enable-small --cross-prefix=D:/android-ndk-r8e/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi- --enable-cross-compile --target-os=linux --extra-cflags='-ID:/android-ndk-r8e/platforms/android-9/arch-arm/usr/include' --extra-ldflags='-LD:/android-ndk-r8e/platforms/android-9/arch-arm/usr/lib -nostdlib' --arch=arm --disable-symver --disable-debug --disable-stripping
}
第三步:在ffmpeg下添加一个文件av.mk和Android.mk,在libavcodec、libavfilter、libavformat、libavutil、libpostproc和libswscale下添加Android.mk,然后分别修改libavcodec、libswresample 、libavfilter、libavformat、libavutil、libpostproc和libswscale下的Makefile,把include $(SUBDIR)../config.mak屏蔽
Ffmpeg下的Android.mk:
{
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_WHOLE_STATIC_LIBRARIES:= libavformat libavcodec libavutil libpostproc libswresample libswscale
LOCAL_LDLIBS := \
-llog \
-lgcc \
-lz
LOCAL_MODULE := ffmpeg
include $(BUILD_SHARED_LIBRARY)
#include$(BUILD_STATIC_LIBRARY)
include $(call all-makefiles-under, $(LOCAL_PATH))
}
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))
}
libavcodec、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_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES:= $(FFLIBS)
LOCAL_MODULE :=$(FFNAME)
include $(BUILD_STATIC_LIBRARY)
}
libavformat下的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_CFLAGS +=-include "string.h" -Dipv6mr_interface=ipv6mr_ifindex
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)/../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)
}
第四步:
没有找到config.mak, config.h的话,手动从C:\cygwin\home\WIN下拷过来
手动添加 libavutil/ffversion.h #define FFMPEG_VERSION "wr.ndkr8e.ffmpeg281";
没有找到avconfig.h,手动从C:\cygwin\home\WIN\libavutil下拷过来
将libavutil里的libm.h里的static函数注释掉
第五步:
最后运行ndk-build
遇到的问题:
问题1:
{
$ ./android_config.sh
D:/android-ndk-r8e/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-gccis unable to create an executable file.
C compiler testfailed.
}
尝试
export TMPDIR="d:/temp"
{
$ /cygdrive/d/ffmpeg-2.8.1/android_config.sh
/cygdrive/d/ffmpeg-2.8.1/android_config.sh:行3:$'\r':未找到命令
.nable to createtemporary file in d:/temp
}
解决:
这个问题是因为cygwin的路径起点与交叉编译工具链的路径起点不一致,需要在configure进行之前将configure内用到的TMPDIR变量设置为cygwin中某个文件夹在windows中的路径。
即:exportTMPDIR=D:/cygwin/tmp或者其它路径。
export TMPDIR=C:/cygwin/temp
{
WIN@WIN70509/cygdrive/d/ffmpeg-2.8.1
$ ./android_config.sh
D:/ffmpeg-2.8.1/configure:line 5743: [: =: unary operator expected
install prefix /usr/local
source path .
C compiler D:/android-ndk-r8e/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-gcc
C library bionic
host C compiler gcc
host C library
ARCH arm (armv5te)
big-endian no
runtime cpudetection yes
ARMv5TE enabled yes
ARMv6 enabled yes
ARMv6T2 enabled yes
VFP enabled yes
NEON enabled yes
THUMB enabled no
debug symbols no
strip symbols no
optimize forsize yes
optimizations yes
static no
shared yes
postprocessingsupport yes
new filtersupport yes
network support yes
threadingsupport no
safe bitstreamreader yes
SDL support no
opencl enabled no
texi2htmlenabled no
perl enabled no
pod2man enabled no
makeinfo enabled no
makeinfo supportsHTML no
Enabled programs:
ffmpeg ffprobe
External libraries: