Param: add process latency param and info

This commit is contained in:
Wim Taymans 2021-06-22 16:10:13 +02:00
parent 8c77713a7b
commit 79866a93cd
7 changed files with 97 additions and 4 deletions

View file

@ -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

View file

@ -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 */
};
/** /**
* \} * \}
*/ */

View file

@ -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 },
}; };
@ -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 },
};
/** /**
* \} * \}
*/ */

View file

@ -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 }
}; };

View file

@ -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 */

View file

@ -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;
} }

View file

@ -148,9 +148,12 @@ struct filter {
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;