mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-06-13 14:33:03 -04:00
audioconvert: allocate port buffers dynamically
The port buffer table was embedded in struct port as a fixed array buffers[MAX_BUFFERS] of struct buffer, each holding datas[MAX_DATAS] (MAX_DATAS == SPA_AUDIO_MAX_CHANNELS == 64). This reserved ~17 KB per port regardless of the actual buffer/channel count, multiplied by every active port. Allocate the buffer table and the per-buffer data-pointer pool in a single calloc in port_use_buffers(), sized to the real number of buffers and blocks, and release it in clear_buffers(). free_dir() now clears each port so the allocation (and any mmapped buffer data) is released on node destruction. This mirrors the dynamic-allocation approach already used for the channelmix matrices and preserves a lot of memory in the common low-channel-count case. Co-authored-by: Copilot copilot@github.com
This commit is contained in:
parent
b5555cc3f6
commit
65a5fa0250
1 changed files with 28 additions and 7 deletions
|
|
@ -140,7 +140,7 @@ struct buffer {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
struct spa_list link;
|
struct spa_list link;
|
||||||
struct spa_buffer *buf;
|
struct spa_buffer *buf;
|
||||||
void *datas[MAX_DATAS];
|
void **datas;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct port {
|
struct port {
|
||||||
|
|
@ -162,7 +162,7 @@ struct port {
|
||||||
struct spa_param_info params[N_PORT_PARAMS];
|
struct spa_param_info params[N_PORT_PARAMS];
|
||||||
char position[16];
|
char position[16];
|
||||||
|
|
||||||
struct buffer buffers[MAX_BUFFERS];
|
struct buffer *buffers;
|
||||||
uint32_t n_buffers;
|
uint32_t n_buffers;
|
||||||
|
|
||||||
struct spa_latency_info latency[2];
|
struct spa_latency_info latency[2];
|
||||||
|
|
@ -3051,6 +3051,8 @@ static int clear_buffers(struct impl *this, struct port *port)
|
||||||
SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_MAPPED);
|
SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_MAPPED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(port->buffers);
|
||||||
|
port->buffers = NULL;
|
||||||
port->n_buffers = 0;
|
port->n_buffers = 0;
|
||||||
spa_list_init(&port->queue);
|
spa_list_init(&port->queue);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -3351,6 +3353,21 @@ impl_node_port_use_buffers(void *object,
|
||||||
|
|
||||||
maxsize = this->quantum_limit * sizeof(float);
|
maxsize = this->quantum_limit * sizeof(float);
|
||||||
|
|
||||||
|
if (n_buffers > 0) {
|
||||||
|
void **datas;
|
||||||
|
size_t buffers_size = n_buffers * sizeof(struct buffer);
|
||||||
|
|
||||||
|
port->buffers = calloc(1, buffers_size +
|
||||||
|
n_buffers * port->blocks * sizeof(void*));
|
||||||
|
if (port->buffers == NULL) {
|
||||||
|
res = -errno;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
datas = SPA_PTROFF(port->buffers, buffers_size, void*);
|
||||||
|
for (i = 0; i < n_buffers; i++)
|
||||||
|
port->buffers[i].datas = &datas[i * port->blocks];
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < n_buffers; i++) {
|
for (i = 0; i < n_buffers; i++) {
|
||||||
struct buffer *b;
|
struct buffer *b;
|
||||||
uint32_t n_datas = buffers[i]->n_datas;
|
uint32_t n_datas = buffers[i]->n_datas;
|
||||||
|
|
@ -4336,11 +4353,15 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_dir(struct dir *dir)
|
static void free_dir(struct impl *this, struct dir *dir)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for (i = 0; i < MAX_PORTS; i++)
|
for (i = 0; i < MAX_PORTS; i++) {
|
||||||
free(dir->ports[i]);
|
if (dir->ports[i] != NULL) {
|
||||||
|
clear_buffers(this, dir->ports[i]);
|
||||||
|
free(dir->ports[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (dir->conv.free)
|
if (dir->conv.free)
|
||||||
convert_free(&dir->conv);
|
convert_free(&dir->conv);
|
||||||
free(dir->tag);
|
free(dir->tag);
|
||||||
|
|
@ -4355,8 +4376,8 @@ static int impl_clear(struct spa_handle *handle)
|
||||||
|
|
||||||
this = (struct impl *) handle;
|
this = (struct impl *) handle;
|
||||||
|
|
||||||
free_dir(&this->dir[SPA_DIRECTION_INPUT]);
|
free_dir(this, &this->dir[SPA_DIRECTION_INPUT]);
|
||||||
free_dir(&this->dir[SPA_DIRECTION_OUTPUT]);
|
free_dir(this, &this->dir[SPA_DIRECTION_OUTPUT]);
|
||||||
|
|
||||||
free_tmp(this);
|
free_tmp(this);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue