mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-06 13:30:01 -05:00
node: add port and node params
Add a new struct spa_param_info that lists the available params on a node/port and if they are readable/writable/updated. We can use this to replace and improve the PARAM_List and also to notify property change and updates. Update elements and code to deal with this new param stuff. Add port and node info to most elements and signal changes. Use async enum_params in -inspect and use the param info to know which ones to enumerate. Use the port info to know what parameters to update in the remote-node.
This commit is contained in:
parent
3d25adc598
commit
499dd3ff22
52 changed files with 1979 additions and 1461 deletions
|
|
@ -31,6 +31,7 @@
|
|||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
#include <spa/node/utils.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/param.h>
|
||||
#include <spa/pod/filter.h>
|
||||
|
|
@ -76,6 +77,7 @@ struct port {
|
|||
struct spa_io_buffers *io;
|
||||
struct spa_io_sequence *control;
|
||||
struct spa_port_info info;
|
||||
struct spa_param_info params[8];
|
||||
|
||||
bool have_format;
|
||||
struct spa_audio_info format;
|
||||
|
|
@ -98,18 +100,20 @@ struct impl {
|
|||
struct spa_log *log;
|
||||
struct spa_cpu *cpu;
|
||||
|
||||
struct props props;
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *user_data;
|
||||
|
||||
struct spa_node_info info;
|
||||
struct props props;
|
||||
struct spa_param_info params[8];
|
||||
|
||||
bool started;
|
||||
|
||||
struct port in_port;
|
||||
struct port out_port;
|
||||
|
||||
bool started;
|
||||
|
||||
uint32_t cpu_flags;
|
||||
channelmix_func_t convert;
|
||||
uint32_t cpu_flags;
|
||||
uint32_t n_matrix;
|
||||
float matrix[4096];
|
||||
};
|
||||
|
|
@ -457,19 +461,6 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
|
|||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_PARAM_PropInfo,
|
||||
SPA_PARAM_Props };
|
||||
|
||||
if (result.index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamList, id,
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index]));
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case SPA_PARAM_PropInfo:
|
||||
{
|
||||
struct props *p = &this->props;
|
||||
|
|
@ -592,6 +583,14 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void emit_info(struct impl *this)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->info && this->info.change_mask) {
|
||||
this->callbacks->info(this->user_data, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_port_info(struct impl *this, struct port *port)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->port_info && port->info.change_mask) {
|
||||
|
|
@ -614,20 +613,22 @@ impl_node_set_callbacks(struct spa_node *node,
|
|||
this->callbacks = callbacks;
|
||||
this->user_data = user_data;
|
||||
|
||||
emit_info(this);
|
||||
emit_port_info(this, GET_IN_PORT(this, 0));
|
||||
emit_port_info(this, GET_OUT_PORT(this, 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_node_add_port(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
|
||||
static int impl_node_add_port(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id,
|
||||
const struct spa_dict *props)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint32_t port_id)
|
||||
static int impl_node_remove_port(struct spa_node *node,
|
||||
enum spa_direction direction, uint32_t port_id)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
|
@ -703,22 +704,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_PARAM_EnumFormat,
|
||||
SPA_PARAM_Format,
|
||||
SPA_PARAM_Buffers,
|
||||
SPA_PARAM_Meta,
|
||||
SPA_PARAM_IO };
|
||||
|
||||
if (result.index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamList, id,
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index]));
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case SPA_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id,
|
||||
result.index, ¶m, &b)) <= 0)
|
||||
|
|
@ -764,9 +749,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
break;
|
||||
}
|
||||
case SPA_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (result.index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
|
|
@ -870,6 +852,15 @@ static int port_set_format(struct spa_node *node,
|
|||
|
||||
spa_log_debug(this->log, NAME " %p: set format on port %d %d", this, port_id, res);
|
||||
}
|
||||
if (port->have_format) {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
} else {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
}
|
||||
emit_port_info(this, port);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1206,6 +1197,14 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this->cpu_flags = spa_cpu_get_flags(this->cpu);
|
||||
|
||||
this->node = impl_node;
|
||||
this->info = SPA_NODE_INFO_INIT();
|
||||
this->info.change_mask = SPA_NODE_CHANGE_MASK_FLAGS;
|
||||
this->info.flags = SPA_NODE_FLAG_RT;
|
||||
this->params[0] = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ);
|
||||
this->params[1] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE);
|
||||
this->info.params = this->params;
|
||||
this->info.n_params = 2;
|
||||
props_reset(&this->props);
|
||||
|
||||
port = GET_OUT_PORT(this, 0);
|
||||
port->direction = SPA_DIRECTION_OUTPUT;
|
||||
|
|
@ -1213,6 +1212,13 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
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[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
port->info.params = port->params;
|
||||
port->info.n_params = 5;
|
||||
spa_list_init(&port->queue);
|
||||
|
||||
port = GET_IN_PORT(this, 0);
|
||||
|
|
@ -1221,10 +1227,15 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
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[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
port->info.params = port->params;
|
||||
port->info.n_params = 0;
|
||||
spa_list_init(&port->queue);
|
||||
|
||||
props_reset(&this->props);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
#include <spa/node/utils.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/param.h>
|
||||
#include <spa/pod/filter.h>
|
||||
|
|
@ -79,8 +80,7 @@ struct port {
|
|||
struct spa_io_range *ctrl;
|
||||
|
||||
struct spa_port_info info;
|
||||
struct spa_dict info_props;
|
||||
struct spa_dict_item info_props_items[2];
|
||||
struct spa_param_info params[8];
|
||||
|
||||
bool have_format;
|
||||
struct spa_audio_info format;
|
||||
|
|
@ -103,7 +103,9 @@ struct impl {
|
|||
struct spa_log *log;
|
||||
struct spa_cpu *cpu;
|
||||
|
||||
struct spa_node_info info;
|
||||
struct props props;
|
||||
struct spa_param_info params[8];
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *user_data;
|
||||
|
|
@ -227,9 +229,22 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void emit_info(struct impl *this)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->info && this->info.change_mask) {
|
||||
this->callbacks->info(this->user_data, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_port_info(struct impl *this, struct port *port)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->port_info && port->info.change_mask) {
|
||||
struct spa_dict_item items[1];
|
||||
|
||||
items[0] = SPA_DICT_ITEM_INIT("port.dsp", "32 bit float mono audio");
|
||||
port->info.props = &SPA_DICT_INIT_ARRAY(items);
|
||||
|
||||
this->callbacks->port_info(this->user_data, port->direction, port->id, &port->info);
|
||||
port->info.change_mask = 0;
|
||||
}
|
||||
|
|
@ -249,6 +264,7 @@ impl_node_set_callbacks(struct spa_node *node,
|
|||
this->callbacks = callbacks;
|
||||
this->user_data = user_data;
|
||||
|
||||
emit_info(this);
|
||||
emit_port_info(this, GET_IN_PORT(this, 0));
|
||||
emit_port_info(this, GET_OUT_PORT(this, 0));
|
||||
|
||||
|
|
@ -388,22 +404,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_PARAM_EnumFormat,
|
||||
SPA_PARAM_Format,
|
||||
SPA_PARAM_Buffers,
|
||||
SPA_PARAM_Meta,
|
||||
SPA_PARAM_IO };
|
||||
|
||||
if (result.index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamList, id,
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index]));
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case SPA_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id,
|
||||
result.index, ¶m, &b)) <= 0)
|
||||
|
|
@ -451,9 +451,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
break;
|
||||
}
|
||||
case SPA_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (result.index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
|
|
@ -582,6 +579,13 @@ static int port_set_format(struct spa_node *node,
|
|||
spa_log_debug(this->log, NAME " %p: set format on port %d %d %d",
|
||||
this, port_id, res, port->stride);
|
||||
}
|
||||
if (port->have_format) {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
} else {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -907,10 +911,13 @@ static int init_port(struct impl *this, enum spa_direction direction, uint32_t p
|
|||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_PROPS;
|
||||
port->info.flags = flags;
|
||||
|
||||
port->info_props_items[0] = SPA_DICT_ITEM_INIT("port.dsp", "32 bit float mono audio");
|
||||
port->info_props = SPA_DICT_INIT(port->info_props_items, 1);
|
||||
port->info.props = &port->info_props;
|
||||
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[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
port->info.params = port->params;
|
||||
port->info.n_params = 5;
|
||||
port->have_format = false;
|
||||
emit_port_info(this, port);
|
||||
|
||||
|
|
@ -957,11 +964,16 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
if (this->cpu)
|
||||
this->cpu_flags = spa_cpu_get_flags(this->cpu);
|
||||
|
||||
this->info = SPA_NODE_INFO_INIT();
|
||||
this->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
this->info.flags = SPA_NODE_FLAG_RT;
|
||||
this->info.params = this->params;
|
||||
this->info.n_params = 0;
|
||||
props_reset(&this->props);
|
||||
|
||||
init_port(this, SPA_DIRECTION_OUTPUT, 0, SPA_PORT_FLAG_CAN_USE_BUFFERS);
|
||||
init_port(this, SPA_DIRECTION_INPUT, 0, SPA_PORT_FLAG_CAN_USE_BUFFERS);
|
||||
|
||||
props_reset(&this->props);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
#include <spa/node/utils.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/param.h>
|
||||
#include <spa/pod/filter.h>
|
||||
|
|
@ -62,8 +63,7 @@ struct port {
|
|||
struct spa_io_range *ctrl;
|
||||
|
||||
struct spa_port_info info;
|
||||
struct spa_dict info_props;
|
||||
struct spa_dict_item info_props_items[3];
|
||||
struct spa_param_info params[8];
|
||||
char position[16];
|
||||
|
||||
bool have_format;
|
||||
|
|
@ -86,6 +86,9 @@ struct impl {
|
|||
struct spa_log *log;
|
||||
struct spa_cpu *cpu;
|
||||
|
||||
struct spa_node_info info;
|
||||
struct spa_param_info params[8];
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *user_data;
|
||||
|
||||
|
|
@ -117,17 +120,24 @@ struct impl {
|
|||
|
||||
static void emit_node_info(struct impl *this)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->info) {
|
||||
struct spa_node_info info = SPA_NODE_INFO_INIT();
|
||||
info.max_input_ports = MAX_PORTS;
|
||||
info.max_output_ports = MAX_PORTS+1;
|
||||
info.change_mask = 0;
|
||||
this->callbacks->info(this->user_data, &info);
|
||||
if (this->callbacks && this->callbacks->info && this->info.change_mask) {
|
||||
this->callbacks->info(this->user_data, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
}
|
||||
}
|
||||
static void emit_port_info(struct impl *this, struct port *port)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->port_info && port->info.change_mask) {
|
||||
struct spa_dict_item items[3];
|
||||
uint32_t n_items = 0;
|
||||
|
||||
if (port->info.change_mask & SPA_PORT_CHANGE_MASK_PROPS) {
|
||||
items[n_items++] = SPA_DICT_ITEM_INIT("port.dsp", "32 bit float mono audio");
|
||||
items[n_items++] = SPA_DICT_ITEM_INIT("port.channel", port->position);
|
||||
if (port->direction == SPA_DIRECTION_OUTPUT)
|
||||
items[n_items++] = SPA_DICT_ITEM_INIT("port.monitor", "1");
|
||||
port->info.props = &SPA_DICT_INIT(items, n_items);
|
||||
}
|
||||
this->callbacks->port_info(this->user_data, port->direction, port->id, &port->info);
|
||||
port->info.change_mask = 0;
|
||||
}
|
||||
|
|
@ -137,7 +147,6 @@ static int init_port(struct impl *this, enum spa_direction direction, uint32_t p
|
|||
uint32_t rate, uint32_t position)
|
||||
{
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
int n_items = 0;
|
||||
|
||||
port->direction = direction;
|
||||
port->id = port_id;
|
||||
|
|
@ -145,14 +154,17 @@ static int init_port(struct impl *this, enum spa_direction direction, uint32_t p
|
|||
snprintf(port->position, 16, "%s", rindex(spa_type_audio_channel[position].name, ':')+1);
|
||||
|
||||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_PROPS;
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
port->info_props_items[n_items++] = SPA_DICT_ITEM_INIT("port.dsp", "32 bit float mono audio");
|
||||
port->info_props_items[n_items++] = SPA_DICT_ITEM_INIT("port.channel", port->position);
|
||||
if (direction == SPA_DIRECTION_OUTPUT)
|
||||
port->info_props_items[n_items++] = SPA_DICT_ITEM_INIT("port.monitor", "1");
|
||||
port->info_props = SPA_DICT_INIT(port->info_props_items, n_items);
|
||||
port->info.props = &port->info_props;
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
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[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
port->info.params = port->params;
|
||||
port->info.n_params = 5;
|
||||
|
||||
port->n_buffers = 0;
|
||||
port->have_format = false;
|
||||
|
|
@ -195,18 +207,8 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
|
|||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_PARAM_Profile };
|
||||
|
||||
if (result.index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamList, id,
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index]));
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case SPA_PARAM_Profile:
|
||||
return -ENOTSUP;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -440,22 +442,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_PARAM_EnumFormat,
|
||||
SPA_PARAM_Format,
|
||||
SPA_PARAM_Buffers,
|
||||
SPA_PARAM_Meta,
|
||||
SPA_PARAM_IO, };
|
||||
|
||||
if (result.index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamList, id,
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index]));
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case SPA_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id, result.index, ¶m, &b)) <= 0)
|
||||
return res;
|
||||
|
|
@ -486,9 +472,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
|
||||
break;
|
||||
case SPA_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (result.index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
|
|
@ -669,6 +652,14 @@ static int port_set_format(struct spa_node *node,
|
|||
|
||||
port->have_format = true;
|
||||
}
|
||||
if (port->have_format) {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
} else {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
}
|
||||
emit_port_info(this, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1066,12 +1057,30 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
|
||||
this->node = impl_node;
|
||||
|
||||
this->info = SPA_NODE_INFO_INIT();
|
||||
this->info.max_input_ports = MAX_PORTS;
|
||||
this->info.max_output_ports = MAX_PORTS+1;
|
||||
this->info.change_mask = SPA_NODE_CHANGE_MASK_FLAGS;
|
||||
this->info.flags = SPA_NODE_FLAG_RT;
|
||||
this->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
|
||||
this->params[0] = SPA_PARAM_INFO(SPA_PARAM_Profile, SPA_PARAM_INFO_WRITE);
|
||||
this->info.params = this->params;
|
||||
this->info.n_params = 1;
|
||||
|
||||
port = GET_OUT_PORT(this, 0);
|
||||
port->direction = SPA_DIRECTION_OUTPUT;
|
||||
port->id = 0;
|
||||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
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[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
port->info.params = port->params;
|
||||
port->info.n_params = 5;
|
||||
spa_list_init(&port->queue);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <spa/utils/list.h>
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/io.h>
|
||||
#include <spa/node/utils.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/param.h>
|
||||
#include <spa/pod/filter.h>
|
||||
|
|
@ -75,6 +76,7 @@ struct port {
|
|||
struct spa_io_range *io_range;
|
||||
struct spa_io_sequence *io_control;
|
||||
struct spa_port_info info;
|
||||
struct spa_param_info params[8];
|
||||
|
||||
bool have_format;
|
||||
struct spa_audio_info format;
|
||||
|
|
@ -96,6 +98,7 @@ struct impl {
|
|||
struct spa_log *log;
|
||||
struct spa_cpu *cpu;
|
||||
|
||||
struct spa_node_info info;
|
||||
struct props props;
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
|
|
@ -172,8 +175,8 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
|
|||
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
||||
switch (prop->key) {
|
||||
case SPA_PROP_rate:
|
||||
spa_pod_get_double(&prop->value, &p->rate);
|
||||
resample_update_rate(&this->resample, p->rate);
|
||||
if (spa_pod_get_double(&prop->value, &p->rate) == 0)
|
||||
resample_update_rate(&this->resample, p->rate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -230,6 +233,14 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void emit_node_info(struct impl *this)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->info && this->info.change_mask) {
|
||||
this->callbacks->info(this->user_data, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_port_info(struct impl *this, struct port *port)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->port_info && port->info.change_mask) {
|
||||
|
|
@ -252,6 +263,7 @@ impl_node_set_callbacks(struct spa_node *node,
|
|||
this->callbacks = callbacks;
|
||||
this->user_data = user_data;
|
||||
|
||||
emit_node_info(this);
|
||||
emit_port_info(this, GET_IN_PORT(this, 0));
|
||||
emit_port_info(this, GET_OUT_PORT(this, 0));
|
||||
|
||||
|
|
@ -349,22 +361,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_PARAM_EnumFormat,
|
||||
SPA_PARAM_Format,
|
||||
SPA_PARAM_Buffers,
|
||||
SPA_PARAM_Meta,
|
||||
SPA_PARAM_IO };
|
||||
|
||||
if (result.index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamList, id,
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index]));
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case SPA_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id,
|
||||
result.index, ¶m, &b)) <= 0)
|
||||
|
|
@ -409,9 +405,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
break;
|
||||
}
|
||||
case SPA_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (result.index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
|
|
@ -513,6 +506,16 @@ static int port_set_format(struct spa_node *node,
|
|||
|
||||
spa_log_debug(this->log, NAME " %p: set format on port %d %d", this, port_id, res);
|
||||
}
|
||||
|
||||
if (port->have_format) {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
} else {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
}
|
||||
emit_port_info(this, port);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -888,12 +891,24 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
|
||||
this->node = impl_node;
|
||||
|
||||
this->info = SPA_NODE_INFO_INIT();
|
||||
this->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
this->info.flags = SPA_NODE_FLAG_RT;
|
||||
|
||||
port = GET_OUT_PORT(this, 0);
|
||||
port->direction = SPA_DIRECTION_OUTPUT;
|
||||
port->id = 0;
|
||||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
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[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
port->info.params = port->params;
|
||||
port->info.n_params = 5;
|
||||
spa_list_init(&port->queue);
|
||||
|
||||
port = GET_IN_PORT(this, 0);
|
||||
|
|
@ -902,6 +917,14 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
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[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
port->info.params = port->params;
|
||||
port->info.n_params = 5;
|
||||
spa_list_init(&port->queue);
|
||||
|
||||
props_reset(&this->props);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ struct port {
|
|||
struct spa_io_range *ctrl;
|
||||
|
||||
struct spa_port_info info;
|
||||
struct spa_param_info params[8];
|
||||
|
||||
struct spa_dict info_props;
|
||||
struct spa_dict_item info_props_items[2];
|
||||
char position[8];
|
||||
|
|
@ -88,6 +90,9 @@ struct impl {
|
|||
struct spa_log *log;
|
||||
struct spa_cpu *cpu;
|
||||
|
||||
struct spa_node_info info;
|
||||
struct spa_param_info params[8];
|
||||
|
||||
const struct spa_node_callbacks *callbacks;
|
||||
void *user_data;
|
||||
|
||||
|
|
@ -113,12 +118,9 @@ struct impl {
|
|||
|
||||
static void emit_node_info(struct impl *this)
|
||||
{
|
||||
if (this->callbacks && this->callbacks->info) {
|
||||
struct spa_node_info info = SPA_NODE_INFO_INIT();
|
||||
info.max_input_ports = 1;
|
||||
info.max_output_ports = MAX_PORTS;
|
||||
info.change_mask = 0;
|
||||
this->callbacks->info(this->user_data, &info);
|
||||
if (this->callbacks && this->callbacks->info && this->info.change_mask) {
|
||||
this->callbacks->info(this->user_data, &this->info);
|
||||
this->info.change_mask = 0;
|
||||
}
|
||||
}
|
||||
static void emit_port_info(struct impl *this, struct port *port)
|
||||
|
|
@ -140,13 +142,25 @@ static int init_port(struct impl *this, enum spa_direction direction,
|
|||
snprintf(port->position, 7, "%s", rindex(spa_type_audio_channel[position].name, ':')+1);
|
||||
|
||||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_PROPS;
|
||||
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
||||
port->info_props_items[0] = SPA_DICT_ITEM_INIT("port.dsp", "32 bit float mono audio");
|
||||
port->info_props_items[1] = SPA_DICT_ITEM_INIT("port.channel", port->position);
|
||||
port->info_props = SPA_DICT_INIT(port->info_props_items, 2);
|
||||
port->info.props = &port->info_props;
|
||||
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
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[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
port->info.params = port->params;
|
||||
port->info.n_params = 5;
|
||||
|
||||
spa_list_init(&port->queue);
|
||||
|
||||
port->n_buffers = 0;
|
||||
|
|
@ -190,18 +204,6 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
|
|||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_PARAM_Profile };
|
||||
|
||||
if (result.index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamList, id,
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index]));
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -431,22 +433,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_List:
|
||||
{
|
||||
uint32_t list[] = { SPA_PARAM_EnumFormat,
|
||||
SPA_PARAM_Format,
|
||||
SPA_PARAM_Buffers,
|
||||
SPA_PARAM_Meta,
|
||||
SPA_PARAM_IO };
|
||||
|
||||
if (result.index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamList, id,
|
||||
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index]));
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case SPA_PARAM_EnumFormat:
|
||||
if ((res = port_enum_formats(node, direction, port_id,
|
||||
result.index, ¶m, &b)) <= 0)
|
||||
|
|
@ -479,9 +465,6 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
|
|||
break;
|
||||
|
||||
case SPA_PARAM_Meta:
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
|
||||
switch (result.index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
|
|
@ -645,6 +628,14 @@ static int port_set_format(struct spa_node *node,
|
|||
|
||||
port->have_format = true;
|
||||
}
|
||||
if (port->have_format) {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
} else {
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
}
|
||||
emit_port_info(this, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -993,13 +984,30 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
this->cpu_flags = spa_cpu_get_flags(this->cpu);
|
||||
|
||||
this->node = impl_node;
|
||||
this->info = SPA_NODE_INFO_INIT();
|
||||
this->info.max_input_ports = 1;
|
||||
this->info.max_output_ports = MAX_PORTS;
|
||||
this->info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS;
|
||||
this->info.flags = SPA_NODE_FLAG_RT;
|
||||
this->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
|
||||
this->params[0] = SPA_PARAM_INFO(SPA_PARAM_Profile, SPA_PARAM_INFO_WRITE);
|
||||
this->info.params = this->params;
|
||||
this->info.n_params = 1;
|
||||
|
||||
port = GET_IN_PORT(this, 0);
|
||||
port->direction = SPA_DIRECTION_INPUT;
|
||||
port->id = 0;
|
||||
port->info = SPA_PORT_INFO_INIT();
|
||||
port->info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
port->info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
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[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||
port->info.params = port->params;
|
||||
port->info.n_params = 5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue