Search code examples
androidgstreameregl

Android: createWindowSurface failed EGL_NOT_INITIALIZED


I was recently having issues with my App crashing as soon as I was leaving a certain Activity. The App uses gstreamer 1.4+ for streaming which uses an glimagesink at the end of the pipeline to display the stream on a SurfaceView. I found that sometimes (most of the time in my case), when the stream didn't deliver a keyframe before the Activity was destroyed the App would crash with the following error:

 validate_display:211 error 3001 (EGL_NOT_INITIALIZED)
 eglMakeCurrent:450 error 3008 (EGL_BAD_DISPLAY)
 validate_display:211 error 3001 (EGL_NOT_INITIALIZED)
 eglMakeCurrent:450 error 3008 (EGL_BAD_DISPLAY)
 validate_display:211 error 3001 (EGL_NOT_INITIALIZED)
 Shutting down VM
 thread exiting with uncaught exception (group=0x41b992a0)
 FATAL EXCEPTION: main
 java.lang.RuntimeException: createWindowSurface failed EGL_NOT_INITIALIZED
    at android.view.HardwareRenderer$GlRenderer.createSurface(HardwareRenderer.java:1018)
    at android.view.HardwareRenderer$GlRenderer.createEglSurface(HardwareRenderer.java:911)
    at android.view.HardwareRenderer$GlRenderer.initialize(HardwareRenderer.java:748)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1652)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1131)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4611)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
    at android.view.Choreographer.doCallbacks(Choreographer.java:555)
    at android.view.Choreographer.doFrame(Choreographer.java:525)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4898)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
    at dalvik.system.NativeStart.main(Native Method)

Solution

  • This crash was driving me nuts, I found no clue whatsoever on what caused it. But recently I found this bug report, which seems to be the source of the issue: android issue 37413. Together with the helpful notes on EGL found over here I was able to find a fix.

    The source of the problem is that in recent versions of Android calling eglTerminate without calling eglInitialize first results in EGL_NOT_INITIALIZED which in turn results in an uncaught RuntimeException. As outlined in the first link this is a bug in Android as it does not conform to the EGL spec.

    The solution is to make sure EGL is initialized (I call mine when passing the SurfaceView to gstreamer):

    EGL10 egl = (EGL10) EGLContext.getEGL();
    EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    boolean ret = egl.eglInitialize(display, null);
    
    if (!ret)
        Log.e(TAG, "EGL init error: " + egl.eglGetError());
    else
        // do your thing
    

    Please note that some of the classnames are ambivalent - you need to use the classes from javax.microedition.khronos.egl, not the ones from android.opengl.