pinos: add new plugin API

Experiment with new plugin API that is designed for speed, minimal
allocations and locking, for use with real-time scheduling.
This commit is contained in:
Wim Taymans 2016-06-02 11:16:13 +02:00
parent d374f50d28
commit b44d2d86b6
7 changed files with 1776 additions and 1 deletions

104
pinos/spi/buffer.h Normal file
View file

@ -0,0 +1,104 @@
/* Simple Plugin Interface
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __SPI_BUFFER_H__
#define __SPI_BUFFER_H__
G_BEGIN_DECLS
#include <inttypes.h>
#include <pinos/spi/result.h>
#include <pinos/spi/params.h>
typedef struct _SpiBuffer SpiBuffer;
typedef enum {
SPI_META_TYPE_INVALID = 0,
SPI_META_TYPE_HEADER,
} SpiMetaType;
typedef struct {
uint32_t flags;
uint32_t seq;
int64_t pts;
int64_t dts_offset;
} SpiMetaHeader;
typedef struct {
SpiMetaType type;
void *data;
size_t size;
} SpiMeta;
/**
* SpiDataType:
* @SPI_DATA_TYPE_INVALID: invalid data type, is ignored
* @SPI_DATA_TYPE_MEMPTR: data and size point to memory
* @SPI_DATA_TYPE_FD: data points to SpiDataFd
* @SPI_DATA_TYPE_FD: data points to SpiDataFd
*/
typedef enum {
SPI_DATA_TYPE_INVALID = 0,
SPI_DATA_TYPE_MEMPTR,
SPI_DATA_TYPE_FD,
} SpiDataType;
typedef struct {
int fd;
int offset;
size_t size;
} SpiDataFD;
/**
* SpiData:
* @id: user id
* @type: the type of data
* @data: pointer to data
* @size: size of data
*/
typedef struct {
SpiDataType type;
void *data;
size_t size;
} SpiData;
typedef void (*SpiNotify) (void *data);
/**
* SpiBuffer:
* @refcount: reference counter
* @notify: called when the refcount reaches 0
* @size: total size of the buffer
* @n_metas: number of metadata
* @metas: array of @n_metas metadata
* @n_datas: number of data pointers
* @datas: array of @n_datas data pointers
*/
struct _SpiBuffer {
volatile int refcount;
SpiNotify notify;
size_t size;
int n_metas;
SpiMeta *metas;
int n_datas;
SpiData *datas;
};
#endif /* __SPI_BUFFER_H__ */

234
pinos/spi/node.h Normal file
View file

@ -0,0 +1,234 @@
/* Simple Plugin Interface
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __SPI_NODE_H__
#define __SPI_NODE_H__
G_BEGIN_DECLS
#include <inttypes.h>
#include <pinos/spi/result.h>
#include <pinos/spi/params.h>
#include <pinos/spi/buffer.h>
typedef struct _SpiNode SpiNode;
typedef struct _SpiEvent SpiEvent;
/**
* SpiPortInfoFlags:
* @SPI_PORT_INFO_FLAG_NONE: no flags
* @SPI_PORT_INFO_FLAG_REMOVABLE: port can be removed
* @SPI_PORT_INFO_FLAG_OPTIONAL: processing on port is optional
*/
typedef enum {
SPI_PORT_INFO_FLAG_NONE = 0,
SPI_PORT_INFO_FLAG_REMOVABLE = 1 << 0,
SPI_PORT_INFO_FLAG_OPTIONAL = 1 << 1,
} SpiPortInfoFlags;
/**
* SpiPortInfo
* @flags: extra port flags
* @size: minimum size of the buffers or 0 when not specified
* @align: required alignment of the data
* @maxbuffering: the maximum amount of bytes that the element will keep
* around internally
* @latency: latency on this port
* @features: NULL terminated array of extra port features
*
*/
typedef struct {
SpiPortInfoFlags flags;
int minsize;
int align;
int maxbuffering;
int latency;
const char **features;
} SpiPortInfo;
/**
* SpiPortStatusFlags:
* @SPI_PORT_STATUS_FLAG_NONE: no status flags
* @SPI_PORT_STATUS_FLAG_HAVE_OUTPUT: port has output
* @SPI_PORT_STATUS_FLAG_ACCEPT_INPUT: port accepts input
*/
typedef enum {
SPI_PORT_STATUS_FLAG_NONE = 0,
SPI_PORT_STATUS_FLAG_HAVE_OUTPUT = 1 << 0,
SPI_PORT_STATUS_FLAG_ACCEPT_INPUT = 1 << 1,
} SpiPortStatusFlags;
typedef struct {
SpiPortStatusFlags flags;
} SpiPortStatus;
typedef enum {
SPI_EVENT_TYPE_INVALID = 0,
SPI_EVENT_TYPE_ACTIVATED,
SPI_EVENT_TYPE_DEACTIVATED,
SPI_EVENT_TYPE_HAVE_OUTPUT,
SPI_EVENT_TYPE_NEED_INPUT,
SPI_EVENT_TYPE_REQUEST_DATA,
SPI_EVENT_TYPE_RELEASE_ID,
SPI_EVENT_TYPE_DRAINED,
SPI_EVENT_TYPE_MARKER,
SPI_EVENT_TYPE_ERROR,
} SpiEventType;
typedef struct {
int n_ids;
void **ids;
} SpiEventReleaseID;
struct _SpiEvent {
const void *id;
SpiEventType type;
int port_id;
void *data;
size_t size;
};
typedef enum {
SPI_DATA_FLAG_NONE = 0,
SPI_DATA_FLAG_FORMAT_CHANGED = (1 << 0),
SPI_DATA_FLAG_PROPERTIES_CHANGED = (1 << 1),
SPI_DATA_FLAG_EOS = (1 << 2),
SPI_DATA_FLAG_NO_BUFFER = (1 << 3),
} SpiDataFlags;
/**
* SpiDataInfo:
* @port_id: the port id
* @flags: extra flags
* @buffer: a buffer
* @event: an event
*/
typedef struct {
int port_id;
SpiDataFlags flags;
SpiBuffer *buffer;
SpiEvent *event;
} SpiDataInfo;
typedef enum {
SPI_COMMAND_INVALID = 0,
SPI_COMMAND_ACTIVATE,
SPI_COMMAND_DEACTIVATE,
SPI_COMMAND_START,
SPI_COMMAND_STOP,
SPI_COMMAND_FLUSH,
SPI_COMMAND_DRAIN,
SPI_COMMAND_MARKER,
} SpiCommandType;
typedef struct {
int port_id;
SpiCommandType type;
void *data;
size_t size;
} SpiCommand;
typedef enum {
SPI_DIRECTION_INVALID = 0,
SPI_DIRECTION_INPUT,
SPI_DIRECTION_OUTPUT
} SpiDirection;
typedef void (*SpiEventCallback) (SpiNode *node,
SpiEvent *event,
void *user_data);
/**
* SpiNodeInterface:
*
* Spi node interface.
*/
struct _SpiNode {
void * user_data;
int size;
SpiResult (*get_params) (SpiNode *node,
SpiParams **props);
SpiResult (*set_params) (SpiNode *node,
const SpiParams *props);
SpiResult (*send_command) (SpiNode *node,
SpiCommand *command);
SpiResult (*get_event) (SpiNode *node,
SpiEvent **event);
SpiResult (*set_event_callback) (SpiNode *node,
SpiEventCallback callback,
void *user_data);
SpiResult (*get_n_ports) (SpiNode *node,
int *n_input_ports,
int *max_input_ports,
int *n_output_ports,
int *max_output_ports);
SpiResult (*get_port_ids) (SpiNode *node,
int n_input_ports,
int *input_ids,
int n_output_ports,
int *output_ids);
SpiResult (*add_port) (SpiNode *node,
SpiDirection direction,
int *port_id);
SpiResult (*remove_port) (SpiNode *node,
int port_id);
SpiResult (*get_port_formats) (SpiNode *node,
int port_id,
int format_idx,
SpiParams **format);
SpiResult (*set_port_format) (SpiNode *node,
int port_id,
int test_only,
const SpiParams *format);
SpiResult (*get_port_format) (SpiNode *node,
int port_id,
const SpiParams **format);
SpiResult (*get_port_info) (SpiNode *node,
int port_id,
SpiPortInfo *info);
SpiResult (*get_port_params) (SpiNode *node,
int port_id,
SpiParams **params);
SpiResult (*set_port_params) (SpiNode *node,
int port_id,
const SpiParams *params);
SpiResult (*get_port_status) (SpiNode *node,
int port_id,
SpiPortStatus *status);
SpiResult (*send_port_data) (SpiNode *node,
SpiDataInfo *data);
SpiResult (*receive_port_data) (SpiNode *node,
int n_data,
SpiDataInfo *data);
};
G_END_DECLS
#endif /* __SPI_NODE_H__ */

194
pinos/spi/params.h Normal file
View file

@ -0,0 +1,194 @@
/* Simple Plugin Interface
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __SPI_PARAMS_H__
#define __SPI_PARAMS_H__
G_BEGIN_DECLS
#include <pinos/spi/result.h>
typedef struct _SpiParams SpiParams;
/**
* SpiParamType:
*/
typedef enum {
SPI_PARAM_TYPE_INVALID = 0,
SPI_PARAM_TYPE_BOOL,
SPI_PARAM_TYPE_INT8,
SPI_PARAM_TYPE_UINT8,
SPI_PARAM_TYPE_INT16,
SPI_PARAM_TYPE_UINT16,
SPI_PARAM_TYPE_INT32,
SPI_PARAM_TYPE_UINT32,
SPI_PARAM_TYPE_INT64,
SPI_PARAM_TYPE_UINT64,
SPI_PARAM_TYPE_FLOAT,
SPI_PARAM_TYPE_DOUBLE,
SPI_PARAM_TYPE_STRING,
SPI_PARAM_TYPE_POINTER,
SPI_PARAM_TYPE_FRACTION,
SPI_PARAM_TYPE_BITMASK,
SPI_PARAM_TYPE_BYTES,
} SpiParamType;
/**
* SpiParamFlags:
* @SPI_PARAM_FLAG_NONE: no flags
* @SPI_PARAM_FLAG_OPTIONAL: the value can be left unset
* @SPI_PARAM_FLAG_READABLE: param is readable
* @SPI_PARAM_FLAG_WRITABLE: param is writable
* @SPI_PARAM_FLAG_READWRITE: param is readable and writable
* @SPI_PARAM_FLAG_DEPRECATED: param is deprecated and should not be used
*/
typedef enum {
SPI_PARAM_FLAG_NONE = 0,
SPI_PARAM_FLAG_OPTIONAL = (1 << 0),
SPI_PARAM_FLAG_READABLE = (1 << 1),
SPI_PARAM_FLAG_WRITABLE = (1 << 2),
SPI_PARAM_FLAG_READWRITE = SPI_PARAM_FLAG_READABLE | SPI_PARAM_FLAG_WRITABLE,
SPI_PARAM_FLAG_DEPRECATED = (1 << 3),
} SpiParamFlags;
/* SpiParamRangeType:
* @SPI_PARAM_RANGE_TYPE_NONE: no range specified, full range of type applies
* @SPI_PARAM_RANGE_TYPE_MIN_MAX: range contains 2 values, min and max
* @SPI_PARAM_RANGE_TYPE_ENUM: range contains enum of possible values with
* NULL-terminated name
* @SPI_PARAM_RANGE_TYPE_FLAGS: range contains flags of possible values with
* NULL-terminated name
*/
typedef enum {
SPI_PARAM_RANGE_TYPE_NONE = 0,
SPI_PARAM_RANGE_TYPE_MIN_MAX,
SPI_PARAM_RANGE_TYPE_ENUM,
SPI_PARAM_RANGE_TYPE_FLAGS,
} SpiParamRangeType;
/**
* SpiParamRangeInfo:
* @name: name of this value
* @description: user visible description of this value
* @size: the size of value
* @value: a possible value
*/
typedef struct {
const char *name;
const char *description;
int size;
const void *value;
} SpiParamRangeInfo;
/**
* SpiParamInfo:
* @id: unique id
* @name: human readable name
* @description: description of the param
* @flags: param flags
* @type: param type
* @max_size: maximum size of param value
* @default_size: size of default value
* @default_value: default value of param
* @range_type: type of the range values
* @range_values: array of possible values
* @tags: extra tags, NULL terminated
* @priv: extra private data
*/
typedef struct {
int id;
const char *name;
const char *description;
SpiParamFlags flags;
SpiParamType type;
int maxsize;
int default_size;
const void *default_value;
SpiParamRangeType range_type;
const SpiParamRangeInfo *range_values;
const char **tags;
const void *priv;
} SpiParamInfo;
/**
* SpiParams:
*
* Generic parameters.
*/
struct _SpiParams {
/**
* SpiParams::get_param_info:
* @params: a #SpiParams
* @idx: the param index
* @info: pointer to a result #SpiParamInfo
*
* Gets the information about the parameter at @idx in @params.
*
* Returns: #SPI_RESULT_OK on success.
* #SPI_RESULT_NO_MORE_PARAM_INFO when there is no param info
* at @idx. This can be used to iterate the @params.
*/
SpiResult (*get_param_info) (const SpiParams *params,
int idx,
const SpiParamInfo **infos);
/**
* SpiParams::set_param
* @params: a #SpiParams
* @id: the param id
* @type: the value type to set
* @size: the value size
* @value: the value to set
*
* Sets @value in @param. @type should match the type specified
* in the #SpiParamInfo for @id or else #SPI_RESULT_WRONG_PARAM_TYPE
* is returned.
*
* Returns: #SPI_RESULT_OK on success.
* #SPI_RESULT_INVALID_PARAM_ID when @id is not valid
* #SPI_RESULT_WRONG_PARAM_TYPE when @type is not correct
*/
SpiResult (*set_param) (SpiParams *params,
int id,
SpiParamType type,
size_t size,
const void *value);
/**
* SpiParams::get_param
* @params: a #SpiParams
* @id: the param id
* @type: a location for the value type
* @size: a location for the value size
* @value: a location for the value pointer
*
* Get the type, size and value of the parameter with @id.
*
* Returns: #SPI_RESULT_OK on success.
* #SPI_RESULT_INVALID_PARAM_ID when @id is not valid
* #SPI_RESULT_PARAM_UNSET when no value has been set yet
*/
SpiResult (*get_param) (const SpiParams *params,
int id,
SpiParamType *type,
size_t *size,
const void **value);
};
G_END_DECLS
#endif /* __SPI_PARAMS_H__ */

52
pinos/spi/result.h Normal file
View file

@ -0,0 +1,52 @@
/* Simple Plugin Interface
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __SPI_RESULT_H__
#define __SPI_RESULT_H__
G_BEGIN_DECLS
typedef enum {
SPI_RESULT_OK = 0,
SPI_RESULT_ERROR = -1,
SPI_RESULT_INACTIVE = -2,
SPI_RESULT_NO_FORMAT = -3,
SPI_RESULT_INVALID_COMMAND = -4,
SPI_RESULT_INVALID_PORT = -5,
SPI_RESULT_HAVE_ENOUGH_INPUT = -6,
SPI_RESULT_NEED_MORE_INPUT = -7,
SPI_RESULT_HAVE_EVENT = -8,
SPI_RESULT_PORTS_CHANGED = -9,
SPI_RESULT_FORMAT_CHANGED = -10,
SPI_RESULT_PROPERTIES_CHANGED = -11,
SPI_RESULT_NOT_IMPLEMENTED = -12,
SPI_RESULT_INVALID_PARAM_ID = -13,
SPI_RESULT_PARAM_UNSET = -14,
SPI_RESULT_NO_MORE_FORMATS = -15,
SPI_RESULT_WRONG_PARAM_TYPE = -16,
SPI_RESULT_INVALID_MEDIA_TYPE = -17,
SPI_RESULT_INVALID_FORMAT_PARAMS = -18,
SPI_RESULT_FORMAT_INCOMPLETE = -19,
SPI_RESULT_NO_MORE_PARAM_INFO = -20,
SPI_RESULT_INVALID_ARGUMENTS = -21,
} SpiResult;
G_END_DECLS
#endif /* __SPI_RESULT_H__ */