fix use_buffers checks

We can set 0 buffers even if there is no format.
Return -ENOSPC when too many buffers are set.
This commit is contained in:
Wim Taymans 2023-01-10 12:30:25 +01:00
parent 9f3237b74e
commit 97aafe2234
31 changed files with 146 additions and 88 deletions

View file

@ -2219,7 +2219,7 @@ static int client_node_port_use_buffers(void *data,
if (n_buffers > MAX_BUFFERS) {
pw_log_error("%p: too many buffers %u > %u", c, n_buffers, MAX_BUFFERS);
return -EINVAL;
return -ENOSPC;
}
if (p->object->port.type_id == TYPE_ID_VIDEO && direction == SPA_DIRECTION_INPUT) {

View file

@ -731,6 +731,7 @@ impl_node_port_use_buffers(void *object,
{
struct state *this = object;
uint32_t i;
int res;
spa_return_val_if_fail(this != NULL, -EINVAL);
@ -738,14 +739,15 @@ impl_node_port_use_buffers(void *object,
spa_log_debug(this->log, "%p: use %d buffers", this, n_buffers);
if (!this->have_format)
return -EIO;
if (n_buffers == 0) {
if (this->n_buffers > 0) {
spa_alsa_pause(this);
clear_buffers(this);
return 0;
if ((res = clear_buffers(this)) < 0)
return res;
}
if (n_buffers > 0 && !this->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &this->buffers[i];

View file

@ -673,9 +673,6 @@ impl_node_port_use_buffers(void *object,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
if (!this->have_format)
return -EIO;
spa_log_debug(this->log, "%p: use %d buffers", this, n_buffers);
if (this->n_buffers > 0) {
@ -683,6 +680,11 @@ impl_node_port_use_buffers(void *object,
if ((res = clear_buffers(this)) < 0)
return res;
}
if (n_buffers > 0 && !this->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &this->buffers[i];
struct spa_data *d = buffers[i]->datas;

View file

@ -748,11 +748,13 @@ impl_node_port_use_buffers(void *object,
spa_log_debug(this->log, "%p: port %d.%d buffers:%d format:%d", this,
direction, port_id, n_buffers, port->have_format);
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &port->buffers[i];
struct spa_data *d = buffers[i]->datas;

View file

@ -2049,13 +2049,16 @@ impl_node_port_use_buffers(void *object,
port = GET_PORT(this, direction, port_id);
spa_return_val_if_fail(port->have_format, -EIO);
spa_log_debug(this->log, "%p: use buffers %d on port %d:%d",
this, n_buffers, direction, port_id);
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
maxsize = this->quantum_limit * sizeof(float);
for (i = 0; i < n_buffers; i++) {

View file

@ -649,10 +649,13 @@ impl_node_port_use_buffers(void *object,
port = GET_PORT(this, direction, port_id);
spa_return_val_if_fail(port->have_format, -EIO);
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;
struct spa_data *d = buffers[i]->datas;

View file

@ -586,10 +586,13 @@ impl_node_port_use_buffers(void *object,
port = GET_PORT(this, direction, port_id);
spa_return_val_if_fail(port->have_format, -EIO);
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;
struct spa_data *d = buffers[i]->datas;

View file

@ -829,11 +829,13 @@ impl_node_port_use_buffers(void *object,
port = &this->port;
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;
struct spa_data *d = buffers[i]->datas;

View file

@ -629,14 +629,14 @@ impl_node_port_use_buffers(void *object,
spa_log_debug(this->log, "%p: use %d buffers", this, n_buffers);
if (!port->have_format)
return -EIO;
if (n_buffers == 0) {
if (port->n_buffers > 0) {
spa_avb_pause(this);
clear_buffers(this, port);
return 0;
}
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &port->buffers[i];

View file

@ -629,14 +629,14 @@ impl_node_port_use_buffers(void *object,
spa_log_debug(this->log, "%p: use %d buffers", this, n_buffers);
if (!port->have_format)
return -EIO;
if (n_buffers == 0) {
if (port->n_buffers > 0) {
spa_avb_pause(this);
clear_buffers(this, port);
return 0;
}
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &port->buffers[i];

View file

@ -1453,11 +1453,13 @@ impl_node_port_use_buffers(void *object,
spa_log_debug(this->log, "use buffers %d", n_buffers);
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &port->buffers[i];

View file

@ -1202,11 +1202,13 @@ impl_node_port_use_buffers(void *object,
spa_log_debug(this->log, "use buffers %d", n_buffers);
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &port->buffers[i];
struct spa_data *d = buffers[i]->datas;

View file

@ -1186,11 +1186,13 @@ impl_node_port_use_buffers(void *object,
spa_log_debug(this->log, "use buffers %d", n_buffers);
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &port->buffers[i];

View file

@ -1155,11 +1155,13 @@ impl_node_port_use_buffers(void *object,
spa_log_debug(this->log, "use buffers %d", n_buffers);
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &port->buffers[i];
struct spa_data *d = buffers[i]->datas;

View file

@ -506,10 +506,13 @@ impl_node_port_use_buffers(void *object,
spa_log_debug(this->log, NAME " %p: use buffers %d on port %d:%d",
this, n_buffers, direction, port_id);
spa_return_val_if_fail(port->have_format, -EIO);
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;
struct spa_data *d = buffers[i]->datas;

View file

@ -693,11 +693,13 @@ impl_node_port_use_buffers(void *object,
port = GET_PORT(this, direction, port_id);
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;

View file

@ -693,11 +693,13 @@ impl_node_port_use_buffers(void *object,
port = GET_PORT(this, direction, port_id);
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;

View file

@ -774,14 +774,15 @@ static int impl_node_port_use_buffers(void *object,
port = GET_PORT(impl, direction, port_id);
if (!port->current_format)
return -EIO;
if (port->n_buffers) {
spa_libcamera_stream_off(impl);
if ((res = spa_libcamera_clear_buffers(impl, port)) < 0)
return res;
}
if (n_buffers > 0 && !port->current_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
if (buffers == NULL)
return 0;

View file

@ -685,11 +685,13 @@ impl_node_port_use_buffers(void *object,
port = &this->port;
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;
struct spa_data *d = buffers[i]->datas;

View file

@ -585,11 +585,13 @@ impl_node_port_use_buffers(void *object,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
port = &this->port;
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;
struct spa_data *d = buffers[i]->datas;

View file

@ -597,11 +597,13 @@ impl_node_port_use_buffers(void *object,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
port = &this->port;
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;
struct spa_data *d = buffers[i]->datas;

View file

@ -756,14 +756,15 @@ static int impl_node_port_use_buffers(void *object,
port = GET_PORT(this, direction, port_id);
if (!port->have_format)
return -EIO;
if (port->n_buffers) {
spa_v4l2_stream_off(this);
if ((res = spa_v4l2_clear_buffers(this)) < 0)
return res;
}
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
if (buffers == NULL)
return 0;

View file

@ -712,11 +712,13 @@ impl_node_port_use_buffers(void *object,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
port = &this->port;
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;
struct spa_data *d = buffers[i]->datas;

View file

@ -528,11 +528,13 @@ impl_node_port_use_buffers(void *object,
port = GET_PORT(this, direction, port_id);
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;
struct spa_data *d = buffers[i]->datas;

View file

@ -505,11 +505,13 @@ impl_node_port_use_buffers(void *object,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
port = &this->port[direction];
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;

View file

@ -740,11 +740,13 @@ impl_node_port_use_buffers(void *object,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
port = &this->port;
if (!port->have_format)
return -EIO;
clear_buffers(this, port);
if (n_buffers > 0 && !port->have_format)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b;

View file

@ -46,6 +46,7 @@
#define M_PI_M2 ( M_PI + M_PI )
#define BUFFER_SAMPLES 128
#define MAX_BUFFERS 32
struct buffer {
uint32_t id;
@ -79,7 +80,7 @@ struct data {
struct spa_audio_info_raw format;
struct buffer buffers[32];
struct buffer buffers[MAX_BUFFERS];
uint32_t n_buffers;
struct spa_list empty;
@ -325,6 +326,9 @@ static int impl_port_use_buffers(void *object,
struct data *d = object;
uint32_t i;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &d->buffers[i];
struct spa_data *datas = buffers[i]->datas;

View file

@ -34,6 +34,7 @@
#define WIDTH 640
#define HEIGHT 480
#define BPP 3
#define MAX_BUFFERS 32
#include "sdl.h"
@ -68,7 +69,7 @@ struct data {
struct spa_video_info_raw format;
int32_t stride;
struct spa_buffer *buffers[32];
struct spa_buffer *buffers[MAX_BUFFERS];
int n_buffers;
struct pw_proxy *out, *in, *link;
@ -264,6 +265,9 @@ static int impl_port_use_buffers(void *object,
struct data *d = object;
uint32_t i;
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++)
d->buffers[i] = buffers[i];
d->n_buffers = n_buffers;

View file

@ -754,7 +754,6 @@ do_port_use_buffers(struct impl *impl,
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
spa_log_debug(this->log, "%p: %s port %d.%d use buffers %p %u flags:%08x", this,
direction == SPA_DIRECTION_INPUT ? "input" : "output",
port_id, mix_id, buffers, n_buffers, flags);

View file

@ -885,16 +885,19 @@ static int impl_port_use_buffers(void *object,
pw_log_debug("%p: port:%d.%d buffers:%u disconnecting:%d", impl,
direction, port_id, n_buffers, impl->disconnecting);
if ((port = get_port(impl, direction, port_id)) == NULL)
return -EINVAL;
if (impl->disconnecting && n_buffers > 0)
return -EIO;
if ((port = get_port(impl, direction, port_id)) == NULL)
return -EINVAL;
clear_buffers(port);
impl_flags = port->flags;
prot = PROT_READ | (direction == SPA_DIRECTION_OUTPUT ? PROT_WRITE : 0);
clear_buffers(port);
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
int buf_size = 0;

View file

@ -922,13 +922,13 @@ static int impl_port_use_buffers(void *object,
if (impl->disconnecting && n_buffers > 0)
return -EIO;
if (n_buffers > MAX_BUFFERS)
return -EINVAL;
prot = PROT_READ | (direction == SPA_DIRECTION_OUTPUT ? PROT_WRITE : 0);
clear_buffers(stream);
if (n_buffers > MAX_BUFFERS)
return -ENOSPC;
for (i = 0; i < n_buffers; i++) {
int buf_size = 0;
struct buffer *b = &impl->buffers[i];