android - Renderscript将NV12 yuv转换为RGB

时间:2017-04-26 18:39:24

标签: android renderscript

我写下面的代码将NV12 yuv转换为RGB,但颜色不正确。 yuv2rgb.rs

#pragma version(1)
#pragma rs java_package_name(com.example.myexam)
#pragma rs_fp_relaxed

rs_allocation gYUV;
uint32_t gW;
uint32_t gH;

uchar4 __attribute__((kernel)) YUV2RGB(uint32_t x,uint32_t y)
{
    uchar yps = rsGetElementAt_uchar(gYUV, x, y);
    uchar u = rsGetElementAt_uchar(gYUV,(x & ~1),gH + (y>>1));
    uchar v = rsGetElementAt_uchar(gYUV,(x & ~1)+1,gH + (y>>1));
    uchar4 rgb = rsYuvToRGBA_uchar4(yps, u, v);
    return rgb;
}

java代码:

public Bitmap NV12_toRGB(byte[] yuv,int W,int H) {
    RenderScript rs = RenderScript.create(this);
    Type.Builder yuvBlder = new Type.Builder(rs, Element.U8(rs))
            .setX(W).setY(H*3/2);
    Allocation allocIn = Allocation.createTyped(rs,yuvBlder.create(),Allocation.USAGE_SCRIPT);
    Type rgbType = Type.createXY(rs, Element.RGBA_8888(rs), W, H);
    Allocation allocOut = Allocation.createTyped(rs,rgbType,Allocation.USAGE_SCRIPT);

    ScriptC_yuv2rgb scriptC_yuv2rgb = new ScriptC_yuv2rgb(rs);
    scriptC_yuv2rgb.set_gW(W);
    scriptC_yuv2rgb.set_gH(H);
    allocIn.copyFrom(yuv);
    scriptC_yuv2rgb.set_gYUV(allocIn);
    scriptC_yuv2rgb.forEach_YUV2RGB(allocOut);

    Bitmap bmp = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
    allocOut.copyTo(bmp);

    allocIn.destroy();
    scriptC_yuv2rgb.destroy();
    return bmp;
}

我猜(x,y)是矩阵坐标,所以y应该是(x,y),你应该是((x / 2)* 2,H + y / 2),v应该是在你旁边,((x / 2)* 2 + 1,H + y / 2)。听起来这个逻辑错了!

1 个答案:

答案 0 :(得分:2)

需要修复两个错误:

    因为x& x,所以
  1. -1应为~1 -1恰好等于x,但x& 〜1将屏蔽最后一位,因此保持该值均匀。
  2. yuv矩阵大小不正确。由于紫外矢量存储在y数据的末尾,因此总矩阵大小应为W * H * 3/2。
  3. 应用这两个更改后,它可以正常工作。 的java:

    public Bitmap YUV_toRGB(byte[] yuv,int W,int H) {
            RenderScript rs = RenderScript.create(this);
            Type.Builder yuvBlder = new Type.Builder(rs, Element.U8(rs))
                    .setX(W).setY(H*3/2);
            Allocation allocIn = Allocation.createTyped(rs,yuvBlder.create(),Allocation.USAGE_SCRIPT);
            Type rgbType = Type.createXY(rs, Element.RGBA_8888(rs), W, H);
            Allocation allocOut = Allocation.createTyped(rs,rgbType,Allocation.USAGE_SCRIPT);
    
            ScriptC_yuv2rgb scriptC_yuv2rgb = new ScriptC_yuv2rgb(rs);
            allocIn.copyFrom(yuv);
            scriptC_yuv2rgb.set_gW(W);
            scriptC_yuv2rgb.set_gH(H);
            scriptC_yuv2rgb.set_gYUV(allocIn);
            scriptC_yuv2rgb.forEach_YUV2RGB(allocOut);
    
            Bitmap bmp = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
            allocOut.copyTo(bmp);
    
            allocIn.destroy();
            scriptC_yuv2rgb.destroy();
            return bmp;
        }
    

    yuv2rgb.rs

    #pragma version(1)
    #pragma rs java_package_name(com.example.myexam)
    #pragma rs_fp_relaxed
    
    rs_allocation gYUV;
    uint32_t gW;
    uint32_t gH;
    
    uchar4 __attribute__((kernel)) YUV2RGB(uint32_t x,uint32_t y)
    {
        uchar yps = rsGetElementAt_uchar(gYUV, x, y);
        uchar u = rsGetElementAt_uchar(gYUV,(x & ~1),gH + (y>>1));
        uchar v = rsGetElementAt_uchar(gYUV,(x & ~1)+1,gH + (y>>1));
        uchar4 rgb = rsYuvToRGBA_uchar4(yps, u, v);
        return rgb;
    }