安卓:编码的相机预览帧总是横向的。如何旋转?

标签 android opengl-es android-camera live-streaming android-mediacodec

目标:无论设备的方向如何,都以正确的方向将 Android Camera 流式传输到 Wowza 服务器(即视频总是正面朝上)

我已经查看了此处关于相机方向的所有问题,到目前为止,它们似乎都只是更改渲染到屏幕的预览或在 MP4 文件中设置一个标志(不适合我的用例:流式传输).

我正在将摄像机帧流式传输到 Wowza 服务器,在 Wowza 服务器上,接收到的视频始终是横向的。如果手机始终保持同一方向,这很好,但我不能保证我的用户会这样做。根据我收集到的信息,当您直接从相机抓取帧并将它们提供给编码器时,您将获得设备相机的自然方向(在我的情况下可能是横向安装的)并且这完全不受预览的影响.这是有问题的,因为如果设备在流式传输期间旋转,图像也会随之旋转。

我曾尝试使用 openGL 矩阵在自定义 GLSurfaceView.Renderer 中转换预览,它所做的只是转换屏幕上的 View ,而不是发送到编码器的帧。

我已经阅读了 Grafika 的示例,但不确定在将帧馈送到编码器之前我需要在哪个过程中旋转帧。我使用 SurfaceTexture 作为相机预览,然后将其渲染到 GLSurfaceView(并使用我自己的自定义 GLSurfaceView.Renderer)。

如何将帧旋转到编码器?

理想情况下,我会在 openGL 中执行此操作。我曾考虑过在填充 mediacodec.dequeueInputBuffer 缓冲区之前旋转帧,但这将使用 CPU 完成,而且由于实时应用程序,我很谨慎。也许我忽略了一些关于预览的内容。我见过其他广播应用程序会在设备旋转时拆除 UI 上的预览层并重建它。

引用资料:

https://github.com/Kickflip/kickflip-android-sdk/

https://github.com/google/grafika

最佳答案

Grafika 中的相机 Activity 对每一帧渲染两次:一次用于显示,一次用于编码。您想做同样的事情,但要进行轮换(并对 MediaCodec/MediaRecorder 配置进行适当调整,即 720x1280 与 1280x720)。

例如,考虑 drawFrame() method in ContinuousCapture .它选择 SurfaceView 的 EGLSurface,绘制,然后切换到视频编码器的 EGLSurface 并调用相同的绘制方法。它甚至会调用 drawExtra() 来证明它可以。

在这两种情况下,您只是将 GLES 渲染到 EGLSurface 上,而 EGLSurface 从底层 Surface 获取其尺寸,它来自 SurfaceView 或 MediaCodec。如果您修改 FullFrameRect#drawFrame() 以采用矩阵参数,并传入一个旋转矩阵来代替它当前使用的单位矩阵,您应该会得到您想要的结果。

关于安卓:编码的相机预览帧总是横向的。如何旋转?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35051449/

相关文章:

Android:从相机获取图片 - 小心

android - CWAC-相机预览和图片不匹配

android - 验证对话框输入

Android Gridview 教程 - 有效的示例代码?

android - 如何使用 Libgdx 获取整个屏幕的位图?

Android Systemproperties.set 不起作用

java - 我可以使用 jfk 的 Map 1 键到多值吗?

c++ - 如何使用 OpenGL 交叉编译 UnixBench?

android - 关于 OpenGL ES 2 的问题

ios - 为 GPUImage 创建耗时的制服