diff --git a/webrtc/sdk/android/api/org/webrtc/SurfaceTextureHelper.java b/webrtc/sdk/android/api/org/webrtc/SurfaceTextureHelper.java index a3db84de8a..1fbc53fe64 100644 --- a/webrtc/sdk/android/api/org/webrtc/SurfaceTextureHelper.java +++ b/webrtc/sdk/android/api/org/webrtc/SurfaceTextureHelper.java @@ -10,6 +10,7 @@ package org.webrtc; +import android.annotation.TargetApi; import android.graphics.Matrix; import android.graphics.SurfaceTexture; import android.opengl.GLES11Ext; @@ -39,10 +40,8 @@ public class SurfaceTextureHelper { private static final String TAG = "SurfaceTextureHelper"; /** * Callback interface for being notified that a new texture frame is available. The calls will be - * made on a dedicated thread with a bound EGLContext. The thread will be the same throughout the - * lifetime of the SurfaceTextureHelper instance, but different from the thread calling the - * SurfaceTextureHelper constructor. The callee is not allowed to make another EGLContext current - * on the calling thread. + * made on the SurfaceTextureHelper handler thread, with a bound EGLContext. The callee is not + * allowed to make another EGLContext current on the calling thread. */ public interface OnTextureFrameAvailableListener { abstract void onTextureFrameAvailable( @@ -127,13 +126,24 @@ public class SurfaceTextureHelper { oesTextureId = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); surfaceTexture = new SurfaceTexture(oesTextureId); - surfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() { - @Override - public void onFrameAvailable(SurfaceTexture surfaceTexture) { - hasPendingTexture = true; - tryDeliverTextureFrame(); - } - }); + setOnFrameAvailableListener(surfaceTexture, (SurfaceTexture st) -> { + hasPendingTexture = true; + tryDeliverTextureFrame(); + }, handler); + } + + @TargetApi(21) + private static void setOnFrameAvailableListener(SurfaceTexture surfaceTexture, + SurfaceTexture.OnFrameAvailableListener listener, Handler handler) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + surfaceTexture.setOnFrameAvailableListener(listener, handler); + } else { + // The documentation states that the listener will be called on an arbitrary thread, but in + // pratice, it is always the thread on which the SurfaceTexture was constructed. There are + // assertions in place in case this ever changes. For API >= 21, we use the new API to + // explicitly specify the handler. + surfaceTexture.setOnFrameAvailableListener(listener); + } } /**