From 22384416546fe2966a8760849983e10dd00015b4 Mon Sep 17 00:00:00 2001 From: Jonathan Yu Date: Wed, 16 Aug 2017 13:25:45 -0700 Subject: [PATCH] Explicitly specify the onFrameAvailable() thread. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are already asserting in tryDeliverTextureFrame() that we are on the SurfaceTextureHelper handler thread, but this behavior isn't guaranteed by Android. Also updated docs for OnTextureFrameAvailableListener, since other classes (e.g. capturers) were also asserting that they were called on the SurfaceTextureHelper thread. Bug: webrtc:8087, b/64609528 Change-Id: I47148c452f66f24477e438b06ef124a96965853d Reviewed-on: https://chromium-review.googlesource.com/610495 Reviewed-by: Sami Kalliomäki Commit-Queue: Jonathan Yu Cr-Commit-Position: refs/heads/master@{#19398} --- .../api/org/webrtc/SurfaceTextureHelper.java | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) 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); + } } /**