static bool YV12_to_RGB32(unsigned char *pYV12, unsigned char *pRGB32, int iWidth, int iHeight)
{
if (!pYV12 || !pRGB32)
return false;
const long nYLen = long(iHeight * iWidth);
const int nHfWidth = (iWidth >> 1);
if (nYLen < 1 || nHfWidth < 1)
return false;
unsigned char *yData = pYV12;
unsigned char *vData = pYV12 + iWidth * iHeight + (iHeight / 2) * (iWidth / 2);
unsigned char *uData = pYV12 + iWidth * iHeight;
if (!uData || !vData)
return false;
int rgb[4];
int jCol, iRow;
for (iRow = 0; iRow < iHeight; iRow++)
{
for (jCol = 0; jCol < iWidth; jCol++)
{
rgb[3] = 1;
int Y = yData[iRow * iWidth + jCol];
int U = uData[(iRow / 2) * (iWidth / 2) + (jCol / 2)];
int V = vData[(iRow / 2) * (iWidth / 2) + (jCol / 2)];
int R = Y + (U - 128) + (((U - 128) * 103) >> 8);
int G = Y - (((V - 128) * 88) >> 8) - (((U - 128) * 183) >> 8);
int B = Y + (V - 128) + (((V - 128) * 198) >> 8);
// r分量值
R = R < 0 ? 0 : R;
rgb[2] = R > 255 ? 255 : R;
// g分量值
G = G < 0 ? 0 : G;
rgb[1] = G > 255 ? 255 : G;
// b分量值
B = B < 0 ? 0 : B;
rgb[0] = B > 255 ? 255 : B;
pRGB32[4 * (iRow * iWidth + jCol) + 0] = rgb[0];
pRGB32[4 * (iRow * iWidth + jCol) + 1] = rgb[1];
pRGB32[4 * (iRow * iWidth + jCol) + 2] = rgb[2];
pRGB32[4 * (iRow * iWidth + jCol) + 3] = rgb[3];
}
}
return true;
}
static int YV12ToBGR24_Native(unsigned char *pYV12, unsigned char *pRGB24, int iWidth, int iHeight)
{
if (!pYV12 || !pRGB24)
return FALSE;
const long nYLen = long(iHeight * iWidth);
const int nHfWidth = (iWidth >> 1);
if (nYLen < 1 || nHfWidth < 1)
return -1;
// yv12数据格式,其中Y分量长度为width * height, U和V分量长度都为width * height / 4
// |WIDTH |
// y......y--------
// y......y HEIGHT
// y......y
// y......y--------
// v..v
// v..v
// u..u
// u..u
unsigned char *yData = pYV12;
unsigned char *vData = &yData[nYLen];
unsigned char *uData = &vData[nYLen >> 2];
if (!uData || !vData)
return -1;
// Convert YV12 to RGB24
//
// formula
// [1 1 1 ]
// [r g b] = [y u-128 v-128] [0 0.34375 0 ]
// [1.375 0.703125 1.734375]
// another formula
// [1 1 1 ]
// [r g b] = [y u-128 v-128] [0 0.698001 0 ]
// [1.370705 0.703125 1.732446]
int rgb[3];
int i, j, m, n, x, y;
m = -iWidth;
n = -nHfWidth;
for (y = 0; y < iHeight; y++)
{
m += iWidth;
if (!(y % 2))
n += nHfWidth;
for (x = 0; x < iWidth; x++)
{
i = m + x;
j = n + (x >> 1);
rgb[2] = int(yData[i] + 1.370705 * (vData[j] - 128)); // r分量值
rgb[1] = int(yData[i] - 0.698001 * (uData[j] - 128) - 0.703125 * (vData[j] - 128)); // g分量值
rgb[0] = int(yData[i] + 1.732446 * (uData[j] - 128)); // b分量值
j = nYLen - iWidth - m + x;
i = (j << 1) + j;
for (j = 0; j < 3; j++)
{
if (rgb[j] >= 0 && rgb[j] <= 255)
pRGB24[i + j] = rgb[j];
else
pRGB24[i + j] = (rgb[j] < 0) ? 0 : 255;
}
}
}
return 0;
}