mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-19 08:57:14 -05:00
media-session/pulse-server: more error checks + minor fixes
This commit is contained in:
parent
f330446291
commit
2681b8236b
10 changed files with 79 additions and 54 deletions
|
|
@ -908,6 +908,7 @@ static struct device *alsa_create_device(struct impl *impl, uint32_t id,
|
||||||
if (impl->conn &&
|
if (impl->conn &&
|
||||||
(card = spa_dict_lookup(info->props, SPA_KEY_API_ALSA_CARD)) != NULL) {
|
(card = spa_dict_lookup(info->props, SPA_KEY_API_ALSA_CARD)) != NULL) {
|
||||||
const char *reserve;
|
const char *reserve;
|
||||||
|
const char *path = spa_dict_lookup(info->props, SPA_KEY_API_ALSA_PATH);
|
||||||
|
|
||||||
device->priority -= atol(card) * 64;
|
device->priority -= atol(card) * 64;
|
||||||
|
|
||||||
|
|
@ -920,9 +921,10 @@ static struct device *alsa_create_device(struct impl *impl, uint32_t id,
|
||||||
|
|
||||||
if (device->reserve == NULL) {
|
if (device->reserve == NULL) {
|
||||||
pw_log_warn("can't create device reserve for %s: %m", reserve);
|
pw_log_warn("can't create device reserve for %s: %m", reserve);
|
||||||
|
} else if (path) {
|
||||||
|
rd_device_set_application_device_name(device->reserve, path);
|
||||||
} else {
|
} else {
|
||||||
rd_device_set_application_device_name(device->reserve,
|
pw_log_warn("empty reserve device path for %s", reserve);
|
||||||
spa_dict_lookup(info->props, SPA_KEY_API_ALSA_PATH));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (device->reserve != NULL)
|
if (device->reserve != NULL)
|
||||||
|
|
|
||||||
|
|
@ -536,7 +536,7 @@ static int find_node(void *data, struct node *node)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(node->media, find->media) != 0) {
|
if (node->media && strcmp(node->media, find->media) != 0) {
|
||||||
pw_log_debug(".. incompatible media %s <-> %s", node->media, find->media);
|
pw_log_debug(".. incompatible media %s <-> %s", node->media, find->media);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,11 +158,13 @@ static char *serialize_props(struct stream *str, const struct spa_pod *param)
|
||||||
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
||||||
switch (prop->key) {
|
switch (prop->key) {
|
||||||
case SPA_PROP_volume:
|
case SPA_PROP_volume:
|
||||||
spa_pod_get_float(&prop->value, &val);
|
if (spa_pod_get_float(&prop->value, &val) < 0)
|
||||||
|
continue;
|
||||||
fprintf(f, "%s\"volume\": %f", (comma ? ", " : ""), val);
|
fprintf(f, "%s\"volume\": %f", (comma ? ", " : ""), val);
|
||||||
break;
|
break;
|
||||||
case SPA_PROP_mute:
|
case SPA_PROP_mute:
|
||||||
spa_pod_get_bool(&prop->value, &b);
|
if (spa_pod_get_bool(&prop->value, &b) < 0)
|
||||||
|
continue;
|
||||||
fprintf(f, "%s\"mute\": %s", (comma ? ", " : ""), b ? "true" : "false");
|
fprintf(f, "%s\"mute\": %s", (comma ? ", " : ""), b ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
case SPA_PROP_channelVolumes:
|
case SPA_PROP_channelVolumes:
|
||||||
|
|
|
||||||
|
|
@ -615,7 +615,8 @@ static uint32_t collect_transport_codec_info(struct pw_manager_object *card,
|
||||||
|
|
||||||
/* Codec description list */
|
/* Codec description list */
|
||||||
spa_pod_parser_pod(&prs, (struct spa_pod *)labels);
|
spa_pod_parser_pod(&prs, (struct spa_pod *)labels);
|
||||||
spa_pod_parser_push_struct(&prs, &f);
|
if (spa_pod_parser_push_struct(&prs, &f) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int32_t id;
|
int32_t id;
|
||||||
|
|
|
||||||
|
|
@ -212,13 +212,14 @@ static int do_extension_stream_restore_write(struct client *client, uint32_t com
|
||||||
spa_zero(map);
|
spa_zero(map);
|
||||||
spa_zero(vol);
|
spa_zero(vol);
|
||||||
|
|
||||||
message_get(m,
|
if (message_get(m,
|
||||||
TAG_STRING, &name,
|
TAG_STRING, &name,
|
||||||
TAG_CHANNEL_MAP, &map,
|
TAG_CHANNEL_MAP, &map,
|
||||||
TAG_CVOLUME, &vol,
|
TAG_CVOLUME, &vol,
|
||||||
TAG_STRING, &device_name,
|
TAG_STRING, &device_name,
|
||||||
TAG_BOOLEAN, &mute,
|
TAG_BOOLEAN, &mute,
|
||||||
TAG_INVALID);
|
TAG_INVALID) < 0)
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
if (name == NULL || name[0] == '\0')
|
if (name == NULL || name[0] == '\0')
|
||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
|
|
@ -247,9 +248,10 @@ static int do_extension_stream_restore_write(struct client *client, uint32_t com
|
||||||
|
|
||||||
if (key_from_name(name, key, sizeof(key)) >= 0) {
|
if (key_from_name(name, key, sizeof(key)) >= 0) {
|
||||||
pw_log_debug("%s -> %s: %s", name, key, ptr);
|
pw_log_debug("%s -> %s: %s", name, key, ptr);
|
||||||
pw_manager_set_metadata(client->manager,
|
if (pw_manager_set_metadata(client->manager,
|
||||||
client->metadata_routes,
|
client->metadata_routes,
|
||||||
PW_ID_CORE, key, "Spa:String:JSON", "%s", ptr);
|
PW_ID_CORE, key, "Spa:String:JSON", "%s", ptr) < 0)
|
||||||
|
pw_log_warn(NAME ": failed to set metadata %s = %s", key, ptr);
|
||||||
}
|
}
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -537,7 +537,8 @@ static int format_parse_param(const struct spa_pod *param, struct sample_spec *s
|
||||||
struct spa_audio_info info = { 0 };
|
struct spa_audio_info info = { 0 };
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
spa_format_parse(param, &info.media_type, &info.media_subtype);
|
if (spa_format_parse(param, &info.media_type, &info.media_subtype) < 0)
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw ||
|
info.media_subtype != SPA_MEDIA_SUBTYPE_raw ||
|
||||||
|
|
|
||||||
|
|
@ -522,11 +522,13 @@ destroy_proxy(void *data)
|
||||||
{
|
{
|
||||||
struct object *o = data;
|
struct object *o = data;
|
||||||
|
|
||||||
|
spa_assert(o->info);
|
||||||
|
|
||||||
if (o->info->events)
|
if (o->info->events)
|
||||||
spa_hook_remove(&o->object_listener);
|
spa_hook_remove(&o->object_listener);
|
||||||
spa_hook_remove(&o->proxy_listener);
|
spa_hook_remove(&o->proxy_listener);
|
||||||
|
|
||||||
if (o->info && o->info->destroy)
|
if (o->info->destroy)
|
||||||
o->info->destroy(o);
|
o->info->destroy(o);
|
||||||
|
|
||||||
o->this.proxy = NULL;
|
o->this.proxy = NULL;
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,7 @@ static int read_format_info(struct message *m, struct format_info *info)
|
||||||
static int message_get(struct message *m, ...)
|
static int message_get(struct message *m, ...)
|
||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
int res;
|
int res = 0;
|
||||||
|
|
||||||
va_start(va, m);
|
va_start(va, m);
|
||||||
|
|
||||||
|
|
@ -342,102 +342,109 @@ static int message_get(struct message *m, ...)
|
||||||
switch (dtag) {
|
switch (dtag) {
|
||||||
case TAG_STRING:
|
case TAG_STRING:
|
||||||
if (tag != TAG_STRING)
|
if (tag != TAG_STRING)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_string(m, va_arg(va, char**))) < 0)
|
if ((res = read_string(m, va_arg(va, char**))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_STRING_NULL:
|
case TAG_STRING_NULL:
|
||||||
if (tag != TAG_STRING)
|
if (tag != TAG_STRING)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
*va_arg(va, char**) = NULL;
|
*va_arg(va, char**) = NULL;
|
||||||
break;
|
break;
|
||||||
case TAG_U8:
|
case TAG_U8:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_u8(m, va_arg(va, uint8_t*))) < 0)
|
if ((res = read_u8(m, va_arg(va, uint8_t*))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_U32:
|
case TAG_U32:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_u32(m, va_arg(va, uint32_t*))) < 0)
|
if ((res = read_u32(m, va_arg(va, uint32_t*))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_S64:
|
case TAG_S64:
|
||||||
case TAG_U64:
|
case TAG_U64:
|
||||||
case TAG_USEC:
|
case TAG_USEC:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_u64(m, va_arg(va, uint64_t*))) < 0)
|
if ((res = read_u64(m, va_arg(va, uint64_t*))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_SAMPLE_SPEC:
|
case TAG_SAMPLE_SPEC:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_sample_spec(m, va_arg(va, struct sample_spec*))) < 0)
|
if ((res = read_sample_spec(m, va_arg(va, struct sample_spec*))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_ARBITRARY:
|
case TAG_ARBITRARY:
|
||||||
{
|
{
|
||||||
const void **val = va_arg(va, const void**);
|
const void **val = va_arg(va, const void**);
|
||||||
size_t *len = va_arg(va, size_t*);
|
size_t *len = va_arg(va, size_t*);
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_arbitrary(m, val, len)) < 0)
|
if ((res = read_arbitrary(m, val, len)) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TAG_BOOLEAN_TRUE:
|
case TAG_BOOLEAN_TRUE:
|
||||||
if (tag != TAG_BOOLEAN)
|
if (tag != TAG_BOOLEAN)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
*va_arg(va, bool*) = true;
|
*va_arg(va, bool*) = true;
|
||||||
break;
|
break;
|
||||||
case TAG_BOOLEAN_FALSE:
|
case TAG_BOOLEAN_FALSE:
|
||||||
if (tag != TAG_BOOLEAN)
|
if (tag != TAG_BOOLEAN)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
*va_arg(va, bool*) = false;
|
*va_arg(va, bool*) = false;
|
||||||
break;
|
break;
|
||||||
case TAG_TIMEVAL:
|
case TAG_TIMEVAL:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_timeval(m, va_arg(va, struct timeval*))) < 0)
|
if ((res = read_timeval(m, va_arg(va, struct timeval*))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_CHANNEL_MAP:
|
case TAG_CHANNEL_MAP:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_channel_map(m, va_arg(va, struct channel_map*))) < 0)
|
if ((res = read_channel_map(m, va_arg(va, struct channel_map*))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_CVOLUME:
|
case TAG_CVOLUME:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_cvolume(m, va_arg(va, struct volume*))) < 0)
|
if ((res = read_cvolume(m, va_arg(va, struct volume*))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_PROPLIST:
|
case TAG_PROPLIST:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_props(m, va_arg(va, struct pw_properties*), true)) < 0)
|
if ((res = read_props(m, va_arg(va, struct pw_properties*), true)) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_VOLUME:
|
case TAG_VOLUME:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_volume(m, va_arg(va, float*))) < 0)
|
if ((res = read_volume(m, va_arg(va, float*))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case TAG_FORMAT_INFO:
|
case TAG_FORMAT_INFO:
|
||||||
if (dtag != tag)
|
if (dtag != tag)
|
||||||
return -EINVAL;
|
goto invalid;
|
||||||
if ((res = read_format_info(m, va_arg(va, struct format_info*))) < 0)
|
if ((res = read_format_info(m, va_arg(va, struct format_info*))) < 0)
|
||||||
return res;
|
goto done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
res = 0;
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
invalid:
|
||||||
|
res = -EINVAL;
|
||||||
|
|
||||||
|
done:
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
return 0;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ensure_size(struct message *m, uint32_t size)
|
static int ensure_size(struct message *m, uint32_t size)
|
||||||
|
|
|
||||||
|
|
@ -1914,7 +1914,7 @@ static int do_create_playback_stream(struct client *client, uint32_t command, ui
|
||||||
struct channel_map map;
|
struct channel_map map;
|
||||||
uint32_t sink_index, syncid;
|
uint32_t sink_index, syncid;
|
||||||
const char *sink_name;
|
const char *sink_name;
|
||||||
struct buffer_attr attr;
|
struct buffer_attr attr = { 0 };
|
||||||
bool corked = false,
|
bool corked = false,
|
||||||
no_remap = false,
|
no_remap = false,
|
||||||
no_remix = false,
|
no_remix = false,
|
||||||
|
|
@ -2178,8 +2178,8 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint
|
||||||
fail_on_suspend = false,
|
fail_on_suspend = false,
|
||||||
relative_volume = false,
|
relative_volume = false,
|
||||||
passthrough = false;
|
passthrough = false;
|
||||||
uint32_t direct_on_input_idx;
|
uint32_t direct_on_input_idx = SPA_ID_INVALID;
|
||||||
struct volume volume;
|
struct volume volume = VOLUME_INIT;
|
||||||
struct pw_properties *props = NULL;
|
struct pw_properties *props = NULL;
|
||||||
uint8_t n_formats = 0;
|
uint8_t n_formats = 0;
|
||||||
struct stream *stream = NULL;
|
struct stream *stream = NULL;
|
||||||
|
|
@ -2287,6 +2287,8 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint
|
||||||
TAG_BOOLEAN, &passthrough,
|
TAG_BOOLEAN, &passthrough,
|
||||||
TAG_INVALID)) < 0)
|
TAG_INVALID)) < 0)
|
||||||
goto error_protocol;
|
goto error_protocol;
|
||||||
|
} else {
|
||||||
|
volume_set = false;
|
||||||
}
|
}
|
||||||
if (sample_spec_valid(&ss)) {
|
if (sample_spec_valid(&ss)) {
|
||||||
if (n_params < MAX_FORMATS &&
|
if (n_params < MAX_FORMATS &&
|
||||||
|
|
@ -4576,7 +4578,10 @@ error:
|
||||||
static uint64_t bytes_to_usec(uint64_t length, const struct sample_spec *ss)
|
static uint64_t bytes_to_usec(uint64_t length, const struct sample_spec *ss)
|
||||||
{
|
{
|
||||||
uint64_t u;
|
uint64_t u;
|
||||||
u = length / sample_spec_frame_size(ss);
|
uint64_t frame_size = sample_spec_frame_size(ss);
|
||||||
|
if (frame_size == 0)
|
||||||
|
return 0;
|
||||||
|
u = length / frame_size;
|
||||||
u *= SPA_USEC_PER_SEC;
|
u *= SPA_USEC_PER_SEC;
|
||||||
u /= ss->rate;
|
u /= ss->rate;
|
||||||
return u;
|
return u;
|
||||||
|
|
|
||||||
|
|
@ -91,13 +91,15 @@ static int volume_parse_param(const struct spa_pod *param, struct volume_info *i
|
||||||
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
||||||
switch (prop->key) {
|
switch (prop->key) {
|
||||||
case SPA_PROP_volume:
|
case SPA_PROP_volume:
|
||||||
spa_pod_get_float(&prop->value, &info->level);
|
if (spa_pod_get_float(&prop->value, &info->level) < 0)
|
||||||
|
continue;
|
||||||
SPA_FLAG_UPDATE(info->flags, VOLUME_HW_VOLUME,
|
SPA_FLAG_UPDATE(info->flags, VOLUME_HW_VOLUME,
|
||||||
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SPA_PROP_mute:
|
case SPA_PROP_mute:
|
||||||
spa_pod_get_bool(&prop->value, &info->mute);
|
if (spa_pod_get_bool(&prop->value, &info->mute) < 0)
|
||||||
|
continue;
|
||||||
SPA_FLAG_UPDATE(info->flags, VOLUME_HW_MUTE,
|
SPA_FLAG_UPDATE(info->flags, VOLUME_HW_MUTE,
|
||||||
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
||||||
break;
|
break;
|
||||||
|
|
@ -108,7 +110,8 @@ static int volume_parse_param(const struct spa_pod *param, struct volume_info *i
|
||||||
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
||||||
break;
|
break;
|
||||||
case SPA_PROP_volumeBase:
|
case SPA_PROP_volumeBase:
|
||||||
spa_pod_get_float(&prop->value, &info->base);
|
if (spa_pod_get_float(&prop->value, &info->base) < 0)
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
case SPA_PROP_volumeStep:
|
case SPA_PROP_volumeStep:
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue