Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Unified Diff: talk/app/webrtc/java/android/org/webrtc/SurfaceTextureHelper.java

Issue 1366413003: Add C++ SurfaceTextureHandler (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressed comments. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: talk/app/webrtc/java/android/org/webrtc/SurfaceTextureHelper.java
diff --git a/talk/app/webrtc/java/android/org/webrtc/SurfaceTextureHelper.java b/talk/app/webrtc/java/android/org/webrtc/SurfaceTextureHelper.java
index dfd54544a5b46b75cd9afa05877f924e91caea9b..9ab38210d4b1e62b1f6d577d936c134624fbdec0 100644
--- a/talk/app/webrtc/java/android/org/webrtc/SurfaceTextureHelper.java
+++ b/talk/app/webrtc/java/android/org/webrtc/SurfaceTextureHelper.java
@@ -37,6 +37,7 @@ import android.os.HandlerThread;
import android.os.SystemClock;
import android.util.Log;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
@@ -45,8 +46,11 @@ import java.util.concurrent.TimeUnit;
* the frame. Only one texture frame can be in flight at once, so returnTextureFrame() must be
* called in order to receive a new frame. Call disconnect() to stop receiveing new frames and
* release all resources.
+ * Note that there is a C++ counter part of this class that optionally can be used. It is used for
+ * wrapping texture frames into webrtc::VideoFrames and also handles calling returnTextureFrame()
+ * when the webrtc::VideoFrame is no longer used.
*/
-public final class SurfaceTextureHelper {
+final class SurfaceTextureHelper {
private static final String TAG = "SurfaceTextureHelper";
/**
* Callback interface for being notified that a new texture frame is available. The calls will be
@@ -65,18 +69,16 @@ public final class SurfaceTextureHelper {
private final EglBase eglBase;
private final SurfaceTexture surfaceTexture;
private final int oesTextureId;
- private final OnTextureFrameAvailableListener listener;
+ private OnTextureFrameAvailableListener listener;
// The possible states of this class.
private boolean hasPendingTexture = false;
private boolean isTextureInUse = false;
private boolean isQuitting = false;
/**
- * Construct a new SurfaceTextureHelper to stream textures to the given |listener|, sharing OpenGL
- * resources with |sharedContext|.
+ * Construct a new SurfaceTextureHelper sharing OpenGL resources with |sharedContext|.
*/
- public SurfaceTextureHelper(EGLContext sharedContext, OnTextureFrameAvailableListener listener) {
- this.listener = listener;
+ public SurfaceTextureHelper(EGLContext sharedContext) {
thread = new HandlerThread(TAG);
thread.start();
handler = new Handler(thread.getLooper());
@@ -87,13 +89,6 @@ public final 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();
- }
- }, handler);
// Reattach EGL context to private thread.
eglBase.detachCurrent();
@@ -105,6 +100,24 @@ public final class SurfaceTextureHelper {
}
/**
+ * Start to stream textures to the given |listener|.
+ * A Listener can only be set once.
+ */
+ public void setListener(OnTextureFrameAvailableListener listener) {
+ if (this.listener != null) {
+ throw new IllegalStateException("SurfaceTextureHelper listener has already been set.");
+ }
+ this.listener = listener;
+ surfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
+ @Override
+ public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+ hasPendingTexture = true;
+ tryDeliverTextureFrame();
+ }
+ }, handler);
+ }
+
+ /**
* Retrieve the underlying SurfaceTexture. The SurfaceTexture should be passed in to a video
* producer such as a camera or decoder.
*/
@@ -131,23 +144,34 @@ public final class SurfaceTextureHelper {
}
/**
- * Call disconnect() to stop receiving frames and release all resources. This function will block
- * until all frames are returned and all resoureces are released. You are guaranteed to not
- * receive any more onTextureFrameAvailable() after this function returns.
+ * Call disconnect() to stop receiving frames. Resources are released when the texture frame has
+ * been returned by a call to returnTextureFrame(). You are guaranteed to not receive any more
+ * onTextureFrameAvailable() after this function returns.
*/
public void disconnect() {
+ final CountDownLatch barrier = new CountDownLatch(1);
handler.postAtFrontOfQueue(new Runnable() {
@Override public void run() {
isQuitting = true;
+ barrier.countDown();
if (!isTextureInUse) {
release();
}
}
});
- try {
- thread.join();
- } catch (InterruptedException e) {
- Log.e(TAG, "SurfaceTexture thread was interrupted in join().");
+ boolean wasInterrupted = true;
+ while(true) {
+ try {
+ barrier.await();
+ break;
+ } catch (InterruptedException e) {
+ // Someone is asking us to return early at our convenience. We must wait until the
+ // |isQuitting| flag has been set but we should preserve the information and pass it along.
+ wasInterrupted = true;
+ }
+ }
+ if (wasInterrupted) {
+ Thread.currentThread().interrupt();
}
}

Powered by Google App Engine
This is Rietveld 408576698