Note: Some information presented here may be slightly out of date, as the specifications and code underneath all this is still somewhat a moving target. If you find something here which doesn't look right, please do not be too alarmed, as it may just need updating. |
Last Updated: Sept 24, 2002 |
UCI codecs are implemented as shared libraries conforming to the following specifications:
The name of the shared library is "codec_type_name.extension", where type indicates the type of codec (currently defined types are "audio" and "video"), name is the name of the codec, and extension is the standard shared library extension for the platform on which it is intended to run ("so" for most unix platforms). extension can optionally also include other versioning information or extensions as per the convention for the platform (such as ".so.0", etc), with the stipulation that it must still be separated from the name using a period ("."). (for example, "codec_video_foo-12.so" is not a valid codec library name, but "codec_video_foo.-12.so" or "codec_video_foo.v-12.so" would be, if such a convention needed to be used). On platforms which use SONAMEs or similarly embed the library name within the library file, such names should be the same as the filename, to avoid confusion and linking errors.
Note that it is illegal to have two codecs installed in a given system with the same type and name which implement the same version of the UCI interface (interface_version in the codec_info structure returned by the library's codec_get_info function). It is only allowed to have codecs with the same type and name if they are used to implement different interface versions (for backwards compatibility). In this case, extension should have appropriate versioning information to keep the filenames and SONAMEs different between the different versions of the codec library.
The shared library is located in one of the defined directories for codec libraries. This can vary according to system configuration, but by default the UCI library will check all of the normal shared library directories (as defined by /etc/ld.so.conf or other appropriate configuration files) for subdirectories named "codecs", and look in any such subdirectories it finds. This behavior can be modified or completely changed in /etc/uci.conf, however.
The shared library must export the following functions (as defined elsewhere in this document):
If the codec supports encoding, the shared library must export the following functions (as defined elsewhere in this document):
If the codec supports decoding, the shared library must export the following functions (as defined elsewhere in this document):
It is assumed that these shared libraries will normally be thin interfaces to the actual codec implementation, which is stored in a separate library. As there are some situations where numerous codec interface libraries will be loaded and unloaded without actually needing to use the codecs themselves (such as when scanning codec_info structures), it is reccomended if possible to use demand-loading or explicit dlopen calls (in codec_init), etc, to link to the actual codec code libraries, such that the entire codec implementation (and any supporting libraries, and so on) does not need to be loaded into memory unless an application actually indicates its intention to use the codec.
Return a codec_info structure describing this codec. codec_init is not required to be called before calling this function.
The codec_info structure:
typedef struct { int interface_version; char *name; char *short_description; char *long_description; codec_type_t codec_type; int flags; int num_formats; codec_format_info formats[]; } codec_info;
'interface_version' indicates the version of the codec interface implemented by this codec. This should be set to CODEC_INTERFACE_VERSION.
'name' is the brief, unique name identifying this codec. This should be the same as the codec name used in the shared library filename.
'short_description' is a brief (less than 60 chars, one line) description of the codec, such as "The Foo Group's MPEG4 codec". This should not have any line-terminators at the end of it.
'long_description' is a longer description of the codec. This can contain multiple lines and has no length limit (it is reccomended this be kept under a screen's worth of text, however). This can contain any number of newline ('\n') characters, and should be terminated with a single newline.
'codec_type' is an integer value indicating the type of codec implemented by this library. Currently supported values are CODEC_TYPE_VIDEO or CODEC_TYPE_AUDIO.
'flags' contains a set of bitmapped flags for the codec, which may be one or more of the following (bitwise ORed together):
'num_formats' contains the number of entries in the following 'formats' array.
'formats' is an array of codec_format_info structures describing the encoded formats this codec supports:
typedef struct { int id; char *name; char *short_description; int flags; codec_fmt_identifier *idents; codec_param_def *encode_init_paramdef; codec_param_def *encode_paramdef; codec_param_def *decode_init_paramdef; codec_param_def *decode_paramdef; } codec_format_info;
typedef struct { int id_type; char *data; } codec_fmt_identifier;
id_type
can be one of:
Will be called before any other functions (except for codec_get_info). This function should perform any setup required to actually use the codec (loading additional libraries, setting up global structures, etc).
This function will only be called once per process.
This function should return CODEC_STATUS_OK if initialization was successful, or an error code otherwise. If an error code is returned, no further calls to this codec will be made.
This function will be called when all use of this codec has been finished. It should clean up any resources allocated in codec_init or in other calls to this codec.
Return a structure indicating the list of raw data formats in which this codec can take data to be encoded. If "iparam" is provided, this function should return a list of formats which are compatible with the initialization parameters specified. "iparam" may be NULL, in which case this function should return a list which indicates all formats available for any combination of initialization parameters. Formats whose availability may vary depending on initialization parameters should be indicated as such by setting CODEC_RAWFMT_SELECTED_AVAIL in the flags associated with that entry. If valid data is provided for "iparam", it is illegal to return any entries with CODEC_RAWFMT_SELECTED_AVAIL set. In the case where the codec supports the same set of input formats regardless of any initialization parameters, this function should return the same data regardless of what is passed to it in "iparam".
All video codecs must support at least one of the following raw formats:
All audio codecs must support at least one of the following raw formats:
Codecs may support more than one of these formats (and in fact are encouraged to do so if it can be done easily), as well as any number of other standard or nonstandard formats for communicating with applications.
This function is called to begin an encoding session with the provided parameters. It should return CODEC_STATUS_OK on success or an error code otherwise. On successful completion, the codec should fill in appropriate values for the following members of the encode_session structure:
typedef struct { codec_instance *cinst; int format; void *reserved; // Used for storing UCI internal data (don't touch!) // Session information filled in by encode_init size_t min_raw_buffer_size; size_t max_raw_buffer_size; size_t encode_buffer_size; size_t stream_header_size; char *stream_header; void *codec_data; } encode_session;
min_raw_buffer_size/max_raw_buffer_size - This indicates the minimum and maximum amount of raw data that can be handled by one call to encode_data. For video codecs, these should both be set to the size of one frame.
encode_buffer_size - This should contain the minimum size of buffer which is guaranteed to hold max_raw_buffer_size's worth of encoded data.
stream_header and stream_header_size - If the encoding format needs a "header" to be stored in the file to contain format parameter information, stream_header should point to the data structure that should be stored for this purpose. stream_header_size contains the size of the structure to write. If this data is allocated from the heap, it should be freed later by encode_end.
codec_data - This pointer can be used to point to any codec-internal data associated with this session, or otherwise identify the session to the codec. Its contents are private to the codec.
typedef struct codec_data_st { int flags; int buffer_id; char *buffer; size_t data_begin; size_t data_end; void (*unlock_func)(void *); void *unlock_data; } codec_data;
flags
can be one or more of the following:
[This needs to be documented]
The following issues may still need to be considered in greater detail: