YV12转换到RGB32[]

       
       在做视频回调解码时,需要用到数据转换,找了很多,后来公司同事写了一个,基本上可以通用,发出来给大家分享下。
        /// <summary>
        /// 将YV12转换成RGB32
        /// </summary>
        /// <param name="pYU12">yv12数据</param>
        /// <param name="lPicHeight">图片高度</param>
        /// <param name="lPicWidth">图片宽度</param>
        /// <returns></returns>
        public static byte[] GetRgb32_From_Yv12(IntPtr pYV12, Int32 lPicHeight, Int32 lPicWidth)
        {
            // YUV平面
            byte[] pYPlaneByte = new byte[lPicHeight * lPicWidth];
            byte[] pUPlaneByte = new byte[(lPicHeight / 2) * (lPicWidth / 2)];
            byte[] pVPlaneByte = new byte[(lPicHeight / 2) * (lPicWidth / 2)];

            // 根据解码数据首地址及分量长度,进行地址偏移,获取各YUV分量的内存地址
            IntPtr pYPlaneAddr = (IntPtr)(pYV12.ToInt32() + 0);
            IntPtr pUPlaneAddr = (IntPtr)(pYV12.ToInt32() + lPicHeight * lPicWidth);
            IntPtr pVPlaneAddr = (IntPtr)(pYV12.ToInt32() + lPicHeight * lPicWidth + (lPicHeight / 2) * (lPicWidth / 2));

            // 将YUV数据从非托管内存指针复制到托管 8 位无符号整数数组。
            Marshal.Copy(pYPlaneAddr, pYPlaneByte, 0, lPicHeight * lPicWidth);
            Marshal.Copy(pUPlaneAddr, pUPlaneByte, 0, (lPicHeight / 2) * (lPicWidth / 2));
            Marshal.Copy(pVPlaneAddr, pVPlaneByte, 0, (lPicHeight / 2) * (lPicWidth / 2));

            //YV12转换到RGB32
            byte[] Rgba32 = GetRgb32_From_Yv12(pYPlaneByte, pUPlaneByte, pVPlaneByte, lPicHeight, lPicWidth);

            return Rgba32;
        }
        /// <summary>
        /// YUV12转RGB32
        /// </summary>
        /// <param name="pYPlaneByte"></param>
        /// <param name="pUPlaneByte"></param>
        /// <param name="pVPlaneByte"></param>
        /// <param name="lPicHeight"></param>
        /// <param name="lPicWidth"></param>
        /// <returns></returns>
        public static byte[] GetRgb32_From_Yv12(byte[] pYPlaneByte, byte[] pUPlaneByte, byte[] pVPlaneByte, Int32 lPicHeight, Int32 lPicWidth)
        {

            int picSize = lPicWidth * lPicHeight;

            byte[] pRrgaByte = new byte[picSize * 4];
            int A = 0;

            for (int iRow = 0; iRow < lPicHeight; iRow++)
            {
                for (int jCol = 0; jCol < lPicWidth; jCol++)
                {
                    int Y = pYPlaneByte[iRow * lPicWidth + jCol];
                    int U = pUPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)];
                    int V = pVPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)];

                    int R = Y + (U - 128) + (((U - 128) * 103) >> 8);
                    int G = Y - (((V - 128) * 88) >> 8) - (((U - 128) * 183) >> 8);
                    int B = Y + (V - 128) + (((V - 128) * 198) >> 8);

                    R = Math.Max(0, Math.Min(255, R));
                    G = Math.Max(0, Math.Min(255, G));
                    B = Math.Max(0, Math.Min(255, B));

                    pRrgaByte[4 * (iRow * lPicWidth + jCol) + 0] = Convert.ToByte(B);
                    pRrgaByte[4 * (iRow * lPicWidth + jCol) + 1] = Convert.ToByte(G);
                    pRrgaByte[4 * (iRow * lPicWidth + jCol) + 2] = Convert.ToByte(R);
                    pRrgaByte[4 * (iRow * lPicWidth + jCol) + 3] = Convert.ToByte(A);
                    //pRrgaByte[4 * (iRow * lPicWidth + jCol) + 0] = Convert.ToByte(R);
                    //pRrgaByte[4 * (iRow * lPicWidth + jCol) + 1] = Convert.ToByte(G);
                    //pRrgaByte[4 * (iRow * lPicWidth + jCol) + 2] = Convert.ToByte(B);
                    //pRrgaByte[4 * (iRow * lPicWidth + jCol) + 3] = Convert.ToByte(A);
                }
            }

            return pRrgaByte;
        }

 
 
 
 
 
发布了20 篇原创文章 · 获赞 5 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/mt122/article/details/7301096
今日推荐