mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -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 &&
|
||||
(card = spa_dict_lookup(info->props, SPA_KEY_API_ALSA_CARD)) != NULL) {
|
||||
const char *reserve;
|
||||
const char *path = spa_dict_lookup(info->props, SPA_KEY_API_ALSA_PATH);
|
||||
|
||||
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) {
|
||||
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 {
|
||||
rd_device_set_application_device_name(device->reserve,
|
||||
spa_dict_lookup(info->props, SPA_KEY_API_ALSA_PATH));
|
||||
pw_log_warn("empty reserve device path for %s", reserve);
|
||||
}
|
||||
}
|
||||
if (device->reserve != NULL)
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ static int find_node(void *data, struct node *node)
|
|||
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);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,11 +158,13 @@ static char *serialize_props(struct stream *str, const struct spa_pod *param)
|
|||
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
||||
switch (prop->key) {
|
||||
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);
|
||||
break;
|
||||
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");
|
||||
break;
|
||||
case SPA_PROP_channelVolumes:
|
||||
|
|
|
|||
|
|
@ -615,7 +615,8 @@ static uint32_t collect_transport_codec_info(struct pw_manager_object *card,
|
|||
|
||||
/* Codec description list */
|
||||
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) {
|
||||
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(vol);
|
||||
|
||||
message_get(m,
|
||||
TAG_STRING, &name,
|
||||
TAG_CHANNEL_MAP, &map,
|
||||
TAG_CVOLUME, &vol,
|
||||
TAG_STRING, &device_name,
|
||||
TAG_BOOLEAN, &mute,
|
||||
TAG_INVALID);
|
||||
if (message_get(m,
|
||||
TAG_STRING, &name,
|
||||
TAG_CHANNEL_MAP, &map,
|
||||
TAG_CVOLUME, &vol,
|
||||
TAG_STRING, &device_name,
|
||||
TAG_BOOLEAN, &mute,
|
||||
TAG_INVALID) < 0)
|
||||
return -EPROTO;
|
||||
|
||||
if (name == NULL || name[0] == '\0')
|
||||
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) {
|
||||
pw_log_debug("%s -> %s: %s", name, key, ptr);
|
||||
pw_manager_set_metadata(client->manager,
|
||||
client->metadata_routes,
|
||||
PW_ID_CORE, key, "Spa:String:JSON", "%s", ptr);
|
||||
if (pw_manager_set_metadata(client->manager,
|
||||
client->metadata_routes,
|
||||
PW_ID_CORE, key, "Spa:String:JSON", "%s", ptr) < 0)
|
||||
pw_log_warn(NAME ": failed to set metadata %s = %s", key, 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 };
|
||||
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 ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw ||
|
||||
|
|
|
|||
|
|
@ -522,11 +522,13 @@ destroy_proxy(void *data)
|
|||
{
|
||||
struct object *o = data;
|
||||
|
||||
spa_assert(o->info);
|
||||
|
||||
if (o->info->events)
|
||||
spa_hook_remove(&o->object_listener);
|
||||
spa_hook_remove(&o->proxy_listener);
|
||||
|
||||
if (o->info && o->info->destroy)
|
||||
if (o->info->destroy)
|
||||
o->info->destroy(o);
|
||||
|
||||
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, ...)
|
||||
{
|
||||
va_list va;
|
||||
int res;
|
||||
int res = 0;
|
||||
|
||||
va_start(va, m);
|
||||
|
||||
|
|
@ -342,102 +342,109 @@ static int message_get(struct message *m, ...)
|
|||
switch (dtag) {
|
||||
case TAG_STRING:
|
||||
if (tag != TAG_STRING)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_string(m, va_arg(va, char**))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_STRING_NULL:
|
||||
if (tag != TAG_STRING)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
*va_arg(va, char**) = NULL;
|
||||
break;
|
||||
case TAG_U8:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_u8(m, va_arg(va, uint8_t*))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_U32:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_u32(m, va_arg(va, uint32_t*))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_S64:
|
||||
case TAG_U64:
|
||||
case TAG_USEC:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_u64(m, va_arg(va, uint64_t*))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_SAMPLE_SPEC:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_sample_spec(m, va_arg(va, struct sample_spec*))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_ARBITRARY:
|
||||
{
|
||||
const void **val = va_arg(va, const void**);
|
||||
size_t *len = va_arg(va, size_t*);
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_arbitrary(m, val, len)) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
case TAG_BOOLEAN_TRUE:
|
||||
if (tag != TAG_BOOLEAN)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
*va_arg(va, bool*) = true;
|
||||
break;
|
||||
case TAG_BOOLEAN_FALSE:
|
||||
if (tag != TAG_BOOLEAN)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
*va_arg(va, bool*) = false;
|
||||
break;
|
||||
case TAG_TIMEVAL:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_timeval(m, va_arg(va, struct timeval*))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_CHANNEL_MAP:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_channel_map(m, va_arg(va, struct channel_map*))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_CVOLUME:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_cvolume(m, va_arg(va, struct volume*))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_PROPLIST:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_props(m, va_arg(va, struct pw_properties*), true)) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_VOLUME:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_volume(m, va_arg(va, float*))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
case TAG_FORMAT_INFO:
|
||||
if (dtag != tag)
|
||||
return -EINVAL;
|
||||
goto invalid;
|
||||
if ((res = read_format_info(m, va_arg(va, struct format_info*))) < 0)
|
||||
return res;
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
}
|
||||
res = 0;
|
||||
goto done;
|
||||
|
||||
invalid:
|
||||
res = -EINVAL;
|
||||
|
||||
done:
|
||||
va_end(va);
|
||||
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
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;
|
||||
uint32_t sink_index, syncid;
|
||||
const char *sink_name;
|
||||
struct buffer_attr attr;
|
||||
struct buffer_attr attr = { 0 };
|
||||
bool corked = false,
|
||||
no_remap = 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,
|
||||
relative_volume = false,
|
||||
passthrough = false;
|
||||
uint32_t direct_on_input_idx;
|
||||
struct volume volume;
|
||||
uint32_t direct_on_input_idx = SPA_ID_INVALID;
|
||||
struct volume volume = VOLUME_INIT;
|
||||
struct pw_properties *props = NULL;
|
||||
uint8_t n_formats = 0;
|
||||
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_INVALID)) < 0)
|
||||
goto error_protocol;
|
||||
} else {
|
||||
volume_set = false;
|
||||
}
|
||||
if (sample_spec_valid(&ss)) {
|
||||
if (n_params < MAX_FORMATS &&
|
||||
|
|
@ -4576,7 +4578,10 @@ error:
|
|||
static uint64_t bytes_to_usec(uint64_t length, const struct sample_spec *ss)
|
||||
{
|
||||
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 /= ss->rate;
|
||||
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) {
|
||||
switch (prop->key) {
|
||||
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,
|
||||
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
||||
|
||||
break;
|
||||
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,
|
||||
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
||||
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);
|
||||
break;
|
||||
case SPA_PROP_volumeBase:
|
||||
spa_pod_get_float(&prop->value, &info->base);
|
||||
if (spa_pod_get_float(&prop->value, &info->base) < 0)
|
||||
continue;
|
||||
break;
|
||||
case SPA_PROP_volumeStep:
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue