当前位置: 首页 > 知识库问答 >
问题:

如何直接从Android Surface访问EGL图像以用于MediaCodec视频解码器?

越胤
2023-03-14

我目前正在编写一个android应用程序,在那里我需要缓存视频帧,这样我可以很容易地来回几乎没有延迟。

现在,我让android解码视频帧,方法是为MediaCodeC对象的Configure调用提供一个表面,并调用ReleaseOutputBuffer,将呈现标志设置为true

我找到的访问解码表面数据的唯一方法(除了解码返回的bytebuffer(其格式似乎依赖于设备)之外)是在链接到表面的SurfaceTexture上调用UpdateTexImage,将其附加到GL_Texture_External_OES目标,并将其呈现到我自己创建的GL_Texture2D目标纹理以缓存它。

我想优化这个缓存过程,并且能够在不同的线程上解码帧。使用我当前的方法,这意味着我必须为视频解码器创建另一个EGL上下文,共享上下文等等。

我的问题是:有没有可能在不调用updateTexImage的情况下访问与Surface相关联的EGL-image或本机缓冲区数据?

这样,我就可以缓存egl映像(根据EGL_Android_Image_Native_Buffer,它不需要egl上下文)。这也将以YUV格式缓存,这将比我现在缓存的原始RGB纹理存储效率高得多。

共有1个答案

乔伯寅
2023-03-14

简短的回答:没有。

更长的答案:surface封装了一个缓冲区队列。(编辑:现在在这里对该系统进行了一些详细的解释。)当您调用updateTexImage()时,如果有一个新的数据帧可用,则会丢弃头部的缓冲区,队列中的下一个缓冲区将成为当前数据帧。调用updateTexImage()是查看连续帧所必需的;没有检查缓冲区的机制,而不是在头部。

SurfaceTexture包装GLConsumer的实例。这个消费者要求生产者(视频解码器)以一种可以用作“硬件纹理”的格式生成数据,即设备的GL实现可以理解的东西。它可能是也可能不是YUV。更重要的是,使用者并不要求缓冲区可供“软件”使用,这意味着您不能假设您可以直接访问数据--您需要使用GLES。(有关标志的完整列表,请参阅gralloc头。)

 类似资料:
  • 我正在开发一个通过RTP接收H264编码数据的应用程序,但我无法让Android的MediaCodec输出任何内容。我正在按照https://stackoverflow.com/a/7668578/10788248对RTP数据包进行解包 在编码帧被重新组装后,我将它们输入到出列的输入缓冲区中。 当我对输入缓冲区进行排队时,我不会得到任何错误,但是解码器的回调从来不会调用onOutputBuffer

  • 这行工作良好,但我想创建一个视频文件从图像在另一个文件夹。“我的文件夹”中的映像名称为: 我如何从不同的文件夹输入图像文件?示例: 我尝试了这个命令,但是只生成了第一个图像(img001.jpg)的视频。

  • 我已经使用Android MediaCodec库来转码视频文件(这里主要是更改分辨率示例代码) 我想做的另一件事是截断视频--只花15秒开始。逻辑是检查是否大于15秒,我将向解码器缓冲区写入。 但是我得到了一个异常

  • 在我的Android应用程序中,我想通过改变mp4视频的分辨率、比特率来压缩mp4视频。我不想使用FFmpeg(因为我不想使用NDK),所以我决定使用MediaCodec API。 以下是我的逻辑步骤: null 我的问题是:我不知道如何设置解码器的输出和编码器的输入之间的连接。我可以将视频解码到一个表面,或者从一个表面编码一个新的视频。但我不明白怎么把它们联系起来。 我阅读了以下链接:Andro

  • 我能够在MediaCodec和MediaMuxer的帮助下录制(编码)视频。接下来,我需要在MediaCodec和MediaMuxer的帮助下处理音频部分和带视频的mux音频。 我面临两个问题: > 如何将音频和视频数据传递给MediaMuxer(因为writeSampleData()方法一次只接受一种类型的数据)? 我提到了MediaMuxerTest,但它使用的是MediaExtractor。

  • 我正在尝试使用MediaCodec从视频中检索所有帧,用于图像处理,我正在尝试渲染视频并从outBuffers捕获帧,但我无法从接收到的字节启动位图实例。 我试着将它呈现为一个表面或无(null),因为我注意到当你呈现为null时,outBuffers将获得呈现帧的字节。 这是代码: 任何帮助都是非常有用的