I\'m trying to produce short sequential mp4 files from CameraPreview data via MediaCodec.createInputSurface()
. However, recreating the MediaCodec
a
The signalEndOfInputStream()
call updates the state of various layers in the MediaCodec stack. You can get some sense of what operations are valid from the comments above the tests in MediaCodecTest, but by and large the behavior of MediaCodec is simply not defined for "unusual" uses.
So you have to look at the code. The lifetime of the input surface is tied to that of the OMXNodeInstance; it's represented by GraphicBufferSource. Once you signal EOS, the GraphicBufferSource will ignore additional frames (see line 426). There's no way to reset the EOS flag without tearing down the GraphicBufferSource, but when you do that it disconnects the buffer queue that underlies the Surface.
So I don't think you're going to be able to stop/restart the MediaCodec and continue to use the Surface.
However... you shouldn't need to. CameraToMpegTest routes the camera preview to a SurfaceTexture, and then renders the texture onto the encoder's input surface with GLES. The SurfaceTexture is decoupled from the encoder and shouldn't need to change. I think what needs to change is CodecInputSurface, which calls eglCreateWindowSurface()
with the Surface from the MediaCodec to tell GLES where to draw. If you add a new "update Surface" API there (destroy old EGLSurface, create new EGLSurface, eglMakeCurrent), and call it whenever you spin up a new MediaCodec, I think it'll all just work.
Update to address comments:
It's important that you only change the EGLSurface
. The checkAndUpdateEglStateLocked()
function in GLConsumer.cpp checks to make sure the EGLDisplay
and EGLContext
don't change once they've been set. You can't call release()
/eglSetup()
in CodecInputSurface because it changes the EGLContext
. You just want to destroy and recreate the EGLSurface
.