adapter: pass spa_node to adapter

Make it possible to pass a spa_node as the follower of the adapter. This
avoids us having to wrap it in a pw_impl_node in order to unwrap it
again for the adapter spa_node.
This commit is contained in:
Wim Taymans 2022-05-11 12:28:26 +02:00
parent 9d186cf622
commit daf53b94ed
4 changed files with 108 additions and 45 deletions

View file

@ -71,6 +71,7 @@ struct node_data {
struct spa_list link;
struct pw_impl_node *adapter;
struct pw_impl_node *follower;
struct spa_handle *handle;
struct spa_hook adapter_listener;
struct pw_resource *resource;
struct pw_resource *bound_resource;
@ -114,7 +115,10 @@ static void node_free(void *data)
spa_hook_remove(&nd->adapter_listener);
pw_impl_node_destroy(nd->follower);
if (nd->follower)
pw_impl_node_destroy(nd->follower);
if (nd->handle)
pw_unload_spa_handle(nd->handle);
}
static void node_initialized(void *data)
@ -169,10 +173,13 @@ static void *create_object(void *_data,
struct factory_data *d = _data;
struct pw_impl_client *client;
struct pw_impl_node *adapter, *follower;
const char *str, *factory_name;
struct spa_node *spa_follower;
const char *str;
int res;
struct node_data *nd;
bool linger, do_register;
struct spa_handle *handle = NULL;
const struct pw_properties *p;
if (properties == NULL)
goto error_properties;
@ -183,6 +190,10 @@ static void *create_object(void *_data,
linger = pw_properties_get_bool(properties, PW_KEY_OBJECT_LINGER, false);
do_register = pw_properties_get_bool(properties, PW_KEY_OBJECT_REGISTER, true);
p = pw_context_get_properties(d->context);
pw_properties_set(properties, "clock.quantum-limit",
pw_properties_get(p, "default.clock.quantum-limit"));
client = resource ? pw_resource_get_client(resource): NULL;
if (client && !linger) {
pw_properties_setf(properties, PW_KEY_CLIENT_ID, "%d",
@ -190,29 +201,44 @@ static void *create_object(void *_data,
}
follower = NULL;
spa_follower = NULL;
str = pw_properties_get(properties, "adapt.follower.node");
if (str != NULL) {
if (sscanf(str, "pointer:%p", &follower) != 1)
goto error_properties;
pw_properties_setf(properties, "audio.adapt.follower", "pointer:%p", follower);
spa_follower = pw_impl_node_get_implementation(follower);
}
if (follower == NULL) {
str = pw_properties_get(properties, "adapt.follower.spa-node");
if (str != NULL) {
if (sscanf(str, "pointer:%p", &spa_follower) != 1)
goto error_properties;
}
if (spa_follower == NULL) {
void *iface;
const char *factory_name;
factory_name = pw_properties_get(properties, SPA_KEY_FACTORY_NAME);
if (factory_name == NULL)
goto error_properties;
follower = pw_spa_node_load(d->context,
factory_name,
PW_SPA_NODE_FLAG_ACTIVATE |
PW_SPA_NODE_FLAG_NO_REGISTER,
pw_properties_copy(properties), 0);
if (follower == NULL)
handle = pw_context_load_spa_handle(d->context,
factory_name,
properties ? &properties->dict : NULL);
if (handle == NULL)
goto error_errno;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Node, &iface)) < 0)
goto error_res;
spa_follower = iface;
}
if (spa_follower == NULL) {
res = -EINVAL;
goto error_res;
}
adapter = pw_adapter_new(pw_impl_module_get_context(d->module),
follower,
spa_follower,
properties,
sizeof(struct node_data));
properties = NULL;
@ -228,6 +254,7 @@ static void *create_object(void *_data,
nd->data = d;
nd->adapter = adapter;
nd->follower = follower;
nd->handle = handle;
nd->resource = resource;
nd->new_id = new_id;
nd->linger = linger;
@ -248,6 +275,7 @@ error_properties:
goto error_cleanup;
error_errno:
res = -errno;
error_res:
pw_resource_errorf_id(resource, new_id, res, "can't create node: %s", spa_strerror(res));
goto error_cleanup;
error_usage:
@ -257,6 +285,8 @@ error_usage:
goto error_cleanup;
error_cleanup:
pw_properties_free(properties);
if (handle)
pw_unload_spa_handle(handle);
errno = -res;
return NULL;
}