[Android] LibVLC/AWindow: add SurfaceTextureThread

Thomas Guillem git at videolan.org
Mon Dec 19 12:07:41 CET 2016


vlc-android | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Dec 15 17:50:49 2016 +0100| [a6a975a05f0f190a3001519593d1b09baca4da5e] | committer: Thomas Guillem

LibVLC/AWindow: add SurfaceTextureThread

Helper used from the JNI to create A SurfaceTexture, and update a TexImage when
available.

> https://code.videolan.org/videolan/vlc-android/commit/a6a975a05f0f190a3001519593d1b09baca4da5e
---

 libvlc/src/org/videolan/libvlc/AWindow.java | 129 ++++++++++++++++++++++++++++
 1 file changed, 129 insertions(+)

diff --git a/libvlc/src/org/videolan/libvlc/AWindow.java b/libvlc/src/org/videolan/libvlc/AWindow.java
index ef5303c..1f3a2b8 100644
--- a/libvlc/src/org/videolan/libvlc/AWindow.java
+++ b/libvlc/src/org/videolan/libvlc/AWindow.java
@@ -585,4 +585,133 @@ class AWindow implements IVLCVout {
             }
         });
     }
+
+    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+    private static class SurfaceTextureThread extends Thread
+            implements SurfaceTexture.OnFrameAvailableListener {
+        SurfaceTexture mSurfaceTexture = null;
+
+        final int mTexName;
+        boolean mFrameAvailable = false;
+        Looper mLooper = null;
+
+        private SurfaceTextureThread(int texName) {
+            mTexName = texName;
+        }
+
+        @Override
+        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+            synchronized (this) {
+                if (mFrameAvailable)
+                    throw new IllegalStateException("An available frame was not updated");
+                mFrameAvailable = true;
+                notify();
+            }
+        }
+
+        @Override
+        public void run() {
+            Looper.prepare();
+
+            synchronized (this) {
+                mLooper = Looper.myLooper();
+                mSurfaceTexture = new SurfaceTexture(mTexName);
+                mSurfaceTexture.setOnFrameAvailableListener(this);
+                notify();
+            }
+
+            Looper.loop();
+
+            mSurfaceTexture.setOnFrameAvailableListener(null);
+            mSurfaceTexture.release();
+        }
+
+        void release() {
+            synchronized (this) {
+                while (mLooper == null) {
+                    try {
+                        wait();
+                    } catch (InterruptedException ignored) {
+                    }
+                }
+            }
+            mLooper.quit();
+            try {
+                join();
+            } catch (InterruptedException ignored) {
+            }
+        }
+
+        boolean waitAndUpdateTexImage(float[] transformMatrix) {
+            synchronized (this) {
+                while (!mFrameAvailable) {
+                    try {
+                        wait(500);
+                        if (!mFrameAvailable)
+                            return false;
+                    } catch (InterruptedException ignored) {
+                    }
+                }
+                mFrameAvailable = false;
+            }
+            mSurfaceTexture.updateTexImage();
+            mSurfaceTexture.getTransformMatrix(transformMatrix);
+            return true;
+        }
+
+        Surface getSurface() {
+            synchronized (this) {
+                while (mSurfaceTexture == null) {
+                    try {
+                        wait();
+                    } catch (InterruptedException ignored) {
+                    }
+                }
+                return new Surface(mSurfaceTexture);
+            }
+        }
+    }
+
+    /**
+     * Create a SurfaceTextureThread
+     *
+     * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
+     * @return a valid and started SurfaceTextureThread
+     */
+    @SuppressWarnings("unused") /* used by JNI */
+    static private SurfaceTextureThread SurfaceTextureThread_create(int texName) {
+        if (AndroidUtil.isICSOrLater()) {
+            final SurfaceTextureThread st = new SurfaceTextureThread(texName);
+            st.start();
+            return st;
+        } else
+            return null;
+    }
+
+    /**
+     * Release the SurfaceTexture and join the thread
+     */
+    @SuppressWarnings("unused") /* used by JNI */
+    static private void SurfaceTextureThread_release(SurfaceTextureThread st) {
+        st.release();
+    }
+
+    /**
+     * Wait for a frame and update the TexImage
+     *
+     * @return true on success, false on error or timeout
+     */
+    @SuppressWarnings("unused") /* used by JNI */
+    static private boolean SurfaceTextureThread_waitAndUpdateTexImage(SurfaceTextureThread st,
+                                                                      float[] transformMatrix) {
+        return st.waitAndUpdateTexImage(transformMatrix);
+    }
+
+    /**
+     * Get a Surface from the SurfaceTexture
+     */
+    @SuppressWarnings("unused") /* used by JNI */
+    static private Surface SurfaceTextureThread_getSurface(SurfaceTextureThread st) {
+        return st.getSurface();
+    }
 }
\ No newline at end of file



More information about the Android mailing list