/*
    unicap
    Copyright (C) 2004-2011  Arne Caspari

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#ifndef __UNICAP_H__
#define __UNICAP_H__

#ifdef __cplusplus
#define UNICAP_BEGIN_DECLS extern "C" {
#define UNICAP_END_DECLS }
#else
#define UNICAP_BEGIN_DECLS
#define UNICAP_END_DECLS
#endif

#include <sys/types.h>
#include <sys/time.h>

#include <unistd.h>

#include <unicap_status.h>
#include <unicap_version.h>

#define UNICAP_MAX_DEVICES 128


/**
 * unicap_buffer_type_t:
 * @UNICAP_BUFFER_TYPE_USER: buffer is provided by the application
 * @UNICAP_BUFFER_TYPE_SYSTEM: buffer is provided by the driver or library
 */
typedef enum
{
	UNICAP_BUFFER_TYPE_USER = 0, 
	UNICAP_BUFFER_TYPE_SYSTEM,
} unicap_buffer_type_t;


typedef enum
{
   UNICAP_FLAGS_BUFFER_TYPE_USER       = 1,      
   UNICAP_FLAGS_BUFFER_TYPE_SYSTEM     = 1 << 1,
   UNICAP_FLAGS_BUFFER_INTERLACED      = 1 << 2,
   UNICAP_FLAGS_BUFFER_ODD_FIELD_FIRST = 1 << 3,
   
   UNICAP_FLAGS_BUFFER_LOCKED          = 1 << 16,
} unicap_buffer_flags_t;

typedef struct unicap_data_buffer_private unicap_data_buffer_private_t;


/**
 * unicap_device_t:
 * @identifier: unique textual ID of a device 
 * @model_name: model name of the device
 * @vendor_name: name of the device vendor
 * @model_id: unique model id, ie. serial number
 * @vendor_id: numerical ID of the vendor ( eg. USB Vendor ID )
 * @cpi_layer: name of the plugin used to communicate with the device
 * @device: name of the device file, if any
 * @flags: flags
 *
 * A struct defining a device
 *
 */
struct _unicap_device_t
{
	char identifier[128];
	char model_name[128];
	char vendor_name[128];
		
	unsigned long long model_id;
	unsigned int vendor_id;
	
	char cpi_layer[1024];
	char device[1024];
		
	unsigned int flags;
};

typedef struct _unicap_device_t unicap_device_t;

/**
 * unicap_rect_t:
 * @x: horizontal position
 * @y: vertical position
 * @width: width of the rectangle
 * @height: height of the rectangle
 *
 * A struct defining a rectangle
 */
struct _unicap_rect_t
{
	int x;
	int y;	
	int width;
	int height;
};

typedef struct _unicap_rect_t unicap_rect_t;

/**
 * unicap_format_flags_t:
 *
 * Flags used in #unicap_format_t.
 *
 * The first five bits are used to specify the number of significant
 * bits in the pixel data. In order to access the number of sigificant
 * bits, do a bitwise AND operation with
 * @UNICAP_FLAGS_SIGNIFICANT_BITS_MASK. If all bits in the data are
 * significant, the special value @UNICAP_FLAGS_SIGNIFICANT_BITS_ALL
 * can be used.
 *
 * @UNICAP_FLAGS_SIGNIFICANT_BITS_ALL:  all bits are significant
 * @UNICAP_FLAGS_SIGNIFICANT_BITS_MASK: mask to access the number of significant bits
 */
typedef enum
{
  UNICAP_FLAGS_SIGNIFICANT_BITS_ALL  = 0,
  UNICAP_FLAGS_SIGNIFICANT_BITS_MASK = 0x1F,
  UNICAP_FLAGS_FIELD_ALTERNATE       = 1<<5,
  UNICAP_FLAGS_FIELD_TOP             = 1<<6,
  UNICAP_FLAGS_FIELD_BOTTOM          = 1<<7,
  UNICAP_FLAGS_FIELD_INTERLACED      = 1<<8,
} unicap_format_flags_t;

/**
 * unicap_format_t:
 * @identifier: unique textual identifier of this format
 * @size: size of the format
 * @min_size: minimum size
 * @max_size: maximum size
 * @h_stepping: horizontal stepping
 * @v_stepping: vertical stepping
 * @sizes: array of allowed sizes. Might be NULL
 * @size_count: number of element in the sizes array
 * @bpp: bits per pixel
 * @fourcc: FOURCC describing the colour format
 * @flags: 
 * @buffer_types:
 * @system_buffer_count: 
 * @buffer_size: amount of memory required by one data buffer of this
 * format
 * @buffer_type: 
 * 
 */
struct _unicap_format_t
{
      char identifier[128];
      
      unicap_rect_t size;
      
      unicap_rect_t min_size;
      unicap_rect_t max_size;
      
      int h_stepping;
      int v_stepping;
      unicap_rect_t *sizes;
      int size_count;
      
      int bpp;
      unsigned int fourcc;
      unicap_format_flags_t flags;

      unsigned int buffer_types;
      int system_buffer_count;

      size_t buffer_size;

      unicap_buffer_type_t buffer_type;
};

typedef struct _unicap_format_t unicap_format_t;


/**
 * unicap_data_buffer_t:
 * @format: a #unicap_format_t describing the layout of the data
 * buffer
 * @frame_number:
 * @fill_time: the time when capturing completed on this buffer
 * @duration: frame duration of this buffer ( might not be present on
 * all devices )
 * @capture_start_time: the time when the capturing started on this
 * buffer ( might not be supported on all devices )
 * @data: the image data
 * @buffer_size: size of the memory buffer pointed to by data
 * @type: 
 * 
 */
struct _unicap_data_buffer_t
{
   unicap_format_t format;
      
   int frame_number;
   struct timeval fill_time;
   struct timeval duration;
   struct timeval capture_start_time;
      
   unsigned char *data;
   size_t buffer_size;	

   unicap_buffer_type_t type;

   unicap_buffer_flags_t flags;
   
   unicap_data_buffer_private_t *priv;
};

typedef struct _unicap_data_buffer_t unicap_data_buffer_t;


/**
 * unicap_property_range_t:
 * @min: minimum value
 * @max: maximum value
 */
struct _unicap_property_range_t
{
	double min;
	double max;
};

typedef struct _unicap_property_range_t unicap_property_range_t;

/**
 * unicap_property_value_list_t:
 * @values: array of values
 * @value_count: number of elements in values array
 * 
 */
struct _unicap_property_value_list_t
{
	double *values;
	int value_count;	
};

typedef struct _unicap_property_value_list_t unicap_property_value_list_t;

/**
 * unicap_property_menu_t:
 * @menu_items: an array of menu items
 * @menu_item_count: number of elements in the menu_items array
 *
 */
struct _unicap_property_menu_t
{
	char **menu_items;
	int menu_item_count;
};

typedef struct _unicap_property_menu_t unicap_property_menu_t;

/**
 * unicap_property_type_enum_t:
 * @UNICAP_PROPERTY_TYPE_RANGE: a property with a value in a given
 * range
 * @UNICAP_PROPERTY_TYPE_VALUE_LIST: a property with a value out of a
 * list of values
 * @UNICAP_PROPERTY_TYPE_MENU: 
 * @UNICAP_PROPERTY_TYPE_DATA:
 * @UNICAP_PROPERTY_TYPE_FLAGS: a property where only the flags are valid
 */
typedef enum 
{
	UNICAP_PROPERTY_TYPE_RANGE = 0,
	UNICAP_PROPERTY_TYPE_VALUE_LIST,
	UNICAP_PROPERTY_TYPE_MENU,
	UNICAP_PROPERTY_TYPE_DATA,
	UNICAP_PROPERTY_TYPE_FLAGS, 

	UNICAP_PROPERTY_TYPE_UNKNOWN
} unicap_property_type_enum_t;


#ifndef UNICAP_FLAGS_NOT_AS_ENUM 

typedef enum
{
   UNICAP_FLAGS_MANUAL              = 1ULL, 
   UNICAP_FLAGS_AUTO                = (1ULL<<1ULL),
   UNICAP_FLAGS_ONE_PUSH            = (1ULL<<2ULL),
   UNICAP_FLAGS_READ_OUT            = (1ULL<<3ULL),
   UNICAP_FLAGS_ON_OFF              = (1ULL<<4ULL),
   UNICAP_FLAGS_READ_ONLY           = (1ULL<<5ULL),
   UNICAP_FLAGS_FORMAT_CHANGE       = (1ULL<<6ULL),
   UNICAP_FLAGS_WRITE_ONLY          = (1ULL<<7ULL),

   UNICAP_FLAGS_CHECK_STEPPING      = (1ULL<<32ULL),
   
   UNICAP_FLAGS_DUMMY_VALUE         = (0xffffffffffffffffULL)
} unicap_property_flags_t;

#else

#define UNICAP_FLAGS_MANUAL         (1ULL)
#define UNICAP_FLAGS_AUTO           (1ULL<<1ULL)
#define UNICAP_FLAGS_ONE_PUSH       (1ULL<<2ULL)
#define UNICAP_FLAGS_READ_OUT       (1ULL<<3ULL)
#define UNICAP_FLAGS_ON_OFF         (1ULL<<4ULL)
#define UNICAP_FLAGS_READ_ONLY      (1ULL<<5ULL)
#define UNICAP_FLAGS_FORMAT_CHANGE  (1ULL<<6ULL)
#define UNICAP_FLAGS_WRITE_ONLY     (1ULL<<7ULL)
#define UNICAP_FLAGS_CHECK_STEPPING (1ULL<<32ULL)
#define UNICAP_FLAGS_DUMMY_VALUE    (0xffffffffffffffffULL)
typedef u_int64_t unicap_property_flags_t;

#endif
   

/**
 * unicap_property_t:
 * @identifier:   unique textual identifier of this properties
 * @category:     a category for this property, for example: 'Lens Control' for zoom and focus properties
 * @unit:         optional unit, for example: 's' for Exposure
 * denoting the Exposure time in seconds
 * @relations:    properties that might their state or value when
 * changing this property
 * @relations_count: size of the relations array
 * @value:           for UNICAP_PROPERTY_TYPE_RANGE and UNICAP_PROPERTY_TYPE_VALUE_LIST properties: current value
 * @menu_item:       for UNICAP_PROPERTY_TYPE_MENU properties: selected menu entry
 * @range:           for UNICAP_PROPERTY_TYPE_RANGE properties: valid range for value
 * @value_list:      for UNICAP_PROPERTY_TYPE_VALUE_LIST properties: list
 * of valid values
 * @menu:            for UNICAP_PROPERTY_TYPE_MENU properties: menu
 * @stepping:        for UNICAP_PROPERTY_TYPE_RANGE properties: stepping 
 * @type: the type of the property
 * @flags: when enumerated, this field contains the default flags for the property; for get/set operations, this 
 * field contains the actual flags
 * @flags_mask: when enumerated, this field contains the allowed flags for the property; for get/set operations, this field acts as a mask
 * @property_data: a pointer to an opaque data structure
 * @property_data_size: size of the data structure pointed at by property_data
 */
struct _unicap_property_t
{
      char identifier[128];
      char category[128];
      char unit[128];
      
      char **relations;
      int relations_count;	
      
      union
      {
	    double value;
	    char menu_item[128]; 
      };
      
      
      union{	
	    unicap_property_range_t range;
	    unicap_property_value_list_t value_list;
	    unicap_property_menu_t menu; 
      };
	    
      
      double stepping;
      
      unicap_property_type_enum_t type;	
      unicap_property_flags_t flags;
      unicap_property_flags_t flags_mask;
      
      void *property_data; 
      size_t property_data_size;	
};

typedef struct _unicap_property_t unicap_property_t;




typedef enum 
{
	UNICAP_EVENT_FIRST = 0,
	UNICAP_EVENT_DEVICE_REMOVED = 0, 
	UNICAP_EVENT_NEW_DEVICE,
	UNICAP_EVENT_NEW_FRAME, 
	UNICAP_EVENT_DROP_FRAME, 
	UNICAP_EVENT_FORMAT_CHANGED,
	UNICAP_EVENT_LAST
} unicap_event_t;

typedef struct _unicap_handle *unicap_handle_t;

typedef void (*unicap_callback_t) (unicap_event_t event, ...);
typedef void (*unicap_new_frame_callback_t) (unicap_event_t event, unicap_handle_t handle, unicap_data_buffer_t *buffer, void *user_ptr);
typedef void (*unicap_drop_frame_callback_t) (unicap_event_t event, unicap_handle_t handle, void *user_ptr);
typedef void (*unicap_new_device_callback_t) (unicap_event_t event, unicap_device_t *device, void *user_ptr);
typedef void (*unicap_format_changed_callback_t) (unicap_event_t event, unicap_device_t *device, unicap_format_t *format, void *user_ptr);

UNICAP_BEGIN_DECLS

/**
 * unicap_check_version:
 * @major: major version to check against
 * @minor: minor version to check against
 * @micro: micro version to check against
 *
 * Checks that the unicap library version is compatible with given
 * version
 *
 * Returns: TRUE if compatible
 */
unicap_status_t unicap_check_version( unsigned int major, unsigned int minor, unsigned int micro );
   
	

/**
 * unicap_reenumerate_devices:
 * @count: if not NULL, receives number of devices found
 * 
 * Rebuild internal list of devices.
 *
 * Returns: status
 */
unicap_status_t unicap_reenumerate_devices( int *count );

/**
 * unicap_enumerate_devices: 
 * @specifier: specifies which devices should be returned, or NULL
 * @device: receives the device
 * @index: number of the device to be enumerated
 * 
 * Enumerates currently connected video capture devices
 * 
 * Returns: status
 */
unicap_status_t unicap_enumerate_devices( unicap_device_t *specifier, unicap_device_t *device, int index );

/**
 * unicap_open:
 * @handle: receives the new handle
 * @device: device to open, as returned by #unicap_enumerate_devices
 * 
 * Acquire a handle to a device. 
 *
 * Returns: status
 */
unicap_status_t unicap_open( unicap_handle_t *handle, unicap_device_t *device );

/**
 * unicap_register_callback:
 * @handle: a handle
 * @event: event to register a callback for
 * @callback: the callback function to call when the event occurs
 * @user_ptr: user provided data that gets passed to the callback function
 * 
 */
unicap_status_t unicap_register_callback( unicap_handle_t handle, 
					  unicap_event_t event, 
					  unicap_callback_t callback, 
					  void *user_ptr );


/**
 * unicap_unregister_callback:
 * @handle: a handle
 * @event: the event to clear
 *
 * Returns: status
 */
unicap_status_t unicap_unregister_callback( unicap_handle_t handle, 
					    unicap_event_t event );


/**
 * unicap_close: 
 * @handle: a handle
 * 
 * Clsoing a handle decrements the reference count on the device. If
 * the reference count is 0, all resources associated with the device
 * get freed.
 * 
 * Returns: status
 */
unicap_status_t unicap_close( unicap_handle_t handle );

/** 
 * unicap_get_device:
 * @handle: a handle
 * @device: a pointer to the location where the device should be stored
 * 
 * Gets the device controled by handle
 * 
 * Returns: status
 */
unicap_status_t unicap_get_device( unicap_handle_t handle, unicap_device_t *device );	

/**
 * unicap_clone_handle: 
 * @handle: the handle to clone
 * 
 * Copies the handle, increment the reference count
 * 
 * Returns: new handle
 */
unicap_handle_t unicap_clone_handle( unicap_handle_t handle );

/**
 * unicap_reenumerate_formats: 
 * @handle: A handle
 * @count: Receives the number of formats currently supported by the device. Might be NULL
 * 
 * Re-create the list of formats supported by the device. Invalidates all data returned by prior calls 
 * to unicap_emumerate_formats() and unicap_get_format(). 
 *
 * Returns: status
 */
unicap_status_t unicap_reenumerate_formats( unicap_handle_t handle, 
					    int *count );

/**
 * unicap_enumerate_formats:
 * @handle: A handle
 * @specifier: limits the enumerated formats to the ones matching the fields in specifier. Fields set to -1 in the specifier are ignored
 * @format: A pointer to allocated storage where the enumerated format shoudl be stored
 * @index: index of the format in the enumeration
 * 
 * Enumerate formats known to the device 
 *
 * Returns: STATUS_NO_MORE_FORMATS: end of the list of matching formats has been reached
 */
unicap_status_t unicap_enumerate_formats( unicap_handle_t handle, unicap_format_t *specifier, unicap_format_t *format, int index );

/**
 * unicap_set_format:
 * @handle: a handle
 * @format: the format to set
 * 
 * Set a format. 
 * 
 * Returns: STATUS_NO_MATCH: given format not valid for device
 */
unicap_status_t unicap_set_format( unicap_handle_t handle, unicap_format_t *format );

/**
 * unicap_get_format:
 * @handle: a handle
 * @format: a pointer to the location where the returned format should be stored
 * 
 * Get the current format
 * 
 * Returns: status
*/
unicap_status_t unicap_get_format( unicap_handle_t handle, unicap_format_t *format );

/**
 * unicap_reenumerate_properties:
 * @handle: a handle
 * @count: receives number of properties supported by the device. Might be NULL
 * 
 * Re-create the list of properties supported by the device. This invalidates all data returned by prior calls to 
 * unicap_enumerate_properties() and unicap_get_property()
 *
 * Returns: status
 */
unicap_status_t unicap_reenumerate_properties( unicap_handle_t handle, int *count );

/**
 * unicap_enumerate_properties:
 * @handle: a handle
 * @specifier: specifier
 * @property: a pointer to the location where the enumerated property should be stored
 * @index: index of the property
 * 
 * Enumerate properties matching "specifier"
 * 
 * Returns: status
 */
unicap_status_t unicap_enumerate_properties( unicap_handle_t handle, unicap_property_t *specifier, unicap_property_t *property, int index );

/**
 * unicap_set_property:
 * @handle: a handle
 * @property: the property to set
 * 
 * Set a device property
 * 
 * Returns: status
 */
unicap_status_t unicap_set_property( unicap_handle_t handle, unicap_property_t *property );

/**
 * unicap_set_property_value: Sets the value of a property
 * @handle: A handle
 * @identifier: identifier of the property to set
 * @value: new value
 * 
 * Set a RANGE or VALUE_LIST property
 * 
 * Returns: status
 */
unicap_status_t unicap_set_property_value( unicap_handle_t handle, char *identifier, double value );

/**
 * unicap_set_property_manual: 
 * @handle: A handle
 * @identifier: identifier of the property to set
 * 
 * Sets a property to manual mode, disabling the automatic mode
 *
 * Returns: status
 */
unicap_status_t unicap_set_property_manual( unicap_handle_t handle, char *identifier );

/**
 * unicap_set_property_auto: 
 * @handle: A handle
 * @identifier: identifier of the property to set
 * 
 * Sets the property to automatic mode
 *
 * Returns: status
 */
unicap_status_t unicap_set_property_auto( unicap_handle_t handle, char *identifier );

/**
 * unicap_set_property_one_push: 
 * @handle: a handle
 * @identifier: identifier of the property to set
 * 
 * Enable one push mode on a property
 *
 * Returns: status
 */
unicap_status_t unicap_set_property_one_push( unicap_handle_t handle, char *identifier );

/**
 * unicap_get_property:
 * @handle: a handle
 * @property: a pointer to the location where the returned property should be stored
 * 
 * Get a device property
 * 
 * Returns: status
 */
unicap_status_t unicap_get_property( unicap_handle_t handle, unicap_property_t *property );

/**
 * unicap_get_property_value: 
 * @handle: a handle
 * @identifier: identifier of the property to query
 * @value: a pointer to the location where the value should be stored
 * 
 * Returns the value of a property
 * 
 * Returns: status
 */
unicap_status_t unicap_get_property_value( unicap_handle_t handle, const char *identifier, double *value );

/**
 * unicap_get_property_menu:
 * @handle: A handle
 * @identifier: identifier of the property to query
 * @value: pointer to store the string location
 * 
 * Returns the menu string of a property. Property must be of
 * UNICAP_PROPERTY_TYPE_MENU type. The returned string is owned by the
 * unicap library and might be overwritten by subsequent calls to unicap_get_property_menu.
 * 
 * Returns: status
 */
unicap_status_t unicap_get_property_menu( unicap_handle_t handle, const char *identifier, char **value );

/**
 * unicap_get_property_auto:
 * @handle: a handle
 * @identifier: identifier of the property to query
 * @enabled: location to store the enabled flag
 * 
 * Retrieve the current property auto mode 
 *
 * Returns: status
 */
unicap_status_t unicap_get_property_auto( unicap_handle_t handle, const char *identifier, int *enabled );



/** 
 * unicap_start_capture:
 * @handle: a handle
 * 
 * Start the capture device. After this call, unicap_wait_buffer calls are allowed
 * 
 * Returns: status
 */
unicap_status_t unicap_start_capture( unicap_handle_t handle );

/**
 * unicap_stop_capture:
 * @handle: A handle
 * 
 * Stop the capture device
 * 
 * Returns: status
 */
unicap_status_t unicap_stop_capture( unicap_handle_t handle );

/** 
 * unicap_queue_buffer:
 * @handle: A handle
 * @data_buffer: A pointer to the buffer to queue
 * 
 * Queue a buffer to be filled by the capture device. The queued
 * buffer must not be touched ( especially not be freed ) until it is
 * in the ready queue or dequeued. Supplied buffer must be at least of
 * the buffer size returned by get_format
 * 
 * Returns: status
 */
unicap_status_t unicap_queue_buffer( unicap_handle_t handle, unicap_data_buffer_t *data_buffer );

/** 
 * unicap_dequeue_buffer:
 * @handle: A handle
 * @data_buffer: receives the dequeued buffer or NULL if no buffer was queued
 *
 * Removes the first buffer from the queue. Depending on the
 * device:Can only be called if the capture device is stopped.
 * 
 * Returns: status
 */
unicap_status_t unicap_dequeue_buffer( unicap_handle_t handle, unicap_data_buffer_t **data_buffer );

/**
 * unicap_wait_buffer:
 * @handle: A handle
 * @data_buffer: A pointer to the location where the returned buffer should be stored
 * 
 * Removes a buffer from the ready queue. If no buffer is available, this function blocks until a buffer got filled.
 * 
 * Returns: status
 */
unicap_status_t unicap_wait_buffer( unicap_handle_t handle, unicap_data_buffer_t **data_buffer );

/**
 * unicap_poll_buffer:
 * @handle: A handle
 * @count: A pointer to the location where return value should be stored
 * 
 * Poll for buffers in the fill queue
 * 
 * Returns: status
 */
unicap_status_t unicap_poll_buffer( unicap_handle_t handle, int *count );


unicap_status_t unicap_describe_device( unicap_device_t *device, char *buffer, size_t *buffer_size );
unicap_status_t unicap_describe_format( unicap_format_t *format, char *buffer, size_t *buffer_size );
unicap_status_t unicap_describe_property( unicap_property_t *property, char *buffer, size_t *buffer_size );

unicap_status_t unicap_void_device( unicap_device_t *device );
unicap_status_t unicap_void_format( unicap_format_t *format );
unicap_status_t unicap_void_property( unicap_property_t *property );

unicap_format_t *unicap_copy_format( unicap_format_t *dest, const unicap_format_t *src );
unicap_property_t *unicap_copy_property( unicap_property_t *dest, const unicap_property_t *src );


#ifdef UNICAP_FLAGS_NOT_AS_ENUM 
#define UNICAP_FLAGS_LOCKED               ( 1<<0 )
#define UNICAP_FLAGS_LOCK_CURRENT_PROCESS ( 1<<1 )
#else
typedef enum
{
   UNICAP_FLAGS_LOCKED =                  ( 1<< 0 ),
   UNICAP_FLAGS_LOCK_CURRENT_PROCESS =    ( 1<< 1 ),
} unicap_lock_flags_t;
#endif
   
/**
 * unicap_lock_stream:
 * @handle:
 *
 */
unicap_status_t unicap_lock_stream( unicap_handle_t handle );

/**
 * unicap_lock_stream:
 * @handle:
 *
 */
unicap_status_t unicap_unlock_stream( unicap_handle_t handle );

/**
 * unicap_is_stream_locked: 
 * @device:
 *
 * 
 */
int unicap_is_stream_locked( unicap_device_t *device );
	
unicap_status_t unicap_lock_properties( unicap_handle_t handle );
	
unicap_status_t unicap_unlock_properties( unicap_handle_t handle );
	
void unicap_cpi_register_event_notification( void *, 
					     void *data, unicap_handle_t handle );

/*
 */
void unicap_cache_init( void );

int unicap_get_ref_count( unicap_handle_t handle );

typedef void (*unicap_data_buffer_func_t)( unicap_data_buffer_t *buffer, void *ptr );

struct unicap_data_buffer_init_data
{
   unicap_data_buffer_func_t free_func;
   void *free_func_data;
   unicap_data_buffer_func_t ref_func;
   void *ref_func_data;
   unicap_data_buffer_func_t unref_func;
   void *unref_func_data;
};

typedef struct unicap_data_buffer_init_data unicap_data_buffer_init_data_t;

unicap_data_buffer_t *unicap_data_buffer_new( unicap_format_t *format );
void unicap_data_buffer_init( unicap_data_buffer_t *buffer, unicap_format_t *format, unicap_data_buffer_init_data_t *init_data );
void unicap_data_buffer_free( unicap_data_buffer_t *buffer );
unicap_status_t unicap_data_buffer_ref( unicap_data_buffer_t *buffer );
unicap_status_t unicap_data_buffer_unref( unicap_data_buffer_t *buffer );
unsigned int unicap_data_buffer_get_refcount( unicap_data_buffer_t *buffer );
void *unicap_data_buffer_set_user_data( unicap_data_buffer_t *buffer, void *data );
void *unicap_data_buffer_get_user_data( unicap_data_buffer_t *buffer );



UNICAP_END_DECLS

#endif//__UNICAP_H__
