2017-04-26 190 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