在Android上使用带有FFMPEG和OpenCV的NDK进行视频处理非常慢

video processing on android using ndk with ffmpeg and opencv is very slow

本文关键字:NDK 视频 非常 处理 OpenCV Android FFMPEG      更新时间:2023-10-16

我正在使用ndk在Android上进行一些视频处理。

我现在正在做的是使用ffmpeg解码视频,抓住帧,将其转换为opencv mat,然后在上面叠加一些图像,然后将其转换回avframe,将其编码回视频。

但是它非常慢!以 50 fps 处理 480*480 的视频大约需要 15 秒。

我尝试使用 opengl es 来做到这一点,使用 glReadPixel 读取结果图像,但据我所知,glReadPixel 在某些设备上并不真正有效。所以我不得不放弃它。

据我了解,我在当前的工作流程中有一些非常昂贵的操作,

  1. 将AVFrame从yuv转换为bgr色彩空间,然后转换为opencv mat
  2. 将一个垫子覆盖在另一个垫子上
  3. 将opencv垫子隐藏为AVFrame,然后将帧从bgr转换为yuv空间,然后将其编码为视频。

那么,有没有办法改善我目前的工作流程?

我正在添加多线程功能,但只有具有多核杯的设备才能从中受益。

OpenGL ES不是为直接处理视频而设计的。 您需要使用一些 EGL 扩展并使用着色器代码将帧从 YUV 转换为 RGB 颜色空间。 这提供了最大的性能提升。 您也不得使用 glTexImage2D() 和 glReadPixels()。 此答案包含指向介绍如何将 OpenGL ES 用于视频的文章的链接。

您可以尝试 NDK r10 中的原生媒体 API。请参阅示例。

我认为你遇到了和我一样的问题。

目前,我认为解决方案之一是添加一个缓冲区,并在开始时处理一些帧,然后显示一段时间。我的线程继续将帧放到垫子上缓冲,而另一个线程可以使用 openCV 在缓冲区中处理垫子。使用缓冲区,您无需等待它处理整个视频。

让我知道它是否适合您,但我同意您的看法,只有具有多核的设备才能受益。

查看Android处理视频帧从位图到垫子有明显的延迟