spa: do not use SPA_PROP_live

Remove support for changing `SPA_PROP_live` in node implementations
that supported it, and hard-code `SPA_PROP_live = true`. If a mode
of operation is desired where the data is processed as fast as possible,
it can be achieved by implementing non-driver operation and using the
freewheel driver in pipewire.
This commit is contained in:
Barnabás Pőcze 2026-03-27 11:22:24 +01:00
parent 00b4717c6e
commit 7f4baba41c
5 changed files with 73 additions and 316 deletions

View file

@ -41,13 +41,11 @@ enum wave_type {
#define DEFAULT_RATE 48000 #define DEFAULT_RATE 48000
#define DEFAULT_CHANNELS 2 #define DEFAULT_CHANNELS 2
#define DEFAULT_LIVE true
#define DEFAULT_WAVE WAVE_SINE #define DEFAULT_WAVE WAVE_SINE
#define DEFAULT_FREQ 440.0 #define DEFAULT_FREQ 440.0
#define DEFAULT_VOLUME 1.0 #define DEFAULT_VOLUME 1.0
struct props { struct props {
bool live;
uint32_t wave; uint32_t wave;
float freq; float freq;
float volume; float volume;
@ -55,7 +53,6 @@ struct props {
static void reset_props(struct props *props) static void reset_props(struct props *props)
{ {
props->live = DEFAULT_LIVE;
props->wave = DEFAULT_WAVE; props->wave = DEFAULT_WAVE;
props->freq = DEFAULT_FREQ; props->freq = DEFAULT_FREQ;
props->volume = DEFAULT_VOLUME; props->volume = DEFAULT_VOLUME;
@ -160,13 +157,6 @@ static int impl_node_enum_params(void *object, int seq,
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_live),
SPA_PROP_INFO_description, SPA_POD_String("Configure live mode of the source"),
SPA_PROP_INFO_type, SPA_POD_Bool(p->live));
break;
case 1:
spa_pod_builder_push_object(&b, &f[0], SPA_TYPE_OBJECT_PropInfo, id); spa_pod_builder_push_object(&b, &f[0], SPA_TYPE_OBJECT_PropInfo, id);
spa_pod_builder_add(&b, spa_pod_builder_add(&b,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_waveType), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_waveType),
@ -182,14 +172,14 @@ static int impl_node_enum_params(void *object, int seq,
spa_pod_builder_pop(&b, &f[1]); spa_pod_builder_pop(&b, &f[1]);
param = spa_pod_builder_pop(&b, &f[0]); param = spa_pod_builder_pop(&b, &f[0]);
break; break;
case 2: case 1:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_frequency), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_frequency),
SPA_PROP_INFO_description, SPA_POD_String("Select the frequency"), SPA_PROP_INFO_description, SPA_POD_String("Select the frequency"),
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(p->freq, 0.0, 50000000.0)); SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(p->freq, 0.0, 50000000.0));
break; break;
case 3: case 2:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id, SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_volume), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_volume),
@ -209,7 +199,6 @@ static int impl_node_enum_params(void *object, int seq,
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id, SPA_TYPE_OBJECT_Props, id,
SPA_PROP_live, SPA_POD_Bool(p->live),
SPA_PROP_waveType, SPA_POD_Int(p->wave), SPA_PROP_waveType, SPA_POD_Int(p->wave),
SPA_PROP_frequency, SPA_POD_Float(p->freq), SPA_PROP_frequency, SPA_POD_Float(p->freq),
SPA_PROP_volume, SPA_POD_Float(p->volume)); SPA_PROP_volume, SPA_POD_Float(p->volume));
@ -263,7 +252,6 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
if (id == SPA_PARAM_Props) { if (id == SPA_PARAM_Props) {
struct props *p = &this->props; struct props *p = &this->props;
struct port *port = &this->port;
if (param == NULL) { if (param == NULL) {
reset_props(p); reset_props(p);
@ -271,15 +259,9 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
} }
spa_pod_parse_object(param, spa_pod_parse_object(param,
SPA_TYPE_OBJECT_Props, NULL, SPA_TYPE_OBJECT_Props, NULL,
SPA_PROP_live, SPA_POD_OPT_Bool(&p->live),
SPA_PROP_waveType, SPA_POD_OPT_Int(&p->wave), SPA_PROP_waveType, SPA_POD_OPT_Int(&p->wave),
SPA_PROP_frequency, SPA_POD_OPT_Float(&p->freq), SPA_PROP_frequency, SPA_POD_OPT_Float(&p->freq),
SPA_PROP_volume, SPA_POD_OPT_Float(&p->volume)); SPA_PROP_volume, SPA_POD_OPT_Float(&p->volume));
if (p->live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
else
port->info.flags &= ~SPA_PORT_FLAG_LIVE;
} }
else else
return -ENOENT; return -ENOENT;
@ -314,23 +296,15 @@ static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
static void set_timer(struct impl *this, bool enabled) static void set_timer(struct impl *this, bool enabled)
{ {
if (this->props.live) { struct itimerspec ts = {0};
struct itimerspec ts = {0};
if (enabled) { if (enabled) {
if (this->props.live) { uint64_t next_time = this->start_time + this->elapsed_time;
uint64_t next_time = this->start_time + this->elapsed_time; ts.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC;
ts.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC; ts.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
ts.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
} else {
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 1;
}
}
spa_system_timerfd_settime(this->data_system,
this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
} }
spa_system_timerfd_settime(this->data_system, this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
} }
static int read_timer(struct impl *this) static int read_timer(struct impl *this)
@ -338,14 +312,12 @@ static int read_timer(struct impl *this)
uint64_t expirations; uint64_t expirations;
int res = 0; int res = 0;
if (this->props.live) { if ((res = spa_system_timerfd_read(this->data_system, this->timer_source.fd, &expirations)) < 0) {
if ((res = spa_system_timerfd_read(this->data_system, if (res != -EAGAIN)
this->timer_source.fd, &expirations)) < 0) { spa_log_error(this->log, "%p: timerfd error: %s",
if (res != -EAGAIN) this, spa_strerror(res));
spa_log_error(this->log, "%p: timerfd error: %s",
this, spa_strerror(res));
}
} }
return 0; return 0;
} }
@ -469,10 +441,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
return 0; return 0;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
if (this->props.live) this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
else
this->start_time = 0;
this->sample_count = 0; this->sample_count = 0;
this->elapsed_time = 0; this->elapsed_time = 0;
@ -893,9 +862,6 @@ static inline void reuse_buffer(struct impl *this, struct port *port, uint32_t i
b->outstanding = false; b->outstanding = false;
spa_list_append(&port->empty, &b->link); spa_list_append(&port->empty, &b->link);
if (!this->props.live && !this->following)
set_timer(this, true);
} }
static int impl_node_port_reuse_buffer(void *object, uint32_t port_id, uint32_t buffer_id) static int impl_node_port_reuse_buffer(void *object, uint32_t port_id, uint32_t buffer_id)
@ -969,7 +935,7 @@ static int impl_node_process(void *object)
io->buffer_id = SPA_ID_INVALID; io->buffer_id = SPA_ID_INVALID;
} }
if (!this->props.live || this->following) if (this->following)
return make_buffer(this); return make_buffer(this);
else else
return SPA_STATUS_OK; return SPA_STATUS_OK;
@ -1111,9 +1077,7 @@ impl_init(const struct spa_handle_factory *factory,
port->info_all = SPA_PORT_CHANGE_MASK_FLAGS | port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
SPA_PORT_CHANGE_MASK_PARAMS; SPA_PORT_CHANGE_MASK_PARAMS;
port->info = SPA_PORT_INFO_INIT(); port->info = SPA_PORT_INFO_INIT();
port->info.flags = SPA_PORT_FLAG_NO_REF; port->info.flags = SPA_PORT_FLAG_NO_REF | SPA_PORT_FLAG_LIVE;
if (this->props.live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
port->params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); port->params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
port->params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); port->params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
port->params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ); port->params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);

View file

@ -26,10 +26,6 @@
#define SPA_LOG_TOPIC_DEFAULT &log_topic #define SPA_LOG_TOPIC_DEFAULT &log_topic
SPA_LOG_TOPIC_DEFINE_STATIC(log_topic, "spa.fakesink"); SPA_LOG_TOPIC_DEFINE_STATIC(log_topic, "spa.fakesink");
struct props {
bool live;
};
#define MAX_BUFFERS 16 #define MAX_BUFFERS 16
#define MAX_PORTS 1 #define MAX_PORTS 1
@ -68,7 +64,6 @@ struct impl {
uint64_t info_all; uint64_t info_all;
struct spa_node_info info; struct spa_node_info info;
struct spa_param_info params[1]; struct spa_param_info params[1];
struct props props;
struct spa_hook_list hooks; struct spa_hook_list hooks;
struct spa_callbacks callbacks; struct spa_callbacks callbacks;
@ -86,13 +81,6 @@ struct impl {
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS) #define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS)
#define DEFAULT_LIVE false
static void reset_props(struct impl *this, struct props *props)
{
props->live = DEFAULT_LIVE;
}
static int impl_node_enum_params(void *object, int seq, static int impl_node_enum_params(void *object, int seq,
uint32_t id, uint32_t start, uint32_t num, uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter) const struct spa_pod *filter)
@ -115,14 +103,6 @@ static int impl_node_enum_params(void *object, int seq,
spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) { switch (id) {
case SPA_PARAM_Props:
if (result.index > 0)
return 0;
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
SPA_PROP_live, SPA_POD_Bool(this->props.live));
break;
default: default:
return -ENOENT; return -ENOENT;
} }
@ -150,26 +130,7 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);
switch (id) { switch (id) {
case SPA_PARAM_Props:
{
struct port *port = &this->port;
if (param == NULL) {
reset_props(this, &this->props);
return 0;
}
spa_pod_parse_object(param,
SPA_TYPE_OBJECT_Props, NULL,
SPA_PROP_live, SPA_POD_OPT_Bool(&this->props.live));
if (this->props.live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
else
port->info.flags &= ~SPA_PORT_FLAG_LIVE;
break;
}
default: default:
return -ENOENT; return -ENOENT;
} }
@ -178,23 +139,15 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
static void set_timer(struct impl *this, bool enabled) static void set_timer(struct impl *this, bool enabled)
{ {
if (this->callbacks.funcs || this->props.live) { struct itimerspec ts = {0};
struct itimerspec ts = {0};
if (enabled) { if (enabled) {
if (this->props.live) { uint64_t next_time = this->start_time + this->elapsed_time;
uint64_t next_time = this->start_time + this->elapsed_time; ts.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC;
ts.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC; ts.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
ts.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
} else {
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 1;
}
}
spa_system_timerfd_settime(this->data_system,
this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
} }
spa_system_timerfd_settime(this->data_system, this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
} }
static inline int read_timer(struct impl *this) static inline int read_timer(struct impl *this)
@ -202,14 +155,12 @@ static inline int read_timer(struct impl *this)
uint64_t expirations; uint64_t expirations;
int res = 0; int res = 0;
if (this->callbacks.funcs || this->props.live) { if ((res = spa_system_timerfd_read(this->data_system, this->timer_source.fd, &expirations)) < 0) {
if ((res = spa_system_timerfd_read(this->data_system, if (res != -EAGAIN)
this->timer_source.fd, &expirations)) < 0) { spa_log_error(this->log, "%p: timerfd error: %s",
if (res != -EAGAIN) this, spa_strerror(res));
spa_log_error(this->log, "%p: timerfd error: %s",
this, spa_strerror(res));
}
} }
return res; return res;
} }
@ -297,10 +248,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
return 0; return 0;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
if (this->props.live) this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
else
this->start_time = 0;
this->buffer_count = 0; this->buffer_count = 0;
this->elapsed_time = 0; this->elapsed_time = 0;
@ -650,10 +598,8 @@ static int impl_node_process(void *object)
io->buffer_id = SPA_ID_INVALID; io->buffer_id = SPA_ID_INVALID;
io->status = SPA_STATUS_OK; io->status = SPA_STATUS_OK;
} }
if (this->callbacks.funcs == NULL)
return consume_buffer(this); return SPA_STATUS_OK;
else
return SPA_STATUS_OK;
} }
static const struct spa_node_methods impl_node = { static const struct spa_node_methods impl_node = {
@ -757,8 +703,6 @@ impl_init(const struct spa_handle_factory *factory,
this->params[0] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE); this->params[0] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE);
this->info.params = this->params; this->info.params = this->params;
this->info.n_params = 1; this->info.n_params = 1;
reset_props(this, &this->props);
this->timer_source.func = on_input; this->timer_source.func = on_input;
this->timer_source.data = this; this->timer_source.data = this;
@ -774,9 +718,7 @@ impl_init(const struct spa_handle_factory *factory,
port->info_all = SPA_PORT_CHANGE_MASK_FLAGS | port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
SPA_PORT_CHANGE_MASK_PARAMS; SPA_PORT_CHANGE_MASK_PARAMS;
port->info = SPA_PORT_INFO_INIT(); port->info = SPA_PORT_INFO_INIT();
port->info.flags = SPA_PORT_FLAG_NO_REF; port->info.flags = SPA_PORT_FLAG_NO_REF | SPA_PORT_FLAG_LIVE;
if (this->props.live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
port->params[0] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); port->params[0] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
port->params[1] = SPA_PARAM_INFO(SPA_PARAM_IO, 0); port->params[1] = SPA_PARAM_INFO(SPA_PARAM_IO, 0);
port->params[2] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); port->params[2] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);

View file

@ -27,7 +27,6 @@
SPA_LOG_TOPIC_DEFINE_STATIC(log_topic, "spa.fakesrc"); SPA_LOG_TOPIC_DEFINE_STATIC(log_topic, "spa.fakesrc");
struct props { struct props {
bool live;
uint32_t pattern; uint32_t pattern;
}; };
@ -88,12 +87,10 @@ struct impl {
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) < MAX_PORTS) #define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) < MAX_PORTS)
#define DEFAULT_LIVE false
#define DEFAULT_PATTERN 0 #define DEFAULT_PATTERN 0
static void reset_props(struct impl *this, struct props *props) static void reset_props(struct impl *this, struct props *props)
{ {
props->live = DEFAULT_LIVE;
props->pattern = DEFAULT_PATTERN; props->pattern = DEFAULT_PATTERN;
} }
@ -128,7 +125,6 @@ static int impl_node_enum_params(void *object, int seq,
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id, SPA_TYPE_OBJECT_Props, id,
SPA_PROP_live, SPA_POD_Bool(p->live),
SPA_PROP_patternType, SPA_POD_CHOICE_ENUM_Int(2, p->pattern, p->pattern)); SPA_PROP_patternType, SPA_POD_CHOICE_ENUM_Int(2, p->pattern, p->pattern));
break; break;
} }
@ -163,7 +159,6 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
case SPA_PARAM_Props: case SPA_PARAM_Props:
{ {
struct props *p = &this->props; struct props *p = &this->props;
struct port *port = &this->port;
if (param == NULL) { if (param == NULL) {
reset_props(this, p); reset_props(this, p);
@ -171,13 +166,7 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
} }
spa_pod_parse_object(param, spa_pod_parse_object(param,
SPA_TYPE_OBJECT_Props, NULL, SPA_TYPE_OBJECT_Props, NULL,
SPA_PROP_live, SPA_POD_OPT_Bool(&p->live),
SPA_PROP_patternType, SPA_POD_OPT_Int(&p->pattern)); SPA_PROP_patternType, SPA_POD_OPT_Int(&p->pattern));
if (p->live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
else
port->info.flags &= ~SPA_PORT_FLAG_LIVE;
break; break;
} }
default: default:
@ -193,23 +182,15 @@ static int fill_buffer(struct impl *this, struct buffer *b)
static void set_timer(struct impl *this, bool enabled) static void set_timer(struct impl *this, bool enabled)
{ {
if (this->callbacks.funcs || this->props.live) { struct itimerspec ts = {0};
struct itimerspec ts = {0};
if (enabled) { if (enabled) {
if (this->props.live) { uint64_t next_time = this->start_time + this->elapsed_time;
uint64_t next_time = this->start_time + this->elapsed_time; ts.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC;
ts.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC; ts.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
ts.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
} else {
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 1;
}
}
spa_system_timerfd_settime(this->data_system,
this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
} }
spa_system_timerfd_settime(this->data_system, this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
} }
static inline int read_timer(struct impl *this) static inline int read_timer(struct impl *this)
@ -217,14 +198,12 @@ static inline int read_timer(struct impl *this)
uint64_t expirations; uint64_t expirations;
int res = 0; int res = 0;
if (this->callbacks.funcs || this->props.live) { if ((res = spa_system_timerfd_read(this->data_system, this->timer_source.fd, &expirations)) < 0) {
if ((res = spa_system_timerfd_read(this->data_system, if (res != -EAGAIN)
this->timer_source.fd, &expirations)) < 0) { spa_log_error(this->log, "%p: timerfd error: %s",
if (res != -EAGAIN) this, spa_strerror(res));
spa_log_error(this->log, "%p: timerfd error: %s",
this, spa_strerror(res));
}
} }
return res; return res;
} }
@ -310,10 +289,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
return 0; return 0;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
if (this->props.live) this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
else
this->start_time = 0;
this->buffer_count = 0; this->buffer_count = 0;
this->elapsed_time = 0; this->elapsed_time = 0;
@ -681,10 +657,7 @@ static int impl_node_process(void *object)
io->buffer_id = SPA_ID_INVALID; io->buffer_id = SPA_ID_INVALID;
} }
if (this->callbacks.funcs == NULL) return SPA_STATUS_OK;
return make_buffer(this);
else
return SPA_STATUS_OK;
} }
static const struct spa_node_methods impl_node = { static const struct spa_node_methods impl_node = {
@ -804,9 +777,7 @@ impl_init(const struct spa_handle_factory *factory,
port->info_all = SPA_PORT_CHANGE_MASK_FLAGS | port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
SPA_PORT_CHANGE_MASK_PARAMS; SPA_PORT_CHANGE_MASK_PARAMS;
port->info = SPA_PORT_INFO_INIT(); port->info = SPA_PORT_INFO_INIT();
port->info.flags = SPA_PORT_FLAG_NO_REF; port->info.flags = SPA_PORT_FLAG_NO_REF | SPA_PORT_FLAG_LIVE;
if (this->props.live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
port->params[0] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); port->params[0] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
port->params[1] = SPA_PARAM_INFO(SPA_PARAM_IO, 0); port->params[1] = SPA_PARAM_INFO(SPA_PARAM_IO, 0);
port->params[2] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); port->params[2] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);

View file

@ -35,17 +35,14 @@ enum pattern {
PATTERN_SNOW, PATTERN_SNOW,
}; };
#define DEFAULT_LIVE true
#define DEFAULT_PATTERN PATTERN_SMPTE_SNOW #define DEFAULT_PATTERN PATTERN_SMPTE_SNOW
struct props { struct props {
bool live;
uint32_t pattern; uint32_t pattern;
}; };
static void reset_props(struct props *props) static void reset_props(struct props *props)
{ {
props->live = DEFAULT_LIVE;
props->pattern = DEFAULT_PATTERN; props->pattern = DEFAULT_PATTERN;
} }
@ -139,13 +136,6 @@ static int impl_node_enum_params(void *object, int seq,
switch (result.index) { switch (result.index) {
case 0: case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_live),
SPA_PROP_INFO_description, SPA_POD_String("Configure live mode of the source"),
SPA_PROP_INFO_type, SPA_POD_Bool(p->live));
break;
case 1:
spa_pod_builder_push_object(&b, &f[0], SPA_TYPE_OBJECT_PropInfo, id); spa_pod_builder_push_object(&b, &f[0], SPA_TYPE_OBJECT_PropInfo, id);
spa_pod_builder_add(&b, spa_pod_builder_add(&b,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_patternType), SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_patternType),
@ -174,7 +164,6 @@ static int impl_node_enum_params(void *object, int seq,
case 0: case 0:
param = spa_pod_builder_add_object(&b, param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id, SPA_TYPE_OBJECT_Props, id,
SPA_PROP_live, SPA_POD_Bool(p->live),
SPA_PROP_patternType, SPA_POD_Int(p->pattern)); SPA_PROP_patternType, SPA_POD_Int(p->pattern));
break; break;
default: default:
@ -229,7 +218,6 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
case SPA_PARAM_Props: case SPA_PARAM_Props:
{ {
struct props *p = &this->props; struct props *p = &this->props;
struct port *port = &this->port;
if (param == NULL) { if (param == NULL) {
reset_props(p); reset_props(p);
@ -237,13 +225,8 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
} }
spa_pod_parse_object(param, spa_pod_parse_object(param,
SPA_TYPE_OBJECT_Props, NULL, SPA_TYPE_OBJECT_Props, NULL,
SPA_PROP_live, SPA_POD_OPT_Bool(&p->live),
SPA_PROP_patternType, SPA_POD_OPT_Int(&p->pattern)); SPA_PROP_patternType, SPA_POD_OPT_Int(&p->pattern));
if (p->live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
else
port->info.flags &= ~SPA_PORT_FLAG_LIVE;
break; break;
} }
default: default:
@ -261,22 +244,15 @@ static int fill_buffer(struct impl *this, struct buffer *b)
static void set_timer(struct impl *this, bool enabled) static void set_timer(struct impl *this, bool enabled)
{ {
if (this->props.live) { struct timespec ts = {0};
struct timespec ts = {0};
if (enabled) { if (enabled) {
if (this->props.live) { uint64_t next_time = this->start_time + this->elapsed_time;
uint64_t next_time = this->start_time + this->elapsed_time; ts.tv_sec = next_time / SPA_NSEC_PER_SEC;
ts.tv_sec = next_time / SPA_NSEC_PER_SEC; ts.tv_nsec = next_time % SPA_NSEC_PER_SEC;
ts.tv_nsec = next_time % SPA_NSEC_PER_SEC;
} else {
ts.tv_sec = 0;
ts.tv_nsec = 1;
}
}
spa_loop_utils_update_timer(this->loop_utils, this->timer_source, &ts, NULL, true);
} }
spa_loop_utils_update_timer(this->loop_utils, this->timer_source, &ts, NULL, true);
} }
static int make_buffer(struct impl *this) static int make_buffer(struct impl *this)
@ -356,10 +332,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
return 0; return 0;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
if (this->props.live) this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
else
this->start_time = 0;
this->frame_count = 0; this->frame_count = 0;
this->elapsed_time = 0; this->elapsed_time = 0;
@ -753,9 +726,6 @@ static inline void reuse_buffer(struct impl *this, struct port *port, uint32_t i
b->outstanding = false; b->outstanding = false;
spa_list_append(&port->empty, &b->link); spa_list_append(&port->empty, &b->link);
if (!this->props.live)
set_timer(this, true);
} }
static int impl_node_port_reuse_buffer(void *object, uint32_t port_id, uint32_t buffer_id) static int impl_node_port_reuse_buffer(void *object, uint32_t port_id, uint32_t buffer_id)
@ -793,10 +763,7 @@ static int impl_node_process(void *object)
io->buffer_id = SPA_ID_INVALID; io->buffer_id = SPA_ID_INVALID;
} }
if (!this->props.live) return SPA_STATUS_OK;
return make_buffer(this);
else
return SPA_STATUS_OK;
} }
static const struct spa_node_methods impl_node = { static const struct spa_node_methods impl_node = {
@ -910,9 +877,7 @@ impl_init(const struct spa_handle_factory *factory,
port->info_all = SPA_PORT_CHANGE_MASK_FLAGS | port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
SPA_PORT_CHANGE_MASK_PARAMS; SPA_PORT_CHANGE_MASK_PARAMS;
port->info = SPA_PORT_INFO_INIT(); port->info = SPA_PORT_INFO_INIT();
port->info.flags = SPA_PORT_FLAG_NO_REF; port->info.flags = SPA_PORT_FLAG_NO_REF | SPA_PORT_FLAG_LIVE;
if (this->props.live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
port->params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); port->params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
port->params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); port->params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
port->params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ); port->params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);

View file

@ -33,17 +33,6 @@ SPA_LOG_TOPIC_DEFINE_STATIC(log_topic, "spa.vulkan.compute-source");
#define FRAMES_TO_TIME(this,f) ((this->position->video.framerate.denom * (f) * SPA_NSEC_PER_SEC) / \ #define FRAMES_TO_TIME(this,f) ((this->position->video.framerate.denom * (f) * SPA_NSEC_PER_SEC) / \
(this->position->video.framerate.num)) (this->position->video.framerate.num))
#define DEFAULT_LIVE true
struct props {
bool live;
};
static void reset_props(struct props *props)
{
props->live = DEFAULT_LIVE;
}
struct buffer { struct buffer {
uint32_t id; uint32_t id;
#define BUFFER_FLAG_OUT (1<<0) #define BUFFER_FLAG_OUT (1<<0)
@ -95,7 +84,6 @@ struct impl {
#define IDX_Props 1 #define IDX_Props 1
#define N_NODE_PARAMS 2 #define N_NODE_PARAMS 2
struct spa_param_info params[N_NODE_PARAMS]; struct spa_param_info params[N_NODE_PARAMS];
struct props props;
struct spa_hook_list hooks; struct spa_hook_list hooks;
struct spa_callbacks callbacks; struct spa_callbacks callbacks;
@ -136,38 +124,6 @@ static int impl_node_enum_params(void *object, int seq,
spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) { switch (id) {
case SPA_PARAM_PropInfo:
{
struct props *p = &this->props;
switch (result.index) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_live),
SPA_PROP_INFO_description, SPA_POD_String("Configure live mode of the source"),
SPA_PROP_INFO_type, SPA_POD_Bool(p->live));
break;
default:
return 0;
}
break;
}
case SPA_PARAM_Props:
{
struct props *p = &this->props;
switch (result.index) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
SPA_PROP_live, SPA_POD_Bool(p->live));
break;
default:
return 0;
}
break;
}
default: default:
return -ENOENT; return -ENOENT;
} }
@ -212,25 +168,6 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);
switch (id) { switch (id) {
case SPA_PARAM_Props:
{
struct props *p = &this->props;
struct port *port = &this->port;
if (param == NULL) {
reset_props(p);
return 0;
}
spa_pod_parse_object(param,
SPA_TYPE_OBJECT_Props, NULL,
SPA_PROP_live, SPA_POD_OPT_Bool(&p->live));
if (p->live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
else
port->info.flags &= ~SPA_PORT_FLAG_LIVE;
break;
}
default: default:
return -ENOENT; return -ENOENT;
} }
@ -240,23 +177,15 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
static void set_timer(struct impl *this, bool enabled) static void set_timer(struct impl *this, bool enabled)
{ {
if (this->props.live) { struct itimerspec ts = {0};
struct itimerspec ts = {0};
if (enabled) { if (enabled) {
if (this->props.live) { uint64_t next_time = this->start_time + this->elapsed_time;
uint64_t next_time = this->start_time + this->elapsed_time; ts.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC;
ts.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC; ts.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
ts.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
} else {
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 1;
}
}
spa_system_timerfd_settime(this->data_system,
this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
} }
spa_system_timerfd_settime(this->data_system, this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
} }
static int read_timer(struct impl *this) static int read_timer(struct impl *this)
@ -264,14 +193,12 @@ static int read_timer(struct impl *this)
uint64_t expirations; uint64_t expirations;
int res = 0; int res = 0;
if (this->props.live) { if ((res = spa_system_timerfd_read(this->data_system, this->timer_source.fd, &expirations)) < 0) {
if ((res = spa_system_timerfd_read(this->data_system, if (res != -EAGAIN)
this->timer_source.fd, &expirations)) < 0) { spa_log_error(this->log, "%p: timerfd error: %s",
if (res != -EAGAIN) this, spa_strerror(res));
spa_log_error(this->log, "%p: timerfd error: %s",
this, spa_strerror(res));
}
} }
return res; return res;
} }
@ -346,9 +273,6 @@ static inline void reuse_buffer(struct impl *this, struct port *port, uint32_t i
SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT); SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT);
spa_list_append(&port->empty, &b->link); spa_list_append(&port->empty, &b->link);
if (!this->props.live)
set_timer(this, true);
} }
} }
@ -407,10 +331,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
return 0; return 0;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
if (this->props.live) this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
this->start_time = SPA_TIMESPEC_TO_NSEC(&now);
else
this->start_time = 0;
this->frame_count = 0; this->frame_count = 0;
this->elapsed_time = 0; this->elapsed_time = 0;
@ -872,10 +793,7 @@ static int impl_node_process(void *object)
io->buffer_id = SPA_ID_INVALID; io->buffer_id = SPA_ID_INVALID;
} }
if (!this->props.live) return SPA_STATUS_OK;
return make_buffer(this);
else
return SPA_STATUS_OK;
} }
static const struct spa_node_methods impl_node = { static const struct spa_node_methods impl_node = {
@ -983,7 +901,6 @@ impl_init(const struct spa_handle_factory *factory,
this->params[IDX_Props] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE); this->params[IDX_Props] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE);
this->info.params = this->params; this->info.params = this->params;
this->info.n_params = N_NODE_PARAMS; this->info.n_params = N_NODE_PARAMS;
reset_props(&this->props);
this->timer_source.func = on_output; this->timer_source.func = on_output;
this->timer_source.data = this; this->timer_source.data = this;
@ -1000,9 +917,7 @@ impl_init(const struct spa_handle_factory *factory,
SPA_PORT_CHANGE_MASK_PARAMS | SPA_PORT_CHANGE_MASK_PARAMS |
SPA_PORT_CHANGE_MASK_PROPS; SPA_PORT_CHANGE_MASK_PROPS;
port->info = SPA_PORT_INFO_INIT(); port->info = SPA_PORT_INFO_INIT();
port->info.flags = SPA_PORT_FLAG_NO_REF; port->info.flags = SPA_PORT_FLAG_NO_REF | SPA_PORT_FLAG_LIVE;
if (this->props.live)
port->info.flags |= SPA_PORT_FLAG_LIVE;
port->params[IDX_EnumFormat] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); port->params[IDX_EnumFormat] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
port->params[IDX_Meta] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); port->params[IDX_Meta] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ); port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);