使用MediaCodec录制720p视频,但编码视频的fps太低

时间:2015-09-27 05:38:13

标签: android multithreading opengl-es frame-rate mediacodec

我设法编写了一个视频录制演示,我的实现与Grafika的ContinuousCaptureActivity相同。    在ContinuousCaptureActivity.java中,作者在SurfaceCreated中创建了egl对象,它在UI线程中运行,并在UI线程中调用drawFrame。他在drawFrame中做了两件事,画框到画面并将数据推送到编码器。

请参阅此处的代码:ContinuousCaptureActivity

因为我将编码视频大小设置为1280 * 720,因此相机预览不平滑且目标视频的fps较低。    我计划创建一个新的线程来进行编码工作,但我不知道如何处理多线程的opengl es。谁可以提供一些建议?

添加:我发现Texture2dProgram的drawFrame使用GLES20.glDrawArrays,GLES20.glDrawElements会获得更好的性能吗?

2 个答案:

答案 0 :(得分:2)

首先,1280x720不应成为主流设备的问题。一些超级便宜的低端设备可能会遇到困难,但如果硬件无法处理1280x720x30fps,那么你真的无能为力。

我在720p时看到低FPS的最常见原因是无法使用合理的fps值配置相机(使用setPreviewFpsRange()使用getSupportedPreviewFpsRange()的值),并且未能致电setRecordingHint(true)(或相当于Camera2)。后者可以从15fps到30fps,但可能会影响预览的宽高比。

视频编码在一个名为mediaserver的独立过程中执行,该过程管理与视频编码器硬件的所有交互。已经存在多个线程,因此添加另一个线程不会有帮助。

GLES代码绘制了两个带纹理的三角形。使用不同的API不会改变差异。

如果您认为存在性能瓶颈,则需要使用systrace等工具来缩小范围。

答案 1 :(得分:0)

我终于找到了一种方法来使绘图框更快地进行屏幕显示,最终节省了处理每一帧的时间。

详情如下:

        mPreviewWidth = mCamera.getParameters().getPreviewSize().width;
        mPreviewHeight = mCamera.getParameters().getPreviewSize().height;
        holder.setFixedSize(mPreviewWidth, mPreviewHeight);

将这些代码添加到https://github.com/google/grafika/blob/master/src/com/android/grafika/ContinuousCaptureActivity.java#L352

然后使用GLES20.glViewport(0, 0, mPreviewWidth, mPreviewHeight);替换https://github.com/google/grafika/blob/master/src/com/android/grafika/ContinuousCaptureActivity.java#L436

这种修改会减少画框的数据大小。 但如果我们使用TextureView,它会使预览图像不那么平滑,我们可以使用setScaleX(1.00001f); setScaleY(1.00001f);来解决它。