
配景形貌:
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_x4
- uint8x16_t data0 = vld1q_u8(src8); //从src8加载16个8位数据到data0
- uint8x16_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++;
- }
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |