Generic YUV Conversion
Generic YUV conversion provides the ability to convert any YUV format to any supported color space, using the YUV_PARAMS structure and adhering to the restrictions listed below. After defining the YUV format, you can proceed with the conversion normally, just like any other conversion. Use L_ClrConvert to perform the conversion and call L_ClrFree to free the conversion handle. Currently the conversion from any color space to Generic YUV is not supported.
Generic YUV conversion currently has the following restrictions:
1. |
No sub-sampling of Y is supported |
2. |
The number of Y elements must be a multiple of both U, and V. |
3. |
With non-planar formats, vertical sub-sampling of Y, U, and V is not supported. |
4. |
No alignment supported in planar format; line width must not contain additional bytes. |
5. |
The horizontal sub-sampling periods of U, and V must be multiples of each other, and the vertical sub-sampling periods of U, and V must be multiples of each other. |
Examples:
1. |
Converting Y41P to RGB using Generic YUV Conversion: |
L_VOID GenericY41PToRGB(L_UCHAR *pIn, L_UCHAR *pOut, L_INT nWidth, L_INT nHeight)
{
/*Declare a handle*/
HANDLE hClrHandle;
/*Declare a CONVERSION_PARAMS structure*/
CONVERSION_PARAMS cpParams;
/*Declare a YUV_PARAMS structure*/
YUV_PARAMS yuvParams;
/*Byte ordering of the format; for Y41P:
U0 Y0 V0 Y1 U4 Y2 V4 Y3 Y4 Y5 Y6 Y7
0 1 2 3 4 5 6 7 8 9 10 11
Put the Y component order first, then the U and V last as follows:
Y positions: 1,3,5,7,8,9,10,11
U positions: 0,4
V positions: 2,6 */
L_INT pOff[] = {1,3,5,7,8,9,10,11,0,4,2,6};
ZeroMemory (&cpParams, sizeof (CONVERSION_PARAMS));
/*Determine the size of the structure*/
yuvParams.uStructSize = sizeof(YUV_PARAMS);
/*Determine the horizontal sub-sampling of U */
yuvParams.nUh = 4;
/*Determine the vertical sub-sampling of U */
yuvParams.nUv = 1;
/*Determine the horizontal sub-sampling of V */
yuvParams.nVh = 4;
/*Determine the vertical sub-sampling of V */
yuvParams.nVv = 1;
/*Set the byte ordering*/
yuvParams.pOffsets = pOff;
/*The YUV values range*/
yuvParams.nRange = YUVRANGE_FULL;
/*This represents the macro pixels(smallest group of pixels allowed), which indicates how many actual pixels are in the macro pixel. This value is important only in non – planar format*/
yuvParams.nMacroPixel = 8;
/*This is a Boolean value that represents the type of the YUV format (Planar = TRUE, or non – Planar = FALSE.)*/
yuvParams.bPlanar =FALSE;
/*Fill the pYuvParams value with the address of the YUV_PARAMS structure*/
cpParams.pYuvParams = &yuvParams;
/*Determine the size of CONVERSION_PARAMS*/
cpParams.uStructSize = sizeof (CONVERSION_PARAMS);
/*Determine the type of conversion to be used in the conversion, for YUVGeneric, only use USE_BUILTIN*/
cpParams.nMethod = USE_BUILTIN;
/*Determine the type of conversion to be activated. For YUVGeneric,
only USE_BUILTIN*/
cpParams.nActiveMethod = USE_BUILTIN;
/*Initialize the conversion*/
L_ClrInit(&hClrHandle, CCS_YUV, CCS_RGB, &cpParams);
/*Convert the buffers pIn to pOut*/
L_ClrConvert(hClrHandle, pIn, pOut, nWidth, nHeight, 0, 0);
/*Free the handles*/
L_ClrFree(hClrHandle);
}
2. |
Converting YVU9 (Planar) to RGB using Generic YUV Conversion: |
L_VOID GenericYVU9ToRGB(L_UCHAR *pIn, L_UCHAR *pOut, L_INT nWidth, L_INT nHeight)
{
/*Declare a handle*/
HANDLE hClrHandle;
/*Declare a CONVERSION_PARAMS structure*/
CONVERSION_PARAMS cpParams;
/*Declare a YUV_PARAMS structure*/
YUV_PARAMS yuvParams;
/*This array of integers specifies the byte order of the yuv format. For planar formats it takes only a single value that represents the plane sequence in the buffer:
YUV, YVU, UYV, UVY, VYU, or VUY.*/
L_INT pOff[] = {PLANAR_YVU}; /*PLANAR_YVU means the Y plane comes first in the buffer, then the V plane, and the U plane is last*/
ZeroMemory (&cpParams, sizeof (CONVERSION_PARAMS));
/*Determine the size of the structure*/
yuvParams.uStructSize = sizeof(YUV_PARAMS);
/*Determine the horizontal sub-sampling of U*/
yuvParams.nUh = 4;
/*Determine the vertical sub-sampling of U*/
yuvParams.nUv = 4;
/*Determine the horizontal sub-sampling of V*/
yuvParams.nVh = 4;
/*Determine the vertical sub-sampling of V*/
yuvParams.nVv = 4;
/*This is a pointer to an integer. Pass the byte order array.*/
yuvParams.pOffsets = pOff;
/*The range value determines the YUV range values. */
yuvParams.nRange = YUVRANGE_FULL;
/*This represents the macro pixels(smallest group of pixels allowed) , which indicates how many actual pixels are in the macro pixel. This value is important only in non – planar format*/
yuvParams.nMacroPixel = 16;
/*This is a Boolean value that represents the type of the YUV format (Planar, or non – Planar.)*/
yuvParams.bPlanar = TRUE;
/*Pass the YUV_PARAMS structure address to the pYuvParams member of the CONVERSION_PARAMS structure.*/
cpParams.pYuvParams = &yuvParams;
/*Determine the size of the CONVERSION_PARAMS structure.*/
cpParams.uStructSize = sizeof (CONVERSION_PARAMS);
/*Determine the type of conversion to be used. For YUVGeneric, use only USE_BUILTIN*/
cpParams.nMethod = USE_BUILTIN;
/*Determine the type of conversion to be activated. For YUVGeneric, use only USE_BUILTIN.*/
cpParams.nActiveMethod = USE_BUILTIN;
/*Initialize the conversion*/
L_ClrInit(&hClrHandle, CCS_YUV, CCS_RGB, &cpParams);
/*Convert the buffers pIn to pOut*/
L_ClrConvert(hClrHandle, pIn, pOut, nWidth, nHeight, 0, 0);
/*Free the handles*/
L_ClrFree(hClrHandle);
}