UCI Spec General Notes

The following are additional notes and explanations regarding the UCI specifications as currently documented. This information is intended to aid with understanding of the intent behind some of what has been put together, but is not intended to alter or replace the specs as detailed elsewhere. When in doubt of specifics, go with what's written in the spec documentations themselves.

If you find something in conflict with what the specs say, please let the maintainer know so it can be corrected here.

The Theory Behind Codec Parameters

The subject of codec parameters warrants some additional explanation, as it may not be inherently obvious from the API descriptions above. A system for parameters has been developed that is both flexible, allowing codecs to define a wide variety of both standard and nonstandard parameters, and fast, producing a minimum of overhead for a given application to determine and set appropriate values for any given parameter.

In general, a parameter block consists of an array of codec_param_values. codec_param_values are simple unions which can hold a variety of different data types, as appropriate for any given parameter. Each "slot" in a parameter block is defined by its associated entry in the parameter block definition associated with that parameter block.

Parameter block definitions are arrays of codec_param_def elements, one per parameter block slot, defined by the codec for each type of parameter block it deals with (encode_init_params, decode_init_params, etc) (these parameter block definitions are provided as part of the information returned from codec_get_info). Each of these codec_param_def elements defines the meaning and use of one slot of the associated parameter block, including name, type, brief (human-readable) description, default value, min/max ranges, valid enumerated values, etc.

A codec can, therefore, define as many or as few parameters as it needs for any particular parameter block, and specify the types, meanings, and accepted values for each one. An application can then fill in the values it understands, leaving default settings for any parameters it does not understand or does not want to change.

The UCI library contains several functions used to optimize the use of parameter blocks, as well as a set of macro definitions intended to make their use easy and intuitive for the codec developer and application developer alike.

As an example of how this system is used, say a hypothetical codec has several encoding parameters which need to be passed to it when encode_init is called. It might define its encode_init_paramdef as follows:

  encode_init_paramdef = {
    CODEC_PARAMDEF_INT_RANGE("bitrate", "Output bitrate (kbps)", 1800, 100, 64000),
    CODEC_PARAMDEF_STR("message", "message text to be included in stream", "Created with Foo Codec!"),
    CODEC_PARAMDEF_END
  };

It would then return this structure as the encode_init_paramdef returned in its codec_info structure. This would indicate that when encode_init is called, the codec expects the parameter block passed to it to contain two parameters, one is an int containing a bitrate value (in kbps), which must be between 100 and 64000, and defaults to 1800. The second is a pointer to a string value, which contains a message to be included in the output stream, and defaults to "Created with Foo Codec!".

In order for an application to customize these parameters when beginning an encoding run, the first step is to obtain an appropriate structure associated with the parameter block being used (which needs to be done anyway). In this case, it would be the encode_init_settings structure, which can be created using the following call:

  encode_init = codec_new_encode_init_params(codec_handle);

This call creates and initializes the structure which contains data for initializing an encoding session. Along with several standard pieces of information, this structure also contains a parameter block which is already set up correctly for the codec in use. Parameter values can be set with calls such as the following:

  codec_set_parameter_int(encode_init, "bitrate", 2000);
  codec_set_parameter_str(encode_init, "message", "Hi Mom!");

All standard parameters have a predefined type and meaning (as recorded in the UCI project's standard parameter database (see below)), so an application will know ahead of time which of these functions to use with which parameters. For nonstandard parameters, the codec_get_param_type function can be used.

Additionally, for parameters which are changed more frequently (for example, parameters passed on every encode_data call which may change from frame to frame), a more efficient method of setting parameters can be used. A pointer to a given parameter's slot within a particular parameter block can be obtained beforehand:

  int *bitrate_param;
  bitrate_param = codec_get_paramptr_int(encode_init, "bitrate");

Later, this pointer can be used to set that slot of that parameter block directly, with a minimum of overhead:

  *bitrate_param = 2000;

Note that while this method is faster, there is no way to verify that the value being set is in fact a valid one according to the information in the parameter definition. It is up to the application to obtain information on what valid values are (through codec_get_param_max, codec_get_param_min, codec_get_param_enumdata, etc) and ensure that they are adhered to.

Results

Certain operations (encode_data, decode_data) also support returning status or result information from the codec to the application by way of "results" structures. Although these are labeled as "results" instead of "params" to distinguish the direction of information flow, these also take the form of parameter blocks as described above, and can be accessed in exactly the same way. The UCI library also provides some handy routines for reading values from parameter blocks for this purpose.

Standard Parameters

The UCI project will be maintaining a database of standard names, types, and interpretations for parameters and results, as well as guidelines for using nonstandard parameters and for submitting suggested parameters for standardization. This standard parameter database will help application programmers by providing a set of well-defined parameters which many codecs support, with well-defined semantics, so that an application can control most common aspects of any codec without having to tailor their code to each specific set of parameter names a codec author might choose to come up with. It is strongly encouraged that codecs use standard parameter names when feasable to make them as compatible as possible with the widest range of applications.

Codec Classes

Additionally, we are considering the possibility of introducing the concept of "classes" for codecs, which would imply a certain set of supported parameters which are common to a group of different codecs or formats (for example, an "mpeg" class for all codecs which implement a set of parameters common to most MPEG-style compression algorithms (such as quantizers, motion-compensation styles, etc)) (A codec could be a member of more than one class). It's still being decided whether this feature would be actually useful enough on a general scale to warrant inclusion.