mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-05-06 06:46:29 -04:00
filter-graph: handle allocation errors and do cleanup
Make sure clean up everything on error.
This commit is contained in:
parent
9972df2614
commit
7bfc820ae8
4 changed files with 76 additions and 30 deletions
|
|
@ -76,6 +76,14 @@ static void layout_from_name(AVChannelLayout *layout, const char *name)
|
||||||
av_channel_layout_from_string(layout, "FC");
|
av_channel_layout_from_string(layout, "FC");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ffmpeg_cleanup(void *instance)
|
||||||
|
{
|
||||||
|
struct instance *i = instance;
|
||||||
|
avfilter_graph_free(&i->filter_graph);
|
||||||
|
av_frame_free(&i->frame);
|
||||||
|
free(i);
|
||||||
|
}
|
||||||
|
|
||||||
static void *ffmpeg_instantiate(const struct spa_fga_plugin *plugin, const struct spa_fga_descriptor *desc,
|
static void *ffmpeg_instantiate(const struct spa_fga_plugin *plugin, const struct spa_fga_descriptor *desc,
|
||||||
unsigned long SampleRate, int index, const char *config)
|
unsigned long SampleRate, int index, const char *config)
|
||||||
{
|
{
|
||||||
|
|
@ -99,21 +107,21 @@ static void *ffmpeg_instantiate(const struct spa_fga_plugin *plugin, const struc
|
||||||
i->filter_graph = avfilter_graph_alloc();
|
i->filter_graph = avfilter_graph_alloc();
|
||||||
if (i->filter_graph == NULL) {
|
if (i->filter_graph == NULL) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return NULL;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = avfilter_graph_parse2(i->filter_graph, d->desc.name, &in, &out);
|
res = avfilter_graph_parse2(i->filter_graph, d->desc.name, &in, &out);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
spa_log_error(p->log, "can parse filter graph %s", d->desc.name);
|
spa_log_error(p->log, "can parse filter graph %s", d->desc.name);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n_fp = 0, fp = in; fp != NULL; fp = fp->next, n_fp++) {
|
for (n_fp = 0, fp = in; fp != NULL; fp = fp->next, n_fp++) {
|
||||||
ctx = avfilter_graph_alloc_filter(i->filter_graph, d->buffersrc, "src");
|
ctx = avfilter_graph_alloc_filter(i->filter_graph, d->buffersrc, "src");
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
spa_log_error(p->log, "can't alloc buffersrc");
|
spa_log_error(p->log, "can't alloc buffersrc");
|
||||||
return NULL;
|
goto error_free;
|
||||||
}
|
}
|
||||||
av_channel_layout_describe(&d->layout[n_fp], channel, sizeof(channel));
|
av_channel_layout_describe(&d->layout[n_fp], channel, sizeof(channel));
|
||||||
|
|
||||||
|
|
@ -132,7 +140,7 @@ static void *ffmpeg_instantiate(const struct spa_fga_plugin *plugin, const struc
|
||||||
cnv = avfilter_graph_alloc_filter(i->filter_graph, d->format, "format");
|
cnv = avfilter_graph_alloc_filter(i->filter_graph, d->format, "format");
|
||||||
if (cnv == NULL) {
|
if (cnv == NULL) {
|
||||||
spa_log_error(p->log, "can't alloc format");
|
spa_log_error(p->log, "can't alloc format");
|
||||||
return NULL;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
av_channel_layout_describe(&d->layout[n_fp], channel, sizeof(channel));
|
av_channel_layout_describe(&d->layout[n_fp], channel, sizeof(channel));
|
||||||
|
|
@ -148,7 +156,7 @@ static void *ffmpeg_instantiate(const struct spa_fga_plugin *plugin, const struc
|
||||||
ctx = avfilter_graph_alloc_filter(i->filter_graph, d->buffersink, "sink");
|
ctx = avfilter_graph_alloc_filter(i->filter_graph, d->buffersink, "sink");
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
spa_log_error(p->log, "can't alloc buffersink");
|
spa_log_error(p->log, "can't alloc buffersink");
|
||||||
return NULL;
|
goto error_free;
|
||||||
}
|
}
|
||||||
avfilter_init_str(ctx, NULL);
|
avfilter_init_str(ctx, NULL);
|
||||||
avfilter_link(cnv, 0, ctx, 0);
|
avfilter_link(cnv, 0, ctx, 0);
|
||||||
|
|
@ -159,6 +167,8 @@ static void *ffmpeg_instantiate(const struct spa_fga_plugin *plugin, const struc
|
||||||
avfilter_graph_config(i->filter_graph, NULL);
|
avfilter_graph_config(i->filter_graph, NULL);
|
||||||
|
|
||||||
i->frame = av_frame_alloc();
|
i->frame = av_frame_alloc();
|
||||||
|
if (i->frame == NULL)
|
||||||
|
goto error_free;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
char *dump = avfilter_graph_dump(i->filter_graph, NULL);
|
char *dump = avfilter_graph_dump(i->filter_graph, NULL);
|
||||||
|
|
@ -166,14 +176,10 @@ static void *ffmpeg_instantiate(const struct spa_fga_plugin *plugin, const struc
|
||||||
free(dump);
|
free(dump);
|
||||||
#endif
|
#endif
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
|
|
||||||
static void ffmpeg_cleanup(void *instance)
|
error_free:
|
||||||
{
|
ffmpeg_cleanup(i);
|
||||||
struct instance *i = instance;
|
return NULL;
|
||||||
avfilter_graph_free(&i->filter_graph);
|
|
||||||
av_frame_free(&i->frame);
|
|
||||||
free(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ffmpeg_free(const struct spa_fga_descriptor *desc)
|
static void ffmpeg_free(const struct spa_fga_descriptor *desc)
|
||||||
|
|
@ -181,10 +187,12 @@ static void ffmpeg_free(const struct spa_fga_descriptor *desc)
|
||||||
struct descriptor *d = (struct descriptor*)desc;
|
struct descriptor *d = (struct descriptor*)desc;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
avfilter_graph_free(&d->filter_graph);
|
avfilter_graph_free(&d->filter_graph);
|
||||||
|
if (d->desc.ports) {
|
||||||
for (i = 0; i < d->desc.n_ports; i++)
|
for (i = 0; i < d->desc.n_ports; i++)
|
||||||
free((void*)d->desc.ports[i].name);
|
free((void*)d->desc.ports[i].name);
|
||||||
free((char*)d->desc.name);
|
|
||||||
free(d->desc.ports);
|
free(d->desc.ports);
|
||||||
|
}
|
||||||
|
free((char*)d->desc.name);
|
||||||
free(d);
|
free(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,14 +278,14 @@ static const struct spa_fga_descriptor *ffmpeg_plugin_make_desc(void *plugin, co
|
||||||
desc->filter_graph = avfilter_graph_alloc();
|
desc->filter_graph = avfilter_graph_alloc();
|
||||||
if (desc->filter_graph == NULL) {
|
if (desc->filter_graph == NULL) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return NULL;
|
goto error_free_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = avfilter_graph_parse2(desc->filter_graph, name, &in, &out);
|
res = avfilter_graph_parse2(desc->filter_graph, name, &in, &out);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
spa_log_error(p->log, "can parse filter graph %s", name);
|
spa_log_error(p->log, "can parse filter graph %s", name);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
goto error_free_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->desc.n_ports = 0;
|
desc->desc.n_ports = 0;
|
||||||
|
|
@ -300,13 +308,13 @@ static const struct spa_fga_descriptor *ffmpeg_plugin_make_desc(void *plugin, co
|
||||||
spa_log_error(p->log, "%p: too many in/out ports %d > %d", desc,
|
spa_log_error(p->log, "%p: too many in/out ports %d > %d", desc,
|
||||||
n_fp, MAX_CTX);
|
n_fp, MAX_CTX);
|
||||||
errno = ENOSPC;
|
errno = ENOSPC;
|
||||||
return NULL;
|
goto error_free_desc;
|
||||||
}
|
}
|
||||||
if (desc->desc.n_ports >= MAX_PORTS) {
|
if (desc->desc.n_ports >= MAX_PORTS) {
|
||||||
spa_log_error(p->log, "%p: too many ports %d > %d", desc,
|
spa_log_error(p->log, "%p: too many ports %d > %d", desc,
|
||||||
desc->desc.n_ports, MAX_PORTS);
|
desc->desc.n_ports, MAX_PORTS);
|
||||||
errno = ENOSPC;
|
errno = ENOSPC;
|
||||||
return NULL;
|
goto error_free_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->desc.instantiate = ffmpeg_instantiate;
|
desc->desc.instantiate = ffmpeg_instantiate;
|
||||||
|
|
@ -316,9 +324,13 @@ static const struct spa_fga_descriptor *ffmpeg_plugin_make_desc(void *plugin, co
|
||||||
desc->desc.run = ffmpeg_run;
|
desc->desc.run = ffmpeg_run;
|
||||||
|
|
||||||
desc->desc.name = strdup(name);
|
desc->desc.name = strdup(name);
|
||||||
|
if (desc->desc.name == NULL)
|
||||||
|
goto error_free_desc;
|
||||||
desc->desc.flags = 0;
|
desc->desc.flags = 0;
|
||||||
|
|
||||||
desc->desc.ports = calloc(desc->desc.n_ports, sizeof(struct spa_fga_port));
|
desc->desc.ports = calloc(desc->desc.n_ports, sizeof(struct spa_fga_port));
|
||||||
|
if (desc->desc.ports == NULL)
|
||||||
|
goto error_free_desc;
|
||||||
|
|
||||||
for (n_fp = 0, n_p = 0, fp = in; fp != NULL; fp = fp->next, n_fp++) {
|
for (n_fp = 0, n_p = 0, fp = in; fp != NULL; fp = fp->next, n_fp++) {
|
||||||
for (j = 0; j < desc->layout[n_fp].nb_channels; j++, n_p++) {
|
for (j = 0; j < desc->layout[n_fp].nb_channels; j++, n_p++) {
|
||||||
|
|
@ -327,6 +339,8 @@ static const struct spa_fga_descriptor *ffmpeg_plugin_make_desc(void *plugin, co
|
||||||
desc->desc.ports[n_p].name = spa_aprintf("%s", fp->name);
|
desc->desc.ports[n_p].name = spa_aprintf("%s", fp->name);
|
||||||
else
|
else
|
||||||
desc->desc.ports[n_p].name = spa_aprintf("%s_%d", fp->name, j);
|
desc->desc.ports[n_p].name = spa_aprintf("%s_%d", fp->name, j);
|
||||||
|
if (desc->desc.ports[n_p].name == NULL)
|
||||||
|
goto error_free_desc;
|
||||||
desc->desc.ports[n_p].flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_AUDIO;
|
desc->desc.ports[n_p].flags = SPA_FGA_PORT_INPUT | SPA_FGA_PORT_AUDIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -337,11 +351,15 @@ static const struct spa_fga_descriptor *ffmpeg_plugin_make_desc(void *plugin, co
|
||||||
desc->desc.ports[n_p].name = spa_aprintf("%s", fp->name);
|
desc->desc.ports[n_p].name = spa_aprintf("%s", fp->name);
|
||||||
else
|
else
|
||||||
desc->desc.ports[n_p].name = spa_aprintf("%s_%d", fp->name, j);
|
desc->desc.ports[n_p].name = spa_aprintf("%s_%d", fp->name, j);
|
||||||
|
if (desc->desc.ports[n_p].name == NULL)
|
||||||
|
goto error_free_desc;
|
||||||
desc->desc.ports[n_p].flags = SPA_FGA_PORT_OUTPUT | SPA_FGA_PORT_AUDIO;
|
desc->desc.ports[n_p].flags = SPA_FGA_PORT_OUTPUT | SPA_FGA_PORT_AUDIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
desc->desc.ports[n_p].index = n_p;
|
desc->desc.ports[n_p].index = n_p;
|
||||||
desc->desc.ports[n_p].name = strdup("latency");
|
desc->desc.ports[n_p].name = strdup("latency");
|
||||||
|
if (desc->desc.ports[n_p].name == NULL)
|
||||||
|
goto error_free_desc;
|
||||||
desc->desc.ports[n_p].flags = SPA_FGA_PORT_OUTPUT | SPA_FGA_PORT_CONTROL;
|
desc->desc.ports[n_p].flags = SPA_FGA_PORT_OUTPUT | SPA_FGA_PORT_CONTROL;
|
||||||
desc->desc.ports[n_p].hint = SPA_FGA_HINT_LATENCY;
|
desc->desc.ports[n_p].hint = SPA_FGA_HINT_LATENCY;
|
||||||
desc->latency_idx = n_p++;
|
desc->latency_idx = n_p++;
|
||||||
|
|
@ -349,8 +367,14 @@ static const struct spa_fga_descriptor *ffmpeg_plugin_make_desc(void *plugin, co
|
||||||
desc->buffersrc = avfilter_get_by_name("abuffer");
|
desc->buffersrc = avfilter_get_by_name("abuffer");
|
||||||
desc->buffersink = avfilter_get_by_name("abuffersink");
|
desc->buffersink = avfilter_get_by_name("abuffersink");
|
||||||
desc->format = avfilter_get_by_name("aformat");
|
desc->format = avfilter_get_by_name("aformat");
|
||||||
|
if (desc->buffersrc == NULL || desc->buffersink == NULL || desc->format == NULL)
|
||||||
|
goto error_free_desc;
|
||||||
|
|
||||||
return &desc->desc;
|
return &desc->desc;
|
||||||
|
|
||||||
|
error_free_desc:
|
||||||
|
ffmpeg_free(&desc->desc);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct spa_fga_plugin_methods impl_plugin = {
|
static struct spa_fga_plugin_methods impl_plugin = {
|
||||||
|
|
|
||||||
|
|
@ -503,10 +503,12 @@ static void lv2_free(const struct spa_fga_descriptor *desc)
|
||||||
{
|
{
|
||||||
struct descriptor *d = (struct descriptor*)desc;
|
struct descriptor *d = (struct descriptor*)desc;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
if (d->desc.ports) {
|
||||||
for (i = 0; i < d->desc.n_ports; i++)
|
for (i = 0; i < d->desc.n_ports; i++)
|
||||||
free((void*)d->desc.ports[i].name);
|
free((void*)d->desc.ports[i].name);
|
||||||
free((char*)d->desc.name);
|
|
||||||
free(d->desc.ports);
|
free(d->desc.ports);
|
||||||
|
}
|
||||||
|
free((char*)d->desc.name);
|
||||||
free(d);
|
free(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -535,18 +537,18 @@ static const struct spa_fga_descriptor *lv2_plugin_make_desc(void *plugin, const
|
||||||
desc->desc.free = lv2_free;
|
desc->desc.free = lv2_free;
|
||||||
|
|
||||||
desc->desc.name = strdup(name);
|
desc->desc.name = strdup(name);
|
||||||
|
if (desc->desc.name == NULL)
|
||||||
|
goto error_free;
|
||||||
|
|
||||||
desc->desc.flags = 0;
|
desc->desc.flags = 0;
|
||||||
|
|
||||||
desc->desc.n_ports = lilv_plugin_get_num_ports(p->p);
|
desc->desc.n_ports = lilv_plugin_get_num_ports(p->p);
|
||||||
if (desc->desc.n_ports > MAX_PORTS) {
|
if (desc->desc.n_ports > MAX_PORTS)
|
||||||
free(desc);
|
goto error_free;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
desc->desc.ports = calloc(desc->desc.n_ports, sizeof(struct spa_fga_port));
|
desc->desc.ports = calloc(desc->desc.n_ports, sizeof(struct spa_fga_port));
|
||||||
if (desc->desc.ports == NULL) {
|
if (desc->desc.ports == NULL)
|
||||||
free(desc);
|
goto error_free;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mins = alloca(desc->desc.n_ports * sizeof(float));
|
mins = alloca(desc->desc.n_ports * sizeof(float));
|
||||||
maxes = alloca(desc->desc.n_ports * sizeof(float));
|
maxes = alloca(desc->desc.n_ports * sizeof(float));
|
||||||
|
|
@ -564,6 +566,8 @@ static const struct spa_fga_descriptor *lv2_plugin_make_desc(void *plugin, const
|
||||||
|
|
||||||
fp->index = i;
|
fp->index = i;
|
||||||
fp->name = strdup(lilv_node_as_string(symbol));
|
fp->name = strdup(lilv_node_as_string(symbol));
|
||||||
|
if (fp->name == NULL)
|
||||||
|
goto error_free;
|
||||||
|
|
||||||
fp->flags = 0;
|
fp->flags = 0;
|
||||||
if (lilv_port_is_a(p->p, port, c->lv2_InputPort))
|
if (lilv_port_is_a(p->p, port, c->lv2_InputPort))
|
||||||
|
|
@ -597,6 +601,10 @@ static const struct spa_fga_descriptor *lv2_plugin_make_desc(void *plugin, const
|
||||||
fp->min = -FLT_MAX;
|
fp->min = -FLT_MAX;
|
||||||
}
|
}
|
||||||
return &desc->desc;
|
return &desc->desc;
|
||||||
|
|
||||||
|
error_free:
|
||||||
|
lv2_free(&desc->desc);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct spa_fga_plugin_methods impl_plugin = {
|
static struct spa_fga_plugin_methods impl_plugin = {
|
||||||
|
|
|
||||||
|
|
@ -475,6 +475,8 @@ static const struct spa_fga_descriptor *onnx_plugin_make_desc(void *plugin, cons
|
||||||
desc->desc.run = onnx_run;
|
desc->desc.run = onnx_run;
|
||||||
|
|
||||||
desc->desc.name = strdup(name);
|
desc->desc.name = strdup(name);
|
||||||
|
if (desc->desc.name == NULL)
|
||||||
|
goto error;
|
||||||
desc->desc.flags = 0;
|
desc->desc.flags = 0;
|
||||||
|
|
||||||
spa_log_info(p->log, "onnx: loading model %s", path);
|
spa_log_info(p->log, "onnx: loading model %s", path);
|
||||||
|
|
@ -568,6 +570,8 @@ static const struct spa_fga_descriptor *onnx_plugin_make_desc(void *plugin, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->desc.ports = calloc(desc->n_tensors, sizeof(struct spa_fga_port));
|
desc->desc.ports = calloc(desc->n_tensors, sizeof(struct spa_fga_port));
|
||||||
|
if (desc->desc.ports == NULL)
|
||||||
|
goto error;
|
||||||
desc->desc.n_ports = 0;
|
desc->desc.n_ports = 0;
|
||||||
|
|
||||||
/* make ports */
|
/* make ports */
|
||||||
|
|
|
||||||
|
|
@ -211,10 +211,14 @@ static void * spatializer_instantiate(const struct spa_fga_plugin *plugin, const
|
||||||
|
|
||||||
impl->tmp[0] = calloc(impl->plugin->quantum_limit, sizeof(float));
|
impl->tmp[0] = calloc(impl->plugin->quantum_limit, sizeof(float));
|
||||||
impl->tmp[1] = calloc(impl->plugin->quantum_limit, sizeof(float));
|
impl->tmp[1] = calloc(impl->plugin->quantum_limit, sizeof(float));
|
||||||
|
if (impl->tmp[0] == NULL || impl->tmp[1] == NULL)
|
||||||
|
goto error;
|
||||||
impl->rate = SampleRate;
|
impl->rate = SampleRate;
|
||||||
|
|
||||||
return impl;
|
return impl;
|
||||||
error:
|
error:
|
||||||
|
free(impl->tmp[0]);
|
||||||
|
free(impl->tmp[1]);
|
||||||
if (impl->sofa)
|
if (impl->sofa)
|
||||||
mysofa_close_cached(impl->sofa);
|
mysofa_close_cached(impl->sofa);
|
||||||
free(impl);
|
free(impl);
|
||||||
|
|
@ -247,6 +251,12 @@ static void spatializer_reload(void * Instance)
|
||||||
float coords[3];
|
float coords[3];
|
||||||
struct convolver_ir ir[2];
|
struct convolver_ir ir[2];
|
||||||
|
|
||||||
|
if (left_ir == NULL || right_ir == NULL) {
|
||||||
|
free(left_ir);
|
||||||
|
free(right_ir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 3; i++)
|
for (uint8_t i = 0; i < 3; i++)
|
||||||
coords[i] = impl->port[3 + i][0];
|
coords[i] = impl->port[3 + i][0];
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue