Android Camera Hal中通过Neon指令优化数据拷贝

背景描述:

Camera apk普通相机模式录像操作时,一般是同时请求两个流,即预览流和录像流。对于两个流输出图像格式和分辨率相同的情况下,是不是可以通过一个流拷贝得到另一个流的数据,进而节省掉一个Sensor输出处理两次的的开销?

我们都知道平时使用的memcpy()函数是由cpu来实现处理的,如果图像数据比较大的话是很耗cpu的,那么有没有什么方法能优化下copy操作使cpu占用小些?

这里介绍使用ARM Neon指令集实现输出拷贝的优化。

下面以具体实现,了解如何使用Neon指令实现一帧NV12图像数据的拷贝。

Android源码中有对Neon的支持,只需要在使用的模块引用&调用就可以了,实现如下:

#include <arm_neon.h>   //neon指令相关数据结构和接口定义void NeonMemcpy(void *dest, const void *src, size_t size){uint8_t* dst8 = static_cast<uint8_t*>(dest);const uint8_t* src8 = static_cast<const uint8_t*>(src);//小数据直接拷贝if (size < 64) {for (; size > 0; size--) {*dst8++ = *src8++;}return;}// 64字节对齐预处理const uintptr_t mask = 0x3F;const uintptr_t misalign = reinterpret_cast<uintptr_t>(src8) & mask;if (misalign > 0) {const size_t align_bytes = 64 - misalign;for (size_t i = 0; i < align_bytes; i++) {*dst8++ = *src8++;}size -= align_bytes;}// 主拷贝循环(每次64字节)const size_t chunks = size >> 6; // 64字节块数for (size_t i = 0; i < chunks; i++) {// 使用基本NEON指令替代vld1q_u8_x4uint8x16_t data0 = vld1q_u8(src8);        //从src8加载16个8位数据到data0uint8x16_t data1 = vld1q_u8(src8 + 16);uint8x16_t data2 = vld1q_u8(src8 + 32);uint8x16_t data3 = vld1q_u8(src8 + 48);vst1q_u8(dst8, data0);                   //将data0中的16个8位数据存储到dst8中vst1q_u8(dst8 + 16, data1);vst1q_u8(dst8 + 32, data2);vst1q_u8(dst8 + 48, data3);src8 += 64;dst8 += 64;}// 处理剩余数据(16字节块)size &= 63;const size_t vec16_count = size >> 4;for (size_t i = 0; i < vec16_count; i++) {vst1q_u8(dst8, vld1q_u8(src8));src8 += 16;dst8 += 16;size -= 16;}// 尾部字节处理for (; size > 0; size--) {*dst8++ = *src8++;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/908600.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPS word 已有多级列表序号

wps的word中&#xff0c;原来已生成的文档里&#xff0c;已存在序号。比如&#xff0c;存在2、2.1、2.1.1、2.1.1.1、2.1.1.1.1 5层序号&#xff0c;而且已分为5级。但增加内容的时候&#xff0c;并不会自动增加序号&#xff0c;应该如何解决&#xff1f; 原来长这样&#xff…

从零开始制作小程序简单概述

以下是结合案例的“从零制作小红书风格小程序”的全流程指南&#xff0c;采用小红书爆款笔记的结构呈现&#xff0c;并附CSDN参考资源&#x1f447;&#xff1a; 一、核心开发步骤&#xff08;附工具推荐&#xff09; 账号与定位 ✅ 注册类型选择&#xff1a;个人店&#xff08…

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…

网络编程之服务器模型与UDP编程

一、服务器模型 在网络通信中&#xff0c;通常要求一个服务器连接多个客户端 为了处理多个客户端的请求&#xff0c;通常有多种表现形式 1、循环服务器模型 一个服务器可以连接多个客户端&#xff0c;但同一时间只能连接并处理一个客户的请求 socket() 结构体 bind() listen() …

open3D:三维点云处理

open3d 点云数据处理 爆肝5万字❤️Open3D 点云数据处理基础&#xff08;Python版&#xff09;_python 点云 焊缝-CSDN博客 如何用NumPy读取和保存点云数据 - 知乎 读取并可视化点云 np.loadtxt 从txt中读取点集&#xff0c;并open3d显示单个点云 txt内容&#xff1a;每行皆…

使用联邦多轨迹图神经网络(GNNs)结合稀缺数据预测婴儿脑连接|文献速递-深度学习医疗AI最新文献

Title 题目 Predicting infant brain connectivity with federated multi-trajectory GNNs using scarce data 使用联邦多轨迹图神经网络&#xff08;GNNs&#xff09;结合稀缺数据预测婴儿脑连接 01 文献速递介绍 多模态影像下的婴儿脑连接演化预测&#xff1a;联邦学习与…

[特殊字符] 深入理解 Linux 内核进程管理:架构、核心函数与调度机制

Linux 内核作为一个多任务操作系统&#xff0c;其进程管理子系统是核心组成部分之一。无论是用户应用的运行、驱动行为的触发&#xff0c;还是系统调度决策&#xff0c;几乎所有操作都离不开进程的创建、调度与销毁。本文将从进程的概念出发&#xff0c;深入探讨 Linux 内核中进…

第16节 Node.js 文件系统

Node.js 提供一组类似 UNIX&#xff08;POSIX&#xff09;标准的文件操作API。 Node 导入文件系统模块(fs)语法如下所示&#xff1a; var fs require("fs") 异步和同步 Node.js 文件系统&#xff08;fs 模块&#xff09;模块中的方法均有异步和同步版本&#xff…

《探秘局域网广播:网络世界的 “大喇叭”》

揭开局域网广播的神秘面纱 在当今数字化时代,网络已成为人们生活和工作中不可或缺的一部分。从日常的网页浏览、社交媒体互动,到企业级的数据传输、云计算应用,网络通信无处不在。在这个庞大而复杂的网络世界里,数据如同信息流在各个节点之间穿梭,而局域网广播则是其中一种…

基于Ubuntu22.04安装SVN服务器之仓库迁移

基于Ubuntu22.04安装SVN服务器之仓库迁移 第一步: 停止svn服务器 第一步: 停止svn服务器 1&#xff09;建议迁移的时候先把SN服务器停掉&#xff0c;以免操作失败。 svnserve -d -r /usr/svn第二步&#xff1a;dump出svn代码库 1&#xff09;通过dump出旧的svn服务器上的代码…

Unity UI 性能优化终极指南 — Image篇

&#x1f3af; Unity UI 性能优化终极指南 — Image篇 &#x1f9e9; Image 是什么&#xff1f; Image 是UGUI中最常用的基本绘制组件支持显示 Sprite&#xff0c;可以用于背景、按钮图标、装饰等是UI性能瓶颈的头号来源之一&#xff0c;直接影响Draw Call和Overdraw &#x1…

「Java基本语法」代码格式与注释规范

Java代码的基本格式 Java代码的规范格式是编写和维护Java程序的基础&#xff0c;其中包括类定义、方法定义、代码缩进、大括号位置等。 1&#xff0e;核心规则 每个Java文件必须包含一个公共类&#xff08;public class&#xff09;&#xff0c;且Java源文件的文件名必须和这…

2025年AI编程工具推荐

目录 &#x1f451; **一、全能型AI开发环境&#xff08;IDE&#xff09;**&#x1f6e0;️ **二、AI代码助手与插件**&#x1f3af; **三、垂直领域工具**&#x1f1e8;&#x1f1f3; **四、国产工具精选**&#x1f52e; **五、创新前沿工具**⚖️ **选型建议** 2025年&#x…

【工具使用】STM32CubeMX-FreeRTOS操作系统-信号标志、互斥锁、信号量篇

一、概述 无论是新手还是大佬&#xff0c;基于STM32单片机的开发&#xff0c;使用STM32CubeMX都是可以极大提升开发效率的&#xff0c;并且其界面化的开发&#xff0c;也大大降低了新手对STM32单片机的开发门槛。     本文主要讲述STM32芯片FreeRTOS信号标志、互斥锁和信号…

ArrayList和LinkedList(深入源码加扩展)

ArrayList 和 LinkedList 是 Java 集合框架中两种常用的列表实现,它们在底层数据结构、性能特点和适用场景上有显著的区别。以下是它们的详细对比以及 ArrayList 的扩容机制。 1. ArrayList 和 LinkedList 的底层区别 (1) 底层数据结构 ArrayList: 基于动态数组(Dynamic Ar…

浅谈 React Suspense

React Suspense 是 React 中用于处理异步操作的功能。它可以让你"等待"某些操作&#xff0c;如数据获取或组件加载完成&#xff0c;然后再渲染组件。Suspense 的核心理念是让组件在准备好之前显示一个备用的 UI&#xff0c;例如加载指示器&#xff0c;从而提高用户体…

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…

Linux【4】------RK3568启动和引导顺序

引导顺序 RK3568 的启动流程如下&#xff1a; 加电后&#xff0c;芯片首先执行 BootROM 中的代码&#xff1b; BootROM 会尝试从配置好的外部设备&#xff08;如 NOR/NAND/eMMC/SD 卡&#xff09;加载启动程序&#xff1b; 如果这些设备都没有有效的启动代码&#xff0c;Bo…

Deepseek/cherry studio中的Latex公式复制到word中

需要将Deepseek/cherry studio中公式复制到word中&#xff0c;但是deepseek输出Latex公式&#xff0c;比如以下Latex代码段&#xff0c;需要通过Mathtype翻译才能在word中编辑。 $$\begin{aligned}H_1(k1) & H_1(k) \frac{1}{A_1} \left( Q_1 u_1(k) Q_{i1} - Q_2 u_2(k…

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…