mirror of
https://github.com/gentoo-mirror/gentoo.git
synced 2026-09-24 17:09:10 -07:00
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 <sam@gentoo.org>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
From 483b59a9d95aa084dfcd1c17e13ee27bd106d4b0 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org>
|
||||
From: Wim Taymans <wtaymans@redhat.com>
|
||||
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
|
||||
|
||||
@@ -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 <wtaymans@redhat.com>
|
||||
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
|
||||
|
||||
@@ -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 <wtaymans@redhat.com>
|
||||
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<<SPA_CONTROL_UMP;
|
||||
+ if (p->object->port.type_id == TYPE_ID_OSC)
|
||||
+ types |= 1u<<SPA_CONTROL_OSC;
|
||||
+ if (types != 0)
|
||||
+ spa_pod_builder_add(b,
|
||||
+ SPA_FORMAT_CONTROL_types, SPA_POD_CHOICE_FLAGS_Int(types),
|
||||
+ 0);
|
||||
+
|
||||
+ *param = spa_pod_builder_pop(b, &f);
|
||||
break;
|
||||
+ }
|
||||
case TYPE_ID_VIDEO:
|
||||
*param = spa_pod_builder_add_object(b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
diff --git a/spa/plugins/alsa/alsa-seq-bridge.c b/spa/plugins/alsa/alsa-seq-bridge.c
|
||||
index 68e6c91a8..445808017 100644
|
||||
--- a/spa/plugins/alsa/alsa-seq-bridge.c
|
||||
+++ b/spa/plugins/alsa/alsa-seq-bridge.c
|
||||
@@ -529,8 +529,7 @@ impl_node_port_enum_params(void *object, int seq,
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
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_CONTROL_types, SPA_POD_CHOICE_FLAGS_Int(1u<<SPA_CONTROL_UMP));
|
||||
+ SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
|
||||
break;
|
||||
|
||||
case SPA_PARAM_Format:
|
||||
@@ -541,8 +540,7 @@ impl_node_port_enum_params(void *object, int seq,
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_Format,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application),
|
||||
- SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control),
|
||||
- SPA_FORMAT_CONTROL_types, SPA_POD_Int(1u<<SPA_CONTROL_UMP));
|
||||
+ SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
|
||||
break;
|
||||
|
||||
case SPA_PARAM_Buffers:
|
||||
@@ -635,7 +633,7 @@ static int port_set_format(void *object, struct seq_port *port,
|
||||
port->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
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
From c507c4b0ffa094d92c76ad4589ad776b677d94d2 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <c507c4b0ffa094d92c76ad4589ad776b677d94d2.1748327071.git.sam@gentoo.org>
|
||||
In-Reply-To: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org>
|
||||
References: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org>
|
||||
From: Wim Taymans <wtaymans@redhat.com>
|
||||
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
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From eda42ef2fc9eaa41dd7dc1582ae062d2ce727612 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <eda42ef2fc9eaa41dd7dc1582ae062d2ce727612.1748327071.git.sam@gentoo.org>
|
||||
In-Reply-To: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org>
|
||||
References: <483b59a9d95aa084dfcd1c17e13ee27bd106d4b0.1748327071.git.sam@gentoo.org>
|
||||
From: Robert Mader <robert.mader@collabora.com>
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user