android - Android中显示定制视频的高效路径

标签 android opengl-es android-camera

在 Android 中,我需要一种有效的方法来修改相机流,然后再将其显示在屏幕上。 This post讨论了几种这样做的方法,我能够实现第一种:

  1. 从onPreviewFrame获取帧缓冲区
  2. 将帧转换为 YUV
  3. 修改框架
  4. 将修改后的帧转换为 jpeg
  5. 将框架显示到放置在 SurfaceView 上的 ImageView,用于 预览

这确实有效,但将我通过常规相机预览获得的 30 fps 降低到了 5 fps 左右。从不同图像空间来回转换帧也很耗电,这是我不希望的。

是否有关于如何直接访问原始帧而不必经过这么多转换的示例?使用 OpenGL 是执行此操作的正确方法吗?这一定是一件很常见的事情,但我找不到好的例子。

注意:为了向后兼容,我宁愿避免使用 Camera2 API。

最佳答案

基于 CPU 的管道的最有效形式如下所示:

  1. 从 Surface 上的相机接收帧,而不是以 byte[] 形式接收帧。使用Camera2,您可以将帧直接发送到ImageReader ;这将使您的 CPU 能够访问来自相机的原始 YUV 数据,而无需复制或转换它。 (我不确定如何使用旧的 Camera API 来配置它,因为它需要 SurfaceTexture 或 SurfaceHolder,而 ImageReader 不提供这些。您可以通过 SurfaceTexture 运行帧并从 获取 RGB 值glReadPixels(),但我不知道这是否会给你带来任何东西。)
  2. 对 YUV 数据进行修改。
  3. 将 YUV 数据转换为 RGB。
  4. 将 RGB 数据转换为位图或 GLES 纹理。 glTexImage2D会更高效,但 OpenGL ES 的学习曲线很陡峭。如果您决定走这条路,您需要的大部分内容都在 Grafika 中(例如 texture upload benchmark )。
  5. 渲染图像。根据您在步骤 #4 中所做的操作,您可以通过 custom View 上的 Canvas 渲染位图。 ,或者在 SurfaceView 或 TextureView 上使用 GLES 渲染纹理。

我认为最显着的加速是消除 JPEG 压缩和解压缩,所以您应该从这里开始。将帧编辑器的输出转换为位图,然后将其绘制在 TextureView 或自定义 View 的 Canvas 上,而不是转换为 JPEG 并使用 ImageView。如果这不能让您获得想要的加速,请找出导致您速度减慢的原因,并在管道的该部分上进行工作。

关于android - Android中显示定制视频的高效路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31252840/

相关文章:

android - ACTION_IMAGE_CAPTURE Intent : Avoid Activity being destroyed/process being killed

android - 位图重复+圆角

iphone - 无法在以编程方式创建的窗口中单击 iAd - bannerViewActionShouldBegin 未调用?

android - 在 Android 上使用像素着色器时 FPS 大幅下降

android - 如何从 sdcard 中选择一个图像文件,然后如何将它发送到服务器?

android - WindowManager$BadTokenException 无法添加窗口

android - 崩溃时进入Android应用

java - 使用 CountDownTimer 方法暂停循环,直到方法完成

opengl-es - 如何使用 glsl 绘制一个移动的球并留下轨迹?

android - 如何添加像 Retrica 这样的相机预览实时滤镜?