Android 如何在计算着色器中访问ARCore视频帧

Android 如何在计算着色器中访问ARCore视频帧,android,opengl-es,gpgpu,arcore,Android,Opengl Es,Gpgpu,Arcore,我正在实现一项技术,该技术使用ARCore(目前为1.16.0)以及OpenGL ES 3.2计算着色器中的自定义图像处理 有两种方法可以从计算着色器访问视频帧,这两种方法都有缺点: 使用Session.setCameraTextureName()这似乎是一个自然的选择,因为我让ARCore为我将数据获取到OpenGL纹理中。然而,它在RGBA中,这可能意味着在我获得数据之前,会发生不必要的有损转换。此外,由于它是GL\u纹理\u外部纹理,因此我无法直接访问像素(使用imageLoad()),必

我正在实现一项技术,该技术使用ARCore(目前为1.16.0)以及OpenGL ES 3.2计算着色器中的自定义图像处理

有两种方法可以从计算着色器访问视频帧,这两种方法都有缺点:

  • 使用
    Session.setCameraTextureName()
    这似乎是一个自然的选择,因为我让ARCore为我将数据获取到OpenGL纹理中。然而,它在RGBA中,这可能意味着在我获得数据之前,会发生不必要的有损转换。此外,由于它是GL\u纹理\u外部纹理,因此我无法直接访问像素(使用
    imageLoad()
    ),必须通过采样器。此外,在我测试过的设备上,每个CameraConfig的纹理分辨率都是1080,这对于我的计算算法来说太多了,需要缩小尺寸
  • 使用
    Frame.acquireCameraImage()
    这里的优点是我以YCbCr获取图像,可能跳过了有损转换步骤,并且我可以选择适当的分辨率。缺点是我需要进行两次
    glTexSubImage2D()
    调用
  • (有趣的是,在三星S8和A3上,所有配置的纹理分辨率均为1920x1080,图像分辨率分别为640x480、1280x720和1920x1080。)

    看起来ARCore+compute有点灰色。欢迎任何关于哪一个更好的选择的建议,但请引用来源:

    编辑:根据反馈添加一些具体问题:

    • 从主内存中的YCbCr图像到RGBA OpenGL ES纹理,通常在后台使用什么路径
    • 此路径是否比
      glTexSubImage2D()
    • 无论我是否设置会话的纹理名称,我是否为此支付计算成本
    • 在转换链中,主存储器YCbCr图像是否始终位于RGBA纹理之前
    从主内存中的YCbCr图像到RGBA OpenGL ES纹理,通常在后台使用什么路径

    使用
    GL\u TEXTURE\u EXTERNAL\u OES
    基本上是零拷贝访问。GPU可以直接访问摄像头/视频块写入的YUV图像。颜色转换是动态发生的;这样做可能会有一些GPU开销——这取决于硬件——但内存中没有创建第二个RGB拷贝。多少开销-现代移动GPU可以非常有效地做到这一点,但旧的可能有两个平面YUV 2倍的纹理成本

    此路径是否比glTexSubImage2D()快

    一般来说,是的,这就是直接访问路径存在的原因。然而,在一种情况下,而不是在另一种情况下,您必须注入额外的下采样,这一事实并不意味着这是一个明显的“正确答案”

    还要注意,成本是不同的。直接YUV-RGB转换会产生GPU成本。纹理上载会产生CPU成本。根据设备的相对CPU/GPU性能,以及应用程序的其他部分正在使用的资源,其中一个可能会比另一个更轻松

    无论我是否设置会话的纹理名称,我是否为此支付计算成本

    否。当访问纹理时,YUV到RGB的转换在采样器中完成

    在转换链中,主存储器YCbCr图像是否始终位于RGBA纹理之前

    RGBA纹理完全是虚拟的-它不存在于内存中

    所有配置的纹理分辨率为1920x1080,图像分辨率为640x480、1280x720和1920x1080


    请注意,相机HAL层中有许多特定于供应商的“魔力”。很难说低分辨率图像是如何产生的;它们可以由相机直接以较低的分辨率生成,也可以由供应商HAL单独进行缩小(如果相机不能直接进行,通常使用硬件定标器)。

    没有“正确答案”。正如你自己所说,这两种方法都有缺点。不清楚您对“更好”的定义是什么-颜色精度、性能、内存带宽、开发时间?只有真正的答案-两个都试试,并根据您的用例衡量“更好”。@solidpixel,好的,我需要澄清我所说的“更好”是什么意思。然而,我不同意测量是唯一能找到答案的现实选择。在我瞄准的数千台安卓设备的一个重要子集上,以接近最佳的方式实现这两条路径是一项巨大的任务。从视频捕获系统设计的一些基本事实开始是很有意义的,例如,ARCore的视频纹理是否通常通过比glTexSubImage2D更快的路径上传,以及主存储器YCbCr图像是否总是在转换链中位于RGBA纹理之前。感谢@solidpixel,这非常有帮助。一个后续问题:在许多可用的ARCore camera配置中,(虚拟)纹理分辨率高于(主内存)图像分辨率。由于您暗示低分辨率主存储器图像直接来自相机HAL,这是否意味着虚拟GLES纹理是该图像的放大版本,还是来自相机HAL的图像有多个版本?不确定;我从来没有使用过这个的AR部分,我只知道这个部分的图形API部分。ARCore文档讨论了“CPU分辨率”和“GPU分辨率”。听起来GPU的分辨率总是1080p,而且它必须仍然在主内存的某个地方,GPU才能访问它。。。