I'm currently working on an App, that transforms a RGB picture to YV12, converts it to NV12 and then back to RGB.
I'm getting the following error on my conversion: http://www.pic-upload.de/view-21874004/ConversionError.jpg.html
So the left side is, what I want. A simple blue color. The right side displays what I'm getting. It looks like, there is way too much green in the conversion result.
Here's the code that transforms the rgb to yv12:
__global__ void RGBtoYV12(unsigned char* yuv, unsigned char* pData)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int width = gridDim.x * blockDim.x * 1.5;
int iwidth = gridDim.x;
int rgbID = i * 4;
int upos = blockDim.x * gridDim.x;
int vpos = upos + upos / 4;
int col = i % iwidth;
int row = i / iwidth; //bzw. threadIdx.x;
int r = pData[rgbID], g = pData[rgbID+1], b = pData[rgbID+2];
//Y
unsigned char y = 0.299 * r + 0.587 * g + 0.114 * b;
yuv[upos - (row+1)*iwidth + col] = y;
if ( !((i/gridDim.x)%2) && !(i%2))
{
//YV12
// U
yuv[width - ( (iwidth/2) * ((row/2)+1) - ((col/2)+1) )] = 0.493 * (b - y);//((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
// V
yuv[vpos - ( (iwidth/2) * ((row/2)+1) - ((col/2)+1) )] = 0.887 * (r - y); //((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
}
}
The conversion from NV12 is processed like this:
__global__ void NV12toRGB(unsigned char* nv12, unsigned char* rgba, int decodedPitch)
{
int ix = blockIdx.x * blockDim.x + threadIdx.x;
int iy = blockIdx.y * blockDim.y + threadIdx.y;
int i = iy * decodedPitch + ix;
int rgbStart = (iy * gridDim.x * blockDim.x + ix) * 4;
int quadX = (ix / 2);
int quadY = (iy / 2);
int uvAdr = decodedPitch / 2 * quadY + quadX;
int uvStart = decodedPitch * gridDim.y * blockDim.y;
int y = nv12[i];
int u = nv12[uvStart + 2 * uvAdr];
int v = nv12[uvStart + 2 * uvAdr + 1];
// R
int r = y + 1.13983 * v;
// G
int g = y - 0.39393 * u - 0.58081 * v;
// B
int b = y + 2.028 * u;
rgba[rgbStart] = r;
rgba[rgbStart+1] = g;
rgba[rgbStart+2] = b;
rgba[rgbStart+3] = 255;
}
As you can see, I do the conversion with cuda on GPU. I think the indexation of the color-values is correct, but I don't know, what goes wrong with the color conversion. Any help or other conversion formulas, i could try out, would be much appreciated.
Greetings
You have floating point multiplications, but results declared as integers. You lose all the precision there. For example
int r = y + 1.13983 * v;
Replace this with
float r = y + 1.13983 * v;
There may be other issues as well, but this stands out.