android - 处理来自 Mediacodec 输出的帧并在 Android 上更新帧

标签 android image frame surface textureview

我正在做一个关于图像处理的项目。我实时接收原始 h264 视频流并使用 MediaCodec 对其进行解码。我已在 TextureView 或 SurfaceView 上成功显示解码视频。现在我想处理每一帧,使用 OpenCV4Android 对其进行处理并在屏幕上显示更新的视频帧。我知道 OpenCV 有一个示例项目演示了如何处理来自手机摄像头的视频帧,但我想知道如果我有另一个视频源该怎么做。

还有一些关于TextureView的问题:

  1. SurfaceTextureListener 的 onSurfaceTextureUpdated() 有什么作用?如果我在这个函数中调用 getBitmap(),那么这是否意味着我得到了视频的每一帧?那么 SurfaceTexture.onFrameAvailableListener 呢?

  2. 是否可以使用隐藏的 TextureView 作为中间体,提取其帧进行处理并将其渲染回另一个表面,例如 OpenGL ES 纹理以进行显示?

最佳答案

Grafika 中的各种示例使用相机作为输入的也可以处理来自视频流的输入。无论哪种方式,您都可以将视频帧发送到 Surface。

如果您想在软件中而不是在 GPU 上处理视频帧,事情就会变得更加困难。您要么必须在 Surface 上接收帧并将其复制到内存缓冲区,可能在此过程中执行 RGB 到 YUV 颜色转换,要么必须从 MediaCodec 获取 YUV 缓冲区输出。后者比较棘手,因为可能有几种不同的格式,包括高通专有的平铺格式。

关于TextureView:

  1. onSurfaceTextureUpdated() 在 TextureView 收到新帧时被调用。您可以使用 getBitmap() 获取视频的每一帧,但您需要调整视频播放的速度以匹配您的过滤器速度——如果您落后,TextureView 会丢帧。

  2. 您可以通过将其他 View 元素放在它上面来创建一个“隐藏的 TextureView”,但那样做很愚蠢。 TextureView 使用 SurfaceTexture将视频帧转换为 OpenGL ES 纹理,然后将它们渲染为绘制 View UI 的一部分。使用 glReadPixels() 检索位图数据。您可以直接使用这些元素。大鳞片ExtractMpegFramesTest证明了这一点。

关于android - 处理来自 Mediacodec 输出的帧并在 Android 上更新帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34986857/

相关文章:

java - 如何在 Java 中将图像从彩色转换为黑白(灰度)

python - 在 tkinter 中更改框架的大小,由类定义

security - 内容安全策略框架祖先

java - 运行没有main方法的Java程序?

java - 通过 TCP 连接到 3G 移动设备

java - 通过 Firebase 比较两个帐户的答案

android - TensorFlow 重新训练的 inception v3 模型在 Android 上崩溃

c++ - 是否可以使用 C++ 创建图像?

events - Backbone.js 查看 img onload

android - 如何从雅虎的天气API解析日期到Java Date