因此,我需要定期生成CODEC_CONFIG和END_OF_STREAM数据,而无需重新创建输入Surface,因此必须调用mCamera.setPreviewTexture(…).假设MediaFormat没有变化,这可能吗?
(我正在调整fadden的CameraToMpegTest示例.我的完整代码是here)
不成功的尝试:
调用MediaCodec.signalEndOfInputStream(),耗尽MediaCodec,然后在块之间调用MediaCodec.flush()会在第二次调用MediaCodec.signalEndOfInputStream()时产生IllegalStateException.
调用MediaCodec.signalEndOfInputStream(),然后调用MediaCodec.stop();介质之间的MediaCodec.configure(…),MediaCodec.start()不再调用MediaCodec.createInputSurface()会产生以下错误:
09-30 13:12:49.889 17638-17719/x.xx.xxxx E/Surface﹕ queueBuffer: error queuing buffer to SurfaceTexture,-19 09-30 13:12:49.889 17638-17719/x.xx.xxxx E/IMGSRV﹕ :0: UnlockPostBuffer: Failed to queue buffer 0x592e1e70 09-30 13:12:49.889 17638-17719/x.xx.xxxx E/CameraToMpegTest﹕ Encoding loop exception! 09-30 13:12:49.889 17638-17719/x.xx.xxxx W/System.err﹕ java.lang.RuntimeException: eglSwapBuffers: EGL error: 0x300b 09-30 13:12:49.896 17638-17719/x.xx.xxxx W/System.err﹕ at x.xx.xxxx.ChunkedHWRecorder$CodecInputSurface.checkEglError(ChunkedHWRecorder.java:731) 09-30 13:12:49.896 17638-17719/x.xx.xxxx W/System.err﹕ at x.xx.xxxx.ChunkedHWRecorder$CodecInputSurface.swapBuffers(ChunkedHWRecorder.java:713) 09-30 13:12:49.896 17638-17719/x.xx.xxxx W/System.err﹕ at x.xx.xxxx.ChunkedHWRecorder.startRecording(ChunkedHWRecorder.java:164) 09-30 13:12:49.896 17638-17719/x.xx.xxxx W/System.err﹕ at x.xx.xxxx.HWRecorderActivity$CameraToMpegWrapper.run(HWRecorderActivity.java:76) 09-30 13:12:49.896 17638-17719/x.xx.xxxx W/System.err﹕ at java.lang.Thread.run(Thread.java:841)
解决方法
所以你必须看看代码.输入表面的寿命与OMXNodeInstance的寿命相关;它由GraphicBufferSource表示.一旦您发出EOS信号,GraphicBufferSource将忽略其他帧(见line 426).没有拆除GraphicBufferSource就无法重置EOS标志,但是当你这样做时它会断开Surface底层的缓冲队列.
因此,我认为您无法停止/重新启动MediaCodec并继续使用Surface.
但是……你不应该这样做. CameraToMpegTest将相机预览路由到SurfaceTexture,然后使用GLES将纹理渲染到编码器的输入表面上. SurfaceTexture与编码器分离,不需要更改.我认为需要改变的是CodecInputSurface,它使用MediaCodec中的Surface调用eglCreateWindowSurface()来告诉GLES在哪里绘制.如果你在那里添加一个新的“更新Surface”API(破坏旧的EGLSurface,创建新的EGLSurface,eglMakeCurrent),并在你启动一个新的MediaCodec时调用它,我认为它一切正常.
重要的是您只需更改EGLSurface. GLConsumer.cpp中的checkAndUpdateEglStateLocked()函数检查以确保EGLDisplay和EGLContext在设置后不会更改.您不能在CodecInputSurface中调用release()/ eglSetup(),因为它会更改EGLContext.您只想破坏并重新创建EGLSurface.