Question

When I decode a video to a surface I want to save the frames i want as bitmap/jpeg files. I don't want to draw on the screen and just want to save the content of the SurfaceTexture as an image file.

Was it helpful?

Solution

You have to render the texture.

If it were a normal texture, and you were using GLES 2 or later, you could attach it to an FBO and read directly from that. A SurfaceTexture is backed by an "external texture", and might be in a format that the GL driver doesn't support a full set of operations on, so you can't do that. You need to render it, and read the result.

FWIW, the way you go about saving the frame can have a significant performance impact. A full example demonstrating the use of MediaExtractor, MediaCodec, glReadPixels(), and PNG file creation is now up on bigflake (ExtractMpegFramesTest).

OTHER TIPS

I've been looking at this lately, on the Android platform. Summing up the various options and why they are/aren't applicable.

  1. glReadPixels() The only option Android Java coders currently really have. Said to be slow. Reads from a framebuffer, not a texture (so one must render the texture to an internal frame buffer first, unless one wants to record the screen itself). Okay. Got things to work.

  2. EGL_KHR_image_base() An extension that seems to be available on the native (NJK) level, but not in Java.

  3. glGetTexImage() Looked promising but not available in OpenGL 2.0 ES variant.

  4. Pixel Buffer Objects Probably the 'right' way to do things, but requires OpenGL 3.0 ES (i.e. selected Android 4.3+ devices).

I'm not saying this is adding any info that wouldn't be available elsewhere. But having so many seemingly similar options (that still wouldn't work) was confusing. I'm not an OpenGL expert so any mistakes above are gladly corrected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top