what
1. SurfaceTexture用来捕获视频流中的图像帧,视频流可以是相机预览或者是视频解码数据。
里边承接图像数据的也是GraphicBuffer, GLConsumer 作为其BufferQueue的消费方,取得数据后可以通过eglImage挂到opengles texture 里边对其做纹理采样。
how
1. 就用法来讲,主要就是有数据后BufferQueue Producer在queueBuffer时 回调应用的onFrameAvailable(),应用自己决定是否、何时调用updateTetxtureImage()去做纹理绑定、采样
2. BufferQueue:
native层,在SurfaceTexture native对象 创建前创建了生产者和消费者;
消费者作为其构造函数传入给SurfaceTexture;
生产者作为全局变量保存,同时也保存在SurfaceTexture java 对象的mProducer里边 ;
3.GraphicBuffer的获取
生产方:通过 SurfaceTexture_getProducer()获取到BufferQueueProducer ;
消费方:SurfaceTexture 在UpdateTexImage()时去acquireBuffer
相关技术点
SurfaceView
1. what
只拥有BufferQueue的生产端,消费端为SurfaceFlinger,渲染后必须上屏。
TextureView
1. what
由于其里边拥有SurfaceTexture, 可用于离屏渲染,拥有BufferQueue的生产端和消费端,
生产端可为camera、MediaCodec、任意render 模块, 可以跨进程(底层是GraphicBuffer嘛),消费端为SurfaceTexture GLConsumer, 可对图像做二次处理。
YUV
1. why
一般情况下SurfaceTexture承载的数据都是YUV类型(来自mediacodec、camera),有必要简单说下。
2. what
一种图像数据编码格式,常用的为YUV420,俗称I420,
各格式说明:
4:4:4 ,完全取样
4:2:2 ,2:1水平取样,垂直完全采样
4:2:0 ,2:1水平取样,垂直2:1采样
4:1:1 ,4:1水平取样,垂直完全采样
3. 格式 packed,planar、semi-planar
packed:不带后缀,如YUV420,数据以逐像素为单位排列,如
planar:带后缀P,如YUV420P,Y、U、V 分开存储,如
semi-planar:带后缀SP,如YUV420SP,UV交叉存储,与Y分开存储,如
这边可能要注意,排列可能为YYY.....UVUV, 或YYY...VUVU,即UV的第一个值到底是U还是V,
前者准确点叫YUV,后者叫YVU,又如 NV12、NV21 哈哈哈是不是有点迷糊了😜,
4. rgb与yuv的转换
一般可以用gpu,做个纹理采样去转,若gpu不支持硬件转换,需自己写shader;
有的gpu硬件支持直接转,如高通平台adreno