public class SurfaceTexture
extends Object
java.lang.Object | |
↳ | android.graphics.SurfaceTexture |
从图像流中捕获帧作为OpenGL ES纹理。
图像流可能来自相机预览或视频解码。 甲Surface
从表面纹理创建可以用作输出目的地为android.hardware.camera2
, MediaCodec
, MediaPlayer
,和Allocation
的API。 当updateTexImage()
被调用时,表面纹理创建时所指定的纹理对象的内容进行更新,以包含来自图像流最近的图像。 这可能会导致流的某些帧被跳过。
指定较旧的Camera
API的输出目标时,也可以使用SurfaceTexture来代替Camera
。 这样做会导致图像流中的所有帧被发送到SurfaceTexture对象而不是设备的显示。
从纹理采样时,首先应使用通过getTransformMatrix(float[])
查询的矩阵来转换纹理坐标。 变换矩阵可能每次调用updateTexImage()
时updateTexImage()
更改,所以每次纹理图像更新时都应该重新查询。 该矩阵将s和t在包含区间[0,1]上的传统2D OpenGL ES纹理坐标列向量形式(s,t,0,1)转换为流动纹理中正确的采样位置。 这种变换补偿了图像流源的任何属性,使其看起来不同于传统的OpenGL ES纹理。 例如,可以通过使用查询矩阵变换列向量(0,0,0,1)来完成从图像的左下角采样,而从图像的右上角采样可以通过变换( 1,1,1,0,1)。
纹理对象使用GL_TEXTURE_EXTERNAL_OES纹理目标,该目标由GL_OES_EGL_image_external OpenGL ES扩展定义。 这限制了纹理的使用方式。 每次绑定纹理时,它都必须绑定到GL_TEXTURE_EXTERNAL_OES目标,而不是GL_TEXTURE_2D目标。 此外,从纹理采样的任何OpenGL ES 2.0着色器必须使用例如“#extension GL_OES_EGL_image_external:require”指令声明其使用此扩展名。 这些着色器还必须使用samplerExternalOES GLSL采样器类型访问纹理。
SurfaceTexture对象可以在任何线程上创建。 updateTexImage()
只能在包含纹理对象的OpenGL ES上下文的线程上调用。 框架可用的回调在任意线程上调用,因此除非特别小心,否则不应直接从回调调用updateTexImage()
。
Nested classes |
|
---|---|
interface |
SurfaceTexture.OnFrameAvailableListener 回调接口用于通知新的流帧可用。 |
class |
SurfaceTexture.OutOfResourcesException 此类已在API级别19中弃用。不再抛出。 |
Public constructors |
|
---|---|
SurfaceTexture(int texName) 构建一个新的SurfaceTexture,将图像传输到给定的OpenGL纹理。 |
|
SurfaceTexture(int texName, boolean singleBufferMode) 构建一个新的SurfaceTexture,将图像传输到给定的OpenGL纹理。 |
Public methods |
|
---|---|
void |
attachToGLContext(int texName) 将SurfaceTexture附加到调用线程上当前的OpenGL ES上下文。 |
void |
detachFromGLContext() 从拥有OpenGL ES纹理对象的OpenGL ES上下文中分离SurfaceTexture。 |
long |
getTimestamp() 检索与最近一次调用updateTexImage所设置的纹理图像关联的时间戳。 |
void |
getTransformMatrix(float[] mtx) 检索与最近一次调用updateTexImage设置的纹理图像关联的4x4纹理坐标变换矩阵。 |
void |
release() release()释放所有缓冲区并将SurfaceTexture置于'废弃'状态。 |
void |
releaseTexImage() 释放纹理内容。 |
void |
setDefaultBufferSize(int width, int height) 设置图像缓冲区的默认大小。 |
void |
setOnFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener listener) 当一个新的图像帧可用于SurfaceTexture时,注册一个将被调用的回调函数。 |
void |
setOnFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener listener, Handler handler) 当一个新的图像帧可用于SurfaceTexture时,注册一个将被调用的回调函数。 |
void |
updateTexImage() 将纹理图像更新为图像流中最新的帧。 |
Protected methods |
|
---|---|
void |
finalize() 当垃圾收集确定没有更多对该对象的引用时,由对象上的垃圾回收器调用。 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
SurfaceTexture (int texName)
构建一个新的SurfaceTexture,将图像传输到给定的OpenGL纹理。
Parameters | |
---|---|
texName |
int : the OpenGL texture object name (e.g. generated via glGenTextures) |
Throws | |
---|---|
|
If the SurfaceTexture cannot be created. |
SurfaceTexture (int texName, boolean singleBufferMode)
构建一个新的SurfaceTexture,将图像传输到给定的OpenGL纹理。 在单缓冲模式下,应用程序负责序列化对图像内容缓冲区的访问。 每次更新图像内容时,必须在图像内容生产者取得缓冲区所有权之前调用releaseTexImage()
方法。 例如,产生的图像内容与NDK ANativeWindow_lock和ANativeWindow_unlockAndPost功能时, releaseTexImage()
必须在每个ANativeWindow_lock之前被调用,或者调用将失败。 使用OpenGL ES生成图像内容时,必须在第一个OpenGL ES函数调用每个帧之前调用releaseTexImage()
。
Parameters | |
---|---|
texName |
int : the OpenGL texture object name (e.g. generated via glGenTextures) |
singleBufferMode |
boolean : whether the SurfaceTexture will be in single buffered mode. |
Throws | |
---|---|
|
If the SurfaceTexture cannot be created. |
void attachToGLContext (int texName)
将SurfaceTexture附加到调用线程上当前的OpenGL ES上下文。 将创建一个新的OpenGL ES纹理对象,并使用上次调用detachFromGLContext()
时当前的SurfaceTexture图像框进行detachFromGLContext()
。 这个新纹理绑定到GL_TEXTURE_EXTERNAL_OES纹理目标。 这可以用来从多个OpenGL ES上下文访问SurfaceTexture图像内容。 但请注意,图像内容一次只能从一个OpenGL ES上下文访问。
Parameters | |
---|---|
texName |
int : 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. |
void detachFromGLContext ()
从拥有OpenGL ES纹理对象的OpenGL ES上下文中分离SurfaceTexture。 这个调用必须在调用线程上使用当前的OpenGL ES上下文。 作为此调用的结果,OpenGL ES纹理对象将被删除。 调用此方法后,所有呼叫updateTexImage()
会抛出IllegalStateException
直到成功调用attachToGLContext(int)
而成。 这可以用来从多个OpenGL ES上下文访问SurfaceTexture图像内容。 但请注意,图像内容一次只能从一个OpenGL ES上下文访问。
long getTimestamp ()
检索与最近一次调用updateTexImage所设置的纹理图像关联的时间戳。 这个时间戳以纳秒为单位,通常单调增加。 时间戳不应受到时间调整的影响,并且摄像机应严格单调,但对于MediaPlayer而言,可能会在设置位置时重置。 时间戳的具体含义和零点取决于向SurfaceTexture提供图像的源。 除非图像源另有规定,否则通常无法在SurfaceTexture实例之间或跨多个程序调用比较时间戳。 它主要用于确定后续帧之间的时间偏移。
Returns | |
---|---|
long |
void getTransformMatrix (float[] mtx)
检索与最近一次调用updateTexImage设置的纹理图像关联的4x4纹理坐标变换矩阵。 该变换矩阵将形式(s,t,0,1)与包含范围[0,1]中的s和t的二维齐次纹理坐标映射到应该用于从纹理对该位置进行采样的纹理坐标。 在该变换的范围之外采样纹理是未定义的。 该矩阵按列主存储顺序存储,以便通过glLoadMatrixf或glUniformMatrix4fv函数直接传递给OpenGL ES。
Parameters | |
---|---|
mtx |
float : the array into which the 4x4 matrix will be stored. The array must have exactly 16 elements. |
void release ()
release()释放所有缓冲区并将SurfaceTexture置于'废弃'状态。 一旦进入这种状态,SurfaceTexture就永远不会离开它。 处于“废弃”状态时,IGraphicBufferProducer接口的所有方法都将失败,并显示NO_INIT错误。 请注意,在调用此方法时,如果缓冲区上有其他引用(例如,如果缓冲区被客户端或OpenGL ES作为纹理引用),则会从SurfaceTexture的角度释放所有缓冲区,则那些缓冲区将保持分配。 在完成SurfaceTexture时总是调用此方法。 如果不这样做,可能会导致资源重新分配大量时间。
void releaseTexImage ()
释放纹理内容。 这在单缓冲模式下是需要的,以允许图像内容生产者获得图像缓冲区的所有权。 欲了解更多信息,请参阅SurfaceTexture(int, boolean)
。
void setDefaultBufferSize (int width, int height)
设置图像缓冲区的默认大小。 图像生成器可能会覆盖缓冲区大小,在这种情况下将使用生产者设置缓冲区大小,而不是此方法设置的默认大小。 基于视频和相机的图像制作者都会覆盖大小。 此方法可用于在使用Canvas
(通过lockCanvas(Rect)
)或OpenGL ES(通过EGLSurface)生成图像时设置图像大小。 下一次图像制作者请求缓冲区填充时,新的默认缓冲区大小将生效。 对于Canvas
这将是下一次lockCanvas(Rect)
。 对于OpenGL ES,应该销毁EGLSurface(通过eglDestroySurface),使其不是当前的(通过eglMakeCurrent),然后重新创建(通过eglCreateWindowSurface)以确保新的默认大小已生效。 宽度和高度参数不得大于GL_MAX_VIEWPORT_DIMS和GL_MAX_TEXTURE_SIZE的最小值(请参阅glGetIntegerv
)。 在调用updateTexImage()之前,可能无法报告由于尺寸无效导致的错误。
Parameters | |
---|---|
width |
int
|
height |
int
|
void setOnFrameAvailableListener (SurfaceTexture.OnFrameAvailableListener listener)
当一个新的图像帧可用于SurfaceTexture时,注册一个将被调用的回调函数。
可以在任意线程上调用 updateTexImage()
,因此在没有首先将OpenGL ES上下文绑定到调用回调的线程的情况下调用 updateTexImage()
是不安全的。
Parameters | |
---|---|
listener |
SurfaceTexture.OnFrameAvailableListener : The listener to use, or null to remove the listener. |
void setOnFrameAvailableListener (SurfaceTexture.OnFrameAvailableListener listener, Handler handler)
当一个新的图像帧可用于SurfaceTexture时,注册一个将被调用的回调函数。
如果指定了处理程序,则将在该处理程序的线程上调用回调。 如果没有指定处理程序,那么可以在任意线程上调用回调函数,因此在没有首先将OpenGL ES上下文绑定到调用回调的线程的情况下调用updateTexImage()
是不安全的。
Parameters | |
---|---|
listener |
SurfaceTexture.OnFrameAvailableListener : The listener to use, or null to remove the listener. |
handler |
Handler : The handler on which the listener should be invoked, or null to use an arbitrary thread. |
void updateTexImage ()
将纹理图像更新为图像流中最新的帧。 这只能在调用线程上拥有纹理的OpenGL ES上下文时调用。 它将隐含地将其纹理绑定到GL_TEXTURE_EXTERNAL_OES纹理目标。
void finalize ()
当垃圾收集确定没有更多对该对象的引用时,由对象上的垃圾回收器调用。 子类会覆盖finalize
方法以处置系统资源或执行其他清理。
的常规协定finalize
是,它被调用,如果当在Java TM虚拟机已确定不再有由该目的可以通过还没有死亡,除了作为一个动作的结果的任何线程访问的任何手段取决于某些其他可以完成的对象或类别的最终定稿。 该finalize
方法可以采取任何行动,包括再制作该对象提供给其他线程; 然而, finalize
的通常目的是在对象被不可撤销地丢弃之前执行清理操作。 例如,表示输入/输出连接的对象的finalize方法可能会执行显式I / O事务,以在永久丢弃该对象之前中断连接。
类Object
的finalize
方法Object
执行特殊操作; 它只是正常返回。 Object
子类可能会覆盖此定义。
Java编程语言不保证哪个线程将为任何给定的对象调用finalize
方法。 但是,保证调用finalize的线程在调用finalize时不会保留任何用户可见的同步锁。 如果finalize方法引发未捕获的异常,则忽略该异常,并终止该对象的终止。
在针对一个对象调用了 finalize
方法之后,在Java虚拟机再次确定不再有任何方式可以通过任何尚未死亡的线程访问此对象的方法之前,不会采取进一步的操作,包括可能的操作通过准备完成的其他对象或类别,此时该对象可能被丢弃。
对于任何给定的对象,Java虚拟机永远不会多次调用 finalize
方法。
finalize
方法引发的任何异常 finalize
导致终止此对象的终止,但会被忽略。
Throws | |
---|---|
Throwable |