mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	pulse-server: move sample playing into pending-sample.c
This commit is contained in:
		
							parent
							
								
									20d00e1092
								
							
						
					
					
						commit
						e37da42632
					
				
					 3 changed files with 92 additions and 83 deletions
				
			
		| 
						 | 
				
			
			@ -7,12 +7,100 @@
 | 
			
		|||
#include <pipewire/work-queue.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,8 @@
 | 
			
		|||
#include <spa/utils/hook.h>
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue