Android:编码相机预览帧始终处于横向状态。如何旋转?

时间:2016-01-28 01:41:53

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

目标:无论设备的方向如何(即视频始终正面朝上),Android摄像头都以正确的方向流式传输到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

1 个答案:

答案 0 :(得分:1)

Grafika中的相机活动每帧渲染两次:一次用于显示,一次用于编码。你想做同样的事情,但抛出一个旋转(并对MediaCodec / MediaRecorder配置进行适当的调整,即720x1280与1280x720)。

例如,考虑drawFrame() method in ContinuousCapture。它选择SurfaceView的EGLSurface,绘制,然后切换到视频编码器的EGLSurface并调用相同的绘制方法。它甚至会打电话给drawExtra()只是为了表明它可以。

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