2015-09-27 119 views
3

我设法写了一个录像演示,我的实现与Grafika的ContinuousCaptureActivity相同。 在ContinuousCaptureActivity.java中,作者在UI线程中运行的SurfaceCreated中创建egl对象,并在UI线程中调用drawFrame。他在drawFrame中做了2件事情,画出画面并将数据推送给编码器。使用MediaCodec录制720p视频,但编码视频的fps太低

在这里看到的代码:ContinuousCaptureActivity

因为我设置编码视频尺寸为1280 * 720大,摄像头预览不顺畅和目标视频的FPS低。 我打算创建一个新线程来完成编码工作,但我不知道如何处理opengl的多线程。谁可以提供一些建议?

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

回答

2

首先,1280x720不应该是主流设备的问题。一些超便宜的低端设备可能会很困难,但如果硬件无法处理1280x720x30fps,则无法做任何事情。

我在720p的看到了低FPS最常见的原因是未能以合理的FPS值(使用setPreviewFpsRange()getSupportedPreviewFpsRange()的值)配置摄像头,并没有打电话给setRecordingHint(true)(或相当于Camera2)。后者可以将您从15​​fps提升到30fps,但可能会影响预览的纵横比。

视频编码在独立的进程中执行,称为mediaserver,它管理与视频编码器硬件的所有交互。游戏中已经有多个线程,因此添加另一个线程无济于事。

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

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

+0

setRecordHint(true)在某些设备上导致异常,所以我放弃它。我终于使用了480 * 848的视频尺寸,视频的颜色也不错。 – dragonfly

+0

请看看这个: http://stackoverflow.com/questions/32823341/use-opengl-es-to-render-video-to-surfaceview-but-concerned-about-more-overhead – dragonfly

+0

嗨,请看看这个,我有更新的问题: http://stackoverflow.com/questions/30668846/record-video-with-mediacodec-and-mediamuxer-but-the-bitrate-and-framerate-are-i – dragonfly

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);来解决它。