spa: parse the audio.position completetly

Parse the audio.position spec completely so that we have the right
number of channels but only store the first max_position channels.

Also rename some field to make it clear that this is about the max
number of channel positions.
This commit is contained in:
Wim Taymans 2025-10-22 12:47:00 +02:00
parent ae50bb5dc0
commit 6465a63bf6
4 changed files with 13 additions and 11 deletions

View file

@ -29,7 +29,7 @@ extern "C" {
SPA_API_AUDIO_RAW_JSON int SPA_API_AUDIO_RAW_JSON int
spa_audio_parse_position_n(const char *str, size_t len, spa_audio_parse_position_n(const char *str, size_t len,
uint32_t *position, uint32_t max_channels, uint32_t *n_channels) uint32_t *position, uint32_t max_position, uint32_t *n_channels)
{ {
struct spa_json iter; struct spa_json iter;
char v[256]; char v[256];
@ -38,9 +38,10 @@ spa_audio_parse_position_n(const char *str, size_t len,
if (spa_json_begin_array_relax(&iter, str, len) <= 0) if (spa_json_begin_array_relax(&iter, str, len) <= 0)
return 0; return 0;
while (spa_json_get_string(&iter, v, sizeof(v)) > 0 && while (spa_json_get_string(&iter, v, sizeof(v)) > 0) {
channels < max_channels) { if (channels < max_position)
position[channels++] = spa_type_audio_channel_from_short_name(v); position[channels] = spa_type_audio_channel_from_short_name(v);
channels++;
} }
*n_channels = channels; *n_channels = channels;
return channels; return channels;

View file

@ -243,7 +243,7 @@ static int position_to_string(struct channel_map *map, char *val, size_t len)
uint32_t i, o = 0; uint32_t i, o = 0;
int r; int r;
o += snprintf(val, len, "[ "); o += snprintf(val, len, "[ ");
for (i = 0; i < map->channels; i++) { for (i = 0; i < map->n_pos; i++) {
r = snprintf(val+o, len-o, "%s%s", i == 0 ? "" : ", ", r = snprintf(val+o, len-o, "%s%s", i == 0 ? "" : ", ",
spa_debug_type_find_short_name(spa_type_audio_channel, spa_debug_type_find_short_name(spa_type_audio_channel,
map->pos[i])); map->pos[i]));
@ -1645,7 +1645,7 @@ skip_channels:
} else { } else {
const struct channel_map *map = NULL; const struct channel_map *map = NULL;
spa_pod_builder_int(b, min); spa_pod_builder_int(b, min);
if (state->default_pos.channels == min) { if (state->default_pos.n_pos == min) {
map = &state->default_pos; map = &state->default_pos;
spa_log_debug(state->log, "%p: using provided default", state); spa_log_debug(state->log, "%p: using provided default", state);
} else if (min <= 8) { } else if (min <= 8) {
@ -1655,7 +1655,7 @@ skip_channels:
if (map) { if (map) {
spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_position, 0); spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_position, 0);
spa_pod_builder_push_array(b, &f[0]); spa_pod_builder_push_array(b, &f[0]);
for (i = 0; i < map->channels; i++) { for (i = 0; i < map->n_pos; i++) {
spa_log_debug(state->log, "%p: position %zd %d", state, i, map->pos[i]); spa_log_debug(state->log, "%p: position %zd %d", state, i, map->pos[i]);
spa_pod_builder_id(b, map->pos[i]); spa_pod_builder_id(b, map->pos[i]);
} }

View file

@ -72,7 +72,7 @@ struct buffer {
#define BW_PERIOD (3 * SPA_NSEC_PER_SEC) #define BW_PERIOD (3 * SPA_NSEC_PER_SEC)
struct channel_map { struct channel_map {
uint32_t channels; uint32_t n_pos;
uint32_t pos[MAX_CHANNELS]; uint32_t pos[MAX_CHANNELS];
}; };
@ -315,7 +315,7 @@ void spa_alsa_emit_port_info(struct state *state, bool full);
static inline void spa_alsa_parse_position(struct channel_map *map, const char *val, size_t len) static inline void spa_alsa_parse_position(struct channel_map *map, const char *val, size_t len)
{ {
spa_audio_parse_position_n(val, len, map->pos, SPA_N_ELEMENTS(map->pos), &map->channels); spa_audio_parse_position_n(val, len, map->pos, SPA_N_ELEMENTS(map->pos), &map->n_pos);
} }
static inline uint32_t spa_alsa_parse_rates(uint32_t *rates, uint32_t max, const char *val, size_t len) static inline uint32_t spa_alsa_parse_rates(uint32_t *rates, uint32_t max, const char *val, size_t len)

View file

@ -232,16 +232,17 @@ struct impl {
float *discard_data; float *discard_data;
}; };
static inline void print_channels(char *buffer, size_t max_size, uint32_t n_channels, uint32_t *positions) static inline void print_channels(char *buffer, size_t max_size, uint32_t n_positions, uint32_t *positions)
{ {
uint32_t i; uint32_t i;
struct spa_strbuf buf; struct spa_strbuf buf;
spa_strbuf_init(&buf, buffer, max_size); spa_strbuf_init(&buf, buffer, max_size);
spa_strbuf_append(&buf, "["); spa_strbuf_append(&buf, "[");
for (i = 0; i < n_channels; i++) { for (i = 0; i < n_positions; i++) {
spa_strbuf_append(&buf, "%s%s", i ? "," : "", spa_strbuf_append(&buf, "%s%s", i ? "," : "",
spa_type_audio_channel_to_short_name(positions[i])); spa_type_audio_channel_to_short_name(positions[i]));
} }
spa_strbuf_append(&buf, "]"); spa_strbuf_append(&buf, "]");
} }