Unity渲染iOS中的NV12格式数据---(下)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity渲染iOS中的NV12格式数据---(下)相关的知识,希望对你有一定的参考价值。

参考技术A 上一篇中我们提到先在ios端将NV12先转换成YUV,再传入Unity中转换成RGB,由于在iOS端转换过程是在CPU中进行的,效率较慢,一帧图像数据大概消耗20ms左右。因为Unity的shader转换是在GPU中进行,效率高,所以考虑将这一步骤也挪到Unity中进行。

需要更改的有两个步骤:

注意GL_LUMINANCE_ALPHA参数,我们先来看看百度对于glTexImage2D方法的介绍。

internalformat 指定纹理中的颜色组件。因为在上一篇中我们每个数据只包含Y、U、V中的一个方向的分量,所以我们使用GL_ALPHA,同理在shader中取值时也是通过alpha通道取值。这一次NV12格式的数据UV方向分量在一起,所以我们使用GL_LUMINANCE_ALPHA,灰度值和Alpha值,将U、V分别存入RGB和A中。

注意在取值时从rgb通道取出U方向分量,alpha通道取出V方向分量。

D3D处理2D图像: NV12格式及其转换

1. NV12格式介绍

YUV 4:2:0是视频和图片编码和解码最常用的输入和输出格式。而在D3D中NV12是支持最广泛的YUV 4:2:0格式,主要因为它在GPU中处理的效率最高,只有两个plane, 而且UVplane和Luminance(Y) plane的pitch(stride)相等,高度为前者一半,所以在很多场景都是可以一起处理,而不需要分为两个或者三个plane来分别进行操作,不管是渲染,拷贝,还是在graphic pipeline中通过映射成其他格式,都非常方便和高效。
反观其他的YUV格式,I420/IYUV, YV12/等,虽然在编码的时候是首选格式,但是在D3D中不支持,或者有很多限制,比如不能映射到CPU中进行操作。

图一

2. NV12在GPU中的布局

GPU为了处理数据的高效率,往往每次操作的内存可能需要对齐,比如2KB/16KB/32KB或者64KB等,这样数据传输和拷贝的速度更快,所以实际NV12格式的图像在显存中存放的布局和实际的大小可能不一样,比如一个HD视频解出来一帧图像,分辨率为1920x1080, Y和UV plane每行1920个byte,Y plane高为1080,而UV plane高为540,但是在不同的GPU中,实际存放布局可能完全不同,比如在AMD的GPU中,Y/UV plane的宽一般存为2048 byte(2K

以上是关于Unity渲染iOS中的NV12格式数据---(下)的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中的 NV12 到 RGB24 转换代码

随笔安卓平台YUV数据(NV12/I420)渲染

D3D处理2D图像: NV12格式及其转换

NV12格式转RGB的CUDA实现

Unity下如何实现RTMP或RTSP流播放和录制

C++ YUV420文件读取与显示,绘制矩形框,绘制线段(绘制直线),绘制多边形(常用YUV数据格式——YUV420P中的YU12与YUV420SP中的NV21)