3e5aaf49ce
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
177 lines
5.8 KiB
Diff
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
|
|
|