2017-04-26 163 views
2

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

#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)是坐标矩阵,所以ÿ应为(X,Y)中,u应当是( (x/2)* 2,H + y/2),v应该接近u,((x/2)* 2 + 1,H + y/2)。听起来像这个逻辑是错误的!

回答

2

两个错误需要修正:

  1. -1应为〜1因为x & -1只是等于x,但X &〜1将屏蔽掉最后一位所以保持价值甚至。
  2. yuv矩阵大小不正确。由于uv矢量存储在y数据的末尾,因此总矩阵大小应为W * H * 3/2。

应用这两个更改后,它工作正常。 的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; 
} 
+0

哎呀,-1表示0xFFFFFFFF的,所以和-1等于什么都不做。 – lucky1928