From 2e4ef773aa0b1f5ce37a0650bbaf9e55dfc4c069 Mon Sep 17 00:00:00 2001 From: Sam James Date: Tue, 27 May 2025 07:26:43 +0100 Subject: [PATCH] media-video/pipewire: backport several patches to 1.4.3 Robert Mader (1): gst: src: Change DEFAULT_MIN_BUFFERS back to 1 Wim Taymans (4): pod: add bytes start/append/end functions Use "8 bit raw midi" for control ports again alsa: remove UMP flag from control format adapter: negotiate from target to follower Closes: https://bugs.gentoo.org/956654 Signed-off-by: Sam James --- ...add-bytes-start-append-end-functions.patch | 50 ++ ...bit-raw-midi-for-control-ports-again.patch | 265 ++++++++++ ...-remove-UMP-flag-from-control-format.patch | 451 ++++++++++++++++++ ...er-negotiate-from-target-to-follower.patch | 202 ++++++++ ...Change-DEFAULT_MIN_BUFFERS-back-to-1.patch | 39 ++ ...-1.4.3.ebuild => pipewire-1.4.3-r1.ebuild} | 0 6 files changed, 1007 insertions(+) create mode 100644 media-video/pipewire/files/1.4.3/0001-pod-add-bytes-start-append-end-functions.patch create mode 100644 media-video/pipewire/files/1.4.3/0002-Use-8-bit-raw-midi-for-control-ports-again.patch create mode 100644 media-video/pipewire/files/1.4.3/0003-alsa-remove-UMP-flag-from-control-format.patch create mode 100644 media-video/pipewire/files/1.4.3/0004-adapter-negotiate-from-target-to-follower.patch create mode 100644 media-video/pipewire/files/1.4.3/0005-gst-src-Change-DEFAULT_MIN_BUFFERS-back-to-1.patch rename media-video/pipewire/{pipewire-1.4.3.ebuild => pipewire-1.4.3-r1.ebuild} (100%) diff --git a/media-video/pipewire/files/1.4.3/0001-pod-add-bytes-start-append-end-functions.patch b/media-video/pipewire/files/1.4.3/0001-pod-add-bytes-start-append-end-functions.patch new file mode 100644 index 0000000000000..d0b413f6dc1bc --- /dev/null +++ b/media-video/pipewire/files/1.4.3/0001-pod-add-bytes-start-append-end-functions.patch @@ -0,0 +1,50 @@ +From 483b59a9d95aa084dfcd1c17e13ee27bd106d4b0 Mon Sep 17 00:00:00 2001 +Message-ID: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org> +From: Wim Taymans +Date: Fri, 23 May 2025 16:41:00 +0200 +Subject: [PATCH 1/5] pod: add bytes start/append/end functions + +Add functions to dynamically start and build a bytes pod. +--- + spa/include/spa/pod/builder.h | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/spa/include/spa/pod/builder.h b/spa/include/spa/pod/builder.h +index 553f75512..3dc4a4f1c 100644 +--- a/spa/include/spa/pod/builder.h ++++ b/spa/include/spa/pod/builder.h +@@ -326,6 +326,31 @@ spa_pod_builder_reserve_bytes(struct spa_pod_builder *builder, uint32_t len) + return SPA_POD_BODY(spa_pod_builder_deref(builder, offset)); + } + ++SPA_API_POD_BUILDER uint32_t ++spa_pod_builder_bytes_start(struct spa_pod_builder *builder) ++{ ++ uint32_t offset = builder->state.offset; ++ const struct spa_pod_bytes p = SPA_POD_INIT_Bytes(0); ++ spa_pod_builder_raw(builder, &p, sizeof(p)); ++ return offset; ++} ++SPA_API_POD_BUILDER int ++spa_pod_builder_bytes_append(struct spa_pod_builder *builder, uint32_t offset, ++ const void *data, uint32_t size) ++{ ++ int res = spa_pod_builder_raw(builder, data, size); ++ struct spa_pod *pod = spa_pod_builder_deref(builder, offset); ++ if (pod) ++ pod->size += size; ++ return res; ++} ++ ++SPA_API_POD_BUILDER int ++spa_pod_builder_bytes_end(struct spa_pod_builder *builder, uint32_t offset) ++{ ++ return spa_pod_builder_pad(builder, builder->state.offset); ++} ++ + #define SPA_POD_INIT_Pointer(type,value) ((struct spa_pod_pointer){ { sizeof(struct spa_pod_pointer_body), SPA_TYPE_Pointer }, { (type), 0, (value) } }) + + SPA_API_POD_BUILDER int +-- +2.49.0 + diff --git a/media-video/pipewire/files/1.4.3/0002-Use-8-bit-raw-midi-for-control-ports-again.patch b/media-video/pipewire/files/1.4.3/0002-Use-8-bit-raw-midi-for-control-ports-again.patch new file mode 100644 index 0000000000000..54361ee977b35 --- /dev/null +++ b/media-video/pipewire/files/1.4.3/0002-Use-8-bit-raw-midi-for-control-ports-again.patch @@ -0,0 +1,265 @@ +From 76db05a0f8edb8b7d4d896d3860bc555934ad383 Mon Sep 17 00:00:00 2001 +Message-ID: <76db05a0f8edb8b7d4d896d3860bc555934ad383.1748327071.git.sam@gentoo.org> +In-Reply-To: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org> +References: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org> +From: Wim Taymans +Date: Fri, 23 May 2025 16:46:13 +0200 +Subject: [PATCH 2/5] Use "8 bit raw midi" for control ports again + +There is no need to encode the potential format in the format.dsp of +control ports, this is just for legacy compatibility with JACK apps. The +actual format can be negotiated with the types field. + +Fixes midi port visibility with apps compiled against 1.2, such as JACK +apps in flatpaks. +--- + pipewire-jack/src/pipewire-jack.c | 20 +------------------ + spa/plugins/alsa/alsa-seq-bridge.c | 2 +- + spa/plugins/audioconvert/audioconvert.c | 2 +- + spa/plugins/bluez5/midi-node.c | 4 ++-- + .../videoconvert/videoconvert-ffmpeg.c | 2 +- + src/examples/midi-src.c | 2 +- + src/modules/module-ffado-driver.c | 2 +- + src/modules/module-jack-tunnel.c | 2 +- + src/modules/module-netjack2-driver.c | 2 +- + src/modules/module-netjack2-manager.c | 2 +- + src/modules/module-rtp/stream.c | 2 +- + src/modules/module-vban/stream.c | 2 +- + src/pipewire/filter.c | 4 +++- + src/pipewire/stream.c | 2 +- + src/tools/pw-cat.c | 2 +- + 15 files changed, 18 insertions(+), 34 deletions(-) + +diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c +index 14c062a21..b859b64b0 100644 +--- a/pipewire-jack/src/pipewire-jack.c ++++ b/pipewire-jack/src/pipewire-jack.c +@@ -3466,24 +3466,6 @@ static const char* type_to_string(jack_port_type_id_t type_id) + } + } + +-static const char* type_to_format_dsp(jack_port_type_id_t type_id) +-{ +- switch(type_id) { +- case TYPE_ID_AUDIO: +- return JACK_DEFAULT_AUDIO_TYPE; +- case TYPE_ID_VIDEO: +- return JACK_DEFAULT_VIDEO_TYPE; +- case TYPE_ID_OSC: +- return JACK_DEFAULT_OSC_TYPE; +- case TYPE_ID_MIDI: +- return JACK_DEFAULT_MIDI_TYPE; +- case TYPE_ID_UMP: +- return JACK_DEFAULT_UMP_TYPE; +- default: +- return NULL; +- } +-} +- + static bool type_is_dsp(jack_port_type_id_t type_id) + { + switch(type_id) { +@@ -5544,7 +5526,7 @@ jack_port_t * jack_port_register (jack_client_t *client, + + spa_list_init(&p->mix); + +- pw_properties_set(p->props, PW_KEY_FORMAT_DSP, type_to_format_dsp(type_id)); ++ pw_properties_set(p->props, PW_KEY_FORMAT_DSP, type_to_string(type_id)); + pw_properties_set(p->props, PW_KEY_PORT_NAME, port_name); + if (flags > 0x1f) { + pw_properties_setf(p->props, PW_KEY_PORT_EXTRA, +diff --git a/spa/plugins/alsa/alsa-seq-bridge.c b/spa/plugins/alsa/alsa-seq-bridge.c +index 7ec39321c..68e6c91a8 100644 +--- a/spa/plugins/alsa/alsa-seq-bridge.c ++++ b/spa/plugins/alsa/alsa-seq-bridge.c +@@ -275,7 +275,7 @@ static void emit_port_info(struct seq_state *this, struct seq_port *port, bool f + snprintf(alias, sizeof(alias), "%s:%s", client_name, port_name); + clean_name(alias); + +- items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"); ++ items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"); + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_OBJECT_PATH, path); + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, name); + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_ALIAS, alias); +diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c +index c1fa022d1..c36028bcd 100644 +--- a/spa/plugins/audioconvert/audioconvert.c ++++ b/spa/plugins/audioconvert/audioconvert.c +@@ -362,7 +362,7 @@ static void emit_port_info(struct impl *this, struct port *port, bool full) + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_IGNORE_LATENCY, "true"); + } else if (PORT_IS_CONTROL(this, port->direction, port->id)) { + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, "control"); +- items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"); ++ items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"); + } + if (this->group_name[0] != '\0') + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, this->group_name); +diff --git a/spa/plugins/bluez5/midi-node.c b/spa/plugins/bluez5/midi-node.c +index b5fd179ea..cfba2bfcf 100644 +--- a/spa/plugins/bluez5/midi-node.c ++++ b/spa/plugins/bluez5/midi-node.c +@@ -2024,13 +2024,13 @@ impl_init(const struct spa_handle_factory *factory, + for (i = 0; i < N_PORTS; ++i) { + struct port *port = &this->ports[i]; + static const struct spa_dict_item in_port_items[] = { +- SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"), ++ SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"), + SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, "in"), + SPA_DICT_ITEM_INIT(SPA_KEY_PORT_ALIAS, "in"), + SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, "group.0"), + }; + static const struct spa_dict_item out_port_items[] = { +- SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"), ++ SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"), + SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, "out"), + SPA_DICT_ITEM_INIT(SPA_KEY_PORT_ALIAS, "out"), + SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, "group.0"), +diff --git a/spa/plugins/videoconvert/videoconvert-ffmpeg.c b/spa/plugins/videoconvert/videoconvert-ffmpeg.c +index ddb810be5..3da0e5677 100644 +--- a/spa/plugins/videoconvert/videoconvert-ffmpeg.c ++++ b/spa/plugins/videoconvert/videoconvert-ffmpeg.c +@@ -228,7 +228,7 @@ static void emit_port_info(struct impl *this, struct port *port, bool full) + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_IGNORE_LATENCY, "true"); + } else if (PORT_IS_CONTROL(this, port->direction, port->id)) { + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, "control"); +- items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"); ++ items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"); + } + if (this->group_name[0] != '\0') + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, this->group_name); +diff --git a/src/examples/midi-src.c b/src/examples/midi-src.c +index edcaa0f08..12f86d6f2 100644 +--- a/src/examples/midi-src.c ++++ b/src/examples/midi-src.c +@@ -213,7 +213,7 @@ int main(int argc, char *argv[]) + PW_FILTER_PORT_FLAG_MAP_BUFFERS, + sizeof(struct port), + pw_properties_new( +- PW_KEY_FORMAT_DSP, "32 bit raw UMP", ++ PW_KEY_FORMAT_DSP, "8 bit raw midi", + PW_KEY_PORT_NAME, "output", + NULL), + NULL, 0); +diff --git a/src/modules/module-ffado-driver.c b/src/modules/module-ffado-driver.c +index 4345e5a19..1c9c7c590 100644 +--- a/src/modules/module-ffado-driver.c ++++ b/src/modules/module-ffado-driver.c +@@ -772,7 +772,7 @@ static int make_stream_ports(struct stream *s) + break; + case ffado_stream_type_midi: + props = pw_properties_new( +- PW_KEY_FORMAT_DSP, "32 bit raw UMP", ++ PW_KEY_FORMAT_DSP, "8 bit raw midi", + PW_KEY_PORT_NAME, port->name, + PW_KEY_PORT_PHYSICAL, "true", + PW_KEY_PORT_TERMINAL, "true", +diff --git a/src/modules/module-jack-tunnel.c b/src/modules/module-jack-tunnel.c +index 7ab4c9faf..76ac73c8d 100644 +--- a/src/modules/module-jack-tunnel.c ++++ b/src/modules/module-jack-tunnel.c +@@ -515,7 +515,7 @@ static void make_stream_ports(struct stream *s) + } else { + snprintf(name, sizeof(name), "%s_%d", prefix, i - s->info.channels); + props = pw_properties_new( +- PW_KEY_FORMAT_DSP, "32 bit raw UMP", ++ PW_KEY_FORMAT_DSP, "8 bit raw midi", + PW_KEY_PORT_NAME, name, + PW_KEY_PORT_PHYSICAL, "true", + NULL); +diff --git a/src/modules/module-netjack2-driver.c b/src/modules/module-netjack2-driver.c +index 0aa9a85cd..011052e7b 100644 +--- a/src/modules/module-netjack2-driver.c ++++ b/src/modules/module-netjack2-driver.c +@@ -452,7 +452,7 @@ static void make_stream_ports(struct stream *s) + } else { + snprintf(name, sizeof(name), "midi%d", i - s->info.channels); + props = pw_properties_new( +- PW_KEY_FORMAT_DSP, "32 bit raw UMP", ++ PW_KEY_FORMAT_DSP, "8 bit raw midi", + PW_KEY_AUDIO_CHANNEL, name, + PW_KEY_PORT_PHYSICAL, "true", + NULL); +diff --git a/src/modules/module-netjack2-manager.c b/src/modules/module-netjack2-manager.c +index 2cef87218..fe482fd94 100644 +--- a/src/modules/module-netjack2-manager.c ++++ b/src/modules/module-netjack2-manager.c +@@ -614,7 +614,7 @@ static void make_stream_ports(struct stream *s) + } else { + snprintf(name, sizeof(name), "midi%d", i - s->info.channels); + props = pw_properties_new( +- PW_KEY_FORMAT_DSP, "32 bit raw UMP", ++ PW_KEY_FORMAT_DSP, "8 bit raw midi", + PW_KEY_PORT_PHYSICAL, "true", + PW_KEY_AUDIO_CHANNEL, name, + NULL); +diff --git a/src/modules/module-rtp/stream.c b/src/modules/module-rtp/stream.c +index f4d3fa3b8..cbd3ee994 100644 +--- a/src/modules/module-rtp/stream.c ++++ b/src/modules/module-rtp/stream.c +@@ -390,7 +390,7 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core, + res = -EINVAL; + goto out; + } +- pw_properties_set(props, PW_KEY_FORMAT_DSP, "32 bit raw UMP"); ++ pw_properties_set(props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); + impl->stride = impl->format_info->size; + impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000); + if (impl->rate == 0) +diff --git a/src/modules/module-vban/stream.c b/src/modules/module-vban/stream.c +index efa5af370..10eb34a82 100644 +--- a/src/modules/module-vban/stream.c ++++ b/src/modules/module-vban/stream.c +@@ -307,7 +307,7 @@ struct vban_stream *vban_stream_new(struct pw_core *core, + res = -EINVAL; + goto out; + } +- pw_properties_set(props, PW_KEY_FORMAT_DSP, "32 bit raw UMP"); ++ pw_properties_set(props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); + impl->stride = impl->format_info->size; + impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000); + if (impl->rate == 0) +diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c +index 519c1e2f7..03706e98a 100644 +--- a/src/pipewire/filter.c ++++ b/src/pipewire/filter.c +@@ -1855,8 +1855,10 @@ void *pw_filter_add_port(struct pw_filter *filter, + add_control_dsp_port_params(impl, p, 1u << SPA_CONTROL_Midi); + else if (spa_streq(str, "8 bit raw control")) + add_control_dsp_port_params(impl, p, 0); +- else if (spa_streq(str, "32 bit raw UMP")) ++ else if (spa_streq(str, "32 bit raw UMP")) { + add_control_dsp_port_params(impl, p, 1u << SPA_CONTROL_UMP); ++ pw_properties_set(props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); ++ } + } + /* then override with user provided if any */ + if (update_params(impl, p, SPA_ID_INVALID, params, n_params) < 0) +diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c +index 4af3a3afa..f5684d5e7 100644 +--- a/src/pipewire/stream.c ++++ b/src/pipewire/stream.c +@@ -2053,7 +2053,7 @@ pw_stream_connect(struct pw_stream *stream, + pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, str); + else if (impl->media_type == SPA_MEDIA_TYPE_application && + impl->media_subtype == SPA_MEDIA_SUBTYPE_control) +- pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, "32 bit raw UMP"); ++ pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); + if (pw_properties_get(impl->port_props, PW_KEY_PORT_GROUP) == NULL) + pw_properties_set(impl->port_props, PW_KEY_PORT_GROUP, "stream.0"); + +diff --git a/src/tools/pw-cat.c b/src/tools/pw-cat.c +index 36a78981e..928afed0e 100644 +--- a/src/tools/pw-cat.c ++++ b/src/tools/pw-cat.c +@@ -1985,7 +1985,7 @@ int main(int argc, char *argv[]) + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); + +- pw_properties_set(data.props, PW_KEY_FORMAT_DSP, "32 bit raw UMP"); ++ pw_properties_set(data.props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); + break; + case TYPE_DSD: + { +-- +2.49.0 + diff --git a/media-video/pipewire/files/1.4.3/0003-alsa-remove-UMP-flag-from-control-format.patch b/media-video/pipewire/files/1.4.3/0003-alsa-remove-UMP-flag-from-control-format.patch new file mode 100644 index 0000000000000..f29487147a3b6 --- /dev/null +++ b/media-video/pipewire/files/1.4.3/0003-alsa-remove-UMP-flag-from-control-format.patch @@ -0,0 +1,451 @@ +From 06941f7315c3ca814771cc8b6612c3d01a8bf968 Mon Sep 17 00:00:00 2001 +Message-ID: <06941f7315c3ca814771cc8b6612c3d01a8bf968.1748327071.git.sam@gentoo.org> +In-Reply-To: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org> +References: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org> +From: Wim Taymans +Date: Fri, 23 May 2025 16:53:42 +0200 +Subject: [PATCH 3/5] alsa: remove UMP flag from control format + +Don't set the UMP type flag on the format. Use the negotiated types flag +to decide what format to output. Add support for output to old style +midi. + +Set the UMP type flag only on the new mixer and JACK when UMP is +enabled. + +This ensures that only new (or explicitly requesting) apps get UMP and +old apps receive old midi. + +This makes JACK running on 1.2 in flatpaks work with midi again. +--- + pipewire-jack/src/pipewire-jack.c | 23 ++++- + spa/plugins/alsa/alsa-seq-bridge.c | 13 +-- + spa/plugins/alsa/alsa-seq.c | 159 ++++++++++++++++++++--------- + spa/plugins/alsa/alsa-seq.h | 3 + + spa/plugins/control/mixer.c | 3 +- + src/modules/module-jack-tunnel.c | 33 +++--- + 6 files changed, 157 insertions(+), 77 deletions(-) + +diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c +index b859b64b0..695938f90 100644 +--- a/pipewire-jack/src/pipewire-jack.c ++++ b/pipewire-jack/src/pipewire-jack.c +@@ -2549,11 +2549,28 @@ static int param_enum_format(struct client *c, struct port *p, + case TYPE_ID_UMP: + case TYPE_ID_OSC: + case TYPE_ID_MIDI: +- *param = spa_pod_builder_add_object(b, +- SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, ++ { ++ struct spa_pod_frame f; ++ int32_t types = 0; ++ ++ spa_pod_builder_push_object(b, &f, ++ SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat); ++ spa_pod_builder_add(b, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), +- SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); ++ SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control), ++ 0); ++ if (p->object->port.type_id == TYPE_ID_UMP) ++ types |= 1u<object->port.type_id == TYPE_ID_OSC) ++ types |= 1u<have_format = false; + } else { + struct spa_audio_info info = { 0 }; +- uint32_t types; ++ uint32_t types = 0; + + if ((err = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0) + return err; +@@ -646,13 +644,12 @@ static int port_set_format(void *object, struct seq_port *port, + + if ((err = spa_pod_parse_object(format, + SPA_TYPE_OBJECT_Format, NULL, +- SPA_FORMAT_CONTROL_types, SPA_POD_Int(&types))) < 0) ++ SPA_FORMAT_CONTROL_types, SPA_POD_OPT_Int(&types))) < 0) + return err; +- if (types != 1u << SPA_CONTROL_UMP) +- return -EINVAL; + + port->current_format = info; + port->have_format = true; ++ port->control_types = types; + } + + port->info.change_mask |= SPA_PORT_CHANGE_MASK_RATE; +diff --git a/spa/plugins/alsa/alsa-seq.c b/spa/plugins/alsa/alsa-seq.c +index 04280f291..75d9c604a 100644 +--- a/spa/plugins/alsa/alsa-seq.c ++++ b/spa/plugins/alsa/alsa-seq.c +@@ -586,7 +586,8 @@ static int prepare_buffer(struct seq_state *state, struct seq_port *port) + spa_pod_builder_init(&port->builder, + port->buffer->buf->datas[0].data, + port->buffer->buf->datas[0].maxsize); +- spa_pod_builder_push_sequence(&port->builder, &port->frame, 0); ++ spa_pod_builder_push_sequence(&port->builder, &port->frame, 0); ++ port->ev_offset = SPA_IDX_INVALID; + + return 0; + } +@@ -620,10 +621,8 @@ static int process_read(struct seq_state *state) + struct seq_stream *stream = &state->streams[SPA_DIRECTION_OUTPUT]; + const bool ump = state->ump; + uint32_t i; +- uint32_t *data; + uint8_t midi1_data[MAX_EVENT_SIZE]; + uint32_t ump_data[MAX_EVENT_SIZE]; +- long size; + int res = -1; + + /* copy all new midi events into their port buffers */ +@@ -631,10 +630,11 @@ static int process_read(struct seq_state *state) + const snd_seq_addr_t *addr; + struct seq_port *port; + uint64_t ev_time, diff; +- uint32_t offset; ++ uint32_t offset, ev_type; + void *event; +- uint8_t *midi1_ptr; +- size_t midi1_size = 0; ++ uint8_t *data_ptr; ++ size_t data_size = 0; ++ long size; + uint64_t ump_state = 0; + snd_seq_event_type_t SPA_UNUSED type; + +@@ -679,7 +679,7 @@ static int process_read(struct seq_state *state) + continue; + + if ((res = prepare_buffer(state, port)) < 0) { +- spa_log_debug(state->log, "can't prepare buffer port:%p %d.%d: %s", ++ spa_log_warn(state->log, "can't prepare buffer port:%p %d.%d: %s", + port, addr->client, addr->port, spa_strerror(res)); + continue; + } +@@ -702,8 +702,8 @@ static int process_read(struct seq_state *state) + #ifdef HAVE_ALSA_UMP + snd_seq_ump_event_t *ev = event; + +- data = (uint32_t*)&ev->ump[0]; +- size = spa_ump_message_size(snd_ump_msg_hdr_type(ev->ump[0])) * 4; ++ data_ptr = (uint8_t*)&ev->ump[0]; ++ data_size = spa_ump_message_size(snd_ump_msg_hdr_type(ev->ump[0])) * 4; + #else + spa_assert_not_reached(); + #endif +@@ -712,40 +712,69 @@ static int process_read(struct seq_state *state) + + snd_midi_event_reset_decode(stream->codec); + if ((size = snd_midi_event_decode(stream->codec, midi1_data, sizeof(midi1_data), ev)) < 0) { +- spa_log_warn(state->log, "decode failed: %s", snd_strerror(size)); ++ spa_log_warn(state->log, "decode failed: %s", snd_strerror(data_size)); + continue; + } ++ data_ptr = midi1_data; ++ data_size = size; ++ } ++ ++ ev_type = (port->control_types & (1u << SPA_CONTROL_UMP)) ? ++ SPA_CONTROL_UMP : SPA_CONTROL_Midi; + +- midi1_ptr = midi1_data; +- midi1_size = size; ++ spa_log_trace_fp(state->log, "event %d time:%"PRIu64" offset:%d size:%ld port:%d.%d", ++ type, ev_time, offset, data_size, addr->client, addr->port); ++ ++ if ((ump && ev_type == SPA_CONTROL_UMP) || ++ (!ump && ev_type == SPA_CONTROL_Midi)) { ++ /* no conversion needed */ ++ spa_pod_builder_control(&port->builder, offset, ev_type); ++ spa_pod_builder_bytes(&port->builder, data_ptr, data_size); + } ++ else if (ump) { ++ bool continued = port->ev_offset != SPA_IDX_INVALID; ++ ++ /* UMP -> MIDI */ ++ size = spa_ump_to_midi((uint32_t*)data_ptr, data_size, ++ midi1_data, sizeof(midi1_data)); ++ if (size < 0) ++ continue; ++ ++ if (!continued) { ++ spa_pod_builder_control(&port->builder, offset, ev_type); ++ port->ev_offset = spa_pod_builder_bytes_start(&port->builder); ++ if (midi1_data[0] == 0xf0) ++ continued = true; ++ } else { ++ if (midi1_data[size-1] == 0xf7) ++ continued = false; ++ } ++ spa_pod_builder_bytes_append(&port->builder, port->ev_offset, midi1_data, size); + +- do { +- if (!ump) { +- data = ump_data; +- size = spa_ump_from_midi(&midi1_ptr, &midi1_size, ++ if (!continued) { ++ spa_pod_builder_bytes_end(&port->builder, port->ev_offset); ++ port->ev_offset = SPA_IDX_INVALID; ++ } ++ } else { ++ /* MIDI -> UMP */ ++ while (data_size > 0) { ++ size = spa_ump_from_midi(&data_ptr, &data_size, + ump_data, sizeof(ump_data), 0, &ump_state); + if (size <= 0) + break; +- } +- +- spa_log_trace_fp(state->log, "event %d time:%"PRIu64" offset:%d size:%ld port:%d.%d", +- type, ev_time, offset, size, addr->client, addr->port); + +- spa_pod_builder_control(&port->builder, offset, SPA_CONTROL_UMP); +- spa_pod_builder_bytes(&port->builder, data, size); +- +- /* make sure we can fit at least one control event of max size otherwise +- * we keep the event in the queue and try to copy it in the next cycle */ +- if (port->builder.state.offset + +- sizeof(struct spa_pod_control) + +- MAX_EVENT_SIZE > port->buffer->buf->datas[0].maxsize) +- goto done; ++ spa_pod_builder_control(&port->builder, offset, ev_type); ++ spa_pod_builder_bytes(&port->builder, ump_data, size); ++ } ++ } + +- } while (!ump); ++ /* make sure we can fit at least one control event of max size otherwise ++ * we keep the event in the queue and try to copy it in the next cycle */ ++ if (port->builder.state.offset + ++ sizeof(struct spa_pod_control) + ++ MAX_EVENT_SIZE > port->buffer->buf->datas[0].maxsize) ++ break; + } +- +-done: + if (res < 0 && res != -EAGAIN) + spa_log_warn(state->log, "event read failed: %s", snd_strerror(res)); + +@@ -760,6 +789,8 @@ done: + continue; + + if (prepare_buffer(state, port) >= 0) { ++ if (port->ev_offset != SPA_IDX_INVALID) ++ spa_pod_builder_bytes_end(&port->builder, port->ev_offset); + spa_pod_builder_pop(&port->builder, &port->frame); + + port->buffer->buf->datas[0].chunk->offset = 0; +@@ -846,9 +877,7 @@ static int process_write(struct seq_state *state) + SPA_POD_SEQUENCE_FOREACH(pod, c) { + size_t body_size; + uint8_t *body; +- +- if (c->type != SPA_CONTROL_UMP) +- continue; ++ int size; + + body = SPA_POD_BODY(&c->value); + body_size = SPA_POD_BODY_SIZE(&c->value); +@@ -862,33 +891,67 @@ static int process_write(struct seq_state *state) + + if (ump) { + #ifdef HAVE_ALSA_UMP ++ uint8_t *ump_data; ++ uint32_t data[MAX_EVENT_SIZE]; + snd_seq_ump_event_t ev; + +- snd_seq_ump_ev_clear(&ev); +- snd_seq_ev_set_ump_data(&ev, body, SPA_MIN(sizeof(ev.ump), (size_t)body_size)); +- snd_seq_ev_set_source(&ev, state->event.addr.port); +- snd_seq_ev_set_dest(&ev, port->addr.client, port->addr.port); +- snd_seq_ev_schedule_real(&ev, state->event.queue_id, 0, &out_rt); +- +- if ((err = snd_seq_ump_event_output(state->event.hndl, &ev)) < 0) { +- spa_log_warn(state->log, "failed to output event: %s", +- snd_strerror(err)); +- } ++ do { ++ switch (c->type) { ++ case SPA_CONTROL_UMP: ++ ump_data = body; ++ size = body_size; ++ body_size = 0; ++ break; ++ case SPA_CONTROL_Midi: ++ size = spa_ump_from_midi(&body, &body_size, ++ data, sizeof(data), 0, &port->ump_state); ++ ump_data = (uint8_t*)data; ++ break; ++ default: ++ size = 0; ++ body_size = 0; ++ continue; ++ } ++ if (size <= 0) ++ break; ++ ++ snd_seq_ump_ev_clear(&ev); ++ snd_seq_ev_set_ump_data(&ev, ump_data, SPA_MIN(sizeof(ev.ump), (size_t)size)); ++ snd_seq_ev_set_source(&ev, state->event.addr.port); ++ snd_seq_ev_set_dest(&ev, port->addr.client, port->addr.port); ++ snd_seq_ev_schedule_real(&ev, state->event.queue_id, 0, &out_rt); ++ ++ if ((err = snd_seq_ump_event_output(state->event.hndl, &ev)) < 0) { ++ spa_log_warn(state->log, "failed to output event: %s", ++ snd_strerror(err)); ++ } ++ } while (body_size > 0); + #else + spa_assert_not_reached(); + #endif + } else { + snd_seq_event_t ev; + uint8_t data[MAX_EVENT_SIZE]; +- int size; ++ uint8_t *midi_data; + +- if ((size = spa_ump_to_midi((uint32_t *)body, body_size, data, sizeof(data))) <= 0) ++ switch (c->type) { ++ case SPA_CONTROL_UMP: ++ if ((size = spa_ump_to_midi((uint32_t *)body, body_size, data, sizeof(data))) <= 0) ++ continue; ++ midi_data = data; ++ break; ++ case SPA_CONTROL_Midi: ++ midi_data = body; ++ size = body_size; ++ break; ++ default: + continue; ++ } + + if (first) + snd_seq_ev_clear(&ev); + +- if ((size = snd_midi_event_encode(stream->codec, data, size, &ev)) < 0) { ++ if ((size = snd_midi_event_encode(stream->codec, midi_data, size, &ev)) < 0) { + spa_log_warn(state->log, "failed to encode event: %s", snd_strerror(size)); + snd_midi_event_reset_encode(stream->codec); + first = true; +diff --git a/spa/plugins/alsa/alsa-seq.h b/spa/plugins/alsa/alsa-seq.h +index 274311c70..7e9fc4297 100644 +--- a/spa/plugins/alsa/alsa-seq.h ++++ b/spa/plugins/alsa/alsa-seq.h +@@ -80,7 +80,10 @@ struct seq_port { + struct buffer *buffer; + struct spa_pod_builder builder; + struct spa_pod_frame frame; ++ uint32_t ev_offset; ++ uint64_t ump_state; + ++ uint32_t control_types; + struct spa_audio_info current_format; + unsigned int have_format:1; + unsigned int valid:1; +diff --git a/spa/plugins/control/mixer.c b/spa/plugins/control/mixer.c +index e97072d45..cfe3c394b 100644 +--- a/spa/plugins/control/mixer.c ++++ b/spa/plugins/control/mixer.c +@@ -298,7 +298,8 @@ static int port_enum_formats(void *object, struct port *port, + *param = spa_pod_builder_add_object(builder, + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), +- SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); ++ SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control), ++ SPA_FORMAT_CONTROL_types, SPA_POD_CHOICE_FLAGS_Int(SPA_ID_INVALID)); + break; + default: + return 0; +diff --git a/src/modules/module-jack-tunnel.c b/src/modules/module-jack-tunnel.c +index 76ac73c8d..7cce66b0b 100644 +--- a/src/modules/module-jack-tunnel.c ++++ b/src/modules/module-jack-tunnel.c +@@ -247,7 +247,6 @@ static void midi_to_jack(struct impl *impl, float *dst, float *src, uint32_t n_s + struct spa_pod_sequence *seq; + struct spa_pod_control *c; + int res; +- bool in_sysex = false; + uint8_t tmp[n_samples * 4]; + size_t tmp_size = 0; + +@@ -267,23 +266,23 @@ static void midi_to_jack(struct impl *impl, float *dst, float *src, uint32_t n_s + + if (c->type != SPA_CONTROL_UMP) + continue; ++ switch (c->type) { ++ case SPA_CONTROL_UMP: ++ size = spa_ump_to_midi(SPA_POD_BODY(&c->value), ++ SPA_POD_BODY_SIZE(&c->value), &tmp[tmp_size], sizeof(tmp) - tmp_size); ++ if (size <= 0) ++ continue; ++ tmp_size += size; ++ break; ++ case SPA_CONTROL_Midi: ++ tmp_size = SPA_POD_BODY_SIZE(&c->value); ++ memcpy(tmp, SPA_POD_BODY(&c->value), SPA_MIN(sizeof(tmp), tmp_size)); ++ break; ++ } + +- size = spa_ump_to_midi(SPA_POD_BODY(&c->value), +- SPA_POD_BODY_SIZE(&c->value), &tmp[tmp_size], sizeof(tmp) - tmp_size); +- if (size <= 0) +- continue; +- +- if (impl->fix_midi) +- fix_midi_event(&tmp[tmp_size], size); +- +- if (!in_sysex && tmp[tmp_size] == 0xf0) +- in_sysex = true; +- +- tmp_size += size; +- if (in_sysex && tmp[tmp_size-1] == 0xf7) +- in_sysex = false; +- +- if (!in_sysex) { ++ if (tmp[0] != 0xf0 || tmp[tmp_size-1] == 0xf7) { ++ if (impl->fix_midi) ++ fix_midi_event(tmp, tmp_size); + if ((res = jack.midi_event_write(dst, c->offset, tmp, tmp_size)) < 0) + pw_log_warn("midi %p: can't write event: %s", dst, + spa_strerror(res)); +-- +2.49.0 + diff --git a/media-video/pipewire/files/1.4.3/0004-adapter-negotiate-from-target-to-follower.patch b/media-video/pipewire/files/1.4.3/0004-adapter-negotiate-from-target-to-follower.patch new file mode 100644 index 0000000000000..81577ad1a0d24 --- /dev/null +++ b/media-video/pipewire/files/1.4.3/0004-adapter-negotiate-from-target-to-follower.patch @@ -0,0 +1,202 @@ +From c507c4b0ffa094d92c76ad4589ad776b677d94d2 Mon Sep 17 00:00:00 2001 +Message-ID: +In-Reply-To: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org> +References: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org> +From: Wim Taymans +Date: Mon, 26 May 2025 15:44:51 +0200 +Subject: [PATCH 4/5] adapter: negotiate from target to follower + +Since 3abda54d80cb02cacb25b9a66ce2808dc4615b34 we prefer the format +of the filter. This reverses the selection of the default value when +negotiating buffers from the target to the follower. + +If the follower does not select a reasonable value for the buffer size, +for example, this then results in wrongly sized buffers. + +Fix this by reversing the order of allocation from target to follower +where we let the target (converter) select a default value, which is +more likely to be correct. + +See #4713, #4619 +--- + spa/plugins/audioconvert/audioadapter.c | 39 ++++++++----------------- + spa/plugins/videoconvert/videoadapter.c | 39 ++++++++----------------- + 2 files changed, 24 insertions(+), 54 deletions(-) + +diff --git a/spa/plugins/audioconvert/audioadapter.c b/spa/plugins/audioconvert/audioadapter.c +index 43a47e25c..f15d5a4ca 100644 +--- a/spa/plugins/audioconvert/audioadapter.c ++++ b/spa/plugins/audioconvert/audioadapter.c +@@ -442,8 +442,8 @@ static int negotiate_buffers(struct impl *this) + + state = 0; + param = NULL; +- if ((res = node_port_enum_params_sync(this, this->follower, +- this->direction, 0, ++ if ((res = node_port_enum_params_sync(this, this->target, ++ SPA_DIRECTION_REVERSE(this->direction), 0, + SPA_PARAM_Buffers, &state, + param, ¶m, &b)) < 0) { + if (res == -ENOENT) +@@ -456,8 +456,8 @@ static int negotiate_buffers(struct impl *this) + } + + state = 0; +- if ((res = node_port_enum_params_sync(this, this->target, +- SPA_DIRECTION_REVERSE(this->direction), 0, ++ if ((res = node_port_enum_params_sync(this, this->follower, ++ this->direction, 0, + SPA_PARAM_Buffers, &state, + param, ¶m, &b)) != 1) { + debug_params(this, this->target, +@@ -497,7 +497,7 @@ static int negotiate_buffers(struct impl *this) + if (this->async) + buffers = SPA_MAX(2u, buffers); + +- spa_log_debug(this->log, "%p: buffers:%d, blocks:%d, size:%d, stride:%d align:%d %d:%d", ++ spa_log_info(this->log, "%p: buffers:%d, blocks:%d, size:%d, stride:%d align:%d %d:%d", + this, buffers, blocks, size, stride, align, follower_alloc, conv_alloc); + + align = SPA_MAX(align, this->max_align); +@@ -941,27 +941,13 @@ static int negotiate_format(struct impl *this) + spa_node_send_command(this->follower, + &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_ParamBegin)); + +- /* first try the ideal converter format, which is likely passthrough */ +- tstate = 0; +- fres = node_port_enum_params_sync(this, this->target, +- SPA_DIRECTION_REVERSE(this->direction), 0, +- SPA_PARAM_EnumFormat, &tstate, +- NULL, &format, &b); +- if (fres == 1) { +- fstate = 0; +- res = node_port_enum_params_sync(this, this->follower, +- this->direction, 0, +- SPA_PARAM_EnumFormat, &fstate, +- format, &format, &b); +- if (res == 1) +- goto found; +- } +- +- /* then try something the follower can accept */ ++ /* The target has been negotiated on its other ports and so it can propose ++ * a passthrough format or an ideal conversion. We use the suggestions of the ++ * target to find the best follower format */ + for (fstate = 0;;) { + format = NULL; +- res = node_port_enum_params_sync(this, this->follower, +- this->direction, 0, ++ res = node_port_enum_params_sync(this, this->target, ++ SPA_DIRECTION_REVERSE(this->direction), 0, + SPA_PARAM_EnumFormat, &fstate, + NULL, &format, &b); + +@@ -971,8 +957,8 @@ static int negotiate_format(struct impl *this) + break; + + tstate = 0; +- fres = node_port_enum_params_sync(this, this->target, +- SPA_DIRECTION_REVERSE(this->direction), 0, ++ fres = node_port_enum_params_sync(this, this->follower, ++ this->direction, 0, + SPA_PARAM_EnumFormat, &tstate, + format, &format, &b); + if (fres == 0 && res == 1) +@@ -981,7 +967,6 @@ static int negotiate_format(struct impl *this) + res = fres; + break; + } +-found: + if (format == NULL) { + debug_params(this, this->follower, this->direction, 0, + SPA_PARAM_EnumFormat, format, "follower format", res); +diff --git a/spa/plugins/videoconvert/videoadapter.c b/spa/plugins/videoconvert/videoadapter.c +index 078c90553..e10a8adf5 100644 +--- a/spa/plugins/videoconvert/videoadapter.c ++++ b/spa/plugins/videoconvert/videoadapter.c +@@ -416,8 +416,8 @@ static int negotiate_buffers(struct impl *this) + + state = 0; + param = NULL; +- if ((res = spa_node_port_enum_params_sync(this->follower, +- this->direction, 0, ++ if ((res = spa_node_port_enum_params_sync(this->target, ++ SPA_DIRECTION_REVERSE(this->direction), 0, + SPA_PARAM_Buffers, &state, + param, ¶m, &b)) < 0) { + if (res == -ENOENT) +@@ -430,8 +430,8 @@ static int negotiate_buffers(struct impl *this) + } + + state = 0; +- if ((res = spa_node_port_enum_params_sync(this->target, +- SPA_DIRECTION_REVERSE(this->direction), 0, ++ if ((res = spa_node_port_enum_params_sync(this->follower, ++ this->direction, 0, + SPA_PARAM_Buffers, &state, + param, ¶m, &b)) != 1) { + debug_params(this, this->target, +@@ -471,7 +471,7 @@ static int negotiate_buffers(struct impl *this) + if (this->async) + buffers = SPA_MAX(2u, buffers); + +- spa_log_debug(this->log, "%p: buffers:%d, blocks:%d, size:%d, stride:%d align:%d %d:%d", ++ spa_log_info(this->log, "%p: buffers:%d, blocks:%d, size:%d, stride:%d align:%d %d:%d", + this, buffers, blocks, size, stride, align, follower_alloc, conv_alloc); + + align = SPA_MAX(align, this->max_align); +@@ -908,27 +908,13 @@ static int negotiate_format(struct impl *this) + spa_node_send_command(this->follower, + &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_ParamBegin)); + +- /* first try the ideal converter format, which is likely passthrough */ +- tstate = 0; +- fres = spa_node_port_enum_params_sync(this->target, +- SPA_DIRECTION_REVERSE(this->direction), 0, +- SPA_PARAM_EnumFormat, &tstate, +- NULL, &format, &b); +- if (fres == 1) { +- fstate = 0; +- res = spa_node_port_enum_params_sync(this->follower, +- this->direction, 0, +- SPA_PARAM_EnumFormat, &fstate, +- format, &format, &b); +- if (res == 1) +- goto found; +- } +- +- /* then try something the follower can accept */ ++ /* The target has been negotiated on its other ports and so it can propose ++ * a passthrough format or an ideal conversion. We use the suggestions of the ++ * target to find the best follower format */ + for (fstate = 0;;) { + format = NULL; +- res = spa_node_port_enum_params_sync(this->follower, +- this->direction, 0, ++ res = spa_node_port_enum_params_sync(this->target, ++ SPA_DIRECTION_REVERSE(this->direction), 0, + SPA_PARAM_EnumFormat, &fstate, + NULL, &format, &b); + +@@ -938,8 +924,8 @@ static int negotiate_format(struct impl *this) + break; + + tstate = 0; +- fres = spa_node_port_enum_params_sync(this->target, +- SPA_DIRECTION_REVERSE(this->direction), 0, ++ fres = spa_node_port_enum_params_sync(this->follower, ++ this->direction, 0, + SPA_PARAM_EnumFormat, &tstate, + format, &format, &b); + if (fres == 0 && res == 1) +@@ -948,7 +934,6 @@ static int negotiate_format(struct impl *this) + res = fres; + break; + } +-found: + if (format == NULL) { + debug_params(this, this->follower, this->direction, 0, + SPA_PARAM_EnumFormat, format, "follower format", res); +-- +2.49.0 + diff --git a/media-video/pipewire/files/1.4.3/0005-gst-src-Change-DEFAULT_MIN_BUFFERS-back-to-1.patch b/media-video/pipewire/files/1.4.3/0005-gst-src-Change-DEFAULT_MIN_BUFFERS-back-to-1.patch new file mode 100644 index 0000000000000..c6b4ee66dafb7 --- /dev/null +++ b/media-video/pipewire/files/1.4.3/0005-gst-src-Change-DEFAULT_MIN_BUFFERS-back-to-1.patch @@ -0,0 +1,39 @@ +From eda42ef2fc9eaa41dd7dc1582ae062d2ce727612 Mon Sep 17 00:00:00 2001 +Message-ID: +In-Reply-To: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org> +References: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org> +From: Robert Mader +Date: Sun, 25 May 2025 03:57:38 +0200 +Subject: [PATCH 5/5] gst: src: Change DEFAULT_MIN_BUFFERS back to 1 + +The change from 1 to 8 was done without justification in the commit +message and possibly for debug purposes. Unfortunately it breaks +negotiation with the libcamera virtual pipeline, which defaults to +4 buffers. + +Set the the value to 1 again as successful negotiation - even with an +unusually low number of buffers - is usually more desirable than an +error. + +Fixes: 98b7dc7c0 ("gst: don't do set_caps from the pipewire callback") +(cherry picked from commit e81fb773224fb5cd4b9399393ca2d2bfab7f4273) +--- + src/gst/gstpipewiresrc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c +index 694cbea0e..994534c60 100644 +--- a/src/gst/gstpipewiresrc.c ++++ b/src/gst/gstpipewiresrc.c +@@ -41,7 +41,7 @@ GST_DEBUG_CATEGORY_STATIC (pipewire_src_debug); + #define GST_CAT_DEFAULT pipewire_src_debug + + #define DEFAULT_ALWAYS_COPY false +-#define DEFAULT_MIN_BUFFERS 8 ++#define DEFAULT_MIN_BUFFERS 1 + #define DEFAULT_MAX_BUFFERS INT32_MAX + #define DEFAULT_RESEND_LAST false + #define DEFAULT_KEEPALIVE_TIME 0 +-- +2.49.0 + diff --git a/media-video/pipewire/pipewire-1.4.3.ebuild b/media-video/pipewire/pipewire-1.4.3-r1.ebuild similarity index 100% rename from media-video/pipewire/pipewire-1.4.3.ebuild rename to media-video/pipewire/pipewire-1.4.3-r1.ebuild