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

android java 硬编码保存mp4 jni数据转换

目录

java imagereader编码保存

java NV21toYUV420SemiPlanar 编码保存视频用:

imageReader获取nv21

jni NV12toYUV420SemiPlanar函数:


代码来自博客:

【Android Camera2】彻底弄清图像数据YUV420_888转NV21问题/良心教学/避坑必读!_yuv420888转nv21_奔跑的鲁班七号的博客-CSDN博客

java imagereader编码保存

//Planar格式(P)的处理private static ByteBuffer getuvBufferWithoutPaddingP(ByteBuffer uBuffer,ByteBuffer vBuffer, int width, int height, int rowStride, int pixelStride){int pos = 0;byte []byteArray = new byte[height*width/2];for (int row=0; row<height/2; row++) {for (int col=0; col<width/2; col++) {int vuPos = col*pixelStride + row*rowStride;byteArray[pos++] = vBuffer.get(vuPos);byteArray[pos++] = uBuffer.get(vuPos);}}ByteBuffer bufferWithoutPaddings=ByteBuffer.allocate(byteArray.length);// 数组放到buffer中bufferWithoutPaddings.put(byteArray);//重置 limit 和postion 值否则 buffer 读取数据不对bufferWithoutPaddings.flip();return bufferWithoutPaddings;}//Semi-Planar格式(SP)的处理和y通道的数据private static ByteBuffer getBufferWithoutPadding(ByteBuffer buffer, int width, int rowStride, int times,boolean isVbuffer){if(width == rowStride) return buffer;  //没有buffer,不用处理。int bufferPos = buffer.position();int cap = buffer.capacity();byte []byteArray = new byte[times*width];int pos = 0;//对于y平面,要逐行赋值的次数就是height次。对于uv交替的平面,赋值的次数是height/2次for (int i=0;i<times;i++) {buffer.position(bufferPos);//part 1.1 对于u,v通道,会缺失最后一个像u值或者v值,因此需要特殊处理,否则会crashif(isVbuffer && i==times-1){width = width -1;}buffer.get(byteArray, pos, width);bufferPos+= rowStride;pos = pos+width;}//nv21数组转成buffer并返回ByteBuffer bufferWithoutPaddings=ByteBuffer.allocate(byteArray.length);// 数组放到buffer中bufferWithoutPaddings.put(byteArray);//重置 limit 和postion 值否则 buffer 读取数据不对bufferWithoutPaddings.flip();return bufferWithoutPaddings;}private static byte[] YUV_420_888toNV21(Image image) {int width =  image.getWidth();int height = image.getHeight();ByteBuffer yBuffer = getBufferWithoutPadding(image.getPlanes()[0].getBuffer(), image.getWidth(), image.getPlanes()[0].getRowStride(),image.getHeight(),false);ByteBuffer vBuffer;//part1 获得真正的消除padding的ybuffer和ubuffer。需要对P格式和SP格式做不同的处理。如果是P格式的话只能逐像素去做,性能会降低。if(image.getPlanes()[2].getPixelStride()==1){ //如果为true,说明是P格式。vBuffer = getuvBufferWithoutPaddingP(image.getPlanes()[1].getBuffer(), image.getPlanes()[2].getBuffer(),width,height,image.getPlanes()[1].getRowStride(),image.getPlanes()[1].getPixelStride());}else{vBuffer = getBufferWithoutPadding(image.getPlanes()[2].getBuffer(), image.getWidth(), image.getPlanes()[2].getRowStride(),image.getHeight()/2,true);}//part2 将y数据和uv的交替数据(除去最后一个v值)赋值给nv21int ySize = yBuffer.remaining();int vSize = vBuffer.remaining();byte[] nv21;int byteSize = width*height*3/2;nv21 = new byte[byteSize];yBuffer.get(nv21, 0, ySize);vBuffer.get(nv21, ySize, vSize);//part3 最后一个像素值的u值是缺失的,因此需要从u平面取一下。ByteBuffer uPlane = image.getPlanes()[1].getBuffer();byte lastValue = uPlane.get(uPlane.capacity() - 1);nv21[byteSize - 1] = lastValue;return nv21;}

java NV21toYUV420SemiPlanar 编码保存视频用:

        public byte[] NV21toYUV420SemiPlanar(byte[] nv21, int width, int height) {byte[] yuv420sp = new byte[width * height * 3 / 2];int frameSize = width * height;int i, j;System.arraycopy(nv21, 0, yuv420sp, 0, frameSize); // Y分量直接复制for (i = 0; i < frameSize / 4; i++) {j = i * 2;// NV21的UV分量交替排列,转为NV12需要调换U和V的位置yuv420sp[frameSize + j] = nv21[frameSize + j + 1]; // U分量yuv420sp[frameSize + j + 1] = nv21[frameSize + j]; // V分量}return yuv420sp;}

imageReader获取nv21

plane[0] + plane[2] =NV21;; plane[0] + plane[1] =NV12

Image image = reader.acquireLatestImage();
if (image == null) {return;
}Image.Plane[] planes = image.getPlanes();ByteBuffer yBuffer = image.getPlanes()[0].getBuffer();
int ySize = yBuffer.remaining();ByteBuffer vBuffer = image.getPlanes()[2].getBuffer();
int vSize = vBuffer.remaining();byte[] nv21_s = new byte[WIDTH*HEIGHT * 3 / 2];try {yBuffer.get(nv21_s, 0, yBuffer.remaining());vBuffer.get(nv21_s, ySize, vBuffer.remaining());imageQueue.put(nv21_s);
} catch (Exception e) {throw new RuntimeException(e);
}image.close();

注:

1.这种方式会缺最后一个像素的U分量或V分量,如果追求完美,对NV21,可以从plane[1]中取出最后的值追加到末尾;对NV12则是在plane[2]中取出最后的值追加到末尾;

2.只适用于图像宽度为8的整数倍的情况,否则因为需要做内存对齐,后面会补0,,导致image.getWidth()< plane.getRowStride(),这就需要对每一行舍去后面多余的0,然后再拼接,效率会低很多。

jni NV12toYUV420SemiPlanar函数:

    public  native byte[] NV12toYUV420SemiPlanar(byte[] data, int w, int h);
extern "C"JNIEXPORT jbyteArray JNICALL Java_com_sandstar_ai_objectdetector_ObjectDetector_NV12toYUV420SemiPlanar(JNIEnv* env, jobject, jbyteArray nv12, jint width, jint height) {jbyte* nv12_bytes = env->GetByteArrayElements(nv12, NULL);jsize nv21_length = env->GetArrayLength(nv12);int frameSize = width * height;std::vector<uint8_t> yuv420sp(nv21_length);std::memcpy(yuv420sp.data(), nv12_bytes, frameSize); // copy Yfor (int i = 0; i < frameSize / 4; ++i) {int j = i * 2;yuv420sp[frameSize + j] = nv12_bytes[frameSize + j + 1]; // copy Vyuv420sp[frameSize + j + 1] = nv12_bytes[frameSize + j]; // copy U}env->ReleaseByteArrayElements(nv12, nv12_bytes, 0);// Create a new byte array and put the data into itjbyteArray result = env->NewByteArray(nv21_length);env->SetByteArrayRegion(result, 0, nv21_length, reinterpret_cast<jbyte*>(yuv420sp.data()));return result;
}

相关文章:

android java 硬编码保存mp4 jni数据转换

目录 java imagereader编码保存 java NV21toYUV420SemiPlanar 编码保存视频用&#xff1a; imageReader获取nv21 jni NV12toYUV420SemiPlanar函数&#xff1a; 代码来自博客&#xff1a; 【Android Camera2】彻底弄清图像数据YUV420_888转NV21问题/良心教学/避坑必读!_yuv…...

那些你不得不知道的HTML知识点

目录 1、行内元素有哪些&#xff1f;块级元素有哪些&#xff1f; 空(void)元素有哪些&#xff1f;2、页面导入样式时&#xff0c;使用link和import有什么区别&#xff1f;3、title与h1的区别、b与strong的区别、i与em的区别&#xff1f;3.1 title与h1的区别&#xff1a;3.2 b与…...

如何复制主播的性格(此乃广告文)

上面这份ppt写于Fay开源之前。当然&#xff0c;以现在的认知再去评价当时的设计&#xff0c;会发现有诸多的不严谨&#xff0c;甚至缺憾。比如&#xff0c;以单层的网络结构肯定无法拟合人性这个复杂的东西&#xff0c;人性也不是只受已知的几个参数所作用。但我现在想说的是&a…...

【ES6】—【新特性】—Symbol详情

一、一种新的原始数据类型 定义&#xff1a;独一无二的字符串 二、 声明方式 1. 无描述声明 let s1 Symbol() let s2 Symbol() console.log(s1, s2) // Symbol() Symbol() console.log(s1 s2) // falsePS: Symbol 声明的值是独一无二的 2. 有描述的声明 let s1 Symb…...

openresty安装与网站发布

文章目录 安装依赖下载安装包解压安装包安装启动nginx配置环境变量配置开机启动发布静态网站 OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台&#xff0c;其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动…...

创建延时队列、springboot配置多个rabbitmq

创建延时队列 queue.file_delay_destroy x-dead-letter-exchange: exchange.file_delay_destroy x-message-ttl: 259200000 259200000为3天,1000为1秒创建普通队列 queue.file_destroy创建普通交换机 exchange.file_delay_destroytype选择fanout 交换机绑定普通队列 (图中…...

在kaggle中用GPU使用CGAN生成指定mnist手写数字

文章目录 1项目介绍2参考文章3代码的实现过程及对代码的详细解析独热编码定义生成器定义判别器打印我们的引导信息模型训练迭代过程中生成的图片损失函数的变化 4总结5 模型相关的文件 1项目介绍 在GAN的基础上进行有条件的引导生成图片cgan 2参考文章 GAN实战之Pytorch 使用…...

【NI USRP】哪些 USRP 设备支持全双工,哪些支持半双工?

译者 东枫电子科技 设备构成 NI USRPEttus USRPUSRP-2900B200USRP-2901B210USRP-2920N210 WBXUSRP-2921N210 XCVR 2450USRP-2922N210 SBXUSRP-2930N210 WBX GPSDOUSRP-2932N210 SBX GPSDOUSRP-2940RX310 WBX (x2)USRP-2942RX310 SBX (x2)USRP-2943RX310 CBX (x2)U…...

不拼花哨,只拼实用:unittest指南,干货为王!

Python为开发者提供了内置的单元测试框架 unittest&#xff0c;它是一种强大的工具&#xff0c;能够有效地编写和执行单元测试。unittest 提供了完整的测试结构&#xff0c;支持自动化测试的执行&#xff0c;能够对测试用例进行组织&#xff0c;并且提供了丰富的断言方法。最终…...

mysql 获取json数组中某个字段根据下标

MySQL获取JSON数组中某个字段根据下标 在MySQL中&#xff0c;JSON数据类型可以方便地存储、操作和查询包含复杂结构的数据。当我们需要从JSON数组中获取某个字段时&#xff0c;可以使用MySQL的JSON函数来实现。 1. JSON数据类型简介 JSON&#xff08;JavaScript Object Nota…...

深入理解Redis缓存穿透、击穿、雪崩及解决方案

深入理解Redis缓存穿透、击穿、雪崩及解决方案 一、简介Redis 简介缓存作用与优化 二、缓存问题的分类缓存穿透缓存击穿缓存雪崩 三、缓存穿透的解决方案布隆过滤器缓存空对象接口层校验 四、缓存击穿的解决方案互斥锁热点数据提前加载 五、缓存雪崩的解决方案增加缓存容错能力…...

java八股文面试[java基础]——字节码

字节码技术应用 字节码技术的应用场景包括但不限于AOP&#xff0c;动态生成代码&#xff0c;接下来讲一下字节码技术相关的第三方类库&#xff0c;第三方框架的讲解是为了帮助大家了解字节码技术的应用方向&#xff0c;文档并没有对框架机制进行详细分析&#xff0c;有兴趣的可…...

新能源汽车技术的最新进展和未来趋势

文章目录 电池技术的进步智能驾驶与自动驾驶技术充电基础设施建设新能源汽车共享和智能交通未来趋势展望结论 &#x1f389;欢迎来到AIGC人工智能专栏~探索新能源汽车技术的最新进展和未来趋势 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客…...

知虾shopee数据分析工具:shopee出单的商机利器

当今数字化时代&#xff0c;数据已经成为商业成功的关键要素之一。而Shopee作为东南亚最大的电商平台之一&#xff0c;其强大的数据分析工具正为商家提供了宝贵的市场洞察和决策支持。本文将深入探讨Shopee数据分析工具如何帮助商家抓住商机并取得成功。 洞察消费者需求&#x…...

python——ydata-profiling介绍与使用

ydata-profiling介绍与使用 ydata-profiling的作用ydata-profiling的安装与简单使用ydata-profiling的结果结构 ydata-profiling的实际应用场景1. 数据集比较2. 时间序列报告3. 对大型数据集进行概要分析4. 处理敏感数据5. 自定义报告的外观 ydata-profiling的作用 ydata-prof…...

(纯c)数据结构之------>链表(详解)

目录 一. 链表的定义 1.链表的结构. 2.为啥要存在链表及链表的优势. 二. 无头单向链表的常用接口 1.头插\尾插 2.头删\尾删 3.销毁链表/打印链表 4.在pos位置后插入一个值 5.消除pos位置后的值 6.查找链表中的值并且返回它的地址 7.创建一个动态开辟的结点 三.顺序表与链表…...

postman接口自动化测试框架实战!

什么是自动化测试 把人对软件的测试行为转化为由机器执行测试行为的一种实践。 例如GUI自动化测试&#xff0c;模拟人去操作软件界面&#xff0c;把人从简单重复的劳动中解放出来。 本质是用代码去测试另一段代码&#xff0c;属于一种软件开发工作&#xff0c;已经开发完成的用…...

Apache Doris 入门教程35:多源数据目录

概述 多源数据目录&#xff08;Multi-Catalog&#xff09;功能&#xff0c;旨在能够更方便对接外部数据目录&#xff0c;以增强Doris的数据湖分析和联邦数据查询能力。 在之前的 Doris 版本中&#xff0c;用户数据只有两个层级&#xff1a;Database 和 Table。当我们需要连接…...

响应式web-PC端web与移动端web(H5)兼容适配 选型方案

背景 项目需要&#xff0c;公司已经有一套PC端web&#xff0c;需要做一套手机端浏览器可用的&#xff0c;但是又想兼容pc端&#xff0c;适配的web项目。 以下是查阅到响应布局现成的开源模版。根据自己技术栈&#xff0c;vue2,js来搜索相关的开源项目。 RuoYi 使用若依快速…...

Redis持久化之RDB解读

目录 什么是RDB 配置位置参数解读 如何使用 自动触发 手动触发 save bgsave RDBRDB持久化文件的恢复 正常恢复 恢复失败处理方法 RDB优势 RDB 缺点 redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

大模型——基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程

基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程 下载安装Docker Docker官网:https://www.docker.com/ 自定义Docker安装路径 Docker默认安装在C盘,大小大概2.9G,做这行最忌讳的就是安装软件全装C盘,所以我调整了下安装路径。 新建安装目录:E:\MyS…...

如何做好一份技术文档?从规划到实践的完整指南

如何做好一份技术文档&#xff1f;从规划到实践的完整指南 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 总有一行代码&#xff0c;能点亮万千星辰。 &#x1f50d; 在技术的宇宙中&#xff0c;我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…...

Ray框架:分布式AI训练与调参实践

Ray框架&#xff1a;分布式AI训练与调参实践 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 Ray框架&#xff1a;分布式AI训练与调参实践摘要引言框架架构解析1. 核心组件设计2. 关键技术实现2.1 动态资源调度2.2 …...