我正在尝试通过 CameraPreview 数据生成短的连续 mp4 文件MediaCodec.createInputSurface()
。然而,重新创建MediaCodec
与其关联的 Surface 需要停止相机以允许再次调用mCamera.setPreviewTexture(...)
。这种延迟会导致大量的丢帧。
因此我需要生成CODEC_CONFIG
and END_OF_STREAM
定期数据,无需重新创建输入 Surface,因此必须调用mCamera.setPreviewTexture(...)
。这是否可能假设MediaFormat
不变吗?
(我正在改编法登的相机转MPEG测试例子。我的完整代码是here)
不成功的尝试:
Calling MediaCodec.signalEndOfInputStream()
,排空MediaCodec
,然后调用MediaCodec.flush()
块之间产生一个IllegalStateException
2 日致电MediaCodec.signalEndOfInputStream()
.
Calling MediaCodec.signalEndOfInputStream()
,排空MediaCodec
,然后调用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)
Solved谢谢法登。完整的解决方案源码是here.
The signalEndOfInputStream()
调用更新 MediaCodec 堆栈中各个层的状态。您可以从测试上方的注释中了解哪些操作是有效的媒体编解码器测试,但总的来说,MediaCodec 的行为根本不是为“不寻常”用途而定义的。
所以你必须看代码。输入表面的寿命与OMX节点实例;它的代表是图形缓冲区源。一旦您发出 EOS 信号,GraphicBufferSource 将忽略其他帧(请参阅line 426)。没有办法在不拆除 GraphicBufferSource 的情况下重置 EOS 标志,但是当您这样做时,它会断开 Surface 下的缓冲区队列。
因此,我认为您无法停止/重新启动 MediaCodec 并继续使用 Surface。
然而...你不应该需要这样做。 CameraToMpegTest 将相机预览路由到 SurfaceTexture,然后使用 GLES 将纹理渲染到编码器的输入表面上。 SurfaceTexture 与编码器分离,不需要更改。我认为需要改变的是CodecInputSurface,它调用eglCreateWindowSurface()
使用 MediaCodec 中的 Surface 来告诉 GLES 在哪里绘制。如果您在那里添加一个新的“更新 Surface”API(销毁旧的 EGLSurface,创建新的 EGLSurface,eglMakeCurrent),并在每次启动新的 MediaCodec 时调用它,我think一切都会顺利的。
更新以解决评论:
重要的是您只更改EGLSurface
. The checkAndUpdateEglStateLocked()
函数于GLConsumer.cpp检查以确保EGLDisplay
and EGLContext
一旦设置就不要更改。你不能打电话release()
/eglSetup()
在 CodecInputSurface 中,因为它改变了EGLContext
。你只想摧毁并重建EGLSurface
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)