OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 21 matching lines...) Expand all Loading... |
32 import android.opengl.GLES20; | 32 import android.opengl.GLES20; |
33 import android.os.Build; | 33 import android.os.Build; |
34 import android.os.Handler; | 34 import android.os.Handler; |
35 import android.os.HandlerThread; | 35 import android.os.HandlerThread; |
36 import android.os.SystemClock; | 36 import android.os.SystemClock; |
37 | 37 |
38 import java.util.concurrent.Callable; | 38 import java.util.concurrent.Callable; |
39 import java.util.concurrent.CountDownLatch; | 39 import java.util.concurrent.CountDownLatch; |
40 import java.util.concurrent.TimeUnit; | 40 import java.util.concurrent.TimeUnit; |
41 | 41 |
42 import javax.microedition.khronos.egl.EGLContext; | |
43 | |
44 /** | 42 /** |
45 * Helper class to create and synchronize access to a SurfaceTexture. The caller
will get notified | 43 * Helper class to create and synchronize access to a SurfaceTexture. The caller
will get notified |
46 * of new frames in onTextureFrameAvailable(), and should call returnTextureFram
e() when done with | 44 * of new frames in onTextureFrameAvailable(), and should call returnTextureFram
e() when done with |
47 * the frame. Only one texture frame can be in flight at once, so returnTextureF
rame() must be | 45 * the frame. Only one texture frame can be in flight at once, so returnTextureF
rame() must be |
48 * called in order to receive a new frame. Call disconnect() to stop receiveing
new frames and | 46 * called in order to receive a new frame. Call disconnect() to stop receiveing
new frames and |
49 * release all resources. | 47 * release all resources. |
50 * Note that there is a C++ counter part of this class that optionally can be us
ed. It is used for | 48 * Note that there is a C++ counter part of this class that optionally can be us
ed. It is used for |
51 * wrapping texture frames into webrtc::VideoFrames and also handles calling ret
urnTextureFrame() | 49 * wrapping texture frames into webrtc::VideoFrames and also handles calling ret
urnTextureFrame() |
52 * when the webrtc::VideoFrame is no longer used. | 50 * when the webrtc::VideoFrame is no longer used. |
53 */ | 51 */ |
54 class SurfaceTextureHelper { | 52 class SurfaceTextureHelper { |
55 private static final String TAG = "SurfaceTextureHelper"; | 53 private static final String TAG = "SurfaceTextureHelper"; |
56 /** | 54 /** |
57 * Callback interface for being notified that a new texture frame is available
. The calls will be | 55 * Callback interface for being notified that a new texture frame is available
. The calls will be |
58 * made on a dedicated thread with a bound EGLContext. The thread will be the
same throughout the | 56 * made on a dedicated thread with a bound EGLContext. The thread will be the
same throughout the |
59 * lifetime of the SurfaceTextureHelper instance, but different from the threa
d calling the | 57 * lifetime of the SurfaceTextureHelper instance, but different from the threa
d calling the |
60 * SurfaceTextureHelper constructor. The callee is not allowed to make another
EGLContext current | 58 * SurfaceTextureHelper constructor. The callee is not allowed to make another
EGLContext current |
61 * on the calling thread. | 59 * on the calling thread. |
62 */ | 60 */ |
63 public interface OnTextureFrameAvailableListener { | 61 public interface OnTextureFrameAvailableListener { |
64 abstract void onTextureFrameAvailable( | 62 abstract void onTextureFrameAvailable( |
65 int oesTextureId, float[] transformMatrix, long timestampNs); | 63 int oesTextureId, float[] transformMatrix, long timestampNs); |
66 } | 64 } |
67 | 65 |
68 public static SurfaceTextureHelper create(EGLContext sharedContext) { | 66 public static SurfaceTextureHelper create(EglBase.Context sharedContext) { |
69 return create(sharedContext, null); | 67 return create(sharedContext, null); |
70 } | 68 } |
71 | 69 |
72 /** | 70 /** |
73 * Construct a new SurfaceTextureHelper sharing OpenGL resources with |sharedC
ontext|. If | 71 * Construct a new SurfaceTextureHelper sharing OpenGL resources with |sharedC
ontext|. If |
74 * |handler| is non-null, the callback will be executed on that handler's thre
ad. If |handler| is | 72 * |handler| is non-null, the callback will be executed on that handler's thre
ad. If |handler| is |
75 * null, a dedicated private thread is created for the callbacks. | 73 * null, a dedicated private thread is created for the callbacks. |
76 */ | 74 */ |
77 public static SurfaceTextureHelper create(final EGLContext sharedContext, fina
l Handler handler) { | 75 public static SurfaceTextureHelper create(final EglBase.Context sharedContext, |
| 76 final Handler handler) { |
78 final Handler finalHandler; | 77 final Handler finalHandler; |
79 if (handler != null) { | 78 if (handler != null) { |
80 finalHandler = handler; | 79 finalHandler = handler; |
81 } else { | 80 } else { |
82 final HandlerThread thread = new HandlerThread(TAG); | 81 final HandlerThread thread = new HandlerThread(TAG); |
83 thread.start(); | 82 thread.start(); |
84 finalHandler = new Handler(thread.getLooper()); | 83 finalHandler = new Handler(thread.getLooper()); |
85 } | 84 } |
86 // The onFrameAvailable() callback will be executed on the SurfaceTexture ct
or thread. See: | 85 // The onFrameAvailable() callback will be executed on the SurfaceTexture ct
or thread. See: |
87 // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.andr
oid/android/5.1.1_r1/android/graphics/SurfaceTexture.java#195. | 86 // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.andr
oid/android/5.1.1_r1/android/graphics/SurfaceTexture.java#195. |
(...skipping 10 matching lines...) Expand all Loading... |
98 private boolean isOwningThread; | 97 private boolean isOwningThread; |
99 private final EglBase eglBase; | 98 private final EglBase eglBase; |
100 private final SurfaceTexture surfaceTexture; | 99 private final SurfaceTexture surfaceTexture; |
101 private final int oesTextureId; | 100 private final int oesTextureId; |
102 private OnTextureFrameAvailableListener listener; | 101 private OnTextureFrameAvailableListener listener; |
103 // The possible states of this class. | 102 // The possible states of this class. |
104 private boolean hasPendingTexture = false; | 103 private boolean hasPendingTexture = false; |
105 private boolean isTextureInUse = false; | 104 private boolean isTextureInUse = false; |
106 private boolean isQuitting = false; | 105 private boolean isQuitting = false; |
107 | 106 |
108 private SurfaceTextureHelper(EGLContext sharedContext, Handler handler, boolea
n isOwningThread) { | 107 private SurfaceTextureHelper(EglBase.Context sharedContext, |
| 108 Handler handler, boolean isOwningThread) { |
109 if (handler.getLooper().getThread() != Thread.currentThread()) { | 109 if (handler.getLooper().getThread() != Thread.currentThread()) { |
110 throw new IllegalStateException("SurfaceTextureHelper must be created on t
he handler thread"); | 110 throw new IllegalStateException("SurfaceTextureHelper must be created on t
he handler thread"); |
111 } | 111 } |
112 this.handler = handler; | 112 this.handler = handler; |
113 this.isOwningThread = isOwningThread; | 113 this.isOwningThread = isOwningThread; |
114 | 114 |
115 eglBase = new EglBase(sharedContext, EglBase.ConfigType.PIXEL_BUFFER); | 115 eglBase = EglBase.create(sharedContext, EglBase.ConfigType.PIXEL_BUFFER); |
116 eglBase.createDummyPbufferSurface(); | 116 eglBase.createDummyPbufferSurface(); |
117 eglBase.makeCurrent(); | 117 eglBase.makeCurrent(); |
118 | 118 |
119 oesTextureId = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); | 119 oesTextureId = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); |
120 surfaceTexture = new SurfaceTexture(oesTextureId); | 120 surfaceTexture = new SurfaceTexture(oesTextureId); |
121 } | 121 } |
122 | 122 |
123 /** | 123 /** |
124 * Start to stream textures to the given |listener|. | 124 * Start to stream textures to the given |listener|. |
125 * A Listener can only be set once. | 125 * A Listener can only be set once. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 if (isTextureInUse || !isQuitting) { | 235 if (isTextureInUse || !isQuitting) { |
236 throw new IllegalStateException("Unexpected release."); | 236 throw new IllegalStateException("Unexpected release."); |
237 } | 237 } |
238 eglBase.makeCurrent(); | 238 eglBase.makeCurrent(); |
239 GLES20.glDeleteTextures(1, new int[] {oesTextureId}, 0); | 239 GLES20.glDeleteTextures(1, new int[] {oesTextureId}, 0); |
240 surfaceTexture.release(); | 240 surfaceTexture.release(); |
241 eglBase.release(); | 241 eglBase.release(); |
242 handler.getLooper().quit(); | 242 handler.getLooper().quit(); |
243 } | 243 } |
244 } | 244 } |
OLD | NEW |