Hello community, here is the log from the commit of package pipewire for openSUSE:Factory checked in at 2020-07-24 09:49:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pipewire (Old) and /work/SRC/openSUSE:Factory/.pipewire.new.3592 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pipewire" Fri Jul 24 09:49:47 2020 rev:12 rq:821839 version:0.3.6 Changes: -------- --- /work/SRC/openSUSE:Factory/pipewire/pipewire.changes 2020-07-10 14:12:45.383504817 +0200 +++ /work/SRC/openSUSE:Factory/.pipewire.new.3592/pipewire.changes 2020-07-24 09:51:29.197122489 +0200 @@ -1,0 +2,41 @@ +Wed Jul 15 07:26:01 UTC 2020 - Antonio Larrosa <[email protected]> + +- Recommend pipewire from libpipewire, so if the library is + installed the daemon gets pulled in since we want a daemon + to connect to. +- Require pipewire-spa-plugins from pipewire instead of + recommending it since the support plugin is actually required + for most uses (like screen sharing in wayland, which we want to + support out-of-the-box). +- Enable the pipewire.socket systemd user service in %post + (using pulseaudio's %post section as an example of how to do it + since systemd-presets-common-SUSE currently lacks support for + user services). Also disable it in %preun and %postun. + +------------------------------------------------------------------- +Tue Jul 14 08:25:49 UTC 2020 - Antonio Larrosa <[email protected]> + +- Add patches from upstream to fix many issues mainly related to + memory leaks, crashes and wrong behaviour: + * 0001-client-node-fix-buffer-size-calculation.patch + * 0002-gst-fix-proxy-leaks.patch + * 0003-pulse-fix-pa_card_info-profiles2-array-to-be-NULL-terminated.patch + * 0004-pulse-fix-size-calculation.patch + * 0005-jack-fix-crash-on-close-when-metadata-are-not-available.patch + * 0006-a2dpsink-only-request-new-data-when-buffer-is-done.patch + * 0007-pulse-fix-counter-while-populating-car_info-profiles.patch + * 0008-impl-link-reset-state-before-starting-allocation.patch + * 0009-impl-core-clear-the-mempool.patch + * 0010-mem-reset-the-map-in-clear.patch + * 0011-avoid-uninitialized-variables.patch + * 0012-dlclose-on-errors.patch + * 0013-stream-handle-NULL-context.patch + * 0014-state-always-update-state-variables.patch + * 0015-spa-device-fix-leak-of-properties-in-error-case.patch + * 0016-alsa-dont-leak-structure-on-error.patch + * 0017-alsa-dont-leak-properties-on-error.patch + * 0018-stream-fix-some-more-leaks-in-error-paths.patch + * 0019-buffers-increase-max-datas-and-metadata-in-buffers.patch + * 0020-gst-return-NULL-for-unknown-format.patch + +------------------------------------------------------------------- @@ -11 +52 @@ -- Update to version 0.3.6 (boo#1171433): +- Update to version 0.3.6 (boo#1171433, jsc#ECO-2308): New: ---- 0001-client-node-fix-buffer-size-calculation.patch 0002-gst-fix-proxy-leaks.patch 0003-pulse-fix-pa_card_info-profiles2-array-to-be-NULL-terminated.patch 0004-pulse-fix-size-calculation.patch 0005-jack-fix-crash-on-close-when-metadata-are-not-available.patch 0006-a2dpsink-only-request-new-data-when-buffer-is-done.patch 0007-pulse-fix-counter-while-populating-car_info-profiles.patch 0008-impl-link-reset-state-before-starting-allocation.patch 0009-impl-core-clear-the-mempool.patch 0010-mem-reset-the-map-in-clear.patch 0011-avoid-uninitialized-variables.patch 0012-dlclose-on-errors.patch 0013-stream-handle-NULL-context.patch 0014-state-always-update-state-variables.patch 0015-spa-device-fix-leak-of-properties-in-error-case.patch 0016-alsa-dont-leak-structure-on-error.patch 0017-alsa-dont-leak-properties-on-error.patch 0018-stream-fix-some-more-leaks-in-error-paths.patch 0019-buffers-increase-max-datas-and-metadata-in-buffers.patch 0020-gst-return-NULL-for-unknown-format.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pipewire.spec ++++++ --- /var/tmp/diff_new_pack.QrwlOB/_old 2020-07-24 09:51:31.625125055 +0200 +++ /var/tmp/diff_new_pack.QrwlOB/_new 2020-07-24 09:51:31.629125059 +0200 @@ -47,6 +47,26 @@ Patch0: fix-memfd_create-call.patch Patch1: do-not-use-snd_pcm_ioplug_hw_avail.patch Patch2: fix-meson-required-version.patch +Patch101: 0001-client-node-fix-buffer-size-calculation.patch +Patch102: 0002-gst-fix-proxy-leaks.patch +Patch103: 0003-pulse-fix-pa_card_info-profiles2-array-to-be-NULL-terminated.patch +Patch104: 0004-pulse-fix-size-calculation.patch +Patch105: 0005-jack-fix-crash-on-close-when-metadata-are-not-available.patch +Patch106: 0006-a2dpsink-only-request-new-data-when-buffer-is-done.patch +Patch107: 0007-pulse-fix-counter-while-populating-car_info-profiles.patch +Patch108: 0008-impl-link-reset-state-before-starting-allocation.patch +Patch109: 0009-impl-core-clear-the-mempool.patch +Patch110: 0010-mem-reset-the-map-in-clear.patch +Patch111: 0011-avoid-uninitialized-variables.patch +Patch112: 0012-dlclose-on-errors.patch +Patch113: 0013-stream-handle-NULL-context.patch +Patch114: 0014-state-always-update-state-variables.patch +Patch115: 0015-spa-device-fix-leak-of-properties-in-error-case.patch +Patch116: 0016-alsa-dont-leak-structure-on-error.patch +Patch117: 0017-alsa-dont-leak-properties-on-error.patch +Patch118: 0018-stream-fix-some-more-leaks-in-error-paths.patch +Patch119: 0019-buffers-increase-max-datas-and-metadata-in-buffers.patch +Patch120: 0020-gst-return-NULL-for-unknown-format.patch BuildRequires: doxygen BuildRequires: fdupes @@ -86,9 +106,9 @@ BuildRequires: pkgconfig(x11) Requires: %{libpipewire} = %{version} Requires: %{name}-modules = %{version} +Requires: %{name}-spa-plugins-%{spa_ver_str} = %{version} Requires: %{name}-spa-tools = %{version} Requires: %{name}-tools = %{version} -Recommends: %{name}-spa-plugins-%{spa_ver_str} = %{version} %description PipeWire is a server and user space API to deal with multimedia pipelines. @@ -105,6 +125,7 @@ Summary: A Multimedia Framework designed to be an audio and video server and more License: MIT Group: System/Libraries +Recommends: pipewire %description -n %{libpipewire} PipeWire is a server and user space API to deal with multimedia pipelines. @@ -263,6 +284,8 @@ %endif %patch2 -p1 +%autopatch -m 101 -p1 + %build %if %{pkg_vcmp gcc < 8} export CC=gcc-9 @@ -308,6 +331,26 @@ %check %meson_test +%post +if [ ! -f /etc/systemd/user/sockets.target.wants/%{name}.socket ]; then + echo "Switching Pipewire activation using systemd user socket." + echo "Please log out from all sessions once to make it effective." +fi +%systemd_user_post pipewire.socket +# FIXME: workaround to make sure the user socket symlink creation (related to bsc#1083473) +if [ ! -f /etc/systemd/user/sockets.target.wants/%{name}.socket ]; then + # below should work once when preset is defined properly: + # /usr/bin/systemctl --no-reload --global preset pipewire.socket + mkdir -p /etc/systemd/user/sockets.target.wants + ln -s %{_userunitdir}/%{name}.socket /etc/systemd/user/sockets.target.wants/%{name}.socket +fi + +%preun +%systemd_user_preun pipewire.socket + +%postun +%systemd_user_postun pipewire.socket + %post -n %{libpipewire} -p /sbin/ldconfig %postun -n %{libpipewire} -p /sbin/ldconfig ++++++ 0001-client-node-fix-buffer-size-calculation.patch ++++++ >From 61c1fe546e374db03f3b05749123cf9739b966f2 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Mon, 15 Jun 2020 20:44:08 +0200 Subject: [PATCH] client-node: fix buffer size calculation Calculate the size of the buffer as the difference between the first byte and the last byte. This takes into account the alignment. --- src/modules/module-client-node/client-node.c | 13 ++++++------- src/modules/module-client-node/remote-node.c | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 43bd8570..09980bd1 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -769,8 +769,7 @@ do_port_use_buffers(struct impl *impl, for (i = 0; i < n_buffers; i++) { struct buffer *b = &mix->buffers[i]; struct pw_memblock *mem, *m; - size_t data_size; - void *baseptr; + void *baseptr, *endptr; b->outbuf = buffers[i]; memcpy(&b->buffer, buffers[i], sizeof(struct spa_buffer)); @@ -787,14 +786,14 @@ do_port_use_buffers(struct impl *impl, if ((mem = pw_mempool_find_ptr(impl->context->pool, baseptr)) == NULL) return -EINVAL; - data_size = buffers[i]->n_datas * sizeof(struct spa_chunk); + endptr = SPA_MEMBER(baseptr, buffers[i]->n_datas * sizeof(struct spa_chunk), void); for (j = 0; j < buffers[i]->n_metas; j++) { - data_size += SPA_ROUND_UP_N(buffers[i]->metas[j].size, 8); + endptr = SPA_MEMBER(endptr, SPA_ROUND_UP_N(buffers[i]->metas[j].size, 8), void); } for (j = 0; j < buffers[i]->n_datas; j++) { struct spa_data *d = buffers[i]->datas; if (d->type == SPA_DATA_MemPtr) - data_size += d->maxsize; + endptr = SPA_MEMBER(d->data, d->maxsize, void); } m = pw_mempool_import_block(this->client->pool, mem); @@ -805,8 +804,8 @@ do_port_use_buffers(struct impl *impl, mb[i].buffer = &b->buffer; mb[i].mem_id = m->id; - mb[i].offset = SPA_PTRDIFF(baseptr, SPA_MEMBER(mem->map->ptr, 0, void)); - mb[i].size = data_size; + mb[i].offset = SPA_PTRDIFF(baseptr, mem->map->ptr); + mb[i].size = SPA_PTRDIFF(endptr, baseptr); spa_log_debug(this->log, NAME" %p: buffer %d %d %d %d", this, i, mb[i].mem_id, mb[i].offset, mb[i].size); diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index a68e7507..8ab1bac3 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -653,7 +653,7 @@ client_node_port_use_buffers(void *object, b->datas = SPA_MEMBER(b->metas, sizeof(struct spa_meta) * b->n_metas, struct spa_data); - pw_log_debug("add buffer %d %d %u %u %p", mm->block->id, + pw_log_debug("add buffer mem:%d id:%d offset:%u size:%u %p", mm->block->id, bid->id, buffers[i].offset, buffers[i].size, bid->buf); offset = 0; @@ -696,8 +696,8 @@ client_node_port_use_buffers(void *object, int offs = SPA_PTR_TO_INT(d->data); d->data = SPA_MEMBER(mm->ptr, offs, void); d->fd = -1; - pw_log_debug(" data %d %u -> mem %p maxsize %d", - j, bid->id, d->data, d->maxsize); + pw_log_debug(" data %d id:%u -> mem:%p offs:%d maxsize:%d", + j, bid->id, d->data, offs, d->maxsize); } else { pw_log_warn("unknown buffer data type %d", d->type); } ++++++ 0002-gst-fix-proxy-leaks.patch ++++++ >From cd7a56a71c76e6a4d4158bf739fd61644d325584 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Tue, 16 Jun 2020 11:02:16 +0200 Subject: [PATCH] gst: fix proxy leaks --- src/gst/gstpipewiredeviceprovider.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index e0b8d855..ca7f7306 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -404,6 +404,13 @@ static const struct pw_node_events node_events = { .info = node_event_info }; +static void +removed_node (void *data) +{ + struct node_data *nd = data; + pw_proxy_destroy((struct pw_proxy*)nd->proxy); +} + static void destroy_node (void *data) { @@ -428,9 +435,17 @@ destroy_node (void *data) static const struct pw_proxy_events proxy_node_events = { PW_VERSION_PROXY_EVENTS, + .removed = removed_node, .destroy = destroy_node, }; +static void +removed_port (void *data) +{ + struct port_data *pd = data; + pw_proxy_destroy((struct pw_proxy*)pd->proxy); +} + static void destroy_port (void *data) { @@ -442,6 +457,7 @@ destroy_port (void *data) static const struct pw_proxy_events proxy_port_events = { PW_VERSION_PROXY_EVENTS, + .removed = removed_port, .destroy = destroy_port, }; @@ -563,6 +579,7 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider) } GST_DEBUG_OBJECT (self, "disconnect"); + pw_proxy_destroy ((struct pw_proxy*)data->registry); pw_core_disconnect (self->core); pw_context_destroy (c); pw_loop_destroy (l); @@ -654,7 +671,10 @@ gst_pipewire_device_provider_stop (GstDeviceProvider * provider) GstPipeWireDeviceProvider *self = GST_PIPEWIRE_DEVICE_PROVIDER (provider); GST_DEBUG_OBJECT (self, "stopping provider"); - + if (self->registry) { + pw_proxy_destroy ((struct pw_proxy*)self->registry); + self->registry = NULL; + } if (self->core) { pw_core_disconnect (self->core); self->core = NULL; ++++++ 0003-pulse-fix-pa_card_info-profiles2-array-to-be-NULL-terminated.patch ++++++ >From 9c8279aa6e45398b745e99b889963a36bdbe7ebe Mon Sep 17 00:00:00 2001 From: George Kiagiadakis <[email protected]> Date: Wed, 17 Jun 2020 17:17:51 +0300 Subject: [PATCH] pulse: fix pa_card_info.profiles2 array to be NULL terminated profiles2 is meant to be NULL terminated, according to its documentation Fixes a crash in pavucontrol-qt --- pipewire-pulseaudio/src/introspect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pipewire-pulseaudio/src/introspect.c b/pipewire-pulseaudio/src/introspect.c index 526ddda8..5b2a7a1c 100644 --- a/pipewire-pulseaudio/src/introspect.c +++ b/pipewire-pulseaudio/src/introspect.c @@ -1239,13 +1239,13 @@ static void card_callback(struct card_data *d) { struct global *g = d->global; pa_card_info *i = &g->card_info.info; - int n_profiles, j; + int n_profiles, j = 0; struct param *p; n_profiles = g->card_info.n_profiles; i->profiles = alloca(sizeof(pa_card_profile_info) * n_profiles); - i->profiles2 = alloca(sizeof(pa_card_profile_info2 *) * n_profiles); + i->profiles2 = alloca(sizeof(pa_card_profile_info2 *) * n_profiles + 1); i->n_profiles = 0; pw_log_debug("context %p: info for %d", g->context, g->id); @@ -1282,6 +1282,7 @@ static void card_callback(struct card_data *d) i->active_profile2 = i->profiles2[j]; } } + i->profiles2[j] = NULL; d->cb(d->context, i, 0, d->userdata); } ++++++ 0004-pulse-fix-size-calculation.patch ++++++ >From ba57de9b81cb9841b7183f57f300112458f5ee73 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Wed, 17 Jun 2020 16:56:40 +0200 Subject: [PATCH] pulse: fix size calculation --- pipewire-pulseaudio/src/introspect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipewire-pulseaudio/src/introspect.c b/pipewire-pulseaudio/src/introspect.c index 5b2a7a1c..f0512ead 100644 --- a/pipewire-pulseaudio/src/introspect.c +++ b/pipewire-pulseaudio/src/introspect.c @@ -1245,7 +1245,7 @@ static void card_callback(struct card_data *d) n_profiles = g->card_info.n_profiles; i->profiles = alloca(sizeof(pa_card_profile_info) * n_profiles); - i->profiles2 = alloca(sizeof(pa_card_profile_info2 *) * n_profiles + 1); + i->profiles2 = alloca(sizeof(pa_card_profile_info2 *) * (n_profiles + 1)); i->n_profiles = 0; pw_log_debug("context %p: info for %d", g->context, g->id); ++++++ 0005-jack-fix-crash-on-close-when-metadata-are-not-available.patch ++++++ >From a108752514dafa5c6555050991406decc9bff5f2 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis <[email protected]> Date: Wed, 17 Jun 2020 14:28:42 +0300 Subject: [PATCH] jack: fix crash on close when metadata are not available --- pipewire-jack/src/pipewire-jack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 28a8ff82..5d4ee7b7 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -2400,7 +2400,7 @@ int jack_client_close (jack_client_t *client) if (c->registry) pw_proxy_destroy((struct pw_proxy*)c->registry); - if (c->metadata->proxy) + if (c->metadata && c->metadata->proxy) pw_proxy_destroy((struct pw_proxy*)c->metadata->proxy); pw_core_disconnect(c->core); pw_context_destroy(c->context.context); ++++++ 0006-a2dpsink-only-request-new-data-when-buffer-is-done.patch ++++++ >From 1f1386879b8dd3d3be9a54f749bb839ae2281223 Mon Sep 17 00:00:00 2001 From: Julian Bouzas <[email protected]> Date: Wed, 17 Jun 2020 13:36:05 -0400 Subject: [PATCH] a2dpsink: only request new data when buffer is done --- spa/plugins/bluez5/a2dp-sink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spa/plugins/bluez5/a2dp-sink.c b/spa/plugins/bluez5/a2dp-sink.c index 2ef5317f..575234f2 100644 --- a/spa/plugins/bluez5/a2dp-sink.c +++ b/spa/plugins/bluez5/a2dp-sink.c @@ -563,7 +563,10 @@ static int flush_data(struct impl *this, uint64_t now_time) if (written > 0 && l1 > 0) written += add_data(this, src, l1); if (written <= 0) { - port->need_data = true; + /* only request new data when the current buffer will be fully processed in the next iteration */ + if (port->ready_offset + (this->frame_count * this->codesize) >= d[0].chunk->size) + port->need_data = true; + if (written < 0 && written != -ENOSPC) { spa_list_remove(&b->link); b->outstanding = true; ++++++ 0007-pulse-fix-counter-while-populating-car_info-profiles.patch ++++++ >From 715be5dfe779e73139904461b5e3da53e030ead6 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis <[email protected]> Date: Wed, 17 Jun 2020 18:01:17 +0300 Subject: [PATCH] pulse: fix counter while populating card_info profiles --- pipewire-pulseaudio/src/introspect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipewire-pulseaudio/src/introspect.c b/pipewire-pulseaudio/src/introspect.c index f0512ead..67f1bd54 100644 --- a/pipewire-pulseaudio/src/introspect.c +++ b/pipewire-pulseaudio/src/introspect.c @@ -1262,7 +1262,6 @@ static void card_callback(struct card_data *d) continue; } - j = i->n_profiles++; i->profiles[j].name = name; i->profiles[j].description = name; i->profiles[j].n_sinks = 1; @@ -1281,6 +1280,7 @@ static void card_callback(struct card_data *d) i->active_profile = &i->profiles[j]; i->active_profile2 = i->profiles2[j]; } + j = ++i->n_profiles; } i->profiles2[j] = NULL; d->cb(d->context, i, 0, d->userdata); ++++++ 0008-impl-link-reset-state-before-starting-allocation.patch ++++++ >From ebede9123918ca01a6004fb28a4a8b6c24f4732e Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Fri, 19 Jun 2020 12:12:48 +0200 Subject: [PATCH] impl-link: reset state before starting allocation Reset our state before checking the state of the ports or else we might still think a port has buffers while they are being allocated. --- src/pipewire/impl-link.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pipewire/impl-link.c b/src/pipewire/impl-link.c index aeda03f8..c0095f0a 100644 --- a/src/pipewire/impl-link.c +++ b/src/pipewire/impl-link.c @@ -411,6 +411,9 @@ static int do_allocation(struct pw_impl_link *this) pw_log_debug(NAME" %p: out-node:%p in-node:%p: out-flags:%08x in-flags:%08x", this, output->node, input->node, out_flags, in_flags); + this->rt.in_mix.have_buffers = false; + this->rt.out_mix.have_buffers = false; + if (out_flags & SPA_PORT_FLAG_LIVE) { pw_log_debug(NAME" %p: setting link as live", this); output->node->live = true; ++++++ 0009-impl-core-clear-the-mempool.patch ++++++ >From f78e44c28ac1767ee1ae916b0d4bb8f2d19dd2d6 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Fri, 19 Jun 2020 15:20:50 +0200 Subject: [PATCH] impl-core: clear the mempool When a client sends hello, clear the mempool again to make sure it get's the new memory. --- src/pipewire/impl-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pipewire/impl-core.c b/src/pipewire/impl-core.c index e1b494e4..103c2863 100644 --- a/src/pipewire/impl-core.c +++ b/src/pipewire/impl-core.c @@ -162,6 +162,8 @@ static int core_hello(void *object, uint32_t version) pw_log_debug(NAME" %p: hello %d from resource %p", context, version, resource); pw_map_for_each(&client->objects, destroy_resource, client); + pw_mempool_clear(client->pool); + this->info.change_mask = PW_CORE_CHANGE_MASK_ALL; pw_core_resource_info(resource, &this->info); ++++++ 0010-mem-reset-the-map-in-clear.patch ++++++ >From 95192b21f152ba6fa769049a2298aba1221f794d Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Fri, 19 Jun 2020 16:58:22 +0200 Subject: [PATCH] mem: reset the map in clear Or else the free list is not cleared. --- src/pipewire/mem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pipewire/mem.c b/src/pipewire/mem.c index 79d94672..94b62049 100644 --- a/src/pipewire/mem.c +++ b/src/pipewire/mem.c @@ -164,6 +164,7 @@ void pw_mempool_clear(struct pw_mempool *pool) spa_list_consume(b, &impl->blocks, link) pw_memblock_free(&b->this); + pw_map_reset(&impl->map); } void pw_mempool_destroy(struct pw_mempool *pool) ++++++ 0011-avoid-uninitialized-variables.patch ++++++ >From f08c35259c3d87adaeb9fa09c1c471d7357cec86 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Tue, 23 Jun 2020 15:25:27 +0200 Subject: [PATCH] avoid uninitialized variables --- spa/examples/adapter-control.c | 6 +++--- src/tools/pw-profiler.c | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/spa/examples/adapter-control.c b/spa/examples/adapter-control.c index 8a3daf59..499d4d60 100644 --- a/spa/examples/adapter-control.c +++ b/spa/examples/adapter-control.c @@ -490,10 +490,10 @@ static int negotiate_formats(struct data *data) if (spa_node_port_enum_params_sync(data->source_follower_node, SPA_DIRECTION_OUTPUT, 0, SPA_PARAM_Buffers, &state, filter, ¶m, &b) != 1) - return res; + return -ENOTSUP; spa_pod_fixate(param); - if (spa_pod_parse_object(param, SPA_TYPE_OBJECT_ParamBuffers, NULL, - SPA_PARAM_BUFFERS_size, SPA_POD_Int(&buffer_size)) < 0) + if ((res = spa_pod_parse_object(param, SPA_TYPE_OBJECT_ParamBuffers, NULL, + SPA_PARAM_BUFFERS_size, SPA_POD_Int(&buffer_size))) < 0) return res; /* set the sink and source formats */ diff --git a/src/tools/pw-profiler.c b/src/tools/pw-profiler.c index e0a7492a..5cc09ca3 100644 --- a/src/tools/pw-profiler.c +++ b/src/tools/pw-profiler.c @@ -114,15 +114,14 @@ static int process_clock(struct data *d, const struct spa_pod *pod, struct point static int process_driver_block(struct data *d, const struct spa_pod *pod, struct point *point) { - union { - char *s; - } dummy; - uint32_t driver_id; + char *name = NULL; + uint32_t driver_id = 0; struct measurement driver; + spa_zero(driver); spa_pod_parse_struct(pod, SPA_POD_Int(&driver_id), - SPA_POD_String(&dummy.s), + SPA_POD_String(&name), SPA_POD_Long(&driver.prev_signal), SPA_POD_Long(&driver.signal), SPA_POD_Long(&driver.awake), @@ -169,8 +168,8 @@ static int add_follower(struct data *d, uint32_t id, const char *name) static int process_follower_block(struct data *d, const struct spa_pod *pod, struct point *point) { - uint32_t id; - const char *name; + uint32_t id = 0; + const char *name = NULL; struct measurement m; int idx; ++++++ 0012-dlclose-on-errors.patch ++++++ >From 35bb7d794bf975e82d04bdd0d3f3c7907a679ce6 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Tue, 23 Jun 2020 15:25:45 +0200 Subject: [PATCH] dlclose on errors --- spa/plugins/audioconvert/test-helper.h | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/spa/plugins/audioconvert/test-helper.h b/spa/plugins/audioconvert/test-helper.h index 8f7b7206..d95317b4 100644 --- a/spa/plugins/audioconvert/test-helper.h +++ b/spa/plugins/audioconvert/test-helper.h @@ -46,28 +46,33 @@ static inline struct spa_handle *load_handle(const struct spa_support *support, if ((hnd = dlopen(path, RTLD_NOW)) == NULL) { fprintf(stderr, "can't load %s: %s\n", lib, dlerror()); - errno = -ENOENT; - return NULL; + res = -ENOENT; + goto error; } if ((enum_func = dlsym(hnd, SPA_HANDLE_FACTORY_ENUM_FUNC_NAME)) == NULL) { fprintf(stderr, "can't find enum function\n"); - errno = -ENOENT; - return NULL; + res = -ENXIO; + goto error_close; } if ((factory = get_factory(enum_func, name, SPA_VERSION_HANDLE_FACTORY)) == NULL) { fprintf(stderr, "can't find factory\n"); - errno = -ENOENT; - return NULL; + res = -ENOENT; + goto error_close; } handle = calloc(1, spa_handle_factory_get_size(factory, NULL)); if ((res = spa_handle_factory_init(factory, handle, NULL, support, n_support)) < 0) { fprintf(stderr, "can't make factory instance: %d\n", res); - errno = -res; - return NULL; + goto error_close; } return handle; + +error_close: + dlclose(hnd); +error: + errno = -res; + return NULL; } static inline uint32_t get_cpu_flags(void) ++++++ 0013-stream-handle-NULL-context.patch ++++++ >From d5604990545012a2318eebdc38d569bbc5773a38 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Wed, 24 Jun 2020 12:50:42 +0200 Subject: [PATCH] stream: handle NULL context --- pipewire-pulseaudio/src/stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipewire-pulseaudio/src/stream.c b/pipewire-pulseaudio/src/stream.c index bcb338bf..1c1ce5f7 100644 --- a/pipewire-pulseaudio/src/stream.c +++ b/pipewire-pulseaudio/src/stream.c @@ -212,7 +212,7 @@ static void stream_state_changed(void *data, enum pw_stream_state old, pw_log_debug("stream %p: state '%s'->'%s' (%d)", s, pw_stream_state_as_string(old), pw_stream_state_as_string(state), s->state); - if (s->state == PA_STREAM_TERMINATED) + if (s->state == PA_STREAM_TERMINATED || c == NULL) return; switch(state) { ++++++ 0014-state-always-update-state-variables.patch ++++++ >From f678f4371de0a8a4b75023fb123d0210ac685ed2 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Sat, 27 Jun 2020 13:21:12 +0200 Subject: [PATCH] state: always update state variables Or else we might leak the error string. --- src/pipewire/impl-link.c | 8 ++++---- src/pipewire/impl-node.c | 11 +++++------ src/pipewire/impl-port.c | 24 +++++++++++++----------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/pipewire/impl-link.c b/src/pipewire/impl-link.c index 8be818b4..22446c86 100644 --- a/src/pipewire/impl-link.c +++ b/src/pipewire/impl-link.c @@ -89,6 +89,10 @@ static void pw_impl_link_update_state(struct pw_impl_link *link, enum pw_link_st { enum pw_link_state old = link->info.state; + link->info.state = state; + free((char*)link->info.error); + link->info.error = error; + if (state == old) return; @@ -105,10 +109,6 @@ static void pw_impl_link_update_state(struct pw_impl_link *link, enum pw_link_st pw_link_state_as_string(state)); } - link->info.state = state; - free((char*)link->info.error); - link->info.error = error; - pw_impl_link_emit_state_changed(link, old, state, error); link->info.change_mask |= PW_LINK_CHANGE_MASK_STATE; diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index fb415cdb..97ee439d 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -285,9 +285,12 @@ do_node_add(struct spa_loop *loop, static void node_update_state(struct pw_impl_node *node, enum pw_node_state state, char *error) { - enum pw_node_state old; + enum pw_node_state old = node->info.state; + + free((char*)node->info.error); + node->info.error = error; + node->info.state = state; - old = node->info.state; if (old == state) return; @@ -302,10 +305,6 @@ static void node_update_state(struct pw_impl_node *node, enum pw_node_state stat pw_node_state_as_string(old), pw_node_state_as_string(state)); } - free((char*)node->info.error); - node->info.error = error; - node->info.state = state; - switch (state) { case PW_NODE_STATE_RUNNING: pw_loop_invoke(node->data_loop, do_node_add, 1, NULL, 0, true, node); diff --git a/src/pipewire/impl-port.c b/src/pipewire/impl-port.c index 7e4528e7..21434360 100644 --- a/src/pipewire/impl-port.c +++ b/src/pipewire/impl-port.c @@ -98,17 +98,19 @@ void pw_impl_port_update_state(struct pw_impl_port *port, enum pw_impl_port_stat { enum pw_impl_port_state old = port->state; - if (old != state) { - pw_log(state == PW_IMPL_PORT_STATE_ERROR ? - SPA_LOG_LEVEL_ERROR : SPA_LOG_LEVEL_DEBUG, - NAME" %p: state %s -> %s (%s)", port, - port_state_as_string(old), port_state_as_string(state), error); - - port->state = state; - free((void*)port->error); - port->error = error; - pw_impl_port_emit_state_changed(port, old, state, error); - } + port->state = state; + free((void*)port->error); + port->error = error; + + if (old == state) + return; + + pw_log(state == PW_IMPL_PORT_STATE_ERROR ? + SPA_LOG_LEVEL_ERROR : SPA_LOG_LEVEL_DEBUG, + NAME" %p: state %s -> %s (%s)", port, + port_state_as_string(old), port_state_as_string(state), error); + + pw_impl_port_emit_state_changed(port, old, state, error); } static int tee_process(void *object) ++++++ 0015-spa-device-fix-leak-of-properties-in-error-case.patch ++++++ >From d871adbd4d602e0ba70e4c23f792aea1b214b79e Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Thu, 2 Jul 2020 10:52:15 +0200 Subject: [PATCH] spa-device: fix leak of properties in error case --- src/modules/spa/spa-device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modules/spa/spa-device.c b/src/modules/spa/spa-device.c index 4486bce8..a1cc82e1 100644 --- a/src/modules/spa/spa-device.c +++ b/src/modules/spa/spa-device.c @@ -147,6 +147,7 @@ struct pw_impl_device *pw_spa_device_load(struct pw_context *context, pw_log_error("can't get device interface %d", res); goto error_exit_unload; error_device: + properties = NULL; res = -errno; pw_log_error("can't create device: %m"); goto error_exit_unload; @@ -155,5 +156,7 @@ struct pw_impl_device *pw_spa_device_load(struct pw_context *context, pw_unload_spa_handle(handle); error_exit: errno = -res; + if (properties) + pw_properties_free(properties); return NULL; } ++++++ 0016-alsa-dont-leak-structure-on-error.patch ++++++ >From ac54b7ace1305795497fb01f6badeaf138035fbb Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Thu, 2 Jul 2020 15:52:50 +0200 Subject: [PATCH] alsa: don't leak structure on error --- pipewire-alsa/alsa-plugins/pcm_pipewire.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c index 9d2397f4..d2fdcf44 100644 --- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c +++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c @@ -915,8 +915,10 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, else pw->node_name = strdup(node_name); - if (pw->node_name == NULL) - return -errno; + if (pw->node_name == NULL) { + err = -errno; + goto error; + } pw->target = PW_ID_ANY; if (str != NULL) ++++++ 0017-alsa-dont-leak-properties-on-error.patch ++++++ >From e11d35107fc9e3a392b74855238be40f7bf69ff7 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Thu, 2 Jul 2020 15:53:16 +0200 Subject: [PATCH] alsa: don't leak properties on error --- pipewire-alsa/alsa-plugins/pcm_pipewire.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c index d2fdcf44..560460cb 100644 --- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c +++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c @@ -890,7 +890,7 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, snd_pcm_pipewire_t *pw; int err; const char *str; - struct pw_properties *props; + struct pw_properties *props = NULL; struct pw_loop *loop; assert(pcmp); @@ -947,6 +947,7 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, pw_thread_loop_lock(pw->main_loop); pw->core = pw_context_connect(pw->context, props, 0); + props = NULL; if (pw->core == NULL) { err = -errno; pw_thread_loop_unlock(pw->main_loop); @@ -983,7 +984,9 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, return 0; - error: +error: + if (props) + pw_properties_free(props); snd_pcm_pipewire_free(pw); return err; } ++++++ 0018-stream-fix-some-more-leaks-in-error-paths.patch ++++++ >From 21fc163c49309a04689fc4d636df4622198f5570 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Thu, 2 Jul 2020 16:22:49 +0200 Subject: [PATCH] stream: fix some more leaks in error paths --- src/pipewire/stream.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 086c3468..9db27296 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c #@@ -1474,7 +1474,6 @@ pw_stream_connect(struct pw_stream *stream, # impl->warn_mlock = SPA_FLAG_IS_SET(flags, PW_STREAM_FLAG_RT_PROCESS); # pw_properties_set(stream->properties, "mem.warn-mlock", impl->warn_mlock ? "true" : "false"); # #- # if ((pw_properties_get(stream->properties, PW_KEY_MEDIA_CLASS) == NULL)) { # const char *media_type = pw_properties_get(stream->properties, PW_KEY_MEDIA_TYPE); # pw_properties_setf(stream->properties, PW_KEY_MEDIA_CLASS, "Stream/%s/%s", @@ -1504,6 +1503,10 @@ pw_stream_connect(struct pw_stream *stream, pw_log_debug(NAME" %p: creating node", stream); props = pw_properties_copy(stream->properties); + if (props == NULL) { + res = -errno; + goto error_node; + } if ((str = pw_properties_get(props, PW_KEY_STREAM_MONITOR)) && pw_properties_parse_bool(str)) { @@ -1533,6 +1536,7 @@ pw_stream_connect(struct pw_stream *stream, PW_VERSION_NODE, props, 0); + props = NULL; if (impl->node == NULL) { res = -errno; goto error_node; @@ -1540,6 +1544,7 @@ pw_stream_connect(struct pw_stream *stream, } else { impl->node = follower; pw_properties_free(props); + props = NULL; } if (!SPA_FLAG_IS_SET(impl->flags, PW_STREAM_FLAG_INACTIVE)) pw_impl_node_set_active(impl->node, true); @@ -1560,12 +1565,17 @@ pw_stream_connect(struct pw_stream *stream, error_connect: pw_log_error(NAME" %p: can't connect: %s", stream, spa_strerror(res)); - return res; + goto exit_cleanup; error_node: pw_log_error(NAME" %p: can't make node: %s", stream, spa_strerror(res)); - return res; + goto exit_cleanup; error_proxy: pw_log_error(NAME" %p: can't make proxy: %s", stream, spa_strerror(res)); + goto exit_cleanup; + +exit_cleanup: + if (props) + pw_properties_free(props); return res; } ++++++ 0019-buffers-increase-max-datas-and-metadata-in-buffers.patch ++++++ >From dfd3bd84b466a03c9e5d31a2944fdd911ae77a8d Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Wed, 1 Jul 2020 11:40:13 +0200 Subject: [PATCH] buffers: increase max datas and metadata in buffers --- src/modules/module-client-node/client-node.c | 15 +++++++++------ src/pipewire/buffers.c | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 4415fab9..c39cee9b 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -50,6 +50,8 @@ #define MAX_OUTPUTS 64 #define MAX_BUFFERS 64 +#define MAX_METAS 16u +#define MAX_DATAS 64u #define MAX_AREAS 1024 #define MAX_MIX 128 @@ -72,8 +74,8 @@ struct buffer { struct spa_buffer *outbuf; struct spa_buffer buffer; - struct spa_meta metas[4]; - struct spa_data datas[4]; + struct spa_meta metas[MAX_METAS]; + struct spa_data datas[MAX_DATAS]; struct pw_memblock *mem; }; @@ -814,11 +816,12 @@ do_port_use_buffers(struct impl *impl, spa_log_debug(this->log, NAME" %p: buffer %d %d %d %d", this, i, mb[i].mem_id, mb[i].offset, mb[i].size); - for (j = 0; j < buffers[i]->n_metas; j++) + b->buffer.n_metas = SPA_MIN(buffers[i]->n_metas, MAX_METAS); + for (j = 0; j < b->buffer.n_metas; j++) memcpy(&b->buffer.metas[j], &buffers[i]->metas[j], sizeof(struct spa_meta)); - b->buffer.n_metas = j; - for (j = 0; j < buffers[i]->n_datas; j++) { + b->buffer.n_datas = SPA_MIN(buffers[i]->n_datas, MAX_DATAS); + for (j = 0; j < b->buffer.n_datas; j++) { struct spa_data *d = &buffers[i]->datas[j]; memcpy(&b->datas[j], d, sizeof(struct spa_data)); @@ -1070,7 +1073,7 @@ static int client_node_port_buffers(void *data, if (oldbuf->n_datas != newbuf->n_datas) return -EINVAL; - for (j = 0; j < newbuf->n_datas; j++) { + for (j = 0; j < b->buffer.n_datas; j++) { struct spa_chunk *oldchunk = oldbuf->datas[j].chunk; struct spa_data *d = &newbuf->datas[j]; diff --git a/src/pipewire/buffers.c b/src/pipewire/buffers.c index e95dfe38..08bf2236 100644 --- a/src/pipewire/buffers.c +++ b/src/pipewire/buffers.c @@ -39,7 +39,7 @@ #define NAME "buffers" #define MAX_ALIGN 32 -#define MAX_BLOCKS 4u +#define MAX_BLOCKS 64u struct port { struct spa_node *node; ++++++ 0020-gst-return-NULL-for-unknown-format.patch ++++++ >From a596cdbf2ef15bb90b19c470722b50524bb93261 Mon Sep 17 00:00:00 2001 From: Wim Taymans <[email protected]> Date: Mon, 13 Jul 2020 11:50:06 +0200 Subject: [PATCH] gst: return NULL for unknown format --- src/gst/gstpipewireformat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gst/gstpipewireformat.c b/src/gst/gstpipewireformat.c index 222bb9f2..2bd84bb3 100644 --- a/src/gst/gstpipewireformat.c +++ b/src/gst/gstpipewireformat.c @@ -858,6 +858,8 @@ gst_caps_from_format (const struct spa_pod *format) "stream-format", G_TYPE_STRING, "byte-stream", "alignment", G_TYPE_STRING, "au", NULL); + } else { + return NULL; } if ((prop = spa_pod_object_find_prop (obj, prop, SPA_FORMAT_VIDEO_size))) { handle_rect_prop (prop, "width", "height", res);
