Chapter 7. Using Compression Library Algorithms

This chapter describes how to use the algorithms that are supplied with libcl. To use one of these algorithms, you need to select an appropriate algorithm for your application and specify it in the compress or decompress routines.

In this chapter:

Choosing a Compression Library Algorithm

Perhaps the most important aspect of developing an application that uses libcl is selecting the appropriate algorithm to use for the application. The algorithm affects the data size and quality and the rate of compression and decompression, so it is important to consider how an algorithm might affect the end result and whether a particular algorithm achieves the desired effect. A certain amount of experimentation may be necessary.

If you are interested in a particular quality level, you need to set the compression ratio to achieve that quality; if you are primarily interested in a particular data size or data rate, you need to set the compression ratio to achieve the desired data size or rate.

Here are some suggestions for typical application categories:


Note: The performance is quoted for Indigo® workstations with 33 MHz MIPS® R3000® processors only.


  • multimedia information delivery applications

    The key factors to consider when choosing a video compression algorithm for multimedia applications are playback speed, data size or rate, and quality.

    MPEG gives the best video quality for a given data size or rate, but playback speed is limited by the CPU. MVC1 is usually the best choice if MPEG is not fast enough. If an expensive frame-by-frame VCR is not available, recording in real time to disk is important, which can be done with RTR1.

  • telecommunications applications

    The key factors to consider when choosing a video compression algorithm for video/voice mail, video teleconferencing, and other telecommunications applications are the combined compression-decompression speed, data size/rate, and to a lesser extent, quality.

    MVC1 gives the best result for video of about 10 frames per second for a 160 by 120 frame size at the cost of a very high data rate. More performance can be achieved by using gray-scale.

  • previewing animations

    The key factors when choosing a video compression algorithm for previewing 2D and 3D animations are playback speed, quality, and, to a lesser extent, data size/rate. MVC1 gives the appropriate speed and quality.

  • editing movies

    The key factors to consider when choosing a video compression algorithm for movie editing applications are decompression speed, image quality, data size/rate, and compression speed.

    For motion video applications, MVC1 is the best choice, especially when the playback is provided by the MoviePlayer tool. MVC1 provides rapid decompression. Playback speed can be traded off with image quality. When recording from video hardware to disk, recording in real time to disk is important if a frame-by-frame VCR is not available—leading to the use of RTR1.

Table 7-1 summarizes the compression and performance relationships of the image and motion video algorithms. Compression, decompression, and codec performance measurements are in frames per second (FPS), as measured for 320 by 240 frames on Indigo workstations with 33 Mhz MIPS R3000 processors only.

Table 7-1. Capabilities of Image and Video Algorithms




Algorithm

Typical
Compression
Ratio From
24-bit RGB

Average
Bits
per
Pixel

Megabits per
Second at
15 Frames
per Second

Kilobytes
per
Frame
compression


Compress
(Frames per Second)


Decompress[a]
(Frames per Second)


Codec
(Frames per Second)

Uncompresse d

1:1

24

27.65

230.4

 

 

 

RLE 8-bit

4.8:1

5

5.76

48

6

11.5

3.9

MVC1

5.33:1

4.5

5.2

43.2

3

25

2.8

MVC1
Gray-scale

8:1

3

3.456

28.8

7

28

5.6

RTR1

6:1

4

4.608

38.4

NYM[b]

2.5

2.0

RTR1
Gray-scale

9:1

2.67

3.072

25.6

NYM

8

NYM

JPEG

16:1

1.5

1.728

14.4

1.1

1.8

0.7

MPEG

48:1

0.5

0.576

4.8

<< 1

4.75

<<1

[a] Decompressed frame per second is the measured performance, including reading the data from disk, decompressing it, and writing it to the screen.

[b] NYM: not yet measured.


Querying Compression Library Algorithms

This section explains how you can get a list of available algorithms for a video compressor or decompressor, along with the name and type of algorithm, or find the identifier for an algorithm given its name. Other features of the algorithms can also be queried by the application at run time. Querying algorithms, rather than having hard-coded setups, makes it possible to have an algorithm-independent interface, which lets you take advantage of future algorithms as they are implemented without redesigning your code.

Getting a List of Algorithms

Use clQueryAlgorithms() to get a list of algorithms for the compressor or decompressor identified by handle. clQueryAlgorithms() returns the size of the buffer needed to contain the list of algorithms and their types.

If the size of the algorithmTypeBuffer is smaller than the returned value, a partial list of the algorithms and their types is returned, and you must enlarge the algorithmTypeBuffer in order to receive a complete list.

The function prototype for clQueryAlgorithms() is:

int clQueryAlgorithms ( int algorithmMediaType,
                 int *algorithmTypebuffer, int bufferLength )

where

algorithmMediaType 


is the media type of the algorithm. For Indigo2 IMPACT Video, always set this to CL_ALG_VIDEO.

algorithmTypeBuffer  


is a pointer to an array of ints into which clQueryAlgorithms() can write algorithm name/type pairs for each parameter associated with handle. The even (0,2,4,...) entries receive the algorithm name. The odd entries (1,3,5,...) receive the types.

 

The returned types take on one of three values:


bufferLength 

is the length of the buffer, in ints, pointed to by paramValueBuffer. If bufferLength is zero, then paramValueBuffer is ignored and only the return value is valid.

Getting an Algorithm Scheme or Name

Use clQuerySchemeFromHandle() or clQuerySchemeFromName() to return the algorithm scheme identifier used by the other compression functions. Use clGetAlgorithmName() to return the algorithm name. Their function prototypes are:

int clQuerySchemeFromHandle(CLhandle handle)
int clQuerySchemeFromName(int algorithmMediaType, char *name)
char *clGetAlgorithmName(int scheme)

where

handle 

is a handle to a compressor or a decompressor

algorithmMediaType 


is the media type of the algorithm. For Indigo2 IMPACT Video, always set this to CL_ALG_VIDEO.

name 

is the algorithm name

scheme 

is the algorithm scheme

Example 7-1 demonstrates how to query the CL for a list of algorithms—in this case, video algorithms. The necessary buffer size is returned in the first call to clQueryAlgorithms(), and then malloc() is used to allocate enough buffer space to store the returned list of video algorithms.

Example 7-1. Getting a List of Compression Library Algorithms

#include <dmedia/cl.h>
#include <malloc.h>

int *buffer, bufferLength;
char *name;
/*
* Get a buffer containing all the video algorithms and types
*/
bufferLength = clQueryAlgorithms(CL_VIDEO, NULL, 0);
buffer = (int *)malloc(bufferLength * sizeof(int));
clQueryAlgorithms(CL_VIDEO, buffer, bufferLength);

scheme = clQuerySchemeFromName(handle);
name = clGetAlgorithmName(scheme);


Getting License Information

Use clQueryLicense() to obtain license information about an algorithm. The returned message is text intended for inclusion in a message box that is displayed for a user, explaining how to license an algorithm. Failure returns the license error code.

The function prototype is:

int clQueryLicense ( int scheme, int functionality,
                     char **message)

where

scheme 

is the algorithm scheme.

functionality 

is the type of algorithm, which can be one of:

  • CL_COMPRESSOR for compression

  • CL_DECOMPRESSOR for decompression

  • CL_CODEC for both compression and decompression

message 

is a pointer to a returned pointer to a character string containing a message.

Controlling JPEG Compressed Image Quality

JPEG is a tunable algorithm—you can trade quality for compression ratio and vice versa. You can specify a hint (CL_COMPRESSION_RATIO) for an approximate compression ratio, or you can set more explicit quality factors or target bit rates, as described in this section.

The source image is compressed in three basic steps.

  1. Data is transformed from spatial to frequency form in eight-by-eight blocks using a discrete cosine transform (DCT).

  2. The frequency coefficients are filtered down by a linear quantization.

  3. The coefficients are Huffman-encoded into a bit stream.

The process is reversed for decompression.

The quantization step controls the trade-off between image quality and size. The JPEG quantization table is used to scale each of the 64 DCT coefficients. The luminance (Y) and the chrominance (Cr and Cb) components each use a separate table.

The CL provides three methods for controlling image quality from these quantization tables. You can

  • specify an overall JPEG quality factor (CL_JPEG_QUALITY_FACTOR) for scaling the default JPEG quantization tables

  • manually set the quantization tables using CL_JPEG_QUANTIZATION_TABLES

  • specify a target bit rate that you would like the compressed data to approximate

The JPEG algorithm does not allow you to specify exact compression ratios, but the hardware implementation of JPEG used in Indigo2 IMPACT Compression supports the concept of a target bit rate. Specifying CL_BITRATE causes the hardware to create a new quantization table as each field is compressed. If the current field were compressed again, this quantization table would yield the exact target bit rate. Since this bit rate would reduce the maximum capture rate, the CL applies the new quantization table to the next field, since adjacent fields usually have similar compressibility.

Specifying a JPEG Quality Factor

You can use the CL_JPEG_QUALITY_FACTOR parameter to specify a JPEG quantization table scale factor that represents a rough percentage of the image detail preservation. This is one method to control the image loss and therefore the compression ratio for the Indigo2 IMPACT Compression JPEG algorithm.

Each time the quality factor is set, the reference quantization tables are scaled and downloaded into the codec. The formula used to obtain the scale factor is:

scalefactor = 50/quality          (quality < 50)
scalefactor = 2 - 2*quality/100;  (otherwise)

The default quality is CL_JPEG_QUALITY_DEFAULT, which represents a good-quality compressed image. A quality factor of 1 results in coarse quantization, a high compression ratio, and very poor image quality.
A quality factor of 100 results in the finest possible quantization, a low compression ratio (perhaps even image expansion), and near-perfect image quality. The most useful quality factor is typically in the range of 25–95.

To bypass scaling, specify CL_JPEG_QUALITY_NO_SCALE.

When CL_QUALITY_FACTOR is set, the approximate value of CL_COMPRESSION_RATIO is calculated; when CL_COMPRESSION_RATIO is set, the approximate value of CL_QUALITY_FACTOR is calculated. When decompressing JPEG, clDecompress() fills in this value. The actual compression ratio is determined by the quality factor and the image content and therefore may not be exactly what you expect.

Defining and Using Custom JPEG Quantization Tables

You can customize the JPEG quantization tables by using the CL_JPEG_QUANTIZATION_TABLES parameter. To set the tables, specify an unsigned short *qtables[4] argument. For each j, qtables[j] must either be NULL or point to a unsigned short[64] area of memory that represents a JPEG-baseline quantization table in natural scanning order. These custom tables are stored as reference tables; then scaled versions of them based on the current CL_JPEG_QUALITY_FACTOR are downloaded into the codec, becoming the tables associated with the ID j.

When getting the value of CL_JPEG_QUANTIZATION_TABLES, the CL allocates the required memory and returns the currently used tables, as indicated by CL_JPEG_COMPONENT_TABLES, scaled by the value of CL_JPEG_QUALITY_FACTOR. Your application is responsible for freeing the memory allocated to return these tables.

You can specify the quantization tables on a per-component basis, by using the CL_JPEG_COMPONENT_TABLES parameter. It specifies the IDs of the AC Huffman table, DC Huffman table, and quantization table to be used for each component. You cannot change this parameter for Indigo2 IMPACT Compression; it is set up for YUV422 processing. This setting uses AC Huffman table 0, DC Huffman table 0, and quantization table 0 for component 0; AC Huffman table 1, DC Huffman table 1, and quantization table 1 for components 1 and 2.

Specifying a Bit Rate Target

You can specify a target bit rate for the compressed data stream. The bit rate is the number of bits per second.

bitrate = (image_height * image_width * components_per_pixel
              * fields_per_second * 8) / compression_ratio;

Useful values for bit rate for NTSC video range from 15,000,000 (2:1 compression) to 3,000,000 (100:1).