mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Param: add process latency param and info
This commit is contained in:
		
							parent
							
								
									8c77713a7b
								
							
						
					
					
						commit
						79866a93cd
					
				
					 7 changed files with 97 additions and 4 deletions
				
			
		| 
						 | 
					@ -112,6 +112,52 @@ spa_latency_build(struct spa_pod_builder *builder, uint32_t id, const struct spa
 | 
				
			||||||
			SPA_PARAM_LATENCY_maxNs, SPA_POD_Long(info->max_ns));
 | 
								SPA_PARAM_LATENCY_maxNs, SPA_POD_Long(info->max_ns));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct spa_process_latency_info {
 | 
				
			||||||
 | 
						float quantum;
 | 
				
			||||||
 | 
						uint32_t rate;
 | 
				
			||||||
 | 
						uint64_t ns;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SPA_PROCESS_LATENCY_INFO_INIT(...)	(struct spa_process_latency_info) { __VA_ARGS__ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int
 | 
				
			||||||
 | 
					spa_process_latency_parse(const struct spa_pod *latency, struct spa_process_latency_info *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
 | 
						spa_zero(*info);
 | 
				
			||||||
 | 
						if ((res = spa_pod_parse_object(latency,
 | 
				
			||||||
 | 
								SPA_TYPE_OBJECT_ParamProcessLatency, NULL,
 | 
				
			||||||
 | 
								SPA_PARAM_PROCESS_LATENCY_quantum, SPA_POD_OPT_Float(&info->quantum),
 | 
				
			||||||
 | 
								SPA_PARAM_PROCESS_LATENCY_rate, SPA_POD_OPT_Int(&info->rate),
 | 
				
			||||||
 | 
								SPA_PARAM_PROCESS_LATENCY_ns, SPA_POD_OPT_Long(&info->ns))) < 0)
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline struct spa_pod *
 | 
				
			||||||
 | 
					spa_process_latency_build(struct spa_pod_builder *builder, uint32_t id,
 | 
				
			||||||
 | 
							const struct spa_process_latency_info *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (struct spa_pod *)spa_pod_builder_add_object(builder,
 | 
				
			||||||
 | 
								SPA_TYPE_OBJECT_ParamProcessLatency, id,
 | 
				
			||||||
 | 
								SPA_PARAM_PROCESS_LATENCY_quantum, SPA_POD_Float(info->quantum),
 | 
				
			||||||
 | 
								SPA_PARAM_PROCESS_LATENCY_rate, SPA_POD_Int(info->rate),
 | 
				
			||||||
 | 
								SPA_PARAM_PROCESS_LATENCY_ns, SPA_POD_Long(info->ns));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int
 | 
				
			||||||
 | 
					spa_process_latency_info_add(const struct spa_process_latency_info *process,
 | 
				
			||||||
 | 
							struct spa_latency_info *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						info->min_quantum += process->quantum;
 | 
				
			||||||
 | 
						info->max_quantum += process->quantum;
 | 
				
			||||||
 | 
						info->min_rate += process->rate;
 | 
				
			||||||
 | 
						info->max_rate += process->rate;
 | 
				
			||||||
 | 
						info->min_ns += process->ns;
 | 
				
			||||||
 | 
						info->max_ns += process->ns;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}  /* extern "C" */
 | 
					}  /* extern "C" */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,6 +57,7 @@ enum spa_param_type {
 | 
				
			||||||
	SPA_PARAM_Route,		/**< routing configuration as SPA_TYPE_OBJECT_ParamRoute */
 | 
						SPA_PARAM_Route,		/**< routing configuration as SPA_TYPE_OBJECT_ParamRoute */
 | 
				
			||||||
	SPA_PARAM_Control,		/**< Control parameter, a SPA_TYPE_Sequence */
 | 
						SPA_PARAM_Control,		/**< Control parameter, a SPA_TYPE_Sequence */
 | 
				
			||||||
	SPA_PARAM_Latency,		/**< latency reporting, a SPA_TYPE_OBJECT_ParamLatency */
 | 
						SPA_PARAM_Latency,		/**< latency reporting, a SPA_TYPE_OBJECT_ParamLatency */
 | 
				
			||||||
 | 
						SPA_PARAM_ProcessLatency,	/**< processing latency, a SPA_TYPE_OBJECT_ParamProcessLatency */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** information about a parameter */
 | 
					/** information about a parameter */
 | 
				
			||||||
| 
						 | 
					@ -185,6 +186,14 @@ enum spa_param_latency {
 | 
				
			||||||
	SPA_PARAM_LATENCY_maxNs,		/**< max latency (Long) in nanoseconds */
 | 
						SPA_PARAM_LATENCY_maxNs,		/**< max latency (Long) in nanoseconds */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** properties for SPA_TYPE_OBJECT_ParamProcessLatency */
 | 
				
			||||||
 | 
					enum spa_param_process_latency {
 | 
				
			||||||
 | 
						SPA_PARAM_PROCESS_LATENCY_START,
 | 
				
			||||||
 | 
						SPA_PARAM_PROCESS_LATENCY_quantum,	/**< latency relative to quantum (Float) */
 | 
				
			||||||
 | 
						SPA_PARAM_PROCESS_LATENCY_rate,		/**< latency (Int) relative to rate */
 | 
				
			||||||
 | 
						SPA_PARAM_PROCESS_LATENCY_ns,		/**< latency (Long) in nanoseconds */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \}
 | 
					 * \}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,7 @@ static const struct spa_type_info spa_type_param[] = {
 | 
				
			||||||
	{ SPA_PARAM_Route, SPA_TYPE_OBJECT_ParamRoute, SPA_TYPE_INFO_PARAM_ID_BASE "Route", NULL },
 | 
						{ SPA_PARAM_Route, SPA_TYPE_OBJECT_ParamRoute, SPA_TYPE_INFO_PARAM_ID_BASE "Route", NULL },
 | 
				
			||||||
	{ SPA_PARAM_Control, SPA_TYPE_Sequence, SPA_TYPE_INFO_PARAM_ID_BASE "Control", NULL },
 | 
						{ SPA_PARAM_Control, SPA_TYPE_Sequence, SPA_TYPE_INFO_PARAM_ID_BASE "Control", NULL },
 | 
				
			||||||
	{ SPA_PARAM_Latency, SPA_TYPE_OBJECT_ParamLatency, SPA_TYPE_INFO_PARAM_ID_BASE "Latency", NULL },
 | 
						{ SPA_PARAM_Latency, SPA_TYPE_OBJECT_ParamLatency, SPA_TYPE_INFO_PARAM_ID_BASE "Latency", NULL },
 | 
				
			||||||
 | 
						{ SPA_PARAM_ProcessLatency, SPA_TYPE_OBJECT_ParamProcessLatency, SPA_TYPE_INFO_PARAM_ID_BASE "ProcessLatency", NULL },
 | 
				
			||||||
	{ 0, 0, NULL, NULL },
 | 
						{ 0, 0, NULL, NULL },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -385,7 +386,7 @@ static const struct spa_type_info spa_type_profiler[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SPA_TYPE_INFO_PARAM_Latency		SPA_TYPE_INFO_PARAM_BASE "Latency"
 | 
					#define SPA_TYPE_INFO_PARAM_Latency		SPA_TYPE_INFO_PARAM_BASE "Latency"
 | 
				
			||||||
#define SPA_TYPE_INFO_PARAM_LATENCY_BASE		SPA_TYPE_INFO_PARAM_Latency ":"
 | 
					#define SPA_TYPE_INFO_PARAM_LATENCY_BASE	SPA_TYPE_INFO_PARAM_Latency ":"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct spa_type_info spa_type_param_latency[] = {
 | 
					static const struct spa_type_info spa_type_param_latency[] = {
 | 
				
			||||||
	{ SPA_PARAM_LATENCY_START, SPA_TYPE_Id, SPA_TYPE_INFO_PARAM_LATENCY_BASE, spa_type_param, },
 | 
						{ SPA_PARAM_LATENCY_START, SPA_TYPE_Id, SPA_TYPE_INFO_PARAM_LATENCY_BASE, spa_type_param, },
 | 
				
			||||||
| 
						 | 
					@ -399,6 +400,17 @@ static const struct spa_type_info spa_type_param_latency[] = {
 | 
				
			||||||
	{ 0, 0, NULL, NULL },
 | 
						{ 0, 0, NULL, NULL },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SPA_TYPE_INFO_PARAM_ProcessLatency		SPA_TYPE_INFO_PARAM_BASE "ProcessLatency"
 | 
				
			||||||
 | 
					#define SPA_TYPE_INFO_PARAM_PROCESS_LATENCY_BASE	SPA_TYPE_INFO_PARAM_ProcessLatency ":"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct spa_type_info spa_type_param_process_latency[] = {
 | 
				
			||||||
 | 
						{ SPA_PARAM_PROCESS_LATENCY_START, SPA_TYPE_Id, SPA_TYPE_INFO_PARAM_LATENCY_BASE, spa_type_param, },
 | 
				
			||||||
 | 
						{ SPA_PARAM_PROCESS_LATENCY_quantum, SPA_TYPE_Float, SPA_TYPE_INFO_PARAM_PROCESS_LATENCY_BASE "quantum", NULL, },
 | 
				
			||||||
 | 
						{ SPA_PARAM_PROCESS_LATENCY_rate, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_PROCESS_LATENCY_BASE "rate", NULL, },
 | 
				
			||||||
 | 
						{ SPA_PARAM_PROCESS_LATENCY_ns, SPA_TYPE_Long, SPA_TYPE_INFO_PARAM_PROCESS_LATENCY_BASE "ns", NULL, },
 | 
				
			||||||
 | 
						{ 0, 0, NULL, NULL },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \}
 | 
					 * \}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,6 +124,7 @@ static const struct spa_type_info spa_types[] = {
 | 
				
			||||||
	{ SPA_TYPE_OBJECT_ParamRoute, SPA_TYPE_Object, SPA_TYPE_INFO_PARAM_Route, spa_type_param_route },
 | 
						{ SPA_TYPE_OBJECT_ParamRoute, SPA_TYPE_Object, SPA_TYPE_INFO_PARAM_Route, spa_type_param_route },
 | 
				
			||||||
	{ SPA_TYPE_OBJECT_Profiler, SPA_TYPE_Object, SPA_TYPE_INFO_Profiler, spa_type_profiler },
 | 
						{ SPA_TYPE_OBJECT_Profiler, SPA_TYPE_Object, SPA_TYPE_INFO_Profiler, spa_type_profiler },
 | 
				
			||||||
	{ SPA_TYPE_OBJECT_ParamLatency, SPA_TYPE_Object, SPA_TYPE_INFO_PARAM_Latency, spa_type_param_latency },
 | 
						{ SPA_TYPE_OBJECT_ParamLatency, SPA_TYPE_Object, SPA_TYPE_INFO_PARAM_Latency, spa_type_param_latency },
 | 
				
			||||||
 | 
						{ SPA_TYPE_OBJECT_ParamProcessLatency, SPA_TYPE_Object, SPA_TYPE_INFO_PARAM_ProcessLatency, spa_type_param_process_latency },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ 0, 0, NULL, NULL }
 | 
						{ 0, 0, NULL, NULL }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,6 +96,7 @@ enum {
 | 
				
			||||||
	SPA_TYPE_OBJECT_ParamRoute,
 | 
						SPA_TYPE_OBJECT_ParamRoute,
 | 
				
			||||||
	SPA_TYPE_OBJECT_Profiler,
 | 
						SPA_TYPE_OBJECT_Profiler,
 | 
				
			||||||
	SPA_TYPE_OBJECT_ParamLatency,
 | 
						SPA_TYPE_OBJECT_ParamLatency,
 | 
				
			||||||
 | 
						SPA_TYPE_OBJECT_ParamProcessLatency,
 | 
				
			||||||
	_SPA_TYPE_OBJECT_LAST,			/**< not part of ABI */
 | 
						_SPA_TYPE_OBJECT_LAST,			/**< not part of ABI */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* vendor extensions */
 | 
						/* vendor extensions */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,9 @@
 | 
				
			||||||
#include <math.h>
 | 
					#include <math.h>
 | 
				
			||||||
#include <signal.h>
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <spa/pod/builder.h>
 | 
				
			||||||
 | 
					#include <spa/param/latency-utils.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <pipewire/pipewire.h>
 | 
					#include <pipewire/pipewire.h>
 | 
				
			||||||
#include <pipewire/filter.h>
 | 
					#include <pipewire/filter.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,6 +90,9 @@ static void do_quit(void *userdata, int signal_number)
 | 
				
			||||||
int main(int argc, char *argv[])
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct data data = { 0, };
 | 
						struct data data = { 0, };
 | 
				
			||||||
 | 
						const struct spa_pod *params[1];
 | 
				
			||||||
 | 
						uint8_t buffer[1024];
 | 
				
			||||||
 | 
						struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_init(&argc, &argv);
 | 
						pw_init(&argc, &argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,11 +144,18 @@ int main(int argc, char *argv[])
 | 
				
			||||||
				NULL),
 | 
									NULL),
 | 
				
			||||||
			NULL, 0);
 | 
								NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params[0] = spa_process_latency_build(&b,
 | 
				
			||||||
 | 
								SPA_PARAM_ProcessLatency,
 | 
				
			||||||
 | 
								&SPA_PROCESS_LATENCY_INFO_INIT(
 | 
				
			||||||
 | 
									.ns = 10 * SPA_NSEC_PER_MSEC
 | 
				
			||||||
 | 
								));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Now connect this filter. We ask that our process function is
 | 
						/* Now connect this filter. We ask that our process function is
 | 
				
			||||||
	 * called in a realtime thread. */
 | 
						 * called in a realtime thread. */
 | 
				
			||||||
	if (pw_filter_connect(data.filter,
 | 
						if (pw_filter_connect(data.filter,
 | 
				
			||||||
				PW_FILTER_FLAG_RT_PROCESS,
 | 
									PW_FILTER_FLAG_RT_PROCESS,
 | 
				
			||||||
				NULL, 0) < 0) {
 | 
									params, 1) < 0) {
 | 
				
			||||||
		fprintf(stderr, "can't connect\n");
 | 
							fprintf(stderr, "can't connect\n");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -147,10 +147,13 @@ struct filter {
 | 
				
			||||||
	uint32_t change_mask_all;
 | 
						uint32_t change_mask_all;
 | 
				
			||||||
	struct spa_node_info info;
 | 
						struct spa_node_info info;
 | 
				
			||||||
	struct spa_list param_list;
 | 
						struct spa_list param_list;
 | 
				
			||||||
#define IDX_Props	0
 | 
					#define IDX_Props		0
 | 
				
			||||||
#define N_NODE_PARAMS	1
 | 
					#define IDX_ProcessLatency	1
 | 
				
			||||||
 | 
					#define N_NODE_PARAMS		2
 | 
				
			||||||
	struct spa_param_info params[N_NODE_PARAMS];
 | 
						struct spa_param_info params[N_NODE_PARAMS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct spa_process_latency_info process_latency;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct data data;
 | 
						struct data data;
 | 
				
			||||||
	uintptr_t seq;
 | 
						uintptr_t seq;
 | 
				
			||||||
	struct pw_time time;
 | 
						struct pw_time time;
 | 
				
			||||||
| 
						 | 
					@ -173,6 +176,8 @@ static int get_param_index(uint32_t id)
 | 
				
			||||||
	switch (id) {
 | 
						switch (id) {
 | 
				
			||||||
	case SPA_PARAM_Props:
 | 
						case SPA_PARAM_Props:
 | 
				
			||||||
		return IDX_Props;
 | 
							return IDX_Props;
 | 
				
			||||||
 | 
						case SPA_PARAM_ProcessLatency:
 | 
				
			||||||
 | 
							return IDX_ProcessLatency;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -236,6 +241,8 @@ static struct param *add_param(struct filter *impl, struct port *port,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (id == SPA_PARAM_ProcessLatency && port == NULL)
 | 
				
			||||||
 | 
							spa_process_latency_parse(param, &impl->process_latency);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->id = id;
 | 
						p->id = id;
 | 
				
			||||||
	p->flags = flags;
 | 
						p->flags = flags;
 | 
				
			||||||
| 
						 | 
					@ -732,6 +739,9 @@ static int default_latency(struct filter *impl, struct port *port, enum spa_dire
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		spa_latency_info_combine(&info, &p->latency[direction]);
 | 
							spa_latency_info_combine(&info, &p->latency[direction]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_process_latency_info_add(&impl->process_latency, &info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_list_for_each(p, &impl->port_list, link) {
 | 
						spa_list_for_each(p, &impl->port_list, link) {
 | 
				
			||||||
		uint8_t buffer[4096];
 | 
							uint8_t buffer[4096];
 | 
				
			||||||
		struct spa_pod_builder b;
 | 
							struct spa_pod_builder b;
 | 
				
			||||||
| 
						 | 
					@ -1431,6 +1441,7 @@ pw_filter_connect(struct pw_filter *filter,
 | 
				
			||||||
	impl->info.flags = impl->process_rt ? SPA_NODE_FLAG_RT : 0;
 | 
						impl->info.flags = impl->process_rt ? SPA_NODE_FLAG_RT : 0;
 | 
				
			||||||
	impl->info.props = &filter->properties->dict;
 | 
						impl->info.props = &filter->properties->dict;
 | 
				
			||||||
	impl->params[IDX_Props] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_WRITE);
 | 
						impl->params[IDX_Props] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_WRITE);
 | 
				
			||||||
 | 
						impl->params[IDX_ProcessLatency] = SPA_PARAM_INFO(SPA_PARAM_ProcessLatency, SPA_PARAM_INFO_WRITE);
 | 
				
			||||||
	impl->info.params = impl->params;
 | 
						impl->info.params = impl->params;
 | 
				
			||||||
	impl->info.n_params = N_NODE_PARAMS;
 | 
						impl->info.n_params = N_NODE_PARAMS;
 | 
				
			||||||
	impl->info.change_mask = impl->change_mask_all;
 | 
						impl->info.change_mask = impl->change_mask_all;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue