我正在开发一个视频编码应用程序,希望在托管 Activity 进入后台或屏幕关闭/打开时防止其停止。我的编码器架构源于优秀的 CameraToMpegTest 示例,增加了将相机帧显示到 GLSurfaceView 上(请参见下面的 Github 链接)。我目前正在执行后台录制,采用两种状态的解决方案:
- 当托管 Activity 在前台时,每次调用 GLSurfaceView.Renderer 的 onDrawFrame 时编码一个视频帧。这样可以在突发情况下访问 GLSurfaceView 的 EGL 状态,以免阻塞其他排队到渲染器线程的事件。
- 当托管 Activity 进入后台时,停止 onDrawFrame 编码,并在另一个后台线程中循环编码帧。此模式与 CameraToMpegTest 示例相同。
然而,如果屏幕关闭了,GLSurfaceView的EGLContext会丢失,并且需要重新调用
然而,如果屏幕关闭了,GLSurfaceView的EGLContext会丢失,并且需要重新调用
onSurfaceCreated
。在这种情况下,我们必须重新创建连接到MediaCodec输入Surface的EGL窗口表面。不幸的是,第二次调用eglCreateWindowSurface
会产生如下问题:E/libEGL(18839): EGLNativeWindowType 0x7a931098 already connected to another API
在调用之前,我释放与Android Surface相关的所有EGL资源。
有没有一种方法可以交换与MediaCodec输入Surface相关联的EGLSurface?
更新 我将在基于MediaCodec和MediaMuxer类的Android视频sdk中应用此处所学到的教训。希望它能帮助你!
MediaCodec
不应受到后台运行的影响,甚至不应意识到它在后台运行。例如,在 Android 4.4 中添加的screenrecord
命令就可以愉快地在后台运行。事实上,它正在编码任何东西,这意味着它仍在接收输入数据,所以我的猜测是某些东西正在影响Camera
。我不明白为什么会导致预览Surface
是空白的,而预览byte[]
却有真实数据。 - faddeneglCreateWindowSurface
上出现“已连接到另一个API”的错误。这是否可能呢? - dbroeglMakeCurrent(nothing)
时,请确保您在正确的线程中。如果上下文+线程在线程#1中处于当前状态,则在线程#2中调用eglMakeCurrent(nothing)
将不会释放线程和表面。如果线程的当前上下文与对象中的内容匹配,则您知道自己在正确的位置。(除非您在两个不同的线程中使相同的上下文成为当前上下文,否则您将处于困境之中。) - fadden