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 &&
 | 
						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