博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux下使用ndk编译ffmpeg
阅读量:4471 次
发布时间:2019-06-08

本文共 5914 字,大约阅读时间需要 19 分钟。

我的环境:

OS: ubuntu 12.10
android-ndk-r7 ffmpeg: 0.8

下面是编译步骤:

第一步:
安装配置ndk
运行ndk-build,如果显示如下信息,则表示安装成功
通过设置宏NDK_PROJECT_PATH来指定工程目录
export NDK_PROJECT_PATH=/home/robin/Desktop/wshare/jni

第二步:下载ffmpeg源码

第三步:

建立文件夹jni,把ffmpeg源码解压至jni目录下,用ndk编译时,jni目录是必须的,否则编译出错。
这一步后目录结构如下:
ndk-build 默认编译jni下的文件,如果它找不到该目录,就要通过设置NDK_PROJECT_PATH来告诉它。
如果当前工作目录是在jni目录下或在jni的直接父目录中,则不需要设置这个宏。

第四步:

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

NDK_ROOT=/home/robin/Desktop/android-ndk-r7PREBUILT=${NDK_ROOT}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86PLATFORM=${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.hecho "#define restrict __restrict__" >> config.hecho "#undef HAVE_LRINT" >> config.hecho "#define HAVE_LRINT 1" >> config.hecho "#undef HAVE_LRINTF" >> config.hecho "#define HAVE_LRINTF 1" >> config.hecho "#undef HAVE_ROUND" >> config.hecho "#define HAVE_ROUND 1" >> config.hecho "#undef HAVE_ROUNDF" >> config.hecho "#define HAVE_ROUNDF 1" >> config.hecho "#undef HAVE_TRUNCF" >> config.hecho "#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).makinclude $(LOCAL_PATH)/../config.makOBJS :=OBJS-yes :=MMX-OBJS-yes :=include $(LOCAL_PATH)/Makefile# collect objectsOBJS-$(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-signFFCFLAGS += -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))elseC_OBJS := $(OBJS)S_OBJS :=endifC_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 libswscaleLOCAL_MODULE := ffmpeginclude $(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.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindexLOCAL_LDLIBS := -lzLOCAL_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.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_LDLIBS := -lzLOCAL_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.mkLOCAL_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。编译输出会放在这两个文件夹中。

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 表示生成可执行文件。

参考:

转载于:https://www.cnblogs.com/uvsjoh/archive/2013/01/17/2864630.html

你可能感兴趣的文章
BootStrapTable 文档
查看>>
17 盒子模型
查看>>
iOS 9.0 xcode7
查看>>
ZOJ Problem Set - 1240 IBM Minus One
查看>>
【2051】数字方阵
查看>>
【ACM-ICPC 2018 沈阳赛区网络预赛 K】Supreme Number
查看>>
centos7 showdoc 手动安装部署
查看>>
T-SQL 行列互换
查看>>
OSCP Learning Notes - Post Exploitation(4)
查看>>
Linux如何共享远程文件夹(日志服查询的实现方法)
查看>>
[置顶] 数据结构之 二叉树的构造与遍历(先序,中序,后序,层次)
查看>>
Java笔记(十四) 并发基础知识
查看>>
树莓派 - RPi.GPIO
查看>>
敏捷开发 Scrum
查看>>
C#接口
查看>>
String 转 Date
查看>>
javascript之位置
查看>>
Tomcat在处理GET和POST请求时产生的乱码问题
查看>>
XSS 攻击原理及防护
查看>>
操作符重载
查看>>