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 <pipewire/work-queue.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "client.h"
 | 
					#include "client.h"
 | 
				
			||||||
 | 
					#include "collect.h"
 | 
				
			||||||
 | 
					#include "commands.h"
 | 
				
			||||||
#include "internal.h"
 | 
					#include "internal.h"
 | 
				
			||||||
#include "log.h"
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					#include "message.h"
 | 
				
			||||||
#include "operation.h"
 | 
					#include "operation.h"
 | 
				
			||||||
#include "pending-sample.h"
 | 
					#include "pending-sample.h"
 | 
				
			||||||
 | 
					#include "reply.h"
 | 
				
			||||||
#include "sample-play.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)
 | 
					void pending_sample_free(struct pending_sample *ps)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct client * const client = ps->client;
 | 
						struct client * const client = ps->client;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,8 @@
 | 
				
			||||||
#include <spa/utils/hook.h>
 | 
					#include <spa/utils/hook.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct client;
 | 
					struct client;
 | 
				
			||||||
 | 
					struct pw_properties;
 | 
				
			||||||
 | 
					struct sample;
 | 
				
			||||||
struct sample_play;
 | 
					struct sample_play;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pending_sample {
 | 
					struct pending_sample {
 | 
				
			||||||
| 
						 | 
					@ -23,6 +25,7 @@ struct pending_sample {
 | 
				
			||||||
	unsigned done:1;
 | 
						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);
 | 
					void pending_sample_free(struct pending_sample *ps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* PULSE_SERVER_PENDING_SAMPLE_H */
 | 
					#endif /* PULSE_SERVER_PENDING_SAMPLE_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,7 +50,6 @@
 | 
				
			||||||
#include "quirks.h"
 | 
					#include "quirks.h"
 | 
				
			||||||
#include "reply.h"
 | 
					#include "reply.h"
 | 
				
			||||||
#include "sample.h"
 | 
					#include "sample.h"
 | 
				
			||||||
#include "sample-play.h"
 | 
					 | 
				
			||||||
#include "server.h"
 | 
					#include "server.h"
 | 
				
			||||||
#include "stream.h"
 | 
					#include "stream.h"
 | 
				
			||||||
#include "utils.h"
 | 
					#include "utils.h"
 | 
				
			||||||
| 
						 | 
					@ -2502,81 +2501,13 @@ static struct pw_manager_object *find_device(struct client *client,
 | 
				
			||||||
	return o;
 | 
						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)
 | 
					static int do_play_sample(struct client *client, uint32_t command, uint32_t tag, struct message *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = client->impl;
 | 
						struct impl *impl = client->impl;
 | 
				
			||||||
	uint32_t sink_index, volume;
 | 
						uint32_t sink_index, volume;
 | 
				
			||||||
	struct sample *sample;
 | 
						struct sample *sample;
 | 
				
			||||||
	struct sample_play *play;
 | 
					 | 
				
			||||||
	const char *sink_name, *name;
 | 
						const char *sink_name, *name;
 | 
				
			||||||
	struct pw_properties *props = NULL;
 | 
						struct pw_properties *props = NULL;
 | 
				
			||||||
	struct pending_sample *ps;
 | 
					 | 
				
			||||||
	struct pw_manager_object *o;
 | 
						struct pw_manager_object *o;
 | 
				
			||||||
	int res;
 | 
						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);
 | 
						pw_properties_setf(props, PW_KEY_TARGET_OBJECT, "%"PRIu64, o->serial);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	play = sample_play_new(client->core, sample, props, sizeof(struct pending_sample));
 | 
						return pending_sample_new(client, sample, props, tag);
 | 
				
			||||||
	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;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_errno:
 | 
					error_errno:
 | 
				
			||||||
	res = -errno;
 | 
						res = -errno;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue