mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
filter: implement set_active()
Make a node implementation and export it, just like we do for the stream. This way we can use the node to implement set_active(). Tweak the draining logic like pw_stream.
This commit is contained in:
parent
d0ac5c2e1d
commit
216d788ce5
2 changed files with 65 additions and 12 deletions
|
|
@ -147,6 +147,7 @@ struct filter {
|
||||||
unsigned int disconnecting:1;
|
unsigned int disconnecting:1;
|
||||||
unsigned int disconnect_core:1;
|
unsigned int disconnect_core:1;
|
||||||
unsigned int draining:1;
|
unsigned int draining:1;
|
||||||
|
unsigned int drained:1;
|
||||||
unsigned int allow_mlock:1;
|
unsigned int allow_mlock:1;
|
||||||
unsigned int warn_mlock:1;
|
unsigned int warn_mlock:1;
|
||||||
unsigned int process_rt:1;
|
unsigned int process_rt:1;
|
||||||
|
|
@ -1002,7 +1003,6 @@ do_call_drained(struct spa_loop *loop,
|
||||||
struct pw_filter *filter = &impl->this;
|
struct pw_filter *filter = &impl->this;
|
||||||
pw_log_trace("%p: drained", filter);
|
pw_log_trace("%p: drained", filter);
|
||||||
pw_filter_emit_drained(filter);
|
pw_filter_emit_drained(filter);
|
||||||
impl->draining = false;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1086,6 +1086,7 @@ static int impl_node_process(void *object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl->drained = drained;
|
||||||
if (drained && impl->draining)
|
if (drained && impl->draining)
|
||||||
call_drained(impl);
|
call_drained(impl);
|
||||||
|
|
||||||
|
|
@ -1129,7 +1130,7 @@ static void proxy_error(void *_data, int seq, int res, const char *message)
|
||||||
struct pw_filter *filter = _data;
|
struct pw_filter *filter = _data;
|
||||||
/* we just emit the state change here to inform the application.
|
/* we just emit the state change here to inform the application.
|
||||||
* If this is supposed to be a permanent error, the app should
|
* If this is supposed to be a permanent error, the app should
|
||||||
* do a pw_stream_set_error() */
|
* do a pw_filter_set_error() */
|
||||||
pw_filter_emit_state_changed(filter, filter->state,
|
pw_filter_emit_state_changed(filter, filter->state,
|
||||||
PW_FILTER_STATE_ERROR, message);
|
PW_FILTER_STATE_ERROR, message);
|
||||||
}
|
}
|
||||||
|
|
@ -1203,8 +1204,6 @@ filter_new(struct pw_context *context, const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl->main_loop = pw_context_get_main_loop(context);
|
impl->main_loop = pw_context_get_main_loop(context);
|
||||||
impl->data_loop = pw_data_loop_get_loop(
|
|
||||||
pw_context_get_data_loop(context));
|
|
||||||
|
|
||||||
this = &impl->this;
|
this = &impl->this;
|
||||||
pw_log_debug("%p: new", impl);
|
pw_log_debug("%p: new", impl);
|
||||||
|
|
@ -1373,11 +1372,17 @@ static int filter_disconnect(struct filter *impl)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
impl->disconnecting = true;
|
impl->disconnecting = true;
|
||||||
|
if (filter->node)
|
||||||
|
pw_impl_node_set_active(filter->node, false);
|
||||||
|
|
||||||
if (filter->proxy) {
|
if (filter->proxy) {
|
||||||
pw_proxy_destroy(filter->proxy);
|
pw_proxy_destroy(filter->proxy);
|
||||||
filter->proxy = NULL;
|
filter->proxy = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter->node)
|
||||||
|
pw_impl_node_destroy(filter->node);
|
||||||
|
|
||||||
if (impl->disconnect_core) {
|
if (impl->disconnect_core) {
|
||||||
impl->disconnect_core = false;
|
impl->disconnect_core = false;
|
||||||
spa_hook_remove(&filter->core_listener);
|
spa_hook_remove(&filter->core_listener);
|
||||||
|
|
@ -1536,17 +1541,28 @@ int pw_filter_update_properties(struct pw_filter *filter, void *port_data, const
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPA_EXPORT
|
static void node_event_destroy(void *data)
|
||||||
int
|
{
|
||||||
|
struct pw_filter *filter = data;
|
||||||
|
spa_hook_remove(&filter->node_listener);
|
||||||
|
filter->node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pw_impl_node_events node_events = {
|
||||||
|
PW_VERSION_IMPL_NODE_EVENTS,
|
||||||
|
.destroy = node_event_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
SPA_EXPORT int
|
||||||
pw_filter_connect(struct pw_filter *filter,
|
pw_filter_connect(struct pw_filter *filter,
|
||||||
enum pw_filter_flags flags,
|
enum pw_filter_flags flags,
|
||||||
const struct spa_pod **params,
|
const struct spa_pod **params,
|
||||||
uint32_t n_params)
|
uint32_t n_params)
|
||||||
{
|
{
|
||||||
struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this);
|
struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this);
|
||||||
|
struct pw_properties *props = NULL;
|
||||||
int res;
|
int res;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct spa_dict_item items[1];
|
|
||||||
|
|
||||||
ensure_loop(impl->main_loop, return -EIO);
|
ensure_loop(impl->main_loop, return -EIO);
|
||||||
|
|
||||||
|
|
@ -1610,12 +1626,27 @@ pw_filter_connect(struct pw_filter *filter,
|
||||||
impl->disconnect_core = true;
|
impl->disconnect_core = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pw_log_debug("%p: export node %p", filter, &impl->impl_node);
|
pw_log_debug("%p: creating node", filter);
|
||||||
|
props = pw_properties_copy(filter->properties);
|
||||||
|
if (props == NULL) {
|
||||||
|
res = -errno;
|
||||||
|
goto error_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter->node = pw_context_create_node(impl->context, props, 0);
|
||||||
|
props = NULL;
|
||||||
|
if (filter->node == NULL) {
|
||||||
|
res = -errno;
|
||||||
|
goto error_node;
|
||||||
|
}
|
||||||
|
pw_impl_node_set_implementation(filter->node, &impl->impl_node);
|
||||||
|
|
||||||
|
impl->data_loop = filter->node->data_loop;
|
||||||
|
|
||||||
|
pw_log_debug("%p: export node %p", filter, filter->node);
|
||||||
|
|
||||||
items[0] = SPA_DICT_ITEM_INIT(PW_KEY_OBJECT_REGISTER, "false");
|
|
||||||
filter->proxy = pw_core_export(filter->core,
|
filter->proxy = pw_core_export(filter->core,
|
||||||
SPA_TYPE_INTERFACE_Node, &SPA_DICT_INIT_ARRAY(items),
|
PW_TYPE_INTERFACE_Node, NULL, filter->node, 0);
|
||||||
&impl->impl_node, 0);
|
|
||||||
if (filter->proxy == NULL) {
|
if (filter->proxy == NULL) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto error_proxy;
|
goto error_proxy;
|
||||||
|
|
@ -1623,13 +1654,24 @@ pw_filter_connect(struct pw_filter *filter,
|
||||||
|
|
||||||
pw_proxy_add_listener(filter->proxy, &filter->proxy_listener, &proxy_events, filter);
|
pw_proxy_add_listener(filter->proxy, &filter->proxy_listener, &proxy_events, filter);
|
||||||
|
|
||||||
|
pw_impl_node_add_listener(filter->node, &filter->node_listener, &node_events, filter);
|
||||||
|
|
||||||
|
pw_impl_node_set_active(filter->node,
|
||||||
|
!SPA_FLAG_IS_SET(impl->flags, PW_FILTER_FLAG_INACTIVE));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_connect:
|
error_connect:
|
||||||
pw_log_error("%p: can't connect: %s", filter, spa_strerror(res));
|
pw_log_error("%p: can't connect: %s", filter, spa_strerror(res));
|
||||||
return res;
|
goto exit_cleanup;
|
||||||
|
error_node:
|
||||||
|
pw_log_error("%p: can't make node: %s", filter, spa_strerror(res));
|
||||||
|
goto exit_cleanup;
|
||||||
error_proxy:
|
error_proxy:
|
||||||
pw_log_error("%p: can't make proxy: %s", filter, spa_strerror(res));
|
pw_log_error("%p: can't make proxy: %s", filter, spa_strerror(res));
|
||||||
|
goto exit_cleanup;
|
||||||
|
exit_cleanup:
|
||||||
|
pw_properties_free(props);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1860,6 +1902,13 @@ int pw_filter_set_active(struct pw_filter *filter, bool active)
|
||||||
ensure_loop(impl->main_loop, return -EIO);
|
ensure_loop(impl->main_loop, return -EIO);
|
||||||
|
|
||||||
pw_log_debug("%p: active:%d", filter, active);
|
pw_log_debug("%p: active:%d", filter, active);
|
||||||
|
if (filter->node == NULL)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
pw_impl_node_set_active(filter->node, active);
|
||||||
|
|
||||||
|
if (!active || impl->drained)
|
||||||
|
impl->drained = impl->draining = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1968,6 +2017,7 @@ do_drain(struct spa_loop *loop,
|
||||||
{
|
{
|
||||||
struct filter *impl = user_data;
|
struct filter *impl = user_data;
|
||||||
impl->draining = true;
|
impl->draining = true;
|
||||||
|
impl->drained = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1120,6 +1120,9 @@ struct pw_filter {
|
||||||
struct pw_proxy *proxy;
|
struct pw_proxy *proxy;
|
||||||
struct spa_hook proxy_listener;
|
struct spa_hook proxy_listener;
|
||||||
|
|
||||||
|
struct pw_impl_node *node;
|
||||||
|
struct spa_hook node_listener;
|
||||||
|
|
||||||
struct spa_list controls;
|
struct spa_list controls;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue