windows下用ndk r9编译ffmpeg

网上大部分资料都是用ndk r4在linux下编译ffmpeg,本文介绍在windows下用r9的ndk编译ffmpeg2.2.4的历程。

最终目标:libffmpeg.so


前面的配置借鉴了网上的资料,但还是详细阐述下吧(ps:以下涉及到新建文件的地方都必须是UNIX格式文件):

1.下载源码解压ffmpeg release v2.2.4

2.用eclipse新建一个android工程,新建jni目录把源码目录ffmpeg2.2.4拷贝到此目录下

3.安装cygwin(之前就有安装的的,所以不知道依赖哪些包,用的时候缺哪里就下载什么吧)

4.下载并解压ndk,adt也可以,新建系统环境变量ANDROID_NDK_HOME,设置好自己的ndk目录

5.在工程目录下新建编译脚本build_ffmpeg.h(UNIX格式),内容如下:

APPNAME="FFmpegRecorder"

# options
echo "Build C/C++ code for $APPNAME using Android NDK"

# paths
NDK_ROOT="${ANDROID_NDK_HOME}"

if [ -z "${NDK_ROOT+aaa}" ];then
echo "please define NDK_ROOT"
exit 1
fi

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# ... use paths from sytem path

APP_ROOT="$DIR/.."
APP_ANDROID_ROOT="$DIR"

echo "NDK_ROOT = $NDK_ROOT"
echo "APP_ROOT = $APP_ROOT"
echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT"

 "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* "NDK_MODULE_PATH="

6.在jni目录下新建Android.mk文件,内容如下:

include $(all-subdir-makefiles)
#LOCAL_PATH := $(call my-dir)  
7.在ffmpeg2.2.4目录下新建配置脚本config.sh,内容如下:
#!/bin/bash
#
# paths
export NDK_ROOT="${ANDROID_NDK_HOME}"
PREBUILT=$NDK_ROOT/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64
PLATFORM=$NDK_ROOT/platforms/android-19/arch-arm
ARMELF_PATH=$PREBUILT/arm-linux-androideabi/lib/ldscripts/armelf_linux_eabi.x
CRT_DIR=$PREBUILT/lib/gcc/arm-linux-androideabi/4.6
echo "PREBUILT = $PREBUILT"
echo "PLATFORM = $PLATFORM"
echo "ARMELF_PATH = $ARMELF_PATH"
echo "CRT_DIR = $CRT_DIR"
./configure --target-os=linux \
        --arch=arm \
        --enable-version3 \
        --enable-gpl \
        --enable-nonfree \
        --disable-stripping \
        --disable-ffmpeg \
        --disable-ffplay \
        --disable-ffserver \
        --disable-ffprobe \
        --disable-encoders \
        --disable-muxers \
        --disable-devices \
        --disable-protocols \
        --enable-protocol=file \
        --enable-avfilter \
        --disable-network \
        --disable-avdevice \
        --enable-cross-compile \
        --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" \
        --disable-asm \
        --enable-neon \
        --enable-armv5te \
        --extra-cflags="-I ${PLATFORM}/usr/include -fPIC -DANDROID -std=c99" \
        --extra-ldflags="-Wl,-T,$ARMELF_PATH -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $CRT_DIR/crtbegin.o $CRT_DIR/crtend.o -lc -lm -ldl"

8.添加各个模块文件

ffmpeg2.2.4目录下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))

ffmpeg2.2.4目录下Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := ffmpeg

LOCAL_WHOLE_STATIC_LIBRARIES := \
		libavutil \
    libavcodec \
    libavfilter \
    libavformat \
    libpostproc \
    libswscale \
    libswresample
    
LOCAL_LDLIBS := -lz
include $(BUILD_SHARED_LIBRARY)



include $(call all-makefiles-under,$(LOCAL_PATH))
ffmpeg2.2.4\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)
ffmpeg-0.6.6\libavcodec下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)
ffmpeg2.2.4/libavfilter、libavutil、libpostproc、 libswresample 和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)
9.源代码修改:

将libavutil/time.h改名libavutil/avtime.h
    libavutil/time.c改名libavutil/avtime.c 

 
  
将以下文件中的"libavutil/time.h"作相应修改

  ffmpeg.c
  f fplay.c
  ffserver.c
  libavcodec/fft-test.c
  libavcodec/dct-test.c
  libavcodec/motion-test.c
  libavformat/rtspenc.c
  libavformat/utils.c
  libavformat/hls.c
  libavformat/sapenc.c
  libavformat/rtspdec.c
  libavformat/network.c
  libavformat/rtpdec.c
  libavformat/rtsp.c
  libavformat/mux.c:37
  libavformat/hlsproto.c
  libavformat/ftp.c
  libavformat/udp.c
  libavformat/rtmphttp.c
  libavformat/tcp.c
  libavformat/avio.c
  libavutil/avtime.c
  libavutil/des.c
编译的时候入到找不到 libavutil/time.h,改成libavutil/avtime.h即可

10.启动cygwin切换到ffmpeg2.2.4目录下,执行:sh config.sh,执行的比较慢,等待完成吧,

如果有错,一般是config.sh里面的路径配置错了,或者自己看看config.log解决问题

11.上一步执行成功,则会生成config.h,对此文件的部分内容做如下修改:


在#define av_restrict restrict这一行之前添加

#define restrict

修改如下定义为下面的值:

#define HAVE_CBRT 1
#define HAVE_ISINF 1
#define HAVE_ISNAN 1
#define HAVE_LOG2F 0
#define HAVE_LRINT 1
#define HAVE_LRINTF 1
#define HAVE_RINT 1
#define HAVE_ROUND 1
#define HAVE_TRUNC 1

12.cygnwin切换到工程目录下执行:sh build_ffmpeg.sh

如果成功,最后会输出以下语句:

[armeabi] SharedLibrary  : libffmpeg.so
[armeabi] Install        : libffmpeg.so => libs/armeabi/libffmpeg.so

libffmpeg.so即为最终结果动态库,大概5.3M大小:libffmpeg.so


如果遇到其他编译问题可以百度查一下,但是建议自己看看错误原因进行分析。


我是折腾了一阵子,祝你好运~_~

你可能感兴趣的:(windows下用ndk r9编译ffmpeg)