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

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: 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..69d6a0b3cbf2066b72a7690c65779922e8f5cb8e 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();
@@ -104,6 +99,21 @@ public final class SurfaceTextureHelper {
});
}
+ // Start to stream textures to the given |listener|.
magjed_webrtc 2015/09/27 11:26:40 Use Javadoc block comment like the rest of the cla
perkj_webrtc 2015/09/28 07:22:47 Done.
+ public void setListener(OnTextureFrameAvailableListener listener) {
+ if (this.listener != null) {
+ throw new RuntimeException("SurfaceTextureHelper listener has already been set.");
magjed_webrtc 2015/09/27 11:26:40 s/RuntimeException/IllegalStateException/g
perkj_webrtc 2015/09/28 07:22:47 Done.
+ }
+ 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.
@@ -113,41 +123,35 @@ public final class SurfaceTextureHelper {
}
/**
- * Call this function to signal that you are done with the frame received in
- * onTextureFrameAvailable(). Only one texture frame can be in flight at once, so you must call
- * this function in order to receive a new frame.
- */
- public void returnTextureFrame() {
- handler.post(new Runnable() {
- @Override public void run() {
- isTextureInUse = false;
- if (isQuitting) {
- release();
- } else {
- tryDeliverTextureFrame();
- }
- }
- });
- }
-
- /**
- * 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 textureFrame have been returned by a call to returnTextureFrame.
magjed_webrtc 2015/09/27 11:26:40 s/textureFrame/texture frame/g. s/have/has/g. s/to
perkj_webrtc 2015/09/28 07:22:47 Done.
+ * 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();
magjed_webrtc 2015/09/27 11:26:40 This is duplicated boilerplate code from ThreadUti
perkj_webrtc 2015/09/28 07:22:47 ok, either land yours first or maybe you can refac
+ 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();
}
}
@@ -185,4 +189,22 @@ public final class SurfaceTextureHelper {
// Quit safely to make sure the clean-up posted above is executed.
thread.quitSafely();
}
+
+ /**
+ * Call this function to signal that you are done with the frame received in
+ * onTextureFrameAvailable(). Only one texture frame can be in flight at once, so you must call
+ * this function in order to receive a new frame.
+ */
+ public void returnTextureFrame() {
magjed_webrtc 2015/09/27 11:26:40 Why have you moved this public method below the pr
perkj_webrtc 2015/09/28 07:22:47 Done.
+ handler.post(new Runnable() {
+ @Override public void run() {
+ isTextureInUse = false;
+ if (isQuitting) {
+ release();
+ } else {
+ tryDeliverTextureFrame();
+ }
+ }
+ });
+ }
}
« no previous file with comments | « no previous file | talk/app/webrtc/java/jni/classreferenceholder.cc » ('j') | talk/app/webrtc/java/jni/surfacetexturehelper_jni.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698