• 方案选择

Android中集成ffmpeg的codec功能无非两种方式:

    1. JNI直接调用,主要用于App开发(无权限修改系统底层),如EXOPlayer,JPlayer等。
    2. 集成ffmpeg到OMX,即封装ffmpeg为OMX的plugin,然后实现component接口。

考虑到性能问题,我选取的方案二即集成ffmpeg到OMX。首先第一个问题就是ffmpeg的编译。也有两种方式:

    1. 集成ffmpeg源码到整个Android系统工程,独立写bp或mk进行编译。(由于ffmpeg配置复杂,参考网上的一些现成mk进行修改发现工作量比较巨大)
    2. 独立NDK编译ffmpeg成动态库或静态库,然后通过prebuild的方式集成。(由于OMX的plugin是直接动态加载动态库,无编译上的依赖,此种方法编译跟普通的ffmpeg编译类似,故推荐该方法)
  • FFmpeg配置

32bit编译配置:

 #!/bin/bash

 chmod  ./configure
#chmod ./version.sh
NDK=/your_ndk_path/android-ndk-r16b
SYSROOT=$NDK/platforms/android-/arch-arm
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
CROSS=$TOOLCHAIN/bin/arm-linux-androideabi- ISYSROOT=$NDK/sysroot
ASM=$ISYSROOT/usr/include/arm-linux-androideabi
CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
NM=$TOOLCHAIN/bin/arm-linux-androideabi-nm CPU=arm
PREFIX=./android/$CPU
ADDI_CFLAGS="-marm" function build_one
{
./configure \
--prefix=$PREFIX \
--target-os=linux \
--arch=$CPU \
--enable-cross-compile \
--incdir=$NDK/sysroot/usr/include \
--sysroot=$SYSROOT \
--cross-prefix=$CROSS \
--cc=$CC \
--nm=$NM \
--extra-cflags="-I$ASM -isysroot $ISYSROOT -Os -fpic $ADDI_CFLAGS" \
--enable-shared \
--enable-static \
--disable-asm \
--enable-pic \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--disable-debug \
--disable-encoders \
--disable-muxers \
--enable-avresample \
--disable-pthreads \
--enable-swresample
make
make install
} rm -rf $PREFIX
make distclean
build_one

说明:

1. --disable-asm选项是因为在ffmpeg-2.0的版本编译出版本运行时出现错误:libavcodec.so: has text relocation。 但是在用ffmpeg-3.3版本时没有出现。也有文章说跟NDK版本也有关系。

可以通过命令检查:readelf -a aarch64/lib/libavcodec.so |grep TEXTREL

2. 在高版本的ffmpeg(如3.3.8)中,可以直接指定--target-os=android ,否则就需要修改configure文件让输出的动态库不带版本号,修改SLIBNAME_WITH_VERSION等选项为:

SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)'
SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)'
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'

   3. ffmpeg增加动态库导出函数,只需要修改源码所在目录的.v文件,如在libavformat/libavformat.v中增加导出ffurl_register_protocol方法供外部代码链接。

64bit编译配置:

 #!/bin/bash

 chmod  ./configure
#chmod ./version.sh
NDK=/disk2/wuxingde/android-ndk-r16b
SYSROOT=$NDK/platforms/android-/arch-arm64
TOOLCHAIN=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64 ISYSROOT=$NDK/sysroot
ASM=$ISYSROOT/usr/include/aarch64-linux-android
CC=$TOOLCHAIN/bin/aarch64-linux-android-gcc
NM=$TOOLCHAIN/bin/aarch64-linux-android-nm CPU=aarch64
PREFIX=$(pwd)/android/$CPU
#ADDI_CFLAGS="-marm" function build_one
{
./configure \
--prefix=$PREFIX \
--target-os=linux \
--arch=$CPU \
--enable-cross-compile \
--incdir=$NDK/sysroot/usr/include \
--sysroot=$SYSROOT \
--cross-prefix=$TOOLCHAIN/bin/aarch64-linux-android- \
--cc=$CC \
--nm=$NM \
--extra-cflags="-I$ASM -isysroot $ISYSROOT -Os -fpic" \
--enable-shared \
--enable-static \
--enable-asm \
--enable-pic \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--disable-debug \
--disable-encoders \
--disable-muxers \
--enable-avresample \
--disable-pthreads \
--enable-swresample
make
make install
} rm -rf $PREFIX
make distclean
build_one
  • PREBUID

如果只用64bit版本可以直接使用下面Android.mk一次性编译:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PREBUILT_LIBS := \
lib/libavcodec.so \
lib/libavformat.so \
lib/libavutil.so \
lib/libavfilter.so \
lib/libswresample.so \
lib/libavresample.so \
lib/libswscale.so include $(BUILD_MULTI_PREBUILT)

如果同时需要32bit和64bit版本需要使用下面Android.mk分别编译各个库:

 LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) LOCAL_SRC_FILES_32 := \
arm/lib/libavcodec.so
LOCAL_SRC_FILES_64 := \
aarch64/lib/libavcodec.so
LOCAL_MODULE := libavcodec
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_MODULE_TARGET_ARCH := arm
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT) include $(CLEAR_VARS)
LOCAL_SRC_FILES_32 := \
arm/lib/libavformat.so
LOCAL_SRC_FILES_64 := \
aarch64/lib/libavformat.so
LOCAL_MODULE := libavformat
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_MODULE_TARGET_ARCH := arm
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT) include $(CLEAR_VARS)
LOCAL_SRC_FILES_32 := \
arm/lib/libavutil.so
LOCAL_SRC_FILES_64 := \
aarch64/lib/libavutil.so
LOCAL_MODULE := libavutil
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_MODULE_TARGET_ARCH := arm
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT) include $(CLEAR_VARS)
LOCAL_SRC_FILES_32 := \
arm/lib/libavresample.so
LOCAL_SRC_FILES_64 := \
aarch64/lib/libavresample.so
LOCAL_MODULE := libavresample
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_MODULE_TARGET_ARCH := arm
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT) include $(CLEAR_VARS)
LOCAL_SRC_FILES_32 := \
arm/lib/libavfilter.so
LOCAL_SRC_FILES_64 := \
aarch64/lib/libavfilter.so
LOCAL_MODULE := libavfilter
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_MODULE_TARGET_ARCH := arm
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT) include $(CLEAR_VARS)
LOCAL_SRC_FILES_32 := \
arm/lib/libswresample.so
LOCAL_SRC_FILES_64 := \
aarch64/lib/libswresample.so
LOCAL_MODULE := libswresample
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_MODULE_TARGET_ARCH := arm
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT) include $(CLEAR_VARS)
LOCAL_SRC_FILES_32 := \
arm/lib/libswscale.so
LOCAL_SRC_FILES_64 := \
aarch64/lib/libswscale.so
LOCAL_MODULE := libswscale
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
#LOCAL_MODULE_TARGET_ARCH := arm
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT)

编译部分就到此结束,这部分由于Android NDK版本(我用的是android-ndk-r16b)和ffmpeg版本不同,网上很多教程都没法用,花费了很多时间。特别要注意ffmpeg中--extra-cflags=配置,不要随意加额外一些定义,可能会导致链接不上的问题。

Android中集成ffmpeg(一):编译ffmpeg的更多相关文章

  1. Android中集成第三方库的方法和问题

    Android中集成第三方库的方法和问题 声明: 1. 本文參考了网上同学们的现有成果,在此表示感谢,參考资料在文后有链接. 2. 本文的重点在第三部分,是在开发中遇到的问题及解决的方法.第一,第二部 ...

  2. Android中集成第三方支付

    常见的第三方支付解决方案 支付宝支付 微信支付 银联支付 Ping++统一支付平台(需要继承服务器端和客户端) 短信支付 支付宝的集成流程 相关资料链接: 支付宝支付指引流程:支付指引流程 支付宝An ...

  3. Android中集成支付宝

    手机的在线支付,被认为是2012年最看好的功能,我个人认为这也是移动互联网较传统互联网将会大放光彩的一个功能. 人人有手机,人人携带手机,花钱买东西,不再需要取钱付现,不再需要回家上网银,想买什么,扫 ...

  4. cocos2d-x在android中响应返回键编译报错的bug分析

    先看一段代码如何在Android中加入返回按键的响应 <span style="font-size:18px;">自己派生CCKeypadDelegate的子类,然后注 ...

  5. Android中集成QQ登陆和QQ好友分享及QQ空间分享

    extends : http://blog.csdn.net/arjinmc/article/details/38439957 相关官方文档及下载地址: 如果只用分享和登陆,用lite包就可以,体积小 ...

  6. Android开发学习之路--Android Studio cmake编译ffmpeg

      最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...

  7. OpenCV - Android Studio 中集成Opencv环境(包含opencv_contrib部分)

    我在上一篇博客中说到了在Android中集成OpenCV,但是那个版本的OpenCV是没有SIFT和SURF算法的,因为这些算法是受专利保护的,所以并没有被包含在预编译库中,所以如果想要使用SIFT和 ...

  8. Android中的Apk的加固(加壳)原理解析和实现

    一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...

  9. Android中的Apk的加固(加壳)原理解析和实现(转)

    一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...

随机推荐

  1. 创建私有CA, 加密解密基础, PKI, SSL

    发现了一篇图文并茂的超棒的  加密解密, CA, PKI, SSL 的基础文章, 链接如下:https://blog.csdn.net/lifetragedy/article/details/5223 ...

  2. 浅谈htmlentities 、htmlspecialchars、addslashes的使用方法

    html_entity_decode():把html实体转换为字符. $str = "just atest & 'learn to use '"; echo html_en ...

  3. (2016北京集训十四)【xsy1557】task

    题解: 限制可以看成图状结构,每个任务的对物品数量的影响可以看成权值,只不过这个权值用一个五元组来表示. 那么题意要求的就是最大权闭合子图,网络流经典应用. 代码: #include<algor ...

  4. 《鸟哥的Linux私房菜》读书笔记--第0章 计算机概论 硬件部分

    一个下午看了不少硬件层面的知识,看得太多太快容易忘记.于是在博客上写下读书笔记. 有关硬件 个人计算机架构&接口设备 主板芯片组为“南北桥”的统称,南北桥用于控制所有组件之间的通信. 北桥连接 ...

  5. vuejs--递归组件(树型表格分享)

    前言    前段时间使用vue做了一套后台管理系统,其中使用最多就是递归组件,也因为自己对官方文档的不熟悉使得自己踩了不少坑,今天写出来和大家一起分享. 递归组件    组件在它的模板内可以递归地调用 ...

  6. Object-C,对象和方法

    学习Object-C,买了2本书,其中1本是用C币买的,总体质量一般,比较基础. 另外一本是,疯狂-李阳写的,大部头,比较吓人,比较全一点. 对于面向对象,之前还是有个大概的理解,再多点基础的例子. ...

  7. 【Henu ACM Round#24 A】k-String

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 如果是一个k-string的话. 考虑最后的串假设形式为sss..ss(k个s) 则s中出现的字母,整个串中最后出现的次数肯定为k的 ...

  8. IIS Express加入MIME映射

    近期在用Grid Report做Web报表的时候,碰到一件非常挠头的事. 本地用VS2010写的代码,调试的时候Web报表无法显示,用24.248server上VS2013相同仍是无法显示.最后把项目 ...

  9. JAVA学习第四十五课 — 其它对象API(一)System、Runtime、Math类

    一.System类 1. static long currentTimeMillis() 返回以毫秒为单位的当前时间. 实际上:当前时间与协调世界时 1970 年 1 月 1 日午夜之间的时间差(以毫 ...

  10. litepal更好的操作sqlite3,配置与基本操作

    litepal更好的操作sqlite3 配置 在app下的build.gradle中加入 创建litepal.xml配置 在app/src/main下面创建assets,新建litepal.xml & ...