public class SurfaceTexture extends Object
The image stream may come from either camera preview or video decode. A
Surface
created from a SurfaceTexture can be used as an output
destination for the android.hardware.camera2
, MediaCodec
,
MediaPlayer
, and Allocation
APIs.
When updateTexImage()
is called, the contents of the texture object specified
when the SurfaceTexture was created are updated to contain the most recent image from the image
stream. This may cause some frames of the stream to be skipped.
A SurfaceTexture may also be used in place of a SurfaceHolder when specifying the output
destination of the older Camera
API. Doing so will cause all the
frames from the image stream to be sent to the SurfaceTexture object rather than to the device's
display.
When sampling from the texture one should first transform the texture coordinates using the
matrix queried via getTransformMatrix(float[])
. The transform matrix may change each
time updateTexImage()
is called, so it should be re-queried each time the texture image
is updated.
This matrix transforms traditional 2D OpenGL ES texture coordinate column vectors of the form (s,
t, 0, 1) where s and t are on the inclusive interval [0, 1] to the proper sampling location in
the streamed texture. This transform compensates for any properties of the image stream source
that cause it to appear different from a traditional OpenGL ES texture. For example, sampling
from the bottom left corner of the image can be accomplished by transforming the column vector
(0, 0, 0, 1) using the queried matrix, while sampling from the top right corner of the image can
be done by transforming (1, 1, 0, 1).
The texture object uses the GL_TEXTURE_EXTERNAL_OES texture target, which is defined by the GL_OES_EGL_image_external OpenGL ES extension. This limits how the texture may be used. Each time the texture is bound it must be bound to the GL_TEXTURE_EXTERNAL_OES target rather than the GL_TEXTURE_2D target. Additionally, any OpenGL ES 2.0 shader that samples from the texture must declare its use of this extension using, for example, an "#extension GL_OES_EGL_image_external : require" directive. Such shaders must also access the texture using the samplerExternalOES GLSL sampler type.
SurfaceTexture objects may be created on any thread. updateTexImage()
may only be
called on the thread with the OpenGL ES context that contains the texture object. The
frame-available callback is called on an arbitrary thread, so unless special care is taken updateTexImage()
should not be called directly from the callback.
Modifier and Type | Class and Description |
---|---|
static interface |
SurfaceTexture.OnFrameAvailableListener
Callback interface for being notified that a new stream frame is available.
|
static class |
SurfaceTexture.OutOfResourcesException
Deprecated.
No longer thrown.
Surface.OutOfResourcesException
is used instead. |
Constructor and Description |
---|
SurfaceTexture(boolean singleBufferMode)
Construct a new SurfaceTexture to stream images to a given OpenGL texture.
|
SurfaceTexture(int texName)
Construct a new SurfaceTexture to stream images to a given OpenGL texture.
|
SurfaceTexture(int texName,
boolean singleBufferMode)
Construct a new SurfaceTexture to stream images to a given OpenGL texture.
|
Modifier and Type | Method and Description |
---|---|
void |
attachToGLContext(int texName)
Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread.
|
void |
detachFromGLContext()
Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object.
|
protected void |
finalize()
Called by the garbage collector on an object when garbage collection
determines that there are no more references to the object.
|
long |
getTimestamp()
Retrieve the timestamp associated with the texture image set by the most recent call to
updateTexImage.
|
void |
getTransformMatrix(float[] mtx)
Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by
the most recent call to updateTexImage.
|
boolean |
isReleased()
Returns true if the SurfaceTexture was released
|
boolean |
isSingleBuffered()
Returns true if the SurfaceTexture is single-buffered
|
void |
release()
release() frees all the buffers and puts the SurfaceTexture into the
'abandoned' state.
|
void |
releaseTexImage()
Releases the the texture content.
|
void |
setDefaultBufferSize(int width,
int height)
Set the default size of the image buffers.
|
void |
setOnFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener listener)
Register a callback to be invoked when a new image frame becomes available to the
SurfaceTexture.
|
void |
setOnFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener listener,
Handler handler)
Register a callback to be invoked when a new image frame becomes available to the
SurfaceTexture.
|
void |
updateTexImage()
Update the texture image to the most recent frame from the image stream.
|
public SurfaceTexture(int texName)
texName
- the OpenGL texture object name (e.g. generated via glGenTextures)Surface.OutOfResourcesException
- If the SurfaceTexture cannot be created.public SurfaceTexture(int texName, boolean singleBufferMode)
releaseTexImage()
method must be called before the image content producer takes
ownership of the buffer. For example, when producing image content with the NDK
ANativeWindow_lock and ANativeWindow_unlockAndPost functions, releaseTexImage()
must be called before each ANativeWindow_lock, or that call will fail. When producing
image content with OpenGL ES, releaseTexImage()
must be called before the first
OpenGL ES function call each frame.texName
- the OpenGL texture object name (e.g. generated via glGenTextures)singleBufferMode
- whether the SurfaceTexture will be in single buffered mode.Surface.OutOfResourcesException
- If the SurfaceTexture cannot be created.public SurfaceTexture(boolean singleBufferMode)
releaseTexImage()
method must be called before the image content producer takes
ownership of the buffer. For example, when producing image content with the NDK
ANativeWindow_lock and ANativeWindow_unlockAndPost functions, releaseTexImage()
must be called before each ANativeWindow_lock, or that call will fail. When producing
image content with OpenGL ES, releaseTexImage()
must be called before the first
OpenGL ES function call each frame.
Unlike SurfaceTexture(int, boolean)
, which takes an OpenGL texture object name,
this constructor creates the SurfaceTexture in detached mode. A texture name must be passed
in using attachToGLContext(int)
before calling releaseTexImage()
and producing
image content using OpenGL ES.singleBufferMode
- whether the SurfaceTexture will be in single buffered mode.Surface.OutOfResourcesException
- If the SurfaceTexture cannot be created.public void setOnFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener listener)
The callback may be called on an arbitrary thread, so it is not
safe to call updateTexImage()
without first binding the OpenGL ES context to the
thread invoking the callback.
listener
- The listener to use, or null to remove the listener.public void setOnFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener listener, Handler handler)
If a handler is specified, the callback will be invoked on that handler's thread.
If no handler is specified, then the callback may be called on an arbitrary thread,
so it is not safe to call updateTexImage()
without first binding the OpenGL ES
context to the thread invoking the callback.
listener
- The listener to use, or null to remove the listener.handler
- The handler on which the listener should be invoked, or null
to use an arbitrary thread.public void setDefaultBufferSize(int width, int height)
Canvas
(via
Surface.lockCanvas(android.graphics.Rect)
), or OpenGL ES (via an EGLSurface).
The new default buffer size will take effect the next time the image producer requests a
buffer to fill. For Canvas
this will be the next time Surface.lockCanvas(android.graphics.Rect)
is called. For OpenGL ES, the EGLSurface should be
destroyed (via eglDestroySurface), made not-current (via eglMakeCurrent), and then recreated
(via eglCreateWindowSurface) to ensure that the new default size has taken effect.
The width and height parameters must be no greater than the minimum of
GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see
glGetIntegerv
).
An error due to invalid dimensions might not be reported until
updateTexImage() is called.public void updateTexImage()
public void releaseTexImage()
SurfaceTexture(int, boolean)
.public void detachFromGLContext()
updateTexImage()
will throw an IllegalStateException
until
a successful call to attachToGLContext(int)
is made.
This can be used to access the SurfaceTexture image contents from multiple OpenGL ES
contexts. Note, however, that the image contents are only accessible from one OpenGL ES
context at a time.public void attachToGLContext(int texName)
detachFromGLContext()
. This new
texture is bound to the GL_TEXTURE_EXTERNAL_OES texture target.
This can be used to access the SurfaceTexture image contents from multiple OpenGL ES
contexts. Note, however, that the image contents are only accessible from one OpenGL ES
context at a time.texName
- The name of the OpenGL ES texture that will be created. This texture name
must be unusued in the OpenGL ES context that is current on the calling thread.public void getTransformMatrix(float[] mtx)
mtx
- the array into which the 4x4 matrix will be stored. The array must have exactly
16 elements.public long getTimestamp()
public void release()
public boolean isReleased()
protected void finalize() throws Throwable
Object
finalize
method to dispose of
system resources or to perform other cleanup.
The general contract of finalize
is that it is invoked
if and when the JavaTM virtual
machine has determined that there is no longer any
means by which this object can be accessed by any thread that has
not yet died, except as a result of an action taken by the
finalization of some other object or class which is ready to be
finalized. The finalize
method may take any action, including
making this object available again to other threads; the usual purpose
of finalize
, however, is to perform cleanup actions before
the object is irrevocably discarded. For example, the finalize method
for an object that represents an input/output connection might perform
explicit I/O transactions to break the connection before the object is
permanently discarded.
The finalize
method of class Object
performs no
special action; it simply returns normally. Subclasses of
Object
may override this definition.
The Java programming language does not guarantee which thread will
invoke the finalize
method for any given object. It is
guaranteed, however, that the thread that invokes finalize will not
be holding any user-visible synchronization locks when finalize is
invoked. If an uncaught exception is thrown by the finalize method,
the exception is ignored and finalization of that object terminates.
After the finalize
method has been invoked for an object, no
further action is taken until the Java virtual machine has again
determined that there is no longer any means by which this object can
be accessed by any thread that has not yet died, including possible
actions by other objects or classes which are ready to be finalized,
at which point the object may be discarded.
The finalize
method is never invoked more than once by a Java
virtual machine for any given object.
Any exception thrown by the finalize
method causes
the finalization of this object to be halted, but is otherwise
ignored.
public boolean isSingleBuffered()