improve error reporting

Move signals from core to the objects themselves
Use per object info to track object signals
Use periods in alsasink and source
This commit is contained in:
Wim Taymans 2017-01-17 10:27:58 +01:00
parent fb69758251
commit cae971e106
23 changed files with 573 additions and 384 deletions

View file

@ -335,8 +335,8 @@ static void *
connection_ensure_size (PinosConnection *conn, ConnectionBuffer *buf, size_t size)
{
if (buf->buffer_size + size > buf->buffer_maxsize) {
buf->buffer_maxsize = buf->buffer_size + MAX_BUFFER_SIZE * ((size + MAX_BUFFER_SIZE-1) / MAX_BUFFER_SIZE);
pinos_log_warn ("connection %p: resize buffer to %zd", conn, buf->buffer_maxsize);
buf->buffer_maxsize = SPA_ROUND_UP_N (buf->buffer_size + size, MAX_BUFFER_SIZE);
pinos_log_warn ("connection %p: resize buffer to %zd %zd %zd", conn, buf->buffer_size, size, buf->buffer_maxsize);
buf->buffer_data = realloc (buf->buffer_data, buf->buffer_maxsize);
}
return (uint8_t *) buf->buffer_data + buf->buffer_size;
@ -404,6 +404,7 @@ connection_add_error (PinosConnection *conn,
memcpy (p, m, sizeof (PinosMessageError));
d = p;
p = SPA_MEMBER (d, sizeof (PinosMessageError), void);
if (m->error) {
strcpy (p, m->error);
d->error = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
@ -1284,6 +1285,7 @@ pinos_connection_parse_message (PinosConnection *conn,
}
case PINOS_MESSAGE_INVALID:
pinos_log_error ("invalid message %d received", conn->in.type);
return false;
}
return true;

View file

@ -73,9 +73,6 @@ context_set_state (PinosContext *context,
...)
{
if (context->state != state) {
pinos_log_debug ("context %p: update state from %s -> %s", context,
pinos_context_state_as_string (context->state),
pinos_context_state_as_string (state));
if (context->error)
free (context->error);
@ -89,6 +86,10 @@ context_set_state (PinosContext *context,
} else {
context->error = NULL;
}
pinos_log_debug ("context %p: update state from %s -> %s (%s)", context,
pinos_context_state_as_string (context->state),
pinos_context_state_as_string (state),
context->error);
context->state = state;
pinos_signal_emit (&context->state_changed, context);
@ -563,7 +564,7 @@ pinos_context_destroy (PinosContext *context)
* Returns: %TRUE on success.
*/
bool
pinos_context_connect (PinosContext *context)
pinos_context_connect (PinosContext *context)
{
PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this);
struct sockaddr_un addr;

View file

@ -865,6 +865,8 @@ pinos_stream_connect (PinosStream *stream,
impl->node_proxy = pinos_proxy_new (stream->context,
SPA_ID_INVALID,
stream->context->uri.client_node);
if (impl->node_proxy == NULL)
return false;
pinos_proxy_set_dispatch (impl->node_proxy,
stream_dispatch_func,

View file

@ -571,6 +571,9 @@ gst_pinos_src_stream_start (GstPinosSrc *pinossrc)
if (state == PINOS_STREAM_STATE_ERROR)
goto start_error;
if (pinossrc->ctx->state == PINOS_CONTEXT_STATE_ERROR)
goto start_error;
pinos_thread_main_loop_wait (pinossrc->main_loop);
}
@ -604,9 +607,13 @@ wait_negotiated (GstPinosSrc *this)
GST_DEBUG_OBJECT (this, "waiting for started signal, state now %s",
pinos_stream_state_as_string (state));
if (state == PINOS_STREAM_STATE_ERROR)
break;
if (this->ctx->state == PINOS_CONTEXT_STATE_ERROR)
break;
if (this->started)
break;
@ -698,6 +705,9 @@ gst_pinos_src_negotiate (GstBaseSrc * basesrc)
if (state == PINOS_STREAM_STATE_ERROR)
goto connect_error;
if (pinossrc->ctx->state == PINOS_CONTEXT_STATE_ERROR)
goto connect_error;
pinos_thread_main_loop_wait (pinossrc->main_loop);
}
pinos_thread_main_loop_unlock (pinossrc->main_loop);

View file

@ -25,6 +25,7 @@
#include "pinos/server/core.h"
#include "pinos/server/module.h"
#include "pinos/server/client-node.h"
typedef struct {
PinosCore *core;
@ -32,15 +33,142 @@ typedef struct {
PinosListener global_added;
PinosListener global_removed;
PinosListener port_added;
PinosListener port_removed;
PinosListener port_unlinked;
PinosListener link_state_changed;
SpaList node_list;
SpaList client_list;
} ModuleImpl;
static void
try_link_port (PinosNode *node, PinosPort *port, ModuleImpl *impl)
typedef struct {
ModuleImpl *impl;
PinosClient *client;
SpaList link;
PinosListener resource_added;
PinosListener resource_removed;
} ClientInfo;
typedef struct {
ModuleImpl *impl;
ClientInfo *info;
PinosNode *node;
PinosResource *resource;
SpaList link;
PinosListener state_changed;
PinosListener port_added;
PinosListener port_removed;
PinosListener port_unlinked;
PinosListener link_state_changed;
} NodeInfo;
static NodeInfo *
find_node_info (ModuleImpl *impl, PinosNode *node)
{
NodeInfo *info;
spa_list_for_each (info, &impl->node_list, link) {
if (info->node == node)
return info;
}
return NULL;
}
static ClientInfo *
find_client_info (ModuleImpl *impl, PinosClient *client)
{
ClientInfo *info;
spa_list_for_each (info, &impl->client_list, link) {
if (info->client == client)
return info;
}
return NULL;
}
static void
node_info_free (NodeInfo *info)
{
spa_list_remove (&info->link);
pinos_signal_remove (&info->state_changed);
pinos_signal_remove (&info->port_added);
pinos_signal_remove (&info->port_removed);
pinos_signal_remove (&info->port_unlinked);
pinos_signal_remove (&info->link_state_changed);
free (info);
}
static void
client_info_free (ClientInfo *cinfo)
{
spa_list_remove (&cinfo->link);
pinos_signal_remove (&cinfo->resource_added);
pinos_signal_remove (&cinfo->resource_removed);
free (cinfo);
}
static void try_link_port (PinosNode *node, PinosPort *port, NodeInfo *info);
static void
on_link_port_unlinked (PinosListener *listener,
PinosLink *link,
PinosPort *port)
{
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, port_unlinked);
ModuleImpl *impl = info->impl;
pinos_log_debug ("module %p: link %p: port %p unlinked", impl, link, port);
if (port->direction == PINOS_DIRECTION_OUTPUT && link->input)
try_link_port (link->input->node, link->input, info);
}
static void
on_link_state_changed (PinosListener *listener,
PinosLink *link,
PinosLinkState old,
PinosLinkState state)
{
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, link_state_changed);
ModuleImpl *impl = info->impl;
switch (state) {
case PINOS_LINK_STATE_ERROR:
{
PinosResource *resource;
pinos_log_debug ("module %p: link %p: state error: %s", impl, link, link->error);
spa_list_for_each (resource, &link->resource_list, link) {
pinos_client_send_error (resource->client,
resource,
SPA_RESULT_ERROR,
link->error);
}
if (info->info->client) {
pinos_client_send_error (info->info->client,
info->resource,
SPA_RESULT_ERROR,
link->error);
}
break;
}
case PINOS_LINK_STATE_UNLINKED:
pinos_log_debug ("module %p: link %p: unlinked", impl, link);
break;
case PINOS_LINK_STATE_INIT:
case PINOS_LINK_STATE_NEGOTIATING:
case PINOS_LINK_STATE_ALLOCATING:
case PINOS_LINK_STATE_PAUSED:
case PINOS_LINK_STATE_RUNNING:
break;
}
}
static void
try_link_port (PinosNode *node,
PinosPort *port,
NodeInfo *info)
{
ModuleImpl *impl = info->impl;
PinosProperties *props;
const char *path;
char *error = NULL;
@ -76,6 +204,9 @@ try_link_port (PinosNode *node, PinosPort *port, ModuleImpl *impl)
if (link == NULL)
goto error;
pinos_signal_add (&link->port_unlinked, &info->port_unlinked, on_link_port_unlinked);
pinos_signal_add (&link->state_changed, &info->link_state_changed, on_link_state_changed);
pinos_link_activate (link);
}
return;
@ -83,80 +214,25 @@ try_link_port (PinosNode *node, PinosPort *port, ModuleImpl *impl)
error:
{
pinos_log_error ("module %p: can't link node '%s'", impl, error);
if (info->info->client) {
pinos_client_send_error (info->info->client,
info->resource,
SPA_RESULT_ERROR,
error);
}
free (error);
return;
}
}
static void
on_link_port_unlinked (PinosListener *listener,
PinosLink *link,
PinosPort *port)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, port_unlinked);
pinos_log_debug ("module %p: link %p: port %p unlinked", impl, link, port);
if (port->direction == PINOS_DIRECTION_OUTPUT && link->input)
try_link_port (link->input->node, link->input, impl);
}
static void
on_link_state_changed (PinosListener *listener,
PinosLink *link)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, link_state_changed);
PinosLinkState state;
state = link->state;
switch (state) {
case PINOS_LINK_STATE_ERROR:
{
PinosResource *resource;
pinos_log_debug ("module %p: link %p: state error: %s", impl, link, link->error);
spa_list_for_each (resource, &link->resource_list, link) {
pinos_resource_send_error (resource,
SPA_RESULT_ERROR,
link->error);
}
#if 0
if (link->input && link->input->node)
pinos_node_update_state (link->input->node, PINOS_NODE_STATE_ERROR, strdup (link->error));
if (link->output && link->output->node)
pinos_node_update_state (link->output->node, PINOS_NODE_STATE_ERROR, strdup (link->error));
#endif
break;
}
case PINOS_LINK_STATE_UNLINKED:
pinos_log_debug ("module %p: link %p: unlinked", impl, link);
#if 0
if (link->input && link->input->node)
pinos_node_update_state (link->input->node, PINOS_NODE_STATE_ERROR, strdup ("node unlinked"));
if (link->output && link->output->node)
pinos_node_update_state (link->output->node, PINOS_NODE_STATE_ERROR, strdup ("node unlinked"));
#endif
break;
case PINOS_LINK_STATE_INIT:
case PINOS_LINK_STATE_NEGOTIATING:
case PINOS_LINK_STATE_ALLOCATING:
case PINOS_LINK_STATE_PAUSED:
case PINOS_LINK_STATE_RUNNING:
break;
}
}
static void
on_port_added (PinosListener *listener,
PinosNode *node,
PinosPort *port)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, port_added);
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, port_added);
try_link_port (node, port, impl);
try_link_port (node, port, info);
}
static void
@ -168,30 +244,87 @@ on_port_removed (PinosListener *listener,
static void
on_node_created (PinosNode *node,
ModuleImpl *impl)
NodeInfo *info)
{
PinosPort *port;
spa_list_for_each (port, &node->input_ports, link)
on_port_added (&impl->port_added, node, port);
on_port_added (&info->port_added, node, port);
spa_list_for_each (port, &node->output_ports, link)
on_port_added (&impl->port_added, node, port);
on_port_added (&info->port_added, node, port);
}
static void
on_node_added (ModuleImpl *impl, PinosNode *node)
on_state_changed (PinosListener *listener,
PinosNode *node,
PinosNodeState old,
PinosNodeState state)
{
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, state_changed);
if (old == PINOS_NODE_STATE_CREATING && state == PINOS_NODE_STATE_SUSPENDED)
on_node_created (node, info);
}
static void
on_node_added (ModuleImpl *impl,
PinosNode *node,
PinosResource *resource,
ClientInfo *cinfo)
{
NodeInfo *info;
info = calloc (1, sizeof (NodeInfo));
info->impl = impl;
info->node = node;
info->resource = resource;
info->info = cinfo;
spa_list_insert (impl->node_list.prev, &info->link);
spa_list_init (&info->port_unlinked.link);
spa_list_init (&info->link_state_changed.link);
pinos_signal_add (&node->port_added, &info->port_added, on_port_added);
pinos_signal_add (&node->port_removed, &info->port_removed, on_port_removed);
pinos_signal_add (&node->state_changed, &info->state_changed, on_state_changed);
pinos_log_debug ("module %p: node %p added", impl, node);
if (node->state > PINOS_NODE_STATE_CREATING)
on_node_created (node, impl);
on_node_created (node, info);
}
static void
on_node_removed (ModuleImpl *impl, PinosNode *node)
on_resource_added (PinosListener *listener,
PinosClient *client,
PinosResource *resource)
{
pinos_log_debug ("module %p: node %p removed", impl, node);
ClientInfo *cinfo = SPA_CONTAINER_OF (listener, ClientInfo, resource_added);
ModuleImpl *impl = cinfo->impl;
if (resource->type == impl->core->uri.client_node) {
PinosClientNode *cnode = resource->object;
on_node_added (impl, cnode->node, resource, cinfo);
}
}
static void
on_resource_removed (PinosListener *listener,
PinosClient *client,
PinosResource *resource)
{
ClientInfo *cinfo = SPA_CONTAINER_OF (listener, ClientInfo, resource_removed);
ModuleImpl *impl = cinfo->impl;
if (resource->type == impl->core->uri.client_node) {
PinosClientNode *cnode = resource->object;
NodeInfo *ninfo;
if ((ninfo = find_node_info (impl, cnode->node)))
node_info_free (ninfo);
pinos_log_debug ("module %p: node %p removed", impl, cnode->node);
}
}
static void
@ -201,9 +334,19 @@ on_global_added (PinosListener *listener,
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, global_added);
if (global->type == impl->core->uri.node) {
PinosNode *node = global->object;
on_node_added (impl, node);
if (global->type == impl->core->uri.client) {
PinosClient *client = global->object;
ClientInfo *cinfo;
cinfo = calloc (1, sizeof (ClientInfo));
cinfo->impl = impl;
cinfo->client = global->object;
spa_list_insert (impl->client_list.prev, &cinfo->link);
pinos_signal_add (&client->resource_added, &cinfo->resource_added, on_resource_added);
pinos_signal_add (&client->resource_removed, &cinfo->resource_removed, on_resource_removed);
pinos_log_debug ("module %p: client %p added", impl, cinfo->client);
}
}
@ -214,9 +357,14 @@ on_global_removed (PinosListener *listener,
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, global_removed);
if (global->type == impl->core->uri.node) {
PinosNode *node = global->object;
on_node_removed (impl, node);
if (global->type == impl->core->uri.client) {
PinosClient *client = global->object;
ClientInfo *cinfo;
if ((cinfo = find_client_info (impl, client)))
client_info_free (cinfo);
pinos_log_debug ("module %p: client %p removed", impl, client);
}
}
@ -241,12 +389,11 @@ module_new (PinosCore *core,
impl->core = core;
impl->properties = properties;
spa_list_init (&impl->node_list);
spa_list_init (&impl->client_list);
pinos_signal_add (&core->global_added, &impl->global_added, on_global_added);
pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed);
pinos_signal_add (&core->port_added, &impl->port_added, on_port_added);
pinos_signal_add (&core->port_removed, &impl->port_removed, on_port_removed);
pinos_signal_add (&core->port_unlinked, &impl->port_unlinked, on_link_port_unlinked);
pinos_signal_add (&core->link_state_changed, &impl->link_state_changed, on_link_state_changed);
return impl;
}

View file

@ -64,7 +64,6 @@ typedef struct {
PinosListener global_added;
PinosListener global_removed;
PinosListener node_state_changed;
} PinosProtocolDBus;
typedef struct {
@ -371,16 +370,13 @@ on_node_state_changed (PinosListener *listener,
PinosNodeState old,
PinosNodeState state)
{
PinosProtocolDBus *impl = SPA_CONTAINER_OF (listener, PinosProtocolDBus, node_state_changed);
PinosProtocolDBusObject *object;
PinosProtocolDBusNode *object = SPA_CONTAINER_OF (listener, PinosProtocolDBusNode, state_changed);
pinos_log_debug ("protocol-dbus %p: node %p state change %s -> %s", impl, node,
pinos_log_debug ("protocol-dbus %p: node %p state change %s -> %s", object->parent.impl, node,
pinos_node_state_as_string (old),
pinos_node_state_as_string (state));
if ((object = find_object (impl, node))) {
pinos_node1_set_state (object->iface, node->state);
}
pinos_node1_set_state (object->parent.iface, node->state);
}
static bool
@ -550,6 +546,7 @@ on_global_added (PinosListener *listener,
PinosNode *node = global->object;
PinosProperties *props = node->properties;
char *path;
PinosProtocolDBusNode *obj;
asprintf (&path, "%s_%u", PINOS_DBUS_OBJECT_NODE, global->id);
skel = pinos_object_skeleton_new (path);
@ -565,13 +562,14 @@ on_global_added (PinosListener *listener,
pinos_node1_set_properties (iface, props ? pinos_properties_to_variant (props) : NULL);
pinos_object_skeleton_set_node1 (skel, iface);
object_new (sizeof (PinosProtocolDBusNode),
impl,
global,
iface,
skel,
true,
NULL);
obj = object_new (sizeof (PinosProtocolDBusNode),
impl,
global,
iface,
skel,
true,
NULL);
pinos_signal_add (&node->state_changed, &obj->state_changed, on_node_state_changed);
}
else if (global->object == impl) {
PinosProtocolDBus *proto = global->object;
@ -681,7 +679,6 @@ pinos_protocol_dbus_new (PinosCore *core,
pinos_signal_add (&core->global_added, &impl->global_added, on_global_added);
pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed);
pinos_signal_add (&core->node_state_changed, &impl->node_state_changed, on_node_state_changed);
impl->server_manager = g_dbus_object_manager_server_new (PINOS_DBUS_OBJECT_PREFIX);

View file

@ -32,17 +32,17 @@ typedef struct {
PinosListener global_added;
PinosListener global_removed;
PinosListener node_state_request;
PinosListener node_state_changed;
SpaList node_list;
} ModuleImpl;
typedef struct {
ModuleImpl *impl;
PinosNode *node;
SpaList link;
SpaSource *idle_timeout;
ModuleImpl *impl;
PinosNode *node;
SpaList link;
PinosListener node_state_request;
PinosListener node_state_changed;
SpaSource *idle_timeout;
} NodeInfo;
static NodeInfo *
@ -66,6 +66,16 @@ remove_idle_timeout (NodeInfo *info)
}
}
static void
node_info_free (NodeInfo *info)
{
spa_list_remove (&info->link);
remove_idle_timeout (info);
pinos_signal_remove (&info->node_state_request);
pinos_signal_remove (&info->node_state_changed);
free (info);
}
static void
idle_timeout (SpaSource *source,
void *data)
@ -82,12 +92,7 @@ on_node_state_request (PinosListener *listener,
PinosNode *node,
PinosNodeState state)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, node_state_changed);
NodeInfo *info;
if ((info = find_node_info (impl, node)) == NULL)
return;
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, node_state_request);
remove_idle_timeout (info);
}
@ -97,11 +102,8 @@ on_node_state_changed (PinosListener *listener,
PinosNodeState old,
PinosNodeState state)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, node_state_changed);
NodeInfo *info;
if ((info = find_node_info (impl, node)) == NULL)
return;
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, node_state_changed);
ModuleImpl *impl = info->impl;
if (state != PINOS_NODE_STATE_IDLE) {
remove_idle_timeout (info);
@ -137,6 +139,10 @@ on_global_added (PinosListener *listener,
info->impl = impl;
info->node = node;
spa_list_insert (impl->node_list.prev, &info->link);
pinos_signal_add (&node->state_request, &info->node_state_request, on_node_state_request);
pinos_signal_add (&node->state_changed, &info->node_state_changed, on_node_state_changed);
pinos_log_debug ("module %p: node %p added", impl, node);
}
}
@ -151,11 +157,10 @@ on_global_removed (PinosListener *listener,
PinosNode *node = global->object;
NodeInfo *info;
if ((info = find_node_info (impl, node))) {
remove_idle_timeout (info);
spa_list_remove (&info->link);
free (info);
}
if ((info = find_node_info (impl, node)))
node_info_free (info);
pinos_log_debug ("module %p: node %p removed", impl, node);
}
}
@ -185,8 +190,6 @@ module_new (PinosCore *core,
pinos_signal_add (&core->global_added, &impl->global_added, on_global_added);
pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed);
pinos_signal_add (&core->node_state_request, &impl->node_state_request, on_node_state_request);
pinos_signal_add (&core->node_state_changed, &impl->node_state_changed, on_node_state_changed);
return impl;
}
@ -199,7 +202,6 @@ module_destroy (ModuleImpl *impl)
pinos_global_destroy (impl->global);
pinos_signal_remove (&impl->node_state_changed);
free (impl);
}
#endif

View file

@ -196,10 +196,11 @@ spa_proxy_node_send_command (SpaNode *node,
/* send start */
cnc.seq = this->seq++;
cnc.command = command;
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_NODE_COMMAND,
&cnc,
true);
pinos_client_send_message (this->resource->client,
this->resource,
PINOS_MESSAGE_NODE_COMMAND,
&cnc,
true);
if (command->type == SPA_NODE_COMMAND_START) {
uint8_t cmd = PINOS_TRANSPORT_CMD_NEED_DATA;
write (this->data_source.fd, &cmd, 1);
@ -214,10 +215,11 @@ spa_proxy_node_send_command (SpaNode *node,
/* send start */
cnc.command = command;
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_NODE_COMMAND,
&cnc,
true);
pinos_client_send_message (this->resource->client,
this->resource,
PINOS_MESSAGE_NODE_COMMAND,
&cnc,
true);
break;
}
}
@ -498,10 +500,11 @@ spa_proxy_node_port_set_format (SpaNode *node,
sf.port_id = port_id;
sf.flags = flags;
sf.format = (SpaFormat *) format;
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_SET_FORMAT,
&sf,
true);
pinos_client_send_message (this->resource->client,
this->resource,
PINOS_MESSAGE_SET_FORMAT,
&sf,
true);
return SPA_RESULT_RETURN_ASYNC (sf.seq);
}
@ -680,10 +683,11 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
am.flags = msh->flags;
am.offset = msh->offset;
am.size = msh->size;
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_ADD_MEM,
&am,
false);
pinos_client_send_message (this->resource->client,
this->resource,
PINOS_MESSAGE_ADD_MEM,
&am,
false);
mb[i].buffer = &b->buffer;
mb[i].mem_id = am.mem_id;
@ -710,10 +714,11 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
am.flags = d->flags;
am.offset = d->mapoffset;
am.size = d->maxsize;
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_ADD_MEM,
&am,
false);
pinos_client_send_message (this->resource->client,
this->resource,
PINOS_MESSAGE_ADD_MEM,
&am,
false);
b->buffer.datas[j].type = SPA_DATA_TYPE_ID;
b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem);
n_mem++;
@ -736,10 +741,11 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
ub.port_id = port_id;
ub.n_buffers = n_buffers;
ub.buffers = mb;
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_USE_BUFFERS,
&ub,
true);
pinos_client_send_message (this->resource->client,
this->resource,
PINOS_MESSAGE_USE_BUFFERS,
&ub,
true);
return SPA_RESULT_RETURN_ASYNC (ub.seq);
}
@ -772,10 +778,10 @@ spa_proxy_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
#if 0
static void
copy_meta_in (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
{
#if 0
ProxyBuffer *b = &port->buffers[buffer_id];
unsigned int i;
@ -791,13 +797,13 @@ copy_meta_in (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
memcpy (b->outbuf->datas[i].data, b->datas[i].data, b->buffer.datas[i].size);
}
}
#endif
}
#endif
#if 0
static void
copy_meta_out (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
{
#if 0
ProxyBuffer *b = &port->buffers[buffer_id];
unsigned int i;
@ -813,8 +819,8 @@ copy_meta_out (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
memcpy (b->datas[i].data, b->outbuf->datas[i].data, b->outbuf->datas[i].size);
}
}
#endif
}
#endif
static SpaResult
spa_proxy_node_port_reuse_buffer (SpaNode *node,
@ -840,6 +846,7 @@ spa_proxy_node_port_reuse_buffer (SpaNode *node,
rb.port_id = port_id;
rb.buffer_id = buffer_id;
pinos_transport_add_event (pnode->transport, &rb.event);
cmd = PINOS_TRANSPORT_CMD_HAVE_EVENT;
write (this->data_source.fd, &cmd, 1);
@ -1074,7 +1081,8 @@ proxy_on_data_fd_events (SpaSource *source)
if (source->rmask & SPA_IO_IN) {
uint8_t cmd;
read (this->data_source.fd, &cmd, 1);
if (read (this->data_source.fd, &cmd, 1) < 1)
return;
if (cmd & PINOS_TRANSPORT_CMD_HAVE_EVENT) {
SpaNodeEvent event;
@ -1086,17 +1094,6 @@ proxy_on_data_fd_events (SpaSource *source)
}
if (cmd & PINOS_TRANSPORT_CMD_HAVE_DATA) {
SpaNodeEventHaveOutput ho;
unsigned int i;
for (i = 0; i < this->n_outputs; i++) {
SpaProxyPort *port = &this->out_ports[i];
SpaPortOutput *output;
if ((output = port->io) == NULL)
continue;
copy_meta_in (this, port, output->buffer_id);
}
ho.event.type = SPA_NODE_EVENT_TYPE_HAVE_OUTPUT;
ho.event.size = sizeof (ho);
ho.port_id = 0;
@ -1191,10 +1188,11 @@ on_transport_changed (PinosListener *listener,
tu.memfd = info.memfd;
tu.offset = info.offset;
tu.size = info.size;
pinos_resource_send_message (this->resource,
PINOS_MESSAGE_TRANSPORT_UPDATE,
&tu,
true);
pinos_client_send_message (this->resource->client,
this->resource,
PINOS_MESSAGE_TRANSPORT_UPDATE,
&tu,
true);
}
static void
@ -1379,7 +1377,7 @@ pinos_client_node_get_data_socket (PinosClientNode *this,
if (impl->data_fd == -1) {
int fd[2];
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fd) != 0)
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, fd) != 0)
return SPA_RESULT_ERRNO;
impl->proxy.data_source.fd = fd[0];

View file

@ -88,14 +88,16 @@ client_bind_func (PinosGlobal *global,
info.change_mask = ~0;
info.props = this->properties ? &this->properties->dict : NULL;
return pinos_resource_send_message (resource,
PINOS_MESSAGE_CLIENT_INFO,
&m,
true);
return pinos_client_send_message (client,
resource,
PINOS_MESSAGE_CLIENT_INFO,
&m,
true);
no_mem:
pinos_resource_send_error (client->core_resource,
SPA_RESULT_NO_MEMORY,
"no memory");
pinos_client_send_error (client,
client->core_resource,
SPA_RESULT_NO_MEMORY,
"no memory");
return SPA_RESULT_NO_MEMORY;
}
@ -129,6 +131,8 @@ pinos_client_new (PinosCore *core,
this->properties = properties;
spa_list_init (&this->resource_list);
pinos_signal_init (&this->resource_added);
pinos_signal_init (&this->resource_removed);
pinos_map_init (&this->objects, 64);
pinos_signal_init (&this->destroy_signal);
@ -203,13 +207,15 @@ do_send_message (PinosAccessData *data)
if (data->res == SPA_RESULT_SKIPPED) {
data->res = SPA_RESULT_OK;
} else if (data->res == SPA_RESULT_NO_PERMISSION) {
pinos_resource_send_error (data->resource,
data->res,
"no permission");
pinos_client_send_error (data->client,
data->resource,
data->res,
"no permission");
} else if (SPA_RESULT_IS_ERROR (data->res)) {
pinos_resource_send_error (data->resource,
data->res,
"error %d", data->res);
pinos_client_send_error (data->client,
data->resource,
data->res,
"error %d", data->res);
} else {
data->res = impl->send_func (data->resource,
data->resource->id,
@ -255,6 +261,33 @@ pinos_client_send_message (PinosClient *client,
return SPA_RESULT_NOT_IMPLEMENTED;
}
SpaResult
pinos_client_send_error (PinosClient *client,
PinosResource *resource,
SpaResult res,
const char *message,
...)
{
PinosMessageError m;
char buffer[128];
va_list ap;
va_start (ap, message);
vsnprintf (buffer, sizeof (buffer), message, ap);
va_end (ap);
m.id = resource->id;
m.res = res;
m.error = buffer;
pinos_log_error ("client %p: %u send error %d (%s)", client, resource->id, res, buffer);
return pinos_client_send_message (client,
client->core_resource,
PINOS_MESSAGE_ERROR,
&m,
true);
}
void
pinos_client_update_properties (PinosClient *client,
@ -282,9 +315,10 @@ pinos_client_update_properties (PinosClient *client,
info.props = client->properties ? &client->properties->dict : NULL;
spa_list_for_each (resource, &client->resource_list, link) {
pinos_resource_send_message (resource,
PINOS_MESSAGE_CLIENT_INFO,
&m,
true);
pinos_client_send_message (client,
resource,
PINOS_MESSAGE_CLIENT_INFO,
&m,
true);
}
}

View file

@ -60,6 +60,12 @@ struct _PinosClient {
PinosMap objects;
SpaList resource_list;
PINOS_SIGNAL (resource_added, (PinosListener *listener,
PinosClient *client,
PinosResource *resource));
PINOS_SIGNAL (resource_removed, (PinosListener *listener,
PinosClient *client,
PinosResource *resource));
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosClient *client));
@ -80,6 +86,11 @@ SpaResult pinos_client_send_message (PinosClient *client,
void *message,
bool flush);
SpaResult pinos_client_send_error (PinosClient *client,
PinosResource *resource,
SpaResult res,
const char *message, ...);
void pinos_client_update_properties (PinosClient *client,
const SpaDict *dict);

View file

@ -57,9 +57,10 @@ registry_dispatch_func (void *object,
break;
if (&global->link == &this->global_list) {
pinos_resource_send_error (resource,
SPA_RESULT_INVALID_OBJECT_ID,
"unknown object id %u", m->id);
pinos_client_send_error (client,
resource,
SPA_RESULT_INVALID_OBJECT_ID,
"unknown object id %u", m->id);
return SPA_RESULT_ERROR;
}
pinos_log_debug ("global %p: bind object id %d", global, m->id);
@ -127,16 +128,18 @@ core_dispatch_func (void *object,
ng.id = global->id;
ng.type = spa_id_map_get_uri (this->uri.map, global->type);
pinos_resource_send_message (registry_resource,
PINOS_MESSAGE_NOTIFY_GLOBAL,
&ng,
false);
pinos_client_send_message (client,
registry_resource,
PINOS_MESSAGE_NOTIFY_GLOBAL,
&ng,
false);
}
nd.seq = m->seq;
pinos_resource_send_message (client->core_resource,
PINOS_MESSAGE_NOTIFY_DONE,
&nd,
true);
pinos_client_send_message (client,
client->core_resource,
PINOS_MESSAGE_NOTIFY_DONE,
&nd,
true);
break;
}
case PINOS_MESSAGE_CREATE_CLIENT_NODE:
@ -165,18 +168,20 @@ core_dispatch_func (void *object,
goto no_mem;
if ((res = pinos_client_node_get_data_socket (node, &data_fd)) < 0) {
pinos_resource_send_error (resource,
SPA_RESULT_ERROR,
"can't get data fd");
pinos_client_send_error (client,
resource,
SPA_RESULT_ERROR,
"can't get data fd");
break;
}
r.seq = m->seq;
r.datafd = data_fd;
pinos_resource_send_message (node->resource,
PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE,
&r,
true);
pinos_client_send_message (client,
node->resource,
PINOS_MESSAGE_CREATE_CLIENT_NODE_DONE,
&r,
true);
break;
}
default:
@ -186,9 +191,10 @@ core_dispatch_func (void *object,
return SPA_RESULT_OK;
no_mem:
pinos_resource_send_error (resource,
SPA_RESULT_NO_MEMORY,
"no memory");
pinos_client_send_error (client,
resource,
SPA_RESULT_NO_MEMORY,
"no memory");
return SPA_RESULT_NO_MEMORY;
}
@ -237,10 +243,11 @@ core_bind_func (PinosGlobal *global,
info.cookie = random ();
info.props = NULL;
return pinos_resource_send_message (resource,
PINOS_MESSAGE_CORE_INFO,
&m,
true);
return pinos_client_send_message (resource->client,
resource,
PINOS_MESSAGE_CORE_INFO,
&m,
true);
no_mem:
pinos_log_error ("can't create core resource");
return SPA_RESULT_NO_MEMORY;
@ -289,14 +296,6 @@ pinos_core_new (PinosMainLoop *main_loop)
pinos_signal_init (&this->destroy_signal);
pinos_signal_init (&this->global_added);
pinos_signal_init (&this->global_removed);
pinos_signal_init (&this->node_state_request);
pinos_signal_init (&this->node_state_changed);
pinos_signal_init (&this->port_added);
pinos_signal_init (&this->port_removed);
pinos_signal_init (&this->port_unlinked);
pinos_signal_init (&this->link_state_changed);
pinos_signal_init (&this->node_unlink);
pinos_signal_init (&this->node_unlink_done);
this->global = pinos_core_add_global (this,
NULL,
@ -367,10 +366,11 @@ pinos_core_add_global (PinosCore *core,
pinos_log_debug ("global %p: new %u %s", this, ng.id, ng.type);
spa_list_for_each (registry, &core->registry_resource_list, link) {
pinos_resource_send_message (registry,
PINOS_MESSAGE_NOTIFY_GLOBAL,
&ng,
true);
pinos_client_send_message (registry->client,
registry,
PINOS_MESSAGE_NOTIFY_GLOBAL,
&ng,
true);
}
return this;
}
@ -389,9 +389,10 @@ pinos_global_bind (PinosGlobal *global,
res = impl->bind (global, client, version, id);
} else {
res = SPA_RESULT_NOT_IMPLEMENTED;
pinos_resource_send_error (client->core_resource,
res,
"can't bind object id %d", id);
pinos_client_send_error (client,
client->core_resource,
res,
"can't bind object id %d", id);
}
return res;
}
@ -408,10 +409,11 @@ pinos_global_destroy (PinosGlobal *global)
ng.id = global->id;
spa_list_for_each (registry, &core->registry_resource_list, link) {
pinos_resource_send_message (registry,
PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE,
&ng,
true);
pinos_client_send_message (registry->client,
registry,
PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE,
&ng,
true);
}
pinos_map_remove (&core->objects, global->id);

View file

@ -91,30 +91,6 @@ struct _PinosCore {
PINOS_SIGNAL (global_removed, (PinosListener *listener,
PinosCore *core,
PinosGlobal *global));
PINOS_SIGNAL (node_state_request, (PinosListener *listener,
PinosNode *object,
PinosNodeState state));
PINOS_SIGNAL (node_state_changed, (PinosListener *listener,
PinosNode *object,
PinosNodeState old,
PinosNodeState state));
PINOS_SIGNAL (port_added, (PinosListener *listener,
PinosNode *node,
PinosPort *port));
PINOS_SIGNAL (port_removed, (PinosListener *listener,
PinosNode *node,
PinosPort *port));
PINOS_SIGNAL (port_unlinked, (PinosListener *listener,
PinosLink *link,
PinosPort *port));
PINOS_SIGNAL (link_state_changed, (PinosListener *listener,
PinosLink *link));
PINOS_SIGNAL (node_unlink, (PinosListener *listener,
PinosNode *node));
PINOS_SIGNAL (node_unlink_done, (PinosListener *listener,
PinosNode *node));
};
PinosCore * pinos_core_new (PinosMainLoop *main_loop);

View file

@ -56,9 +56,11 @@ pinos_link_update_state (PinosLink *link,
PinosLinkState state,
char *error)
{
if (state != link->state) {
PinosLinkState old = link->state;
if (state != old) {
pinos_log_debug ("link %p: update state %s -> %s", link,
pinos_link_state_as_string (link->state),
pinos_link_state_as_string (old),
pinos_link_state_as_string (state));
link->state = state;
@ -66,7 +68,7 @@ pinos_link_update_state (PinosLink *link,
free (link->error);
link->error = error;
pinos_signal_emit (&link->core->link_state_changed, link);
pinos_signal_emit (&link->state_changed, link, old, state);
}
}
@ -684,7 +686,7 @@ on_port_destroy (PinosLink *this,
pinos_port_clear_buffers (other);
}
pinos_signal_emit (&this->core->port_unlinked, this, port);
pinos_signal_emit (&this->port_unlinked, this, port);
pinos_link_update_state (this, PINOS_LINK_STATE_UNLINKED, NULL);
pinos_link_destroy (this);
@ -811,14 +813,16 @@ link_bind_func (PinosGlobal *global,
info.input_node_id = this->input ? this->input->node->global->id : -1;
info.input_port_id = this->input ? this->input->port_id : -1;
return pinos_resource_send_message (resource,
PINOS_MESSAGE_LINK_INFO,
&m,
true);
return pinos_client_send_message (resource->client,
resource,
PINOS_MESSAGE_LINK_INFO,
&m,
true);
no_mem:
pinos_resource_send_error (client->core_resource,
SPA_RESULT_NO_MEMORY,
"no memory");
pinos_client_send_error (client,
client->core_resource,
SPA_RESULT_NO_MEMORY,
"no memory");
return SPA_RESULT_NO_MEMORY;
}
@ -850,6 +854,8 @@ pinos_link_new (PinosCore *core,
this->output = output;
spa_list_init (&this->resource_list);
pinos_signal_init (&this->port_unlinked);
pinos_signal_init (&this->state_changed);
pinos_signal_init (&this->destroy_signal);
pinos_signal_init (&this->free_signal);

View file

@ -48,6 +48,10 @@ struct _PinosLink {
PinosLinkState state;
char *error;
PINOS_SIGNAL (state_changed, (PinosListener *listener,
PinosLink *link,
PinosLinkState old,
PinosLinkState state));
PINOS_SIGNAL (destroy_signal, (PinosListener *,
PinosLink *));
@ -60,6 +64,9 @@ struct _PinosLink {
SpaList output_link;
PinosPort *input;
SpaList input_link;
PINOS_SIGNAL (port_unlinked, (PinosListener *listener,
PinosLink *link,
PinosPort *port));
uint32_t queue[64];
SpaRingbuffer ringbuffer;

View file

@ -140,14 +140,16 @@ module_bind_func (PinosGlobal *global,
info.args = this->args;
info.props = NULL;
return pinos_resource_send_message (resource,
PINOS_MESSAGE_MODULE_INFO,
&m,
true);
return pinos_client_send_message (client,
resource,
PINOS_MESSAGE_MODULE_INFO,
&m,
true);
no_mem:
pinos_resource_send_error (resource,
SPA_RESULT_NO_MEMORY,
"no memory");
pinos_client_send_error (client,
client->core_resource,
SPA_RESULT_NO_MEMORY,
"no memory");
return SPA_RESULT_NO_MEMORY;
}

View file

@ -92,13 +92,13 @@ update_port_ids (PinosNode *node, bool create)
node->input_port_map[np->port_id] = np;
if (!impl->async_init)
pinos_signal_emit (&node->core->port_added, node, np);
pinos_signal_emit (&node->port_added, node, np);
i++;
} else if (p) {
node->input_port_map[p->port_id] = NULL;
ports = ports->next;
if (!impl->async_init)
pinos_signal_emit (&node->core->port_removed, node, p);
pinos_signal_emit (&node->port_removed, node, p);
pinos_log_debug ("node %p: input port removed %d", node, p->port_id);
pinos_port_destroy (p);
} else {
@ -127,13 +127,13 @@ update_port_ids (PinosNode *node, bool create)
node->output_port_map[np->port_id] = np;
if (!impl->async_init)
pinos_signal_emit (&node->core->port_added, node, np);
pinos_signal_emit (&node->port_added, node, np);
i++;
} else if (p) {
node->output_port_map[p->port_id] = NULL;
ports = ports->next;
if (!impl->async_init)
pinos_signal_emit (&node->core->port_removed, node, p);
pinos_signal_emit (&node->port_removed, node, p);
pinos_log_debug ("node %p: output port removed %d", node, p->port_id);
pinos_port_destroy (p);
} else {
@ -443,14 +443,16 @@ node_bind_func (PinosGlobal *global,
info.error = this->error;
info.props = this->properties ? &this->properties->dict : NULL;
return pinos_resource_send_message (resource,
PINOS_MESSAGE_NODE_INFO,
&m,
true);
return pinos_client_send_message (client,
resource,
PINOS_MESSAGE_NODE_INFO,
&m,
true);
no_mem:
pinos_resource_send_error (resource,
SPA_RESULT_NO_MEMORY,
"no memory");
pinos_client_send_error (client,
client->core_resource,
SPA_RESULT_NO_MEMORY,
"no memory");
return SPA_RESULT_NO_MEMORY;
}
@ -515,6 +517,10 @@ pinos_node_new (PinosCore *core,
pinos_log_warn ("node %p: error setting callback", this);
pinos_signal_init (&this->destroy_signal);
pinos_signal_init (&this->port_added);
pinos_signal_init (&this->port_removed);
pinos_signal_init (&this->state_request);
pinos_signal_init (&this->state_changed);
pinos_signal_init (&this->free_signal);
pinos_signal_init (&this->async_complete);
pinos_signal_init (&this->transport_changed);
@ -747,7 +753,7 @@ pinos_node_set_state (PinosNode *node,
SpaResult res = SPA_RESULT_OK;
PinosNodeImpl *impl = SPA_CONTAINER_OF (node, PinosNodeImpl, this);
pinos_signal_emit (&node->core->node_state_request, node, state);
pinos_signal_emit (&node->state_request, node, state);
pinos_log_debug ("node %p: set state %s", node, pinos_node_state_as_string (state));
@ -814,7 +820,7 @@ pinos_node_update_state (PinosNode *node,
node->error = error;
node->state = state;
pinos_signal_emit (&node->core->node_state_changed, node, old, state);
pinos_signal_emit (&node->state_changed, node, old, state);
spa_zero (info);
m.info = &info;
@ -824,10 +830,11 @@ pinos_node_update_state (PinosNode *node,
spa_list_for_each (resource, &node->resource_list, link) {
info.id = node->global->id;
pinos_resource_send_message (resource,
PINOS_MESSAGE_NODE_INFO,
&m,
true);
pinos_client_send_message (resource->client,
resource,
PINOS_MESSAGE_NODE_INFO,
&m,
true);
}
}
}

View file

@ -56,6 +56,13 @@ struct _PinosNode {
PinosProperties *properties;
PinosNodeState state;
char *error;
PINOS_SIGNAL (state_request, (PinosListener *listener,
PinosNode *object,
PinosNodeState state));
PINOS_SIGNAL (state_changed, (PinosListener *listener,
PinosNode *object,
PinosNodeState old,
PinosNodeState state));
SpaHandle *handle;
SpaNode *node;
@ -66,6 +73,12 @@ struct _PinosNode {
SpaList input_ports;
SpaList output_ports;
PINOS_SIGNAL (port_added, (PinosListener *listener,
PinosNode *node,
PinosPort *port));
PINOS_SIGNAL (port_removed, (PinosListener *listener,
PinosNode *node,
PinosPort *port));
PinosPort **input_port_map;
PinosPort **output_port_map;

View file

@ -46,7 +46,6 @@ pinos_resource_new (PinosClient *client,
this->core = client->core;
this->client = client;
this->id = id;
this->type = type;
this->object = object;
this->destroy = destroy;
@ -55,6 +54,7 @@ pinos_resource_new (PinosClient *client,
this->id = pinos_map_insert_new (&client->objects, this);
pinos_log_debug ("resource %p: new for client %p id %u", this, client, this->id);
pinos_signal_emit (&client->resource_added, client, this);
return this;
}
@ -62,19 +62,23 @@ pinos_resource_new (PinosClient *client,
void
pinos_resource_destroy (PinosResource *resource)
{
PinosClient *client = resource->client;
pinos_log_debug ("resource %p: destroy", resource);
pinos_signal_emit (&resource->destroy_signal, resource);
if (resource->client->core_resource) {
if (client->core_resource) {
PinosMessageRemoveId m;
m.id = resource->id;
pinos_resource_send_message (resource->client->core_resource,
PINOS_MESSAGE_REMOVE_ID,
&m,
true);
pinos_client_send_message (client,
client->core_resource,
PINOS_MESSAGE_REMOVE_ID,
&m,
true);
}
pinos_map_remove (&resource->client->objects, resource->id);
pinos_map_remove (&client->objects, resource->id);
pinos_signal_emit (&client->resource_removed, client, resource);
if (resource->destroy)
resource->destroy (resource);
@ -100,13 +104,15 @@ do_dispatch_message (PinosAccessData *data)
PinosResourceImpl *impl = SPA_CONTAINER_OF (data->resource, PinosResourceImpl, this);
if (data->res == SPA_RESULT_NO_PERMISSION) {
pinos_resource_send_error (data->resource,
data->res,
"no permission");
pinos_client_send_error (data->client,
data->resource,
data->res,
"no permission");
} else if (SPA_RESULT_IS_ERROR (data->res)) {
pinos_resource_send_error (data->resource,
data->res,
"error %d", data->res);
pinos_client_send_error (data->client,
data->resource,
data->res,
"error %d", data->res);
} else {
data->res = impl->dispatch_func (data->resource,
data->opcode,
@ -147,43 +153,3 @@ pinos_resource_dispatch (PinosResource *resource,
return SPA_RESULT_NOT_IMPLEMENTED;
}
SpaResult
pinos_resource_send_message (PinosResource *resource,
uint32_t opcode,
void *message,
bool flush)
{
return pinos_client_send_message (resource->client,
resource,
opcode,
message,
flush);
}
SpaResult
pinos_resource_send_error (PinosResource *resource,
SpaResult res,
const char *message,
...)
{
PinosClient *client = resource->client;
PinosMessageError m;
char buffer[128];
va_list ap;
va_start (ap, message);
vsnprintf (buffer, sizeof (buffer), message, ap);
va_end (ap);
m.id = resource->id;
m.res = res;
m.error = buffer;
pinos_log_error ("resource %p: %u send error %d %s", resource, resource->id, res, buffer);
return pinos_resource_send_message (client->core_resource,
PINOS_MESSAGE_ERROR,
&m,
true);
}

View file

@ -72,14 +72,6 @@ SpaResult pinos_resource_dispatch (PinosResource *resource,
uint32_t opcode,
void *message);
SpaResult pinos_resource_send_message (PinosResource *resource,
uint32_t opcode,
void *message,
bool flush);
SpaResult pinos_resource_send_error (PinosResource *resource,
SpaResult res,
const char *message, ...);
#ifdef __cplusplus
}
#endif

View file

@ -32,16 +32,16 @@
typedef struct _SpaALSAState SpaALSASink;
static const char default_device[] = "default";
static const uint32_t default_buffer_time = 4000;
static const uint32_t default_period_time = 100;
static const uint32_t default_period_size = 128;
static const uint32_t default_periods = 2;
static const bool default_period_event = 0;
static void
reset_alsa_sink_props (SpaALSAProps *props)
{
strncpy (props->device, default_device, 64);
props->buffer_time = default_buffer_time;
props->period_time = default_period_time;
props->period_size = default_period_size;
props->periods = default_periods;
props->period_event = default_period_event;
}
@ -64,8 +64,8 @@ enum {
PROP_ID_DEVICE,
PROP_ID_DEVICE_NAME,
PROP_ID_CARD_NAME,
PROP_ID_BUFFER_TIME,
PROP_ID_PERIOD_TIME,
PROP_ID_PERIOD_SIZE,
PROP_ID_PERIODS,
PROP_ID_PERIOD_EVENT,
PROP_ID_LAST,
};
@ -90,14 +90,14 @@ static const SpaPropInfo prop_info[] =
SPA_PROP_TYPE_STRING, 127,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL },
{ PROP_ID_BUFFER_TIME, offsetof (SpaALSAProps, buffer_time),
"buffer-time",
{ PROP_ID_PERIOD_SIZE, offsetof (SpaALSAProps, period_size),
"period-size",
SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
NULL },
{ PROP_ID_PERIOD_TIME, offsetof (SpaALSAProps, period_time),
"period-time",
{ PROP_ID_PERIODS, offsetof (SpaALSAProps, periods),
"periods",
SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,

View file

@ -39,16 +39,16 @@ update_state (SpaALSASource *this, SpaNodeState state)
}
static const char default_device[] = "hw:0";
static const uint32_t default_buffer_time = 10000;
static const uint32_t default_period_time = 1000;
static const uint32_t default_period_size = 128;
static const uint32_t default_periods = 2;
static const bool default_period_event = 0;
static void
reset_alsa_props (SpaALSAProps *props)
{
strncpy (props->device, default_device, 64);
props->buffer_time = default_buffer_time;
props->period_time = default_period_time;
props->period_size = default_period_size;
props->periods = default_periods;
props->period_event = default_period_event;
props->props.unset_mask = 0xf;
}
@ -65,8 +65,8 @@ enum {
PROP_ID_DEVICE,
PROP_ID_DEVICE_NAME,
PROP_ID_CARD_NAME,
PROP_ID_BUFFER_TIME,
PROP_ID_PERIOD_TIME,
PROP_ID_PERIOD_SIZE,
PROP_ID_PERIODS,
PROP_ID_PERIOD_EVENT,
PROP_ID_LAST,
};
@ -91,14 +91,14 @@ static const SpaPropInfo prop_info[] =
SPA_PROP_TYPE_STRING, 127,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL },
{ PROP_ID_BUFFER_TIME, offsetof (SpaALSAProps, buffer_time),
"buffer-time",
{ PROP_ID_PERIOD_SIZE, offsetof (SpaALSAProps, period_size),
"period-size",
SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
NULL },
{ PROP_ID_PERIOD_TIME, offsetof (SpaALSAProps, period_time),
"period-time",
{ PROP_ID_PERIODS, offsetof (SpaALSAProps, periods),
"periods",
SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,

View file

@ -111,14 +111,13 @@ int
spa_alsa_set_format (SpaALSAState *state, SpaFormatAudio *fmt, SpaPortFormatFlags flags)
{
unsigned int rrate, rchannels;
snd_pcm_uframes_t size;
snd_pcm_uframes_t period_size;
int err, dir;
snd_pcm_hw_params_t *params;
snd_pcm_format_t format;
SpaAudioInfoRaw *info = &fmt->info.raw;
snd_pcm_t *hndl;
unsigned int buffer_time;
unsigned int period_time;
unsigned int periods;
SpaALSAProps *props = &state->props[1];
if ((err = spa_alsa_open (state)) < 0)
@ -166,17 +165,31 @@ spa_alsa_set_format (SpaALSAState *state, SpaFormatAudio *fmt, SpaPortFormatFlag
state->rate = info->rate;
state->frame_size = info->channels * 2;
period_size = props->period_size;
CHECK (snd_pcm_hw_params_set_period_size_near (hndl, params, &period_size, &dir), "set_period_size");
state->period_frames = period_size;
periods = props->periods;
CHECK (snd_pcm_hw_params_set_periods_near (hndl, params, &periods, &dir), "set_periods_near");
state->buffer_frames = periods * state->period_frames;
CHECK (snd_pcm_hw_params_set_buffer_size (hndl, params, state->buffer_frames), "set_buffer_size");
#if 0
/* set the buffer time */
buffer_time = props->buffer_time;
CHECK (snd_pcm_hw_params_set_buffer_time_near (hndl, params, &buffer_time, &dir), "set_buffer_time_near");
CHECK (snd_pcm_hw_params_get_buffer_size (params, &size), "get_buffer_size");
state->buffer_frames = size;
/* set the period time */
period_time = props->period_time;
CHECK (snd_pcm_hw_params_set_period_time_near (hndl, params, &period_time, &dir), "set_period_time_near");
CHECK (snd_pcm_hw_params_get_period_size (params, &size, &dir), "get_period_size");
state->period_frames = size;
#endif
spa_log_info (state->log, "buffer frames %zd, period frames %zd", state->buffer_frames, state->period_frames);
@ -391,10 +404,12 @@ mmap_write (SpaALSAState *state)
}
#endif
#if 0
ni.event.type = SPA_NODE_EVENT_TYPE_NEED_INPUT;
ni.event.size = sizeof (ni);
ni.port_id = 0;
state->event_cb (&state->node, &ni.event, state->user_data);
#endif
size = avail;
while (size > 0) {
@ -536,7 +551,6 @@ alsa_on_fd_events (SpaSource *source)
if (revents & SPA_IO_ERR) {
if ((err = xrun_recovery (state, hndl, err)) < 0) {
spa_log_error (state->log, "error: %s", snd_strerror (err));
return;
}
}

View file

@ -44,8 +44,8 @@ typedef struct {
char device[64];
char device_name[128];
char card_name[128];
uint32_t buffer_time;
uint32_t period_time;
uint32_t period_size;
uint32_t periods;
bool period_event;
} SpaALSAProps;