Android SurfaceTextureHelper: Replace API 21 with API 11 version of setOnFrameAvailableListener()
BUG=b/24809429 R=glaznev@webrtc.org, perkj@webrtc.org Review URL: https://codereview.webrtc.org/1395543004 . Cr-Commit-Position: refs/heads/master@{#10247}
This commit is contained in:
parent
e9e3668759
commit
747c1bccd9
@ -271,7 +271,7 @@ public final class GlRectDrawerTest extends ActivityTestCase {
|
||||
|
||||
// Create resources for generating OES textures.
|
||||
final SurfaceTextureHelper surfaceTextureHelper =
|
||||
new SurfaceTextureHelper(eglBase.getContext());
|
||||
SurfaceTextureHelper.create(eglBase.getContext());
|
||||
final StubOesTextureProducer oesProducer = new StubOesTextureProducer(
|
||||
eglBase.getContext(), surfaceTextureHelper.getSurfaceTexture(), WIDTH, HEIGHT);
|
||||
final SurfaceTextureHelperTest.MockTextureListener listener =
|
||||
|
||||
@ -32,6 +32,7 @@ import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.opengl.EGL14;
|
||||
import android.opengl.GLES20;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.SystemClock;
|
||||
|
||||
@ -113,7 +114,7 @@ public final class SurfaceTextureHelperTest extends ActivityTestCase {
|
||||
|
||||
// Create SurfaceTextureHelper and listener.
|
||||
final SurfaceTextureHelper surfaceTextureHelper =
|
||||
new SurfaceTextureHelper(eglBase.getContext());
|
||||
SurfaceTextureHelper.create(eglBase.getContext());
|
||||
final MockTextureListener listener = new MockTextureListener();
|
||||
surfaceTextureHelper.setListener(listener);
|
||||
surfaceTextureHelper.getSurfaceTexture().setDefaultBufferSize(width, height);
|
||||
@ -179,7 +180,7 @@ public final class SurfaceTextureHelperTest extends ActivityTestCase {
|
||||
|
||||
// Create SurfaceTextureHelper and listener.
|
||||
final SurfaceTextureHelper surfaceTextureHelper =
|
||||
new SurfaceTextureHelper(eglBase.getContext());
|
||||
SurfaceTextureHelper.create(eglBase.getContext());
|
||||
final MockTextureListener listener = new MockTextureListener();
|
||||
surfaceTextureHelper.setListener(listener);
|
||||
surfaceTextureHelper.getSurfaceTexture().setDefaultBufferSize(width, height);
|
||||
@ -238,7 +239,7 @@ public final class SurfaceTextureHelperTest extends ActivityTestCase {
|
||||
public static void testDisconnect() throws InterruptedException {
|
||||
// Create SurfaceTextureHelper and listener.
|
||||
final SurfaceTextureHelper surfaceTextureHelper =
|
||||
new SurfaceTextureHelper(EGL14.EGL_NO_CONTEXT);
|
||||
SurfaceTextureHelper.create(EGL14.EGL_NO_CONTEXT);
|
||||
final MockTextureListener listener = new MockTextureListener();
|
||||
surfaceTextureHelper.setListener(listener);
|
||||
// Create EglBase with the SurfaceTexture as target EGLSurface.
|
||||
@ -274,7 +275,7 @@ public final class SurfaceTextureHelperTest extends ActivityTestCase {
|
||||
@SmallTest
|
||||
public static void testDisconnectImmediately() {
|
||||
final SurfaceTextureHelper surfaceTextureHelper =
|
||||
new SurfaceTextureHelper(EGL14.EGL_NO_CONTEXT);
|
||||
SurfaceTextureHelper.create(EGL14.EGL_NO_CONTEXT);
|
||||
surfaceTextureHelper.disconnect();
|
||||
}
|
||||
|
||||
@ -286,10 +287,11 @@ public final class SurfaceTextureHelperTest extends ActivityTestCase {
|
||||
public static void testFrameOnSeparateThread() throws InterruptedException {
|
||||
final HandlerThread thread = new HandlerThread("SurfaceTextureHelperTestThread");
|
||||
thread.start();
|
||||
final Handler handler = new Handler(thread.getLooper());
|
||||
|
||||
// Create SurfaceTextureHelper and listener.
|
||||
final SurfaceTextureHelper surfaceTextureHelper =
|
||||
new SurfaceTextureHelper(EGL14.EGL_NO_CONTEXT, thread);
|
||||
SurfaceTextureHelper.create(EGL14.EGL_NO_CONTEXT, handler);
|
||||
// Create a mock listener and expect frames to be delivered on |thread|.
|
||||
final MockTextureListener listener = new MockTextureListener(thread);
|
||||
surfaceTextureHelper.setListener(listener);
|
||||
|
||||
@ -36,6 +36,7 @@ import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -63,7 +64,35 @@ final class SurfaceTextureHelper {
|
||||
int oesTextureId, float[] transformMatrix, long timestampNs);
|
||||
}
|
||||
|
||||
private final HandlerThread thread;
|
||||
public static SurfaceTextureHelper create(EGLContext sharedContext) {
|
||||
return create(sharedContext, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new SurfaceTextureHelper sharing OpenGL resources with |sharedContext|. If
|
||||
* |handler| is non-null, the callback will be executed on that handler's thread. If |handler| is
|
||||
* null, a dedicated private thread is created for the callbacks.
|
||||
*/
|
||||
public static SurfaceTextureHelper create(final EGLContext sharedContext, final Handler handler) {
|
||||
final Handler finalHandler;
|
||||
if (handler != null) {
|
||||
finalHandler = handler;
|
||||
} else {
|
||||
final HandlerThread thread = new HandlerThread(TAG);
|
||||
thread.start();
|
||||
finalHandler = new Handler(thread.getLooper());
|
||||
}
|
||||
// The onFrameAvailable() callback will be executed on the SurfaceTexture ctor thread. See:
|
||||
// http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/graphics/SurfaceTexture.java#195.
|
||||
// Therefore, in order to control the callback thread on API lvl < 21, the SurfaceTextureHelper
|
||||
// is constructed on the |handler| thread.
|
||||
return ThreadUtils.invokeUninterruptibly(finalHandler, new Callable<SurfaceTextureHelper>() {
|
||||
@Override public SurfaceTextureHelper call() {
|
||||
return new SurfaceTextureHelper(sharedContext, finalHandler, (handler == null));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final Handler handler;
|
||||
private final boolean isOwningThread;
|
||||
private final EglBase eglBase;
|
||||
@ -75,23 +104,12 @@ final class SurfaceTextureHelper {
|
||||
private boolean isTextureInUse = false;
|
||||
private boolean isQuitting = false;
|
||||
|
||||
/**
|
||||
* Construct a new SurfaceTextureHelper sharing OpenGL resources with |sharedContext|.
|
||||
*/
|
||||
public SurfaceTextureHelper(EGLContext sharedContext) {
|
||||
this(sharedContext, null);
|
||||
}
|
||||
|
||||
public SurfaceTextureHelper(EGLContext sharedContext, HandlerThread thread) {
|
||||
if (thread == null) {
|
||||
this.thread = new HandlerThread(TAG);
|
||||
this.thread.start();
|
||||
this.isOwningThread = true;
|
||||
} else {
|
||||
this.thread = thread;
|
||||
this.isOwningThread = false;
|
||||
private SurfaceTextureHelper(EGLContext sharedContext, Handler handler, boolean isOwningThread) {
|
||||
if (!handler.getLooper().isCurrentThread()) {
|
||||
throw new IllegalStateException("SurfaceTextureHelper must be created on the handler thread");
|
||||
}
|
||||
this.handler = new Handler(this.thread.getLooper());
|
||||
this.handler = handler;
|
||||
this.isOwningThread = isOwningThread;
|
||||
|
||||
eglBase = new EglBase(sharedContext, EglBase.ConfigType.PIXEL_BUFFER);
|
||||
eglBase.createDummyPbufferSurface();
|
||||
@ -99,9 +117,6 @@ final class SurfaceTextureHelper {
|
||||
|
||||
oesTextureId = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
|
||||
surfaceTexture = new SurfaceTexture(oesTextureId);
|
||||
|
||||
// The EGL context will be re-attached to the private thread.
|
||||
eglBase.detachCurrent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,7 +134,7 @@ final class SurfaceTextureHelper {
|
||||
hasPendingTexture = true;
|
||||
tryDeliverTextureFrame();
|
||||
}
|
||||
}, handler);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,7 +169,7 @@ final class SurfaceTextureHelper {
|
||||
* onTextureFrameAvailable() after this function returns.
|
||||
*/
|
||||
public void disconnect() {
|
||||
if (Thread.currentThread() == thread) {
|
||||
if (handler.getLooper().isCurrentThread()) {
|
||||
isQuitting = true;
|
||||
if (!isTextureInUse) {
|
||||
release();
|
||||
@ -175,7 +190,7 @@ final class SurfaceTextureHelper {
|
||||
}
|
||||
|
||||
private void tryDeliverTextureFrame() {
|
||||
if (Thread.currentThread() != thread) {
|
||||
if (!handler.getLooper().isCurrentThread()) {
|
||||
throw new IllegalStateException("Wrong thread.");
|
||||
}
|
||||
if (isQuitting || !hasPendingTexture || isTextureInUse) {
|
||||
@ -196,7 +211,7 @@ final class SurfaceTextureHelper {
|
||||
}
|
||||
|
||||
private void release() {
|
||||
if (Thread.currentThread() != thread) {
|
||||
if (!handler.getLooper().isCurrentThread()) {
|
||||
throw new IllegalStateException("Wrong thread.");
|
||||
}
|
||||
if (isTextureInUse || !isQuitting) {
|
||||
@ -207,7 +222,7 @@ final class SurfaceTextureHelper {
|
||||
surfaceTexture.release();
|
||||
eglBase.release();
|
||||
if (isOwningThread) {
|
||||
thread.quitSafely();
|
||||
handler.getLooper().quitSafely();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,9 +314,8 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
||||
cameraThread.start();
|
||||
cameraThreadHandler = new Handler(cameraThread.getLooper());
|
||||
videoBuffers = new FramePool(cameraThread);
|
||||
surfaceHelper =
|
||||
new SurfaceTextureHelper(sharedContext == null ? EGL14.EGL_NO_CONTEXT : sharedContext,
|
||||
cameraThread);
|
||||
surfaceHelper = SurfaceTextureHelper.create(
|
||||
sharedContext == null ? EGL14.EGL_NO_CONTEXT : sharedContext, cameraThreadHandler);
|
||||
if (sharedContext != null) {
|
||||
surfaceHelper.setListener(this);
|
||||
}
|
||||
|
||||
@ -64,19 +64,18 @@ SurfaceTextureHelper::SurfaceTextureHelper(JNIEnv* jni,
|
||||
: j_surface_texture_helper_class_(
|
||||
jni,
|
||||
FindClass(jni, "org/webrtc/SurfaceTextureHelper")),
|
||||
j_surface_texture_helper_(
|
||||
jni,
|
||||
jni->NewObject(*j_surface_texture_helper_class_,
|
||||
GetMethodID(jni,
|
||||
*j_surface_texture_helper_class_,
|
||||
"<init>",
|
||||
"(Landroid/opengl/EGLContext;)V"),
|
||||
egl_shared_context)),
|
||||
j_return_texture_method_(
|
||||
GetMethodID(jni,
|
||||
*j_surface_texture_helper_class_,
|
||||
"returnTextureFrame",
|
||||
"()V")) {
|
||||
j_surface_texture_helper_(jni, jni->CallStaticObjectMethod(
|
||||
*j_surface_texture_helper_class_,
|
||||
GetStaticMethodID(
|
||||
jni,
|
||||
*j_surface_texture_helper_class_,
|
||||
"create",
|
||||
"(Landroid/opengl/EGLContext;)Lorg/webrtc/SurfaceTextureHelper;"),
|
||||
egl_shared_context)),
|
||||
j_return_texture_method_(GetMethodID(jni,
|
||||
*j_surface_texture_helper_class_,
|
||||
"returnTextureFrame",
|
||||
"()V")) {
|
||||
CHECK_EXCEPTION(jni) << "error during initialization of SurfaceTextureHelper";
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user