我正在做一个关于图像处理的项目。我实时接收原始 h264 视频流并使用 MediaCodec 对其进行解码。我已在 TextureView 或 SurfaceView 上成功显示解码视频。现在我想处理每一帧,使用 OpenCV4Android 对其进行处理并在屏幕上显示更新的视频帧。我知道 OpenCV 有一个示例项目演示了如何处理来自手机摄像头的视频帧,但我想知道如果我有另一个视频源该怎么做。
还有一些关于TextureView的问题:
SurfaceTextureListener 的 onSurfaceTextureUpdated() 有什么作用?如果我在这个函数中调用 getBitmap(),那么这是否意味着我得到了视频的每一帧?那么 SurfaceTexture.onFrameAvailableListener 呢?
是否可以使用隐藏的 TextureView 作为中间体,提取其帧进行处理并将其渲染回另一个表面,例如 OpenGL ES 纹理以进行显示?
最佳答案
Grafika 中的各种示例使用相机作为输入的也可以处理来自视频流的输入。无论哪种方式,您都可以将视频帧发送到 Surface。
如果您想在软件中而不是在 GPU 上处理视频帧,事情就会变得更加困难。您要么必须在 Surface 上接收帧并将其复制到内存缓冲区,可能在此过程中执行 RGB 到 YUV 颜色转换,要么必须从 MediaCodec 获取 YUV 缓冲区输出。后者比较棘手,因为可能有几种不同的格式,包括高通专有的平铺格式。
关于TextureView:
onSurfaceTextureUpdated()
在 TextureView 收到新帧时被调用。您可以使用getBitmap()
获取视频的每一帧,但您需要调整视频播放的速度以匹配您的过滤器速度——如果您落后,TextureView 会丢帧。您可以通过将其他 View 元素放在它上面来创建一个“隐藏的 TextureView”,但那样做很愚蠢。 TextureView 使用 SurfaceTexture将视频帧转换为 OpenGL ES 纹理,然后将它们渲染为绘制 View UI 的一部分。使用
glReadPixels()
检索位图数据。您可以直接使用这些元素。大鳞片ExtractMpegFramesTest证明了这一点。
关于android - 处理来自 Mediacodec 输出的帧并在 Android 上更新帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34986857/