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);
}