我设法编写了一个视频录制演示,我的实现与Grafika的ContinuousCaptureActivity相同。 在ContinuousCaptureActivity.java中,作者在SurfaceCreated中创建了egl对象,它在UI线程中运行,并在UI线程中调用drawFrame。他在drawFrame中做了两件事,画框到画面并将数据推送到编码器。
请参阅此处的代码:ContinuousCaptureActivity
因为我将编码视频大小设置为1280 * 720,因此相机预览不平滑且目标视频的fps较低。 我计划创建一个新的线程来进行编码工作,但我不知道如何处理多线程的opengl es。谁可以提供一些建议?
添加:我发现Texture2dProgram的drawFrame使用GLES20.glDrawArrays,GLES20.glDrawElements会获得更好的性能吗?
答案 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);
然后使用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);
来解决它。