= Livido Roadmap = notes from Tilburg ----------------- = function headers used in plugin code = :: inner API specification // basic functions /// allocation for the port - plugin livido_port_t *lvd_init_port(int port_type); // host fn int lvd_free_port(livido_port_t *port); /// property functions - host + plugin // checks if read-only flag is set int lvd_set_property (livido_port_t *port, const char *key, int atom_type, void *value, int num_elements); int lvd_get_property(livido_port_t *port, const char *key, void *value); // host int lvd_del_property(livido_port_t *port, const char *key); // host livido_storage_t *lvd_get_property_storage(livido_port_t *port, const char *key); ///< returns the livido_storage_t from where to retrieve num_elements, atom size and atom type ... // host char **lvd_list_properties(livido_port_t *port); //// vvvv bottom vvvv livido_atom_t *livido_alloca_atom(int atom_type, void *value, size_t size); livido_free_atom(); :: plugin API ////////////////////////////////////////////////// int livido_setup(livido_filter_t **filters) { // returns the number of filters available, fill up filters livido_filter_t *filt; filt=livido_init_filter(); filt->info=lvd_init_info( // name author version api_version flags "example plugin","livido team",1, 1, 0x0, // function pointers &my_init,&my_process,&my_deinit, // input channels, output channels 1, 1, 1, 0); lvd_set_string(filt->info,"license","gpl2"); // we are the plugin so we know how many channels are there! lvd_init_channel(filt->inchannels[0], "input", ); lvd_init_param_int32; filt->info = livido_init_port( 5, LIVIDO_FILTER_NAME,AUTHOR, VERSION, API , FLAGS, "example plugin", "livido tream". 1, 1, 0x0 ); } int my_init(livido_filter_t *filter); int my_process(livido_filter_t *filter); int my_deinit(livido_filter_t *filter); livido_filter_t *livido_get_filter(int index);// get_metadata // init, process and deinit are pointers inside filter->info ------------- = notes by salsaman and list of ports = plugins return multiple port sets ! we must be able to copy complete ports for the host At top level we have: plugin plugin has 1 or more filters filter has 5 port sets 1 instance port 1 in_channels port array 1 out_channels port array 1 in_parameters port array 1 out_parameters port array port a port has 1 or more properties some properties are mandatory some are optional the mandatory and optional properties depend on the port_type port_type : this is a list with type livido_port_type_int it is set in the port property "type" when the port is initialised. The type is passed as a parameter in the init_port function : TODO function template for init_port. TODO: do we really need to store this ? Niels: Storing the type is necessary for things like parameter conversion/scaling. Yes. Plus the way I have it, a port always needs at least one property. "type" can be it. port_type can be one of: LIVIDO_PORT_TYPE_INSTANCE LIVIDO_PORT_TYPE_CHANNEL LIVIDO_PORT_TYPE_INT32 LIVIDO_PORT_TYPE_FLOAT LIVIDO_PORT_TYPE_RGB LIVIDO_PORT_TYPE_RGBA LIVIDO_PORT_TYPE_BOOLEAN LIVIDO_PORT_TYPE_STRING LIVIDO_PORT_TYPE_TRANSITION LIVIDO_PORT_TYPE_STRING_LIST LIVIDO_PORT_TYPE_COORD Niels: The type specifier is set by ATOM_TYPE (so we dont need INT/DOUBLE as port type) GF: There is a problem with that, DOUBLE has a mandatory property: "decimals", INT does not have this property. What happened to RGB/RGBA ?? And I have used BOOLEAN in place of SWITCH. STRING is better than TEXT I think. Everything apart from an instance and a channel is known as a parameter. After the port type is set, the other properties, mandatory and optional are known. Properties Each port has a linked list of properties A property has: - a key - a value - flags Niels: - next pointer to next property - flags is a bit field. One bit represents "read-only", and it can be set/cleared at any time. - key is a non-NULL const char *, unique for that port - value is livido_storage Niels: init_port sets ANY property (we talked about this!) in ANY order GF: My implementation gets around this by providing. eg. livido_init_int32_param. Some port/property pairs can take only one type of atom. Others give a choice for atom types. eg. for LIVIDO_PORT_TYPE_INT, "value", only atom type INT is allowed. for LIVIDO_PORT_TYPE_RGB, "value", atom type can be INT or DOUBLE or STRING. Niels: eg. for LIVIDO_PORT_TYPE_NUMBER "value", only atom type INT and DOUBLE are allowed. Niels: eg. for LIVIDO_PORT_TYPE_COLORKEY "value", atom types are INT,DOUBLE and STRING For some port types therefore, we must pass in an extra parameter to our init_port function, which tells the type of these "choice" properties. This is set as the atom type of the "value" property. Once this is set it is constant for that port. For other properties which take a choice of atom types in that port, their atom type must match the atom type of the "value" property. Atom types: LIVIDO_ATOM_TYPE_INT32 LIVIDO_ATOM_TYPE_DOUBLE LIVIDO_ATOM_TYPE_BOOLEAN LIVIDO_ATOM_TYPE_CHARPTR LIVIDO_ATOM_TYPE_VOIDPTR LIVIDO_ATOM_TYPE_UINT8PTR LIVIDO_ATOM_TYPE_INT8PTR LIVIDO_ATOM_TYPE_UINT16PTR LIVIDO_ATOM_TYPE_INT16PTR LIVIDO_ATOM_TYPE_UINT32PTR LIVIDO_ATOM_TYPE_INT32PTR TODO : we need "long" for timecode ! Niels: would that fit in a double ? (abuse) Lets add LIVIDO_ATOM_TYPE_LONG Done. as well as atom type, each property has a number of elements, sometimes this is fixed (e.g. 3 for rgb/value, 0 - n for channel/pixel_data - depending on setting of "current_palette"). For example, for LIVIDO_PORT_RGB8, the "value" property can accept atom_types int or double, and has 3 elements. livido_storage: at this level we have - number of elements - a union of atom * and atom ** number of elements, is a uint32_t > 0 the union contains an atom * if number of elements == 1 otherwise it containts a atom ** By convention, a livido_storage may only take one type of atom, and once the first atom in the storage is set, this is constant for the life of the port. Niels: the atom is not constant ; its value is updated on put_value ... Niels: the type of atom is constant and cannot be changed on put() Agreed. livido_atom a livido_atom has: - a size of type size_t - a void * value - a const uint32_t denoting the atom type ////////////////////////////////////////////////////////////////// as well as a function to init a port, there are functions to get and set properties. get/set can be by atom or by storage. Property values are copied on a get/set, except for pointer type atoms which are copied by reference. There is no built in type checking to ensure that the correct atom type is set in a port/property pair. The livido system takes care of updating storage, and copying atoms/storage. GF: charptr is also copied on get/set. If the property flag "read-only" is set, the set_property function will return an error, and not change the value. There is a function to return the atom type of port/property pair. There is a function to return the number of elements in port/property pair. There is a function to see if a particular port/property exists. There is a function to set the flags of a port/property. There is a function to get the size of an atom within a port/property. Niels: There is a function that gets the byte size of a single atom There is a function that gets the datatype of an atom There is a function that gets the length of an atom(1) or array(N) There is a function that finds a property There is a function that sorts the property list (searched item placed first in the list) This is for 2 things: deleting properties (!) and for making following acceses faster GF: deleting properties is a very bad idea. It should not be allowed in livido ! There is a function that sets the flag of a property There is a function that deletes a property (needed for free_port) There is a function that sets a property There is a function that gets a property There is a function that gets a property as There is a function that sets a property from another type (convert/scale on set) Function that lists properties There is a function that frees the port There is a function that allocates the port Disabled -------- This is an optional property for all port types except instance. It takes a single atom of type boolean. The plugin may set this property to TRUE for channels in the get_metadata() function. TODO : when does the plugin set this to TRUE for parameters - we need a trigger function for parameters. The host may set this to FALSE before calling init() in the plugin. int get_metadata() A plugin function which sets a port set. The host calls this any time after dlopen of the plugin. int init() The host calls this and passes back the port set, with some values changed. Prior to this, the host can change the "value" property of parameters. The host must also attend to "disabled" in the channel ports, and set the "current_palette" property in the channel ports. process() host calls this and passes port set as parameters. deinit() host calls this to finalise the port set setup(&unt32_t error) return number_of_classes (uint32_t) get_metadata(uint32_t index); returns: livido_class_t * struct { livido_port_t *instance; livido_port_t **in_channels; livido_port_t **out_channels; livido_port_t **in_parameters; livido_port_t **out_parameters; } host sets/clears "disabled" for channels, checks "palette_list" - int32 array sets "current_palette" - single int32 host can change "value" for any non-disabled in_parameter host calls init(livido_filter_t *) here plugin now knows number of channels in use knows "value" if all parameter loop: host calls: update_parameters(in_parameters); calls: process() : deinit(livido_filter_t *) Conversion functions -------------------- we provide functions for converting between atom types for some port/property pairs (i.e. those pairs which have a choice of atom types) Now we spec the functions; the port/property pairs, whether they are mandatory or optional, their types. Port type: meta Mandatory properties: "type" : "num_classes" : int32 "classes" : array of voidptr atoms Port type: info Mandatory properties: "type" : LIVIDO_ATOM_TYPE_INT32 : always equal to LIVIDO_PORT_TYPE_INSTANCE Niels: the "type" atom is really bogus; just have int port_type inside the Port Niels: Why ? Because "type" is really only a dummy property because it can only have Niels: LIVIDO_PORT_TYPE_INSTANCE GF: all property lists need at least one entry in livido. "name" : LIVIDO_ATOM_TYPE_CHARPTR : the filter name "author" : LIVIDO_ATOM_TYPE_CHARPTR : the filter author name "version" : LIVIDO_ATOM_TYPE_INT32 : filter verison "api_version" : LIVIDO_ATOM_TYPE_INT32 : livido api verison "flags" : LIVIDO_ATOM_TYPE_INT32 : bitmap of instance_flags "init_func" : LIVIDO_ATOM_TYPE_VOIDPTR : pointer to a livido_init_f "process_func" : LIVIDO_ATOM_TYPE_VOIDPTR : pointer to a livido_process_f "deinit_func" : LIVIDO_ATOM_TYPE_VOIDPTR : pointer to a livido_deinit_f num_in_channels : total number in array num_out_channels : total number in array num_in_parameters : total number in array num_out_parameters : total number in array ////////////////// optional /////////////////// "update_parameters_func" : LIVIDO_ATOM_TYPE_VOIDPTR : pointer to a livido_init_f "description" : LIVIDO_ATOM_TYPE_CHARPTR : filter description "license" : CHARPTR "url" : CHARPTR "keyframe_next_func" : LIVIDO_ATOM_TYPE_VOIDPTR : pointer to a livido_keyframe_next_f "keyframe_prev_func" : LIVIDO_ATOM_TYPE_VOIDPTR : pointer to a livido_keyframe_next_f "scale_x" : FLOAT "scale_y" : FLOAT "num_threads" : INT32 (==1 if not present) "fps" : FLOAT except if plugin requires "internal" : VOID_PTR /////////////////////////////////////////////////// Port type: channel Mandatory properties: "type" : LIVIDO_ATOM_TYPE_INT32 : always equal to LIVIDO_PORT_TYPE_CHANNEL "name" : STRING "flags" : LIVIDO_ATOM_TYPE_INT32 : bitmap of channel_flags "width" : LIVIDO_ATOM_TYPE_INT32 : width in pixels, plugin can set this is get_metadata to a non-zero value (zero means any) "height" : LIVIDO_ATOM_TYPE_INT32 : "palette_list" : same as stringlist but with INT atoms "current_palette" : INT32 set by host from palette_list "pixel_data" : LIVIDO_ATOM_TYPE_*PTR : number of elements varies depending on "current_palette" "rowstrides" : ///< length of one row in bytes (include padding) : same number of elements as "pixel_data" "timecode" : ///< timecode since 'play start' (RT) or start of the timeline (NLE) in microseconds : long ///////////////// optional /////////////// "window" : array of INT or FLOAT "v_shift" (INT) "h_shift" (INT) "interlacing" (INT) : Progressive,None (default) ,Topfirst,Bot.first "fps" (DOUBLE) : default is same as instance "fps" "same_as" : INT "disabled" : LIVIDO_ATOM_TYPE_BOOLEAN : plugin may create this property, host may not create it but may change its value before calling init() Port type: rgb Mandatory properties : "type", "name", "min", "max", "value" Optional properties: "step_size": FLOAT "page_size" : FLOAT "description" : LIVIDO_ATOM_TYPE_STRING "disabled" : BOOLEAN Port type: int32 Mandatory properties : "type" : LIVIDO_ATOM_TYPE_INT32 : always equal to LIVIDO_PORT_TYPE_INT32 "name" : LIVIDO_ATOM_TYPE_STRING "value" : LIVIDO_ATOM_TYPE_INT32 "min" : LIVIDO_ATOM_TYPE_INT32 "max" : LIVIDO_ATOM_TYPE_INT32 Optional : "description" : LIVIDO_ATOM_TYPE_STRING "disabled" : BOOLEAN Port type: float Mandatory properties : "type" : LIVIDO_ATOM_TYPE_INT32 : always equal to LIVIDO_PORT_TYPE_INT32 "name" : LIVIDO_ATOM_TYPE_STRING "value" : LIVIDO_ATOM_TYPE_FLOAT "min" : LIVIDO_ATOM_TYPE_FLOAT "max" : LIVIDO_ATOM_TYPE_FLOAT "decimals" : INT32 Optional : "description" : LIVIDO_ATOM_TYPE_STRING "disabled" : BOOLEAN Port type: string Mandatory properties : "type" : LIVIDO_ATOM_TYPE_INT32 : always equal to LIVIDO_PORT_TYPE_INT32 "name" : LIVIDO_ATOM_TYPE_STRING "value" : LIVIDO_ATOM_TYPE_STRING Optional : "min_length" : LIVIDO_ATOM_TYPE_FLOAT "max_length" : LIVIDO_ATOM_TYPE_FLOAT "padding_character" : CHARPTR "encoding" : CHARPTR (default is utf-8 if not set) "description" : LIVIDO_ATOM_TYPE_STRING "disabled" : BOOLEAN Port type: string_list Mandatory properties : "type" : LIVIDO_ATOM_TYPE_INT32 : always equal to LIVIDO_PORT_TYPE_INT32 "name" : LIVIDO_ATOM_TYPE_STRING "value" : LIVIDO_ATOM_TYPE_STRING / INT "list_values" : array of CHARPTR Optional : "encoding" : CHARPTR (default is utf-8 if not set) "description" : LIVIDO_ATOM_TYPE_STRING "disabled" : BOOLEAN Port type: transition Mandatory properties : "type" : LIVIDO_ATOM_TYPE_INT32 : always equal to LIVIDO_PORT_TYPE_INT32 "name" : LIVIDO_ATOM_TYPE_STRING "value" : LIVIDO_ATOM_TYPE_FLOAT (from 0.0 to 1.0) Optional : "disabled" : BOOLEAN Port type: boolean Mandatory properties : "type" : LIVIDO_ATOM_TYPE_INT32 : always equal to LIVIDO_PORT_TYPE_INT32 "name" : LIVIDO_ATOM_TYPE_STRING "value" : LIVIDO_ATOM_TYPE_BOOLEAN Optional : "disabled" : BOOLEAN Port type: coordinate Mandatory properties : "type" : LIVIDO_ATOM_TYPE_INT32 : always equal to LIVIDO_PORT_TYPE_INT32 "name" : LIVIDO_ATOM_TYPE_STRING "value" : LIVIDO_ATOM_TYPE_FLOAT (from 0.0 to 1.0 or higher for polar, etc blah blah blah), [1 - n values], cartesian Optional : "disabled" : BOOLEAN "geometry" : CHARPTR (e.g. "cartesian", "logarithm", "polar") ------------------------- header in work, last night in tilburg: http://www.xs4all.nl/~salsaman/livido/current/livido.h