mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
Add port direction again
simplify port numbering again by using 0->max_ports for bot input ports and output ports. This means we need to tall what direction the port is. Add port_info serialize functions Copy metadata and data when we are not sharing buffers. Make pinossink work again.
This commit is contained in:
parent
b208e8b690
commit
d828073bb8
26 changed files with 1104 additions and 648 deletions
|
|
@ -73,9 +73,15 @@ struct _SpaAudioMixer {
|
|||
|
||||
int port_count;
|
||||
int port_queued;
|
||||
SpaAudioMixerPort ports[MAX_PORTS + 1];
|
||||
SpaAudioMixerPort in_ports[MAX_PORTS];
|
||||
SpaAudioMixerPort out_ports[1];
|
||||
};
|
||||
|
||||
#define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !this->in_ports[(p)].valid)
|
||||
#define CHECK_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && this->in_ports[(p)].valid)
|
||||
#define CHECK_OUT_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
|
||||
#define CHECK_PORT(this,d,p) (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p))
|
||||
|
||||
enum {
|
||||
PROP_ID_LAST,
|
||||
};
|
||||
|
|
@ -198,10 +204,10 @@ spa_audiomixer_node_get_n_ports (SpaNode *node,
|
|||
|
||||
if (n_input_ports)
|
||||
*n_input_ports = 0;
|
||||
if (n_output_ports)
|
||||
*n_output_ports = 1;
|
||||
if (max_input_ports)
|
||||
*max_input_ports = MAX_PORTS;
|
||||
if (n_output_ports)
|
||||
*n_output_ports = 1;
|
||||
if (max_output_ports)
|
||||
*max_output_ports = 1;
|
||||
|
||||
|
|
@ -225,18 +231,19 @@ spa_audiomixer_node_get_port_ids (SpaNode *node,
|
|||
|
||||
if (input_ids) {
|
||||
for (i = 0, idx = 0; i < MAX_PORTS && idx < n_input_ports; i++) {
|
||||
if (this->ports[i].valid)
|
||||
if (this->in_ports[i].valid)
|
||||
input_ids[idx++] = i;
|
||||
}
|
||||
}
|
||||
if (n_output_ports > 0 && output_ids)
|
||||
output_ids[0] = MAX_PORTS;
|
||||
output_ids[0] = 0;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_add_port (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id)
|
||||
{
|
||||
SpaAudioMixer *this;
|
||||
|
|
@ -246,28 +253,26 @@ spa_audiomixer_node_add_port (SpaNode *node,
|
|||
|
||||
this = (SpaAudioMixer *) node->handle;
|
||||
|
||||
if (port_id >= MAX_PORTS)
|
||||
if (!CHECK_FREE_IN_PORT (this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
if (this->ports[port_id].valid)
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
this->ports[port_id].valid = true;
|
||||
this->in_ports[port_id].valid = true;
|
||||
this->port_count++;
|
||||
|
||||
this->ports[port_id].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
|
||||
this->in_ports[port_id].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
|
||||
SPA_PORT_INFO_FLAG_REMOVABLE |
|
||||
SPA_PORT_INFO_FLAG_OPTIONAL |
|
||||
SPA_PORT_INFO_FLAG_IN_PLACE;
|
||||
this->ports[port_id].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
|
||||
this->in_ports[port_id].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
|
||||
|
||||
this->ports[MAX_PORTS].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_remove_port (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id)
|
||||
{
|
||||
SpaAudioMixer *this;
|
||||
|
|
@ -277,17 +282,17 @@ spa_audiomixer_node_remove_port (SpaNode *node,
|
|||
|
||||
this = (SpaAudioMixer *) node->handle;
|
||||
|
||||
if (port_id >= MAX_PORTS || !this->ports[port_id].valid)
|
||||
if (!CHECK_IN_PORT (this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
this->ports[port_id].valid = false;
|
||||
this->in_ports[port_id].valid = false;
|
||||
this->port_count--;
|
||||
if (this->ports[port_id].buffer) {
|
||||
this->ports[port_id].buffer = NULL;
|
||||
if (this->in_ports[port_id].buffer) {
|
||||
this->in_ports[port_id].buffer = NULL;
|
||||
this->port_queued--;
|
||||
}
|
||||
if (this->port_count == this->port_queued)
|
||||
this->ports[MAX_PORTS].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
this->out_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -295,6 +300,7 @@ spa_audiomixer_node_remove_port (SpaNode *node,
|
|||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_enum_formats (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
SpaFormat **format,
|
||||
const SpaFormat *filter,
|
||||
|
|
@ -309,10 +315,10 @@ spa_audiomixer_node_port_enum_formats (SpaNode *node,
|
|||
|
||||
this = (SpaAudioMixer *) node->handle;
|
||||
|
||||
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
|
||||
if (!CHECK_PORT (this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
port = &this->ports[port_id];
|
||||
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
|
||||
|
||||
index = (*state == NULL ? 0 : *(int*)state);
|
||||
|
||||
|
|
@ -333,6 +339,7 @@ spa_audiomixer_node_port_enum_formats (SpaNode *node,
|
|||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_set_format (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
SpaPortFormatFlags flags,
|
||||
const SpaFormat *format)
|
||||
|
|
@ -346,10 +353,10 @@ spa_audiomixer_node_port_set_format (SpaNode *node,
|
|||
|
||||
this = (SpaAudioMixer *) node->handle;
|
||||
|
||||
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
|
||||
if (!CHECK_PORT (this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
port = &this->ports[port_id];
|
||||
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
|
||||
|
||||
if (format == NULL) {
|
||||
port->have_format = false;
|
||||
|
|
@ -366,6 +373,7 @@ spa_audiomixer_node_port_set_format (SpaNode *node,
|
|||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_get_format (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
const SpaFormat **format)
|
||||
{
|
||||
|
|
@ -377,10 +385,10 @@ spa_audiomixer_node_port_get_format (SpaNode *node,
|
|||
|
||||
this = (SpaAudioMixer *) node->handle;
|
||||
|
||||
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
|
||||
if (!CHECK_PORT (this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
port = &this->ports[port_id];
|
||||
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
|
||||
|
||||
if (!port->have_format)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
|
@ -392,6 +400,7 @@ spa_audiomixer_node_port_get_format (SpaNode *node,
|
|||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_get_info (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
const SpaPortInfo **info)
|
||||
{
|
||||
|
|
@ -403,25 +412,27 @@ spa_audiomixer_node_port_get_info (SpaNode *node,
|
|||
|
||||
this = (SpaAudioMixer *) node->handle;
|
||||
|
||||
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
|
||||
if (!CHECK_PORT (this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
port = &this->ports[port_id];
|
||||
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
|
||||
*info = &port->info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_get_props (SpaNode *node,
|
||||
uint32_t port_id,
|
||||
SpaProps **props)
|
||||
spa_audiomixer_node_port_get_props (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
SpaProps **props)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_set_props (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
const SpaProps *props)
|
||||
{
|
||||
|
|
@ -430,6 +441,7 @@ spa_audiomixer_node_port_set_props (SpaNode *node,
|
|||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_use_buffers (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
SpaBuffer **buffers,
|
||||
uint32_t n_buffers)
|
||||
|
|
@ -439,6 +451,7 @@ spa_audiomixer_node_port_use_buffers (SpaNode *node,
|
|||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_alloc_buffers (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
SpaAllocParam **params,
|
||||
uint32_t n_params,
|
||||
|
|
@ -448,16 +461,9 @@ spa_audiomixer_node_port_alloc_buffers (SpaNode *node,
|
|||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_reuse_buffer (SpaNode *node,
|
||||
uint32_t port_id,
|
||||
uint32_t buffer_id)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_get_status (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
const SpaPortStatus **status)
|
||||
{
|
||||
|
|
@ -469,10 +475,10 @@ spa_audiomixer_node_port_get_status (SpaNode *node,
|
|||
|
||||
this = (SpaAudioMixer *) node->handle;
|
||||
|
||||
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
|
||||
if (!CHECK_PORT (this, direction, port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
port = &this->ports[port_id];
|
||||
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
|
||||
if (!port->have_format)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
||||
|
|
@ -495,7 +501,7 @@ spa_audiomixer_node_port_push_input (SpaNode *node,
|
|||
|
||||
this = (SpaAudioMixer *) node->handle;
|
||||
|
||||
if (this->ports[MAX_PORTS].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT)
|
||||
if (this->out_ports[0].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT)
|
||||
return SPA_RESULT_HAVE_ENOUGH_INPUT;
|
||||
|
||||
for (i = 0; i < n_info; i++) {
|
||||
|
|
@ -503,12 +509,12 @@ spa_audiomixer_node_port_push_input (SpaNode *node,
|
|||
SpaAudioMixerPort *port;
|
||||
int idx = info[i].port_id;
|
||||
|
||||
if (idx >= MAX_PORTS || !this->ports[idx].valid) {
|
||||
if (!CHECK_IN_PORT (this, SPA_DIRECTION_INPUT, idx)) {
|
||||
info[i].status = SPA_RESULT_INVALID_PORT;
|
||||
have_error = true;
|
||||
continue;
|
||||
}
|
||||
port = &this->ports[idx];
|
||||
port = &this->in_ports[idx];
|
||||
buffer = port->buffers[info[i].buffer_id];
|
||||
|
||||
if (buffer == NULL) {
|
||||
|
|
@ -524,19 +530,19 @@ spa_audiomixer_node_port_push_input (SpaNode *node,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (this->ports[idx].buffer != NULL) {
|
||||
if (port->buffer != NULL) {
|
||||
info[i].status = SPA_RESULT_HAVE_ENOUGH_INPUT;
|
||||
have_error = true;
|
||||
continue;
|
||||
}
|
||||
this->ports[idx].buffer = buffer;
|
||||
this->ports[idx].buffer_queued = 0;
|
||||
this->ports[idx].buffer_index = 0;
|
||||
this->ports[idx].buffer_offset = 0;
|
||||
port->buffer = buffer;
|
||||
port->buffer_queued = 0;
|
||||
port->buffer_index = 0;
|
||||
port->buffer_offset = 0;
|
||||
this->port_queued++;
|
||||
|
||||
if (this->port_queued == this->port_count)
|
||||
this->ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
this->out_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
}
|
||||
info[i].status = SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -592,7 +598,7 @@ add_port_data (SpaAudioMixer *this, SpaBuffer *out, SpaAudioMixerPort *port)
|
|||
if (++port->buffer_index == port->buffer->n_datas) {
|
||||
port->buffer = NULL;
|
||||
port->status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
|
||||
this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
break;
|
||||
}
|
||||
port->buffer_offset = 0;
|
||||
|
|
@ -623,37 +629,37 @@ mix_data (SpaAudioMixer *this, SpaPortOutputInfo *info)
|
|||
|
||||
min_size = 0;
|
||||
min_port = 0;
|
||||
for (i = 1; i < MAX_PORTS; i++) {
|
||||
if (!this->ports[i].valid)
|
||||
for (i = 0; i < MAX_PORTS; i++) {
|
||||
if (!this->in_ports[i].valid)
|
||||
continue;
|
||||
|
||||
if (this->ports[i].buffer == NULL) {
|
||||
if (this->in_ports[i].buffer == NULL) {
|
||||
if (pull_size && info->flags & SPA_PORT_OUTPUT_FLAG_PULL) {
|
||||
pull_port (this, i, info, pull_size);
|
||||
}
|
||||
if (this->ports[i].buffer == NULL)
|
||||
if (this->in_ports[i].buffer == NULL)
|
||||
return SPA_RESULT_NEED_MORE_INPUT;
|
||||
}
|
||||
|
||||
if (min_size == 0 || this->ports[i].buffer_queued < min_size) {
|
||||
min_size = this->ports[i].buffer_queued;
|
||||
if (min_size == 0 || this->in_ports[i].buffer_queued < min_size) {
|
||||
min_size = this->in_ports[i].buffer_queued;
|
||||
min_port = i;
|
||||
}
|
||||
}
|
||||
if (min_port == 0)
|
||||
return SPA_RESULT_NEED_MORE_INPUT;
|
||||
|
||||
buf = this->ports[min_port].buffer;
|
||||
buf = this->in_ports[min_port].buffer;
|
||||
info->buffer_id = buf->id;
|
||||
this->ports[min_port].buffer = NULL;
|
||||
this->ports[min_port].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
|
||||
this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
this->in_ports[min_port].buffer = NULL;
|
||||
this->in_ports[min_port].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
|
||||
this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
|
||||
|
||||
for (i = 1; i < MAX_PORTS; i++) {
|
||||
if (!this->ports[i].valid || this->ports[i].buffer == NULL)
|
||||
for (i = 0; i < MAX_PORTS; i++) {
|
||||
if (!this->in_ports[i].valid || this->in_ports[i].buffer == NULL)
|
||||
continue;
|
||||
|
||||
add_port_data (this, buf, &this->ports[i]);
|
||||
add_port_data (this, buf, &this->in_ports[i]);
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -673,10 +679,10 @@ spa_audiomixer_node_port_pull_output (SpaNode *node,
|
|||
|
||||
this = (SpaAudioMixer *) node->handle;
|
||||
|
||||
if (info->port_id != MAX_PORTS)
|
||||
if (!CHECK_OUT_PORT (this, SPA_DIRECTION_OUTPUT, info->port_id))
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
port = &this->ports[info->port_id];
|
||||
port = &this->out_ports[info->port_id];
|
||||
|
||||
if (!port->have_format)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
|
@ -697,8 +703,17 @@ spa_audiomixer_node_port_pull_output (SpaNode *node,
|
|||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_reuse_buffer (SpaNode *node,
|
||||
uint32_t port_id,
|
||||
uint32_t buffer_id)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_audiomixer_node_port_push_event (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
SpaNodeEvent *event)
|
||||
{
|
||||
|
|
@ -726,10 +741,10 @@ static const SpaNode audiomixer_node = {
|
|||
spa_audiomixer_node_port_set_props,
|
||||
spa_audiomixer_node_port_use_buffers,
|
||||
spa_audiomixer_node_port_alloc_buffers,
|
||||
spa_audiomixer_node_port_reuse_buffer,
|
||||
spa_audiomixer_node_port_get_status,
|
||||
spa_audiomixer_node_port_push_input,
|
||||
spa_audiomixer_node_port_pull_output,
|
||||
spa_audiomixer_node_port_reuse_buffer,
|
||||
spa_audiomixer_node_port_push_event,
|
||||
};
|
||||
|
||||
|
|
@ -781,10 +796,10 @@ spa_audiomixer_init (const SpaHandleFactory *factory,
|
|||
this->props[1].props.prop_info = prop_info;
|
||||
reset_audiomixer_props (&this->props[1]);
|
||||
|
||||
this->ports[MAX_PORTS].valid = true;
|
||||
this->ports[MAX_PORTS].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS |
|
||||
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
|
||||
SPA_PORT_INFO_FLAG_NO_REF;
|
||||
this->out_ports[0].valid = true;
|
||||
this->out_ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS |
|
||||
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
|
||||
SPA_PORT_INFO_FLAG_NO_REF;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue