mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
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
This commit is contained in:
parent
4b591df145
commit
fcf00b3d35
2 changed files with 51 additions and 8 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue