Chapter 8. Using Optional Color-Space Conversion
Prev |  | Next

## Chapter 8. Using Optional Color-Space Conversion

A color space is a color component encoding format, for example, RGB and YUV. Because various types of video equipment use different formats, conversion is sometimes required. The Video Library for Indigo2 IMPACT Video has a particular node, VL_CSC, to handle color-space conversion.

| Note: The node VL_CSC is available only if the color-space conversion option board is installed.

The Indigo2 IMPACT Video color-space converter (CSC) node controls the optional hardware color-space converter option hardware. The CSC hardware can perform many types of image-processing operations on a video path. This node allows VL control over the conversion process.

The Indigo2 IMPACT Video CSC feature can be used in two ways: for standard conversions between YUV and RGB; or for image processing, for example, posterization[1] , solarization[2] , or color correction. VL for Indigo2 IMPACT includes controls for these types of conversions.

This chapter explains

- features of the color-space conversion node

- performing standard color-space conversions

- using the color-space converter for image processing

The chapter concludes with examples.

| Note: For background information on color-space conversion, see Appendix D, “Indigo2 IMPACT Video Color-Space Conversions,” later in this guide.

## Features of the Color-Space Conversion Node

Table 8-1 lists the video formats supported for color-space conversion.

Table 8-1. Supported Video Output Formats

Format | Description
--- | ---
YUV 4:2:2 (CCIR 601)) | Single-link YUV
YUVA 4:2:2:4 (CCIR 601) | Dual-link YUV with alpha
YUVA 4:4:4:4 (CCIR 601) | Dual-link YUV with alpha and all chroma samples
RGBA RP-175 | Dual-link RGBA, 8-bit [16-235] or 10-bit [64-940]
RGBA (0-255) | Dual-link RGBA [0-255] (8 bits, full-scale)
RGBA (0-1023) | RGBA full-scale and 10 bits to or from memory only

Figure 8-1 is a software model of a color-space converter.

Figure 8-1. Color-Space Conversion Software Model

The high-level processing blocks comprising a color-space converter in Figure 8-1 include

- an input block taking in pixel/alpha, or dual-linked, input and producing component streams; 4:2:2 -> 4:4:4 upsampling is performed for 4:2:2 / 4:2:2:4 inputs

- input lookup tables for each component stream

- a 3 x 3 matrix multiplier

- an output lookup table for each coefficient stream

- an output block producing pixel/alpha, or dual-linked, streams; 4:4:4 to 4:2:2 downsampling is performed for 4:2:2 / 4:2:2:4 output packings

These processing blocks allow the standard RGB-to-YUV and YUV-to-RGB color-space conversions to be implemented, as well as other forms of image processing such as color correction or posterization.

By default, the Video Library's color-space converter node loads standard conversion values for the lookup tables and matrix multiplier, depending on the source and target color spaces. The application can use the node's controls to override these values and achieve nonstandard conversions.

Figure 8-2 shows a more detailed model of IMPACT Video's color-space converter, including delay blocks synchronizing the component paths. This model also shows elements unique to IMPACT Video, such as the constant-hue processing block.

Figure 8-2. Color-Space Conversion Input to Output Paths: YUV to G'B'R'

## Performing Standard Color-Space Conversions

The VL_CSC node converts incoming video from one packing to another, where packing describes color space, component encoding, and bits per component, as shown in Table 8-1. The node operates on full-range or limited-range data.

The kind of the color-space conversion node is VL_CSC; its type is VL_INTERNAL; its number is VL_MGV_NODE_NUMBER_CSC.

The normal usage of the color-space node is to convert from RGB to YUV/YCrCb or from YUV/YCrCb to RGB color spaces. These conversions are specified by setting the input and output packing of the color-space converter using the VL_MGV_CSC_INPUT_PACKING and VL_MGV_CSC_OUTPUT_PACKING controls, respectively, and by specifying the input and output ranges using the VL_MGV_CSC_INPUT_RANGE and VL_MGV_CSC_OUTPUT_RANGE. All other controls on the color-space converter node, such as the input, output, and alpha LUTs and matrix coefficients, default to values supporting the specified conversion.

This section explains

- color-space conversion packings

- color-space conversion ranges

- constant hue

- ports

- full-range and limited-range video

- specifying standard color-space conversion node controls

### Color-Space Conversion Packings

The controls that set color-space packing are VL_MGV_CSC_IN_PACKING and VL_MGV_CSC_OUT_PACKING. Table 8-2 summarizes the packing types to use with the color-space converter and their meanings in terms of color space, component ordering, and component size.

Table 8-2. Supported Packing Types for Color-Space Conversion

Packing | Color-Space | Components | Component size
--- | --- | --- | ---
VL_PACKING_YVYU_422_8 | YUV | 4:2:2 | 8
VL_PACKING_YVYU_422_10 | YUV | 4:2:2 | 10
VL_PACKING_YUVA_4444_8 | YUV | 4:4:4:4 | 8
VL_PACKING_YUVA_4444_10 | YUV | 4:4:4:4 | 10
VL_PACKING_AUYV_4444_8 | YUV | 4:4:4:4 | 8
VL_PACKING_AUYV_4444_10 | YUV | 4:4:4:4 | 10
VL_PACKING_AYU_AYV_10 | YUV | 4:2:2:4 | 10
VL_PACKING_RGBA_8 | RGB | 4:4:4:4 | 8
VL_PACKING_RGBA_10 | RGB | 4:4:4:4 | 10
VL_PACKING_ABGR_8 | RGB | 4:4:4:4 | 8
VL_PACKING_ABGR_10 | RGB | 4:4:4:4 | 10

| Note: Although Indigo2 IMPACT Video supports the packing formats VL_PACKING_RGB_332_P, VL_PACKING_Y_8_P, and VL_PACKING_RGB_8, the color-space conversion feature does not.

Besides color space, component encoding, and bits per component, a packing also denotes component order, as stored in memory, which is ignored by the color-space converter node.

Eight-bit video supplied through the video inputs or memory nodes is automatically left-shifted to 10 bits, with bits 0 and 1 set to zero. Consequently, at the color-space converter's input and output, all data is 10-bit, and the 8- and 10-bit packings listed in Table 8-2 are functionally equivalent.

Setting VL_MGV_CSC_IN_PACKING or VL_MGV_CSC_OUT_PACKING loads the input, output, and alpha LUTs and matrix multiplier coefficients with values that reflect the conversion specified by this control and by the range controls.

### Color-Space Conversion Ranges

The Video Library formats denote the range of pixel components. Note that formats also convey color-space information; this information is not used by the color-space converter node, although it is highly recommended that the packing and format color spaces specified on the input or output agree.

The controls that set the input and output ranges of the color-space converter are VL_MGV_CSC_IN_RANGE and VL_MGV_CSC_OUT_RANGE. Table 8-3 summarizes the ranges supported by the color-space converter node.

Table 8-3. Supported Ranges

Format | Range
--- | ---
VL_FORMAT_DIGITAL_COMPONENT_SERIAL | CCIR-Range YCrCb 8-bit: 16-235 (Y), 16-240 (Cr, Cb) 10-bit 64-940 (Y), 64-960 (Cr, Cb)
VL_FORMAT_DIGITAL_COMPONENT_SERIAL_RGB | RP-175-Range RGB 8-bit: 16-235 (R, G, B) 10-bit: 64-940 (R, G, B)
VL_FORMAT_SMPTE_YUV | Full-Range YUV 8-bit: 0-255 (Y, U, V) 10-bit 0-1023 (Y, U, V)
VL_FORMAT_RGB | Full-Range RGB 8-bit 0-255 (R, G, B) 10-bit 0-1023 (R, G, B)

When a range control is set, input, output, and alpha LUTs and matrix multiplier coefficients are loaded with values that reflect the conversion specified by the input/output packing and range.

| Note: If output packing is VL_PACKING_YVYU_422_8 or VL_PACKING_YVYU_422_10, output range is VL_FORMAT_SMPTE_YUV (full-range YUV), and the converted output is to be saved in memory, you must use VGI1 1, that is, memory drain node 1 (1 or VL_MGV_NODE_NUMBER_MEM_VGI1_2).

### Constant Hue

In addition to the standard color-space conversion model, the Indigo2 IMPACT Video color-space option provides a constant-hue algorithm. This algorithm allows illegal YUV values to survive a YUV-to-RGB-to-YUV conversion. In normal conversion, YUV values that cannot be represented in the RGB color space are clamped or otherwise forced into the legal RGB range. Because the YUV (YCrCb) color space is a superset of the RGB color space, illegal RGB values can be generated when YUV is converted to RGB. If the constant-hue block is disabled, then the illegal RGB values are clipped by the output LUT. The lost (clipped) information can result in significantly degraded quality when the image is subsequently transformed back to YUV for video output.

The constant-hue algorithm saves the normally lost information in a correction factor that can be stored in the alpha channel. To restore the original YUV image, this correction factor must be saved with the pixel data.

If the constant-hue algorithm is enabled, the illegal RGB values are converted into legal R'G'B' values. A constant-hue factor, used to restore R'G'B' to the original YUV values, can optionally be stored in the alpha channel. If the constant-hue factor is not saved, then the R'G'B' image appears as if it were range-compressed. The VL_MGV_CSC_ALPHA_CORRECTION control determines whether the alpha channel is replaced by the constant-hue factors, or if the alpha from the color-space converter's input is retained.

Note that because the correction factor computed by the algorithm is directly related to the pixel value, the correction factor is invalidated if the pixel value is recalculated (for example, during compositing).

The controls for constant hue are

- VL_MGV_CSC_CONST_HUE: boolean control to enable (TRUE) or disable (FALSE) the constant-hue algorithm

- VL_MGV_CSC_ALPHA_CORRECTION: boolean control to select the contents of the alpha channel

  If this value is set to TRUE, the constant-hue factor is saved in the alpha channel. If it is set to FALSE, the alpha value from the input is retained.

| Note: VL_MGV_CSC_ALPHA_CORRECTION has no effect if VL_MGV_CSC_CONST_HUE is disabled. When both VL_MGV_CSC_CONST_HUE and VL_MGV_CSC_ALPHA_CORRECTION are enabled, it is not advisable to load the alpha LUT.

By default, the constant-hue processing block is enabled, but the constant-hue factor is not stored in the alpha channel (the input alpha is retained).

If the constant-hue factor is not stored in the alpha channel, you might need to range-limit or expand the input alpha value. For example, when full-range RGBA is converted to YCrCbA, the range is limited from [0-255] to CCIRs [16-235]. The range is altered using the output alpha LUT. The default contents of this LUT are determined by the input and output ranges.

### VL_CSC Ports

Table 8-4 lists the ports for the color-space conversion node.

Table 8-4. Color-Space Conversion Node Ports

Port | Use
--- | ---
VL_IMPACT_PORT_PIXEL_DRN_A | Pixel input 4:2:2:4
VL_IMPACT_PORT_ALPHA_DRN_A | Alpha input 4:2:2:4
VL_IMPACT_PORT_DUALLINK_DRN_A | Dual link input 4:4:4:4
VL_IMPACT_PORT_PIXEL_SRC_A | Pixel output 4:2:2:4
VL_IMPACT_PORT_ALPHA_SRC_A | Alpha output 4:2:2:4
VL_IMPACT_PORT_DUALLINK_SRC_A | Dual link input 4:4:4:4

The color-space converter node has both single- and dual-linked input and output ports. Only one of these should be used at a time.

- Use the dual-linked ports if the video stream is coming from a dual-linked video or memory node. In almost all cases, the dual-linked stream contains RGBA, YUV 4:4:4:4, or YUV 4:2:2:4 samples. For RGBA, the components are split across the two links according to the RP-175 specification: link 1 (pixels) contains RGB 4:2:2, while link 2 (alpha) contains AGB 4:2:2.

  | Note: Use dual-linked connections for RGB or YUV 4:4:4:4 input or output. Because the chrominance samples span both input/output ports, any mistiming between two single-linked connections results in corrupted video.

- Use the single-linked port if the pixel and alpha are coming from two single-linked ports. The single-linked nodes allow pixel values to be specified independently of alpha values for YUV input or output. For example, to convert a YCrCb 4:2:2 stream to RGB, connect only the pixel input port; the alpha input port contains black.

  | Note: Exercise caution when both the alpha and pixel ports are connected to different sources; these sources must be perfectly timed or the output pixels can have mismatched alpha.

The software model in Figure 8-1 shows the pixel and alpha ports on the input and output blocks.

### Full-Range and Limited-Range Video

The color-space conversion node operates on full-range or limited-range data. Range is specified by a VL format.

#### Standard D1 VIdeo Range

The standard D1 video range is as follows:

- RGB (three primaries): Y (the luminance signal) and A (the auxiliary channel) each contain the ranges 16-235 for 8-bit data and 64-940 for 10-bit data.

- The U (Cb) and V (Cr) signals contain the ranges 16-240 for 8-bit data and 64-960 for 10-bit data.

#### Standard RGBA Full Range

The standard full range is 0-255 for 8-bit data and 0-1023 for 10-bit data.

For full-range component values, the resulting video stream might contain false EAV/SAV codes. The VGI1 memory nodes (memory nodes 0, 1, and 2) and the color-space converter can ignore these codes, but the rest of the device cannot. Consequently, full-range YUV or RGB data should be exchanged between the VGI1 and color-space converter only. RP-175-range RGB or CCIR-range YUV video can be exchanged among all Indigo2 IMPACT Video nodes.

### Specifying Standard Color-Space Conversion Node Controls

Table 8-5 summarizes controls for standard color-space conversion.

Table 8-5. Controls for Standard Color-Space Conversion

Control | Use | Default | Type
--- | --- | --- | ---
VL_MGV_CSC_IN_PACKING, VL_MGV_CSC_OUT_PACKING | Sets the packing for the color-space converter node's input or output, respectively | VL_PACKING_YVYU _422_10 | intVal
VL_MGV_CSC_IN_RANGE, VL_MGV_CSC_OUT_RANGE | Sets the input range (RP-175, CCIR, or full) associated with the input or output video, respectively | VL_FORMAT_DIGITAL _COMPONENT_SERIAL | intVal
VL_MGV_CSC_CONST_HUE | Enables or disables constant-hue algorithm | TRUE | boolVal
VL_MGV_CSC_ALPHA _CORRECTION | When VL_MGV_CSC_CONST_HUE is enabled, this control saves the constant hue correction factor (TRUE) or retains alpha input data (FALSE) | FALSE | boolVal

For all these controls the access is GS:

- G: the value can be retrieved through `vlGetControl()`

- S: the value can be set through `vlSetControl()` while the path is not transferring

When any of these controls are set, the LUTs and matrix coefficients are loaded with values reflecting the input packing/output packing, range conversion, and constant hue, if it is set. Applications can optionally load custom LUTs or coefficients after setting the input and output packing and range.

## Using the Color-Space Converter for Image Processing

This section describes the color-space converter in more detail for application developers who wish to use it as an image processing device capable of posterization, solarization, or color correction, or for nonstandard conversions. These applications specify custom values for the lookup tables and matrix coefficients, and require more effort than standard conversions.

| Note: See also Appendix D, “Indigo2 IMPACT Video Color-Space Conversions,” and “VL_CSC” in Appendix C for information on the CSC controls.

In addition to standard conversions, the color-space converter can be loaded with user-defined input lookup tables, matrix multiplier coefficients and output lookup tables. Applications can manipulate the tables and coefficients to perform color correction, colorization, or other image-processing functions. See Appendix D for a description of the color-space converter model and the relationships between the various internal processing blocks.

### Using Custom LUTs and Matrix Multiplier Coefficients

User-defined software-loadable lookup tables support operations such as gamma correction. The input and alpha lookup tables each contain 1024 entries of 12-bit values. For each of these tables, up to four lookup tables can be loaded simultaneously. An application can use the LUT selection controls to select which of the tables is active.

The output lookup tables each contain 4096 entries of 10-bit values. Only one table can be loaded for each of the VR, GY, and UB output LUTs. The matrix multiplier operates with 23-bit internal precision.

Color-space conversion is supported in the active video region only; the vertical and horizontal blanking areas are replaced with black (in the appropriate target color space). Consequently, ancillary data, such as telextext, embedded audio, and embedded timecode, is lost.

| Note: Use the standard controls VL_MGV_CSC_IN_PACKING, VL_MGV_CSC_OUT_PACKING, VL_MGV_CSC_IN_RANGE, and VL_MGV_CSC_OUT_RANGE for image processing, even if the input and output packings/ranges are identical. Even if the application subsequently changes all of the lookup tables and coefficients, it should still set the input and output packing to reflect the color space and component encoding. The packing control enables or disables parts of the color-space converter, such as the 4:2:2 to or from 4:4:4 filters.

Standard conversion controls take precedence over those for image processing. For example, if the input or output packing control is set, lookup tables and coefficient values are recalculated to effect the conversion implied by the input/output packing and range.

### Using Image-Processing Controls

Table 8-6 summarizes image-processing controls. Access for all these controls is GST:

- G: The value can be retrieved through `vlGetControl()`.

- S: The value can be set through `vlSetControl()` while the path is not transferring.

- T: The value can be set through `vlSetControl()` while the path is transferring

  Table 8-6. Image-Processing Controls

  Control | Use | Default | Type
  --- | --- | --- | ---
  VL_MGV_CSC_COEF | Specifies the matrix multiplier coefficients | Multiplier operates in pass-through mode | extendedVal; data type MGV_CSC_COEF
  VL_MGV_CSC_LUT_IN_PAGE VL_MGV_CSC_LUT_ALPHA_PAGE | Selects the active LUT | 0 | intVal
  VL_MGV_CSC_LUT_IN_YG VL_MGV_CSC_LUT_IN_UB VL_MGV_CSC_LUT_IN_VR VL_MGV_CSC_LUT_ALPHA | Specifies the contents of the input or alpha lookup tables | Pass-through (1:1 mapping) | extendedVal; data type MGV_CSC_LUT_INPUT _AND_ALPHA
  VL_MGV_CSC_LUT_OUT_YG VL_MGV_CSC_LUT_OUT_UB VL_MGV_CSC_LUT_OUT_VR | Specifies the contents of the output lookup tables | Pass-through (1:1 mapping) | extendedVal data type MGV_CSC_LUT_OUTPUT

#### Using Coefficients

The control VL_MGV_CSC_COEFF specifies the matrix multiplier coefficients. It has a data pointer pointing to an array of nine integers. The coefficients are stored in the following order:

- data[0] = Y/G 1 data[1] = Y/G 2 data[2] = Y/G 3

- data[3] = U/B 1 data[4] = U/B 2 data[5] = U/B 3

- data[6] = V/R 1 data[7] = V/R 2 data[8] = V/R 3

Each coefficient is a 32-bit fractional two's complement value. The magnitude of each coefficient is from -4 to 3.999. Table 8-7 shows values.

Table 8-7. Coefficient Formats

Bit | Value
--- | ---
31 | -22(signed bit)
30 | 21
29 | 20
28 | 2-1
27 | 2-2
26 | 2-3
25 | 2-4
24 | 2-5
23 | 2-6
... | ...
4 | 2-25
3 | 2-26
2 | 2-27
1 | 2-28
0 | 2-29

For the Indigo2 IMPACT Video color-space conversion option board, the valid range for data[0], data[4], and data[8] is from -4 to 3.999; for the other six coefficients, the valid range is from -2 to 1.999. The 31th and 30th bits of the other six coefficients must be either all 0's or all 1's for the range from -2 to 1.999; otherwise they are clamped to the valid range.

#### Selecting the Active LUT

The IMPACT Video color-space converter node can store up to four input LUTs (each with YG, UB, and VR), and four alpha LUTs. Use the control VL_MGV_CSC_LUT_IN_PAGE or VL_MGV_CSC_LUT_ALPHA_PAGE in the application to select which of the four LUTs is active.

#### Using Input and Alpha LUTs

The controls for specifying the contents of the input or alpha lookup tables are VL_MGV_CSC_LUT_IN_YG, VL_MGV_CSC_LUT_IN_UB, VL_MGV_CSC_LUT_IN_VR, and VL_MGV_CSC_LUT_ALPHA.

The data pointer of the extended value points to a VL_MGVInAlphaLutValue structure, as defined in dev_mgv.h. This structure contains the page number for the LUT being specified and a lookup table of 1024 integer entries (see VL_MGV_CSC_LUT_IN_PAGE and VL_MGV_CSC_LUT_ALPHA_PAGE) for selecting the LUT active during color-space conversion). The range for each entry in the lookup table is 0-1023 (10 bits).

#### Using Output LUTs

The controls for specifying output LUTs are VL_MGV_CSC_LUT_OUT_YG, VL_MGV_CSC_LUT_OUT_UB, and VL_MGV_CSC_LUT_OUT_VR.

The data pointer of the extended value points to a VL_MGVOutLutValue structure, as defined in `dev_mgv.h`. This structure contains a lookup table of 4096 integer entries. The Indigo2 IMPACT Video color-space converter can store only one output LUT for each of the YG/UB/VR paths. The range for each entry in the lookup table is 0-1023 (10 bits).

## Examples

This section includes two color-space conversion examples.

Example 8-1. Setting CSC Controls for Standard Color-Space Conversion

    /*
     * The following example is to demostrate how to set CSC controls to perform
     * standard color space conversion. Video input in CCIR 10-bit YUV 422 packing
     * is converted to full-range 10-bit ABGR packing which will be saved in
     * memory. Controls for constant hue and alpha correction are enabled.
     *
     * Video input is source, memory (VGI1) is drain, and CSC is a internal node
     * in a video to memory path. Because this is a CSC example, codes other
     * than CSC are replaced by comments in this examples.
     */

    #include <errno.h>
    #include <stdio.h>
    #include <dmedia/vl.h>
    #include <dmedia/vl_mgv.h>

    void main(void)
    {
            VLTransferDescriptor xferDesc;
            VLControlValue val;
            VLServer svr;
            VLPath path;
            VLNode src, drn;
            VLNode csc_node;

            /* We connect to daemon and set up nodes for source and drain */

            /* Create CSC internal node */
            csc_node = vlGetNode(svr, VL_INTERNAL, VL_CSC, VL_MGV_NODE_NUMBER_CSC);

            /*
             * We create a video to memory path with the source and drain
             * created above.
             */

            /* Add the CSC internal node to the path */
            if (vlAddNode(svr, path, csc_node)) {
                vlPerror(“Add CSC Device Node”);
                vlDestroyPath(svr, path);
            }

            /* Set CSC input range to CCIR */
            val.intVal = VL_FORMAT_DIGITAL_COMPONENT_SERIAL;
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_IN_RANGE, &val) < 0)
                vlPerror(“SetControl of CSC input range failed”);

            /* Set CSC input packing to 10-bit YUV 422 */
            val.intVal = VL_PACKING_YVYU_422_10;
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_IN_PACKING, &val) < 0)
                vlPerror(“SetControl of CSC input packing failed”);

            /* Set CSC output range to full range */
            val.intVal = VL_FORMAT_RGB;
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_OUT_RANGE, &val) < 0)
                vlPerror(“SetControl of CSC output range failed”);

            /* Set CSC output packing to 10-bit ABGR */
            val.intVal = VL_PACKING_ABGR_10;
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_OUT_PACKING, &val) < 0)
                vlPerror(“SetControl of CSC output packing failed”);

            /* Enable CSC constant hue algorithm, default is TRUE */
            val.boolVal = TRUE;
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_CONST_HUE, &val) < 0)
                vlPerror(“SetControl of CSC constant hue failed\n”);

            /* Enable alpha correction in the alpha channel, default is FALSE */
            val.boolVal = TRUE;
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_ALPHA_CORRECTION, &val)
                < 0)
                vlPerror(“SetControl of CSC alpha correction failed\n”);

            /* We set VGI1's controls below */

            /* VGI1's VL_FORMAT should be same as CSC's output range */
            val.intVal = VL_FORMAT_RGB;
            if (vlSetControl(svr, path, drn, VL_FORMAT, &val) < 0)
                vlPerror(“SetControl of memory format failed”);

            /* VGI1's VL_PACKING should be same as CSC's output packing */
            val.intVal = VL_PACKING_ABGR_10;
            if (vlSetControl(svr, path, drn, VL_PACKING, &val) < 0)
                vlPerror(“SetControl of memory packing failed”);

            /* Begin the data transfer */
            if (vlBeginTransfer(svr, path, 1, &xferDesc)) {
                vlPerror(“vlBeginTransfer failed”);
            }

            /* Loop until all requested frames are grabbed */
            vlMainLoop();

    }

Example 8-2 uses the color-space converter node to perform image processing.

Example 8-2. Loading Matrix Coefficients and LUTs

    /*
     * The following example is to demostrate how to load matrix coefficients,
     * input luts, output luts and alpha lut.  Codes other than loading are
     * replaced by comments in this examples.
     */

    #include <errno.h>
    #include <stdio.h>
    #include <dmedia/vl.h>
    #include <dmedia/vl_mgv.h>

    void main(void)
    {
            VLTransferDescriptor xferDesc;
            VLControlValue val;
            VLServer svr;
            VLPath path;
            VLNode src, drn;
            int i;

            int coef_table[9] =
                {0, 10, 20, 30, 40, 50, 60, 70, 80};

            /* We connect to daemon and set up nodes for source and drain */

            /* Create CSC internal node */
            csc_node = vlGetNode(svr, VL_INTERNAL, VL_CSC, VL_MGV_NODE_NUMBER_CSC);

            /*
             * We create a video to memory path with the source and drain
             * created above.
             */

            /* Add the CSC internal node to the path */
            if (vlAddNode(svr, path, csc_node)) {
                vlPerror(“Add CSC Device Node”);
                vlDestroyPath(svr, path);
            }

            /* Load 9 coefficients */
            extVal.dataPointer = coef_table;
            extVal.dataSize = sizeof (coef_table);
            extVal.dataType = MGV_CSC_COEF;

            val.extVal = extVal;

            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_COEF, &val) < 0) {
                vlPerror(“SetControl of CSC coefficients failed”);
            }

            /* Generate one page of lut */
            for (i = 0; i < 1024; i++)
                inlutVal.lut[i] = 1000;

            /* Assign one page of lut we generated to be in 1st page of
               input luts and alpha lut. */
            inlutVal.pageNumber = 0;

            extVal.dataType = MGV_CSC_LUT_INPUT_AND_ALPHA;
            extVal.dataSize = sizeof(VL_MGVInAlphaLutValue);
            extVal.dataPointer = &inlutVal;

            val.extVal = extVal;

            /* Load the page to input Y/G lut */
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_LUT_IN_YG, &val) < 0) {
                vlPerror(“SetControl of CSC YG input lut failed\n”);
            }

            /* Load the page to input U/B lut */
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_LUT_IN_UB, &val) < 0) {
                vlPerror(“SetControl of CSC UB input lut failed\n”);
            }

            /* Load the page to input V/R lut */
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_LUT_IN_VR, &val) < 0) {
                vlPerror(“SetControl of CSC VR input lut failed\n”);
            }

            /* Load the page to alpha lut */
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_LUT_ALPHA, &val) < 0) {
                vlPerror(“SetControl of CSC ALPHA lut failed\n”);
            }

            /* Select the 1st page of input and alpha luts to be active during
               normal mode, so they will be used for normal operation. */
            val.intVal = 0;
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_LUT_IN_PAGE, &val) < 0)
                vlPerror(“SetControl of CSC input lut page failed\n”);

            val.intVal = 0;
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_LUT_ALPHA_PAGE, &val)
                < 0)
                vlPerror(“SetControl of CSC alphalut page failed\n”);

            /* Generate 4 pages of lut */
            for (i = 0; i < 4096; i++)
                outlutVal.lut[i] = 1000;

            extVal.dataType = MGV_CSC_LUT_OUTPUT;
            extVal.dataSize = sizeof(VL_MGVOutLutValue);
            extVal.dataPointer = &outlutVal;

            val.extVal = extVal;

            /* Load all 4 pages to output Y/G lut */
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_LUT_OUT_YG, &val)
                < 0) {
                vlPerror(“SetControl of CSC YG output lut failed\n”);
            }

            /* Load all 4 pages to output U/B lut */
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_LUT_OUT_UB, &val)
                < 0) {
                vlPerror(“SetControl of CSC YG output lut failed\n”);
            }

            /* Load all 4 pages to output V/R lut */
            if (vlSetControl(svr, path, csc_node, VL_MGV_CSC_LUT_OUT_VR, &val)
                < 0) {
                vlPerror(“SetControl of CSC YG output lut failed\n”);
            }

            /* Here we set VGI1 controls, begin transfer and Loop until all
               requested frames are grabbed */

    }

[1] Quantizing the distortion of color difference signals to obtain special effects, here limiting the number of possible colors in the picture, thus giving the effect of a poster painted with a limited number of colors.

[2] A form of contrast enhancement: when transfer functions become so distorted that the slope reverses, the result is “luminance reversal,” where black and white are effectively interchanged.

Prev | Table of Contents | Next
Chapter 7. Blending, Keying, and Transitions |  | Chapter 9. Using Optional Video Texture Mapping