3

I managed to write a video recording demo, my implementation is the same as ContinuousCaptureActivity of Grafika. In ContinuousCaptureActivity.java, The author create egl object in SurfaceCreated which run in UI thread and call drawFrame also in UI thread. He did 2 things in drawFrame, draw frame to screen and push data to encoder.

See the code here: ContinuousCaptureActivity

Because I set the encoding video size to 1280*720 which is large, the camera preview is not smooth and fps of target video is low. I plan to create a new thread to do the encoding work but I do not know how to handle with multithread of opengl es. Who can give some advice?

Add: I found that drawFrame of Texture2dProgram use GLES20.glDrawArrays, Will GLES20.glDrawElements get a better performance?

genpfault
  • 47,669
  • 9
  • 68
  • 119
dragonfly
  • 1,055
  • 12
  • 34

2 Answers2

2

First, 1280x720 shouldn't be an issue for mainstream devices. Some super-cheap low-end devices might struggle, but there isn't really anything you can do if the hardware simply can't handle 1280x720x30fps.

The most common reasons I've seen for low FPS at 720p are failure to configure the Camera with a reasonable fps value (using setPreviewFpsRange() with a value from getSupportedPreviewFpsRange()), and failing to call setRecordingHint(true) (or the Camera2 equivalent). The latter can take you from 15fps to 30fps, but may affect the aspect ratio of the preview.

The video encoding is performed in a separate process, called mediaserver, which manages all interaction with the video encoder hardware. There are already multiple threads in play, so adding another won't help.

The GLES code is drawing two textured triangles. Using a different API won't change the difference.

If you think there is a performance bottleneck, you need to use tools like systrace to narrow it down.

fadden
  • 48,613
  • 5
  • 104
  • 152
  • setRecordHint(true) causes exception on some devices, so I give up it. I finally use 480*848 video size and the color of video is also OK. – dragonfly Sep 28 '15 at 02:39
  • please have a look at this: http://stackoverflow.com/questions/32823341/use-opengl-es-to-render-video-to-surfaceview-but-concerned-about-more-overhead – dragonfly Sep 28 '15 at 12:51
  • Hi, please have a look at this, I have update the question: http://stackoverflow.com/questions/30668846/record-video-with-mediacodec-and-mediamuxer-but-the-bitrate-and-framerate-are-i – dragonfly Sep 30 '15 at 16:02
  • @fadden what is the camera2 equivalent of setRecordingHint? – paleozogt Feb 29 '16 at 21:44
0

I finally found a way to make drawing frame to screen faster which eventually save the time of processing each frame.

The detail is as follows:

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

add these code to https://github.com/google/grafika/blob/master/src/com/android/grafika/ContinuousCaptureActivity.java#L352

then use GLES20.glViewport(0, 0, mPreviewWidth, mPreviewHeight); to replace https://github.com/google/grafika/blob/master/src/com/android/grafika/ContinuousCaptureActivity.java#L436

This modification will reduce data size of frame to draw a lot. But it will make preview image not so smooth if we use TextureView, and we can use setScaleX(1.00001f); setScaleY(1.00001f); to resolve it.

dragonfly
  • 1,055
  • 12
  • 34