1类结构
2.1作用
从Image Stream中捕获帧数据,用作OpenGLES的纹理,其中Image Stream来自相机预览或视频解码。
从SurfaceTexture对象中创建的Surface类对象可被用作下述类的输出目标: android.hardware.camera2, MediaCodec, MediaPlayer, 和 Allocation APIs。
当为旧的Camera API指定输出目标时,也可使用SurfaceTexture来代替SurfaceHolder。如果这样做的话,ImageStream将把所有帧都送到SurfaceTexure对象,而不是设备的显示视图。
2.2updateTexImage()
当updateTexImage()被调用时,SurfaceTexture对象所关联的OpenGLES中纹理对象的内容将被更新为Image Stream中最新的图片。
但是调用updateTexImage()方法可能会造成ImageStream中的某些帧被忽略。
SurfaceTexture对象可以在任何线程中创建。
但是,updateTexImage()方法只能在包OpenGLES环境的线程里调用,即Renderer接口所独立创建的线程当中。一般在onDrawFrame中调用updateTexImage()将数据绑定给OpenGLES对应的纹理对象。
注意,必须显示的调用updateTexImage()将数据更新到GL_OES_EGL_image_external类型的OpenGL ES纹理对象中后,SurfaceTexture才有空间来获取下一帧的数据。否则下一帧数据永远不会交给SurfaceTexture。
2.3getTransformMatrix()
当从OpenGL ES的纹理对象取样时,首先应该调用getTransformMatrix()来转换纹理坐标。
每次updateTexImage()被调用时,纹理矩阵都可能发生变化。所以,每次texture image被更新时,getTransformMatrix ()也应该被调用。
getTransformMatrix()得到的矩阵,将传统的形如(s,t,0,1的)OpenGL ES 二维纹理坐标列向量转换为纹理流中正确的采样位置。
例如,从图片的左下角取样,可使用获得的矩阵转换列向量(0,0,0,1)从而获取正确的位置;从图片的右上角取样,可使用获得的矩阵转换列向量(1,1,0,1)从而获取正确的位置。
2.4GL_TEXTURE_EXTERNAL_OES纹理类型
updateTexImage()方法会将ImageStream的图片数据更新到GL_OES_EGL_image_external类型的纹理中。
OpenGL ES中的纹理对象需要使用GL_TEXTURE_EXTERNAL_OES作为纹理类型,该类型在 GL_OES_EGL_image_external中定义,是OpenGL ES的扩展。
每当使用该类纹理对纹理对象进行绑定时,需使用GL_TEXTURE_EXTERNAL_OES而不是GL_TEXTURE_2D。
额外的,任何需要从该纹理类型采样的OpenGL ES 2.0版本的着色器,必须声明对该扩展的使用。例如,必须加入如下的指令:
"#extensionGL_OES_EGL_image_external : require"
着色器中对纹理采样器类型的声明应使用“samplerExternalOES”类型。
有如下例子:
private static final StringFRAGMENT_SHADER =
" #extensionGL_OES_EGL_image_external : require \n "
+" precision mediump float; \n "
+" uniform samplerExternalOESuTextureSampler; \n "
+”................//其余的定义和声明................”
2.5 SurfaceTexture.OnFrameAvailableListener
新的数据帧有效时的回调接口。接口方法:
void onFrameAvailable (SurfaceTexture surfaceTexture)
可调用SurfaceTexture.setOnFrameAvailableListener()方法来设置该监听器。
当数据帧有效时,即onFrameAvailable被调用时,可调用GLSurfaceView.requestRender(),来显示要求进行渲染,即触发Renderer的onDrawFrame()。