mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
audioconvert: handle realloc errors
The original pointer is untouched when realloc fails and returns NULL so make sure we free the previous values.
This commit is contained in:
parent
d8c73ebede
commit
48e11c6fe0
1 changed files with 52 additions and 15 deletions
|
|
@ -2445,6 +2445,53 @@ static inline void dequeue_buffer(struct impl *this, struct port *port, struct b
|
|||
SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_QUEUED);
|
||||
}
|
||||
|
||||
static void free_tmp(struct impl *this)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
spa_log_warn(this->log, "free tmp %d", this->empty_size);
|
||||
|
||||
free(this->empty);
|
||||
this->empty = NULL;
|
||||
this->empty_size = 0;
|
||||
free(this->scratch);
|
||||
this->scratch = NULL;
|
||||
free(this->tmp[0]);
|
||||
this->tmp[0] = NULL;
|
||||
free(this->tmp[1]);
|
||||
this->tmp[1] = NULL;
|
||||
for (i = 0; i < MAX_PORTS; i++) {
|
||||
this->tmp_datas[0][i] = NULL;
|
||||
this->tmp_datas[1][i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int ensure_tmp(struct impl *this, uint32_t maxsize)
|
||||
{
|
||||
if (maxsize > this->empty_size) {
|
||||
float *empty, *scratch, *tmp[2];
|
||||
|
||||
spa_log_warn(this->log, "resize tmp %d -> %d", this->empty_size, maxsize);
|
||||
|
||||
if ((empty = realloc(this->empty, maxsize + MAX_ALIGN)) != NULL)
|
||||
this->empty = empty;
|
||||
if ((scratch = realloc(this->scratch, maxsize + MAX_ALIGN)) != NULL)
|
||||
this->scratch = scratch;
|
||||
if ((tmp[0] = realloc(this->tmp[0], (maxsize + MAX_ALIGN) * MAX_PORTS)) != NULL)
|
||||
this->tmp[0] = tmp[0];
|
||||
if ((tmp[1] = realloc(this->tmp[1], (maxsize + MAX_ALIGN) * MAX_PORTS)) != NULL)
|
||||
this->tmp[1] = tmp[1];
|
||||
|
||||
if (empty == NULL || scratch == NULL || tmp[0] == NULL || tmp[1] == NULL) {
|
||||
free_tmp(this);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(this->empty, 0, maxsize + MAX_ALIGN);
|
||||
this->empty_size = maxsize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
impl_node_port_use_buffers(void *object,
|
||||
enum spa_direction direction,
|
||||
|
|
@ -2456,6 +2503,7 @@ impl_node_port_use_buffers(void *object,
|
|||
struct impl *this = object;
|
||||
struct port *port;
|
||||
uint32_t i, j, maxsize;
|
||||
int res;
|
||||
|
||||
spa_return_val_if_fail(this != NULL, -EINVAL);
|
||||
|
||||
|
|
@ -2512,17 +2560,9 @@ impl_node_port_use_buffers(void *object,
|
|||
if (direction == SPA_DIRECTION_OUTPUT)
|
||||
queue_buffer(this, port, i);
|
||||
}
|
||||
if (maxsize > this->empty_size) {
|
||||
this->empty = realloc(this->empty, maxsize + MAX_ALIGN);
|
||||
this->scratch = realloc(this->scratch, maxsize + MAX_ALIGN);
|
||||
this->tmp[0] = realloc(this->tmp[0], (maxsize + MAX_ALIGN) * MAX_PORTS);
|
||||
this->tmp[1] = realloc(this->tmp[1], (maxsize + MAX_ALIGN) * MAX_PORTS);
|
||||
if (this->empty == NULL || this->scratch == NULL ||
|
||||
this->tmp[0] == NULL || this->tmp[1] == NULL)
|
||||
return -errno;
|
||||
memset(this->empty, 0, maxsize + MAX_ALIGN);
|
||||
this->empty_size = maxsize;
|
||||
}
|
||||
if ((res = ensure_tmp(this, maxsize)) < 0)
|
||||
return res;
|
||||
|
||||
port->n_buffers = n_buffers;
|
||||
|
||||
return 0;
|
||||
|
|
@ -3250,10 +3290,7 @@ static int impl_clear(struct spa_handle *handle)
|
|||
free_dir(&this->dir[SPA_DIRECTION_INPUT]);
|
||||
free_dir(&this->dir[SPA_DIRECTION_OUTPUT]);
|
||||
|
||||
free(this->empty);
|
||||
free(this->scratch);
|
||||
free(this->tmp[0]);
|
||||
free(this->tmp[1]);
|
||||
free_tmp(this);
|
||||
|
||||
if (this->resample.free)
|
||||
resample_free(&this->resample);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue