pipewire/0019-pulse-server-handle-unsupported-formats.patch
DistroBaker 3e5aaf49ce Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/pipewire.git#4467dc0ac39ed04eb0f686004dcd8e66555c6ad6
2021-02-22 09:10:22 +00:00

177 lines
5.8 KiB
Diff

From fcf00b3d352d931446a384a768b999520662b599 Mon Sep 17 00:00:00 2001
From: Wim Taymans <wtaymans@redhat.com>
Date: Fri, 19 Feb 2021 15:25:32 +0100
Subject: [PATCH 19/30] pulse-server: handle unsupported formats
We can only handle PCM encodings for now, fail conversion otherwise.
If we have no supported formats, return an error code.
VLC first try to send AC3 or EAC3 passthrough and then tries again
with decoded data. If we accept the encoded data we are just playing
noise.
Fixes #428
---
src/modules/module-protocol-pulse/format.c | 3 +
.../module-protocol-pulse/pulse-server.c | 56 ++++++++++++++++---
2 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/src/modules/module-protocol-pulse/format.c b/src/modules/module-protocol-pulse/format.c
index f718e70a7..4bd0daabe 100644
--- a/src/modules/module-protocol-pulse/format.c
+++ b/src/modules/module-protocol-pulse/format.c
@@ -563,6 +563,9 @@ static const struct spa_pod *format_info_build_param(struct spa_pod_builder *b,
spa_zero(ss);
spa_zero(map);
+ if (info->encoding != ENCODING_PCM)
+ return NULL;
+
if ((str = pw_properties_get(info->props, "format.sample_format")) == NULL)
return NULL;
diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c
index 1cce96203..977c9886a 100644
--- a/src/modules/module-protocol-pulse/pulse-server.c
+++ b/src/modules/module-protocol-pulse/pulse-server.c
@@ -1752,6 +1752,16 @@ static const struct pw_stream_events stream_events =
.drained = stream_drained,
};
+static void log_format_info(struct impl *impl, enum spa_log_level level, struct format_info *format)
+{
+ const struct spa_dict_item *it;
+ pw_log(level, NAME" %p: format %s",
+ impl, format_encoding2name(format->encoding));
+ spa_dict_for_each(it, &format->props->dict)
+ pw_log(level, NAME" %p: '%s': '%s'",
+ impl, it->key, it->value);
+}
+
static int do_create_playback_stream(struct client *client, uint32_t command, uint32_t tag, struct message *m)
{
struct impl *impl = client->impl;
@@ -1783,7 +1793,7 @@ static int do_create_playback_stream(struct client *client, uint32_t command, ui
struct pw_properties *props = NULL;
uint8_t n_formats = 0;
struct stream *stream = NULL;
- uint32_t n_params = 0, flags;
+ uint32_t n_params = 0, n_valid_formats = 0, flags;
const struct spa_pod *params[32];
uint8_t buffer[4096];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
@@ -1871,8 +1881,14 @@ static int do_create_playback_stream(struct client *client, uint32_t command, ui
if (sample_spec_valid(&ss)) {
if ((params[n_params] = format_build_param(&b,
- SPA_PARAM_EnumFormat, &ss, &map)) != NULL)
+ SPA_PARAM_EnumFormat, &ss, &map)) != NULL) {
n_params++;
+ n_valid_formats++;
+ } else {
+ pw_log_warn(NAME" %p: unsupported format:%s rate:%d channels:%u",
+ impl, format_id2name(ss.format), ss.rate,
+ ss.channels);
+ }
}
if (client->version >= 21) {
if ((res = message_get(m,
@@ -1891,9 +1907,12 @@ static int do_create_playback_stream(struct client *client, uint32_t command, ui
goto error_protocol;
if ((params[n_params] = format_info_build_param(&b,
- SPA_PARAM_EnumFormat, &format)) != NULL)
+ SPA_PARAM_EnumFormat, &format)) != NULL) {
n_params++;
-
+ n_valid_formats++;
+ } else {
+ log_format_info(impl, SPA_LOG_LEVEL_WARN, &format);
+ }
format_info_clear(&format);
}
}
@@ -1901,6 +1920,9 @@ static int do_create_playback_stream(struct client *client, uint32_t command, ui
if (m->offset != m->length)
goto error_protocol;
+ if (n_valid_formats == 0)
+ goto error_no_formats;
+
stream = calloc(1, sizeof(struct stream));
if (stream == NULL)
goto error_errno;
@@ -1968,6 +1990,9 @@ error_errno:
error_protocol:
res = -EPROTO;
goto error;
+error_no_formats:
+ res = -ENOTSUP;
+ goto error;
error_invalid:
res = -EINVAL;
goto error;
@@ -2012,7 +2037,7 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint
struct pw_properties *props = NULL;
uint8_t n_formats = 0;
struct stream *stream = NULL;
- uint32_t n_params = 0, flags, id;
+ uint32_t n_params = 0, n_valid_formats = 0, flags, id;
const struct spa_pod *params[32];
uint8_t buffer[4096];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
@@ -2082,8 +2107,14 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint
}
if (sample_spec_valid(&ss)) {
if ((params[n_params] = format_build_param(&b,
- SPA_PARAM_EnumFormat, &ss, &map)) != NULL)
+ SPA_PARAM_EnumFormat, &ss, &map)) != NULL) {
n_params++;
+ n_valid_formats++;
+ } else {
+ pw_log_warn(NAME" %p: unsupported format:%s rate:%d channels:%u",
+ impl, format_id2name(ss.format), ss.rate,
+ ss.channels);
+ }
}
if (client->version >= 22) {
if ((res = message_get(m,
@@ -2102,9 +2133,12 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint
goto error_protocol;
if ((params[n_params] = format_info_build_param(&b,
- SPA_PARAM_EnumFormat, &format)) != NULL)
+ SPA_PARAM_EnumFormat, &format)) != NULL) {
n_params++;
-
+ n_valid_formats++;
+ } else {
+ log_format_info(impl, SPA_LOG_LEVEL_WARN, &format);
+ }
format_info_clear(&format);
}
}
@@ -2121,6 +2155,9 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint
if (m->offset != m->length)
goto error_protocol;
+ if (n_valid_formats == 0)
+ goto error_no_formats;
+
stream = calloc(1, sizeof(struct stream));
if (stream == NULL)
goto error_errno;
@@ -2201,6 +2238,9 @@ error_errno:
error_protocol:
res = -EPROTO;
goto error;
+error_no_formats:
+ res = -ENOTSUP;
+ goto error;
error_invalid:
res = -EINVAL;
goto error;
--
2.26.2