Remove unused events, drained and marker can be done with
ASYNC_COMPLETED messages
Handle result of idle callback to disable the poll item
Identify poll items with a unique id.
Remove set_state vfunc
push_event -> send_command, commands are to do something, events are the
result of something.
Add poll item in v4l2 as soon as we have the fd but disable the item
until streaming starts.
This commit is contained in:
Wim Taymans 2016-10-21 14:57:01 +02:00
parent 9b2b4b9b5c
commit 1bd751372e
21 changed files with 188 additions and 190 deletions

View file

@ -983,21 +983,21 @@ spa_proxy_node_port_reuse_buffer (SpaNode *node,
}
static SpaResult
spa_proxy_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
spa_proxy_node_port_send_command (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeCommand *command)
{
SpaProxy *this;
if (node == NULL || event == NULL)
if (node == NULL || command == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = SPA_CONTAINER_OF (node, SpaProxy, node);
switch (event->type) {
switch (command->type) {
default:
spa_log_warn (this->log, "unhandled event %d\n", event->type);
spa_log_warn (this->log, "unhandled command %d\n", command->type);
break;
}
return SPA_RESULT_NOT_IMPLEMENTED;
@ -1015,8 +1015,6 @@ handle_node_event (SpaProxy *this,
case SPA_NODE_EVENT_TYPE_HAVE_OUTPUT:
case SPA_NODE_EVENT_TYPE_NEED_INPUT:
case SPA_NODE_EVENT_TYPE_REUSE_BUFFER:
case SPA_NODE_EVENT_TYPE_DRAINED:
case SPA_NODE_EVENT_TYPE_MARKER:
case SPA_NODE_EVENT_TYPE_ERROR:
case SPA_NODE_EVENT_TYPE_BUFFERING:
case SPA_NODE_EVENT_TYPE_REQUEST_REFRESH:
@ -1237,7 +1235,7 @@ static const SpaNode proxy_node = {
spa_proxy_node_port_push_input,
spa_proxy_node_port_pull_output,
spa_proxy_node_port_reuse_buffer,
spa_proxy_node_port_push_event,
spa_proxy_node_port_send_command,
};
static SpaResult

View file

@ -41,6 +41,8 @@ struct _PinosDataLoopPrivate
SpaPollFd fds[32];
unsigned int n_fds;
uint32_t counter;
gboolean running;
pthread_t thread;
};
@ -78,7 +80,8 @@ loop (void *user_data)
ndata.fds = NULL;
ndata.n_fds = 0;
ndata.user_data = p->user_data;
p->idle_cb (&ndata);
if (p->idle_cb (&ndata) < 0)
p->enabled = false;
n_idle++;
}
}
@ -199,6 +202,7 @@ do_add_item (SpaPoll *poll,
gboolean in_thread = pthread_equal (priv->thread, pthread_self());
unsigned int i;
item->id = ++priv->counter;
g_debug ("data-loop %p: %d: add pollid %d, n_poll %d, n_fds %d", this, in_thread, item->id, priv->n_poll, item->n_fds);
priv->poll[priv->n_poll] = *item;
priv->n_poll++;
@ -210,8 +214,8 @@ do_add_item (SpaPoll *poll,
start_thread (this);
}
for (i = 0; i < priv->n_poll; i++) {
if (priv->poll[i].fds)
g_debug ("poll %d: %p %d", i, priv->poll[i].user_data, priv->poll[i].fds[0].fd);
if (priv->poll[i].n_fds > 0)
g_debug ("poll %d: %d %d", i, priv->poll[i].id, priv->poll[i].fds[0].fd);
}
return SPA_RESULT_OK;
}
@ -227,7 +231,7 @@ do_update_item (SpaPoll *poll,
unsigned int i;
for (i = 0; i < priv->n_poll; i++) {
if (priv->poll[i].id == item->id && priv->poll[i].user_data == item->user_data)
if (priv->poll[i].id == item->id)
priv->poll[i] = *item;
}
if (item->n_fds)
@ -248,9 +252,9 @@ do_remove_item (SpaPoll *poll,
gboolean in_thread = pthread_equal (priv->thread, pthread_self());
unsigned int i;
g_debug ("data-loop %p: remove poll %d %d", this, item->n_fds, priv->n_poll);
g_debug ("data-loop %p: %d: remove poll %d %d", this, item->id, item->n_fds, priv->n_poll);
for (i = 0; i < priv->n_poll; i++) {
if (priv->poll[i].id == item->id && priv->poll[i].user_data == item->user_data) {
if (priv->poll[i].id == item->id) {
priv->n_poll--;
for (; i < priv->n_poll; i++)
priv->poll[i] = priv->poll[i+1];
@ -266,8 +270,8 @@ do_remove_item (SpaPoll *poll,
stop_thread (this, in_thread);
}
for (i = 0; i < priv->n_poll; i++) {
if (priv->poll[i].fds)
g_debug ("poll %d: %p %d", i, priv->poll[i].user_data, priv->poll[i].fds[0].fd);
if (priv->poll[i].n_fds > 0)
g_debug ("poll %d: %d %d", i, priv->poll[i].id, priv->poll[i].fds[0].fd);
}
return SPA_RESULT_OK;
}

View file

@ -655,11 +655,10 @@ do_start (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
pinos_link_update_state (this, PINOS_LINK_STATE_PAUSED);
if (in_state == SPA_NODE_STATE_PAUSED) {
pinos_node_set_state (this->input->node, PINOS_NODE_STATE_RUNNING);
res = pinos_node_set_state (this->input->node, PINOS_NODE_STATE_RUNNING);
}
if (out_state == SPA_NODE_STATE_PAUSED) {
pinos_node_set_state (this->output->node, PINOS_NODE_STATE_RUNNING);
res = pinos_node_set_state (this->output->node, PINOS_NODE_STATE_RUNNING);
}
}
return res;

View file

@ -280,6 +280,7 @@ pinos_main_loop_defer_cancel (PinosMainLoop *loop,
for (walk = priv->work.head; walk; walk = g_list_next (walk)) {
WorkItem *i = walk->data;
if ((id == 0 || i->id == id) && (obj == NULL || i->obj == obj)) {
g_debug ("main-loop %p: cancel defer %d for object %p", loop, i->seq, i->obj);
i->seq = SPA_ID_INVALID;
i->func = NULL;
have_work = TRUE;

View file

@ -328,66 +328,6 @@ send_clock_update (PinosNode *this)
g_debug ("got error %d", res);
}
typedef struct {
PinosNode *node;
PinosNodeState state;
} StateData;
static void
on_state_complete (StateData *data)
{
pinos_node_update_state (data->node, data->state);
}
static gboolean
node_set_state (PinosNode *this,
PinosNodeState state)
{
PinosNodePrivate *priv = this->priv;
SpaResult res = SPA_RESULT_OK;
StateData data;
g_debug ("node %p: set state %s", this, pinos_node_state_as_string (state));
switch (state) {
case PINOS_NODE_STATE_CREATING:
return FALSE;
case PINOS_NODE_STATE_SUSPENDED:
res = suspend_node (this);
break;
case PINOS_NODE_STATE_INITIALIZING:
break;
case PINOS_NODE_STATE_IDLE:
res = pause_node (this);
break;
case PINOS_NODE_STATE_RUNNING:
send_clock_update (this);
res = start_node (this);
break;
case PINOS_NODE_STATE_ERROR:
break;
}
if (SPA_RESULT_IS_ERROR (res))
return FALSE;
data.node = this;
data.state = state;
pinos_main_loop_defer (priv->main_loop,
this,
res,
(PinosDeferFunc) on_state_complete,
g_memdup (&data, sizeof (StateData)),
g_free);
return TRUE;
}
static gboolean
do_read_link (PinosNode *this, PinosLink *link)
{
@ -427,8 +367,6 @@ on_node_event (SpaNode *node, SpaNodeEvent *event, void *user_data)
switch (event->type) {
case SPA_NODE_EVENT_TYPE_INVALID:
case SPA_NODE_EVENT_TYPE_DRAINED:
case SPA_NODE_EVENT_TYPE_MARKER:
case SPA_NODE_EVENT_TYPE_ERROR:
case SPA_NODE_EVENT_TYPE_BUFFERING:
case SPA_NODE_EVENT_TYPE_REQUEST_REFRESH:
@ -793,7 +731,6 @@ static void
pinos_node_class_init (PinosNodeClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
PinosNodeClass *node_class = PINOS_NODE_CLASS (klass);
g_type_class_add_private (klass, sizeof (PinosNodePrivate));
@ -930,8 +867,6 @@ pinos_node_class_init (PinosNodeClass * klass)
2,
G_TYPE_UINT,
G_TYPE_UINT);
node_class->set_state = node_set_state;
}
static void
@ -1287,6 +1222,17 @@ remove_idle_timeout (PinosNode *node)
}
}
typedef struct {
PinosNode *node;
PinosNodeState state;
} StateData;
static void
on_state_complete (StateData *data)
{
pinos_node_update_state (data->node, data->state);
}
/**
* pinos_node_set_state:
* @node: a #PinosNode
@ -1294,26 +1240,58 @@ remove_idle_timeout (PinosNode *node)
*
* Set the state of @node to @state.
*
* Returns: %TRUE on success.
* Returns: a #SpaResult
*/
gboolean
SpaResult
pinos_node_set_state (PinosNode *node,
PinosNodeState state)
{
PinosNodeClass *klass;
gboolean res;
PinosNodePrivate *priv;
SpaResult res = SPA_RESULT_OK;
StateData data;
g_return_val_if_fail (PINOS_IS_NODE (node), FALSE);
klass = PINOS_NODE_GET_CLASS (node);
g_return_val_if_fail (PINOS_IS_NODE (node), SPA_RESULT_INVALID_ARGUMENTS);
priv = node->priv;
remove_idle_timeout (node);
g_debug ("node %p: set state to %s", node, pinos_node_state_as_string (state));
if (klass->set_state)
res = klass->set_state (node, state);
else
res = FALSE;
g_debug ("node %p: set state %s", node, pinos_node_state_as_string (state));
switch (state) {
case PINOS_NODE_STATE_CREATING:
return SPA_RESULT_ERROR;
case PINOS_NODE_STATE_SUSPENDED:
res = suspend_node (node);
break;
case PINOS_NODE_STATE_INITIALIZING:
break;
case PINOS_NODE_STATE_IDLE:
res = pause_node (node);
break;
case PINOS_NODE_STATE_RUNNING:
send_clock_update (node);
res = start_node (node);
break;
case PINOS_NODE_STATE_ERROR:
break;
}
if (SPA_RESULT_IS_ERROR (res))
return res;
data.node = node;
data.state = state;
pinos_main_loop_defer (priv->main_loop,
node,
res,
(PinosDeferFunc) on_state_complete,
g_memdup (&data, sizeof (StateData)),
g_free);
return res;
}

View file

@ -84,9 +84,6 @@ struct _PinosNode {
*/
struct _PinosNodeClass {
GObjectClass parent_class;
gboolean (*set_state) (PinosNode *node,
PinosNodeState state);
};
/* normal GObject stuff */