在Android上使用CPU到GPU的最低开销相机

我的应用程序需要在cpu上对实时相机帧进行一些处理,然后再在GPU上进行渲染.还有一些其他的东西在GPU上呈现,这取决于cpu处理的结果;因此,保持所有内容同步非常重要,这样我们就不会在GPU上渲染帧本身,直到该帧的cpu处理结果也可用.

问题是在Android上这个最低的开销方法是什么?

在我的情况下cpu处理只需要一个灰度图像,因此Y平面打包的YUV格式是理想的(并且往往与相机设备的原生格式很好地匹配). NV12,NV21或全平面YUV都可以提供理想的低开销灰度访问,因此在cpu方面是首选.

在原始相机API中,setPreviewCallbackWithBuffer()是将数据输入cpu进行处理的唯一合理方法.这使得Y平面分离,因此非常适合cpu处理.将此框架提供给OpenGL以便以低开销方式呈现是更具挑战性的方面.最后,我编写了一个NEON颜色转换例程来输出RGB565,并且只需使用glTexSubImage2d就可以在GPU上使用它.这是在Nexus 1时间帧中首次实现的,即使是320×240 glTexSubImage2d调用也需要50ms的cpu时间(我猜想,尝试进行纹理调配的不良驱动程序 – 后来在系统更新中显着改善).

回到那一天,我研究了像eglImage扩展这样的东西,但它们似乎不适用于用户应用程序,也没有足够的文档记录.我对内部android GraphicsBuffer类进行了一些研究,但理想情况下希望保留在受支持的公共API的世界中.

android.hardware.camera2 API承诺能够将ImageReader和SurfaceTexture连接到捕获会话.不幸的是我无法看到任何确保正确的顺序管道的方法 – 在cpu处理完毕之前暂停调用updateTexImage()很容易,但如果在处理过程中另一帧已经到达,那么updateTexImage()将直接跳到最新帧.在多个输出中似乎也会有每个队列中帧的独立副本,理想情况下我想避免这些副本.

理想情况下,这就是我想要的:

>相机驱动程序使用最新帧填充一些内存
> cpu获取指向内存中数据的指针,可以读取Y数据而无需复制
>当帧准备就绪时,cpu处理数据并在我的代码中设置一个标志
>开始渲染帧时,检查新帧是否准备就绪
>调用一些API来绑定与GL纹理相同的内存
>准备好较新的帧时,将保留前一帧的缓冲区释放回池中

我无法看到在Android上使用公共API完全实现零拷贝样式的方法,但是最接近它的是什么?

我试过的一个疯狂的事情似乎有用,但没有记录:ANativeWindow NDK API可以接受数据NV12格式,即使适当的格式常量不是公共标题中的那个.这允许通过memcpy()填充SurfaceTxture的NV12数据,以避免cpu端颜色转换以及glTexImage2d中驱动程序端发生的任何混乱.这仍然是数据的额外副本,虽然感觉它应该是不必要的,并且再次因为它没有文档可能不适用于所有设备.支持的顺序零拷贝相机 – > ImageReader – > SurfaceTexture或同等产品将是完美的.

解决方法

处理视频的最有效方法是完全避免cpu,但听起来这不是你的选择.公共API通常适用于在硬件中执行所有操作,因为这是框架本身需要的内容,尽管RenderScript有一些路径. (我假设您已经看过使用片段着色器的 Grafika filter demo.)

访问cpu上的数据用于表示慢速Camera API或使用GraphicBuffer和相对模糊的EGL功能(例如this question). ImageReader的目的是提供对来自相机的YUV数据的零拷贝访问.

你无法真正序列化相机 – > ImageReader – > SurfaceTexture作为ImageReader没有“转发缓冲区”API.这是不幸的,因为这将使这个微不足道.您可以尝试复制SurfaceTexture所做的事情,使用EGL函数将缓冲区打包为外部纹理,但是再次进入非公共GraphicBuffer-land,我担心缓冲区的所有权/生命周期问题.

我不确定并行路径如何帮助你(Camera2 – > ImageReader,Camera2 – > SurfaceTexture),因为发送到SurfaceTexture的内容不会有你的修改. FWIW,它不涉及额外的副本 – 在Lollipop或其周围,BufferQueue已更新,允许单个缓冲区通过多个队列.

完全有可能有一些我尚未见过的新奇特API,但据我所知,你的ANativeWindow方法可能就是胜利者.我怀疑使用其中一种相机格式(YV12或NV21)比NV12更好,但我不确定.

如果您的处理时间过长,您将丢帧,但除非您的处理不均匀(某些帧比其他帧花费的时间长),否则无论如何都要丢帧.再次进入非公共API的领域,您可以将SurfaceTexture切换到“同步”模式,但如果缓冲区填满,您仍然会丢帧.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方法有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android...
这篇文章主要介绍“Android岛屿数量算法怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android岛屿数量算...
本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Andro...
本文小编为大家详细介绍“Android数据压缩的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android数据压缩的方法是什么”文章能帮助大家解决疑惑...
这篇“Android怎么使用Intent传大数据”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅...
本文小编为大家详细介绍“Android事件冲突怎么解决悬浮窗拖拽问题”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android事件冲突怎么解决悬浮窗拖拽问题”文...
这篇文章主要介绍了Android拼接如何实现动态对象的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android拼接如何实现动态对象文...
今天小编给大家分享一下Android全面屏适配怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下...
本篇内容介绍了“Android怎么开发Input系统触摸事件分发”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何...
今天小编给大家分享一下AndroidRoom怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下...
本文小编为大家详细介绍“AndroidRoom使用方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“AndroidRoom使用方法有哪些”文章能帮助大家...
这篇文章主要介绍“Android中的OpenGL怎么配置使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android中的Open...
这篇文章主要介绍了Android如何自定义自动识别涂鸦工具类的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android如何自定义自动...
今天小编给大家分享一下Android如何自定义有限制区域的图例角度自识别涂鸦工具类的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以...
今天小编给大家分享一下ReactNative错误采集原理在Android中如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章...
这篇文章主要讲解了“Android崩溃日志收集和保存代码分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“A...
这篇“Android面向单Activity开发实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大...
本篇内容介绍了“Android应用启动白屏处理的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何...