diff --git a/pinos/client/stream.c b/pinos/client/stream.c index fff1f43ef..e752352a0 100644 --- a/pinos/client/stream.c +++ b/pinos/client/stream.c @@ -135,18 +135,20 @@ clear_buffers (PinosStream *stream) spa_list_init (&impl->free); } -static void +static bool stream_set_state (PinosStream *stream, PinosStreamState state, char *error) { - if (stream->state != state) { + bool res = stream->state != state; + if (res) { if (stream->error) free (stream->error); stream->error = error; stream->state = state; pinos_signal_emit (&stream->state_changed, stream); } + return res; } /** @@ -604,32 +606,37 @@ handle_node_command (PinosStream *stream, PinosContext *context = stream->context; if (SPA_COMMAND_TYPE (command) == context->type.command_node.Pause) { - pinos_log_debug ("stream %p: pause %d", stream, seq); - - pinos_loop_update_io (stream->context->loop, - impl->rtsocket_source, - SPA_IO_ERR | SPA_IO_HUP); - add_async_complete (stream, seq, SPA_RESULT_OK); - stream_set_state (stream, PINOS_STREAM_STATE_PAUSED, NULL); + + if (stream->state == PINOS_STREAM_STATE_STREAMING) { + pinos_log_debug ("stream %p: pause %d", stream, seq); + + pinos_loop_update_io (stream->context->loop, + impl->rtsocket_source, + SPA_IO_ERR | SPA_IO_HUP); + + stream_set_state (stream, PINOS_STREAM_STATE_PAUSED, NULL); + } } else if (SPA_COMMAND_TYPE (command) == context->type.command_node.Start) { - pinos_log_debug ("stream %p: start %d %d", stream, seq, impl->direction); add_async_complete (stream, seq, SPA_RESULT_OK); - pinos_loop_update_io (stream->context->loop, - impl->rtsocket_source, - SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP); + if (stream->state == PINOS_STREAM_STATE_PAUSED) { + pinos_log_debug ("stream %p: start %d %d", stream, seq, impl->direction); - if (impl->direction == SPA_DIRECTION_INPUT) - send_need_input (stream); - else { - impl->in_need_buffer = true; - pinos_signal_emit (&stream->need_buffer, stream); - impl->in_need_buffer = false; + pinos_loop_update_io (stream->context->loop, + impl->rtsocket_source, + SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP); + + if (impl->direction == SPA_DIRECTION_INPUT) + send_need_input (stream); + else { + impl->in_need_buffer = true; + pinos_signal_emit (&stream->need_buffer, stream); + impl->in_need_buffer = false; + } + stream_set_state (stream, PINOS_STREAM_STATE_STREAMING, NULL); } - - stream_set_state (stream, PINOS_STREAM_STATE_STREAMING, NULL); } else if (SPA_COMMAND_TYPE (command) == context->type.command_node.ClockUpdate) { SpaCommandNodeClockUpdate *cu = (SpaCommandNodeClockUpdate *) command; @@ -660,6 +667,8 @@ client_node_done (void *object, pinos_log_info ("strean %p: create client node done with fd %d", stream, datafd); handle_socket (stream, datafd); do_node_init (stream); + + stream_set_state (stream, PINOS_STREAM_STATE_CONFIGURE, NULL); } static void @@ -703,11 +712,15 @@ client_node_set_format (void *object, if (impl->format) free (impl->format); - impl->format = spa_format_copy (format); + impl->format = format ? spa_format_copy (format) : NULL; impl->pending_seq = seq; pinos_signal_emit (&stream->format_changed, stream, impl->format); - stream_set_state (stream, PINOS_STREAM_STATE_READY, NULL); + + if (format) + stream_set_state (stream, PINOS_STREAM_STATE_READY, NULL); + else + stream_set_state (stream, PINOS_STREAM_STATE_CONFIGURE, NULL); } static void @@ -1038,7 +1051,7 @@ pinos_stream_finish_format (PinosStream *stream, impl->port_info.n_params = n_params; if (SPA_RESULT_IS_OK (res)) { - add_port_update (stream, PINOS_MESSAGE_PORT_UPDATE_INFO | + add_port_update (stream, (n_params ? PINOS_MESSAGE_PORT_UPDATE_INFO : 0) | PINOS_MESSAGE_PORT_UPDATE_FORMAT); if (!impl->format) diff --git a/pinos/examples/video-src.c b/pinos/examples/video-src.c index e2843e7a2..cb1870abf 100644 --- a/pinos/examples/video-src.c +++ b/pinos/examples/video-src.c @@ -69,6 +69,8 @@ typedef struct { PinosListener on_stream_state_changed; PinosListener on_stream_format_changed; + SpaVideoInfoRaw format; + uint8_t params_buffer[1024]; int counter; } Data; @@ -170,19 +172,24 @@ on_stream_format_changed (PinosListener *listener, SpaPODFrame f[2]; SpaAllocParam *params[2]; - spa_pod_builder_init (&b, data->params_buffer, sizeof (data->params_buffer)); - spa_pod_builder_object (&b, &f[0], 0, ctx->type.alloc_param_buffers.Buffers, - PROP (&f[1], ctx->type.alloc_param_buffers.size, SPA_POD_TYPE_INT, STRIDE * HEIGHT), - PROP (&f[1], ctx->type.alloc_param_buffers.stride, SPA_POD_TYPE_INT, STRIDE), - PROP_U_MM (&f[1], ctx->type.alloc_param_buffers.buffers, SPA_POD_TYPE_INT, 32, 2, 32), - PROP (&f[1], ctx->type.alloc_param_buffers.align, SPA_POD_TYPE_INT, 16)); - params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + if (format) { + spa_pod_builder_init (&b, data->params_buffer, sizeof (data->params_buffer)); + spa_pod_builder_object (&b, &f[0], 0, ctx->type.alloc_param_buffers.Buffers, + PROP (&f[1], ctx->type.alloc_param_buffers.size, SPA_POD_TYPE_INT, STRIDE * HEIGHT), + PROP (&f[1], ctx->type.alloc_param_buffers.stride, SPA_POD_TYPE_INT, STRIDE), + PROP_U_MM (&f[1], ctx->type.alloc_param_buffers.buffers, SPA_POD_TYPE_INT, 32, 2, 32), + PROP (&f[1], ctx->type.alloc_param_buffers.align, SPA_POD_TYPE_INT, 16)); + params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); - spa_pod_builder_object (&b, &f[0], 0, ctx->type.alloc_param_meta_enable.MetaEnable, - PROP (&f[1], ctx->type.alloc_param_meta_enable.type, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); - params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); + spa_pod_builder_object (&b, &f[0], 0, ctx->type.alloc_param_meta_enable.MetaEnable, + PROP (&f[1], ctx->type.alloc_param_meta_enable.type, SPA_POD_TYPE_INT, SPA_META_TYPE_HEADER)); + params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam); - pinos_stream_finish_format (stream, SPA_RESULT_OK, params, 2); + pinos_stream_finish_format (stream, SPA_RESULT_OK, params, 2); + } + else { + pinos_stream_finish_format (stream, SPA_RESULT_OK, NULL, 0); + } } static void diff --git a/pinos/server/port.c b/pinos/server/port.c index e16a69b51..731bd9e9a 100644 --- a/pinos/server/port.c +++ b/pinos/server/port.c @@ -203,6 +203,9 @@ static SpaResult pinos_port_pause (PinosPort *port) { SpaCommand cmd = SPA_COMMAND_INIT (port->node->core->type.command_node.Pause); + if (port->state <= SPA_PORT_STATE_PAUSED) + return SPA_RESULT_OK; + port->state = SPA_PORT_STATE_PAUSED; return spa_node_port_send_command (port->node->node, port->direction,