使用unity3D点播预览多路rtsp视频流

      因为最近项目中有需求通过unity3D接入很多路rtsp视频流,为了更大的利用GPU,所以对每路rtsp视频流进行硬解码后变成NV12的视频帧,使用unity3D shader对其进行显示。

      笔者对opengl和opengles比较熟悉,所以对于大同小异的unity3D的shader,基本也可以很快上手。

      直奔主题吧,首先使用unity3D创建Unlit shader,创建RowImage,创建Material,shader绑定Material,Material绑定RowImage。

      NV12根据其视频的内存布局格式,我们需要定义2个2D的纹理,一个去存放Y数据,其数据大小为视频的height*width,一个存放UV格式,其大小为height*width/2,如下:

     private Texture2D texY, texU;

     texY = new Texture2D(width, height, TextureFormat.Alpha8, false);
     texU = new Texture2D(width/2, height/2, TextureFormat.RG16, false);

     因为texU 纹理存放的实uv交替数据,所以,我们用TextureFormat.RG16,表示一个单元里存放一个u分量和一个V分量。

      在update里加载数据显示,代码如下:

 texY.LoadRawTextureData(rawdata.ydata);
 texY.Apply();
            
 texU.LoadRawTextureData(rawdata.uvdata);
 texU.Apply();

 rawImage.texture = texY;
 rawImage.material.SetTexture("_UTex", texU);

 以上是关键的c#代码,shader就很简单了,同样定义2个2D纹理。代码如下:

			sampler2D _MainTex;
			sampler2D _UTex;

然后再fragment着色器里通过2个纹理把Y和UV数据采样出来,转化为RGB即可,代码如下:

fixed4 frag (v2f i) : SV_Target
            {
                fixed4  col;
                float  y = tex2D(_MainTex, i.uv).a;
                fixed4  uvs = tex2D(_UTex, i.uv);
                float  u = uvs.r - 0.5;
                float  v = uvs.g - 0.5;


                float r = y + 1.403 * v;
                float g = y - 0.344  * u - 0.714 * v;
                float b = y + 1.770  * u;

                col.rgba = float4(r, g, b, 1.0f);
                return col;
            }

最后实现效果如下:

使用unity3D点播预览多路rtsp视频流_第1张图片

太忙,稍后我会把demo发布。

这是我们的网站 www.founu.com,欢迎大家交流合作。

你可能感兴趣的:(unity3D,shader)