spa: add audio.position support in null sink

This commit is contained in:
Wim Taymans 2020-12-02 12:59:50 +01:00
parent 4c486c7ae3
commit 57886c1198
2 changed files with 42 additions and 11 deletions

View file

@ -39,6 +39,8 @@
#include <spa/node/io.h>
#include <spa/node/keys.h>
#include <spa/param/audio/format-utils.h>
#include <spa/debug/types.h>
#include <spa/param/audio/type-info.h>
#include <spa/param/param.h>
#include <spa/pod/filter.h>
#include <spa/control/control.h>
@ -47,10 +49,16 @@
struct props {
uint32_t channels;
uint32_t rate;
uint32_t n_pos;
uint32_t pos[SPA_AUDIO_MAX_CHANNELS];
};
static void reset_props(struct props *props)
{
props->channels = 0;
props->rate = 0;
props->n_pos = 0;
}
#define DEFAULT_CHANNELS 2
@ -92,8 +100,6 @@ struct impl {
struct spa_loop *data_loop;
struct spa_system *data_system;
uint32_t default_rate;
uint32_t default_channels;
struct props props;
uint64_t info_all;
@ -365,24 +371,29 @@ port_enum_formats(struct impl *this,
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32),
0);
if (this->default_rate != 0) {
if (this->props.rate != 0) {
spa_pod_builder_add(builder,
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(this->default_rate),
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(this->props.rate),
0);
} else {
spa_pod_builder_add(builder,
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(DEFAULT_RATE, 1, INT32_MAX),
0);
}
if (this->default_channels != 0) {
if (this->props.channels != 0) {
spa_pod_builder_add(builder,
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(this->default_channels),
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(this->props.channels),
0);
} else {
spa_pod_builder_add(builder,
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(DEFAULT_CHANNELS, 1, INT32_MAX),
0);
}
if (this->props.n_pos != 0) {
spa_pod_builder_prop(builder, SPA_FORMAT_AUDIO_position, 0);
spa_pod_builder_array(builder, sizeof(uint32_t), SPA_TYPE_Id,
this->props.n_pos, this->props.pos);
}
*param = spa_pod_builder_pop(builder, &f[0]);
break;
default:
@ -704,6 +715,16 @@ impl_get_size(const struct spa_handle_factory *factory,
return sizeof(struct impl);
}
static uint32_t channel_from_name(const char *name, size_t len)
{
int i;
for (i = 0; spa_type_audio_channel[i].name; i++) {
if (strncmp(name, spa_debug_type_short_name(spa_type_audio_channel[i].name), len) == 0)
return spa_type_audio_channel[i].type;
}
return SPA_AUDIO_CHANNEL_UNKNOWN;
}
static int
impl_init(const struct spa_handle_factory *factory,
struct spa_handle *handle,
@ -779,16 +800,24 @@ impl_init(const struct spa_handle_factory *factory,
spa_loop_add_source(this->data_loop, &this->timer_source);
this->default_channels = 0;
this->default_rate = 0;
for (i = 0; info && i < info->n_items; i++) {
if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_CHANNELS)) {
this->default_channels = atoi(info->items[i].value);
this->props.channels = atoi(info->items[i].value);
} else if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_RATE)) {
this->default_rate = atoi(info->items[i].value);
this->props.rate = atoi(info->items[i].value);
} else if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_POSITION)) {
size_t len;
const char *p = info->items[i].value;
while (*p && this->props.n_pos < SPA_AUDIO_MAX_CHANNELS) {
if ((len = strcspn(p, ",")) == 0)
break;
this->props.pos[this->props.n_pos++] = channel_from_name(p, len);
p += len + strspn(p+len, ",");
}
}
}
if (this->props.n_pos > 0)
this->props.channels = this->props.n_pos;
spa_log_info(this->log, NAME " %p: initialized", this);