【问题标题】:How to understand the underneath of setDisplay/setSurface/setPrewviewDisplay/setPreviewTexture for Android如何理解 setDisplay/setSurface/setPrewviewDisplay/setPreviewTexture for Android 的底层
【发布时间】:2023-03-09 18:40:01
【问题描述】:

从 Android api level 1 开始,我们可以通过 setDisplay 或 setPrewviewDisplay 将 MediaPlayer 或 Camera 附加到 Surface,然后图像数据可以传输到 gpu 并更快地处理。

引入SurfaceTexture后,我们可以用目标GL_TEXTURE_EXTERNAL_OES创建自己的纹理,并将MediaPlayer或Camera附加到opengl es。

这些都是众所周知的,但我要说的是下面是关于Android图形架构的。(Android Graphics architecture)

产生的数据在 CPU 端,因此必须以非常快的方式传输到 GPU。

为什么每台 Android 设备的数据传输速度都如此之快,以及如何将其置于底层?

或者这是与Android无关的硬件问题?

【问题讨论】:

    标签: android opengl-es data-transfer android-graphics


    【解决方案1】:

    数据不是在 CPU 端产生的。相机和硬件视频编解码器将它们的数据存储在由内核 gralloc 机制分配的缓冲区中(通过非公共 GraphicBuffer 从本机代码引用)。 Surfaces 通过 BufferQueue 对象进行通信,这些对象通过句柄传递帧,而不复制数据本身。

    由 OEM 负责确保相机、视频编解码器和 GPU 可以使用通用格式。视频编解码器输出的 YUV 必须是 GLES 实现可以作为外部纹理处理的东西。这也是为什么在将 GLES 渲染发送到 MediaCodec 时需要 EGL_RECORDABLE_ANDROID... 需要让 EGL 实现知道它所渲染的帧必须能够被视频编解码器识别。

    【讨论】:

    • 一些第三方播放器如ijkplayer(github.com/Bilibili/ijkplayer)也有api“setDisplay”(github.com/Bilibili/ijkplayer/blob/master/android/ijkplayer/…)。 Ijkplayer 使用软件解码器,我们也可以通过 api setDisplay 将其连接到 gles。怎么理解?
    • 我不熟悉播放器,但您可以使用 GLES 或 Canvas 在 Surface 上绘图。 glTexImage2D() 相当快(Grafika 包含一个简单的基准测试)。
    • 你说图像数据存储在内核gralloc机制分配的缓冲区中,但是cpu的缓冲区,GPU或RAM在哪里?
    • 我用过的Android设备都有UMA,所以GPU和CPU RAM没有区别。在某些情况下,例如 DRM 视频的播放,除了显示处理器和视频解码器(甚至内核都无法触及它们)之外的任何东西都无法访问的内存部分用于保存解码的缓冲区。如果没有 UMA,事情可能会变得更加昂贵,具体取决于架构。该软件架构旨在处理非 UMA 设备,这也是您必须将纹理“上传”到 GLES 的部分原因,并且在完成后无法通过指针戳它们。
    • 什么是UMA,你是说DMA吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 2017-02-05
    • 2013-05-21
    • 1970-01-01
    相关资源
    最近更新 更多