libyuv是Google开源的实现YUV数据格式转换,旋转,缩放和镜像等操作的库。

编译

使用cmake+ndk来编译.so文件

在新建的AS工程中建一个module--libyuv,该module下的源码目录下新建cpp目录,将下载的libyuv相关文件导入到cpp目录中:

在src目录下新建CMakeLists.txt,脚本内容为:

cmake_minimum_required(VERSION 3.4.1)
include_directories(src/main/cpp/libyuv/include)
add_subdirectory(src/main/cpp/libyuv ./build)# 查找指定目录下的所有源文件,然后将结果存进指定变量名
aux_source_directory(src/main/cpp SRC_FILE)
add_library(yuvutilSHARED${SRC_FILE})
find_library(log-lib log)
target_link_libraries(yuvutil ${log-lib} yuv)

在libyuv这个module的build.gradle配置中指定CMakeLists.txt的路径:

 externalNativeBuild {cmake {path 'CMakeLists.txt'}}

在local.properties文件中指定ndk路径:

ndk.dir=/.../Android/sdk/ndk/21.0.6011959

然后build这个module就OK了

使用

ibyuv的旋转,缩放,镜像等操作都是通过I420格式来进行的,所以对于不是I420格式的yuv输入首先要进行格式转换。

应用层通过jni的方式来使用libyuv,此处以NV21转I420为例进行演示。

java层中提供一个native方法:

/*** Convert NV21 to I420* @param nv21Src  NV21 input data* @param width    source width* @param height   source height * @param i420Dst  I420 output data*/
public static native void yuvNV21ToI420(byte[] nv21Src, int width, int height, byte[] i420Dst);

在libyuv的covert.cc文件中提供了NV21转I420的api

// Convert NV12 to I420.
LIBYUV_API
int NV12ToI420(const uint8* src_y,int src_stride_y,const uint8* src_uv,int src_stride_uv,uint8* dst_y,int dst_stride_y,uint8* dst_u,int dst_stride_u,uint8* dst_v,int dst_stride_v,int width,int height) {return X420ToI420(src_y, src_stride_y, src_stride_y, src_uv, src_stride_uv,dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v,dst_stride_v, width, height);
}

jni实现:

extern "C"
JNIEXPORT void JNICALL
Java_com_libyuv_util_YuvUtil_yuvNV21ToI420(JNIEnv *env, jclass jcls, jbyteArray nv21Src,jint width, jint height, jbyteArray i420Dst) {jbyte *src_nv21_data = env->GetByteArrayElements(nv21Src, NULL);jbyte *dst_i420_data = env->GetByteArrayElements(i420Dst, NULL);NV21ToI420(src_nv21_data, width, height, dst_i420_data);env->ReleaseByteArrayElements(i420Dst, dst_i420_data, 0);
}// NV21:YYYY YYYY VU VU
// I420: YYYY YYYY UU VV
void NV21ToI420(jbyte *src_nv21_data, jint width, jint height, jbyte *dst_i420_data) {jbyte *src_y_plane = src_nv21_data;jbyte *src_uv_plane = src_nv21_data + width * height;jbyte *dst_y_plane = dst_i420_data;jbyte *dst_u_plane = dst_i420_data + width * height;jbyte *dst_v_plane = dst_u_plane + (width * height / 4);libyuv::NV12ToI420((const uint8_t *) src_y_plane, width,(const uint8_t *) src_uv_plane, width,(uint8_t *) dst_y_plane, width,(uint8_t *) dst_v_plane, width / 2,(uint8_t *) dst_u_plane, width / 2,width, height);
}

输入都统一为I420的格式后,就可以进行愉快的旋转,缩放和镜像等操作了。

常见的yuv操作都做个封装Util,代码:

https://github.com/sifutang/libyuv.git

推荐阅读:

OpenGL ES 实现实时音频的可视化

或许是迄今为止第一篇讲解 fps 计算原理的文章吧

推荐几个堪称教科书级别的 Android 音视频入门项目

OpenGL 实现视频编辑中的转场效果

觉得不错,点个在看呗~

libyuv的编译与使用相关推荐

  1. Android 端处理 YUV 数据 - Libyuv 的编译与使用

    在 Android 系统上, Camera 输出的图像一般为 NV21(YUV420SP 系列) 格式, 当我们想进行录像处理时, 会面临两个问题 问题 1 图像的旋转问题 后置镜头: 需要旋转 90 ...

  2. libyuv—AndroidStudio 编译libyuv

    libyuv是google 开源的用于实现对各种yuv数据之间的转换包括裁剪.缩放.旋转,以及yuv和rgb 之间的转换,底层有一部分代码是基于汇编实现的,大大提高了转换速度.在Android 平台下 ...

  3. Android libyuv应用系列(二)libyuv在Android中的使用

    请尊重分享成果,转载请注明出处,本文来自Coder包子哥,原文链接: http://blog.csdn.net/zxccxzzxz/article/details/53982849 上篇文章Andro ...

  4. NDK学习笔记:FFmpeg音视频同步3(你追我赶,升级ffmpeg/libyuv支持neon)

    NDK学习笔记:FFmpeg音视频同步3 本篇内容说多不多,但如果要说得明明白白的,可能就有点难度了.所以我决定把我的调试过程日志都呈现出来,方便大家理解.继上一篇文末,我们学习到了什么是DTS/PT ...

  5. ffmpeg学习笔记-native原生绘制

    上次已将ffmpeg的动态库编译出来了,并且使用了ffmpeg的转码功能,成功将mp4格式视频转化为yuv视频,这篇文章基于上次测试的demo,使用surfaceview显示解码完成的像素数据 布局设 ...

  6. metaRTC实现安卓webrtc推流直播

    概述 metaRTC新版本开始支持安卓系统,推拉流(直播和播放)流程中拉流.编解码.渲染.音视频采集播放等都在C++类库中进行,减少了因jvm和native流媒体交换降低性能. 下载源码 https: ...

  7. 【错误记录】编译 ijkplayer 报错 (fatal error: libyuv.h: No such file or directory #include “libyuv.h“ )

    文章目录 一.报错信息 二.解决方案 参考 https://github.com/bilibili/ijkplayer 项目的编译过程 ; 一.报错信息 在编译完 ffmpeg 之后 , 执行 ./c ...

  8. 编译android平台libyuv库(使用ndk)

    环境准备 1.使用ubuntu系统 2.ndk的版本为25.1.8937393 下载源码 git clone https://github.com/lemenkov/libyuv 将inlude 和s ...

  9. libYUV编译成静态库以及使用

    简介 Google提供了一套Image的开源库libyuv(git clone https://chromium.googlesource.com/libyuv/libyuv),实现对各种yuv数据之 ...

最新文章

  1. 合理配置MySQL缓存 提高缓存命中率
  2. OpenStack Skyline 现代化的管理界面
  3. JavaWeb学习总结(二)——Tomcat服务器学习和使用(一)
  4. protobuf 中的嵌套消息的使用 主要对set_allocated_和mutable_的使用
  5. 好大夫王航:长尾开发者应尽快接入百度轻应用
  6. ahp层次分析法软件_层次分析法在历史街区研究中的应用简析
  7. OpenCV人脸识别之二:模型训练
  8. 关于table的用法(二)
  9. 3.过滤——比较过滤结果、2D中的移动平均线_2
  10. Tomato多拨脚本
  11. what?传统风控策略,无法cover到以下风控场景
  12. brighthouse mysql_MySQL 数据库中的数据页合并-爱可生
  13. 机器学习代码实战——KMeans(聚类)
  14. leetcode—25.链表排序题目leetcode总结
  15. python 文字转语音wav_使用Python实现文字转语音并生成wav文件的例子
  16. android 仿旅游日历控件_仿携程日历控件
  17. Java枚举类的使用说明
  18. 在我笔记本Ubuntu上装普罗米修斯记录
  19. linux bond 网卡带宽,Linux网卡绑定实现带宽翻倍
  20. 怎么删除微信的手机充值服务器,微信如何一键清空账单?全部删除的方法

热门文章

  1. 为了搞清楚类加载,竟然手撸JVM!
  2. 世界各国城镇人口占比数据(1960-2018年)
  3. R数据挖掘 第四篇:OLS回归分析
  4. oracle 启动crs进程,由于CRS磁盘dismount造成的CRS进程无法启动问题
  5. 集成友盟的意见反馈功能
  6. Solidworks安装失败,出现内部错误:该产品组件的windows installer没按预期运
  7. 京东数科Java一面面经
  8. 数据处理一条龙!这15个Python库不可不知
  9. Win10 Linux 子系统(WSL)监听端口报错Error `IN6_IS_ADDR_V4MAPPED (sin6-sin6_addr.s6_addr32)` Failed的处理
  10. 从零开始 飞机大战(五)实现子弹定位和动画