Search code examples
androidandroid-mediacodec

Android MediaCodec eglSwapBuffer blocking GPU in asynchronous mode


I have an video effect application where I am using OpenGL to draw to a frame buffer object, then drawing the resulting texture to the display, and then the MediaCodec input surface if the app is encoding.

I had initially written the encoder for API 18 in synchronous mode (based off of the big flake examples). I recently switched it to API 21 and asynchronous mode.

It records video fine, and I believe I have everything set up correctly. Howeverit seems the call to eglSwapBuffers causes the frame rate to drop significantly.

If I remove all other OpenGL calls it runs better, but what I'm rendering isn't that expensive (it can render fine multiple times per frame). Changing the encoder settings (i.e. from 640x360 @ 2Mbps to 1920x1080 @ 16Mbps) makes virtually no difference.

The only thing that makes it run faster is removing the call to eglSwapBuffers (which sends the buffer data to the encoder).

My understanding is that the output buffer does not block the call in asynchronous mode like it did before. Am I wrong about this? Is there a preferred way to call the renderer, or a method of rendering on a separate thread asynchronously?

Any help or ideas of where to start would be greatly appreciated, thanks!


Solution

  • Even in asynchronous mode, the output buffers still block the encoder - you need to process the output quickly and return the output buffers to the encoder after the asynchronous encoder output callback is called, otherwise you will end up blocking the input just as before.

    The only difference between synchronous and asynchronous mode is that you don't need to poll for these events, but you get callbacks instead.