• NV12格式转RGB的CUDA实现


     NV12格式是yuv420格式的一种,NV12格式的u,v排布顺序为交错排布,假如一幅图像尺寸为W*H,则先Y分量有W*H个,然后U分量和V分量交错排布,U分量和V分量各有W*H/4个,U,V加起来总数是Y分量的一半。

    NV12内存YUV分量排布如下所示:

     下面是CUDA实现的NV12格式到BGR格式的转换代码。StepY,StepUV分别为ffmpeg解码出的源数据中的Y分量一行的宽度和UV分量一行的宽度,比实际的图像宽度要大。

    __global__ void YCrCb2RGBConver(uchar *pYdata, uchar *pUVdata,int stepY, int stepUV, uchar *pImgData, int width, int height, int channels)
    {
        const int tidx = blockIdx.x * blockDim.x + threadIdx.x;
        const int tidy = blockIdx.y * blockDim.y + threadIdx.y;
    
        if (tidx < width && tidy < height)
        {
            int indexY, indexU, indexV;
            uchar Y, U, V;
            indexY = tidy * stepY + tidx;    
            Y = pYdata[indexY];
    
            if (tidx % 2 == 0)
            {
                indexU = tidy / 2 * stepUV + tidx;
                indexV = tidy / 2 * stepUV + tidx + 1;
                U = pUVdata[indexU];
                V = pUVdata[indexV];
            }
            else if (tidx % 2 == 1)
            {
                indexV = tidy / 2 * stepUV + tidx;
                indexU = tidy / 2 * stepUV + tidx - 1;
                U = pUVdata[indexU];
                V = pUVdata[indexV];
            }
    
            pImgData[(tidy*width + tidx) * channels + 2] = uchar (Y + 1.402 * (V - 128));
            pImgData[(tidy*width + tidx) * channels + 1] = uchar (Y - 0.34413 * (U - 128) - 0.71414*(V - 128));
            pImgData[(tidy*width + tidx) * channels + 0] = uchar (Y + 1.772*(U - 128));
        }
    }

    CPU版本如下:

    void YCrCb2RGBConver(uchar *pYdata, uchar *pUVdata, int stepY, int stepUV, uchar *pImgData, int width, int height, int channels)
    {
    
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                int indexY, indexU, indexV;
                uchar Y, U, V;
                indexY = i * stepY + j;
                Y = pYdata[indexY];
    
                if (j % 2 == 0)
                {
                    indexU = i / 2 * stepUV + j;
                    indexV = i / 2 * stepUV + j + 1;
                    U = pUVdata[indexU];
                    V = pUVdata[indexV];
                }
                else if (j % 2 == 1)
                {
                    indexV = i / 2 * stepUV + j;
                    indexU = i / 2 * stepUV + j - 1;
                    U = pUVdata[indexU];
                    V = pUVdata[indexV];
                }
    
                pImgData[(i*width + j) * channels + 2] = uchar(Y + 1.402 * (V - 128));
                pImgData[(i*width + j) * channels + 1] = uchar(Y - 0.34413 * (U - 128) - 0.71414*(V - 128));
                pImgData[(i*width + j) * channels + 0] = uchar(Y + 1.772*(U - 128));
            }
        }
    }
  • 相关阅读:
    Webpack常用模块加载器Loader
    CSS动画 关键帧
    React 入门(6): 路由 React-Router
    React 入门(5): 引入JSX 研究JSX的createElement实现
    webpack标准模块 npm通用模块
    常用库的CDN引入
    使用codesandbox.io开启Web云开发
    css-loader + style-loader 模块化css
    React 入门(4): 单文件组件 CSS-Modules
    openldap主从数据同步-基于debain 9
  • 原文地址:https://www.cnblogs.com/riddick/p/7724877.html
Copyright © 2020-2023  润新知