pulse-server: fill in the format info

This commit is contained in:
Wim Taymans 2021-03-10 17:27:11 +01:00
parent d5fc67cf06
commit e334c5862e
2 changed files with 49 additions and 4 deletions

View file

@ -125,6 +125,16 @@ static inline enum sample_format format_id2pa(uint32_t id)
return SAMPLE_INVALID; return SAMPLE_INVALID;
} }
static inline const char *format_id2paname(uint32_t id)
{
size_t i;
for (i = 0; i < SPA_N_ELEMENTS(audio_formats); i++) {
if (id == audio_formats[i].id)
return audio_formats[i].name;
}
return "invalid";
}
struct sample_spec { struct sample_spec {
uint32_t format; uint32_t format;
uint32_t rate; uint32_t rate;
@ -357,6 +367,15 @@ static inline enum channel_position channel_id2pa(uint32_t id, uint32_t *aux)
return CHANNEL_POSITION_AUX0 + (*aux)++; return CHANNEL_POSITION_AUX0 + (*aux)++;
} }
static inline const char *channel_id2paname(uint32_t id, uint32_t *aux)
{
size_t i;
for (i = 0; i < SPA_N_ELEMENTS(audio_channels); i++) {
if (id == audio_channels[i].channel)
return audio_channels[i].name;
}
return audio_channels[CHANNEL_POSITION_AUX0 + (*aux)++].name;
}
static inline uint32_t channel_paname2id(const char *name, size_t size) static inline uint32_t channel_paname2id(const char *name, size_t size)
{ {
@ -550,6 +569,32 @@ static const struct spa_pod *format_build_param(struct spa_pod_builder *b,
return spa_format_audio_raw_build(b, id, &info); return spa_format_audio_raw_build(b, id, &info);
} }
static int format_info_from_spec(struct format_info *info,
struct sample_spec *ss, struct channel_map *map)
{
spa_zero(*info);
info->encoding = ENCODING_PCM;
if ((info->props = pw_properties_new(NULL, NULL)) == NULL)
return -errno;
pw_properties_setf(info->props, "format.sample_format", "\"%s\"",
format_id2paname(ss->format));
pw_properties_setf(info->props, "format.rate", "%d", ss->rate);
pw_properties_setf(info->props, "format.channels", "%d", ss->channels);
if (map && map->channels == ss->channels) {
char chmap[1024] = "";
int i, o;
uint32_t aux = 0;
for (i = 0, o = 0; i < map->channels; i++) {
o += snprintf(chmap+o, sizeof(chmap)-o, "%s%s", i == 0 ? "" : ",",
channel_id2paname(map->map[i], &aux));
}
pw_properties_setf(info->props, "format.channel_map", "\"%s\"", chmap);
}
return 0;
}
static const struct spa_pod *format_info_build_param(struct spa_pod_builder *b, static const struct spa_pod *format_info_build_param(struct spa_pod_builder *b,
uint32_t id, struct format_info *info) uint32_t id, struct format_info *info)
{ {

View file

@ -4322,11 +4322,11 @@ static int fill_sink_input_info(struct client *client, struct message *m,
TAG_INVALID); TAG_INVALID);
if (client->version >= 21) { if (client->version >= 21) {
struct format_info fi; struct format_info fi;
spa_zero(fi); format_info_from_spec(&fi, &dev_info.ss, &dev_info.map);
fi.encoding = ENCODING_PCM;
message_put(m, message_put(m,
TAG_FORMAT_INFO, &fi, TAG_FORMAT_INFO, &fi,
TAG_INVALID); TAG_INVALID);
format_info_clear(&fi);
} }
return 0; return 0;
} }
@ -4389,8 +4389,7 @@ static int fill_source_output_info(struct client *client, struct message *m,
TAG_INVALID); TAG_INVALID);
if (client->version >= 22) { if (client->version >= 22) {
struct format_info fi; struct format_info fi;
spa_zero(fi); format_info_from_spec(&fi, &dev_info.ss, &dev_info.map);
fi.encoding = ENCODING_PCM;
message_put(m, message_put(m,
TAG_CVOLUME, &dev_info.volume_info.volume, TAG_CVOLUME, &dev_info.volume_info.volume,
TAG_BOOLEAN, dev_info.volume_info.mute, /* muted */ TAG_BOOLEAN, dev_info.volume_info.mute, /* muted */
@ -4398,6 +4397,7 @@ static int fill_source_output_info(struct client *client, struct message *m,
TAG_BOOLEAN, true, /* volume writable */ TAG_BOOLEAN, true, /* volume writable */
TAG_FORMAT_INFO, &fi, TAG_FORMAT_INFO, &fi,
TAG_INVALID); TAG_INVALID);
format_info_clear(&fi);
} }
return 0; return 0;
} }