diff --git a/src/modules/module-protocol-pulse/pending-sample.c b/src/modules/module-protocol-pulse/pending-sample.c index 4ef858621..33f9be100 100644 --- a/src/modules/module-protocol-pulse/pending-sample.c +++ b/src/modules/module-protocol-pulse/pending-sample.c @@ -7,12 +7,100 @@ #include #include "client.h" +#include "collect.h" +#include "commands.h" #include "internal.h" #include "log.h" +#include "message.h" #include "operation.h" #include "pending-sample.h" +#include "reply.h" #include "sample-play.h" +static void sample_play_finish(struct pending_sample *ps) +{ + struct client *client = ps->client; + pending_sample_free(ps); + client_unref(client); +} + +static void sample_play_ready_reply(void *data, struct client *client, uint32_t tag) +{ + struct pending_sample *ps = data; + struct message *reply; + uint32_t index = id_to_index(client->manager, ps->play->id); + + pw_log_info("[%s] PLAY_SAMPLE tag:%u index:%u", + client->name, ps->tag, index); + + ps->ready = true; + + reply = reply_new(client, ps->tag); + if (client->version >= 13) + message_put(reply, + TAG_U32, index, + TAG_INVALID); + + client_queue_message(client, reply); + + if (ps->done) + sample_play_finish(ps); +} + +static void sample_play_ready(void *data, uint32_t id) +{ + struct pending_sample *ps = data; + struct client *client = ps->client; + operation_new_cb(client, ps->tag, sample_play_ready_reply, ps); +} + +static void on_sample_done(void *obj, void *data, int res, uint32_t id) +{ + struct pending_sample *ps = obj; + ps->done = true; + if (ps->ready) + sample_play_finish(ps); +} + +static void sample_play_done(void *data, int res) +{ + struct pending_sample *ps = data; + struct client *client = ps->client; + struct impl *impl = client->impl; + + if (res < 0) + reply_error(client, COMMAND_PLAY_SAMPLE, ps->tag, res); + else + pw_log_info("[%s] PLAY_SAMPLE done tag:%u", client->name, ps->tag); + + pw_work_queue_add(impl->work_queue, ps, 0, + on_sample_done, client); +} + +static const struct sample_play_events sample_play_events = { + VERSION_SAMPLE_PLAY_EVENTS, + .ready = sample_play_ready, + .done = sample_play_done, +}; + +int pending_sample_new(struct client *client, struct sample *sample, struct pw_properties *props, uint32_t tag) +{ + struct pending_sample *ps; + struct sample_play *p = sample_play_new(client->core, sample, props, sizeof(*ps)); + if (!p) + return -errno; + + ps = p->user_data; + ps->client = client; + ps->play = p; + ps->tag = tag; + sample_play_add_listener(p, &ps->listener, &sample_play_events, ps); + spa_list_append(&client->pending_samples, &ps->link); + client->ref++; + + return 0; +} + void pending_sample_free(struct pending_sample *ps) { struct client * const client = ps->client; diff --git a/src/modules/module-protocol-pulse/pending-sample.h b/src/modules/module-protocol-pulse/pending-sample.h index fc4714203..94c284431 100644 --- a/src/modules/module-protocol-pulse/pending-sample.h +++ b/src/modules/module-protocol-pulse/pending-sample.h @@ -11,6 +11,8 @@ #include struct client; +struct pw_properties; +struct sample; struct sample_play; struct pending_sample { @@ -23,6 +25,7 @@ struct pending_sample { unsigned done:1; }; +int pending_sample_new(struct client *client, struct sample *sample, struct pw_properties *props, uint32_t tag); void pending_sample_free(struct pending_sample *ps); #endif /* PULSE_SERVER_PENDING_SAMPLE_H */ diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index e4711154b..40d869e5e 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -50,7 +50,6 @@ #include "quirks.h" #include "reply.h" #include "sample.h" -#include "sample-play.h" #include "server.h" #include "stream.h" #include "utils.h" @@ -2502,81 +2501,13 @@ static struct pw_manager_object *find_device(struct client *client, return o; } -static void sample_play_finish(struct pending_sample *ps) -{ - struct client *client = ps->client; - pending_sample_free(ps); - client_unref(client); -} - -static void sample_play_ready_reply(void *data, struct client *client, uint32_t tag) -{ - struct pending_sample *ps = data; - struct message *reply; - uint32_t index = id_to_index(client->manager, ps->play->id); - - pw_log_info("[%s] PLAY_SAMPLE tag:%u index:%u", - client->name, ps->tag, index); - - ps->ready = true; - - reply = reply_new(client, ps->tag); - if (client->version >= 13) - message_put(reply, - TAG_U32, index, - TAG_INVALID); - - client_queue_message(client, reply); - - if (ps->done) - sample_play_finish(ps); -} - -static void sample_play_ready(void *data, uint32_t id) -{ - struct pending_sample *ps = data; - struct client *client = ps->client; - operation_new_cb(client, ps->tag, sample_play_ready_reply, ps); -} - -static void on_sample_done(void *obj, void *data, int res, uint32_t id) -{ - struct pending_sample *ps = obj; - ps->done = true; - if (ps->ready) - sample_play_finish(ps); -} - -static void sample_play_done(void *data, int res) -{ - struct pending_sample *ps = data; - struct client *client = ps->client; - struct impl *impl = client->impl; - - if (res < 0) - reply_error(client, COMMAND_PLAY_SAMPLE, ps->tag, res); - else - pw_log_info("[%s] PLAY_SAMPLE done tag:%u", client->name, ps->tag); - - pw_work_queue_add(impl->work_queue, ps, 0, - on_sample_done, client); -} - -static const struct sample_play_events sample_play_events = { - VERSION_SAMPLE_PLAY_EVENTS, - .ready = sample_play_ready, - .done = sample_play_done, -}; - static int do_play_sample(struct client *client, uint32_t command, uint32_t tag, struct message *m) { struct impl *impl = client->impl; uint32_t sink_index, volume; struct sample *sample; - struct sample_play *play; const char *sink_name, *name; struct pw_properties *props = NULL; - struct pending_sample *ps; struct pw_manager_object *o; int res; @@ -2617,20 +2548,7 @@ static int do_play_sample(struct client *client, uint32_t command, uint32_t tag, pw_properties_setf(props, PW_KEY_TARGET_OBJECT, "%"PRIu64, o->serial); - play = sample_play_new(client->core, sample, props, sizeof(struct pending_sample)); - props = NULL; - if (play == NULL) - goto error_errno; - - ps = play->user_data; - ps->client = client; - ps->play = play; - ps->tag = tag; - sample_play_add_listener(play, &ps->listener, &sample_play_events, ps); - spa_list_append(&client->pending_samples, &ps->link); - client->ref++; - - return 0; + return pending_sample_new(client, sample, props, tag); error_errno: res = -errno;