Use int counters for iterating items

Use counters instead of void* to iterate items. This simplifies some
things and makes it easier to do over the wire.
Add format description to NodeInfo and use this to add format
descriptions to pinos devices.
Small fixes to fix leaks and crashes.
This commit is contained in:
Wim Taymans 2017-02-01 08:58:21 +01:00
parent 8b84d8fde6
commit b38ecafe81
38 changed files with 363 additions and 330 deletions

View file

@ -81,8 +81,8 @@ connection_add_fd (PinosConnection *conn,
return index;
}
#if 0
#define PINOS_DEBUG_MESSAGE(format,args...) pinos_log_debug(stderr, format,##args)
#if 1
#define PINOS_DEBUG_MESSAGE(format,args...) pinos_log_debug(format,##args)
#else
#define PINOS_DEBUG_MESSAGE(format,args...)
#endif
@ -200,6 +200,7 @@ connection_parse_node_info (PinosConnection *conn, PinosMessageNodeInfo *m)
{
void *p;
PinosNodeInfo *di;
int i;
p = conn->in.data;
memcpy (m, p, sizeof (PinosMessageNodeInfo));
@ -207,12 +208,32 @@ connection_parse_node_info (PinosConnection *conn, PinosMessageNodeInfo *m)
m->info = SPA_MEMBER (p, SPA_PTR_TO_INT (m->info), PinosNodeInfo);
di = m->info;
if (m->info->name)
m->info->name = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->name), const char);
if (m->info->error)
m->info->error = SPA_MEMBER (di, SPA_PTR_TO_INT (m->info->error), const char);
if (m->info->props)
m->info->props = pinos_serialize_dict_deserialize (di, SPA_PTR_TO_INT (m->info->props));
if (di->name)
di->name = SPA_MEMBER (di, SPA_PTR_TO_INT (di->name), const char);
if (di->input_formats)
di->input_formats = SPA_MEMBER (di,
SPA_PTR_TO_INT (di->input_formats), SpaFormat *);
for (i = 0; i < di->n_input_formats; i++) {
if (di->input_formats[i]) {
di->input_formats[i] = pinos_serialize_format_deserialize (di,
SPA_PTR_TO_INT (di->input_formats[i]));
}
}
if (di->output_formats)
di->output_formats = SPA_MEMBER (di,
SPA_PTR_TO_INT (di->output_formats), SpaFormat *);
for (i = 0; i < di->n_output_formats; i++) {
if (di->output_formats[i]) {
di->output_formats[i] = pinos_serialize_format_deserialize (di,
SPA_PTR_TO_INT (di->output_formats[i]));
}
}
if (di->error)
di->error = SPA_MEMBER (di, SPA_PTR_TO_INT (di->error), const char);
if (di->props)
di->props = pinos_serialize_dict_deserialize (di, SPA_PTR_TO_INT (di->props));
}
}
@ -359,7 +380,7 @@ connection_add_message (PinosConnection *conn,
buf->buffer_size += 8 + size;
*p++ = dest_id;
*p++ = (type << 16) | (size & 0xffff);
*p++ = (type << 24) | (size & 0xffffff);
return p;
}
@ -624,12 +645,19 @@ connection_add_node_info (PinosConnection *conn, uint32_t dest_id, PinosMessageN
size_t len, slen;
void *p;
PinosMessageNodeInfo *d;
int i;
/* calc len */
len = sizeof (PinosMessageNodeInfo);
if (m->info) {
len += sizeof (PinosNodeInfo);
len += m->info->name ? strlen (m->info->name) + 1 : 0;
len += m->info->n_input_formats * sizeof (SpaFormat *);
for (i = 0; i < m->info->n_input_formats; i++)
len += pinos_serialize_format_get_size (m->info->input_formats[i]);
len += m->info->n_output_formats * sizeof (SpaFormat *);
for (i = 0; i < m->info->n_output_formats; i++)
len += pinos_serialize_format_get_size (m->info->output_formats[i]);
len += m->info->error ? strlen (m->info->error) + 1 : 0;
len += pinos_serialize_dict_get_size (m->info->props);
}
@ -641,18 +669,43 @@ connection_add_node_info (PinosConnection *conn, uint32_t dest_id, PinosMessageN
p = SPA_MEMBER (d, sizeof (PinosMessageNodeInfo), void);
if (m->info) {
PinosNodeInfo *di;
SpaFormat **ifa, **ofa;
memcpy (p, m->info, sizeof (PinosNodeInfo));
d->info = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
di = p;
p = SPA_MEMBER (p, sizeof (PinosNodeInfo), void);
ifa = p;
if (m->info->n_input_formats)
di->input_formats = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
else
di->input_formats = 0;
p = SPA_MEMBER (p, sizeof (SpaFormat*) * m->info->n_input_formats, void);
ofa = p;
if (m->info->n_output_formats)
di->output_formats = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
else
di->output_formats = 0;
p = SPA_MEMBER (p, sizeof (SpaFormat*) * m->info->n_output_formats, void);
if (m->info->name) {
slen = strlen (m->info->name) + 1;
memcpy (p, m->info->name, slen);
di->name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += slen;
}
for (i = 0; i < m->info->n_input_formats; i++) {
len = pinos_serialize_format_serialize (p, m->info->input_formats[i]);
ifa[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p = SPA_MEMBER (p, len, void);
}
for (i = 0; i < m->info->n_output_formats; i++) {
len = pinos_serialize_format_serialize (p, m->info->output_formats[i]);
ofa[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p = SPA_MEMBER (p, len, void);
}
if (m->info->error) {
slen = strlen (m->info->error) + 1;
memcpy (p, m->info->error, slen);
@ -662,6 +715,7 @@ connection_add_node_info (PinosConnection *conn, uint32_t dest_id, PinosMessageN
if (m->info->props) {
len = pinos_serialize_dict_serialize (p, m->info->props);
di->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, di));
p += len;
}
}
}
@ -1084,8 +1138,8 @@ again:
size -= 8;
buf->dest_id = p[0];
buf->type = p[1] >> 16;
len = p[1] & 0xffff;
buf->type = p[1] >> 24;
len = p[1] & 0xffffff;
if (len > size) {
connection_ensure_size (conn, buf, len);
@ -1522,11 +1576,11 @@ pinos_connection_flush (PinosConnection *conn)
}
break;
}
PINOS_DEBUG_MESSAGE ("connection %p: %d written %zd bytes and %u fds", conn, conn->fd, len, buf->n_fds);
buf->buffer_size -= len;
buf->n_fds = 0;
PINOS_DEBUG_MESSAGE ("connection %p: %d written %zd bytes and %u fds", conn, conn->fd, len, buf->n_fds);
return true;
/* ERRORS */

View file

@ -492,6 +492,8 @@ pinos_context_new (PinosLoop *loop,
if (impl == NULL)
return NULL;
impl->fd = -1;
this = &impl->this;
pinos_log_debug ("context %p: new", impl);
@ -686,10 +688,21 @@ pinos_context_disconnect (PinosContext *context)
impl->disconnecting = true;
pinos_proxy_destroy (context->registry_proxy);
pinos_proxy_destroy (context->core_proxy);
pinos_connection_destroy (impl->connection);
close (impl->fd);
if (context->registry_proxy)
pinos_proxy_destroy (context->registry_proxy);
context->registry_proxy = NULL;
if (context->core_proxy)
pinos_proxy_destroy (context->core_proxy);
context->core_proxy = NULL;
if (impl->connection)
pinos_connection_destroy (impl->connection);
impl->connection = NULL;
if (impl->fd != -1)
close (impl->fd);
impl->fd = -1;
context_set_state (context, PINOS_CONTEXT_STATE_UNCONNECTED, NULL);

View file

@ -20,6 +20,7 @@
#include <string.h>
#include "pinos/client/pinos.h"
#include "pinos/client/serialize.h"
#include "pinos/client/context.h"
#include "pinos/client/subscribe.h"
@ -218,6 +219,8 @@ pinos_node_info_update (PinosNodeInfo *info,
const PinosNodeInfo *update)
{
uint64_t change_mask;
int i;
size_t size;
if (update == NULL)
return info;
@ -240,13 +243,38 @@ pinos_node_info_update (PinosNodeInfo *info,
}
if (update->change_mask & (1 << 1))
info->max_inputs = update->max_inputs;
if (update->change_mask & (1 << 2))
if (update->change_mask & (1 << 2)) {
for (i = 0; i < info->n_input_formats; i++)
free (info->input_formats[i]);
info->n_input_formats = update->n_input_formats;
if (info->n_input_formats)
info->input_formats = realloc (info->input_formats, info->n_input_formats * sizeof (SpaFormat *));
else {
free (info->input_formats);
info->input_formats = NULL;
}
for (i = 0; i < info->n_input_formats; i++) {
size = pinos_serialize_format_get_size (update->input_formats[i]);
info->input_formats[i] = size ? pinos_serialize_format_copy_into (malloc (size), update->input_formats[i]) : NULL;
}
}
if (update->change_mask & (1 << 3))
info->max_outputs = update->max_outputs;
if (update->change_mask & (1 << 4))
if (update->change_mask & (1 << 4)) {
for (i = 0; i < info->n_output_formats; i++)
free (info->output_formats[i]);
info->n_output_formats = update->n_output_formats;
if (info->n_output_formats)
info->output_formats = realloc (info->output_formats, info->n_output_formats * sizeof (SpaFormat *));
else {
free (info->output_formats);
info->output_formats = NULL;
}
for (i = 0; i < info->n_output_formats; i++) {
size = pinos_serialize_format_get_size (update->output_formats[i]);
info->output_formats[i] = size ? pinos_serialize_format_copy_into (malloc (size), update->output_formats[i]) : NULL;
}
}
if (update->change_mask & (1 << 5)) {
info->state = update->state;
@ -265,10 +293,22 @@ pinos_node_info_update (PinosNodeInfo *info,
void
pinos_node_info_free (PinosNodeInfo *info)
{
int i;
if (info == NULL)
return;
if (info->name)
free ((void*)info->name);
if (info->input_formats) {
for (i = 0; i < info->n_input_formats; i++)
free (info->input_formats[i]);
free (info->input_formats);
}
if (info->output_formats) {
for (i = 0; i < info->n_output_formats; i++)
free (info->output_formats[i]);
free (info->output_formats);
}
if (info->error)
free ((void*)info->error);
if (info->props)

View file

@ -119,6 +119,8 @@ pinos_thread_main_loop_destroy (PinosThreadMainLoop *loop)
pinos_signal_emit (&loop->destroy_signal, loop);
pinos_thread_main_loop_stop (loop);
if (loop->name)
free (loop->name);
pthread_mutex_destroy (&impl->lock);
@ -187,9 +189,11 @@ pinos_thread_main_loop_stop (PinosThreadMainLoop *loop)
{
PinosThreadMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosThreadMainLoopImpl, this);
pinos_loop_signal_event (loop->loop, impl->event);
pthread_join (impl->thread, NULL);
if (impl->running) {
pinos_loop_signal_event (loop->loop, impl->event);
pthread_join (impl->thread, NULL);
impl->running = false;
}
}
/**

View file

@ -28,6 +28,7 @@
#include <gst/gst.h>
#include "gstpinosformat.h"
#include "gstpinosdeviceprovider.h"
#include "gstpinossrc.h"
#include "gstpinossink.h"
@ -194,19 +195,29 @@ enum
static GstDevice *
new_node (const PinosNodeInfo *info)
{
GstCaps *caps;
GstCaps *caps = NULL;
GstStructure *props;
const gchar *klass = NULL;
SpaDictItem *item;
GstPinosDeviceType type;
int i;
/* FIXME, iterate ports */
#if 0
if (info->possible_formats)
caps = gst_caps_from_string (g_bytes_get_data (info->possible_formats, NULL));
else
caps = gst_caps_new_any();
#endif
caps = gst_caps_from_string ("video/x-raw,width=320,height=240,framerate=15/1");
caps = gst_caps_new_empty();
if (info->max_inputs > 0 && info->max_outputs == 0) {
type = GST_PINOS_DEVICE_TYPE_SINK;
for (i = 0; i < info->n_input_formats; i++) {
gst_caps_append (caps, gst_caps_from_format (info->input_formats[i]));
}
}
else if (info->max_outputs > 0 && info->max_inputs == 0) {
type = GST_PINOS_DEVICE_TYPE_SOURCE;
for (i = 0; i < info->n_output_formats; i++) {
gst_caps_append (caps, gst_caps_from_format (info->output_formats[i]));
}
} else {
type = GST_PINOS_DEVICE_TYPE_UNKNOWN;
}
props = gst_structure_new_empty ("pinos-proplist");
if (info->props) {
@ -222,7 +233,7 @@ new_node (const PinosNodeInfo *info)
info->name,
caps,
klass,
GST_PINOS_DEVICE_TYPE_SOURCE,
type,
props);
}
@ -500,7 +511,7 @@ failed_start:
failed_main_loop:
pinos_loop_destroy (self->loop);
self->loop = NULL;
return FALSE;
return TRUE;
}
static void

View file

@ -46,6 +46,7 @@ typedef struct _GstPinosDeviceClass GstPinosDeviceClass;
#define GST_PINOS_DEVICE_CAST(obj) ((GstPinosDevice *)(obj))
typedef enum {
GST_PINOS_DEVICE_TYPE_UNKNOWN,
GST_PINOS_DEVICE_TYPE_SOURCE,
GST_PINOS_DEVICE_TYPE_SINK,
} GstPinosDeviceType;

View file

@ -201,7 +201,8 @@ pinos_spa_monitor_load (PinosCore *core,
SpaHandle *handle;
SpaResult res;
void *iface;
void *hnd, *state = NULL;
void *hnd;
unsigned int index;
SpaEnumHandleFactoryFunc enum_func;
const SpaHandleFactory *factory;
@ -214,8 +215,8 @@ pinos_spa_monitor_load (PinosCore *core,
goto no_symbol;
}
while (true) {
if ((res = enum_func (&factory, &state)) < 0) {
for (index = 0;; index++) {
if ((res = enum_func (&factory, index)) < 0) {
if (res != SPA_RESULT_ENUM_END)
pinos_log_error ("can't enumerate factories: %d", res);
goto enum_failed;
@ -256,12 +257,11 @@ pinos_spa_monitor_load (PinosCore *core,
spa_list_init (&impl->item_list);
state = NULL;
while (true) {
for (index = 0;; index++) {
SpaMonitorItem *item;
SpaResult res;
if ((res = spa_monitor_enum_items (this->monitor, &item, &state)) < 0) {
if ((res = spa_monitor_enum_items (this->monitor, &item, index)) < 0) {
if (res != SPA_RESULT_ENUM_END)
pinos_log_debug ("spa_monitor_enum_items: got error %d\n", res);
break;

View file

@ -46,7 +46,8 @@ pinos_spa_node_load (PinosCore *core,
SpaClock *spa_clock;
SpaResult res;
SpaHandle *handle;
void *hnd, *state = NULL;
void *hnd;
unsigned int index;
SpaEnumHandleFactoryFunc enum_func;
const SpaHandleFactory *factory;
void *iface;
@ -60,8 +61,8 @@ pinos_spa_node_load (PinosCore *core,
goto no_symbol;
}
while (true) {
if ((res = enum_func (&factory, &state)) < 0) {
for (index = 0; ; index++) {
if ((res = enum_func (&factory, index)) < 0) {
if (res != SPA_RESULT_ENUM_END)
pinos_log_error ("can't enumerate factories: %d", res);
goto enum_failed;

View file

@ -472,13 +472,12 @@ spa_proxy_node_port_enum_formats (SpaNode *node,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
void **state)
unsigned int index)
{
SpaProxy *this;
SpaProxyPort *port;
int index;
if (node == NULL || format == NULL || state == NULL)
if (node == NULL || format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = SPA_CONTAINER_OF (node, SpaProxy, node);
@ -488,13 +487,10 @@ spa_proxy_node_port_enum_formats (SpaNode *node,
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
index = (*state == NULL ? 0 : *(int*)state);
if (index >= port->n_formats)
return SPA_RESULT_ENUM_END;
*format = port->formats[index];
*(int*)state = ++index;
return SPA_RESULT_OK;
}

View file

@ -78,7 +78,7 @@ do_negotiate (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
PinosLinkImpl *impl = SPA_CONTAINER_OF (this, PinosLinkImpl, this);
SpaResult res;
SpaFormat *filter = NULL, *format;
void *istate = NULL, *ostate = NULL;
unsigned int iidx = 0, oidx = 0;
char *error = NULL;
if (in_state != SPA_NODE_STATE_CONFIGURE && out_state != SPA_NODE_STATE_CONFIGURE)
@ -95,8 +95,8 @@ again:
this->input->port_id,
&filter,
NULL,
&istate)) < 0) {
if (res == SPA_RESULT_ENUM_END && istate != NULL) {
iidx)) < 0) {
if (res == SPA_RESULT_ENUM_END && iidx != 0) {
asprintf (&error, "error input enum formats: %d", res);
goto error;
}
@ -110,9 +110,10 @@ again:
this->output->port_id,
&format,
filter,
&ostate)) < 0) {
oidx)) < 0) {
if (res == SPA_RESULT_ENUM_END) {
ostate = NULL;
oidx = 0;
iidx++;
goto again;
}
asprintf (&error, "error output enum formats: %d", res);

View file

@ -22,6 +22,7 @@
#include <errno.h>
#include "pinos/client/pinos.h"
#include "pinos/client/serialize.h"
#include "pinos/server/node.h"
#include "pinos/server/data-loop.h"
@ -423,8 +424,44 @@ node_bind_func (PinosGlobal *global,
info.name = this->name;
info.max_inputs = this->transport->area->max_inputs;
info.n_inputs = this->transport->area->n_inputs;
info.input_formats = NULL;
for (info.n_input_formats = 0; ; info.n_input_formats++) {
SpaFormat *fmt;
void *p;
if (spa_node_port_enum_formats (this->node,
SPA_DIRECTION_INPUT,
0,
&fmt,
NULL,
info.n_input_formats) < 0)
break;
info.input_formats = realloc (info.input_formats, sizeof (SpaFormat*) * (info.n_input_formats + 1));
p = malloc (pinos_serialize_format_get_size (fmt));
info.input_formats[info.n_input_formats] = pinos_serialize_format_copy_into (p, fmt);
}
info.max_outputs = this->transport->area->max_outputs;
info.n_outputs = this->transport->area->n_outputs;
info.output_formats = NULL;
for (info.n_output_formats = 0; ; info.n_output_formats++) {
SpaFormat *fmt;
void *p;
if (spa_node_port_enum_formats (this->node,
SPA_DIRECTION_OUTPUT,
0,
&fmt,
NULL,
info.n_output_formats) < 0)
break;
info.output_formats = realloc (info.output_formats, sizeof (SpaFormat*) * (info.n_output_formats + 1));
p = malloc (pinos_serialize_format_get_size (fmt));
info.output_formats[info.n_output_formats] = pinos_serialize_format_copy_into (p, fmt);
}
info.state = this->state;
info.error = this->error;
info.props = this->properties ? &this->properties->dict : NULL;
@ -667,9 +704,9 @@ pinos_node_destroy (PinosNode * this)
* @node: a #PinosNode
* @direction: a #PinosDirection
*
* Find a new unused port id in @node with @direction
* Find a new unused port in @node with @direction
*
* Returns: the new port id or %SPA_ID_INVALID on error
* Returns: the new port or %NULL on error
*/
PinosPort *
pinos_node_get_free_port (PinosNode *node,
@ -698,12 +735,8 @@ pinos_node_get_free_port (PinosNode *node,
}
}
if (port == NULL) {
if (!spa_list_is_empty (ports))
port = spa_list_first (ports, PinosPort, link);
else
return NULL;
}
if (port == NULL && !spa_list_is_empty (ports))
port = spa_list_first (ports, PinosPort, link);
return port;
@ -812,7 +845,7 @@ pinos_node_update_state (PinosNode *node,
spa_zero (info);
m.info = &info;
info.change_mask = 1 << 1;
info.change_mask = 1 << 5;
info.state = node->state;
info.error = node->error;

View file

@ -110,15 +110,25 @@ dump_node_info (PinosContext *c,
printf ("\tid: %u\n", info->id);
printf ("\ttype: %s\n", PINOS_NODE_URI);
if (data->print_all) {
int i;
printf ("%c\tname: \"%s\"\n", MARK_CHANGE (0), info->name);
printf ("%c\tinputs: %u/%u\n", MARK_CHANGE (1), info->n_inputs, info->max_inputs);
printf ("%c\toutputs: %u/%u\n", MARK_CHANGE (2), info->n_outputs, info->max_outputs);
printf ("%c\tstate: \"%s\"", MARK_CHANGE (3), pinos_node_state_as_string (info->state));
printf ("%c\tinput formats:\n", MARK_CHANGE (2));
for (i = 0; i < info->n_input_formats; i++)
spa_debug_format (info->input_formats[i]);
printf ("%c\toutputs: %u/%u\n", MARK_CHANGE (3), info->n_outputs, info->max_outputs);
printf ("%c\toutput formats:\n", MARK_CHANGE (4));
for (i = 0; i < info->n_output_formats; i++)
spa_debug_format (info->output_formats[i]);
printf ("%c\tstate: \"%s\"", MARK_CHANGE (5), pinos_node_state_as_string (info->state));
if (info->state == PINOS_NODE_STATE_ERROR && info->error)
printf (" \"%s\"\n", info->error);
else
printf ("\n");
print_properties (info->props, MARK_CHANGE (4));
print_properties (info->props, MARK_CHANGE (6));
}
}