FFmpeg库移植并优化YUV、BGR24 转化

最近项目使用OpenCV实现视频帧透视变换,当切换视频流720p、1280p,出现部分手机和小米ipad2平板等出现视频流卡顿、应用程序退出问题。原因分析:OpenCV API 方法:cvtColor() 实现yuv 与 bgr24转化消耗时间较长,因此视频流的优化,就是减少各种转换消耗的时间。

FFmpeg so包编译和jni开发
  • 下载FFmpeg 3.1.3
    网址:https://ffmpeg.org/download.html#build-mac

    image.png

  • 下载NDK
    NDK下载地址

  • 配置ndk环境

    1. 启动终端Terminal
    2. 进入当前用户的home目录
    3. 输入cd ~ 或 /Users/YourUserName
    4. 创建.bash_profile
    5. 输入touch .bash_profile
    6. 编辑.bash_profile文件
    7. 输入open -e .bash_profile

    因为是为了配置NDK开发环境,输入Android NDK下目录,前面是android sdk的,可以不用动它,最终.bash_profile文件如下:

    export NDK_ROOT=/Users/YourUserName/Downloads/android-ndk-r13      
    export PATH=$PATH:$NDK_ROOT
    
  1. 保存文件,关闭.bash_profile
  2. 更新刚配置的环境变量
    输入source .bash_profile
  • 编译FFmpeg
    在编译前,在源码中,修改FFmpeg的configure
    下载FFmpeg源代码之后,首先需要对源代码中的configure文件进行修改。由于编译出来的动态库文件名的版本号在.so之后(例如“libavcodec.so.5.100.1”),而android平台不能识别这样文件名,所以需要修改这种文件名。在configure文件中找到下面几行代码(在3209-3212行):
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)'  

替换为下面内容:

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

接下来开始写shell脚本
重命名为build_android.sh。脚本如下:

#!/bin/bash  
#export TMPDIR="/Users/YourUserName/program/ffmpeg-3.4.2"  
NDK=/Users/YourUserName/Downloads/android-ndk-r13
NDK_VERSION=android-18
function build_one {
./configure \
--target-os=linux \
--arch=$ARCH \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--disable-symver \
--enable-cross-compile \
--cross-prefix=$CROSS_COMPILE \
--sysroot=$SYSROOT \
--extra-cflags="-fpic"
make clean
make
make install
}
ARCH=arm 
CPU=arm
PREFIX=$(pwd)/android/$CPU
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-
SYSROOT=$NDK/platforms/$NDK_VERSION/arch-$ARCH
build_one

如果大家要编译,记得改下前三行,对应自己机器上的环境
接着开始执行这个shell脚本,在终端输入./ build_android.sh
开始进行自动编译:

中间过程:



结果如下:


这时会发现 FFmpeg下多了一个文件夹android:


打开如下:



这样我们要的so就有了,当然,这只是基本的。

  • 移植到Android平台
  1. 在src/main下建一个jni目录



    把前面编译好的android目录移植过来

image.png
  1. 编写 Android.mk Application.mk文件
    Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := ffmpeg/lib/$(TARGET_ARCH_ABI)/libavcodec.so
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE := avdevice
LOCAL_SRC_FILES := ffmpeg/lib/$(TARGET_ARCH_ABI)/libavdevice.so
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE := avfilter
LOCAL_SRC_FILES := ffmpeg/lib/$(TARGET_ARCH_ABI)/libavfilter.so
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE := avformat
LOCAL_SRC_FILES := ffmpeg/lib/$(TARGET_ARCH_ABI)/libavformat.so
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := ffmpeg/lib/$(TARGET_ARCH_ABI)/libavutil.so
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES := ffmpeg/lib/$(TARGET_ARCH_ABI)/libswscale.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := swresample
LOCAL_SRC_FILES := ffmpeg/lib/$(TARGET_ARCH_ABI)/libswresample.so
include $(PREBUILT_SHARED_LIBRARY)

LOCAL_MODULE := apm-plugin-video-preprocessing
LOCAL_SRC_FILES := \
    video_preprocessing_plugin_jni.cpp \

LOCAL_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/include

LOCAL_LDLIBS += -latomic
LOCAL_LDLIBS +=  -lm -llog

LOCAL_SHARED_LIBRARIES := \
        libyuv  \
        avcodec \
        avdevice\
        avfilter\
        avformat\
        avutil  \
        swscale \
        swresample

include $(BUILD_SHARED_LIBRARY)
APP_ALLOW_MISSING_DEPS :=true

Application.mk

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI :=  armeabi armeabi-v7a
#arm64-v8a x86 x86_64
APP_PLATFORM := android-18
APP_CFLAGS += -Wno-error=format-security
APP_ALLOW_MISSING_DEPS :=true
  1. 编写.cpp文件,完成jni开发
    注意:在C++文件中引入C头文件需添加
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavutil/pixfmt.h>
#include <libswscale/swscale.h>
}

1、新建一个类,声明native方法。这个类是java与C/C++交互的中介,方法由java声明,由C/C++实现。

public class VideoPreProcessing {
    static {
        System.loadLibrary("apm-plugin-video-preprocessing");
    }
    ...
    public native void resetVideo();
}

确认自己类的包名!使用javah生成.h头文件
javah命令应该这么写:

/Users/Documents/workspace/app/src/main/java >javah -jni com.example.VideoPreProcessing

然后就能看到生成了一个h文件。
2、 新建一个jni文件夹,新建main.c,把.h里面的内容复制进去,并实现里面的函数。

JNIEXPORT void JNICALL Java_com_example_VideoPreProcessing_resetVideo
        (JNIEnv *env, jobject obj)
{
}

3、至此,VideoPreProcessing.cpp 中可以实现 C++中调用ffmpeg so包实现方法,完成YUV与RGB转换.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容