diff --git a/src/examples/video-src-alloc.c b/src/examples/video-src-alloc.c index 2635e34d3..4e8136c7c 100644 --- a/src/examples/video-src-alloc.c +++ b/src/examples/video-src-alloc.c @@ -218,6 +218,7 @@ static void on_stream_add_buffer(void *_data, struct pw_buffer *buffer) struct spa_data *d; unsigned int seals; + pw_log_info("add buffer %p", buffer); d = buf->datas; if ((d[0].type & (1<datas; + pw_log_info("remove buffer %p", buffer); munmap(d[0].data, d[0].maxsize); close(d[0].fd); diff --git a/src/pipewire/impl-link.c b/src/pipewire/impl-link.c index c0095f0a9..8be818b42 100644 --- a/src/pipewire/impl-link.c +++ b/src/pipewire/impl-link.c @@ -774,19 +774,60 @@ error_resource: static void port_state_changed(struct pw_impl_link *this, struct pw_impl_port *port, struct pw_impl_port *other, enum pw_impl_port_state state, const char *error) { - pw_log_debug(NAME" %p: port state %d", this, state); + pw_log_debug(NAME" %p: port %p state %d", this, port, state); + switch (state) { case PW_IMPL_PORT_STATE_ERROR: pw_impl_link_update_state(this, PW_LINK_STATE_ERROR, error ? strdup(error) : NULL); break; - default: - if (state < PW_IMPL_PORT_STATE_PAUSED && this->prepared) { + case PW_IMPL_PORT_STATE_INIT: + case PW_IMPL_PORT_STATE_CONFIGURE: + if (this->prepared) { + this->prepared = false; pw_impl_link_update_state(this, PW_LINK_STATE_INIT, NULL); } break; + case PW_IMPL_PORT_STATE_READY: + if (this->prepared) { + this->prepared = false; + pw_impl_link_update_state(this, PW_LINK_STATE_NEGOTIATING, NULL); + } + break; + case PW_IMPL_PORT_STATE_PAUSED: + break; } } +static void port_param_changed(struct pw_impl_link *this, uint32_t id, + struct pw_impl_port *outport, struct pw_impl_port *inport) +{ + enum pw_impl_port_state target; + + switch (id) { + case SPA_PARAM_EnumFormat: + target = PW_IMPL_PORT_STATE_CONFIGURE; + break; +// case SPA_PARAM_Buffers: +// target = PW_IMPL_PORT_STATE_READY; +// break; + default: + return; + } + if (outport) + pw_impl_port_update_state(outport, target, NULL); + if (inport) + pw_impl_port_update_state(inport, target, NULL); + + pw_impl_link_prepare(this); +} + +static void input_port_param_changed(void *data, uint32_t id) +{ + struct impl *impl = data; + struct pw_impl_link *this = &impl->this; + port_param_changed(this, id, this->output, this->input); +} + static void input_port_state_changed(void *data, enum pw_impl_port_state old, enum pw_impl_port_state state, const char *error) { @@ -795,6 +836,13 @@ static void input_port_state_changed(void *data, enum pw_impl_port_state old, port_state_changed(this, this->input, this->output, state, error); } +static void output_port_param_changed(void *data, uint32_t id) +{ + struct impl *impl = data; + struct pw_impl_link *this = &impl->this; + port_param_changed(this, id, this->output, this->input); +} + static void output_port_state_changed(void *data, enum pw_impl_port_state old, enum pw_impl_port_state state, const char *error) { @@ -805,12 +853,14 @@ static void output_port_state_changed(void *data, enum pw_impl_port_state old, static const struct pw_impl_port_events input_port_events = { PW_VERSION_IMPL_PORT_EVENTS, + .param_changed = input_port_param_changed, .state_changed = input_port_state_changed, .destroy = input_port_destroy, }; static const struct pw_impl_port_events output_port_events = { PW_VERSION_IMPL_PORT_EVENTS, + .param_changed = output_port_param_changed, .state_changed = output_port_state_changed, .destroy = output_port_destroy, };