summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/design.txt42
-rw-r--r--pinos/Makefile.am2
-rw-r--r--pinos/modules/spa/spa-alsa-sink.c69
-rw-r--r--pinos/modules/spa/spa-v4l2-source.c43
-rw-r--r--spa/include/spa/buffer.h4
-rw-r--r--spa/include/spa/defs.h2
-rw-r--r--spa/include/spa/event.h5
-rw-r--r--spa/include/spa/node.h181
-rw-r--r--spa/include/spa/plugin.h2
-rw-r--r--spa/include/spa/poll.h8
-rw-r--r--spa/include/spa/props.h6
-rw-r--r--spa/lib/control.c6
-rw-r--r--spa/plugins/alsa/alsa-sink.c141
-rw-r--r--spa/plugins/alsa/alsa-utils.c6
-rw-r--r--spa/plugins/audiomixer/audiomixer.c276
-rw-r--r--spa/plugins/audiotestsrc/audiotestsrc.c145
-rw-r--r--spa/plugins/ffmpeg/ffmpeg-dec.c138
-rw-r--r--spa/plugins/ffmpeg/ffmpeg-enc.c138
-rw-r--r--spa/plugins/meson.build1
-rw-r--r--spa/plugins/remote/meson.build7
-rw-r--r--spa/plugins/remote/plugin.c46
-rw-r--r--spa/plugins/remote/proxy.c975
-rw-r--r--spa/plugins/v4l2/v4l2-source.c159
-rw-r--r--spa/plugins/v4l2/v4l2-utils.c83
-rw-r--r--spa/plugins/volume/volume.c210
-rw-r--r--spa/plugins/xv/xv-sink.c171
-rw-r--r--spa/tests/test-mixer.c99
-rw-r--r--spa/tests/test-v4l2.c74
-rw-r--r--spa/tools/spa-inspect.c23
29 files changed, 2264 insertions, 798 deletions
diff --git a/doc/design.txt b/doc/design.txt
index c534bd0d..f7c3b8e8 100644
--- a/doc/design.txt
+++ b/doc/design.txt
@@ -395,44 +395,46 @@ communication channel
node-update
port-update
- start-configure
+ state-configure
2) Set formats S->C CONFIGURE
- add-port
set-property
enumerate ports
+ add-port
+ remove-port
enumerate formats
set-format
- end-configure
-3) Buffer requirements update C->S BUFFER_REQS
+3) Buffer requirements update C->S
Update port status
- start-alloc
+ state-ready if enough formats are set
-4) Start S->C ALLOC
+4) Start S->C READY
read port memory requirements
add_mem
+ remove_mem
add_buffer
- pause/start
+ remove_buffer
+ start->streaming
-5) Pause S->C PAUSED
+5) Pause S->C STREAMING
- start/stop
+ stop-streaming
-5) data transfer C->S STARTED
+5) data transfer C->S
need-input
+ have-output
+
add_mem
add_buffer
process_buffer
reuse_buffer
remove_buffer
remove_mem
- have-output
- pause/stop
6) data transfer S->C
@@ -442,23 +444,17 @@ communication channel
reuse_buffer
remove_buffer
remove_mem
- pause/stop
7) format change C->S
port-update
- start-configure
+ state-configure
8) format change S->C
- Send set-format change on ports
- end-configure, back to 3
-
-9) stop S->C ALLOC
-
- remove_buffer
- remove_mem
+ Send set-format change on ports -> READY if new memory requirements
+ -> RUNNING if all ok
-10) clear format S->C CONFIGURE
+9) format-change to NULL -> CONFIGURE
- format-change to NULL
+10) ERROR
diff --git a/pinos/Makefile.am b/pinos/Makefile.am
index 2f3edc2e..28d7cc3f 100644
--- a/pinos/Makefile.am
+++ b/pinos/Makefile.am
@@ -42,7 +42,7 @@ SERVER_CFLAGS = -D__INCLUDED_FROM_PINOS
AM_LIBADD = $(GLIB_LIBS) $(INTLLIBS) $(GST_LIBS) -L$(top_srcdir)/spa/build/lib/ -lspa-lib
AM_LDADD = $(GLIB_LIBS) $(GST_LIBS) $(INTLLIBS) -L$(top_srcdir)/spa/build/lib/ -lspa-lib
-AM_LDFLAGS = $(NODELETE_LDFLAGS)
+AM_LDFLAGS = $(NODELETE_LDFLAGS) -Wl,-rpath=/home/wim/gst/head/pinos/spa/build/lib/
FOREIGN_CFLAGS = -w
diff --git a/pinos/modules/spa/spa-alsa-sink.c b/pinos/modules/spa/spa-alsa-sink.c
index 1b65145b..bb273029 100644
--- a/pinos/modules/spa/spa-alsa-sink.c
+++ b/pinos/modules/spa/spa-alsa-sink.c
@@ -52,8 +52,7 @@ typedef struct {
struct _PinosSpaAlsaSinkPrivate
{
- SpaHandle *sink;
- const SpaNode *sink_node;
+ SpaNode *sink;
PinosProperties *props;
PinosRingbuffer *ringbuffer;
@@ -78,8 +77,9 @@ enum {
G_DEFINE_TYPE (PinosSpaAlsaSink, pinos_spa_alsa_sink, PINOS_TYPE_NODE);
static SpaResult
-make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char *name)
+make_node (SpaNode **node, const char *lib, const char *name)
{
+ SpaHandle *handle;
SpaResult res;
void *hnd, *state = NULL;
SpaEnumHandleFactoryFunc enum_func;
@@ -95,7 +95,7 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
while (true) {
const SpaHandleFactory *factory;
- const void *iface;
+ void *iface;
if ((res = enum_func (&factory, &state)) < 0) {
if (res != SPA_RESULT_ENUM_END)
@@ -105,12 +105,12 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
if (strcmp (factory->name, name))
continue;
- *handle = calloc (1, factory->size);
- if ((res = factory->init (factory, *handle)) < 0) {
+ handle = calloc (1, factory->size);
+ if ((res = factory->init (factory, handle)) < 0) {
g_error ("can't make factory instance: %d", res);
return res;
}
- if ((res = (*handle)->get_interface (*handle, SPA_INTERFACE_ID_NODE, &iface)) < 0) {
+ if ((res = handle->get_interface (handle, SPA_INTERFACE_ID_NODE, &iface)) < 0) {
g_error ("can't get interface %d", res);
return res;
}
@@ -121,7 +121,7 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
}
static void
-on_sink_event (SpaHandle *handle, SpaEvent *event, void *user_data)
+on_sink_event (SpaNode *node, SpaEvent *event, void *user_data)
{
PinosSpaAlsaSink *this = user_data;
PinosSpaAlsaSinkPrivate *priv = this->priv;
@@ -129,25 +129,19 @@ on_sink_event (SpaHandle *handle, SpaEvent *event, void *user_data)
switch (event->type) {
case SPA_EVENT_TYPE_PULL_INPUT:
{
- SpaBuffer *buf;
SpaInputInfo iinfo;
- SpaOutputInfo oinfo;
SpaResult res;
PinosRingbufferArea areas[2];
uint8_t *data;
size_t size, towrite, total;
+ SpaEventPullInput *pi;
- buf = event->data;
+ pi = event->data;
- oinfo.port_id = 0;
- oinfo.flags = SPA_OUTPUT_FLAG_PULL;
- oinfo.buffer = buf;
- oinfo.event = NULL;
+ g_debug ("pull ringbuffer %zd", pi->size);
- g_debug ("pull ringbuffer %p", buf);
-
- size = buf->size;
- data = buf->datas[0].ptr;
+ size = pi->size;
+ data = NULL;
pinos_ringbuffer_get_read_areas (priv->ringbuffer, areas);
@@ -165,15 +159,14 @@ on_sink_event (SpaHandle *handle, SpaEvent *event, void *user_data)
pinos_ringbuffer_read_advance (priv->ringbuffer, total);
- buf->size = total;
-
iinfo.port_id = event->port_id;
iinfo.flags = SPA_INPUT_FLAG_NONE;
- iinfo.buffer = oinfo.buffer;
- iinfo.event = oinfo.event;
+ iinfo.id = 0;
+ iinfo.offset = 0;
+ iinfo.size = total;
- g_debug ("push sink %p", iinfo.buffer);
- if ((res = priv->sink_node->port_push_input (priv->sink, 1, &iinfo)) < 0)
+ g_debug ("push sink %d", iinfo.id);
+ if ((res = spa_node_port_push_input (priv->sink, 1, &iinfo)) < 0)
g_debug ("got error %d", res);
break;
}
@@ -204,21 +197,21 @@ create_pipeline (PinosSpaAlsaSink *this)
SpaProps *props;
SpaPropValue value;
- if ((res = make_node (&priv->sink, &priv->sink_node, "spa/build/plugins/alsa/libspa-alsa.so", "alsa-sink")) < 0) {
+ if ((res = make_node (&priv->sink, "spa/build/plugins/alsa/libspa-alsa.so", "alsa-sink")) < 0) {
g_error ("can't create alsa-sink: %d", res);
return;
}
- priv->sink_node->set_event_callback (priv->sink, on_sink_event, this);
+ spa_node_set_event_callback (priv->sink, on_sink_event, this);
- if ((res = priv->sink_node->get_props (priv->sink, &props)) < 0)
+ if ((res = spa_node_get_props (priv->sink, &props)) < 0)
g_debug ("got get_props error %d", res);
value.type = SPA_PROP_TYPE_STRING;
value.value = "hw:0";
value.size = strlen (value.value)+1;
- props->set_prop (props, spa_props_index_for_name (props, "device"), &value);
+ spa_props_set_prop (props, spa_props_index_for_name (props, "device"), &value);
- if ((res = priv->sink_node->set_props (priv->sink, props)) < 0)
+ if ((res = spa_node_set_props (priv->sink, props)) < 0)
g_debug ("got set_props error %d", res);
}
@@ -266,7 +259,7 @@ start_pipeline (PinosSpaAlsaSink *sink)
g_debug ("spa-alsa-sink %p: starting pipeline", sink);
cmd.type = SPA_COMMAND_START;
- if ((res = priv->sink_node->send_command (priv->sink, &cmd)) < 0)
+ if ((res = spa_node_send_command (priv->sink, &cmd)) < 0)
g_debug ("got error %d", res);
priv->running = true;
@@ -291,7 +284,7 @@ stop_pipeline (PinosSpaAlsaSink *sink)
}
cmd.type = SPA_COMMAND_STOP;
- if ((res = priv->sink_node->send_command (priv->sink, &cmd)) < 0)
+ if ((res = spa_node_send_command (priv->sink, &cmd)) < 0)
g_debug ("got error %d", res);
}
@@ -395,7 +388,7 @@ negotiate_formats (PinosSpaAlsaSink *this)
SpaPropValue value;
void *state = NULL;
- if ((res = priv->sink_node->port_enum_formats (priv->sink, 0, &format, NULL, &state)) < 0)
+ if ((res = spa_node_port_enum_formats (priv->sink, 0, &format, NULL, &state)) < 0)
return res;
props = &format->props;
@@ -405,19 +398,19 @@ negotiate_formats (PinosSpaAlsaSink *this)
value.value = &val;
val = SPA_AUDIO_FORMAT_S16LE;
- if ((res = props->set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_FORMAT), &value)) < 0)
+ if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_FORMAT), &value)) < 0)
return res;
val = SPA_AUDIO_LAYOUT_INTERLEAVED;
- if ((res = props->set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_LAYOUT), &value)) < 0)
+ if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_LAYOUT), &value)) < 0)
return res;
val = 44100;
- if ((res = props->set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_RATE), &value)) < 0)
+ if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_RATE), &value)) < 0)
return res;
val = 2;
- if ((res = props->set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_CHANNELS), &value)) < 0)
+ if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_CHANNELS), &value)) < 0)
return res;
- if ((res = priv->sink_node->port_set_format (priv->sink, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_format (priv->sink, 0, 0, format)) < 0)
return res;
priv->ringbuffer = pinos_ringbuffer_new (PINOS_RINGBUFFER_MODE_READ, 64 * 1024);
diff --git a/pinos/modules/spa/spa-v4l2-source.c b/pinos/modules/spa/spa-v4l2-source.c
index 96f1161d..9c61b074 100644
--- a/pinos/modules/spa/spa-v4l2-source.c
+++ b/pinos/modules/spa/spa-v4l2-source.c
@@ -48,8 +48,7 @@ typedef struct {
struct _PinosSpaV4l2SourcePrivate
{
- SpaHandle *source;
- const SpaNode *source_node;
+ SpaNode *source;
SpaPollFd fds[16];
unsigned int n_fds;
@@ -70,8 +69,9 @@ enum {
G_DEFINE_TYPE (PinosSpaV4l2Source, pinos_spa_v4l2_source, PINOS_TYPE_NODE);
static SpaResult
-make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char *name)
+make_node (SpaNode **node, const char *lib, const char *name)
{
+ SpaHandle *handle;
SpaResult res;
void *hnd, *state = NULL;
SpaEnumHandleFactoryFunc enum_func;
@@ -87,7 +87,7 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
while (true) {
const SpaHandleFactory *factory;
- const void *iface;
+ void *iface;
if ((res = enum_func (&factory, &state)) < 0) {
if (res != SPA_RESULT_ENUM_END)
@@ -97,12 +97,12 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
if (strcmp (factory->name, name))
continue;
- *handle = calloc (1, factory->size);
- if ((res = factory->init (factory, *handle)) < 0) {
+ handle = calloc (1, factory->size);
+ if ((res = factory->init (factory, handle)) < 0) {
g_error ("can't make factory instance: %d", res);
return res;
}
- if ((res = (*handle)->get_interface (*handle, SPA_INTERFACE_ID_NODE, &iface)) < 0) {
+ if ((res = handle->get_interface (handle, SPA_INTERFACE_ID_NODE, &iface)) < 0) {
g_error ("can't get interface %d", res);
return res;
}
@@ -113,7 +113,7 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
}
static void
-on_source_event (SpaHandle *handle, SpaEvent *event, void *user_data)
+on_source_event (SpaNode *node, SpaEvent *event, void *user_data)
{
PinosSpaV4l2Source *source = user_data;
PinosSpaV4l2SourcePrivate *priv = source->priv;
@@ -126,10 +126,10 @@ on_source_event (SpaHandle *handle, SpaEvent *event, void *user_data)
SpaBuffer *b;
GList *walk;
- if ((res = priv->source_node->port_pull_output (priv->source, 1, info)) < 0)
+ if ((res = spa_node_port_pull_output (priv->source, 1, info)) < 0)
g_debug ("spa-v4l2-source %p: got pull error %d", source, res);
- b = info[0].buffer;
+ b = NULL; /* info[0].id; */
for (walk = priv->ports; walk; walk = g_list_next (walk)) {
SourcePortData *data = walk->data;
@@ -174,23 +174,22 @@ create_pipeline (PinosSpaV4l2Source *this)
SpaPropValue value;
if ((res = make_node (&priv->source,
- &priv->source_node,
"spa/build/plugins/v4l2/libspa-v4l2.so",
"v4l2-source")) < 0) {
g_error ("can't create v4l2-source: %d", res);
return;
}
- priv->source_node->set_event_callback (priv->source, on_source_event, this);
+ spa_node_set_event_callback (priv->source, on_source_event, this);
- if ((res = priv->source_node->get_props (priv->source, &props)) < 0)
+ if ((res = spa_node_get_props (priv->source, &props)) < 0)
g_debug ("got get_props error %d", res);
value.type = SPA_PROP_TYPE_STRING;
value.value = "/dev/video1";
value.size = strlen (value.value)+1;
- props->set_prop (props, spa_props_index_for_name (props, "device"), &value);
+ spa_props_set_prop (props, spa_props_index_for_name (props, "device"), &value);
- if ((res = priv->source_node->set_props (priv->source, props)) < 0)
+ if ((res = spa_node_set_props (priv->source, props)) < 0)
g_debug ("got set_props error %d", res);
}
@@ -208,7 +207,7 @@ negotiate_formats (PinosSpaV4l2Source *this)
SpaRectangle rect;
const gchar *str;
- if ((res = priv->source_node->port_enum_formats (priv->source, 0, &format, NULL, &state)) < 0)
+ if ((res = spa_node_port_enum_formats (priv->source, 0, &format, NULL, &state)) < 0)
return res;
props = &format->props;
@@ -218,7 +217,7 @@ negotiate_formats (PinosSpaV4l2Source *this)
value.value = &val;
val = SPA_VIDEO_FORMAT_YUY2;
- if ((res = props->set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_FORMAT), &value)) < 0)
+ if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_FORMAT), &value)) < 0)
return res;
value.type = SPA_PROP_TYPE_RECTANGLE;
@@ -226,7 +225,7 @@ negotiate_formats (PinosSpaV4l2Source *this)
value.value = &rect;
rect.width = 320;
rect.height = 240;
- if ((res = props->set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_SIZE), &value)) < 0)
+ if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_SIZE), &value)) < 0)
return res;
value.type = SPA_PROP_TYPE_FRACTION;
@@ -234,10 +233,10 @@ negotiate_formats (PinosSpaV4l2Source *this)
value.value = &frac;
frac.num = 25;
frac.denom = 1;
- if ((res = props->set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_FRAMERATE), &value)) < 0)
+ if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_FRAMERATE), &value)) < 0)
return res;
- if ((res = priv->source_node->port_set_format (priv->source, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_format (priv->source, 0, 0, format)) < 0)
return res;
str = "video/x-raw,"
@@ -294,7 +293,7 @@ start_pipeline (PinosSpaV4l2Source *source)
negotiate_formats (source);
cmd.type = SPA_COMMAND_START;
- if ((res = priv->source_node->send_command (priv->source, &cmd)) < 0)
+ if ((res = spa_node_send_command (priv->source, &cmd)) < 0)
g_debug ("got error %d", res);
priv->running = true;
@@ -319,7 +318,7 @@ stop_pipeline (PinosSpaV4l2Source *source)
}
cmd.type = SPA_COMMAND_STOP;
- if ((res = priv->source_node->send_command (priv->source, &cmd)) < 0)
+ if ((res = spa_node_send_command (priv->source, &cmd)) < 0)
g_debug ("got error %d", res);
}
diff --git a/spa/include/spa/buffer.h b/spa/include/spa/buffer.h
index 12b7e609..e0b23136 100644
--- a/spa/include/spa/buffer.h
+++ b/spa/include/spa/buffer.h
@@ -131,7 +131,7 @@ typedef struct {
SpaDataType type;
const char *ptr_type;
void *ptr;
- unsigned int offset;
+ off_t offset;
size_t size;
size_t stride;
} SpaData;
@@ -140,6 +140,7 @@ typedef struct {
* SpaBuffer:
* @refcount: reference counter
* @notify: called when the refcount reaches 0
+ * @user_data: extra user data
* @id: buffer id
* @size: total size of the buffer data
* @n_metas: number of metadata
@@ -150,6 +151,7 @@ typedef struct {
struct _SpaBuffer {
volatile int refcount;
SpaNotify notify;
+ void *user_data;
uint32_t id;
size_t size;
unsigned int n_metas;
diff --git a/spa/include/spa/defs.h b/spa/include/spa/defs.h
index 963308d9..c1eecfef 100644
--- a/spa/include/spa/defs.h
+++ b/spa/include/spa/defs.h
@@ -66,6 +66,8 @@ typedef enum {
typedef void (*SpaNotify) (void *data);
#define SPA_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
+#define SPA_MIN(a,b) ((a)<(b) ? (a) : (b))
+#define SPA_MAX(a,b) ((a)>(b) ? (a) : (b))
#ifdef __cplusplus
} /* extern "C" */
diff --git a/spa/include/spa/event.h b/spa/include/spa/event.h
index d5733e5b..80038e28 100644
--- a/spa/include/spa/event.h
+++ b/spa/include/spa/event.h
@@ -73,6 +73,11 @@ struct _SpaEvent {
size_t size;
};
+typedef struct {
+ off_t offset;
+ size_t size;
+} SpaEventPullInput;
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/spa/include/spa/node.h b/spa/include/spa/node.h
index 1e58d78e..b68f2560 100644
--- a/spa/include/spa/node.h
+++ b/spa/include/spa/node.h
@@ -62,15 +62,18 @@ typedef enum {
* SpaInputInfo:
* @port_id: the port id
* @flags: extra flags
- * @buffer: a buffer
+ * @offset: offset of data in @id
+ * @size: size of data in @id
+ * @id: a buffer id
*
* Input information for a node.
*/
typedef struct {
uint32_t port_id;
SpaInputFlags flags;
- SpaBuffer *buffer;
- SpaEvent *event;
+ off_t offset;
+ size_t size;
+ uint32_t id;
SpaResult status;
} SpaInputInfo;
@@ -93,7 +96,9 @@ typedef enum {
* SpaOutputInfo:
* @port_id: the port id
* @flags: extra flags
- * @buffer: a buffer
+ * @offset: offset to get
+ * @size: size to get
+ * @id: a buffer id will be set
* @event: an event
*
* Output information for a node.
@@ -101,21 +106,36 @@ typedef enum {
typedef struct {
uint32_t port_id;
SpaOutputFlags flags;
- SpaBuffer *buffer;
- SpaEvent *event;
+ off_t offset;
+ size_t size;
+ uint32_t id;
SpaResult status;
} SpaOutputInfo;
/**
+ * SpaNodeState:
+ * @SPA_NODE_STATE_INIT: the node is initializing
+ * @SPA_NODE_STATE_CONFIGURE: the node needs at least one port format
+ * @SPA_NODE_STATE_READY: the node is ready for memory allocation
+ * @SPA_NODE_STREAMING: the node is streaming
+ */
+typedef enum {
+ SPA_NODE_STATE_INIT,
+ SPA_NODE_STATE_CONFIGURE,
+ SPA_NODE_STATE_READY,
+ SPA_NODE_STATE_STREAMING
+} SpaNodeState;
+
+/**
* SpaEventCallback:
- * @node: a #SpaHandle emiting the event
+ * @node: a #SpaNode emiting the event
* @event: the event that was emited
* @user_data: user data provided when registering the callback
*
* This will be called when an out-of-bound event is notified
* on @node.
*/
-typedef void (*SpaEventCallback) (SpaHandle *handle,
+typedef void (*SpaEventCallback) (SpaNode *node,
SpaEvent *event,
void *user_data);
@@ -129,12 +149,14 @@ typedef void (*SpaEventCallback) (SpaHandle *handle,
* The main processing nodes.
*/
struct _SpaNode {
+ /* pointer to the handle owning this interface */
+ SpaHandle *handle;
/* the total size of this node. This can be used to expand this
* structure in the future */
size_t size;
/**
* SpaNode::get_props:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @props: a location for a #SpaProps pointer
*
* Get the configurable properties of @node.
@@ -148,11 +170,11 @@ struct _SpaNode {
* #SPA_RESULT_NOT_IMPLEMENTED when there are no properties
* implemented on @node
*/
- SpaResult (*get_props) (SpaHandle *handle,
+ SpaResult (*get_props) (SpaNode *node,
SpaProps **props);
/**
* SpaNode::set_props:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @props: a #SpaProps
*
* Set the configurable properties in @node.
@@ -172,11 +194,11 @@ struct _SpaNode {
* #SPA_RESULT_WRONG_PROPERTY_TYPE when a property has the wrong
* type.
*/
- SpaResult (*set_props) (SpaHandle *handle,
+ SpaResult (*set_props) (SpaNode *node,
const SpaProps *props);
/**
* SpaNode::send_command:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @command: a #SpaCommand
*
* Send a command to @node.
@@ -186,11 +208,11 @@ struct _SpaNode {
* #SPA_RESULT_NOT_IMPLEMENTED when this node can't process commands
* #SPA_RESULT_INVALID_COMMAND @command is an invalid command
*/
- SpaResult (*send_command) (SpaHandle *handle,
+ SpaResult (*send_command) (SpaNode *node,
SpaCommand *command);
/**
* SpaNode::set_event_callback:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @callback: a callback
* @user_data: user data passed in the callback
*
@@ -198,17 +220,17 @@ struct _SpaNode {
* current callback is removed.
*
* The callback can be emited from any thread. The caller should take
- * appropriate actions to handle the event in other threads when needed.
+ * appropriate actions to node the event in other threads when needed.
*
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
*/
- SpaResult (*set_event_callback) (SpaHandle *handle,
+ SpaResult (*set_event_callback) (SpaNode *node,
SpaEventCallback callback,
void *user_data);
/**
* SpaNode::get_n_ports:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @n_input_ports: location to hold the number of input ports or %NULL
* @max_input_ports: location to hold the maximum number of input ports or %NULL
* @n_output_ports: location to hold the number of output ports or %NULL
@@ -220,14 +242,14 @@ struct _SpaNode {
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
*/
- SpaResult (*get_n_ports) (SpaHandle *handle,
+ SpaResult (*get_n_ports) (SpaNode *node,
unsigned int *n_input_ports,
unsigned int *max_input_ports,
unsigned int *n_output_ports,
unsigned int *max_output_ports);
/**
* SpaNode::get_port_ids:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @n_input_ports: size of the @input_ids array
* @input_ids: array to store the input stream ids
* @n_output_ports: size of the @output_ids array
@@ -239,21 +261,21 @@ struct _SpaNode {
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
*/
- SpaResult (*get_port_ids) (SpaHandle *handle,
+ SpaResult (*get_port_ids) (SpaNode *node,
unsigned int n_input_ports,
uint32_t *input_ids,
unsigned int n_output_ports,
uint32_t *output_ids);
- SpaResult (*add_port) (SpaHandle *handle,
+ SpaResult (*add_port) (SpaNode *node,
SpaDirection direction,
- uint32_t *port_id);
- SpaResult (*remove_port) (SpaHandle *handle,
+ uint32_t port_id);
+ SpaResult (*remove_port) (SpaNode *node,
uint32_t port_id);
/**
* SpaNode::port_enum_formats:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @port_id: the port to query
* @format: pointer to a format
* @filter: a format filter
@@ -273,14 +295,14 @@ struct _SpaNode {
* #SPA_RESULT_INVALID_PORT when port_id is not valid
* #SPA_RESULT_ENUM_END when no format exists
*/
- SpaResult (*port_enum_formats) (SpaHandle *handle,
+ SpaResult (*port_enum_formats) (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state);
/**
* SpaNode::port_set_format:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @port_id: the port to configure
* @flags: flags
* @format: a #SpaFormat with the format
@@ -298,13 +320,13 @@ struct _SpaNode {
* #SPA_RESULT_WRONG_PROPERTY_TYPE when the type or size of a property
* is not correct.
*/
- SpaResult (*port_set_format) (SpaHandle *handle,
+ SpaResult (*port_set_format) (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format);
/**
* SpaNode::port_get_format:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @port_id: the port to query
* @format: a pointer to a location to hold the #SpaFormat
*
@@ -316,43 +338,83 @@ struct _SpaNode {
* #SPA_RESULT_INVALID_PORT when @port_id is not valid
* #SPA_RESULT_INVALID_NO_FORMAT when no format was set
*/
- SpaResult (*port_get_format) (SpaHandle *handle,
+ SpaResult (*port_get_format) (SpaNode *node,
uint32_t port_id,
const SpaFormat **format);
- SpaResult (*port_get_info) (SpaHandle *handle,
+ SpaResult (*port_get_info) (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info);
- SpaResult (*port_get_props) (SpaHandle *handle,
+ SpaResult (*port_get_props) (SpaNode *node,
uint32_t port_id,
SpaProps **props);
- SpaResult (*port_set_props) (SpaHandle *handle,
+ SpaResult (*port_set_props) (SpaNode *node,
uint32_t port_id,
const SpaProps *props);
- SpaResult (*port_use_buffers) (SpaHandle *handle,
+ /**
+ * SpaNode::port_use_buffers:
+ * @node: a #SpaNode
+ * @port_id: a port id
+ * @buffers: an array of buffer pointers
+ * @n_buffers: number of elements in @buffers
+ *
+ * Tell the port to use the given buffers
+ *
+ * For an input port, all the buffers will remain dequeued. Once a buffer
+ * has been pushed on a port with port_push_input, it should not be reused
+ * until the buffer refcount reached 0 and the notify is called.
+ *
+ * For output ports, all buffers will be queued in the port. with
+ * port_pull_output, a buffer can be dequeued. The notify of the buffers
+ * will be set by @node so that buffers will be reused when the refcount
+ * reaches 0.
+ *
+ * Returns: #SPA_RESULT_OK on success
+ */
+ SpaResult (*port_use_buffers) (SpaNode *node,
uint32_t port_id,
SpaBuffer **buffers,
- uint32_t n_buffers);
- SpaResult (*port_alloc_buffers) (SpaHandle *handle,
+ unsigned int n_buffers);
+ /**
+ * SpaNode::port_alloc_buffers:
+ * @node: a #SpaNode
+ * @port_id: a port id
+ * @params: allocation parameters
+ * @n_params: number of elements in @params
+ * @buffers: an array of buffer pointers
+ * @n_buffers: number of elements in @buffers
+ *
+ * Tell the port to allocate buffers.
+ *
+ * For input ports, the buffers will be dequeued and ready to be filled
+ * and pushed into the port. A notify should be configured so that you can
+ * know when a buffer can be reused.
+ *
+ * For output ports, the buffers remain queued. The notify will be configured
+ * so that buffers can be reused when no longer in use.
+ *
+ * Returns: #SPA_RESULT_OK on success
+ */
+ SpaResult (*port_alloc_buffers) (SpaNode *node,
uint32_t port_id,
SpaAllocParam **params,
- uint32_t n_params,
+ unsigned int n_params,
SpaBuffer **buffers,
- uint32_t *n_buffers);
+ unsigned int *n_buffers);
- SpaResult (*port_get_status) (SpaHandle *handle,
+ SpaResult (*port_get_status) (SpaNode *node,
uint32_t port_id,
const SpaPortStatus **status);
+
/**
* SpaNode::port_push_input:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @n_info: number of #SpaInputInfo in @info
* @info: array of #SpaInputInfo
*
- * Push a buffer and/or an event into one or more input ports of
- * @node.
+ * Push a buffer id into one or more input ports of @node.
*
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node or info is %NULL
@@ -361,17 +423,16 @@ struct _SpaNode {
* @info.
* #SPA_RESULT_HAVE_ENOUGH_INPUT when output can be produced.
*/
- SpaResult (*port_push_input) (SpaHandle *handle,
+ SpaResult (*port_push_input) (SpaNode *node,
unsigned int n_info,
SpaInputInfo *info);
/**
* SpaNode::port_pull_output:
- * @handle: a #SpaHandle
+ * @node: a #SpaNode
* @n_info: number of #SpaOutputInfo in @info
* @info: array of #SpaOutputInfo
*
- * Pull a buffer and/or an event from one or more output ports of
- * @node.
+ * Pull a buffer id from one or more output ports of @node.
*
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node or info is %NULL
@@ -386,11 +447,37 @@ struct _SpaNode {
* #SPA_RESULT_NEED_MORE_INPUT when no output can be produced
* because more input is needed.
*/
- SpaResult (*port_pull_output) (SpaHandle *handle,
+ SpaResult (*port_pull_output) (SpaNode *node,
unsigned int n_info,
SpaOutputInfo *info);
+
+ SpaResult (*port_push_event) (SpaNode *node,
+ uint32_t port_id,
+ SpaEvent *event);
+
};
+#define spa_node_get_props(n,...) (n)->get_props((n),__VA_ARGS__)
+#define spa_node_set_props(n,...) (n)->set_props((n),__VA_ARGS__)
+#define spa_node_send_command(n,...) (n)->send_command((n),__VA_ARGS__)
+#define spa_node_set_event_callback(n,...) (n)->set_event_callback((n),__VA_ARGS__)
+#define spa_node_get_n_ports(n,...) (n)->get_n_ports((n),__VA_ARGS__)
+#define spa_node_get_port_ids(n,...) (n)->get_port_ids((n),__VA_ARGS__)
+#define spa_node_add_port(n,...) (n)->add_port((n),__VA_ARGS__)
+#define spa_node_remove_port(n,...) (n)->remove_port((n),__VA_ARGS__)
+#define spa_node_port_enum_formats(n,...) (n)->port_enum_formats((n),__VA_ARGS__)
+#define spa_node_port_set_format(n,...) (n)->port_set_format((n),__VA_ARGS__)
+#define spa_node_port_get_format(n,...) (n)->port_get_format((n),__VA_ARGS__)
+#define spa_node_port_get_info(n,...) (n)->port_get_info((n),__VA_ARGS__)
+#define spa_node_port_get_props(n,...) (n)->port_get_props((n),__VA_ARGS__)
+#define spa_node_port_set_props(n,...) (n)->port_set_props((n),__VA_ARGS__)
+#define spa_node_port_use_buffers(n,...) (n)->port_use_buffers((n),__VA_ARGS__)
+#define spa_node_port_alloc_buffers(n,...) (n)->port_alloc_buffers((n),__VA_ARGS__)
+#define spa_node_port_get_status(n,...) (n)->port_get_status((n),__VA_ARGS__)
+#define spa_node_port_push_input(n,...) (n)->port_push_input((n),__VA_ARGS__)
+#define spa_node_port_pull_output(n,...) (n)->port_pull_output((n),__VA_ARGS__)
+#define spa_node_port_push_event(n,...) (n)->port_push_event((n),__VA_ARGS__)
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/spa/include/spa/plugin.h b/spa/include/spa/plugin.h
index b22af698..836d4a06 100644
--- a/spa/include/spa/plugin.h
+++ b/spa/include/spa/plugin.h
@@ -47,7 +47,7 @@ struct _SpaHandle {
*/
SpaResult (*get_interface) (SpaHandle *handle,
uint32_t interface_id,
- const void **interface);
+ void **interface);
};
/**
diff --git a/spa/include/spa/poll.h b/spa/include/spa/poll.h
index afa21947..ccc61bdc 100644
--- a/spa/include/spa/poll.h
+++ b/spa/include/spa/poll.h
@@ -62,12 +62,16 @@ typedef int (*SpaPollNotify) (SpaPollNotifyData *data);
/**
* SpaPollItem:
+ * @id: id of the poll item
* @fds: array of file descriptors to watch
* @n_fds: number of elements in @fds
- * @callback: callback called when there was activity on any of @fds
- * @user_data: user data
+ * @idle_cb: callback called when there is no other work
+ * @idle_cb: callback called before starting the poll
+ * @idle_cb: callback called after the poll loop
+ * @user_data: user data pass to callbacks
*/
typedef struct {
+ uint32_t id;
SpaPollFd *fds;
unsigned int n_fds;
SpaPollNotify idle_cb;
diff --git a/spa/include/spa/props.h b/spa/include/spa/props.h
index 89269613..5c81aeb0 100644
--- a/spa/include/spa/props.h
+++ b/spa/include/spa/props.h
@@ -43,6 +43,8 @@ typedef enum {
SPA_PROP_TYPE_UINT32,
SPA_PROP_TYPE_INT64,
SPA_PROP_TYPE_UINT64,
+ SPA_PROP_TYPE_INT,
+ SPA_PROP_TYPE_UINT,
SPA_PROP_TYPE_FLOAT,
SPA_PROP_TYPE_DOUBLE,
SPA_PROP_TYPE_STRING,
@@ -208,6 +210,10 @@ struct _SpaProps {
void *priv;
};
+#define spa_props_set_prop(p,...) (p)->set_prop((p),__VA_ARGS__)
+#define spa_props_get_prop(p,...) (p)->get_prop((p),__VA_ARGS__)
+
+
static inline unsigned int
spa_props_index_for_id (const SpaProps *props, uint32_t id)
{
diff --git a/spa/lib/control.c b/spa/lib/control.c
index f7ae7600..db31963b 100644
--- a/spa/lib/control.c
+++ b/spa/lib/control.c
@@ -344,7 +344,7 @@ typedef struct {
SpaBuffer buffer;
SpaMeta metas[16];
SpaData datas[16];
- int mem[16];
+ int memid[16];
} MyBuffer;
static SpaResult
@@ -377,8 +377,8 @@ parse_add_buffer (struct stack_iter *si,
SpaData *d = &b->datas[i];
d->type = SPA_DATA_TYPE_MEMID;
d->ptr_type = NULL;
- b->mem[i] = *p++;
- d->ptr = &b->mem[i];
+ b->memid[i] = *p++;
+ d->ptr = &b->memid[i];
d->offset = *p++;
d->size = *p++;
d->stride = *p++;
diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c
index 849e36c4..ab2bbed4 100644
--- a/spa/plugins/alsa/alsa-sink.c
+++ b/spa/plugins/alsa/alsa-sink.c
@@ -73,6 +73,7 @@ struct _ALSABuffer {
struct _SpaALSASink {
SpaHandle handle;
+ SpaNode node;
SpaALSASinkProps props[2];
@@ -172,14 +173,16 @@ static const SpaPropInfo prop_info[] =
};
static SpaResult
-spa_alsa_sink_node_get_props (SpaHandle *handle,
+spa_alsa_sink_node_get_props (SpaNode *node,
SpaProps **props)
{
- SpaALSASink *this = (SpaALSASink *) handle;
+ SpaALSASink *this;
- if (handle == NULL || props == NULL)
+ if (node == NULL || node->handle == NULL || props == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+
memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
*props = &this->props[0].props;
@@ -187,16 +190,19 @@ spa_alsa_sink_node_get_props (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_set_props (SpaHandle *handle,
+spa_alsa_sink_node_set_props (SpaNode *node,
const SpaProps *props)
{
- SpaALSASink *this = (SpaALSASink *) handle;
- SpaALSASinkProps *p = &this->props[1];
+ SpaALSASink *this;
+ SpaALSASinkProps *p;
SpaResult res;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+ p = &this->props[1];
+
if (props == NULL) {
reset_alsa_sink_props (p);
return SPA_RESULT_OK;
@@ -208,14 +214,16 @@ spa_alsa_sink_node_set_props (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_send_command (SpaHandle *handle,
+spa_alsa_sink_node_send_command (SpaNode *node,
SpaCommand *command)
{
- SpaALSASink *this = (SpaALSASink *) handle;
+ SpaALSASink *this;
- if (handle == NULL || command == NULL)
+ if (node == NULL || node->handle == NULL || command == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+
switch (command->type) {
case SPA_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
@@ -233,7 +241,7 @@ spa_alsa_sink_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
case SPA_COMMAND_STOP:
@@ -249,7 +257,7 @@ spa_alsa_sink_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
case SPA_COMMAND_FLUSH:
@@ -261,15 +269,17 @@ spa_alsa_sink_node_send_command (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_set_event_callback (SpaHandle *handle,
- SpaEventCallback event,
- void *user_data)
+spa_alsa_sink_node_set_event_callback (SpaNode *node,
+ SpaEventCallback event,
+ void *user_data)
{
- SpaALSASink *this = (SpaALSASink *) handle;
+ SpaALSASink *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+
this->event_cb = event;
this->user_data = user_data;
@@ -277,13 +287,13 @@ spa_alsa_sink_node_set_event_callback (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_get_n_ports (SpaHandle *handle,
+spa_alsa_sink_node_get_n_ports (SpaNode *node,
unsigned int *n_input_ports,
unsigned int *max_input_ports,
unsigned int *n_output_ports,
unsigned int *max_output_ports)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports)
@@ -299,13 +309,13 @@ spa_alsa_sink_node_get_n_ports (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_get_port_ids (SpaHandle *handle,
+spa_alsa_sink_node_get_port_ids (SpaNode *node,
unsigned int n_input_ports,
uint32_t *input_ids,
unsigned int n_output_ports,
uint32_t *output_ids)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports > 0)
@@ -316,33 +326,35 @@ spa_alsa_sink_node_get_port_ids (SpaHandle *handle,
static SpaResult
-spa_alsa_sink_node_add_port (SpaHandle *handle,
+spa_alsa_sink_node_add_port (SpaNode *node,
SpaDirection direction,
- uint32_t *port_id)
+ uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_alsa_sink_node_remove_port (SpaHandle *handle,
+spa_alsa_sink_node_remove_port (SpaNode *node,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_alsa_sink_node_port_enum_formats (SpaHandle *handle,
+spa_alsa_sink_node_port_enum_formats (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state)
{
- SpaALSASink *this = (SpaALSASink *) handle;
+ SpaALSASink *this;
int index;
- if (handle == NULL || format == NULL || state == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL || state == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -365,17 +377,19 @@ spa_alsa_sink_node_port_enum_formats (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_port_set_format (SpaHandle *handle,
+spa_alsa_sink_node_port_set_format (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
{
- SpaALSASink *this = (SpaALSASink *) handle;
+ SpaALSASink *this;
SpaResult res;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -393,15 +407,17 @@ spa_alsa_sink_node_port_set_format (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_port_get_format (SpaHandle *handle,
+spa_alsa_sink_node_port_get_format (SpaNode *node,
uint32_t port_id,
const SpaFormat **format)
{
- SpaALSASink *this = (SpaALSASink *) handle;
+ SpaALSASink *this;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -414,15 +430,17 @@ spa_alsa_sink_node_port_get_format (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_port_get_info (SpaHandle *handle,
+spa_alsa_sink_node_port_get_info (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info)
{
- SpaALSASink *this = (SpaALSASink *) handle;
+ SpaALSASink *this;
- if (handle == NULL || info == NULL)
+ if (node == NULL || node->handle == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -432,7 +450,7 @@ spa_alsa_sink_node_port_get_info (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_port_get_props (SpaHandle *handle,
+spa_alsa_sink_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
{
@@ -440,7 +458,7 @@ spa_alsa_sink_node_port_get_props (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_port_set_props (SpaHandle *handle,
+spa_alsa_sink_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
{
@@ -448,15 +466,17 @@ spa_alsa_sink_node_port_set_props (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_port_get_status (SpaHandle *handle,
+spa_alsa_sink_node_port_get_status (SpaNode *node,
uint32_t port_id,
const SpaPortStatus **status)
{
- SpaALSASink *this = (SpaALSASink *) handle;
+ SpaALSASink *this;
- if (handle == NULL || status == NULL)
+ if (node == NULL || node->handle == NULL || status == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -466,7 +486,7 @@ spa_alsa_sink_node_port_get_status (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_port_use_buffers (SpaHandle *handle,
+spa_alsa_sink_node_port_use_buffers (SpaNode *node,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@@ -475,7 +495,7 @@ spa_alsa_sink_node_port_use_buffers (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_port_alloc_buffers (SpaHandle *handle,
+spa_alsa_sink_node_port_alloc_buffers (SpaNode *node,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@@ -485,26 +505,38 @@ spa_alsa_sink_node_port_alloc_buffers (SpaHandle *handle,
return SPA_RESULT_NOT_IMPLEMENTED;
}
+static SpaBuffer *
+find_buffer (SpaALSASink *this, uint32_t id)
+{
+ return NULL;
+}
+
static SpaResult
-spa_alsa_sink_node_port_push_input (SpaHandle *handle,
+spa_alsa_sink_node_port_push_input (SpaNode *node,
unsigned int n_info,
SpaInputInfo *info)
{
- SpaALSASink *this = (SpaALSASink *) handle;
+ SpaALSASink *this;
unsigned int i;
bool have_error = false, have_enough = false;
- if (handle == NULL || n_info == 0 || info == NULL)
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) node->handle;
+
for (i = 0; i < n_info; i++) {
+ SpaBuffer *buffer;
+
if (info[i].port_id != 0) {
info[i].status = SPA_RESULT_INVALID_PORT;
have_error = true;
continue;
}
- if (info[i].buffer != NULL) {
+ buffer = find_buffer (this, info[i].id);
+
+ if (buffer != NULL) {
if (!this->have_format) {
info[i].status = SPA_RESULT_NO_FORMAT;
have_error = true;
@@ -516,7 +548,7 @@ spa_alsa_sink_node_port_push_input (SpaHandle *handle,
have_enough = true;
continue;
}
- this->input_buffer = spa_buffer_ref (info[i].buffer);
+ this->input_buffer = spa_buffer_ref (buffer);
}
info[i].status = SPA_RESULT_OK;
}
@@ -529,7 +561,7 @@ spa_alsa_sink_node_port_push_input (SpaHandle *handle,
}
static SpaResult
-spa_alsa_sink_node_port_pull_output (SpaHandle *handle,
+spa_alsa_sink_node_port_pull_output (SpaNode *node,
unsigned int n_info,
SpaOutputInfo *info)
{
@@ -537,6 +569,7 @@ spa_alsa_sink_node_port_pull_output (SpaHandle *handle,
}
static const SpaNode alsasink_node = {
+ NULL,
sizeof (SpaNode),
spa_alsa_sink_node_get_props,
spa_alsa_sink_node_set_props,
@@ -562,14 +595,18 @@ static const SpaNode alsasink_node = {
static SpaResult
spa_alsa_sink_get_interface (SpaHandle *handle,
uint32_t interface_id,
- const void **interface)
+ void **interface)
{
+ SpaALSASink *this;
+
if (handle == NULL || interface == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaALSASink *) handle;
+
switch (interface_id) {
case SPA_INTERFACE_ID_NODE:
- *interface = &alsasink_node;
+ *interface = &this->node;
break;
default:
return SPA_RESULT_UNKNOWN_INTERFACE;
@@ -589,6 +626,8 @@ alsa_sink_init (const SpaHandleFactory *factory,
handle->get_interface = spa_alsa_sink_get_interface;
this = (SpaALSASink *) handle;
+ this->node = alsasink_node;
+ this->node.handle = handle;
this->props[1].props.n_prop_info = PROP_ID_LAST;
this->props[1].props.prop_info = prop_info;
this->props[1].props.set_prop = spa_props_generic_set_prop;
diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c
index b427060e..d6fef158 100644
--- a/spa/plugins/alsa/alsa-utils.c
+++ b/spa/plugins/alsa/alsa-utils.c
@@ -236,7 +236,7 @@ pull_input (SpaALSASink *this, void *data, snd_pcm_uframes_t frames)
buffer->data[0].ptr_type = "sysmem";
buffer->data[0].size = frames * sizeof (uint16_t) * 2;
- this->event_cb (&this->handle, &event,this->user_data);
+ this->event_cb (&this->node, &event,this->user_data);
spa_buffer_unref ((SpaBuffer *)event.data);
}
@@ -378,7 +378,7 @@ spa_alsa_start (SpaALSASink *this)
state->poll.before_cb = NULL;
state->poll.after_cb = alsa_on_fd_events;
state->poll.user_data = this;
- this->event_cb (&this->handle, &event, this->user_data);
+ this->event_cb (&this->node, &event, this->user_data);
mmap_write (this);
err = snd_pcm_start (state->handle);
@@ -400,7 +400,7 @@ spa_alsa_stop (SpaALSASink *this)
event.port_id = 0;
event.data = &state->poll;
event.size = sizeof (state->poll);
- this->event_cb (&this->handle, &event, this->user_data);
+ this->event_cb (&this->node, &event, this->user_data);
spa_alsa_close (this);
diff --git a/spa/plugins/audiomixer/audiomixer.c b/spa/plugins/audiomixer/audiomixer.c
index 121b54de..e5d94627 100644
--- a/spa/plugins/audiomixer/audiomixer.c
+++ b/spa/plugins/audiomixer/audiomixer.c
@@ -47,28 +47,30 @@ struct _MixerBuffer {
typedef struct {
bool valid;
+ bool have_format;
+ SpaAudioRawFormat format[2];
SpaAudioMixerPortProps props[2];
SpaPortInfo info;
SpaPortStatus status;
- SpaBuffer *buffer;
size_t buffer_index;
size_t buffer_offset;
size_t buffer_queued;
MixerBuffer mix;
+
+ SpaBuffer **buffers;
+ unsigned int n_buffers;
+ SpaBuffer *buffer;
} SpaAudioMixerPort;
struct _SpaAudioMixer {
SpaHandle handle;
+ SpaNode node;
SpaAudioMixerProps props[2];
SpaEventCallback event_cb;
void *user_data;
- bool have_format;
- SpaAudioRawFormat query_format;
- SpaAudioRawFormat current_format;
-
int port_count;
int port_queued;
SpaAudioMixerPort ports[MAX_PORTS];
@@ -89,14 +91,16 @@ reset_audiomixer_props (SpaAudioMixerProps *props)
}
static SpaResult
-spa_audiomixer_node_get_props (SpaHandle *handle,
+spa_audiomixer_node_get_props (SpaNode *node,
SpaProps **props)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
- if (handle == NULL || props == NULL)
+ if (node == NULL || node->handle == NULL || props == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
*props = &this->props[0].props;
@@ -104,16 +108,19 @@ spa_audiomixer_node_get_props (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_set_props (SpaHandle *handle,
+spa_audiomixer_node_set_props (SpaNode *node,
const SpaProps *props)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
- SpaAudioMixerProps *p = &this->props[1];
+ SpaAudioMixer *this;
+ SpaAudioMixerProps *p;
SpaResult res;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+ p = &this->props[1];
+
if (props == NULL) {
reset_audiomixer_props (p);
return SPA_RESULT_OK;
@@ -124,14 +131,16 @@ spa_audiomixer_node_set_props (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_send_command (SpaHandle *handle,
+spa_audiomixer_node_send_command (SpaNode *node,
SpaCommand *command)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
- if (handle == NULL || command == NULL)
+ if (node == NULL || node->handle == NULL || command == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
switch (command->type) {
case SPA_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
@@ -147,7 +156,7 @@ spa_audiomixer_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -162,7 +171,7 @@ spa_audiomixer_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -175,15 +184,17 @@ spa_audiomixer_node_send_command (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_set_event_callback (SpaHandle *handle,
+spa_audiomixer_node_set_event_callback (SpaNode *node,
SpaEventCallback event,
void *user_data)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
this->event_cb = event;
this->user_data = user_data;
@@ -191,13 +202,13 @@ spa_audiomixer_node_set_event_callback (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_get_n_ports (SpaHandle *handle,
+spa_audiomixer_node_get_n_ports (SpaNode *node,
unsigned int *n_input_ports,
unsigned int *max_input_ports,
unsigned int *n_output_ports,
unsigned int *max_output_ports)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports)
@@ -213,18 +224,20 @@ spa_audiomixer_node_get_n_ports (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_get_port_ids (SpaHandle *handle,
+spa_audiomixer_node_get_port_ids (SpaNode *node,
unsigned int n_input_ports,
uint32_t *input_ids,
unsigned int n_output_ports,
uint32_t *output_ids)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
int i, idx;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
if (input_ids) {
for (i = 1, idx = 0; i < MAX_PORTS && idx < n_input_ports; i++) {
if (this->ports[i].valid)
@@ -238,34 +251,34 @@ spa_audiomixer_node_get_port_ids (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_add_port (SpaHandle *handle,
+spa_audiomixer_node_add_port (SpaNode *node,
SpaDirection direction,
- uint32_t *port_id)
+ uint32_t port_id)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
- int i;
+ SpaAudioMixer *this;
- if (handle == NULL || port_id == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
if (direction != SPA_DIRECTION_INPUT)
return SPA_RESULT_INVALID_DIRECTION;
- for (i = 1; i < MAX_PORTS; i++)
- if (!this->ports[i].valid)
- break;
- if (i == MAX_PORTS)
- return SPA_RESULT_TOO_MANY_PORTS;
+ if (port_id >= MAX_PORTS)
+ return SPA_RESULT_INVALID_PORT;
+
+ if (this->ports[port_id].valid)
+ return SPA_RESULT_INVALID_PORT;
- this->ports[i].valid = true;
- *port_id = i;
+ this->ports[port_id].valid = true;
this->port_count++;
- this->ports[i].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFER |
- SPA_PORT_INFO_FLAG_REMOVABLE |
- SPA_PORT_INFO_FLAG_OPTIONAL |
- SPA_PORT_INFO_FLAG_IN_PLACE;
- this->ports[i].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
+ this->ports[port_id].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFER |
+ SPA_PORT_INFO_FLAG_REMOVABLE |
+ SPA_PORT_INFO_FLAG_OPTIONAL |
+ SPA_PORT_INFO_FLAG_IN_PLACE;
+ this->ports[port_id].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
@@ -273,14 +286,16 @@ spa_audiomixer_node_add_port (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_remove_port (SpaHandle *handle,
+spa_audiomixer_node_remove_port (SpaNode *node,
uint32_t port_id)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
if (port_id == 0 || port_id >= MAX_PORTS || !this->ports[port_id].valid)
return SPA_RESULT_INVALID_PORT;
@@ -299,105 +314,124 @@ spa_audiomixer_node_remove_port (SpaHandle *handle,
static SpaResult
-spa_audiomixer_node_port_enum_formats (SpaHandle *handle,
+spa_audiomixer_node_port_enum_formats (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
+ SpaAudioMixerPort *port;
int index;
- if (handle == NULL || format == NULL || state == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL || state == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
- if (port_id > MAX_PORTS)
+ this = (SpaAudioMixer *) node->handle;
+
+ if (port_id > MAX_PORTS || !this->ports[port_id].valid)
return SPA_RESULT_INVALID_PORT;
+ port = &this->ports[port_id];
+
index = (*state == NULL ? 0 : *(int*)state);
switch (index) {
case 0:
- spa_audio_raw_format_init (&this->query_format);
+ spa_audio_raw_format_init (&port->format[0]);
break;
default:
return SPA_RESULT_ENUM_END;
}
- *format = &this->query_format.format;
+ *format = &port->format[0].format;
*(int*)state = ++index;
return SPA_RESULT_OK;
}
static SpaResult
-spa_audiomixer_node_port_set_format (SpaHandle *handle,
+spa_audiomixer_node_port_set_format (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
+ SpaAudioMixerPort *port;
SpaResult res;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
- if (port_id > MAX_PORTS)
+ this = (SpaAudioMixer *) node->handle;
+
+ if (port_id > MAX_PORTS || !this->ports[port_id].valid)
return SPA_RESULT_INVALID_PORT;
+ port = &this->ports[port_id];
+
if (format == NULL) {
- this->have_format = false;
+ port->have_format = false;
return SPA_RESULT_OK;
}
- if ((res = spa_audio_raw_format_parse (format, &this->current_format)) < 0)
+ if ((res = spa_audio_raw_format_parse (format, &port->format[1])) < 0)
return res;
- this->have_format = true;
+ port->have_format = true;
return SPA_RESULT_OK;
}
static SpaResult
-spa_audiomixer_node_port_get_format (SpaHandle *handle,
+spa_audiomixer_node_port_get_format (SpaNode *node,
uint32_t port_id,
const SpaFormat **format)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
+ SpaAudioMixerPort *port;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
if (port_id >= MAX_PORTS || !this->ports[port_id].valid)
return SPA_RESULT_INVALID_PORT;
- if (!this->have_format)
+ port = &this->ports[port_id];
+
+ if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
- *format = &this->current_format.format;
+ *format = &port->format[1].format;
return SPA_RESULT_OK;
}
static SpaResult
-spa_audiomixer_node_port_get_info (SpaHandle *handle,
+spa_audiomixer_node_port_get_info (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
+ SpaAudioMixerPort *port;
- if (handle == NULL || info == NULL)
+ if (node == NULL || node->handle == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
if (port_id >= MAX_PORTS || !this->ports[port_id].valid)
return SPA_RESULT_INVALID_PORT;
- *info = &this->ports[port_id].info;
+ port = &this->ports[port_id];
+ *info = &port->info;
return SPA_RESULT_OK;
}
static SpaResult
-spa_audiomixer_node_port_get_props (SpaHandle *handle,
+spa_audiomixer_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
{
@@ -405,7 +439,7 @@ spa_audiomixer_node_port_get_props (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_port_set_props (SpaHandle *handle,
+spa_audiomixer_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
{
@@ -413,28 +447,32 @@ spa_audiomixer_node_port_set_props (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_port_get_status (SpaHandle *handle,
+spa_audiomixer_node_port_get_status (SpaNode *node,
uint32_t port_id,
const SpaPortStatus **status)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
+ SpaAudioMixerPort *port;
- if (handle == NULL || status == NULL)
+ if (node == NULL || node->handle == NULL || status == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
if (port_id >= MAX_PORTS || !this->ports[port_id].valid)
return SPA_RESULT_INVALID_PORT;
- if (!this->have_format)
+ port = &this->ports[port_id];
+ if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
- *status = &this->ports[port_id].status;
+ *status = &port->status;
return SPA_RESULT_OK;
}
static SpaResult
-spa_audiomixer_node_port_use_buffers (SpaHandle *handle,
+spa_audiomixer_node_port_use_buffers (SpaNode *node,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@@ -443,7 +481,7 @@ spa_audiomixer_node_port_use_buffers (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_port_alloc_buffers (SpaHandle *handle,
+spa_audiomixer_node_port_alloc_buffers (SpaNode *node,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@@ -454,23 +492,25 @@ spa_audiomixer_node_port_alloc_buffers (SpaHandle *handle,
}
static SpaResult
-spa_audiomixer_node_port_push_input (SpaHandle *handle,
+spa_audiomixer_node_port_push_input (SpaNode *node,
unsigned int n_info,
SpaInputInfo *info)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
- SpaBuffer *buffer;
- SpaEvent *event;
+ SpaAudioMixer *this;
unsigned int i;
bool have_error = false;
- if (handle == NULL || n_info == 0 || info == NULL)
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
if (this->ports[0].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT)
return SPA_RESULT_HAVE_ENOUGH_INPUT;
for (i = 0; i < n_info; i++) {
+ SpaBuffer *buffer;
+ SpaAudioMixerPort *port;
int idx = info[i].port_id;
if (idx >= MAX_PORTS || !this->ports[idx].valid) {
@@ -478,18 +518,17 @@ spa_audiomixer_node_port_push_input (SpaHandle *handle,
have_error = true;
continue;
}
+ port = &this->ports[idx];
+ buffer = port->buffers[info[i].id];
- event = info[i].event;
- buffer = info[i].buffer;
-
- if (buffer == NULL && event == NULL) {
+ if (buffer == NULL) {
info[i].status = SPA_RESULT_INVALID_ARGUMENTS;
have_error = true;
continue;
}
if (buffer) {
- if (!this->have_format) {
+ if (!port->have_format) {
info[i].status = SPA_RESULT_NO_FORMAT;
have_error = true;
continue;
@@ -509,11 +548,6 @@ spa_audiomixer_node_port_push_input (SpaHandle *handle,
if (this->port_queued == this->port_count)
this->ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
}
- if (event) {
- info[i].status = SPA_RESULT_NOT_IMPLEMENTED;
- have_error = true;
- continue;
- }
info[i].status = SPA_RESULT_OK;
}
if (have_error)
@@ -557,7 +591,7 @@ pull_port (SpaAudioMixer *this, uint32_t port_id, SpaOutputInfo *info, size_t pu
buffer->data[0].ptr_type = "sysmem";
buffer->data[0].size = pull_size;
- this->event_cb (&this->handle, &event, this->user_data);
+ this->event_cb (&this->node, &event, this->user_data);
}
static void
@@ -613,15 +647,12 @@ static SpaResult
mix_data (SpaAudioMixer *this, SpaOutputInfo *info)
{
int i, min_size, min_port, pull_size;
+ SpaBuffer *buf;
if (info->port_id != 0)
return SPA_RESULT_INVALID_PORT;
- if (info->buffer) {
- pull_size = info->buffer->size;
- } else {
- pull_size = 0;
- }
+ pull_size = info->size;
min_size = 0;
min_port = 0;
@@ -645,43 +676,42 @@ mix_data (SpaAudioMixer *this, SpaOutputInfo *info)
if (min_port == 0)
return SPA_RESULT_NEED_MORE_INPUT;
- if (info->buffer) {
- if (info->buffer->size < min_size)
- min_size = info->buffer->size;
- else
- info->buffer->size = min_size;
- } else {
- info->buffer = this->ports[min_port].buffer;
- this->ports[min_port].buffer = NULL;
- this->ports[min_port].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
- this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
- }
+ buf = this->ports[min_port].buffer;
+ info->id = buf->id;
+ this->ports[min_port].buffer = NULL;
+ this->ports[min_port].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
+ this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
for (i = 1; i < MAX_PORTS; i++) {
if (!this->ports[i].valid || this->ports[i].buffer == NULL)
continue;
- add_port_data (this, info->buffer, &this->ports[i]);
+ add_port_data (this, buf, &this->ports[i]);
}
return SPA_RESULT_OK;
}
static SpaResult
-spa_audiomixer_node_port_pull_output (SpaHandle *handle,
+spa_audiomixer_node_port_pull_output (SpaNode *node,
unsigned int n_info,
SpaOutputInfo *info)
{
- SpaAudioMixer *this = (SpaAudioMixer *) handle;
+ SpaAudioMixer *this;
+ SpaAudioMixerPort *port;
int i;
bool have_error = false;
- if (handle == NULL || n_info == 0 || info == NULL)
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) node->handle;
+
if (info->port_id != 0)
return SPA_RESULT_INVALID_PORT;
- if (!this->have_format)
+ port = &this->ports[info->port_id];
+
+ if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
// if (!(this->ports[0].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT))
@@ -700,7 +730,16 @@ spa_audiomixer_node_port_pull_output (SpaHandle *handle,
return SPA_RESULT_OK;
}
+static SpaResult
+spa_audiomixer_node_port_push_event (SpaNode *node,
+ uint32_t port_id,
+ SpaEvent *event)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
static const SpaNode audiomixer_node = {
+ NULL,
sizeof (SpaNode),
spa_audiomixer_node_get_props,
spa_audiomixer_node_set_props,
@@ -721,19 +760,24 @@ static const SpaNode audiomixer_node = {
spa_audiomixer_node_port_get_status,
spa_audiomixer_node_port_push_input,
spa_audiomixer_node_port_pull_output,
+ spa_audiomixer_node_port_push_event,
};
static SpaResult
spa_audiomixer_get_interface (SpaHandle *handle,
uint32_t interface_id,
- const void **interface)
+ void **interface)
{
+ SpaAudioMixer *this;
+
if (handle == NULL || interface == 0)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioMixer *) handle;
+
switch (interface_id) {
case SPA_INTERFACE_ID_NODE:
- *interface = &audiomixer_node;
+ *interface = &this->node;
break;
default:
return SPA_RESULT_UNKNOWN_INTERFACE;
@@ -753,6 +797,8 @@ spa_audiomixer_init (const SpaHandleFactory *factory,
handle->get_interface = spa_audiomixer_get_interface;
this = (SpaAudioMixer *) handle;
+ this->node = audiomixer_node;
+ this->node.handle = handle;
this->props[1].props.n_prop_info = PROP_ID_LAST;
this->props[1].props.prop_info = prop_info;
this->props[1].props.set_prop = spa_props_generic_set_prop;
diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c
index a8e655ae..50960800 100644
--- a/spa/plugins/audiotestsrc/audiotestsrc.c
+++ b/spa/plugins/audiotestsrc/audiotestsrc.c
@@ -34,6 +34,7 @@ typedef struct {
struct _SpaAudioTestSrc {
SpaHandle handle;
+ SpaNode node;
SpaAudioTestSrcProps props[2];
@@ -121,14 +122,16 @@ reset_audiotestsrc_props (SpaAudioTestSrcProps *props)
}
static SpaResult
-spa_audiotestsrc_node_get_props (SpaHandle *handle,
+spa_audiotestsrc_node_get_props (SpaNode *node,
SpaProps **props)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
+ SpaAudioTestSrc *this;
- if (handle == NULL || props == NULL)
+ if (node == NULL || node->handle == NULL || props == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+
memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
*props = &this->props[0].props;
@@ -136,16 +139,19 @@ spa_audiotestsrc_node_get_props (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_set_props (SpaHandle *handle,
+spa_audiotestsrc_node_set_props (SpaNode *node,
const SpaProps *props)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
- SpaAudioTestSrcProps *p = &this->props[1];
+ SpaAudioTestSrc *this;
+ SpaAudioTestSrcProps *p;
SpaResult res;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+ p = &this->props[1];
+
if (props == NULL) {
reset_audiotestsrc_props (p);
return SPA_RESULT_OK;
@@ -156,14 +162,16 @@ spa_audiotestsrc_node_set_props (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_send_command (SpaHandle *handle,
+spa_audiotestsrc_node_send_command (SpaNode *node,
SpaCommand *command)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
+ SpaAudioTestSrc *this;
- if (handle == NULL || command == NULL)
+ if (node == NULL || node->handle == NULL || command == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+
switch (command->type) {
case SPA_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
@@ -179,7 +187,7 @@ spa_audiotestsrc_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -194,7 +202,7 @@ spa_audiotestsrc_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -207,15 +215,17 @@ spa_audiotestsrc_node_send_command (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_set_event_callback (SpaHandle *handle,
+spa_audiotestsrc_node_set_event_callback (SpaNode *node,
SpaEventCallback event,
void *user_data)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
+ SpaAudioTestSrc *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+
this->event_cb = event;
this->user_data = user_data;
@@ -223,13 +233,13 @@ spa_audiotestsrc_node_set_event_callback (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_get_n_ports (SpaHandle *handle,
+spa_audiotestsrc_node_get_n_ports (SpaNode *node,
unsigned int *n_input_ports,
unsigned int *max_input_ports,
unsigned int *n_output_ports,
unsigned int *max_output_ports)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports)
@@ -245,13 +255,13 @@ spa_audiotestsrc_node_get_n_ports (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_get_port_ids (SpaHandle *handle,
+spa_audiotestsrc_node_get_port_ids (SpaNode *node,
unsigned int n_input_ports,
uint32_t *input_ids,
unsigned int n_output_ports,
uint32_t *output_ids)
{
- if (handle == NULL || input_ids == NULL || output_ids == NULL)
+ if (node == NULL || node->handle == NULL || input_ids == NULL || output_ids == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_output_ports > 0)
@@ -261,33 +271,35 @@ spa_audiotestsrc_node_get_port_ids (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_add_port (SpaHandle *handle,
+spa_audiotestsrc_node_add_port (SpaNode *node,
SpaDirection direction,
- uint32_t *port_id)
+ uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_audiotestsrc_node_remove_port (SpaHandle *handle,
+spa_audiotestsrc_node_remove_port (SpaNode *node,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_audiotestsrc_node_port_enum_formats (SpaHandle *handle,
+spa_audiotestsrc_node_port_enum_formats (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
+ SpaAudioTestSrc *this;
int index;
- if (handle == NULL || format == NULL || state == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL || state == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -307,17 +319,19 @@ spa_audiotestsrc_node_port_enum_formats (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_port_set_format (SpaHandle *handle,
+spa_audiotestsrc_node_port_set_format (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
+ SpaAudioTestSrc *this;
SpaResult res;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -335,15 +349,17 @@ spa_audiotestsrc_node_port_set_format (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_port_get_format (SpaHandle *handle,
+spa_audiotestsrc_node_port_get_format (SpaNode *node,
uint32_t port_id,
const SpaFormat **format)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
+ SpaAudioTestSrc *this;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -356,15 +372,17 @@ spa_audiotestsrc_node_port_get_format (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_port_get_info (SpaHandle *handle,
+spa_audiotestsrc_node_port_get_info (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
+ SpaAudioTestSrc *this;
- if (handle == NULL || info == NULL)
+ if (node == NULL || node->handle == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -374,7 +392,7 @@ spa_audiotestsrc_node_port_get_info (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_port_get_props (SpaHandle *handle,
+spa_audiotestsrc_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
{
@@ -382,7 +400,7 @@ spa_audiotestsrc_node_port_get_props (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_port_set_props (SpaHandle *handle,
+spa_audiotestsrc_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
{
@@ -390,15 +408,17 @@ spa_audiotestsrc_node_port_set_props (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_port_get_status (SpaHandle *handle,
+spa_audiotestsrc_node_port_get_status (SpaNode *node,
uint32_t port_id,
const SpaPortStatus **status)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
+ SpaAudioTestSrc *this;
- if (handle == NULL || status == NULL)
+ if (node == NULL || node->handle == NULL || status == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -411,7 +431,7 @@ spa_audiotestsrc_node_port_get_status (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_port_use_buffers (SpaHandle *handle,
+spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@@ -420,7 +440,7 @@ spa_audiotestsrc_node_port_use_buffers (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_port_alloc_buffers (SpaHandle *handle,
+spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@@ -432,7 +452,7 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaHandle *handle,
static SpaResult
-spa_audiotestsrc_node_port_push_input (SpaHandle *handle,
+spa_audiotestsrc_node_port_push_input (SpaNode *node,
unsigned int n_info,
SpaInputInfo *info)
{
@@ -440,19 +460,21 @@ spa_audiotestsrc_node_port_push_input (SpaHandle *handle,
}
static SpaResult
-spa_audiotestsrc_node_port_pull_output (SpaHandle *handle,
+spa_audiotestsrc_node_port_pull_output (SpaNode *node,
unsigned int n_info,
SpaOutputInfo *info)
{
- SpaAudioTestSrc *this = (SpaAudioTestSrc *) handle;
+ SpaAudioTestSrc *this;
size_t j, size;
uint8_t *ptr;
unsigned int i;
bool have_error = false;
- if (handle == NULL || n_info == 0 || info == NULL)
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) node->handle;
+
for (i = 0; i < n_info; i++) {
if (info[i].port_id != 0) {
info[i].status = SPA_RESULT_INVALID_PORT;
@@ -466,14 +488,7 @@ spa_audiotestsrc_node_port_pull_output (SpaHandle *handle,
continue;
}
- if (info[i].buffer == NULL || info[i].buffer->n_datas == 0) {
- info[i].status = SPA_RESULT_INVALID_ARGUMENTS;
- have_error = true;
- continue;
- }
-
- ptr = info[i].buffer->datas[0].ptr;
- size = info[i].buffer->datas[0].size;
+ size = info[i].size;
for (j = 0; j < size; j++)
ptr[j] = rand();
@@ -486,7 +501,16 @@ spa_audiotestsrc_node_port_pull_output (SpaHandle *handle,
return SPA_RESULT_OK;
}
+static SpaResult
+spa_audiotestsrc_node_port_push_event (SpaNode *node,
+ uint32_t port_id,
+ SpaEvent *event)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
static const SpaNode audiotestsrc_node = {
+ NULL,
sizeof (SpaNode),
spa_audiotestsrc_node_get_props,
spa_audiotestsrc_node_set_props,
@@ -507,19 +531,24 @@ static const SpaNode audiotestsrc_node = {
spa_audiotestsrc_node_port_get_status,
spa_audiotestsrc_node_port_push_input,
spa_audiotestsrc_node_port_pull_output,
+ spa_audiotestsrc_node_port_push_event,
};
static SpaResult
-spa_audiotestsrc_get_interface (SpaHandle *handle,
- uint32_t interface_id,
- const void **interface)
+spa_audiotestsrc_get_interface (SpaHandle *handle,
+ uint32_t interface_id,
+ void **interface)
{
+ SpaAudioTestSrc *this;
+
if (handle == NULL || interface == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaAudioTestSrc *) handle;
+
switch (interface_id) {
case SPA_INTERFACE_ID_NODE:
- *interface = &audiotestsrc_node;
+ *interface = &this->node;
break;
default:
return SPA_RESULT_UNKNOWN_INTERFACE;
@@ -539,6 +568,8 @@ audiotestsrc_init (const SpaHandleFactory *factory,
handle->get_interface = spa_audiotestsrc_get_interface;
this = (SpaAudioTestSrc *) handle;
+ this->node = audiotestsrc_node;
+ this->node.handle = handle;
this->props[1].props.n_prop_info = PROP_ID_LAST;
this->props[1].props.prop_info = prop_info;
this->props[1].props.set_prop = spa_props_generic_set_prop;
diff --git a/spa/plugins/ffmpeg/ffmpeg-dec.c b/spa/plugins/ffmpeg/ffmpeg-dec.c
index 8afa77c1..682c0107 100644
--- a/spa/plugins/ffmpeg/ffmpeg-dec.c
+++ b/spa/plugins/ffmpeg/ffmpeg-dec.c
@@ -67,6 +67,7 @@ typedef struct {
struct _SpaFFMpegDec {
SpaHandle handle;
+ SpaNode node;
SpaFFMpegDecProps props[2];
@@ -86,14 +87,16 @@ static const SpaPropInfo prop_info[] =
};
static SpaResult
-spa_ffmpeg_dec_node_get_props (SpaHandle *handle,
+spa_ffmpeg_dec_node_get_props (SpaNode *node,
SpaProps **props)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
+ SpaFFMpegDec *this;
- if (handle == NULL || props == NULL)
+ if (node == NULL || node->handle == NULL || props == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
+
memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
*props = &this->props[0].props;
@@ -101,16 +104,19 @@ spa_ffmpeg_dec_node_get_props (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_set_props (SpaHandle *handle,
+spa_ffmpeg_dec_node_set_props (SpaNode *node,
const SpaProps *props)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
- SpaFFMpegDecProps *p = &this->props[1];
+ SpaFFMpegDec *this;
+ SpaFFMpegDecProps *p;
SpaResult res;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
+ p = &this->props[1];
+
if (props == NULL) {
reset_ffmpeg_dec_props (p);
return SPA_RESULT_OK;
@@ -122,14 +128,16 @@ spa_ffmpeg_dec_node_set_props (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_send_command (SpaHandle *handle,
+spa_ffmpeg_dec_node_send_command (SpaNode *node,
SpaCommand *command)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
+ SpaFFMpegDec *this;
- if (handle == NULL || command == NULL)
+ if (node == NULL || node->handle == NULL || command == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
+
switch (command->type) {
case SPA_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
@@ -145,7 +153,7 @@ spa_ffmpeg_dec_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
case SPA_COMMAND_STOP:
@@ -159,7 +167,7 @@ spa_ffmpeg_dec_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -172,15 +180,17 @@ spa_ffmpeg_dec_node_send_command (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_set_event_callback (SpaHandle *handle,
+spa_ffmpeg_dec_node_set_event_callback (SpaNode *node,
SpaEventCallback event,
void *user_data)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
+ SpaFFMpegDec *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
+
this->event_cb = event;
this->user_data = user_data;
@@ -188,13 +198,13 @@ spa_ffmpeg_dec_node_set_event_callback (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_get_n_ports (SpaHandle *handle,
+spa_ffmpeg_dec_node_get_n_ports (SpaNode *node,
unsigned int *n_input_ports,
unsigned int *max_input_ports,
unsigned int *n_output_ports,
unsigned int *max_output_ports)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports)
@@ -210,13 +220,13 @@ spa_ffmpeg_dec_node_get_n_ports (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_get_port_ids (SpaHandle *handle,
+spa_ffmpeg_dec_node_get_port_ids (SpaNode *node,
unsigned int n_input_ports,
uint32_t *input_ids,
unsigned int n_output_ports,
uint32_t *output_ids)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports > 0)
@@ -229,34 +239,36 @@ spa_ffmpeg_dec_node_get_port_ids (SpaHandle *handle,
static SpaResult
-spa_ffmpeg_dec_node_add_port (SpaHandle *handle,
+spa_ffmpeg_dec_node_add_port (SpaNode *node,
SpaDirection direction,
- uint32_t *port_id)
+ uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_ffmpeg_dec_node_remove_port (SpaHandle *handle,
+spa_ffmpeg_dec_node_remove_port (SpaNode *node,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_ffmpeg_dec_node_port_enum_formats (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_enum_formats (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
+ SpaFFMpegDec *this;
SpaFFMpegState *s;
int index;
- if (handle == NULL || format == NULL || state == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL || state == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -278,20 +290,22 @@ spa_ffmpeg_dec_node_port_enum_formats (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_port_set_format (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_set_format (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
+ SpaFFMpegDec *this;
SpaFFMpegState *state;
SpaResult res;
SpaFormat *f, *tf;
size_t fs;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -324,16 +338,18 @@ spa_ffmpeg_dec_node_port_set_format (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_port_get_format (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_get_format (SpaNode *node,
uint32_t port_id,
const SpaFormat **format)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
+ SpaFFMpegDec *this;
SpaFFMpegState *state;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -348,15 +364,17 @@ spa_ffmpeg_dec_node_port_get_format (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_port_get_info (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_get_info (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
+ SpaFFMpegDec *this;
- if (handle == NULL || info == NULL)
+ if (node == NULL || node->handle == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -366,7 +384,7 @@ spa_ffmpeg_dec_node_port_get_info (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_port_get_props (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
{
@@ -374,7 +392,7 @@ spa_ffmpeg_dec_node_port_get_props (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_port_set_props (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
{
@@ -382,15 +400,17 @@ spa_ffmpeg_dec_node_port_set_props (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_port_get_status (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_get_status (SpaNode *node,
uint32_t port_id,
const SpaPortStatus **status)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
+ SpaFFMpegDec *this;
- if (handle == NULL || status == NULL)
+ if (node == NULL || node->handle == NULL || status == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -400,12 +420,12 @@ spa_ffmpeg_dec_node_port_get_status (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_port_use_buffers (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_use_buffers (SpaNode *node,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (!IS_VALID_PORT (port_id))
@@ -415,7 +435,7 @@ spa_ffmpeg_dec_node_port_use_buffers (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_port_alloc_buffers (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_alloc_buffers (SpaNode *node,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@@ -427,7 +447,7 @@ spa_ffmpeg_dec_node_port_alloc_buffers (SpaHandle *handle,
static SpaResult
-spa_ffmpeg_dec_node_port_push_input (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_push_input (SpaNode *node,
unsigned int n_info,
SpaInputInfo *info)
{
@@ -435,18 +455,19 @@ spa_ffmpeg_dec_node_port_push_input (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_dec_node_port_pull_output (SpaHandle *handle,
+spa_ffmpeg_dec_node_port_pull_output (SpaNode *node,
unsigned int n_info,
SpaOutputInfo *info)
{
- SpaFFMpegDec *this = (SpaFFMpegDec *) handle;
+ SpaFFMpegDec *this;
SpaFFMpegState *state;
unsigned int i;
bool have_error = false;
- if (handle == NULL || n_info == 0 || info == NULL)
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) node->handle;
for (i = 0; i < n_info; i++) {
if (info[i].port_id != OUTPUT_PORT_ID) {
@@ -469,7 +490,17 @@ spa_ffmpeg_dec_node_port_pull_output (SpaHandle *handle,
return SPA_RESULT_OK;
}
+static SpaResult
+spa_ffmpeg_dec_node_port_push_event (SpaNode *node,
+ uint32_t port_id,
+ SpaEvent *event)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
+
static const SpaNode ffmpeg_dec_node = {
+ NULL,
sizeof (SpaNode),
spa_ffmpeg_dec_node_get_props,
spa_ffmpeg_dec_node_set_props,
@@ -490,19 +521,24 @@ static const SpaNode ffmpeg_dec_node = {
spa_ffmpeg_dec_node_port_get_status,
spa_ffmpeg_dec_node_port_push_input,
spa_ffmpeg_dec_node_port_pull_output,
+ spa_ffmpeg_dec_node_port_push_event,
};
static SpaResult
-spa_ffmpeg_dec_get_interface (SpaHandle *handle,
- uint32_t interface_id,
- const void **interface)
+spa_ffmpeg_dec_get_interface (SpaHandle *handle,
+ uint32_t interface_id,
+ void **interface)
{
+ SpaFFMpegDec *this;
+
if (handle == NULL || interface == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegDec *) handle;
+
switch (interface_id) {
case SPA_INTERFACE_ID_NODE:
- *interface = &ffmpeg_dec_node;
+ *interface = &this->node;
break;
default:
return SPA_RESULT_UNKNOWN_INTERFACE;
@@ -518,6 +554,8 @@ spa_ffmpeg_dec_init (SpaHandle *handle)
handle->get_interface = spa_ffmpeg_dec_get_interface;
this = (SpaFFMpegDec *) handle;
+ this->node = ffmpeg_dec_node;
+ this->node.handle = handle;
this->props[1].props.n_prop_info = PROP_ID_LAST;
this->props[1].props.prop_info = prop_info;
this->props[1].props.set_prop = spa_props_generic_set_prop;
diff --git a/spa/plugins/ffmpeg/ffmpeg-enc.c b/spa/plugins/ffmpeg/ffmpeg-enc.c
index d4a79f65..ea6b316a 100644
--- a/spa/plugins/ffmpeg/ffmpeg-enc.c
+++ b/spa/plugins/ffmpeg/ffmpeg-enc.c
@@ -67,6 +67,7 @@ typedef struct {
struct _SpaFFMpegEnc {
SpaHandle handle;
+ SpaNode node;
SpaFFMpegEncProps props[2];
@@ -86,14 +87,16 @@ static const SpaPropInfo prop_info[] =
};
static SpaResult
-spa_ffmpeg_enc_node_get_props (SpaHandle *handle,
+spa_ffmpeg_enc_node_get_props (SpaNode *node,
SpaProps **props)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
+ SpaFFMpegEnc *this;
- if (handle == NULL || props == NULL)
+ if (node == NULL || node->handle == NULL || props == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+
memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
*props = &this->props[0].props;
@@ -101,16 +104,19 @@ spa_ffmpeg_enc_node_get_props (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_set_props (SpaHandle *handle,
+spa_ffmpeg_enc_node_set_props (SpaNode *node,
const SpaProps *props)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
- SpaFFMpegEncProps *p = &this->props[1];
+ SpaFFMpegEnc *this;
+ SpaFFMpegEncProps *p;
SpaResult res;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+ p = &this->props[1];
+
if (props == NULL) {
reset_ffmpeg_enc_props (p);
return SPA_RESULT_OK;
@@ -122,14 +128,16 @@ spa_ffmpeg_enc_node_set_props (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_send_command (SpaHandle *handle,
+spa_ffmpeg_enc_node_send_command (SpaNode *node,
SpaCommand *command)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
+ SpaFFMpegEnc *this;
- if (handle == NULL || command == NULL)
+ if (node == NULL || node->handle == NULL || command == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+
switch (command->type) {
case SPA_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
@@ -145,7 +153,7 @@ spa_ffmpeg_enc_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
case SPA_COMMAND_STOP:
@@ -159,7 +167,7 @@ spa_ffmpeg_enc_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -172,15 +180,17 @@ spa_ffmpeg_enc_node_send_command (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_set_event_callback (SpaHandle *handle,
+spa_ffmpeg_enc_node_set_event_callback (SpaNode *node,
SpaEventCallback event,
void *user_data)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
+ SpaFFMpegEnc *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+
this->event_cb = event;
this->user_data = user_data;
@@ -188,13 +198,13 @@ spa_ffmpeg_enc_node_set_event_callback (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_get_n_ports (SpaHandle *handle,
+spa_ffmpeg_enc_node_get_n_ports (SpaNode *node,
unsigned int *n_input_ports,
unsigned int *max_input_ports,
unsigned int *n_output_ports,
unsigned int *max_output_ports)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports)
@@ -210,13 +220,13 @@ spa_ffmpeg_enc_node_get_n_ports (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_get_port_ids (SpaHandle *handle,
+spa_ffmpeg_enc_node_get_port_ids (SpaNode *node,
unsigned int n_input_ports,
uint32_t *input_ids,
unsigned int n_output_ports,
uint32_t *output_ids)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports > 0)
@@ -229,34 +239,36 @@ spa_ffmpeg_enc_node_get_port_ids (SpaHandle *handle,
static SpaResult
-spa_ffmpeg_enc_node_add_port (SpaHandle *handle,
+spa_ffmpeg_enc_node_add_port (SpaNode *node,
SpaDirection direction,
- uint32_t *port_id)
+ uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_ffmpeg_enc_node_remove_port (SpaHandle *handle,
+spa_ffmpeg_enc_node_remove_port (SpaNode *node,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_ffmpeg_enc_node_port_enum_formats (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_enum_formats (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
+ SpaFFMpegEnc *this;
SpaFFMpegState *s;
int index;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -278,20 +290,22 @@ spa_ffmpeg_enc_node_port_enum_formats (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_port_set_format (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_set_format (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
+ SpaFFMpegEnc *this;
SpaFFMpegState *state;
SpaResult res;
SpaFormat *f, *tf;
size_t fs;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -324,16 +338,18 @@ spa_ffmpeg_enc_node_port_set_format (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_port_get_format (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_get_format (SpaNode *node,
uint32_t port_id,
const SpaFormat **format)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
+ SpaFFMpegEnc *this;
SpaFFMpegState *state;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -348,15 +364,17 @@ spa_ffmpeg_enc_node_port_get_format (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_port_get_info (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_get_info (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
+ SpaFFMpegEnc *this;
- if (handle == NULL || info == NULL)
+ if (node == NULL || node->handle == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -366,7 +384,7 @@ spa_ffmpeg_enc_node_port_get_info (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_port_get_props (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
{
@@ -374,7 +392,7 @@ spa_ffmpeg_enc_node_port_get_props (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_port_set_props (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
{
@@ -382,15 +400,17 @@ spa_ffmpeg_enc_node_port_set_props (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_port_get_status (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_get_status (SpaNode *node,
uint32_t port_id,
const SpaPortStatus **status)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
+ SpaFFMpegEnc *this;
- if (handle == NULL || status == NULL)
+ if (node == NULL || node->handle == NULL || status == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
@@ -400,12 +420,12 @@ spa_ffmpeg_enc_node_port_get_status (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_port_use_buffers (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_use_buffers (SpaNode *node,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (!IS_VALID_PORT (port_id))
@@ -415,7 +435,7 @@ spa_ffmpeg_enc_node_port_use_buffers (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_port_alloc_buffers (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_alloc_buffers (SpaNode *node,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@@ -427,7 +447,7 @@ spa_ffmpeg_enc_node_port_alloc_buffers (SpaHandle *handle,
static SpaResult
-spa_ffmpeg_enc_node_port_push_input (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_push_input (SpaNode *node,
unsigned int n_info,
SpaInputInfo *info)
{
@@ -435,18 +455,20 @@ spa_ffmpeg_enc_node_port_push_input (SpaHandle *handle,
}
static SpaResult
-spa_ffmpeg_enc_node_port_pull_output (SpaHandle *handle,
+spa_ffmpeg_enc_node_port_pull_output (SpaNode *node,
unsigned int n_info,
SpaOutputInfo *info)
{
- SpaFFMpegEnc *this = (SpaFFMpegEnc *) handle;
+ SpaFFMpegEnc *this;
SpaFFMpegState *state;
unsigned int i;
bool have_error = false;
- if (handle == NULL || n_info == 0 || info == NULL)
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) node->handle;
+
for (i = 0; i < n_info; i++) {
if (info[i].port_id != OUTPUT_PORT_ID) {
@@ -469,7 +491,16 @@ spa_ffmpeg_enc_node_port_pull_output (SpaHandle *handle,
return SPA_RESULT_OK;
}
+static SpaResult
+spa_ffmpeg_enc_node_port_push_event (SpaNode *node,
+ uint32_t port_id,
+ SpaEvent *event)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
static const SpaNode ffmpeg_enc_node = {
+ NULL,
sizeof (SpaNode),
spa_ffmpeg_enc_node_get_props,
spa_ffmpeg_enc_node_set_props,
@@ -490,19 +521,24 @@ static const SpaNode ffmpeg_enc_node = {
spa_ffmpeg_enc_node_port_get_status,
spa_ffmpeg_enc_node_port_push_input,
spa_ffmpeg_enc_node_port_pull_output,
+ spa_ffmpeg_enc_node_port_push_event,
};
static SpaResult
-spa_ffmpeg_enc_get_interface (SpaHandle *handle,
- uint32_t interface_id,
- const void **interface)
+spa_ffmpeg_enc_get_interface (SpaHandle *handle,
+ uint32_t interface_id,
+ void **interface)
{
+ SpaFFMpegEnc *this;
+
if (handle == NULL || interface == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaFFMpegEnc *) handle;
+
switch (interface_id) {
case SPA_INTERFACE_ID_NODE:
- *interface = &ffmpeg_enc_node;
+ *interface = &this->node;
break;
default:
return SPA_RESULT_UNKNOWN_INTERFACE;
@@ -518,6 +554,8 @@ spa_ffmpeg_enc_init (SpaHandle *handle)
handle->get_interface = spa_ffmpeg_enc_get_interface;
this = (SpaFFMpegEnc *) handle;
+ this->node = ffmpeg_enc_node;
+ this->node.handle = handle;
this->props[1].props.n_prop_info = PROP_ID_LAST;
this->props[1].props.prop_info = prop_info;
this->props[1].props.set_prop = spa_props_generic_set_prop;
diff --git a/spa/plugins/meson.build b/spa/plugins/meson.build
index e8a9e231..2d43f779 100644
--- a/spa/plugins/meson.build
+++ b/spa/plugins/meson.build
@@ -2,6 +2,7 @@ subdir('alsa')
subdir('audiomixer')
subdir('audiotestsrc')
subdir('ffmpeg')
+subdir('remote')
#subdir('libva')
subdir('volume')
subdir('v4l2')
diff --git a/spa/plugins/remote/meson.build b/spa/plugins/remote/meson.build
new file mode 100644
index 00000000..880b8e3b
--- /dev/null
+++ b/spa/plugins/remote/meson.build
@@ -0,0 +1,7 @@
+remote_sources = ['proxy.c', 'plugin.c']
+
+remotelib = shared_library('spa-remote',
+ remote_sources,
+ include_directories : inc,
+ link_with : spalib,
+ install : true)
diff --git a/spa/plugins/remote/plugin.c b/spa/plugins/remote/plugin.c
new file mode 100644
index 00000000..05539cd0
--- /dev/null
+++ b/spa/plugins/remote/plugin.c
@@ -0,0 +1,46 @@
+/* Spa Volume plugin
+ * 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.
+ */
+
+#include <spa/plugin.h>
+#include <spa/node.h>
+
+extern const SpaHandleFactory spa_proxy_factory;
+
+SpaResult
+spa_enum_handle_factory (const SpaHandleFactory **factory,
+ void **state)
+{
+ int index;
+
+ if (factory == NULL || state == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ index = (*state == NULL ? 0 : *(int*)state);
+
+ switch (index) {
+ case 0:
+ *factory = &spa_proxy_factory;
+ break;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ *(int*)state = ++index;
+
+ return SPA_RESULT_OK;
+}
diff --git a/spa/plugins/remote/proxy.c b/spa/plugins/remote/proxy.c
new file mode 100644
index 00000000..af988c56
--- /dev/null
+++ b/spa/plugins/remote/proxy.c
@@ -0,0 +1,975 @@
+/* Spa
+ * 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.
+ */
+
+#define _GNU_SOURCE
+
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+
+#include <spa/node.h>
+#include <spa/control.h>
+
+#define MAX_INPUTS 64
+#define MAX_OUTPUTS 64
+#define MAX_PORTS (MAX_INPUTS + MAX_OUTPUTS)
+
+#define CHECK_PORT_ID(this,id) ((id) < MAX_PORTS && (this)->ports[id].valid)
+#define CHECK_PORT_ID_DIR(this,id,dir) (CHECK_PORT_ID(this,id) && (this)->ports[i].direction == (dir))
+
+typedef struct _SpaProxy SpaProxy;
+
+typedef struct {
+ SpaProps props;
+ int socketfd;
+} SpaProxyProps;
+
+typedef struct {
+ SpaDirection direction;
+ bool valid;
+ bool have_format;
+ SpaPortInfo info;
+ SpaPortStatus status;
+ SpaFormat formats[2];
+ SpaBuffer **buffers;
+ unsigned int n_buffers;
+} SpaProxyPort;
+
+struct _SpaProxy {
+ SpaHandle handle;
+ SpaNode node;
+
+ SpaProxyProps props[2];
+
+ SpaEventCallback event_cb;
+ void *user_data;
+
+ SpaPollFd fds[1];
+ SpaPollItem poll;
+
+ unsigned int n_inputs;
+ unsigned int n_outputs;
+ SpaProxyPort ports[MAX_PORTS];
+};
+
+enum {
+ PROP_ID_SOCKET,
+ PROP_ID_LAST,
+};
+
+static const SpaPropInfo prop_info[PROP_ID_LAST] =
+{
+ { PROP_ID_SOCKET, "socket", "The Socket factor",
+ SPA_PROP_FLAG_READWRITE,
+ SPA_PROP_TYPE_INT, sizeof (int),
+ sizeof (int), NULL,
+ SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
+ NULL,
+ offsetof (SpaProxyProps, socketfd),
+ 0, 0,
+ NULL },
+};
+
+static void
+reset_proxy_props (SpaProxyProps *props)
+{
+ props->socketfd = -1;
+}
+
+static void
+update_poll (SpaProxy *this, int socketfd)
+{
+ SpaEvent event;
+ SpaProxyProps *p;
+
+ p = &this->props[1];
+
+ if (p->socketfd != -1) {
+ event.refcount = 1;
+ event.notify = NULL;
+ event.type = SPA_EVENT_TYPE_REMOVE_POLL;
+ event.port_id = 0;
+ event.data = &this->poll;
+ event.size = sizeof (this->poll);
+ this->event_cb (&this->node, &event, this->user_data);
+ }
+ p->socketfd = socketfd;
+
+ if (p->socketfd != -1) {
+ this->fds[0].fd = p->socketfd;
+ event.refcount = 1;
+ event.notify = NULL;
+ event.type = SPA_EVENT_TYPE_ADD_POLL;
+ event.port_id = 0;
+ event.data = &this->poll;
+ event.size = sizeof (this->poll);
+ this->event_cb (&this->node, &event, this->user_data);
+ }
+}
+
+static SpaResult
+spa_proxy_node_get_props (SpaNode *node,
+ SpaProps **props)
+{
+ SpaProxy *this;
+
+ if (node == NULL || node->handle == NULL || props == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
+ *props = &this->props[0].props;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_set_props (SpaNode *node,
+ const SpaProps *props)
+{
+ SpaProxy *this;
+ SpaProxyProps *op, *np;
+ SpaResult res;
+
+ if (node == NULL || node->handle == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ op = &this->props[1];
+ np = &this->props[0];
+
+ if (props == NULL) {
+ reset_proxy_props (np);
+ props = &np->props;
+ }
+
+ /* copy new properties */
+ res = spa_props_copy (props, &np->props);
+
+ /* compare changes */
+ if (op->socketfd != np->socketfd)
+ update_poll (this, np->socketfd);
+
+ /* commit changes */
+ memcpy (op, np, sizeof (*np));
+
+ return res;
+}
+
+static SpaResult
+spa_proxy_node_send_command (SpaNode *node,
+ SpaCommand *command)
+{
+ SpaProxy *this;
+
+ if (node == NULL || node->handle == NULL || command == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ switch (command->type) {
+ case SPA_COMMAND_INVALID:
+ return SPA_RESULT_INVALID_COMMAND;
+
+ case SPA_COMMAND_START:
+ if (this->event_cb) {
+ SpaEvent event;
+
+ event.refcount = 1;
+ event.notify = NULL;
+ event.type = SPA_EVENT_TYPE_STARTED;
+ event.port_id = -1;
+ event.data = NULL;
+ event.size = 0;
+
+ this->event_cb (&this->node, &event, this->user_data);
+ }
+ break;
+
+ case SPA_COMMAND_STOP:
+ if (this->event_cb) {
+ SpaEvent event;
+
+ event.refcount = 1;
+ event.notify = NULL;
+ event.type = SPA_EVENT_TYPE_STOPPED;
+ event.port_id = -1;
+ event.data = NULL;
+ event.size = 0;
+
+ this->event_cb (&this->node, &event, this->user_data);
+ }
+ break;
+
+ case SPA_COMMAND_FLUSH:
+ case SPA_COMMAND_DRAIN:
+ case SPA_COMMAND_MARKER:
+ return SPA_RESULT_NOT_IMPLEMENTED;
+ }
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_set_event_callback (SpaNode *node,
+ SpaEventCallback event,
+ void *user_data)
+{
+ SpaProxy *this;
+
+ if (node == NULL || node->handle == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+ this->event_cb = event;
+ this->user_data = user_data;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_get_n_ports (SpaNode *node,
+ unsigned int *n_input_ports,
+ unsigned int *max_input_ports,
+ unsigned int *n_output_ports,
+ unsigned int *max_output_ports)
+{
+ SpaProxy *this;
+
+ if (node == NULL || node->handle == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ if (n_input_ports)
+ *n_input_ports = this->n_inputs;
+ if (n_output_ports)
+ *n_output_ports = this->n_outputs;
+ if (max_input_ports)
+ *max_input_ports = MAX_INPUTS;
+ if (max_output_ports)
+ *max_output_ports = MAX_OUTPUTS;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_get_port_ids (SpaNode *node,
+ unsigned int n_input_ports,
+ uint32_t *input_ids,
+ unsigned int n_output_ports,
+ uint32_t *output_ids)
+{
+ SpaProxy *this;
+ int c, i;
+
+ if (node == NULL || node->handle == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ if (input_ids) {
+ n_input_ports = SPA_MIN (n_input_ports, MAX_PORTS);
+ for (c = 0, i = 0; i < n_input_ports; i++) {
+ if (this->ports[i].valid && this->ports[i].direction == SPA_DIRECTION_INPUT)
+ input_ids[c++] = i;
+ }
+ }
+ if (output_ids) {
+ n_output_ports = SPA_MIN (n_output_ports, MAX_PORTS);
+ for (c = 0, i = 0; i < n_output_ports; i++) {
+ if (this->ports[i].valid && this->ports[i].direction == SPA_DIRECTION_OUTPUT)
+ output_ids[c++] = i;
+ }
+ }
+ return SPA_RESULT_OK;
+}
+
+
+static SpaResult
+spa_proxy_node_add_port (SpaNode *node,
+ SpaDirection direction,
+ uint32_t port_id)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
+static SpaResult
+spa_proxy_node_remove_port (SpaNode *node,
+ uint32_t port_id)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
+static SpaResult
+spa_proxy_node_port_enum_formats (SpaNode *node,
+ uint32_t port_id,
+ SpaFormat **format,
+ const SpaFormat *filter,
+ void **state)
+{
+ SpaProxy *this;
+ SpaProxyPort *port;
+ int index;
+
+ if (node == NULL || node->handle == NULL || format == NULL || state == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ if (!CHECK_PORT_ID (this, port_id))
+ return SPA_RESULT_INVALID_PORT;
+
+ port = &this->ports[port_id];
+
+ index = (*state == NULL ? 0 : *(int*)state);
+
+ switch (index) {
+ case 0:
+ break;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ *format = &port->formats[0];
+ *(int*)state = ++index;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_port_set_format (SpaNode *node,
+ uint32_t port_id,
+ SpaPortFormatFlags flags,
+ const SpaFormat *format)
+{
+ SpaProxy *this;
+ SpaProxyPort *port;
+ SpaControl control;
+ SpaControlBuilder builder;
+ SpaControlCmdSetFormat sf;
+ uint8_t buf[128];
+ SpaResult res;
+
+ if (node == NULL || node->handle == NULL || format == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ if (!CHECK_PORT_ID (this, port_id))
+ return SPA_RESULT_INVALID_PORT;
+
+ port = &this->ports[port_id];
+
+ spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
+ sf.port = port_id;
+ sf.format = format;
+ spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_SET_FORMAT, &sf);
+ spa_control_builder_end (&builder, &control);
+
+ if ((res = spa_control_write (&control, this->fds[0].fd)) < 0)
+ fprintf (stderr, "proxy %p: error writing control", this);
+
+ port->have_format = format != NULL;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_port_get_format (SpaNode *node,
+ uint32_t port_id,
+ const SpaFormat **format)
+{
+ SpaProxy *this;
+ SpaProxyPort *port;
+
+ if (node == NULL || node->handle == NULL || format == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ if (!CHECK_PORT_ID (this, port_id))
+ return SPA_RESULT_INVALID_PORT;
+
+ port = &this->ports[port_id];
+
+ if (!port->have_format)
+ return SPA_RESULT_NO_FORMAT;
+
+ *format = &port->formats[1];
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_port_get_info (SpaNode *node,
+ uint32_t port_id,
+ const SpaPortInfo **info)
+{
+ SpaProxy *this;
+ SpaProxyPort *port;
+
+ if (node == NULL || node->handle == NULL || info == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ if (!CHECK_PORT_ID (this, port_id))
+ return SPA_RESULT_INVALID_PORT;
+
+ port = &this->ports[port_id];
+
+ *info = &port->info;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_port_get_props (SpaNode *node,
+ uint32_t port_id,
+ SpaProps **props)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
+static SpaResult
+spa_proxy_node_port_set_props (SpaNode *node,
+ uint32_t port_id,
+ const SpaProps *props)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
+static SpaResult
+spa_proxy_node_port_get_status (SpaNode *node,
+ uint32_t port_id,
+ const SpaPortStatus **status)
+{
+ SpaProxy *this;
+ SpaProxyPort *port;
+
+ if (node == NULL || node->handle == NULL || status == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ if (!CHECK_PORT_ID (this, port_id))
+ return SPA_RESULT_INVALID_PORT;
+
+ port = &this->ports[port_id];
+
+ if (!port->have_format)
+ return SPA_RESULT_NO_FORMAT;
+
+ *status = &port->status;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_port_use_buffers (SpaNode *node,
+ uint32_t port_id,
+ SpaBuffer **buffers,
+ uint32_t n_buffers)
+{
+ SpaProxy *this;
+ SpaProxyPort *port;
+
+ if (node == NULL || node->handle == NULL || buffers == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ if (!CHECK_PORT_ID (this, port_id))
+ return SPA_RESULT_INVALID_PORT;
+
+ port = &this->ports[port_id];
+
+ if (!port->have_format)
+ return SPA_RESULT_NO_FORMAT;
+
+ port->buffers = buffers;
+ port->n_buffers = n_buffers;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_port_alloc_buffers (SpaNode *node,
+ uint32_t port_id,
+ SpaAllocParam **params,
+ uint32_t n_params,
+ SpaBuffer **buffers,
+ uint32_t *n_buffers)
+{
+ SpaProxy *this;
+ SpaProxyPort *port;
+
+ if (node == NULL || node->handle == NULL || buffers == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ if (!CHECK_PORT_ID (this, port_id))
+ return SPA_RESULT_INVALID_PORT;
+
+ port = &this->ports[port_id];
+
+ if (!port->have_format)
+ return SPA_RESULT_NO_FORMAT;
+
+ return SPA_RESULT_OK;
+}
+
+static int
+tmpfile_create (void *data, size_t size)
+{
+ char filename[] = "/dev/shm/tmpfilepay.XXXXXX";
+ int fd;
+
+ fd = mkostemp (filename, O_CLOEXEC);
+ if (fd == -1) {
+ fprintf (stderr, "Failed to create temporary file: %s", strerror (errno));
+ return -1;
+ }
+ unlink (filename);
+
+ if (write (fd, data, size) != (ssize_t) size)
+ fprintf (stderr, "Failed to write data: %s", strerror (errno));
+
+ return fd;
+}
+
+typedef struct {
+ SpaBuffer buffer;
+ SpaData datas[16];
+ int idx[16];
+ SpaBuffer *orig;
+} MyBuffer;
+
+static SpaResult
+send_buffer (SpaProxy *this, SpaBuffer *buffer)
+{
+ SpaControl control;
+ SpaControlBuilder builder;
+ uint8_t buf[1024];
+ int fds[16];
+ SpaControlCmdAddBuffer ab;
+ SpaControlCmdProcessBuffer pb;
+ SpaControlCmdRemoveBuffer rb;
+ bool tmpfile = false;
+ unsigned int i;
+ MyBuffer b;
+ SpaResult res;
+
+ spa_control_builder_init_into (&builder, buf, 1024, fds, 16);
+
+ b.buffer.refcount = 1;
+ b.buffer.notify = NULL;
+ b.buffer.id = buffer->id;
+ b.buffer.size = buffer->size;
+ b.buffer.n_metas = buffer->n_metas;
+ b.buffer.metas = buffer->metas;
+ b.buffer.n_datas = buffer->n_datas;
+ b.buffer.datas = b.datas;
+
+ for (i = 0; i < buffer->n_datas; i++) {
+ SpaData *d = &buffer->datas[i];
+ int fd;
+ SpaControlCmdAddMem am;
+
+ if (d->type == SPA_DATA_TYPE_FD) {
+ fd = *((int *)d->ptr);
+ } else {
+ fd = tmpfile_create (d->ptr, d->size + d->offset);
+ tmpfile = true;
+ }
+ am.port = 0;
+ am.id = i;
+ am.type = 0;
+ am.fd_index = spa_control_builder_add_fd (&builder, fd, tmpfile ? true : false);
+ am.offset = 0;
+ am.size = d->offset + d->size;
+ spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am);
+
+ b.idx[i] = i;
+ b.datas[i].type = SPA_DATA_TYPE_MEMID;
+ b.datas[i].ptr_type = NULL;
+ b.datas[i].ptr = &b.idx[i];
+ b.datas[i].offset = d->offset;
+ b.datas[i].size = d->size;
+ b.datas[i].stride = d->stride;
+ }
+ ab.port = 0;
+ ab.buffer = &b.buffer;
+ spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_BUFFER, &ab);
+ pb.port = 0;
+ pb.id = b.buffer.id;
+ spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_PROCESS_BUFFER, &pb);
+ rb.port = 0;
+ rb.id = b.buffer.id;
+ spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_REMOVE_BUFFER, &rb);
+
+ for (i = 0; i < buffer->n_datas; i++) {
+ SpaControlCmdRemoveMem rm;
+ rm.port = 0;
+ rm.id = i;
+ spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_REMOVE_MEM, &rm);
+ }
+ spa_control_builder_end (&builder, &control);
+
+ if ((res = spa_control_write (&control, this->fds[0].fd)) < 0)
+ fprintf (stderr, "proxy %p: error writing control", this);
+
+ spa_control_clear (&control);
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_port_push_input (SpaNode *node,
+ unsigned int n_info,
+ SpaInputInfo *info)
+{
+ SpaProxy *this;
+ SpaProxyPort *port;
+ unsigned int i;
+ bool have_error = false;
+ bool have_enough = false;
+
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ for (i = 0; i < n_info; i++) {
+ if (!CHECK_PORT_ID_DIR (this, info[i].port_id, SPA_DIRECTION_INPUT)) {
+ info[i].status = SPA_RESULT_INVALID_PORT;
+ have_error = true;
+ continue;
+ }
+ port = &this->ports[info[i].port_id];
+
+ if (!port->have_format) {
+ info[i].status = SPA_RESULT_NO_FORMAT;
+ have_error = true;
+ continue;
+ }
+
+ info[i].status = SPA_RESULT_OK;
+ }
+ if (have_error)
+ return SPA_RESULT_ERROR;
+ if (have_enough)
+ return SPA_RESULT_HAVE_ENOUGH_INPUT;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+spa_proxy_node_port_pull_output (SpaNode *node,
+ unsigned int n_info,
+ SpaOutputInfo *info)
+{
+ SpaProxy *this;
+ SpaProxyPort *port;
+ unsigned int i;
+ bool have_error = false;
+ bool need_more = false;
+
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaProxy *) node->handle;
+
+ for (i = 0; i < n_info; i++) {
+ if (!CHECK_PORT_ID_DIR (this, info[i].port_id, SPA_DIRECTION_OUTPUT)) {
+ info[i].status = SPA_RESULT_INVALID_PORT;
+ have_error = true;
+ continue;
+ }
+
+ port = &this->ports[info[i].port_id];
+
+ if (!port->have_format) {
+ info[i].status = SPA_RESULT_NO_FORMAT;
+ have_error = true;
+ continue;
+ }
+ }
+ if (have_error)
+ return SPA_RESULT_ERROR;
+ if (need_more)
+ return SPA_RESULT_NEED_MORE_INPUT;
+
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+parse_control (SpaProxy *this,
+ SpaControl *ctrl)
+{
+ SpaControlIter it;
+ SpaResult res;
+
+ spa_control_iter_init (&it, ctrl);
+ while (spa_control_iter_next (&it) == SPA_RESULT_OK) {
+ SpaControlCmd cmd = spa_control_iter_get_cmd (&it);
+
+ switch (cmd) {
+ case SPA_CONTROL_CMD_ADD_PORT:
+ case SPA_CONTROL_CMD_REMOVE_PORT:
+ case SPA_CONTROL_CMD_SET_FORMAT:
+ case SPA_CONTROL_CMD_SET_PROPERTY:
+ case SPA_CONTROL_CMD_END_CONFIGURE:
+ case SPA_CONTROL_CMD_PAUSE:
+ case SPA_CONTROL_CMD_START:
+ case SPA_CONTROL_CMD_STOP:
+ fprintf (stderr, "proxy %p: got unexpected control %d", this, cmd);
+ break;
+
+ case SPA_CONTROL_CMD_NODE_UPDATE:
+ case SPA_CONTROL_CMD_PORT_UPDATE:
+ case SPA_CONTROL_CMD_PORT_REMOVED:
+ fprintf (stderr, "proxy %p: command not implemented %d", this, cmd);
+ break;
+
+ case SPA_CONTROL_CMD_START_CONFIGURE:
+ {
+ SpaControlBuilder builder;
+ SpaControl control;
+ uint8_t buf[128];
+
+ /* set port format */
+
+ /* send end-configure */
+ spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
+ spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_END_CONFIGURE, NULL);
+ spa_control_builder_end (&builder, &control);
+
+ if ((res = spa_control_write (&control, this->fds[0].fd)) < 0)
+ fprintf (stderr, "proxy %p: error writing control: %d", this, res);
+ break;
+ }
+ case SPA_CONTROL_CMD_PORT_STATUS_CHANGE:
+ {
+ fprintf (stderr, "proxy %p: command not implemented %d", this, cmd);
+ break;
+ }
+ case SPA_CONTROL_CMD_START_ALLOC:
+ {
+ SpaControlBuilder builder;
+ SpaControl control;
+ uint8_t buf[128];
+
+ /* FIXME read port memory requirements */
+ /* FIXME add_mem */
+
+ /* send start */
+ spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
+ spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_START, NULL);
+ spa_control_builder_end (&builder, &control);
+
+ if ((res = spa_control_write (&control, this->fds[0].fd)) < 0)
+ fprintf (stderr, "proxy %p: error writing control %d", this, res);
+ break;
+ }
+ case SPA_CONTROL_CMD_NEED_INPUT:
+ {
+ break;
+ }
+ case SPA_CONTROL_CMD_HAVE_OUTPUT:
+ {
+ break;
+ }
+
+ case SPA_CONTROL_CMD_ADD_MEM:
+ break;
+ case SPA_CONTROL_CMD_REMOVE_MEM:
+ break;
+ case SPA_CONTROL_CMD_ADD_BUFFER:
+ break;
+ case SPA_CONTROL_CMD_REMOVE_BUFFER:
+ break;
+
+ case SPA_CONTROL_CMD_PROCESS_BUFFER:
+ {
+ break;
+ }
+ case SPA_CONTROL_CMD_REUSE_BUFFER:
+ {
+ break;
+ }
+ default:
+ fprintf (stderr, "proxy %p: command unhandled %d", this, cmd);
+ break;
+ }
+ }
+ spa_control_iter_end (&it);
+
+ return SPA_RESULT_OK;
+}
+
+static int
+proxy_on_fd_events (SpaPollNotifyData *data)
+{
+ SpaProxy *this = data->user_data;
+ SpaResult res;
+
+ if (data->fds[0].revents & POLLIN) {
+ SpaControl control;
+ uint8_t buf[1024];
+ int fds[16];
+
+ if ((res = spa_control_read (&control, data->fds[0].fd, buf, 1024, fds, 16)) < 0) {
+ fprintf (stderr, "proxy %p: failed to read control: %d", this, res);
+ return 0;
+ }
+ parse_control (this, &control);
+ spa_control_clear (&control);
+ }
+ return 0;
+}
+
+static const SpaNode proxy_node = {
+ NULL,
+ sizeof (SpaNode),
+ spa_proxy_node_get_props,
+ spa_proxy_node_set_props,
+ spa_proxy_node_send_command,
+ spa_proxy_node_set_event_callback,
+ spa_proxy_node_get_n_ports,
+ spa_proxy_node_get_port_ids,
+ spa_proxy_node_add_port,
+ spa_proxy_node_remove_port,
+ spa_proxy_node_port_enum_formats,
+ spa_proxy_node_port_set_format,
+ spa_proxy_node_port_get_format,
+ spa_proxy_node_port_get_info,
+ spa_proxy_node_port_get_props,
+ spa_proxy_node_port_set_props,
+ spa_proxy_node_port_use_buffers,
+ spa_proxy_node_port_alloc_buffers,
+ spa_proxy_node_port_get_status,
+ spa_proxy_node_port_push_input,
+ spa_proxy_node_port_pull_output,
+};
+
+static SpaResult
+spa_proxy_get_interface (SpaHandle *handle,
+ uint32_t interface_id,
+ void **interface)
+{
+ SpaProxy *this = (SpaProxy *) handle;
+
+ if (handle == NULL || interface == 0)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ switch (interface_id) {
+ case SPA_INTERFACE_ID_NODE:
+ *interface = &this->node;
+ break;
+ default:
+ return SPA_RESULT_UNKNOWN_INTERFACE;
+
+ }
+ return SPA_RESULT_OK;
+}
+
+static SpaResult
+proxy_instantiate (const SpaHandleFactory *factory,
+ SpaHandle *handle)
+{
+ SpaProxy *this;
+
+ if (factory == NULL || handle == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ handle->get_interface = spa_proxy_get_interface;
+
+ this = (SpaProxy *) handle;
+ this->node = proxy_node;
+ this->node.handle = handle;
+ this->props[1].props.n_prop_info = PROP_ID_LAST;
+ this->props[1].props.prop_info = prop_info;
+ this->props[1].props.set_prop = spa_props_generic_set_prop;
+ this->props[1].props.get_prop = spa_props_generic_get_prop;
+ reset_proxy_props (&this->props[1]);
+ memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
+
+ this->fds[0].fd = -1;
+ this->fds[0].events = POLLIN | POLLPRI | POLLERR;
+ this->fds[0].revents = 0;
+ this->poll.id = 0;
+ this->poll.fds = this->fds;
+ this->poll.n_fds = 1;
+ this->poll.idle_cb = NULL;
+ this->poll.before_cb = NULL;
+ this->poll.after_cb = proxy_on_fd_events;
+ this->poll.user_data = this;
+
+ return SPA_RESULT_OK;
+}
+
+static const SpaInterfaceInfo proxy_interfaces[] =
+{
+ { SPA_INTERFACE_ID_NODE,
+ SPA_INTERFACE_ID_NODE_NAME,
+ SPA_INTERFACE_ID_NODE_DESCRIPTION,
+ },
+};
+
+static SpaResult
+proxy_enum_interface_info (const SpaHandleFactory *factory,
+ const SpaInterfaceInfo **info,
+ void **state)
+{
+ int index;
+
+ if (factory == NULL || info == NULL || state == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ index = (*state == NULL ? 0 : *(int*)state);
+
+ switch (index) {
+ case 0:
+ *info = &proxy_interfaces[index];
+ break;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ *(int*)state = ++index;
+
+ return SPA_RESULT_OK;
+}
+
+const SpaHandleFactory spa_proxy_factory =
+{ "proxy",
+ NULL,
+ sizeof (SpaProxy),
+ proxy_instantiate,
+ proxy_enum_interface_info,
+};
diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c
index 312f9e31..1b5293f6 100644
--- a/spa/plugins/v4l2/v4l2-source.c
+++ b/spa/plugins/v4l2/v4l2-source.c
@@ -117,6 +117,7 @@ typedef struct {
struct _SpaV4l2Source {
SpaHandle handle;
+ SpaNode node;
SpaV4l2SourceProps props[2];
@@ -167,14 +168,16 @@ static const SpaPropInfo prop_info[] =
};
static SpaResult
-spa_v4l2_source_node_get_props (SpaHandle *handle,
+spa_v4l2_source_node_get_props (SpaNode *node,
SpaProps **props)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
- if (handle == NULL || props == NULL)
+ if (node == NULL || node->handle == NULL || props == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
*props = &this->props[0].props;
@@ -182,16 +185,19 @@ spa_v4l2_source_node_get_props (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_set_props (SpaHandle *handle,
+spa_v4l2_source_node_set_props (SpaNode *node,
const SpaProps *props)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
- SpaV4l2SourceProps *p = &this->props[1];
+ SpaV4l2Source *this;
+ SpaV4l2SourceProps *p;
SpaResult res;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+ p = &this->props[1];
+
if (props == NULL) {
reset_v4l2_source_props (p);
return SPA_RESULT_OK;
@@ -203,14 +209,16 @@ spa_v4l2_source_node_set_props (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_send_command (SpaHandle *handle,
+spa_v4l2_source_node_send_command (SpaNode *node,
SpaCommand *command)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
- if (handle == NULL || command == NULL)
+ if (node == NULL || node->handle == NULL || command == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
switch (command->type) {
case SPA_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
@@ -228,7 +236,7 @@ spa_v4l2_source_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
case SPA_COMMAND_STOP:
@@ -244,7 +252,7 @@ spa_v4l2_source_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -257,15 +265,17 @@ spa_v4l2_source_node_send_command (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_set_event_callback (SpaHandle *handle,
+spa_v4l2_source_node_set_event_callback (SpaNode *node,
SpaEventCallback event,
void *user_data)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
this->event_cb = event;
this->user_data = user_data;
@@ -273,13 +283,13 @@ spa_v4l2_source_node_set_event_callback (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_get_n_ports (SpaHandle *handle,
+spa_v4l2_source_node_get_n_ports (SpaNode *node,
unsigned int *n_input_ports,
unsigned int *max_input_ports,
unsigned int *n_output_ports,
unsigned int *max_output_ports)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports)
@@ -295,13 +305,13 @@ spa_v4l2_source_node_get_n_ports (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_get_port_ids (SpaHandle *handle,
+spa_v4l2_source_node_get_port_ids (SpaNode *node,
unsigned int n_input_ports,
uint32_t *input_ids,
unsigned int n_output_ports,
uint32_t *output_ids)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_output_ports > 0)
@@ -312,15 +322,15 @@ spa_v4l2_source_node_get_port_ids (SpaHandle *handle,
static SpaResult
-spa_v4l2_source_node_add_port (SpaHandle *handle,
+spa_v4l2_source_node_add_port (SpaNode *node,
SpaDirection direction,
- uint32_t *port_id)
+ uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_v4l2_source_node_remove_port (SpaHandle *handle,
+spa_v4l2_source_node_remove_port (SpaNode *node,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@@ -354,18 +364,20 @@ spa_v4l2_format_init (V4l2Format *f)
}
static SpaResult
-spa_v4l2_source_node_port_enum_formats (SpaHandle *handle,
+spa_v4l2_source_node_port_enum_formats (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
SpaResult res;
- if (handle == NULL || format == NULL || state == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL || state == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -375,20 +387,22 @@ spa_v4l2_source_node_port_enum_formats (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_port_set_format (SpaHandle *handle,
+spa_v4l2_source_node_port_set_format (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
SpaV4l2State *state;
SpaResult res;
V4l2Format *f, *tf;
size_t fs;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -421,16 +435,18 @@ spa_v4l2_source_node_port_set_format (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_port_get_format (SpaHandle *handle,
+spa_v4l2_source_node_port_get_format (SpaNode *node,
uint32_t port_id,
const SpaFormat **format)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
SpaV4l2State *state;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -445,15 +461,17 @@ spa_v4l2_source_node_port_get_format (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_port_get_info (SpaHandle *handle,
+spa_v4l2_source_node_port_get_info (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
- if (handle == NULL || info == NULL)
+ if (node == NULL || node->handle == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -463,7 +481,7 @@ spa_v4l2_source_node_port_get_info (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_port_get_props (SpaHandle *handle,
+spa_v4l2_source_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
{
@@ -471,7 +489,7 @@ spa_v4l2_source_node_port_get_props (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_port_set_props (SpaHandle *handle,
+spa_v4l2_source_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
{
@@ -479,15 +497,17 @@ spa_v4l2_source_node_port_set_props (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_port_get_status (SpaHandle *handle,
+spa_v4l2_source_node_port_get_status (SpaNode *node,
uint32_t port_id,
const SpaPortStatus **status)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
- if (handle == NULL || status == NULL)
+ if (node == NULL || node->handle == NULL || status == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -497,16 +517,18 @@ spa_v4l2_source_node_port_get_status (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_port_use_buffers (SpaHandle *handle,
+spa_v4l2_source_node_port_use_buffers (SpaNode *node,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -516,19 +538,31 @@ spa_v4l2_source_node_port_use_buffers (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_port_alloc_buffers (SpaHandle *handle,
+spa_v4l2_source_node_port_alloc_buffers (SpaNode *node,
uint32_t port_id,
SpaAllocParam **params,
- uint32_t n_params,
+ unsigned int n_params,
SpaBuffer **buffers,
- uint32_t *n_buffers)
+ unsigned int *n_buffers)
{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ SpaV4l2Source *this;
+
+ if (node == NULL || node->handle == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = (SpaV4l2Source *) node->handle;
+
+ if (port_id != 0)
+ return SPA_RESULT_INVALID_PORT;
+
+ spa_v4l2_alloc_buffers (this, params, n_params, buffers, n_buffers);
+
+ return SPA_RESULT_OK;
}
static SpaResult
-spa_v4l2_source_node_port_push_input (SpaHandle *handle,
+spa_v4l2_source_node_port_push_input (SpaNode *node,
unsigned int n_info,
SpaInputInfo *info)
{
@@ -536,18 +570,20 @@ spa_v4l2_source_node_port_push_input (SpaHandle *handle,
}
static SpaResult
-spa_v4l2_source_node_port_pull_output (SpaHandle *handle,
+spa_v4l2_source_node_port_pull_output (SpaNode *node,
unsigned int n_info,
SpaOutputInfo *info)
{
- SpaV4l2Source *this = (SpaV4l2Source *) handle;
+ SpaV4l2Source *this;
SpaV4l2State *state;
unsigned int i;
bool have_error = false;
- if (handle == NULL || n_info == 0 || info == NULL)
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) node->handle;
+
for (i = 0; i < n_info; i++) {
V4l2Buffer *b;
@@ -576,7 +612,7 @@ spa_v4l2_source_node_port_pull_output (SpaHandle *handle,
b->outstanding = true;
- info[i].buffer = &b->buffer;
+ info[i].id = b->buffer.id;
info[i].status = SPA_RESULT_OK;
}
if (have_error)
@@ -585,7 +621,17 @@ spa_v4l2_source_node_port_pull_output (SpaHandle *handle,
return SPA_RESULT_OK;
}
+static SpaResult
+spa_v4l2_source_node_port_push_event (SpaNode *node,
+ uint32_t port_id,
+ SpaEvent *event)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
+
static const SpaNode v4l2source_node = {
+ NULL,
sizeof (SpaNode),
spa_v4l2_source_node_get_props,
spa_v4l2_source_node_set_props,
@@ -606,19 +652,24 @@ static const SpaNode v4l2source_node = {
spa_v4l2_source_node_port_get_status,
spa_v4l2_source_node_port_push_input,
spa_v4l2_source_node_port_pull_output,
+ spa_v4l2_source_node_port_push_event,
};
static SpaResult
spa_v4l2_source_get_interface (SpaHandle *handle,
uint32_t interface_id,
- const void **interface)
+ void **interface)
{
+ SpaV4l2Source *this;
+
if (handle == NULL || interface == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaV4l2Source *) handle;
+
switch (interface_id) {
case SPA_INTERFACE_ID_NODE:
- *interface = &v4l2source_node;
+ *interface = &this->node;
break;
default:
return SPA_RESULT_UNKNOWN_INTERFACE;
@@ -638,6 +689,8 @@ v4l2_source_init (const SpaHandleFactory *factory,
handle->get_interface = spa_v4l2_source_get_interface;
this = (SpaV4l2Source *) handle;
+ this->node = v4l2source_node;
+ this->node.handle = handle;
this->props[1].props.n_prop_info = PROP_ID_LAST;
this->props[1].props.prop_info = prop_info;
this->props[1].props.set_prop = spa_props_generic_set_prop;
diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c
index 5eb7ede4..290170f5 100644
--- a/spa/plugins/v4l2/v4l2-utils.c
+++ b/spa/plugins/v4l2/v4l2-utils.c
@@ -481,19 +481,20 @@ v4l2_on_fd_events (SpaPollNotifyData *data)
event.port_id = 0;
event.size = 0;
event.data = NULL;
- this->event_cb (&this->handle, &event, this->user_data);
+ this->event_cb (&this->node, &event, this->user_data);
return 0;
}
static void
-v4l2_buffer_free (void *data)
+v4l2_buffer_recycle (void *data)
{
- V4l2Buffer *b = (V4l2Buffer *) data;
- SpaV4l2Source *this = b->source;
+ SpaBuffer *buf = data;
+ SpaV4l2Source *this = buf->user_data;
SpaV4l2State *state = &this->state[0];
+ V4l2Buffer *b = &state->buffers[buf->id];
- b->buffer.refcount = 1;
+ b->imported->refcount = 1;
b->outstanding = false;
if (xioctl (state->fd, VIDIOC_QBUF, &b->v4l2_buffer) < 0) {
@@ -531,10 +532,15 @@ spa_v4l2_import_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_bu
b = &state->buffers[i];
+ buffers[i]->notify = v4l2_buffer_recycle;
+ buffers[i]->user_data = this;
+
+ fprintf (stderr, "import buffer %p\n", buffers[i]);
+
b->source = this;
b->buffer.refcount = 0;
- b->buffer.notify = v4l2_buffer_free;
- b->buffer.id = i;
+ b->buffer.notify = v4l2_buffer_recycle;
+ b->buffer.id = buffers[i]->id;
b->buffer.size = buffers[i]->size;
b->buffer.n_metas = buffers[i]->n_metas;
b->buffer.metas = buffers[i]->metas;
@@ -550,7 +556,7 @@ spa_v4l2_import_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_bu
b->v4l2_buffer.m.userptr = (unsigned long) b->buffer.datas[0].ptr;
b->v4l2_buffer.length = b->buffer.datas[0].size;
- v4l2_buffer_free (b);
+ v4l2_buffer_recycle (buffers[i]);
}
state->have_buffers = true;
@@ -558,7 +564,11 @@ spa_v4l2_import_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_bu
}
static int
-mmap_init (SpaV4l2Source *this)
+mmap_init (SpaV4l2Source *this,
+ SpaAllocParam **params,
+ unsigned int n_params,
+ SpaBuffer **buffers,
+ unsigned int *n_buffers)
{
SpaV4l2State *state = &this->state[0];
struct v4l2_requestbuffers reqbuf;
@@ -569,7 +579,7 @@ mmap_init (SpaV4l2Source *this)
CLEAR(reqbuf);
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = state->memtype;
- reqbuf.count = MAX_BUFFERS;
+ reqbuf.count = *n_buffers;
if (xioctl (state->fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
perror ("VIDIOC_REQBUFS");
@@ -577,6 +587,8 @@ mmap_init (SpaV4l2Source *this)
}
fprintf (stderr, "got %d buffers\n", reqbuf.count);
+ *n_buffers = reqbuf.count;
+
if (reqbuf.count < 2) {
fprintf (stderr, "can't allocate enough buffers\n");
return -1;
@@ -601,9 +613,13 @@ mmap_init (SpaV4l2Source *this)
}
b = &state->buffers[i];
+
+ buffers[i] = &b->buffer;
+
b->source = this;
b->buffer.refcount = 0;
- b->buffer.notify = v4l2_buffer_free;
+ b->buffer.notify = v4l2_buffer_recycle;
+ b->buffer.user_data = this;
b->buffer.id = i;
b->buffer.size = buf.length;
b->buffer.n_metas = 1;
@@ -655,6 +671,7 @@ mmap_init (SpaV4l2Source *this)
continue;
}
}
+ b->imported = &b->buffer;
b->outstanding = true;
CLEAR (b->v4l2_buffer);
@@ -662,7 +679,7 @@ mmap_init (SpaV4l2Source *this)
b->v4l2_buffer.memory = state->memtype;
b->v4l2_buffer.index = i;
- v4l2_buffer_free (b);
+ v4l2_buffer_recycle (b);
}
state->have_buffers = true;
@@ -682,6 +699,27 @@ read_init (SpaV4l2Source *this)
}
static int
+spa_v4l2_alloc_buffers (SpaV4l2Source *this,
+ SpaAllocParam **params,
+ unsigned int n_params,
+ SpaBuffer **buffers,
+ unsigned int *n_buffers)
+{
+ SpaV4l2State *state = &this->state[0];
+
+ if (state->cap.capabilities & V4L2_CAP_STREAMING) {
+ if (mmap_init (this, params, n_params, buffers, n_buffers) < 0)
+ if (userptr_init (this) < 0)
+ return -1;
+ } else if (state->cap.capabilities & V4L2_CAP_READWRITE) {
+ if (read_init (this) < 0)
+ return -1;
+ } else
+ return -1;
+ return 0;
+}
+
+static int
spa_v4l2_start (SpaV4l2Source *this)
{
SpaV4l2State *state = &this->state[0];
@@ -691,17 +729,9 @@ spa_v4l2_start (SpaV4l2Source *this)
if (spa_v4l2_open (this) < 0)
return -1;
- if (!state->have_buffers) {
- if (state->cap.capabilities & V4L2_CAP_STREAMING) {
- if (mmap_init (this) < 0)
- if (userptr_init (this) < 0)
- return -1;
- } else if (state->cap.capabilities & V4L2_CAP_READWRITE) {
- if (read_init (this) < 0)
- return -1;
- } else
- return -1;
- }
+ if (!state->have_buffers)
+ return -1;
+
event.refcount = 1;
event.notify = NULL;
@@ -714,13 +744,14 @@ spa_v4l2_start (SpaV4l2Source *this)
state->fds[0].events = POLLIN | POLLPRI | POLLERR;
state->fds[0].revents = 0;
+ state->poll.id = 0;
state->poll.fds = state->fds;
state->poll.n_fds = 1;
state->poll.idle_cb = NULL;
state->poll.before_cb = NULL;
state->poll.after_cb = v4l2_on_fd_events;
state->poll.user_data = this;
- this->event_cb (&this->handle, &event, this->user_data);
+ this->event_cb (&this->node, &event, this->user_data);
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (xioctl (state->fd, VIDIOC_STREAMON, &type) < 0) {
@@ -750,7 +781,7 @@ spa_v4l2_stop (SpaV4l2Source *this)
b = &state->buffers[i];
if (b->outstanding) {
fprintf (stderr, "queueing outstanding buffer %p\n", b);
- v4l2_buffer_free (b);
+ v4l2_buffer_recycle (b);
}
if (state->export_buf) {
close (b->dmafd);
@@ -766,7 +797,7 @@ spa_v4l2_stop (SpaV4l2Source *this)
event.port_id = 0;
event.data = &state->poll;
event.size = sizeof (state->poll);
- this->event_cb (&this->handle, &event, this->user_data);
+ this->event_cb (&this->node, &event, this->user_data);
spa_v4l2_close (this);
diff --git a/spa/plugins/volume/volume.c b/spa/plugins/volume/volume.c
index 9c501c09..e5afc217 100644
--- a/spa/plugins/volume/volume.c
+++ b/spa/plugins/volume/volume.c
@@ -35,10 +35,14 @@ typedef struct {
bool have_format;
SpaPortInfo info;
SpaPortStatus status;
+ SpaBuffer **buffers;
+ unsigned int n_buffers;
+ SpaBuffer *buffer;
} SpaVolumePort;
struct _SpaVolume {
SpaHandle handle;
+ SpaNode node;
SpaVolumeProps props[2];
@@ -50,7 +54,6 @@ struct _SpaVolume {
SpaAudioRawFormat current_format;
SpaVolumePort ports[2];
- SpaBuffer *input_buffer;
};
static const double default_volume = 1.0;
@@ -99,14 +102,16 @@ reset_volume_props (SpaVolumeProps *props)
}
static SpaResult
-spa_volume_node_get_props (SpaHandle *handle,
+spa_volume_node_get_props (SpaNode *node,
SpaProps **props)
{
- SpaVolume *this = (SpaVolume *) handle;
+ SpaVolume *this;
- if (handle == NULL || props == NULL)
+ if (node == NULL || node->handle == NULL || props == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
*props = &this->props[0].props;
@@ -114,16 +119,19 @@ spa_volume_node_get_props (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_set_props (SpaHandle *handle,
+spa_volume_node_set_props (SpaNode *node,
const SpaProps *props)
{
- SpaVolume *this = (SpaVolume *) handle;
- SpaVolumeProps *p = &this->props[1];
+ SpaVolume *this;
+ SpaVolumeProps *p;
SpaResult res;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+ p = &this->props[1];
+
if (props == NULL) {
reset_volume_props (p);
return SPA_RESULT_OK;
@@ -134,14 +142,16 @@ spa_volume_node_set_props (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_send_command (SpaHandle *handle,
+spa_volume_node_send_command (SpaNode *node,
SpaCommand *command)
{
- SpaVolume *this = (SpaVolume *) handle;
+ SpaVolume *this;
- if (handle == NULL || command == NULL)
+ if (node == NULL || node->handle == NULL || command == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
switch (command->type) {
case SPA_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
@@ -157,7 +167,7 @@ spa_volume_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -172,7 +182,7 @@ spa_volume_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -185,15 +195,17 @@ spa_volume_node_send_command (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_set_event_callback (SpaHandle *handle,
+spa_volume_node_set_event_callback (SpaNode *node,
SpaEventCallback event,
void *user_data)
{
- SpaVolume *this = (SpaVolume *) handle;
+ SpaVolume *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
this->event_cb = event;
this->user_data = user_data;
@@ -201,13 +213,13 @@ spa_volume_node_set_event_callback (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_get_n_ports (SpaHandle *handle,
+spa_volume_node_get_n_ports (SpaNode *node,
unsigned int *n_input_ports,
unsigned int *max_input_ports,
unsigned int *n_output_ports,
unsigned int *max_output_ports)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports)
@@ -223,13 +235,13 @@ spa_volume_node_get_n_ports (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_get_port_ids (SpaHandle *handle,
+spa_volume_node_get_port_ids (SpaNode *node,
unsigned int n_input_ports,
uint32_t *input_ids,
unsigned int n_output_ports,
uint32_t *output_ids)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports > 0 && input_ids)
@@ -242,33 +254,35 @@ spa_volume_node_get_port_ids (SpaHandle *handle,
static SpaResult
-spa_volume_node_add_port (SpaHandle *handle,
+spa_volume_node_add_port (SpaNode *node,
SpaDirection direction,
- uint32_t *port_id)
+ uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_volume_node_remove_port (SpaHandle *handle,
+spa_volume_node_remove_port (SpaNode *node,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_volume_node_port_enum_formats (SpaHandle *handle,
+spa_volume_node_port_enum_formats (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state)
{
- SpaVolume *this = (SpaVolume *) handle;
+ SpaVolume *this;
int index;
- if (handle == NULL || format == NULL || state == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL || state == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -288,47 +302,57 @@ spa_volume_node_port_enum_formats (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_port_set_format (SpaHandle *handle,
+spa_volume_node_port_set_format (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
{
- SpaVolume *this = (SpaVolume *) handle;
+ SpaVolume *this;
+ SpaVolumePort *port;
SpaResult res;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
if (port_id >= 2)
return SPA_RESULT_INVALID_PORT;
+ port = &this->ports[port_id];
+
if (format == NULL) {
- this->ports[port_id].have_format = false;
+ port->have_format = false;
return SPA_RESULT_OK;
}
if ((res = spa_audio_raw_format_parse (format, &this->current_format)) < 0)
return res;
- this->ports[port_id].have_format = true;
+ port->have_format = true;
return SPA_RESULT_OK;
}
static SpaResult
-spa_volume_node_port_get_format (SpaHandle *handle,
+spa_volume_node_port_get_format (SpaNode *node,
uint32_t port_id,
const SpaFormat **format)
{
- SpaVolume *this = (SpaVolume *) handle;
+ SpaVolume *this;
+ SpaVolumePort *port;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
if (port_id >= 2)
return SPA_RESULT_INVALID_PORT;
- if (!this->ports[port_id].have_format)
+ port = &this->ports[port_id];
+
+ if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
*format = &this->current_format.format;
@@ -337,25 +361,29 @@ spa_volume_node_port_get_format (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_port_get_info (SpaHandle *handle,
+spa_volume_node_port_get_info (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info)
{
- SpaVolume *this = (SpaVolume *) handle;
+ SpaVolume *this;
+ SpaVolumePort *port;
- if (handle == NULL || info == NULL)
+ if (node == NULL || node->handle == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
if (port_id >= 2)
return SPA_RESULT_INVALID_PORT;
- *info = &this->ports[port_id].info;
+ port = &this->ports[port_id];
+ *info = &port->info;
return SPA_RESULT_OK;
}
static SpaResult
-spa_volume_node_port_get_props (SpaHandle *handle,
+spa_volume_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
{
@@ -363,7 +391,7 @@ spa_volume_node_port_get_props (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_port_set_props (SpaHandle *handle,
+spa_volume_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
{
@@ -371,28 +399,33 @@ spa_volume_node_port_set_props (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_port_get_status (SpaHandle *handle,
+spa_volume_node_port_get_status (SpaNode *node,
uint32_t port_id,
const SpaPortStatus **status)
{
- SpaVolume *this = (SpaVolume *) handle;
+ SpaVolume *this;
+ SpaVolumePort *port;
- if (handle == NULL || status == NULL)
+ if (node == NULL || node->handle == NULL || status == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
if (port_id >= 2)
return SPA_RESULT_INVALID_PORT;
- if (!this->ports[port_id].have_format)
+ port = &this->ports[port_id];
+
+ if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
- *status = &this->ports[port_id].status;
+ *status = &port->status;
return SPA_RESULT_OK;
}
static SpaResult
-spa_volume_node_port_use_buffers (SpaHandle *handle,
+spa_volume_node_port_use_buffers (SpaNode *node,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@@ -401,7 +434,7 @@ spa_volume_node_port_use_buffers (SpaHandle *handle,
}
static SpaResult
-spa_volume_node_port_alloc_buffers (SpaHandle *handle,
+spa_volume_node_port_alloc_buffers (SpaNode *node,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@@ -413,59 +446,56 @@ spa_volume_node_port_alloc_buffers (SpaHandle *handle,
static SpaResult
-spa_volume_node_port_push_input (SpaHandle *handle,
+spa_volume_node_port_push_input (SpaNode *node,
unsigned int n_info,
SpaInputInfo *info)
{
- SpaVolume *this = (SpaVolume *) handle;
- SpaBuffer *buffer;
- SpaEvent *event;
+ SpaVolume *this;
unsigned int i;
bool have_error = false;
bool have_enough = false;
- if (handle == NULL || n_info == 0 || info == NULL)
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
for (i = 0; i < n_info; i++) {
+ SpaVolumePort *port;
+ SpaBuffer *buffer;
+
if (info[i].port_id != 0) {
info[i].status = SPA_RESULT_INVALID_PORT;
have_error = true;
continue;
}
- event = info[i].event;
- buffer = info[i].buffer;
+ port = &this->ports[info[i].port_id];
+ buffer = port->buffers[info[i].id];
- if (buffer == NULL && event == NULL) {
+ if (buffer == NULL) {
info[i].status = SPA_RESULT_INVALID_ARGUMENTS;
have_error = true;
continue;
}
if (buffer) {
- if (!this->ports[0].have_format) {
+ if (!port->have_format) {
info[i].status = SPA_RESULT_NO_FORMAT;
have_error = true;
continue;
}
- if (this->input_buffer != NULL) {
+ if (port->buffer != NULL) {
info[i].status = SPA_RESULT_HAVE_ENOUGH_INPUT;
have_enough = true;
continue;
}
- this->input_buffer = spa_buffer_ref (buffer);
+ port->buffer = spa_buffer_ref (buffer);
this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[1].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
}
- if (event) {
- switch (event->type) {
- default:
- break;
- }
- }
info[i].status = SPA_RESULT_OK;
}
if (have_error)
@@ -476,36 +506,44 @@ spa_volume_node_port_push_input (SpaHandle *handle,
return SPA_RESULT_OK;
}
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
+static SpaBuffer *
+find_free_buffer (SpaVolume *this, SpaVolumePort *port)
+{
+ return NULL;
+}
static SpaResult
-spa_volume_node_port_pull_output (SpaHandle *handle,
+spa_volume_node_port_pull_output (SpaNode *node,
unsigned int n_info,
SpaOutputInfo *info)
{
- SpaVolume *this = (SpaVolume *) handle;
+ SpaVolume *this;
+ SpaVolumePort *port;
unsigned int si, di, i, n_samples, n_bytes, soff, doff ;
SpaBuffer *sbuf, *dbuf;
SpaData *sd, *dd;
uint16_t *src, *dst;
double volume;
- if (handle == NULL || n_info == 0 || info == NULL)
+ if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) node->handle;
+
if (info->port_id != 1)
return SPA_RESULT_INVALID_PORT;
- if (!this->ports[1].have_format)
+ port = &this->ports[info[0].port_id];
+ if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
- if (this->input_buffer == NULL)
+ if (this->ports[0].buffer == NULL)
return SPA_RESULT_NEED_MORE_INPUT;
volume = this->props[1].volume;
- sbuf = this->input_buffer;
- dbuf = info->buffer ? info->buffer : this->input_buffer;
+ sbuf = this->ports[0].buffer;
+ dbuf = find_free_buffer (this, port);
si = di = 0;
soff = doff = 0;
@@ -528,7 +566,7 @@ spa_volume_node_port_pull_output (SpaHandle *handle,
src = (uint16_t*) ((uint8_t*)sd->ptr + soff);
dst = (uint16_t*) ((uint8_t*)dd->ptr + doff);
- n_bytes = MIN (sd->size - soff, dd->size - doff);
+ n_bytes = SPA_MIN (sd->size - soff, dd->size - doff);
n_samples = n_bytes / sizeof (uint16_t);
for (i = 0; i < n_samples; i++)
@@ -550,8 +588,8 @@ spa_volume_node_port_pull_output (SpaHandle *handle,
if (sbuf != dbuf)
spa_buffer_unref (sbuf);
- this->input_buffer = NULL;
- info->buffer = dbuf;
+ this->ports[0].buffer = NULL;
+ info->id = dbuf->id;
this->ports[0].status.flags |= SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[1].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
@@ -559,7 +597,16 @@ spa_volume_node_port_pull_output (SpaHandle *handle,
return SPA_RESULT_OK;
}
+static SpaResult
+spa_volume_node_port_push_event (SpaNode *node,
+ uint32_t port_id,
+ SpaEvent *event)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
+}
+
static const SpaNode volume_node = {
+ NULL,
sizeof (SpaNode),
spa_volume_node_get_props,
spa_volume_node_set_props,
@@ -580,19 +627,24 @@ static const SpaNode volume_node = {
spa_volume_node_port_get_status,
spa_volume_node_port_push_input,
spa_volume_node_port_pull_output,
+ spa_volume_node_port_push_event,
};
static SpaResult
spa_volume_get_interface (SpaHandle *handle,
uint32_t interface_id,
- const void **interface)
+ void **interface)
{
+ SpaVolume *this;
+
if (handle == NULL || interface == 0)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaVolume *) handle;
+
switch (interface_id) {
case SPA_INTERFACE_ID_NODE:
- *interface = &volume_node;
+ *interface = &this->node;
break;
default:
return SPA_RESULT_UNKNOWN_INTERFACE;
@@ -613,6 +665,8 @@ volume_instantiate (const SpaHandleFactory *factory,
handle->get_interface = spa_volume_get_interface;
this = (SpaVolume *) handle;
+ this->node = volume_node;
+ this->node.handle = handle;
this->props[1].props.n_prop_info = PROP_ID_LAST;
this->props[1].props.prop_info = prop_info;
this->props[1].props.set_prop = spa_props_generic_set_prop;
diff --git a/spa/plugins/xv/xv-sink.c b/spa/plugins/xv/xv-sink.c
index b8a5dd55..75350a0c 100644
--- a/spa/plugins/xv/xv-sink.c
+++ b/spa/plugins/xv/xv-sink.c
@@ -69,6 +69,7 @@ typedef struct {
struct _SpaXvSink {
SpaHandle handle;
+ SpaNode node;
SpaXvSinkProps props[2];
@@ -126,14 +127,16 @@ static const SpaPropInfo prop_info[] =
};
static SpaResult
-spa_xv_sink_node_get_props (SpaHandle *handle,
+spa_xv_sink_node_get_props (SpaNode *node,
SpaProps **props)
{
- SpaXvSink *this = (SpaXvSink *) handle;
+ SpaXvSink *this;
- if (handle == NULL || props == NULL)
+ if (node == NULL || node->handle == NULL || props == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) node->handle;
+
memcpy (&this->props[0], &this->props[1], sizeof (this->props[1]));
*props = &this->props[0].props;
@@ -141,16 +144,19 @@ spa_xv_sink_node_get_props (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_set_props (SpaHandle *handle,
+spa_xv_sink_node_set_props (SpaNode *node,
const SpaProps *props)
{
- SpaXvSink *this = (SpaXvSink *) handle;
- SpaXvSinkProps *p = &this->props[1];
+ SpaXvSink *this;
+ SpaXvSinkProps *p;
SpaResult res;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) node->handle;
+ p = &this->props[1];
+
if (props == NULL) {
reset_xv_sink_props (p);
return SPA_RESULT_OK;
@@ -162,14 +168,16 @@ spa_xv_sink_node_set_props (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_send_command (SpaHandle *handle,
- SpaCommand *command)
+spa_xv_sink_node_send_command (SpaNode *node,
+ SpaCommand *command)
{
- SpaXvSink *this = (SpaXvSink *) handle;
+ SpaXvSink *this;
- if (handle == NULL || command == NULL)
+ if (node == NULL || node->handle == NULL || command == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) node->handle;
+
switch (command->type) {
case SPA_COMMAND_INVALID:
return SPA_RESULT_INVALID_COMMAND;
@@ -187,7 +195,7 @@ spa_xv_sink_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
case SPA_COMMAND_STOP:
@@ -203,7 +211,7 @@ spa_xv_sink_node_send_command (SpaHandle *handle,
event.data = NULL;
event.size = 0;
- this->event_cb (handle, &event, this->user_data);
+ this->event_cb (node, &event, this->user_data);
}
break;
@@ -216,15 +224,17 @@ spa_xv_sink_node_send_command (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_set_event_callback (SpaHandle *handle,
+spa_xv_sink_node_set_event_callback (SpaNode *node,
SpaEventCallback event,
void *user_data)
{
- SpaXvSink *this = (SpaXvSink *) handle;
+ SpaXvSink *this;
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) node->handle;
+
this->event_cb = event;
this->user_data = user_data;
@@ -232,13 +242,13 @@ spa_xv_sink_node_set_event_callback (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_get_n_ports (SpaHandle *handle,
+spa_xv_sink_node_get_n_ports (SpaNode *node,
unsigned int *n_input_ports,
unsigned int *max_input_ports,
unsigned int *n_output_ports,
unsigned int *max_output_ports)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_input_ports)
@@ -254,13 +264,13 @@ spa_xv_sink_node_get_n_ports (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_get_port_ids (SpaHandle *handle,
+spa_xv_sink_node_get_port_ids (SpaNode *node,
unsigned int n_input_ports,
uint32_t *input_ids,
unsigned int n_output_ports,
uint32_t *output_ids)
{
- if (handle == NULL)
+ if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (n_output_ports > 0)
@@ -271,33 +281,35 @@ spa_xv_sink_node_get_port_ids (SpaHandle *handle,
static SpaResult
-spa_xv_sink_node_add_port (SpaHandle *handle,
+spa_xv_sink_node_add_port (SpaNode *node,
SpaDirection direction,
- uint32_t *port_id)
+ uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_xv_sink_node_remove_port (SpaHandle *handle,
+spa_xv_sink_node_remove_port (SpaNode *node,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_xv_sink_node_port_enum_formats (SpaHandle *handle,
+spa_xv_sink_node_port_enum_formats (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state)
{
- SpaXvSink *this = (SpaXvSink *) handle;
+ SpaXvSink *this;
int index;
- if (handle == NULL || format == NULL || state == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL || state == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -317,19 +329,21 @@ spa_xv_sink_node_port_enum_formats (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_port_set_format (SpaHandle *handle,
+spa_xv_sink_node_port_set_format (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
{
- SpaXvSink *this = (SpaXvSink *) handle;
+ SpaXvSink *this;
SpaResult res;
SpaFormat *f, *tf;
size_t fs;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -363,15 +377,17 @@ spa_xv_sink_node_port_set_format (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_port_get_format (SpaHandle *handle,
+spa_xv_sink_node_port_get_format (SpaNode *node,
uint32_t port_id,
const SpaFormat **format)
{
- SpaXvSink *this = (SpaXvSink *) handle;
+ SpaXvSink *this;
- if (handle == NULL || format == NULL)
+ if (node == NULL || node->handle == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -384,15 +400,17 @@ spa_xv_sink_node_port_get_format (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_port_get_info (SpaHandle *handle,
+spa_xv_sink_node_port_get_info (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info)
{
- SpaXvSink *this = (SpaXvSink *) handle;
+ SpaXvSink *this;
- if (handle == NULL || info == NULL)
+ if (node == NULL || node->handle == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -402,7 +420,7 @@ spa_xv_sink_node_port_get_info (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_port_get_props (SpaHandle *handle,
+spa_xv_sink_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
{
@@ -410,7 +428,7 @@ spa_xv_sink_node_port_get_props (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_port_set_props (SpaHandle *handle,
+spa_xv_sink_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
{
@@ -418,15 +436,17 @@ spa_xv_sink_node_port_set_props (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_port_get_status (SpaHandle *handle,
+spa_xv_sink_node_port_get_status (SpaNode *node,
uint32_t port_id,
const SpaPortStatus **status)
{
- SpaXvSink *this = (SpaXvSink *) handle;
+ SpaXvSink *this;
- if (handle == NULL || status == NULL)
+ if (node == NULL || node->handle == NULL || status == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) node->handle;
+
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
@@ -436,7 +456,7 @@ spa_xv_sink_node_port_get_status (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_port_use_buffers (SpaHandle *handle,
+spa_xv_sink_node_port_use_buffers (SpaNode *node,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@@ -445,7 +465,7 @@ spa_xv_sink_node_port_use_buffers (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_port_alloc_buffers (SpaHandle *handle,
+spa_xv_sink_node_port_alloc_buffers (SpaNode *node,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@@ -456,63 +476,31 @@ spa_xv_sink_node_port_alloc_buffers (SpaHandle *handle,
}
static SpaResult
-spa_xv_sink_node_port_push_input (SpaHandle *handle,
+spa_xv_sink_node_port_push_input (SpaNode *node,
unsigned int n_info,
SpaInputInfo *info)
{
- return SPA_RESULT_INVALID_PORT;
+ return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
-spa_xv_sink_node_port_pull_output (SpaHandle *handle,
+spa_xv_sink_node_port_pull_output (SpaNode *node,
unsigned int n_info,
SpaOutputInfo *info)
{
- SpaXvSink *this = (SpaXvSink *) handle;
- SpaXvState *state;
- unsigned int i;
- bool have_error = false;
-
- if (handle == NULL || n_info == 0 || info == NULL)
- return SPA_RESULT_INVALID_ARGUMENTS;
-
- state = &this->state;
-
- for (i = 0; i < n_info; i++) {
- XvBuffer *b;
-
- if (info[i].port_id != 0) {
- info[i].status = SPA_RESULT_INVALID_PORT;
- have_error = true;
- continue;
- }
- if (this->current_format == NULL) {
- info[i].status = SPA_RESULT_NO_FORMAT;
- have_error = true;
- continue;
- }
- if (state->ready_count == 0) {
- info[i].status = SPA_RESULT_UNEXPECTED;
- have_error = true;
- continue;
- }
-
- b = state->ready;
- state->ready = b->next;
- state->ready_count--;
-
- b->outstanding = true;
-
- info[i].buffer = &b->buffer;
- info[i].status = SPA_RESULT_OK;
- }
- if (have_error)
- return SPA_RESULT_ERROR;
+ return SPA_RESULT_INVALID_PORT;
+}
- return SPA_RESULT_OK;
+static SpaResult
+spa_xv_sink_node_port_push_event (SpaNode *node,
+ uint32_t port_id,
+ SpaEvent *event)
+{
+ return SPA_RESULT_NOT_IMPLEMENTED;
}
static const SpaNode xvsink_node = {
+ NULL,
sizeof (SpaNode),
spa_xv_sink_node_get_props,
spa_xv_sink_node_set_props,
@@ -533,19 +521,24 @@ static const SpaNode xvsink_node = {
spa_xv_sink_node_port_get_status,
spa_xv_sink_node_port_push_input,
spa_xv_sink_node_port_pull_output,
+ spa_xv_sink_node_port_push_event,
};
static SpaResult
spa_xv_sink_get_interface (SpaHandle *handle,
uint32_t interface_id,
- const void **interface)
+ void **interface)
{
+ SpaXvSink *this;
+
if (handle == NULL || interface == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
+ this = (SpaXvSink *) handle;
+
switch (interface_id) {
case SPA_INTERFACE_ID_NODE:
- *interface = &xvsink_node;
+ *interface = &this->node;
break;
default:
return SPA_RESULT_UNKNOWN_INTERFACE;
@@ -565,6 +558,8 @@ xv_sink_init (const SpaHandleFactory *factory,
handle->get_interface = spa_xv_sink_get_interface;
this = (SpaXvSink *) handle;
+ this->node = xvsink_node;
+ this->node.handle = handle;
this->props[1].props.n_prop_info = PROP_ID_LAST;
this->props[1].props.prop_info = prop_info;
this->props[1].props.set_prop = spa_props_generic_set_prop;
diff --git a/spa/tests/test-mixer.c b/spa/tests/test-mixer.c
index db1ab611..2bf34b3d 100644
--- a/spa/tests/test-mixer.c
+++ b/spa/tests/test-mixer.c
@@ -30,15 +30,11 @@
#include <spa/audio/format.h>
typedef struct {
- SpaHandle *sink;
- const SpaNode *sink_node;
- SpaHandle *mix;
- const SpaNode *mix_node;
+ SpaNode *sink;
+ SpaNode *mix;
uint32_t mix_ports[2];
- SpaHandle *source1;
- const SpaNode *source1_node;
- SpaHandle *source2;
- const SpaNode *source2_node;
+ SpaNode *source1;
+ SpaNode *source2;
bool running;
pthread_t thread;
SpaPollFd fds[16];
@@ -47,8 +43,9 @@ typedef struct {
} AppData;
static SpaResult
-make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char *name)
+make_node (SpaNode **node, const char *lib, const char *name)
{
+ SpaHandle *handle;
SpaResult res;
void *hnd;
SpaEnumHandleFactoryFunc enum_func;
@@ -66,7 +63,7 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
for (i = 0; ;i++) {
const SpaHandleFactory *factory;
- const void *iface;
+ void *iface;
if ((res = enum_func (&factory, &state)) < 0) {
if (res != SPA_RESULT_ENUM_END)
@@ -76,12 +73,12 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
if (strcmp (factory->name, name))
continue;
- *handle = calloc (1, factory->size);
- if ((res = factory->init (factory, *handle)) < 0) {
+ handle = calloc (1, factory->size);
+ if ((res = factory->init (factory, handle)) < 0) {
printf ("can't make factory instance: %d\n", res);
return res;
}
- if ((res = (*handle)->get_interface (*handle, SPA_INTERFACE_ID_NODE, &iface)) < 0) {
+ if ((res = handle->get_interface (handle, SPA_INTERFACE_ID_NODE, &iface)) < 0) {
printf ("can't get interface %d\n", res);
return res;
}
@@ -92,39 +89,38 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
}
static void
-on_mix_event (SpaHandle *handle, SpaEvent *event, void *user_data)
+on_mix_event (SpaNode *node, SpaEvent *event, void *user_data)
{
AppData *data = user_data;
switch (event->type) {
case SPA_EVENT_TYPE_PULL_INPUT:
{
- SpaBuffer *buf;
SpaInputInfo iinfo;
SpaOutputInfo oinfo;
SpaResult res;
+ SpaEventPullInput *pi;
- buf = event->data;
+ pi = event->data;
oinfo.port_id = 0;
oinfo.flags = SPA_OUTPUT_FLAG_NONE;
- oinfo.buffer = buf;
- oinfo.event = NULL;
+ oinfo.size = pi->size;
+ oinfo.offset = pi->offset;
if (event->port_id == data->mix_ports[0]) {
- if ((res = data->source1_node->port_pull_output (data->source1, 1, &oinfo)) < 0)
+ if ((res = spa_node_port_pull_output (data->source1, 1, &oinfo)) < 0)
printf ("got error %d\n", res);
} else {
- if ((res = data->source2_node->port_pull_output (data->source2, 1, &oinfo)) < 0)
+ if ((res = spa_node_port_pull_output (data->source2, 1, &oinfo)) < 0)
printf ("got error %d\n", res);
}
iinfo.port_id = event->port_id;
iinfo.flags = SPA_INPUT_FLAG_NONE;
- iinfo.buffer = oinfo.buffer;
- iinfo.event = oinfo.event;
+ iinfo.id = oinfo.id;
- if ((res = data->mix_node->port_push_input (data->mix, 1, &iinfo)) < 0)
+ if ((res = spa_node_port_push_input (data->mix, 1, &iinfo)) < 0)
printf ("got error from mixer %d\n", res);
break;
}
@@ -135,34 +131,33 @@ on_mix_event (SpaHandle *handle, SpaEvent *event, void *user_data)
}
static void
-on_sink_event (SpaHandle *handle, SpaEvent *event, void *user_data)
+on_sink_event (SpaNode *node, SpaEvent *event, void *user_data)
{
AppData *data = user_data;
switch (event->type) {
case SPA_EVENT_TYPE_PULL_INPUT:
{
- SpaBuffer *buf;
SpaInputInfo iinfo;
SpaOutputInfo oinfo;
SpaResult res;
+ SpaEventPullInput *pi;
- buf = event->data;
+ pi = event->data;
oinfo.port_id = 0;
oinfo.flags = SPA_OUTPUT_FLAG_PULL;
- oinfo.buffer = buf;
- oinfo.event = NULL;
+ oinfo.offset = pi->offset;
+ oinfo.size = pi->size;
- if ((res = data->mix_node->port_pull_output (data->mix, 1, &oinfo)) < 0)
+ if ((res = spa_node_port_pull_output (data->mix, 1, &oinfo)) < 0)
printf ("got error %d\n", res);
iinfo.port_id = event->port_id;
iinfo.flags = SPA_INPUT_FLAG_NONE;
- iinfo.buffer = oinfo.buffer;
- iinfo.event = oinfo.event;
+ iinfo.id = oinfo.id;
- if ((res = data->sink_node->port_push_input (data->sink, 1, &iinfo)) < 0)
+ if ((res = spa_node_port_push_input (data->sink, 1, &iinfo)) < 0)
printf ("got error %d\n", res);
break;
}
@@ -192,13 +187,13 @@ make_nodes (AppData *data)
SpaProps *props;
SpaPropValue value;
- if ((res = make_node (&data->sink, &data->sink_node, "plugins/alsa/libspa-alsa.so", "alsa-sink")) < 0) {
+ if ((res = make_node (&data->sink, "plugins/alsa/libspa-alsa.so", "alsa-sink")) < 0) {
printf ("can't create alsa-sink: %d\n", res);
return res;
}
- data->sink_node->set_event_callback (data->sink, on_sink_event, data);
+ spa_node_set_event_callback (data->sink, on_sink_event, data);
- if ((res = data->sink_node->get_props (data->sink, &props)) < 0)
+ if ((res = spa_node_get_props (data->sink, &props)) < 0)
printf ("got get_props error %d\n", res);
value.type = SPA_PROP_TYPE_STRING;
@@ -206,21 +201,21 @@ make_nodes (AppData *data)
value.size = strlen (value.value)+1;
props->set_prop (props, spa_props_index_for_name (props, "device"), &value);
- if ((res = data->sink_node->set_props (data->sink, props)) < 0)
+ if ((res = spa_node_set_props (data->sink, props)) < 0)
printf ("got set_props error %d\n", res);
- if ((res = make_node (&data->mix, &data->mix_node, "plugins/audiomixer/libspa-audiomixer.so", "audiomixer")) < 0) {
+ if ((res = make_node (&data->mix, "plugins/audiomixer/libspa-audiomixer.so", "audiomixer")) < 0) {
printf ("can't create audiomixer: %d\n", res);
return res;
}
- data->mix_node->set_event_callback (data->mix, on_mix_event, data);
+ spa_node_set_event_callback (data->mix, on_mix_event, data);
- if ((res = make_node (&data->source1, &data->source1_node, "plugins/audiotestsrc/libspa-audiotestsrc.so", "audiotestsrc")) < 0) {
+ if ((res = make_node (&data->source1, "plugins/audiotestsrc/libspa-audiotestsrc.so", "audiotestsrc")) < 0) {
printf ("can't create audiotestsrc: %d\n", res);
return res;
}
- if ((res = make_node (&data->source2, &data->source2_node, "plugins/audiotestsrc/libspa-audiotestsrc.so", "audiotestsrc")) < 0) {
+ if ((res = make_node (&data->source2, "plugins/audiotestsrc/libspa-audiotestsrc.so", "audiotestsrc")) < 0) {
printf ("can't create audiotestsrc: %d\n", res);
return res;
}
@@ -237,7 +232,7 @@ negotiate_formats (AppData *data)
SpaPropValue value;
void *state = NULL;
- if ((res = data->sink_node->port_enum_formats (data->sink, 0, &format, NULL, &state)) < 0)
+ if ((res = spa_node_port_enum_formats (data->sink, 0, &format, NULL, &state)) < 0)
return res;
props = &format->props;
@@ -259,28 +254,30 @@ negotiate_formats (AppData *data)
if ((res = props->set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_CHANNELS), &value)) < 0)
return res;
- if ((res = data->sink_node->port_set_format (data->sink, 0, false, format)) < 0)
+ if ((res = spa_node_port_set_format (data->sink, 0, false, format)) < 0)
return res;
- if ((res = data->mix_node->port_set_format (data->mix, 0, false, format)) < 0)
+ if ((res = spa_node_port_set_format (data->mix, 0, false, format)) < 0)
return res;
- if ((res = data->mix_node->add_port (data->mix, SPA_DIRECTION_INPUT, &data->mix_ports[0])) < 0)
+ data->mix_ports[0] = 0;
+ if ((res = spa_node_add_port (data->mix, SPA_DIRECTION_INPUT, 0)) < 0)
return res;
- if ((res = data->mix_node->port_set_format (data->mix, data->mix_ports[0], false, format)) < 0)
+ if ((res = spa_node_port_set_format (data->mix, data->mix_ports[0], false, format)) < 0)
return res;
- if ((res = data->source1_node->port_set_format (data->source1, 0, false, format)) < 0)
+ if ((res = spa_node_port_set_format (data->source1, 0, false, format)) < 0)
return res;
- if ((res = data->mix_node->add_port (data->mix, SPA_DIRECTION_INPUT, &data->mix_ports[1])) < 0)
+ data->mix_ports[1] = 0;
+ if ((res = spa_node_add_port (data->mix, SPA_DIRECTION_INPUT, 1)) < 0)
return res;
- if ((res = data->mix_node->port_set_format (data->mix, data->mix_ports[1], false, format)) < 0)
+ if ((res = spa_node_port_set_format (data->mix, data->mix_ports[1], false, format)) < 0)
return res;
- if ((res = data->source2_node->port_set_format (data->source2, 0, false, format)) < 0)
+ if ((res = spa_node_port_set_format (data->source2, 0, false, format)) < 0)
return res;
@@ -327,7 +324,7 @@ run_async_sink (AppData *data)
int err;
cmd.type = SPA_COMMAND_START;
- if ((res = data->sink_node->send_command (data->sink, &cmd)) < 0)
+ if ((res = spa_node_send_command (data->sink, &cmd)) < 0)
printf ("got error %d\n", res);
data->running = true;
@@ -345,7 +342,7 @@ run_async_sink (AppData *data)
}
cmd.type = SPA_COMMAND_STOP;
- if ((res = data->sink_node->send_command (data->sink, &cmd)) < 0)
+ if ((res = spa_node_send_command (data->sink, &cmd)) < 0)
printf ("got error %d\n", res);
}
diff --git a/spa/tests/test-v4l2.c b/spa/tests/test-v4l2.c
index 66989dee..e8a5695a 100644
--- a/spa/tests/test-v4l2.c
+++ b/spa/tests/test-v4l2.c
@@ -32,7 +32,7 @@
#include <spa/debug.h>
#include <spa/video/format.h>
-#define USE_BUFFER
+#undef USE_BUFFER
#define MAX_BUFFERS 8
@@ -45,8 +45,7 @@ typedef struct {
} SDLBuffer;
typedef struct {
- SpaHandle *source;
- const SpaNode *source_node;
+ SpaNode *source;
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Texture *texture;
@@ -55,13 +54,16 @@ typedef struct {
SpaPollFd fds[16];
unsigned int n_fds;
SpaPollItem poll;
+
SpaBuffer *bp[MAX_BUFFERS];
SDLBuffer buffers[MAX_BUFFERS];
+ unsigned int n_buffers;
} AppData;
static SpaResult
-make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char *name)
+make_node (SpaNode **node, const char *lib, const char *name)
{
+ SpaHandle *handle;
SpaResult res;
void *hnd;
SpaEnumHandleFactoryFunc enum_func;
@@ -79,7 +81,7 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
for (i = 0; ;i++) {
const SpaHandleFactory *factory;
- const void *iface;
+ void *iface;
if ((res = enum_func (&factory, &state)) < 0) {
if (res != SPA_RESULT_ENUM_END)
@@ -89,12 +91,12 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
if (strcmp (factory->name, name))
continue;
- *handle = calloc (1, factory->size);
- if ((res = factory->init (factory, *handle)) < 0) {
+ handle = calloc (1, factory->size);
+ if ((res = factory->init (factory, handle)) < 0) {
printf ("can't make factory instance: %d\n", res);
return res;
}
- if ((res = (*handle)->get_interface (*handle, SPA_INTERFACE_ID_NODE, &iface)) < 0) {
+ if ((res = handle->get_interface (handle, SPA_INTERFACE_ID_NODE, &iface)) < 0) {
printf ("can't get interface %d\n", res);
return res;
}
@@ -103,10 +105,9 @@ make_node (SpaHandle **handle, const SpaNode **node, const char *lib, const char
}
return SPA_RESULT_ERROR;
}
-#define MIN(a,b) (a < b ? a : b)
static void
-on_source_event (SpaHandle *handle, SpaEvent *event, void *user_data)
+on_source_event (SpaNode *node, SpaEvent *event, void *user_data)
{
AppData *data = user_data;
@@ -121,10 +122,10 @@ on_source_event (SpaHandle *handle, SpaEvent *event, void *user_data)
int i;
uint8_t *src, *dst;
- if ((res = data->source_node->port_pull_output (data->source, 1, info)) < 0)
+ if ((res = spa_node_port_pull_output (data->source, 1, info)) < 0)
printf ("got pull error %d\n", res);
- b = info[0].buffer;
+ b = data->bp[info->id];
if (b->metas[1].type == SPA_META_TYPE_POINTER &&
strcmp (((SpaMetaPointer*)b->metas[1].data)->ptr_type, "SDL_Texture") == 0) {
@@ -156,7 +157,7 @@ on_source_event (SpaHandle *handle, SpaEvent *event, void *user_data)
for (i = 0; i < 240; i++) {
src = ((uint8_t*)sdata + i * sstride);
dst = ((uint8_t*)ddata + i * dstride);
- memcpy (dst, src, MIN (sstride, dstride));
+ memcpy (dst, src, SPA_MIN (sstride, dstride));
}
SDL_UnlockTexture(data->texture);
@@ -190,13 +191,13 @@ make_nodes (AppData *data, const char *device)
SpaProps *props;
SpaPropValue value;
- if ((res = make_node (&data->source, &data->source_node, "plugins/v4l2/libspa-v4l2.so", "v4l2-source")) < 0) {
+ if ((res = make_node (&data->source, "plugins/v4l2/libspa-v4l2.so", "v4l2-source")) < 0) {
printf ("can't create v4l2-source: %d\n", res);
return res;
}
- data->source_node->set_event_callback (data->source, on_source_event, data);
+ spa_node_set_event_callback (data->source, on_source_event, data);
- if ((res = data->source_node->get_props (data->source, &props)) < 0)
+ if ((res = spa_node_get_props (data->source, &props)) < 0)
printf ("got get_props error %d\n", res);
value.type = SPA_PROP_TYPE_STRING;
@@ -204,7 +205,7 @@ make_nodes (AppData *data, const char *device)
value.size = strlen (value.value)+1;
props->set_prop (props, spa_props_index_for_name (props, "device"), &value);
- if ((res = data->source_node->set_props (data->source, props)) < 0)
+ if ((res = spa_node_set_props (data->source, props)) < 0)
printf ("got set_props error %d\n", res);
return res;
}
@@ -238,6 +239,7 @@ alloc_buffers (AppData *data)
b->buffer.refcount = 1;
b->buffer.notify = NULL;
+ b->buffer.id = i;
b->buffer.size = stride * 240;
b->buffer.n_metas = 2;
b->buffer.metas = b->metas;
@@ -265,7 +267,9 @@ alloc_buffers (AppData *data)
b->datas[0].size = stride * 240;
b->datas[0].stride = stride;
}
- data->source_node->port_use_buffers (data->source, 0, data->bp, MAX_BUFFERS);
+ data->n_buffers = MAX_BUFFERS;
+
+ spa_node_port_use_buffers (data->source, 0, data->bp, MAX_BUFFERS);
}
#endif
@@ -287,7 +291,7 @@ negotiate_formats (AppData *data)
#if 0
void *state = NULL;
- if ((res = data->source_node->port_enum_formats (data->source, 0, &format, NULL, &state)) < 0)
+ if ((res = spa_node_port_enum_formats (data->source, 0, &format, NULL, &state)) < 0)
return res;
#else
f.fmt.media_type = SPA_MEDIA_TYPE_VIDEO;
@@ -315,10 +319,10 @@ negotiate_formats (AppData *data)
f.framerate.denom = 1;
#endif
- if ((res = data->source_node->port_set_format (data->source, 0, false, &f.fmt)) < 0)
+ if ((res = spa_node_port_set_format (data->source, 0, false, &f.fmt)) < 0)
return res;
- if ((res = data->source_node->port_get_info (data->source, 0, &info)) < 0)
+ if ((res = spa_node_port_get_info (data->source, 0, &info)) < 0)
return res;
spa_debug_port_info (info);
@@ -326,13 +330,23 @@ negotiate_formats (AppData *data)
#ifdef USE_BUFFER
alloc_buffers (data);
#else
- data->texture = SDL_CreateTexture (data->renderer,
- SDL_PIXELFORMAT_YUY2,
- SDL_TEXTUREACCESS_STREAMING,
- 320, 240);
- if (!data->texture) {
- printf ("can't create texture: %s\n", SDL_GetError ());
- return -1;
+ {
+ unsigned int n_buffers;
+
+ data->texture = SDL_CreateTexture (data->renderer,
+ SDL_PIXELFORMAT_YUY2,
+ SDL_TEXTUREACCESS_STREAMING,
+ 320, 240);
+ if (!data->texture) {
+ printf ("can't create texture: %s\n", SDL_GetError ());
+ return -1;
+ }
+ n_buffers = MAX_BUFFERS;
+ if ((res = spa_node_port_alloc_buffers (data->source, 0, NULL, 0, data->bp, &n_buffers)) < 0) {
+ printf ("can't allocate buffers: %s\n", SDL_GetError ());
+ return -1;
+ }
+ data->n_buffers = n_buffers;
}
#endif
@@ -379,7 +393,7 @@ run_async_source (AppData *data)
int err;
cmd.type = SPA_COMMAND_START;
- if ((res = data->source_node->send_command (data->source, &cmd)) < 0)
+ if ((res = spa_node_send_command (data->source, &cmd)) < 0)
printf ("got error %d\n", res);
data->running = true;
@@ -412,7 +426,7 @@ run_async_source (AppData *data)
}
cmd.type = SPA_COMMAND_STOP;
- if ((res = data->source_node->send_command (data->source, &cmd)) < 0)
+ if ((res = spa_node_send_command (data->source, &cmd)) < 0)
printf ("got error %d\n", res);
}
diff --git a/spa/tools/spa-inspect.c b/spa/tools/spa-inspect.c
index c8387992..f0290f2b 100644
--- a/spa/tools/spa-inspect.c
+++ b/spa/tools/spa-inspect.c
@@ -56,7 +56,8 @@ struct prop_type_name {
{ "uint32", "UInt32" },
{ "int64", "Int64" },
{ "uint64", "UInt64" },
- { "float", "Float" },
+ { "int", "Int" },
+ { "uint", "UInt" },
{ "double", "Double" },
{ "string", "String" },
{ "rectangle", "Rectangle" },
@@ -116,6 +117,12 @@ print_value (const SpaPropInfo *info, int size, const void *value)
case SPA_PROP_TYPE_UINT64:
printf ("%" PRIu64 "\n", *(uint64_t *)value);
break;
+ case SPA_PROP_TYPE_INT:
+ printf ("%d", *(int *)value);
+ break;
+ case SPA_PROP_TYPE_UINT:
+ printf ("%u", *(unsigned int *)value);
+ break;
case SPA_PROP_TYPE_FLOAT:
printf ("%f", *(float *)value);
break;
@@ -292,7 +299,7 @@ print_format (const SpaFormat *format)
}
static void
-inspect_node (const SpaNode *node, SpaHandle *handle)
+inspect_node (SpaNode *node)
{
SpaResult res;
SpaProps *props;
@@ -300,18 +307,18 @@ inspect_node (const SpaNode *node, SpaHandle *handle)
SpaFormat *format;
void *state = NULL;
- if ((res = node->get_props (handle, &props)) < 0)
+ if ((res = node->get_props (node, &props)) < 0)
printf ("can't get properties: %d\n", res);
else
print_props (props, 1);
- if ((res = node->get_n_ports (handle, &n_input, &max_input, &n_output, &max_output)) < 0)
+ if ((res = node->get_n_ports (node, &n_input, &max_input, &n_output, &max_output)) < 0)
printf ("can't get n_ports: %d\n", res);
else
printf ("supported ports %d %d %d %d\n", n_input, max_input, n_output, max_output);
while (true) {
- if ((res = node->port_enum_formats (handle, 0, &format, NULL, &state)) < 0) {
+ if ((res = node->port_enum_formats (node, 0, &format, NULL, &state)) < 0) {
if (res != SPA_RESULT_ENUM_END)
printf ("got error %d\n", res);
break;
@@ -319,7 +326,7 @@ inspect_node (const SpaNode *node, SpaHandle *handle)
if (format)
print_format (format);
}
- if ((res = node->port_get_props (handle, 0, &props)) < 0)
+ if ((res = node->port_get_props (node, 0, &props)) < 0)
printf ("port_get_props error: %d\n", res);
else
print_props (props, 1);
@@ -330,7 +337,7 @@ inspect_factory (const SpaHandleFactory *factory)
{
SpaResult res;
SpaHandle *handle;
- const void *interface;
+ void *interface;
void *state = NULL;
printf ("factory name:\t\t'%s'\n", factory->name);
@@ -366,7 +373,7 @@ inspect_factory (const SpaHandleFactory *factory)
switch (info->interface_id) {
case SPA_INTERFACE_ID_NODE:
- inspect_node (interface, handle);
+ inspect_node (interface);
break;
default:
printf ("skipping unknown interface\n");