简体   繁体   English

android-Renderscript将NV12 yuv转换为RGB

[英]android - Renderscript to convert NV12 yuv to RGB

I write below code to convert NV12 yuv to RGB but the color is not correct. 我写下面的代码将NV12 yuv转换为RGB,但颜色不正确。 yuv2rgb.rs 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 code: 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;
}

I guess the (x,y) is the matrix coordinate, so y should be at (x,y), u should be at ((x/2)*2,H + y/2),v should be next to u, ((x/2)*2+1,H + y/2). 我猜想(x,y)是矩阵坐标,所以y应该在(x,y)处,u应该在((x / 2)* 2,H + y / 2),v应该在u旁边,((x / 2)* 2 + 1,H + y / 2)。 Sounds like this logic is wrong! 听起来这种逻辑是错误的!

Two errors need to be fixed: 需要修复两个错误:

  1. -1 should be ~1 since x & -1 just equal to x, but x & ~1 will mask out the last bit so keep the value even. -1应该为〜1,因为x&-1刚好等于x,但是x&〜1将掩盖最后一位,因此请保持值均匀。
  2. The yuv matrix size not correct. yuv矩阵大小不正确。 since uv vector is stored at the end of the y data, so the total matrix size should be W*H*3/2. 由于uv向量存储在y数据的末尾,因此总矩阵大小应为W * H * 3/2。

After apply these two changes, it works fine. 应用这两个更改后,它可以正常工作。 java: 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 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM