mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
device: handle async implementations
This commit is contained in:
parent
bf677d55da
commit
504b2da72b
1 changed files with 60 additions and 11 deletions
|
|
@ -41,10 +41,23 @@ struct impl {
|
||||||
#define pw_device_resource_info(r,...) pw_device_resource(r,info,0,__VA_ARGS__)
|
#define pw_device_resource_info(r,...) pw_device_resource(r,info,0,__VA_ARGS__)
|
||||||
#define pw_device_resource_param(r,...) pw_device_resource(r,param,0,__VA_ARGS__)
|
#define pw_device_resource_param(r,...) pw_device_resource(r,param,0,__VA_ARGS__)
|
||||||
|
|
||||||
|
struct result_device_params_data {
|
||||||
|
void *data;
|
||||||
|
int (*callback) (void *data, int seq,
|
||||||
|
uint32_t id, uint32_t index, uint32_t next,
|
||||||
|
struct spa_pod *param);
|
||||||
|
};
|
||||||
|
|
||||||
struct resource_data {
|
struct resource_data {
|
||||||
struct spa_hook resource_listener;
|
struct spa_hook resource_listener;
|
||||||
struct pw_device *device;
|
struct pw_device *device;
|
||||||
struct pw_resource *resource;
|
struct pw_resource *resource;
|
||||||
|
|
||||||
|
/* for async replies */
|
||||||
|
int seq;
|
||||||
|
int end;
|
||||||
|
struct result_device_params_data data;
|
||||||
|
struct spa_hook listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct node_data {
|
struct node_data {
|
||||||
|
|
@ -124,20 +137,22 @@ void pw_device_destroy(struct pw_device *device)
|
||||||
|
|
||||||
static void device_unbind_func(void *data)
|
static void device_unbind_func(void *data)
|
||||||
{
|
{
|
||||||
struct pw_resource *resource = data;
|
struct resource_data *d = data;
|
||||||
|
struct pw_resource *resource = d->resource;
|
||||||
spa_list_remove(&resource->link);
|
spa_list_remove(&resource->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void device_pong(void *data, int seq)
|
||||||
|
{
|
||||||
|
struct resource_data *d = data;
|
||||||
|
struct pw_resource *resource = d->resource;
|
||||||
|
pw_log_debug("resource %p: got pong %d", resource, seq);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct pw_resource_events resource_events = {
|
static const struct pw_resource_events resource_events = {
|
||||||
PW_VERSION_RESOURCE_EVENTS,
|
PW_VERSION_RESOURCE_EVENTS,
|
||||||
.destroy = device_unbind_func,
|
.destroy = device_unbind_func,
|
||||||
};
|
.pong = device_pong,
|
||||||
|
|
||||||
struct result_device_params_data {
|
|
||||||
void *data;
|
|
||||||
int (*callback) (void *data, int seq,
|
|
||||||
uint32_t id, uint32_t index, uint32_t next,
|
|
||||||
struct spa_pod *param);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void result_device_params(void *data, int seq, int res, uint32_t type, const void *result)
|
static void result_device_params(void *data, int seq, int res, uint32_t type, const void *result)
|
||||||
|
|
@ -198,6 +213,20 @@ static int reply_param(void *data, int seq, uint32_t id,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void result_device_params_async(void *data, int seq, int res, uint32_t type, const void *result)
|
||||||
|
{
|
||||||
|
struct resource_data *d = data;
|
||||||
|
|
||||||
|
pw_log_debug("async result %d %d (%d/%d)", res, seq, d->seq, d->end);
|
||||||
|
if (seq == d->seq)
|
||||||
|
result_device_params(&d->data, seq, res, type, result);
|
||||||
|
|
||||||
|
if (seq == d->end) {
|
||||||
|
spa_hook_remove(&d->listener);
|
||||||
|
pw_client_set_busy(d->resource->client, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int device_enum_params(void *object, int seq, uint32_t id, uint32_t start, uint32_t num,
|
static int device_enum_params(void *object, int seq, uint32_t id, uint32_t start, uint32_t num,
|
||||||
const struct spa_pod *filter)
|
const struct spa_pod *filter)
|
||||||
{
|
{
|
||||||
|
|
@ -206,11 +235,27 @@ static int device_enum_params(void *object, int seq, uint32_t id, uint32_t start
|
||||||
struct pw_device *device = data->device;
|
struct pw_device *device = data->device;
|
||||||
struct pw_client *client = resource->client;
|
struct pw_client *client = resource->client;
|
||||||
int res;
|
int res;
|
||||||
|
static const struct spa_device_events device_events = {
|
||||||
|
SPA_VERSION_DEVICE_EVENTS,
|
||||||
|
.result = result_device_params_async,
|
||||||
|
};
|
||||||
|
|
||||||
if ((res = pw_device_for_each_param(device, seq, id, start, num,
|
res = pw_device_for_each_param(device, seq, id, start, num,
|
||||||
filter, reply_param, data)) < 0)
|
filter, reply_param, data);
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
pw_core_resource_error(client->core_resource,
|
pw_core_resource_error(client->core_resource,
|
||||||
resource->id, seq, res, spa_strerror(res));
|
resource->id, seq, res, spa_strerror(res));
|
||||||
|
} else if (SPA_RESULT_IS_ASYNC(res)) {
|
||||||
|
data->data.data = data;
|
||||||
|
data->data.callback = reply_param;
|
||||||
|
spa_device_add_listener(device->device, &data->listener,
|
||||||
|
&device_events, data);
|
||||||
|
data->seq = res;
|
||||||
|
data->end = spa_device_sync(device->device, res);
|
||||||
|
pw_client_set_busy(client, true);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -249,7 +294,7 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||||
data = pw_resource_get_user_data(resource);
|
data = pw_resource_get_user_data(resource);
|
||||||
data->device = this;
|
data->device = this;
|
||||||
data->resource = resource;
|
data->resource = resource;
|
||||||
pw_resource_add_listener(resource, &data->resource_listener, &resource_events, resource);
|
pw_resource_add_listener(resource, &data->resource_listener, &resource_events, data);
|
||||||
|
|
||||||
pw_resource_set_implementation(resource, &device_methods, data);
|
pw_resource_set_implementation(resource, &device_methods, data);
|
||||||
|
|
||||||
|
|
@ -393,6 +438,10 @@ static void device_add(struct pw_device *device, uint32_t id,
|
||||||
pw_log_warn("device %p: unknown type %d", device, info->type);
|
pw_log_warn("device %p: unknown type %d", device, info->type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (info->factory == NULL) {
|
||||||
|
pw_log_warn("device %p: missing factory", device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pw_log_debug("device %p: add node %d", device, id);
|
pw_log_debug("device %p: add node %d", device, id);
|
||||||
support = pw_core_get_support(device->core, &n_support);
|
support = pw_core_get_support(device->core, &n_support);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue