= Technical Specification = Livido 1.0 beta version. (C) Gabriel "Salsaman" Finch, Niels Elburg, Dennis "Jaromil" Rojo, Daniel Fischer, Martin Bayer, Kentaro Fukuchi, Andraz Tori 2005. == LIVIDO_API_VERSION == This is defined as 100 for this version of the specification. == LIVIDO GENERAL DESIGN == Livido is an architecture to enable interchange of video processing plugins between video applications in a standardized and compatible way. Livido plugin is a shared object that application can load. Inside a plugin there can be implementations of many different filters, each filter implementation is called a filter class. Host gets to know a list of classes a plugin provides when calling livido_setup function. A class description includes descriptions of inputs and outputs filter can handle. Inputs and outputs can be channels and parameters. Descriptions of acceptable types of channels and parameters are called channel templates and parameter templates respectively. Host prepares for instantination of the filter by setting input and output channels and input parameters and then instantinates a filter. Host can use process_func() on that instance until it deinits an instance. All passing of data between hosts and plugins is done trough ports, ports are the only C structures defined in Livido. == PORTS == A ''port'' is a set of one or more ''properties'': Each port has a mandatory property called "type" (see below), depending upon "type" property port has other mandatory and optional properties. "type" can be one of: * LIVIDO_PORT_TYPE_PLUGIN_INFO : Information about plugin and list of filter classes it includes * LIVIDO_PORT_TYPE_FILTER_CLASS : Descriptive information about single filter class * LIVIDO_PORT_TYPE_CHANNEL_TEMPLATE : Information about what kinds of channels filter accepts * LIVIDO_PORT_TYPE_PARAMETER_TEMPLATE : Information about what kinds of parameters filter has * LIVIDO_PORT_TYPE_FILTER_INSTANCE : All data about an instance * LIVIDO_PORT_TYPE_CHANNEL : Instantination of a channel * LIVIDO_PORT_TYPE_PARAMETER : Instantination of a parameter * LIVIDO_PORT_TYPE_GUI : described in the separate [wiki:TechnicalSpecCurrentGUI livido GUI extension] (TODO) "type" is a single valued property with atom_type LIVIDO_ATOM_TYPE_INT. The "type" is passed as a parameter in the livido_port_new() function as: {{{ livido_port_t *livido_port_new( int port_type ); }}} This returns a pointer to newly allocated port with the "type" property set to ''port_type''. Port types >=512 are available for custom use. == PROPERTIES == As mentioned above, each port is a set of one or more properties.[[BR]] A property has: * a ''key'' (which is a non-NULL string - (const char *) ASCII encoded) * a ''value'' (0 or more elements) * ''number of elements'' (>=0) contained in the value field. * an ''atom_type'' * a bitmap ''flags'' field == PROPERTY RESTRICTIONS == Access to properties is restricted in certain cases, these are restriction flags used troughout this document: * HOSTSET - Read-only for the plugin * PLUGINSET - Read-only for the host * FINAL - Not allowed to change after it was set * MANDATORY - mandatory property that MUST exist at some point in time * OPTIONAL - property that COULD exist Properties inherit restriction of the port where we do not specify otherwise. == ATOM TYPES == LiViDO offers the following '''fundamental''' types (number <64):[[BR]] * LIVIDO_ATOM_TYPE_INT : signed int32_t * LIVIDO_ATOM_TYPE_DOUBLE : corresponds to C type "double" * LIVIDO_ATOM_TYPE_BOOLEAN : signed int32_t, constrained to take values 0 (FALSE) or 1 (TRUE) * LIVIDO_ATOM_TYPE_STRING : array of char '''Note''': STRINGS are all utf-8 encoded in Livido, except property Keys, which are ASCII encoded. '''Pointer''' types (number>=64 and <512): * LIVIDO_ATOM_TYPE_VOIDPTR : corresponds to C void * type * LIVIDO_ATOM_TYPE_PORTPTR : livido_port_t * : a void * to a livido_property_t, currently used only for channel properties "same_as_size", "same_as_palette") * LIVIDO_ATOM_TYPE_INIT_F : pointer to a livido_init_f function * LIVIDO_ATOM_TYPE_PROCESS_F : pointer to a livido_process_f function * LIVIDO_ATOM_TYPE_DEINIT_F : pointer to a livido_deinit_f function Types >=512 are available for custom use. Custom atom types must be pointer types, since livido cannot guess their byte size or type. == PORT TYPE PLUGIN INFO == Port enables a plugin function livido_setup to tell the host what filter classes are available. Port is PLUGINSET and FINAL after livido_setup() finishes. * "type" == LIVIDO_PORT_TYPE_PLUGIN_INFO '''Mandatory properties''':[[BR]] * "filters" : LIVIDO_ATOM_TYPE_PORTPTR : atom or array of livido_filter_t, * "maintainer" : LIVIDO_ATOM_TYPE_STRING : maintainer of plugin package * "version" : LIVIDO_ATOM_TYPE_STRING : plugin package version * "api_version" : LIVIDO_ATOM_TYPE_INT : livido api version: MUST be set to the LIVIDO_API_VERSION as defined above in this spec '''Optional properties''':[[BR]] * "url" : LIVIDO_ATOM_TYPE_STRING : URL of plugin package == PORT TYPE FILTER CLASS == Port type filter class is used to describe all properties of a single filter class. Port is PLUGINSET and FINAL after livido_setup(). "type" == LIVIDO_PORT_TYPE_FILTER_CLASS '''Mandatory properties''':[[BR]] * "name" : LIVIDO_ATOM_TYPE_STRING : the filter name; must be unique in the plugin, * "author" : LIVIDO_ATOM_TYPE_STRING : the filter author(s) * "description" : LIVIDO_ATOM_TYPE_STRING : filter description * "version" : LIVIDO_ATOM_TYPE_INT : filter version * "license" : LIVIDO_ATOM_TYPE_STRING : license of filter * "flags" : LIVIDO_ATOM_TYPE_INT : bitmap of filter flags * "init_func" : LIVIDO_ATOM_TYPE_INIT_F : pointer to a init_func() * "process_func" : LIVIDO_ATOM_TYPE_PROCESS_F : pointer to a process_func() * "deinit_func" : LIVIDO_ATOM_TYPE_DEINIT_F : pointer to a deinit_func() * "in_channel_templates" : LIVIDO_ATOM_TYPE_PORTPTR, list of 0 or more elements: input ports of input channel templates, '''type''' of the referenced port MUST be LIVIDO_PORT_TYPE_CHANNEL_TEMPLATE * "out_channel_templates" : LIVIDO_ATOM_TYPE_PORTPTR, list of 0 or more elements : ports of output channel templates, '''type''' of the referenced port MUST be LIVIDO_PORT_TYPE_CHANNEL_TEMPLATE * "in_parameter_templates" : LIVIDO_ATOM_TYPE_PORTPTR, list of 0 or more elements : ports of input parameter templates, '''type''' of the referenced port MUST be LIVIDO_PORT_TYPE_PARAMETER_TEMPLATE * "out_parameter_templates" : LIVIDO_ATOM_TYPE_PORTPTR, list of 0 or more elements : ports of output parameter templates, '''type''' of the referenced port MUST be LIVIDO_PORT_TYPE_PARAMETER_TEMPLATE '''Optional properties''': [[BR]] * "url" : LIVIDO_ATOM_TYPE_STRING == PORT TYPE FILTER INSTANCE == Port type filter instance is used to hold all data that are related to a single instance of the filter all properties of a single filter class. Port is HOSTSET after livido_setup. "type" == LIVIDO_PORT_TYPE_FILTER_INSTANCE '''Mandatory properties''':[[BR]] * "filter_class" : LIVIDO_ATOM_TYPE_PORTPTR : Pointer to a filter class port this filter instance is based on * "in_channels" : LIVIDO_ATOM_TYPE_PORTPTR, list of 0 or more elements : ports of input channels, '''type''' of the referenced port MUST be LIVIDO_PORT_TYPE_CHANNEL * "out_channels" : LIVIDO_ATOM_TYPE_PORTPTR, list of 0 or more elements : ports of output channels , '''type''' of the referenced port MUST be LIVIDO_PORT_TYPE_CHANNEL * "in_parameters" : LIVIDO_ATOM_TYPE_PORTPTR, list of 0 or more elements : ports of input parameters, '''type''' of the referenced port MUST be LIVIDO_PORT_TYPE_PARAMETER * "out_parameters" : LIVIDO_ATOM_TYPE_PORTPTR, list of 0 or more elements : ports of output parameters, '''type''' of the referenced port MUST be LIVIDO_PORT_TYPE_PARAMETER '''Optional properties''':[[BR]] * Every filter instance can have its internal properties stored inside this port, and host MUST ignore them. Those internal properties MUST have keys prefixed with "PLUGIN_" * Every host can have its internal properties stored inside this port, and filter MUST ignore them. Those internal properties MUST have keys prefixed with "HOST_" == PORT TYPE CHANNEL TEMPLATE == Port type channel template is used as a description of a single channel (input or output) a filter can handle. Port is PLUGINSET and FINAL after livido_setup. * "type" == LIVIDO_PORT_TYPE_CHANNEL_TEMPLATE '''Mandatory properties''': [[BR]] * "name" : LIVIDO_ATOM_TYPE_STRING : name of the channel, MUST be unique across all channels in the filter class * "flags" : LIVIDO_ATOM_TYPE_INT : bitmap of channel_flags that plugin sets * "palette_list" : LIVIDO_ATOM_TYPE_INT : the plugin sets this to an array of allowed palettes for the channel. Its order is plugin's preference for a palette '''Optional properties''': [[BR]] * "description" : LIVIDO_ATOM_TYPE_STRING : description of this channel * "width" : LIVIDO_ATOM_TYPE_INT : If set, frame width in pixels that a plugin can handle. If it is set, host is forbidden to set the width in channel instance to anything else * "height" : LIVIDO_ATOM_TYPE_INT : If set, frame height in pixels that a plugin can handle. If it is set, host is forbidden to set the height in channel instance to anything else * "same_as_size" : LIVIDO_ATOM_TYPE_PORTPTR : plugin can set this to indicate that this channel must match "height" and "width" with another channel. The pointer points to another in/out channel template * "same_as_palette" : LIVIDO_ATOM_TYPE_PORTPTR : plugin can set this to indicate that this channel must match "current_palette" with another channel. The pointer points to another in/out channel template * "optional" : LIVIDO_ATOM_TYPE_BOOLEAN : the plugin may set this to TRUE for channels that can be left out at initialization time. '''Restrictions to properties'''[[BR]] Each channel template can only reference another through *_same_as or be referenced by another, not both.[[BR]] There can be only backward references in the array. For example channel 2 can have *_same_as to channel 1, but not the other way around.[[BR]] Output channels can, however, reference input channels at will == PORT TYPE CHANNEL == Port type channel is used as a fixation of channel properties that the host sets and plugin reads to know what it is getting. Port is HOSTSET after init_func(). Channels should be a one-one match with channel templates (same order, same number). * "type" == LIVIDO_PORT_TYPE_CHANNEL '''Mandatory properties''': [[BR]] * "parent_template" : LIVIDO_ATOM_TYPE_PORT : Pointer to a channel template port this channel instance is based on. FINAL. * "timecode" : LIVIDO_ATOM_TYPE_DOUBLE : time in seconds for this channel, host can choose what exactly it represents * "width" : LIVIDO_ATOM_TYPE_INT : The chosen frame width in pixels * "height" : LIVIDO_ATOM_TYPE_INT : The chosen height in pixels * "current_palette" : LIVIDO_ATOM_TYPE_INT: The chosen palette, which must be one of the palettes contained in "palette_list" of a channel template * "pixel_data" : LIVIDO_ATOM_TYPE_VOIDPTR : array of size 4 of pointers to the image pixels data. depending on the value of "current_palette", only the first pointer is used for packed modes and in planar modes each plane has its own pointer. * "rowstrides" : LIVIDO_ATOM_TYPE_INT : array of size 4 carrying the row width of EACH PLANE in bytes (include padding) '''Optional properties''': [[BR]] * "fps" : LIVIDO_ATOM_TYPE_DOUBLE : fps of channel; * "pixel_aspect_ratio" : LIVIDO_ATOM_TYPE_DOUBLE : physical aspect ratio of the pixel of the image (pixel aspect ratio different than 1.0 means pixels are non-square) * "v_shift" : LIVIDO_ATOM_TYPE_INT : vertical shift in the pixels of the sampling of crominance planes for planar yuv palletes * "h_shift" : LIVIDO_ATOM_TYPE_INT : horizontal shift in the pixels of the sampling of crominance planes for planar yuv palletes * "YUV_sampling" : LIVIDO_ATOM_TYPE_INT : Sampling type for YUV palettes, enum defined below * "interlacing" : LIVIDO_ATOM_TYPE_INT : Interlacing type, defined below. if not present, the image must be NON INTERLACED * "disabled" : LIVIDO_ATOM_TYPE_BOOLEAN : the host MAY set this to TRUE before calling init_func() if the coresponding channel template has optional property set to true == PORT TYPE PARAMETER TEMPLATE == Port type parameter template is used as a description of a single parameter (input or output) filter can handle. Port is PLUGINSET and FINAL after livido_setup. '''Mandatory properties''': [[BR]] * "name" : LIVIDO_ATOM_TYPE_STRING : name of the parameter, MUST be unique across the in_parameter_templates/out_parameter_templates * "default" : any of the fundamental atom type : sane default value of the parameter * "kind" : LIVIDO_ATOM_TYPE_STRING : Tells the host the _minimal_ needed information to be able to present a parameter. Depending of the value of "kind", there are additional properties that are mandatory or optional. The rules for additional properties are spelled out below. '''Optional properties''':[[BR]] * "flags" : LIVIDO_ATOM_TYPE_INT : Plugin sets this to LIVIDO_PARAMETER_CHANGE_UNADVISED if a change in the "value" of instance of the parameter causes some kind of internal reinit of the plugin (realtime hosts can use this to be able to avoid slow behaviour of he plugins). * "description" : LIVIDO_ATOM_TYPE_STRING : parameter description, FINAL ==== PARAMETER CONSTRAINING ==== Parameter constraining in Livido is minimalistic, all GUI related stuff is to be defined in separate document. Parameter constraining is derived from additional properties defined for parameter template that depend on the value of the property "kind". The '''kind''' is a mandatory property of every parameter, the defined values are: * "INDEX" (discrete) * "NUMBER" (continuous) * "TEXT" (utf-8) * "SWITCH" (boolean) * "COLOR_RGBA" * "COORDINATE" Depending on the "kind" parameter atom type and mandatory additional properties MUST BE: * "INDEX" Kind index means a discret number, which can be used for index choosing or passing integer values. It is constrained by min and max: min <= value <= max The '''default''' property can only be of atom type LIVIDO_ATOM_TYPE_INT. Additional properties that kind causes: * '''min''' : LIVIDO_ATOM_TYPE_INT : minimal value of the parameter, MANDATORY * '''max''' : LIVIDO_ATOM_TYPE_INT : maximal value of the parameter, MANDATORY * '''wrap''' : LIVIDO_ATOM_TYPE_BOOLEAN : indicates that the "value" should wrap when going below min or above max, OPTIONAL * "NUMBER" Kind index means a continuous number, which can be used for index choosing or passing integer values. It is constrained by min and max: min <= value <= max The '''default''' property can only be of atom type LIVIDO_ATOM_TYPE_DOUBLE. Additional properties that kind causes: * '''min''' : LIVIDO_ATOM_TYPE_DOUBLE : minimal value of the parameter, MANDATORY for in parameters, OPTIONAL for out parameters. * '''max''' : LIVIDO_ATOM_TYPE_DOUBLE : maximal value of the parameter, MANDATORY for in parameters, OPTIONAL for out parameters. * '''wrap''' : LIVIDO_ATOM_TYPE_BOOLEAN : indicates that the "value" should wraped when going below min or above max, OPTIONAL * '''transition''' : LIVIDO_ATOM_TYPE_BOOLEAN : Indicates that this parameter is transition, OPTIONAL * "TEXT" Kind text means a string, which can be used for passing strings. The '''default''' property can only be of atom type LIVIDO_ATOM_TYPE_STRING. * "SWITCH" Kind switch can be used for passing yes/no choices. The '''default''' property can only be of atom type LIVIDO_ATOM_TYPE_BOOLEAN. * "COLOR_RGBA" Kind color can be used for passing colors. Colors are represented as a list of 3 or 4 elements of type LIVIDO_ATOM_TYPE_DOUBLE. Depending on the default value, host knows if it has to pass 3 or 4 elements in the list to filter. Values of elements consecutively are red, green, blue and alpha, values are generally between 0.0 and 1.0.ccc Additional properties that kind causes: * '''min''' : LIVIDO_ATOM_TYPE_DOUBLE array of N elements: minimal value of the parameter, MANDATORY * '''max''' : LIVIDO_ATOM_TYPE_DOUBLE array of N elements: maximal value of the parameter, MANDATORY * "COORDINATE" Kind coordinate can be used for passing 2d normalized cartesian coordinats. Coordinates are represented as a list of 2 elements of type LIVIDO_ATOM_TYPE_DOUBLE. First value in a list presents an x coordinate and second one y in cartesian coordinates, coordinates inside the picture they relate to are considered to be between 0.0 and 1.0 The '''default''' property can only be of atom type LIVIDO_ATOM_TYPE_DOUBLE and an array of 2 elements. Additional properties that kind causes: * '''min''' : LIVIDO_ATOM_TYPE_DOUBLE array of 2 elements: minimal value of the parameter, MANDATORY * '''max''' : LIVIDO_ATOM_TYPE_DOUBLE array of 2 elements: maximal value of the parameter, MANDATORY == PORT TYPE PARAMETER == Port type parameter is used for passing a single (input or output) . Input parameters are HOSTSET and output parameters are PLUGINSET. Parameters should be a one-one match with channel templates (same order, same number). '''Mandatory properties''': [[BR]] * "parent_template" : LIVIDO_ATOM_TYPE_PORT : Pointer to a parameter template port this parameter instance is based on * "value" : type of the value MUST match the type of '''default''' property of the parent_template == GETTING/SETTING PROPERTY VALUES == On livido_property_set(), the host/plugin programmer does not need to worry about allocating and freeing memory for the data to store. The model (or more precisely the Mediation layer) will take care of that for you. If you store an object the model will make a copy and store that. Later, when you set a new value in this property, the model will automatically livido_free() the old value and make a copy of the new value and store the copy. The exception to this is any atom type of type PTR. If you allocate a chunk of data or a complex structure only the pointer value is stored (!). The model does not know anything about the content of the data your pointer refers to so it will not make a copy. Instead, you need to allocate and free the memory yourself in this case. The plugin and host programmer can both retrieve and set values by Key. On livido_property_get(), Livido will copy the data stored in the property, except for pointer types. For pointer types only the reference to the memory block is copied. The programmer should first allocate a memory area for livido_property_get() to copy to. For setting pointer types, host/plugin must pass in a size_t array with the atom sizes. == LIVIDO CORE FUNCTIONS == All host implementations must implement and offer the following core functions. The functions reside inside a host and plugin dynamically links to them upon loading. * livido_port_t *livido_port_new (int port_type) * void livido_port_free (livido_port_t *port) // only used by host * char **livido_list_properties (livido_port_t *port) // returns NULL terminated char * array of properties * int livido_property_set (livido_port_t *port, const char *key, int atom_type, int num_elems, void *value) // returns a livido error * int livido_property_get (livido_port_t *port, const char *key, int idx, void *value) // returns a livido error * int livido_property_num_elements (livido_port_t *port, const char *key) * size_t livido_property_element_size (livido_port_t *port, const char *key, int idx) * int livido_property_atom_type(livido_port_t *port, const char *key) * void *livido_malloc_f (size_t size) * void livido_free_f (void *ptr) * void *livido_memset_f (void *s, int c, size_t n) * void *livido_memcpy_f (void *dest, const void *src, size_t n) '''Notes''':[[BR]] livido_port_new() will set the "type" property to ''port_type'', and will set it readonly. livido_property_set() will create the property if the property does not exist. livido_property_set() will return LIVIDO_ERROR_PROPERTY_READONLY if the property has the flag bit LIVIDO_PROPERTY_READONLY set. livido_property_set() will return an error LIVIDO_ERROR_WRONG_ATOM_TYPE if you try to change the atom_type of a property. For livido_property_set(), num_elems can be 0 and value can then be NULL. In this way, just the atom_type of the property can be set. The ''sizes'' field of livido_property_set() is only used for pointer type values. It should be an array of size num_elems. For fundamental types, the sizes field should be set to NULL. livido_property_get() will return LIVIDO_ERROR_NOSUCH_PROPERTY if a property does not exist. In this way the existence of a property can be determined. To assist with this, livido_property_get() can be called with a NULL void * value. The function will then not attempt to copy the value, but will return either LIVIDO_ERROR_NOSUCH_PROPERTY, or LIVIDO_NO_ERROR depending on whether the property exists or not. The return values of livido_property_num_elements(), livido_property_element_size(), livido_property_atom_type(), and livido_property_get_readonly() are all undefined if the property does not exist. The void * for livido_property_set() and livido_property_get() is a (void *) typecast to/from an array of the appropriate type: e.g. for LIVIDO_ATOM_TYPE_INT it is an int *. The number of elements in the array must match num_elems in livido_property_set(). Functions livido_malloc_f(), livido_free_f(), livido_memset_f(), livido_memcpy_f() have exactly the same semantics as malloc, free(), memset() and memcpy() from libc. Their purpose is to allow a host to provide a plugin with the application-specific memory managment. Plugins MUST NOT use malloc, free and memset, but have to use livido counterparts. == PLUGIN FUNCTIONS == The only symbol plugin MUST export is livido_setup() function pointer, all other information is passed through respective ports (classes, functions, etc...) ==== livido_setup ==== {{{ livido_port_t *livido_setup(void); }}} This function returns a PLUGIN INFO port that specifies what is the content of this plugin - which filter classes it has, who is the maintainer, etc. Plugin implements livido_setup() in following way: the PLUGIN INFO port is first created by using livido_port_new(). The individual filters are then created and added to the property "filters" in the PLUGIN INFO port. If no filters can be created (because of memory or other problems), the function should return NULL. The returned port MUST have '''type''' LIVIDO_PORT_TYPE_PLUGIN_INFO. ==== init_func ==== {{{ int init_func(livido_port_t *) }}} The port MUST have '''type''' LIVIDO_PORT_TYPE_FILTER_INSTANCE The host calls this and passes in the desired filter. The filter port instance passed to the init_func MUST have been correctly setup to match the filter class it relats to, this means that all the mandatory properties of input and output channels and of input parameters MUST be set. The function returns a livido error code (see below). The init_func() function allows the plugin to create any internal memory structures it needs; plugin store internal data as properties that have keys prefixed with "PLUGIN_" (see the definition of filter intance port) ==== process_func ==== {{{ int process_func(livido_port_t *, double timestamp) }}} The port MUST have '''type''' LIVIDO_PORT_TYPE_FILTER_INSTANCE host calls this for each processing cycle; the plugin can do its frame processing here. The function returns a livido error code (see below). Timestamp is the presentation time in seconds (can be e.g. time since playback start). The function returns a livido error code (see below). ==== deinit_func ==== {{{ int deinit_func(livido_port_t *) }}} The port MUST have '''type''' LIVIDO_PORT_TYPE_FILTER_INSTANCE host calls this to allow the plugin to free() any internal memory. Following this the host may free() the instance's port. The plugin does not need to free any ports or parameters, the host should take care of this.c == OUTLINE LIVIDO PROCESS FLOW OVERVIEW == * Host loads plugin (dlopen) * Host calls the livido_setup() function. * in livido_setup(), for each filter class, the plugin creates and initializes the port of a type LIVIDO_PORT_TYPE_FILTER_CLASS and adds it to the '''filter_list''' property of the returned port. * Host creates a FILTER_INSTANCE: Host examines the in_channel and out_channel ports, and sets the "disabled" flag for any optional channels it does not wish to use. It also checks "palette_list", selects a palette it would like to start using on that channel and sets the chosen value in the "current_palette" property. It also sets the sizes ("width" and "height" properties) if the plugin left them as zero. All input parameters have to have values set at this point. This means host now has a port that it will instantiate. * Host calls init_func() from the filter info port, passing a pointer to a FILTER_INSTANCE it would like to instantiate. * Plugin now knows the channel sizes, palettes and which channels are in use. The plugin may now livido_malloc() internal data. * Host may now change parameter values (respecting "max" and "min" properties) and it after that it may call process_func() in the plugin, passing in the initialised FILTER_INSTANCE. * When the host has finished with the FILTER_INSTANCE, or if it needs to re-initialise it, the host must call deinit_func() in the plugin, passing in a pointer to the FILTER_INSTANCE. The plugin MUST now livido_free() any internally allocated data. * Host can now livido_port_free() the FILTER_INSTANCE, or it can adjust the non-final properties of the ports used and reuse the FILTER_INSTANCE by calling init_func() once more. == LIVIDO FLAGS AND TYPES == ==== Livido palette types ==== Palettes are all unsigned in LiViDO. Some palettes have aliases; these are shown on the same line. '''RGB Palettes''' Palette numbers >0 and <512 {{{ LIVIDO_PALETTE_RGB888 LIVIDO_PALETTE_RGB24 LIVIDO_PALETTE_BGR888 LIVIDO_PALETTE_BGR24 LIVIDO_PALETTE_RGBA8888 LIVIDO_PALETTE_RGBA32 LIVIDO_PALETTE_ARGB8888 LIVIDO_PALETTE_ARGB32 LIVIDO_PALETTE_RGBFLOAT LIVIDO_PALETTE_RGBAFLOAT LIVIDO_PALETTE_RGB565 }}} '''YUV Palettes''' Palette numbers >=512 and <1024 Ranges are 16-235 for Y, 16 - 240 for U and V. {{{ LIVIDO_PALETTE_YUV422P LIVIDO_PALETTE_YV16 [Official name 'YV16', 8 bit Y plane followed by 8 bit 2x1 subsampled V and U planes. Planar.] LIVIDO_PALETTE_YUV420P LIVIDO_PALETTE_YV12 [8 bit Y plane followed by 8 bit 2x2 subsampled V and U planes. Planar (Official name YV12)] LIVIDO_PALETTE_YVU420P LIVIDO_PALETTE_I420 [Same as YUV420P , but U and V are swapped. Planar.] LIVIDO_PALETTE_YUV444P [Unofficial , 8 bit Y plane followed by 8 bit U and V planes, no subsampling. Planar.] LIVIDO_PALETTE_YUVA4444P LIVIDO_PALETTE_YUV4444P [Unofficial, like YUV444P but with Alpha. Planar.] LIVIDO_PALETTE_YUYV8888 [Like YUV 4:2:2 but with different component ordering within the u_int32 macropixel. Packed.] LIVIDO_PALETTE_UYVY8888 [YUV 4:2:2 (Y sample at every pixel, U and V sampled at every second pixel horizontally on each line). A macropixel contains 2 pixels in 1 u_int32. Packed.] LIVIDO_PALETTE_YUV411 [IEEE 1394 Digital Camera 1.04 spec. Is packed YUV format with a 6 pixel macroblock structure containing 4 pixels. Ordering is U2 Y0 Y1 V2 Y2 Y3. Uses same bandwith as YUV420P Only used for SMPTE DV NTSC.] }}} '''Alpha Palettes''' Palette numbers >=1024 and <2048 Alpha palettes have two uses: 1) for masks, 2) to split colour inputs into single colour channels, or to combine single colour channels into a combined channel. The order of colour channels is the same as the order in the combined channel. For example if an input in RGB24 palette is split into 3 non-mask alpha channels, then the alpha channels will be in the order: Red, Green, Blue. A single non-mask alpha channel would represent the luminance. {{{ LIVIDO_PALETTE_A1 LIVIDO_PALETTE_A8 LIVIDO_PALETTE_AFLOAT }}} Palette numbers >=2048 are available for custom palettes. ==== Filter flags ==== * LIVIDO_FILTER_NON_REALTIME[[BR]] non-realtime filter property: the filter is too slow to use in realtime processing. * LIVIDO_FILTER_CAN_DO_INPLACE[[BR]] If this property is set, the filter can do inplace operations. Hosts can select this mode by setting "pixel_data" for the first out_channel to NULL. Plugin will then return the output in "pixel_data" of the first in_channel. This can save a memcpy() in the host. * LIVIDO_FILTER_STATEFUL[[BR]] plugin is stateful ; it has information about what occurred previously. I.e. it has internal state data. * LIVIDO_FILTER_IS_CONVERTER[[BR]] This flag bit should be set if the plugin does not alter the image pixels except for resizing or palette conversion between in channel and out channel(s). It should only be set for the following types of plugins: plugins which only resize the in frame to out frame(s); plugins which only convert the palette from in frame to out frame(s), plugins which simply duplicate the in frame to out frame(s). It is used to assist with categorisation of the plugin type. Flag bits >=30 are available for custom flags. ==== Channel flags ==== * LIVIDO_CHANNEL_CHANGE_UNADVISED[[BR]] plugin MAY use this flag to tell the host, that changing of channel size causes possibly unwanted behaviour of the filter. Unwanted behaviour can for example be reseting the accumulated values which causes the visual result of filter to change in unexpected way or maybe the next call to process function will take disproportional amount of time due to reinitialization. Host is safe to ignore the flag and plugin MUST still be useful, though functionality may suffer. * LIVIDO_CHANNEL_PALETTE_UNADVISED[[BR]] plugin MAY use this flag to tell the host, that changing of channel palette causes possibly unwanted behaviour of the filter. Unwanted behaviour can for example be reseting the accumulated values which causes the visual result of filter to change in unexpected way or maybe the next call to process function will take disproportional amount of time due to reinitialization. Host is safe to ignore the flag and plugin MUST still be useful, though functionality may suffer. Flag bits >=30 are available for custom flags. ==== Parameter flags ==== * LIVIDO_PARAMETER_CHANGE_UNADIVSED[[BR]] plugin MAY use this flag to tell the host, that changing of this parameter causes possibly unwanted behaviour of the filter. Unwanted behaviour can for example be reseting the accumulated values which causes the visual result of filter to change in unexpected way or maybe the next call to process function will take disproportional amount of time due to reinitialization. Host is safe to ignore the flag and plugin MUST still be useful, though functionality may suffer. Flag bits >=30 are available for custom flags. ==== Property flags ==== * LIVIDO_PROPERTY_READONLY Flag bits >=30 are available for custom flags. ==== YUV sampling types ==== * LIVIDO_YUV_SAMPLING_NONE : No subsampling (always YUV 4:4:4) * LIVIDO_YUV_SAMPLING_SMPTE : Chroma is sampled at half the horizontal frequency and is aligned horizontally with luma samples (YUV 4:2:2) * LIVIDO_YUV_SAMPLING_JPEG : Chroma is sampled at half the horizontal and half the vertical frequency. (YUV 4:2:0). Chroma samples are centered between luma samples. * LIVIDO_YUV_SAMPLING_MPEG2 : Same as JPEG, but Chroma samples are horizontally aligned and vertically centered between luma samples. There is notion of fields. (YUV 4:2:0) * LIVIDO_YUV_SAMPLING_DVPAL : Subsampling per field, Chroma samples are located above luma samples, but CB and CR samples are located on alternate lines (YUV 4:2:0) * LIVIDO_YUV_SAMPLING_DVNTSC : Chroma is sampled at 1/4 the horizontal frequency as luma but at full vertical frequency. The chroma samples are horizontally aligned with luma samples. (YUV 4:1:1) Sampling types >=1024 are available for custom samplings. ==== Interlace types ==== * LIVIDO_INTERLACE_NONE * LIVIDO_INTERLACE_TOPFIRST * LIVIDO_INTERLACE_BOTTOMFIRST * LIVIDO_INTERLACE_PROGRESSIVE Interlace types >=1024 are available for custom interlacing. == Livido errors == * LIVIDO_NO_ERROR[[BR]] return code means no problem * LIVIDO_ERROR_MEMORY_ALLOCATION[[BR]] memory allocation by the filter has failed * LIVIDO_ERROR_PROPERTY_READONLY[[BR]] plugin/host tried to set readonly property; returned from livido_property_set() * LIVIDO_ERROR_NOSUCH_ELEMENT[[BR]] plugin/host tried to read value of an invalid element number in a property; returned from livido_property_get() * LIVIDO_ERROR_NOSUCH_PROPERTY[[BR]] property does not exist for the specified port; returned from livido_property_get() * LIVIDO_ERROR_WRONG_ATOM_TYPE[[BR]] once the atom_type of a property is set, you cannot change it. livido_property_set() will return this error if you attempt such a thing, and the value of the property will not be amended. * LIVIDO_ERROR_TOO_MANY_INSTANCES[[BR]] can't create: plugin allows only limited number of filter instances, returned from init_func() * LIVIDO_ERROR_HARDWARE[[BR]] there was an error initialising hardware for the filter; returned from init_func() Error numbers >=1024 are available for custom errors.