gpt4 book ai didi

android - 带表面输入的 MediaCodec : Producing chunked output

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:43:54 24 4
gpt4 key购买 nike

我正在尝试通过 MediaCodec.createInputSurface() 从 CameraPreview 数据生成短序列 mp4 文件。但是,重新创建 MediaCodec 及其关联的 Surface 需要停止 Camera 以允许再次调用 mCamera.setPreviewTexture(...)。这种延迟会导致 Not Acceptable 丢帧量。

因此,我需要定期生成 CODEC_CONFIGEND_OF_STREAM 数据,而无需重新创建输入表面,因此必须调用 mCamera.setPreviewTexture(...) 。这是否可能假设 MediaFormat 未更改?

(我正在改编 fadden 的 CameraToMpegTest 示例。我的完整代码是 here )

不成功的尝试:

调用 MediaCodec.signalEndOfInputStream(),耗尽 MediaCodec,然后在 block 之间调用 MediaCodec.flush() 生成一个 IllegalStateException 在第二次调用 MediaCodec.signalEndOfInputStream() 时。

调用MediaCodec.signalEndOfInputStream(),耗尽MediaCodec,然后调用MediaCodec.stop(); MediaCodec.configure(...)、MediaCodec.start() 在 block 之间没有再次调用 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)

已解决 感谢 fadden。完整的解决方案来源是here .

最佳答案

signalEndOfInputStream() 调用更新 MediaCodec 堆栈中各个层的状态。您可以从 MediaCodecTest 中测试上方的评论中了解哪些操作有效。 ,但总的来说,MediaCodec 的行为并未针对“异常”用途进行定义。

所以你要看代码。输入表面的生命周期与 OMXNodeInstance 的生命周期相关。 ;它由 GraphicBufferSource 表示.一旦您向 EOS 发出信号,GraphicBufferSource 将忽略其他帧(参见 line 426 )。在不拆除 GraphicBufferSource 的情况下无法重置 EOS 标志,但当您这样做时,它会断开 Surface 下的缓冲区队列。

所以我认为您无法停止/重新启动 MediaCodec 并继续使用 Surface。

但是......你不应该需要。 CameraToMpegTest 将相机预览路由到 SurfaceTexture,然后使用 GLES 将纹理渲染到编码器的输入表面上。 SurfaceTexture 与编码器分离,不需要更改。我认为需要更改的是 CodecInputSurface,它使用来自 MediaCodec 的 Surface 调用 eglCreateWindowSurface() 来告诉 GLES 在何处绘制。如果您在那里添加一个新的“更新表面”API(销毁旧的 EGLSurface,创建新的 EGLSurface,eglMakeCurrent),并在启动新的 MediaCodec 时调用它,我认为一切都会正常工作。

更新以解决评论:

仅更改 EGLSurface 很重要。 GLConsumer.cpp 中的 checkAndUpdateEglStateLocked() 函数检查以确保 EGLDisplayEGLContext 在设置后不会更改。您不能在 CodecInputSurface 中调用 release()/eglSetup(),因为它会更改 EGLContext。您只想销毁并重新创建 EGLSurface

关于android - 带表面输入的 MediaCodec : Producing chunked output,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19102308/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com