当前位置: 首页 > news >正文

libyuv的编译与使用

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(yuvutil
        SHARED
        ${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 实现视频编辑中的转场效果

觉得不错,点个在看呗~

相关文章:

  • 没想到,快手成了“生产力”
  • Unity手游实战:从0开始SLG——客户端技术选型
  • 【数字视频技术介绍】| 视频帧类型(I 帧、P 帧、B 帧)
  • 【数字视频技术介绍】| 编码中的时间冗余和空间冗余
  • 错误终结者:Fragment在ViewPager中的正确应用
  • 如何理解图片采样,这应该算是基础知识吧?
  • Android OpenGL ES 实现 3D 阿凡达效果
  • 音视频开发入门必备之基础知识
  • 6/6 音视频技术大咖在线直播,教你开发者硬核个人成长指南
  • 关于多线程,你必须知道的那些玩意儿
  • Android Camera2 实现高帧率预览录制(附源码)
  • 自定义相机中如何实现二维码扫描功能
  • 渐变过渡的相册(shader)
  • 【C++11新特性】 C++11 智能指针之shared_ptr
  • 【C++11新特性】 C++11智能指针之weak_ptr
  • 【译】JS基础算法脚本:字符串结尾
  • android图片蒙层
  • ES6之路之模块详解
  • JS 面试题总结
  • JS变量作用域
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • mongodb--安装和初步使用教程
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Ruby 2.x 源代码分析:扩展 概述
  • Spring Cloud中负载均衡器概览
  • Terraform入门 - 1. 安装Terraform
  • yii2权限控制rbac之rule详细讲解
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 大数据与云计算学习:数据分析(二)
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 基于web的全景—— Pannellum小试
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 为什么要用IPython/Jupyter?
  • RDS-Mysql 物理备份恢复到本地数据库上
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • 组复制官方翻译九、Group Replication Technical Details
  • ​一些不规范的GTID使用场景
  • (007)XHTML文档之标题——h1~h6
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (16)Reactor的测试——响应式Spring的道法术器
  • (c语言)strcpy函数用法
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (二)windows配置JDK环境
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (力扣题库)跳跃游戏II(c++)
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐