zoukankan      html  css  js  c++  java
  • 直接操作 SDL_Overlay YUV叠加上的像素

    根据这篇解码出yuv数据后

    海思h264解码库

    y,u,v数据全部存进数组内,      
     
     IntPtr y = _decodeFrame.pY;
                    IntPtr v = _decodeFrame.pV;
                    IntPtr u = _decodeFrame.pU;
                    byte[] ys = new byte[yLength];
                    Marshal.Copy(y, ys, 0, yLength);
                    byte[] vs = new byte[uLength];
                    Marshal.Copy(v, vs, 0, uLength);
                    byte[] us = new byte[uLength];
                    Marshal.Copy(u, us, 0, uLength);
     
    rgb转yuv转换矩阵C++,网上其他的不能用
    //转换矩阵
    #define MY(a,b,c) (( a*  0.2989  + b*  0.5866  + c*  0.1145))
    #define MU(a,b,c) (( a*(-0.1688) + b*(-0.3312) + c*  0.5000 + 128))
    #define MV(a,b,c) (( a*  0.5000  + b*(-0.4184) + c*(-0.0816) + 128))
     
     简单写个画线的函数以说明,遍历像素修改效率很低      1920为视频宽  1080p        
     
    private void drawLineYUV(Point pnt1, Point pnt2, ref byte[] ys, ref byte[] vs, ref byte[] us, byte R, byte G, byte B)
            {
                //y1 = k x1 + b  b = y1 - k x1  
                //    y2 = k x2 + b k = (y2 - b)/ x2      k = (y2 - y1 - k x1)/ x2
                //(x-x1)/(x2-x1)=(y-y1)/(y2-y1)
                int x1 = pnt1.X;
                int x2 = pnt2.X;
                int y1 = pnt1.Y;
                int y2 = pnt2.Y;
                double k = 1;
                double b = 0;
                if (x1 == x2)
                {
                    int ymin = y1, ymax = y2;
                    if (y1 > y2)
                    {
                        ymin = y2;
                        ymax = y1;
                    }
                    for (int h = ymin; h <= ymin; h++)
                    {
                        int Y = (int)(0.299 * R + 0.587 * G + 0.114 * B);
                        ys[h * 1920 + x1] = (byte)Y;
                        vs[(int)((h * 1920 + x1 * 2) / 4)] = (byte)(int)(R * 0.5000 + G * (-0.4184) + B * (-0.0816) + 128);
                        us[(int)((h * 1920 + x1 * 2) / 4)] = (byte)(int)(R * (-0.1688) + G * (-0.3312) + B * 0.5000 + 128);
                    }
                }
                else
                {
                    int ymin = y1, ymax = y2;
                    if (y1 > y2)
                    {
                        ymin = y2;
                        ymax = y1;
                    }
                    int xmin = x1, xmax = x2;
                    if (y1 > y2)
                    {
                        xmin = x2;
                        xmax = x1;
                    }
     
                    k = (double)(ymax - ymin) / (double)(xmax - xmin);
                    b = ymin - k * xmin;
     
                    for (int w = xmin; w < xmax; w++)
                    {
                        for (int h = ymin; h < ymax; h++)
                        {
                            if (Math.Abs(h - k * w - b) < 2)
                            {
                                int Y = (int)(0.299 * R + 0.587 * G + 0.114 * B);
                                ys[h * 1920 + w] = (byte)Y;
     
                                vs[(int)((h * 1920 + w * 2) / 4)] = (byte)(int)(R * 0.5000 + G * (-0.4184) + B * (-0.0816) + 128);
     
                                us[(int)((h * 1920 + w * 2) / 4)] = (byte)(int)(R * (-0.1688) + G * (-0.3312) + B * 0.5000 + 128);
                            }
                        }
                    }
                }
            }
     
  • 相关阅读:
    Linux Core Dump
    ODP.NET Managed正式推出
    获取EditText的光标位置
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
  • 原文地址:https://www.cnblogs.com/jhlong/p/5433864.html
Copyright © 2011-2022 走看看