我目前正在编写一款安卓应用程序,需要缓存视频帧以便能够在很短的时间内来回切换。
现在,我让安卓通过向 MediaCodec
对象的 Configure 调用提供一个 Surface,并将 render 标志设置为 true ,从而解码视频帧,然后调用 releaseOutputBuffer
。
我发现除了对返回的字节缓冲区进行解码(其格式似乎是与设备相关的),我还可以通过将其链接到 SurfaceTexture 并将其附加到 GL_TEXTURE_EXTERNAL_OES 目标上,再将其渲染到我自己创建的 GL_TEXTURE2D 目标纹理中,从而访问解码表面数据。
我想优化这个缓存过程并能够在不同的线程上解码帧。使用当前的方法,这意味着我必须为视频解码器创建另一个 EGL 上下文,共享上下文等。
我的问题是:是否可以在不调用 updateTexImage
的情况下访问与 Surface 关联的 EGL 图像或本机缓冲区数据?
这样我就可以缓存 EGL 图像(根据 EGL_ANDROID_image_native_buffer
,这不需要 EGL 上下文)。这也会以 YUV 格式进行缓存,比我现在正在缓存的原始 RGB 纹理更省存储空间。
/system/lib/libI420colorconvert.so
,由视频编辑器库(https://android.googlesource.com/platform/frameworks/av/+/jb-mr2-release/libvideoeditor/lvpp/I420ColorConverter.cpp)使用。框架中的大多数YUV内容都用于相机,当涉及到缓冲区格式时,相机比视频解码器更好行为。 - faddenByteBuffer
中,并不意味着存在匹配的gralloc缓冲区格式。也许它进行了直接的memcpy,也许它调整了对齐或步幅。填充缓冲区可能在某个设备和软件版本上工作,但最多也只能算是脆弱的。这可能会引起您的兴趣:http://snorp.net/2011/12/16/android-direct-texture.html(同样,不使用公共API)。如果您想深入研究,可以尝试替换`GLConsumer`。 - fadden