diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 760fd7a127..40d3a37691 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -843,6 +843,7 @@ generate_jni("generated_java_audio_jni") { rtc_android_library("video_java") { java_files = [ + "api/org/webrtc/EglError.java", "api/org/webrtc/EglRenderer.java", "api/org/webrtc/GlRectDrawer.java", "api/org/webrtc/VideoDecoderFallback.java", diff --git a/sdk/android/api/org/webrtc/EglError.java b/sdk/android/api/org/webrtc/EglError.java new file mode 100644 index 0000000000..4e61f64bee --- /dev/null +++ b/sdk/android/api/org/webrtc/EglError.java @@ -0,0 +1,5 @@ +package org.webrtc; + +public interface EglError { + public void onSurfaceCreationFailed(Exception exception); +} diff --git a/sdk/android/api/org/webrtc/EglRenderer.java b/sdk/android/api/org/webrtc/EglRenderer.java index d0a1d98b2b..41f4df0ae3 100644 --- a/sdk/android/api/org/webrtc/EglRenderer.java +++ b/sdk/android/api/org/webrtc/EglRenderer.java @@ -64,17 +64,25 @@ public synchronized void setSurface(Object surface) { // TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression. @SuppressWarnings("NoSynchronizedMethodCheck") public synchronized void run() { - if (surface != null && eglBase != null && !eglBase.hasSurface()) { - if (surface instanceof Surface) { - eglBase.createSurface((Surface) surface); - } else if (surface instanceof SurfaceTexture) { - eglBase.createSurface((SurfaceTexture) surface); + try { + if (surface != null && eglBase != null && !eglBase.hasSurface()) { + if (surface instanceof Surface) { + eglBase.createSurface((Surface) surface); + } else if (surface instanceof SurfaceTexture) { + eglBase.createSurface((SurfaceTexture) surface); + } else { + throw new IllegalStateException("Invalid surface: " + surface); + } + eglBase.makeCurrent(); + // Necessary for YUV frames with odd width. + GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1); + } + } catch (Exception e) { + if (eglError != null) { + eglError.onSurfaceCreationFailed(e); } else { - throw new IllegalStateException("Invalid surface: " + surface); + throw e; } - eglBase.makeCurrent(); - // Necessary for YUV frames with odd width. - GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1); } } } @@ -99,6 +107,7 @@ public synchronized void run() { // EGL and GL resources for drawing YUV/OES textures. After initilization, these are only accessed // from the render thread. @Nullable private EglBase eglBase; + private EglError eglError; private final VideoFrameDrawer frameDrawer = new VideoFrameDrawer(); @Nullable private RendererCommon.GlDrawer drawer; private final Matrix drawMatrix = new Matrix(); @@ -157,6 +166,11 @@ public EglRenderer(String name) { this.name = name; } + public EglRenderer(String name, EglError eglError) { + this.name = name; + this.eglError = eglError; + } + /** * Initialize this class, sharing resources with |sharedContext|. The custom |drawer| will be used * for drawing frames on the EGLSurface. This class is responsible for calling release() on diff --git a/sdk/android/api/org/webrtc/SurfaceEglRenderer.java b/sdk/android/api/org/webrtc/SurfaceEglRenderer.java index 350a4cb51a..9e28eabe1d 100644 --- a/sdk/android/api/org/webrtc/SurfaceEglRenderer.java +++ b/sdk/android/api/org/webrtc/SurfaceEglRenderer.java @@ -41,6 +41,10 @@ public SurfaceEglRenderer(String name) { super(name); } + public SurfaceEglRenderer(String name, EglError eglError) { + super(name, eglError); + } + /** * Initialize this class, sharing resources with |sharedContext|. The custom |drawer| will be used * for drawing frames on the EGLSurface. This class is responsible for calling release() on diff --git a/sdk/android/api/org/webrtc/SurfaceViewRenderer.java b/sdk/android/api/org/webrtc/SurfaceViewRenderer.java index c39416c3e1..3312971125 100644 --- a/sdk/android/api/org/webrtc/SurfaceViewRenderer.java +++ b/sdk/android/api/org/webrtc/SurfaceViewRenderer.java @@ -52,6 +52,14 @@ public SurfaceViewRenderer(Context context) { getHolder().addCallback(eglRenderer); } + public SurfaceViewRenderer(Context context, EglError eglError) { + super(context); + this.resourceName = getResourceName(); + eglRenderer = new SurfaceEglRenderer(resourceName, eglError); + getHolder().addCallback(this); + getHolder().addCallback(eglRenderer); + } + /** * Standard View constructor. In order to render something, you must first call init(). */