编译环境
- 操作系统:macOS 11.6
- NDK:22.1.7171670
- libyuv:Version: 1815 (截止 2022/03/24)
- cmake: 3.20.3
- gcc:
1
2
3
4
5Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 13.0.0 (clang-1300.0.29.3)
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
编译 libyuv
下载 libyuv
由于是编译 Android 中使用的 libyuv
,所以需要创建一个 Android 工程。读者可以创建自己的示例工程,会使用下文中作者的开源工程。
说明:为了能够让 Android 编译 Native 代码,因此需要将下载的 libyuv
放到 jni
目录中。
(可以从官网下载 libyuv 库,若读者无法下载,也可直接使用作者已经下载好的源代码 libyuv-20220324.tar.gz 。为了减少文件大小,该压缩文件中仅移除了 .git
文件夹。)
1 | cd /Users/yhz61010/AndroidStudioProjects/LeoAndroidBaseUtilProject-Kotlin/ |
修改 Android.mk 文件
注意:由于此文的目的不需要 JPEG 功能,因此编译 libyuv
时禁用了相关的 JPEG 依赖。
修改 ./libyuv/jni/Android.mk
文件,禁用 JPEG 依赖:
在 LOCAL_CPP_EXTENSION := .cc
之前,添加如下常量:
1 | LIBYUV_DISABLE_JPEG := "yes" |
之后,将原代码(86 至 87 行) :
1 | LOCAL_STATIC_LIBRARIES := libyuv_static |
替换成:
1 | LOCAL_STATIC_LIBRARIES := libyuv_static |
编译
在如下路径执行 ndk-build
命令,开始编译源代码:
1 | cd /Users/yhz61010/AndroidStudioProjects/LeoAndroidBaseUtilProject-Kotlin/libyuv/jni |
编译成功后,可以在 /Users/yhz61010/AndroidStudioProjects/LeoAndroidBaseUtilProject-Kotlin/libyuv/libs
目录中找到生成的各个平台所需的 libyuv.so
文件。
使用 libyuv
将源代码中的 libyuv/jni/include
文件夹,拷贝到需要使用 libyuv
的项目中,例如作者用到的 yuv-sdk
模块。需要将 include
文件夹,拷贝到 yuv-sdk/main/cpp
文件夹中。并将刚刚生成的不同平台的 so
文件,拷贝到 yuv-sdk/libs
中。
创建 CMakeLists.txt 文件,并修改 build.gradle 文件。
下面就可以开始在自己的 Native 代码中,使用 libyuv
库了。具体代码详见我的开源项目。
写完自己的 Native 代码后,就可以开始编译自己的 libyuv
库了。
-
使用
gradlew
命令编译1
2cd /Users/yhz61010/AndroidStudioProjects/LeoAndroidBaseUtilProject-Kotlin/
./gradlew yuv-sdk:assemble -
使用
Gradle
侧边栏编译
在 Android Studio 中,点击右侧的侧边栏 Gradle -> LeoAndroidBaseUtil -> yuv-sdk -> build -> assemble。 -
使用
Build
菜单编译
在 Android Studio 中,选中yuv-sdk
模块,然后点击 Build 菜单:Build -> Make Module 'LeoAndroidBaseUtil.yuv-sdk’
注意:可以在Build Variants
中修改编译选项。
编译完自己的 libyuv
后,使用起来就非常简单了,具体的可以查看 YuvUtil
工具类。下面是一些示例:
1 | val nv21Bytes = YuvUtil.i420ToNv21(i420Bytes, width, height) |
性能分析
以下是使用 libyuv 库与使用 Kotlin 直接对 YUV420 数据进行操作的性能分析:
视频尺寸(1920x1080) | 旋转 | 镜像 | 同时进行旋转与镜像 |
---|---|---|---|
libyuv | 5.5ms | 4.6ms | 6.9ms |
Kotlin | 26.9ms | 17.3ms | 35.7ms |
参考文献
- 使用libyuv对YUV数据进行缩放,旋转,镜像,裁剪等操作 - 简书
- https://github.com/hzl123456/LibyuvDemo/blob/master/libyuv/src/main/cpp/YuvJni.cpp
- ffmpeg4android/图解RGB565、RGB555、RGB16、RGB24、RGB32、ARGB32等格式的区别.md at master · byhook/ffmpeg4android · GitHub
- graphic4android/CMakeLists.txt at master · byhook/graphic4android · GitHub
- Android YUV图像转换算法和检测工具 - 简书
- Android音视频——Libyuv使用实战 - 掘金
- GitHub - GitLqr/LQRLibyuv: 基于 libyuv 封装各种图像格式转换,用于处理摄像头yuv图像数据
- LibyuvDemo/YuvUtil.java at master · hzl123456/LibyuvDemo · GitHub
- Android NDK —— Libyuv 编译与使用 - 掘金
- libyuvDemo/LibYUVDemo.cpp at 344b81c8fc3e565ce7f68aa19e4d38ec92660411 · zenith22/libyuvDemo · GitHub
- android全平台编译libyuv库实现YUV和RGB的转换_handy周的博客-CSDN博客_libyuv 转rgb
- 编译google libyuv so库_Lammyzp的博客-CSDN博客_libyuv.so
- Android环境下编译libyuv | 17哥
- GitHub - wangwei1237/libyuv-with-jpeg: 编译libyuv for Android
- YUV420转RGBA之使用libyuv - 简书