Android 由于ivalid上下文,SurfaceTexture.UpdateMaximage()失败

Android 由于ivalid上下文,SurfaceTexture.UpdateMaximage()失败,android,egl,Android,Egl,我有一个应用程序,它可以从摄像机捕获视频。 我是isung GLSurfaceView,用于显示预览和用于编码的MediaCodec。 GlSurfaceView有自己的带有EGLContext的GLThread,我正在为MediaCodec创建另一个线程,并在该线程中初始化另一个EGLContext。而且它很有效,我可以录制视频 当我试图最小化然后恢复应用程序时,问题就出现了。调用SurfaceTexture.UpdateMaximage()会导致IllegalStateException,l

我有一个应用程序,它可以从摄像机捕获视频。 我是isung GLSurfaceView,用于显示预览和用于编码的MediaCodec。 GlSurfaceView有自己的带有EGLContext的GLThread,我正在为MediaCodec创建另一个线程,并在该线程中初始化另一个EGLContext。而且它很有效,我可以录制视频

当我试图最小化然后恢复应用程序时,问题就出现了。调用SurfaceTexture.UpdateMaximage()会导致IllegalStateException,logcat显示以下消息:

02-19 18:19:58.400 8528-15845 E/GLConsumer:[unnamed-8528-0] checkAndUpdateEglState: invalid current EGLContext 
02-19 18:19:58.400 8528-15845 E/_GLViewRender: error updating text image 
02-19 18:19:58.400 8528-15845 E/_GLViewRender: java.lang.IllegalStateException: Unable to update texture contents (see logcat for details)
02-19 18:19:58.400 8528-15845 E/_GLViewRender:     at android.graphics.SurfaceTexture.nativeUpdateTexImage(Native Method)
02-19 18:19:58.400 8528-15845 E/_GLViewRender:     at android.graphics.SurfaceTexture.updateTexImage(SurfaceTexture.java:240)
02-19 18:19:58.400 8528-15845 E/_GLViewRender:     at ui.GLSurfaceViewRender.onDrawFrame(GLSurfaceViewRender.java:105)
02-19 18:19:58.400 8528-15845 E/_GLViewRender:     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1583)
02-19 18:19:58.400 8528-15845 E/_GLViewRender:     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1286)
当应用程序最小化时我在做什么:

  • 停止摄影机预览:

    if (isPreviewOn && mCamera != null) {
        isPreviewOn = false;
        mCamera.stopPreview();
    }
    
  • 释放摄像头:

    try {
        mCamera.setPreviewTexture(null);
    } catch (IOException e) {
        e.printStackTrace();
    }
    mCamera.release();
    mCamera = null;
    
  • 召唤

    GLSurfaceView.onPause()
    
    GLSurfaceView.onPause()
    
  • 应用程序恢复时我正在执行的操作:

  • 召唤

    GLSurfaceView.onPause()
    
    GLSurfaceView.onPause()
    
  • 打开摄影机,设置预览表面纹理,然后开始预览

    if (mCamera == null) {
        mCamera = Camera.open(CAMERA_ID);
        params = mCamera.getParameters();
    }
    
    try {
        mCamera.setPreviewTexture(renderer.getSurfaceTexture());
    } catch (IOException e) {
        Log.e(TAG, "error setting ST to preview", e);
        return;
    }
    
    if (!isPreviewOn && mCamera != null) {
        isPreviewOn = true;
        mCamera.startPreview();
    }
    
  • 下次调用updateTextImage时,会发生此错误


    你知道为什么吗?

    第一个线索是,你的表面与你的背景分离了

    我不知道您在哪里使用了这个示例,但我认为当摄影机变为null时,您可以预期剩余的实例也会被null或无效。一切都需要重新创造。通常,大多数初始化都是在从
    GlSurfaceView
    派生的视图的构造函数中完成的

    换句话说:确保你在第一次跑步时通过了相同的步骤。创建一个“Initialize()”方法


    这里有一个古老的例子,展示了使用曲面相机的基本原理。

    第一个线索是曲面与背景分离

    我不知道您在哪里使用了这个示例,但我认为当摄影机变为null时,您可以预期剩余的实例也会被null或无效。一切都需要重新创造。通常,大多数初始化都是在从
    GlSurfaceView
    派生的视图的构造函数中完成的

    换句话说:确保你在第一次跑步时通过了相同的步骤。创建一个“Initialize()”方法


    这是一个老版本,展示了相机在曲面上的基本用法。

    你说得对,当我在onStop中进行全面清理并在onStart中进行完全重新初始化时,一切都正常了。有趣的是,glSurfaceView中的曲面被重新创建,并且当应用程序恢复并调用glSurfaceView.onResume时,会再次调用方法glSurfaceView$Renderer.onSurfaceCreated()。有鉴于此,我将第二个编码线程的初始化调用放入onSurfaceCreated方法中,这样我就可以确保在GLSurfaceView准备好之后,编码上下文和编码表面将被初始化。同样的问题也发生在给MediaPlayer一个表面时。有一个非常严格的生命周期需要尊重,否则它将持续崩溃在非法状态。你是对的,当我在onStop中进行全面清理并在onStart中进行完全重新初始化时,一切都开始工作。有趣的是,glSurfaceView中的曲面被重新创建,并且当应用程序恢复并调用glSurfaceView.onResume时,会再次调用方法glSurfaceView$Renderer.onSurfaceCreated()。有鉴于此,我将第二个编码线程的初始化调用放入onSurfaceCreated方法中,这样我就可以确保在GLSurfaceView准备好之后,编码上下文和编码表面将被初始化。同样的问题也发生在给MediaPlayer一个表面时。有一个非常严格的生命周期需要尊重,否则它将不断地在非法国家崩溃。