linux下使用ndk编译ffmpeg

我的环境:

OS: ubuntu 12.10

android-ndk-r7 ffmpeg: 0.8

下面是编译步骤:

第一步:

安装配置ndk

运行ndk-build,如果显示如下信息,则表示安装成功

linux下使用ndk编译ffmpeg

通过设置宏NDK_PROJECT_PATH来指定工程目录

export NDK_PROJECT_PATH=/home/robin/Desktop/wshare/jni



第二步:下载ffmpeg源码

第三步:

建立文件夹jni,把ffmpeg源码解压至jni目录下,用ndk编译时,jni目录是必须的,否则编译出错。

这一步后目录结构如下:

linux下使用ndk编译ffmpeg

ndk-build 默认编译jni下的文件,如果它找不到该目录,就要通过设置NDK_PROJECT_PATH来告诉它。

如果当前工作目录是在jni目录下或在jni的直接父目录中,则不需要设置这个宏。

第四步:

在ffmpeg目录下创建config_android.sh文件,内容设置如下。需要根据本机的ndk目录做相应更改。有些参数是必须的,有些参数可以根据应用环境按需设置。

NDK_ROOT=/home/robin/Desktop/android-ndk-r7
PREBUILT=${NDK_ROOT}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
PLATFORM=${NDK_ROOT}/platforms/android-14/arch-arm
./configure --target-os=linux 
--arch=arm 
--enable-small 
--enable-static 
--disable-asm 
--enable-armv5te 
--enable-cross-compile 
--disable-debug 
--disable-doc 
--disable-stripping 
--disable-ffmpeg 
--disable-ffplay 
--disable-ffprobe 
--disable-ffserver 
--disable-encoders 
--disable-muxers 
--disable-devices 
--disable-hwaccels 
--disable-bsfs 
--disable-protocols 
--disable-avdevice 
--disable-shared 
--disable-filters 
--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 __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

第五步:

运行./config_android.sh开始进行配置

运行过程中如果出错,可以参看config.log了解具体出错原因,一般而言,出错是由于相关目录没有配置正确。

configure完成后,编辑刚刚生成的config.h,找到这句

#define restrict restrict

Android的GCC不支持restrict关键字,于是修改成下面这样

#define restrict

编辑libavutil/libm.h,把其中的static方法都删除。

可以用

#if 0



#endif 注释掉

第六步:

分别修改libavcodec、libavfilter、libavformat、libavutil、libpostproc和libswscale下的Makefile,把每个Makefile中的下面两句删除或注释掉

include $(SUBDIR)../config.mak

include $(SRC_PATH)/subdir.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,在jni目录下的内如如下:

include $(all-subdir-makefiles)

在ffmpeg目录下,Android.mk内容如下

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

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)

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)

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)

第九步:

运行ndk-build

编译完成后,编译器会在jni相同的目录下创建两个文件夹libs, obj。编译输出会放在这两个文件夹中。

linux下使用ndk编译ffmpeg

Android.mk中部分宏的说明

LOCAL_PATH := $(call my-dir)

一个Android.mk 文件首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’,

由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。

include $( CLEAR_VARS)

CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES,

LOCAL_STATIC_LIBRARIES, 等等...),

除LOCAL_PATH 。这是必要的,因为所有的编译控制文件都在同一个GNU MAKE执行环境中,所有的变量都是全局的。

LOCAL_MODULE := hello-jni

编译的目标对象,LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包含任何空格。

注意:编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'hello-jni'的共享库模块,将会生成'libhello-jni.so'文件。

重要注意事项:

如果你把库命名为‘libhello-jni’,编译系统将不会添加任何的lib前缀,也会生成 'libhello-jni.so',这是为了支持来源于Android平台的

源代码的Android.mk文件,如果你确实需要这么做的话。

LOCAL_SRC_FILES := hello-jni.c

LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这里列出头文件和包含文件,因为编

译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。

注意,默认的C++源码文件的扩展名是’.cpp’. 指定一个不同的扩展名也是可能的,只要定义LOCAL_DEFAULT_CPP_EXTENSION变量,

不要忘记开始的小圆点(也就是’.cxx’,而不是’cxx’)

include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY表示编译生成共享库,是编译系统提供的变量,指向一个GNU Makefile脚本,负责收集自从上次调用

'include $(CLEAR_VARS)'以来,定义在LOCAL_XXX变量中的所有信息,并且决定编译什么,如何正确地去做。还有

BUILD_STATIC_LIBRARY变量表示生成静态库:lib$(LOCAL_MODULE).a, BUILD_EXECUTABLE 表示生成可执行文件。

参考:

http://www.cnblogs.com/qq78292959/archive/2011/01/12/2076982.html

http://www.cnblogs.com/hibraincol/archive/2011/05/30/2063847.html
原文链接: https://www.cnblogs.com/uvsjoh/archive/2013/01/17/2864630.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/75948

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午5:13
下一篇 2023年2月9日 下午5:15

相关推荐