mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
modules: fix format parsing
Use the same logic for parsing the format.
This commit is contained in:
parent
da95043002
commit
c8b8b24a9c
8 changed files with 210 additions and 178 deletions
|
|
@ -125,6 +125,10 @@
|
|||
PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
||||
#define PW_LOG_TOPIC_DEFAULT mod_topic
|
||||
|
||||
#define DEFAULT_RATE 48000
|
||||
#define DEFAULT_CHANNELS 2
|
||||
#define DEFAULT_POSITION "[ FL FR ]"
|
||||
|
||||
/* Hopefully this is enough for any combination of AEC engine and resampler
|
||||
* input requirement for rate matching */
|
||||
#define MAX_BUFSIZE_MS 100
|
||||
|
|
@ -859,9 +863,15 @@ static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_
|
|||
*info = SPA_AUDIO_INFO_RAW_INIT(
|
||||
.format = SPA_AUDIO_FORMAT_F32P);
|
||||
info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate);
|
||||
if (info->rate == 0)
|
||||
info->rate = DEFAULT_RATE;
|
||||
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels);
|
||||
info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL)
|
||||
parse_position(info, str, strlen(str));
|
||||
if (info->channels == 0)
|
||||
parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION));
|
||||
}
|
||||
|
||||
static void copy_props(struct impl *impl, struct pw_properties *props, const char *key)
|
||||
|
|
@ -927,14 +937,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
|
||||
parse_audio_info(props, &impl->info);
|
||||
|
||||
if (impl->info.channels == 0) {
|
||||
impl->info.channels = 2;
|
||||
impl->info.position[0] = SPA_AUDIO_CHANNEL_FL;
|
||||
impl->info.position[1] = SPA_AUDIO_CHANNEL_FR;
|
||||
}
|
||||
if (impl->info.rate == 0)
|
||||
impl->info.rate = 48000;
|
||||
|
||||
if ((str = pw_properties_get(props, "source.props")) != NULL)
|
||||
pw_properties_update_string(impl->source_props, str, strlen(str));
|
||||
if ((str = pw_properties_get(props, "sink.props")) != NULL)
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
|||
"[ node.description=<description of the nodes> ] " \
|
||||
"[ audio.format=<format, default:"DEFAULT_FORMAT"> ] " \
|
||||
"[ audio.rate=<sample rate, default: "SPA_STRINGIFY(DEFAULT_RATE)"> ] " \
|
||||
"[ audio.channels=<number of channels, default:"SPA_STRINGIFY(EFAULT_CHANNELS) "> ] " \
|
||||
"[ audio.channels=<number of channels, default:"SPA_STRINGIFY(DEFAULT_CHANNELS) "> ] " \
|
||||
"[ audio.position=<channel map, default:"DEFAULT_POSITION"> ] " \
|
||||
"[ stream.props=<properties> ] "
|
||||
|
||||
|
|
@ -340,56 +340,59 @@ static void parse_position(struct spa_audio_info_raw *info, const char *val, siz
|
|||
}
|
||||
}
|
||||
|
||||
static int parse_audio_info(struct impl *impl)
|
||||
static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info)
|
||||
{
|
||||
struct pw_properties *props = impl->stream_props;
|
||||
struct spa_audio_info_raw *info = &impl->info;
|
||||
const char *str;
|
||||
|
||||
spa_zero(*info);
|
||||
|
||||
if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL)
|
||||
str = DEFAULT_FORMAT;
|
||||
info->format = format_from_name(str, strlen(str));
|
||||
switch (info->format) {
|
||||
case SPA_AUDIO_FORMAT_S8:
|
||||
case SPA_AUDIO_FORMAT_U8:
|
||||
impl->frame_size = 1;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_S16:
|
||||
impl->frame_size = 2;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_S24:
|
||||
impl->frame_size = 3;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_S24_32:
|
||||
case SPA_AUDIO_FORMAT_S32:
|
||||
case SPA_AUDIO_FORMAT_F32:
|
||||
impl->frame_size = 4;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_F64:
|
||||
impl->frame_size = 8;
|
||||
break;
|
||||
default:
|
||||
pw_log_error("unsupported format '%s'", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, DEFAULT_RATE);
|
||||
if (info->rate == 0) {
|
||||
pw_log_error("invalid rate '%s'", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, DEFAULT_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) == NULL)
|
||||
str = DEFAULT_POSITION;
|
||||
parse_position(info, str, strlen(str));
|
||||
if (info->channels == 0) {
|
||||
pw_log_error("invalid channels '%s'", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
impl->frame_size *= info->channels;
|
||||
|
||||
return 0;
|
||||
info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate);
|
||||
if (info->rate == 0)
|
||||
info->rate = DEFAULT_RATE;
|
||||
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels);
|
||||
info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL)
|
||||
parse_position(info, str, strlen(str));
|
||||
if (info->channels == 0)
|
||||
parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION));
|
||||
}
|
||||
|
||||
static int calc_frame_size(const struct spa_audio_info_raw *info)
|
||||
{
|
||||
int res = info->channels;
|
||||
switch (info->format) {
|
||||
case SPA_AUDIO_FORMAT_U8:
|
||||
case SPA_AUDIO_FORMAT_S8:
|
||||
case SPA_AUDIO_FORMAT_ALAW:
|
||||
case SPA_AUDIO_FORMAT_ULAW:
|
||||
return res;
|
||||
case SPA_AUDIO_FORMAT_S16:
|
||||
case SPA_AUDIO_FORMAT_S16_OE:
|
||||
case SPA_AUDIO_FORMAT_U16:
|
||||
return res * 2;
|
||||
case SPA_AUDIO_FORMAT_S24:
|
||||
case SPA_AUDIO_FORMAT_S24_OE:
|
||||
case SPA_AUDIO_FORMAT_U24:
|
||||
return res * 3;
|
||||
case SPA_AUDIO_FORMAT_S24_32:
|
||||
case SPA_AUDIO_FORMAT_S24_32_OE:
|
||||
case SPA_AUDIO_FORMAT_S32:
|
||||
case SPA_AUDIO_FORMAT_S32_OE:
|
||||
case SPA_AUDIO_FORMAT_U32:
|
||||
case SPA_AUDIO_FORMAT_U32_OE:
|
||||
case SPA_AUDIO_FORMAT_F32:
|
||||
case SPA_AUDIO_FORMAT_F32_OE:
|
||||
return res * 4;
|
||||
case SPA_AUDIO_FORMAT_F64:
|
||||
case SPA_AUDIO_FORMAT_F64_OE:
|
||||
return res * 8;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_props(struct impl *impl, struct pw_properties *props, const char *key)
|
||||
|
|
@ -467,7 +470,11 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
copy_props(impl, props, PW_KEY_NODE_VIRTUAL);
|
||||
copy_props(impl, props, PW_KEY_MEDIA_CLASS);
|
||||
|
||||
if ((res = parse_audio_info(impl)) < 0) {
|
||||
parse_audio_info(impl->stream_props, &impl->info);
|
||||
|
||||
impl->frame_size = calc_frame_size(&impl->info);
|
||||
if (impl->frame_size == 0) {
|
||||
res = -EINVAL;
|
||||
pw_log_error( "can't parse audio format");
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
|||
"[ node.description=<description of the nodes> ] " \
|
||||
"[ audio.format=<format, default:"DEFAULT_FORMAT"> ] " \
|
||||
"[ audio.rate=<sample rate, default: "SPA_STRINGIFY(DEFAULT_RATE)"> ] " \
|
||||
"[ audio.channels=<number of channels, default:"SPA_STRINGIFY(EFAULT_CHANNELS) "> ] " \
|
||||
"[ audio.channels=<number of channels, default:"SPA_STRINGIFY(DEFAULT_CHANNELS) "> ] " \
|
||||
"[ audio.position=<channel map, default:"DEFAULT_POSITION"> ] " \
|
||||
"[ stream.props=<properties> ] "
|
||||
|
||||
|
|
@ -344,56 +344,59 @@ static void parse_position(struct spa_audio_info_raw *info, const char *val, siz
|
|||
}
|
||||
}
|
||||
|
||||
static int parse_audio_info(struct impl *impl)
|
||||
static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info)
|
||||
{
|
||||
struct pw_properties *props = impl->stream_props;
|
||||
struct spa_audio_info_raw *info = &impl->info;
|
||||
const char *str;
|
||||
|
||||
spa_zero(*info);
|
||||
|
||||
if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL)
|
||||
str = DEFAULT_FORMAT;
|
||||
info->format = format_from_name(str, strlen(str));
|
||||
switch (info->format) {
|
||||
case SPA_AUDIO_FORMAT_S8:
|
||||
case SPA_AUDIO_FORMAT_U8:
|
||||
impl->frame_size = 1;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_S16:
|
||||
impl->frame_size = 2;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_S24:
|
||||
impl->frame_size = 3;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_S24_32:
|
||||
case SPA_AUDIO_FORMAT_S32:
|
||||
case SPA_AUDIO_FORMAT_F32:
|
||||
impl->frame_size = 4;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_F64:
|
||||
impl->frame_size = 8;
|
||||
break;
|
||||
default:
|
||||
pw_log_error("unsupported format '%s'", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, DEFAULT_RATE);
|
||||
if (info->rate == 0) {
|
||||
pw_log_error("invalid rate '%s'", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, DEFAULT_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) == NULL)
|
||||
str = DEFAULT_POSITION;
|
||||
parse_position(info, str, strlen(str));
|
||||
if (info->channels == 0) {
|
||||
pw_log_error("invalid channels '%s'", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
impl->frame_size *= info->channels;
|
||||
|
||||
return 0;
|
||||
info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate);
|
||||
if (info->rate == 0)
|
||||
info->rate = DEFAULT_RATE;
|
||||
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels);
|
||||
info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL)
|
||||
parse_position(info, str, strlen(str));
|
||||
if (info->channels == 0)
|
||||
parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION));
|
||||
}
|
||||
|
||||
static int calc_frame_size(const struct spa_audio_info_raw *info)
|
||||
{
|
||||
int res = info->channels;
|
||||
switch (info->format) {
|
||||
case SPA_AUDIO_FORMAT_U8:
|
||||
case SPA_AUDIO_FORMAT_S8:
|
||||
case SPA_AUDIO_FORMAT_ALAW:
|
||||
case SPA_AUDIO_FORMAT_ULAW:
|
||||
return res;
|
||||
case SPA_AUDIO_FORMAT_S16:
|
||||
case SPA_AUDIO_FORMAT_S16_OE:
|
||||
case SPA_AUDIO_FORMAT_U16:
|
||||
return res * 2;
|
||||
case SPA_AUDIO_FORMAT_S24:
|
||||
case SPA_AUDIO_FORMAT_S24_OE:
|
||||
case SPA_AUDIO_FORMAT_U24:
|
||||
return res * 3;
|
||||
case SPA_AUDIO_FORMAT_S24_32:
|
||||
case SPA_AUDIO_FORMAT_S24_32_OE:
|
||||
case SPA_AUDIO_FORMAT_S32:
|
||||
case SPA_AUDIO_FORMAT_S32_OE:
|
||||
case SPA_AUDIO_FORMAT_U32:
|
||||
case SPA_AUDIO_FORMAT_U32_OE:
|
||||
case SPA_AUDIO_FORMAT_F32:
|
||||
case SPA_AUDIO_FORMAT_F32_OE:
|
||||
return res * 4;
|
||||
case SPA_AUDIO_FORMAT_F64:
|
||||
case SPA_AUDIO_FORMAT_F64_OE:
|
||||
return res * 8;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_props(struct impl *impl, struct pw_properties *props, const char *key)
|
||||
|
|
@ -471,7 +474,11 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
copy_props(impl, props, PW_KEY_NODE_VIRTUAL);
|
||||
copy_props(impl, props, PW_KEY_MEDIA_CLASS);
|
||||
|
||||
if ((res = parse_audio_info(impl)) < 0) {
|
||||
parse_audio_info(impl->stream_props, &impl->info);
|
||||
|
||||
impl->frame_size = calc_frame_size(&impl->info);
|
||||
if (impl->frame_size == 0) {
|
||||
res = -EINVAL;
|
||||
pw_log_error( "can't parse audio format");
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2097,8 +2097,9 @@ static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_
|
|||
|
||||
*info = SPA_AUDIO_INFO_RAW_INIT(
|
||||
.format = SPA_AUDIO_FORMAT_F32P);
|
||||
info->rate = pw_properties_get_int32(props, PW_KEY_AUDIO_RATE, 0);
|
||||
info->channels = pw_properties_get_int32(props, PW_KEY_AUDIO_CHANNELS, 0);
|
||||
info->rate = pw_properties_get_int32(props, PW_KEY_AUDIO_RATE, info->rate);
|
||||
info->channels = pw_properties_get_int32(props, PW_KEY_AUDIO_CHANNELS, info->channels);
|
||||
info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL)
|
||||
parse_position(info, str, strlen(str));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -453,6 +453,7 @@ static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_
|
|||
.format = SPA_AUDIO_FORMAT_F32P);
|
||||
info->rate = pw_properties_get_int32(props, PW_KEY_AUDIO_RATE, 0);
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, 0);
|
||||
info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL)
|
||||
parse_position(info, str, strlen(str));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@
|
|||
* tunnel.mode = playback
|
||||
* # Set the pipe name to tunnel to
|
||||
* pipe.filename = "/tmp/fifo_output"
|
||||
* #audio.format=<sample format>
|
||||
* #audio.rate=<sample rate>
|
||||
* #audio.channels=<number of channels>
|
||||
* #audio.position=<channel map>
|
||||
|
|
@ -125,6 +126,11 @@
|
|||
#define DEFAULT_CAPTURE_FILENAME "/tmp/fifo_input"
|
||||
#define DEFAULT_PLAYBACK_FILENAME "/tmp/fifo_output"
|
||||
|
||||
#define DEFAULT_FORMAT "S16"
|
||||
#define DEFAULT_RATE 48000
|
||||
#define DEFAULT_CHANNELS 2
|
||||
#define DEFAULT_POSITION "[ FL FR ]"
|
||||
|
||||
PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
||||
#define PW_LOG_TOPIC_DEFAULT mod_topic
|
||||
|
||||
|
|
@ -133,6 +139,7 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
|||
"[ node.name=<name of the nodes> ] " \
|
||||
"[ node.description=<description of the nodes> ] " \
|
||||
"[ node.target=<remote node target name> ] " \
|
||||
"[ audio.format=<sample format> ] " \
|
||||
"[ audio.rate=<sample rate> ] " \
|
||||
"[ audio.channels=<number of channels> ] " \
|
||||
"[ audio.position=<channel map> ] " \
|
||||
|
|
@ -511,31 +518,28 @@ static inline uint32_t format_from_name(const char *name, size_t len)
|
|||
return SPA_AUDIO_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info)
|
||||
static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
*info = SPA_AUDIO_INFO_RAW_INIT(
|
||||
.rate = 48000,
|
||||
.channels = 2,
|
||||
.format = SPA_AUDIO_FORMAT_S16);
|
||||
|
||||
if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) != NULL) {
|
||||
uint32_t id;
|
||||
|
||||
id = format_from_name(str, strlen(str));
|
||||
if (id != SPA_AUDIO_FORMAT_UNKNOWN)
|
||||
info->format = id;
|
||||
}
|
||||
spa_zero(*info);
|
||||
if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL)
|
||||
str = DEFAULT_FORMAT;
|
||||
info->format = format_from_name(str, strlen(str));
|
||||
|
||||
info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate);
|
||||
if (info->rate == 0)
|
||||
info->rate = DEFAULT_RATE;
|
||||
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels);
|
||||
info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL)
|
||||
parse_position(info, str, strlen(str));
|
||||
|
||||
if (info->channels == 0)
|
||||
parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION));
|
||||
}
|
||||
|
||||
static int calc_frame_size(struct spa_audio_info_raw *info)
|
||||
static int calc_frame_size(const struct spa_audio_info_raw *info)
|
||||
{
|
||||
int res = info->channels;
|
||||
switch (info->format) {
|
||||
|
|
@ -662,13 +666,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
|
||||
parse_audio_info(impl->stream_props, &impl->info);
|
||||
|
||||
if (impl->info.rate != 0 &&
|
||||
pw_properties_get(props, PW_KEY_NODE_RATE) == NULL)
|
||||
pw_properties_setf(props, PW_KEY_NODE_RATE,
|
||||
"1/%u", impl->info.rate),
|
||||
|
||||
copy_props(impl, props, PW_KEY_NODE_RATE);
|
||||
|
||||
impl->frame_size = calc_frame_size(&impl->info);
|
||||
if (impl->frame_size == 0) {
|
||||
pw_log_error("unsupported audio format:%d channels:%d",
|
||||
|
|
@ -676,6 +673,13 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
res = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
if (impl->info.rate != 0 &&
|
||||
pw_properties_get(props, PW_KEY_NODE_RATE) == NULL)
|
||||
pw_properties_setf(props, PW_KEY_NODE_RATE,
|
||||
"1/%u", impl->info.rate),
|
||||
|
||||
copy_props(impl, props, PW_KEY_NODE_RATE);
|
||||
|
||||
impl->leftover = calloc(1, impl->frame_size);
|
||||
if (impl->leftover == NULL) {
|
||||
res = -errno;
|
||||
|
|
|
|||
|
|
@ -118,6 +118,11 @@
|
|||
PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
||||
#define PW_LOG_TOPIC_DEFAULT mod_topic
|
||||
|
||||
#define DEFAULT_FORMAT "S16"
|
||||
#define DEFAULT_RATE 48000
|
||||
#define DEFAULT_CHANNELS 2
|
||||
#define DEFAULT_POSITION "[ FL FR ]"
|
||||
|
||||
#define MODULE_USAGE "[ remote.name=<remote> ] " \
|
||||
"[ node.latency=<latency as fraction> ] " \
|
||||
"[ node.name=<name of the nodes> ] " \
|
||||
|
|
@ -823,28 +828,25 @@ static inline uint32_t format_from_name(const char *name, size_t len)
|
|||
return SPA_AUDIO_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info)
|
||||
static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
*info = SPA_AUDIO_INFO_RAW_INIT(
|
||||
.rate = 48000,
|
||||
.channels = 2,
|
||||
.format = SPA_AUDIO_FORMAT_S16);
|
||||
|
||||
if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) != NULL) {
|
||||
uint32_t id;
|
||||
|
||||
id = format_from_name(str, strlen(str));
|
||||
if (id != SPA_AUDIO_FORMAT_UNKNOWN)
|
||||
info->format = id;
|
||||
}
|
||||
spa_zero(*info);
|
||||
if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL)
|
||||
str = DEFAULT_FORMAT;
|
||||
info->format = format_from_name(str, strlen(str));
|
||||
|
||||
info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate);
|
||||
if (info->rate == 0)
|
||||
info->rate = DEFAULT_RATE;
|
||||
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels);
|
||||
info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL)
|
||||
parse_position(info, str, strlen(str));
|
||||
|
||||
if (info->channels == 0)
|
||||
parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION));
|
||||
}
|
||||
|
||||
static int calc_frame_size(struct spa_audio_info_raw *info)
|
||||
|
|
|
|||
|
|
@ -1484,56 +1484,59 @@ static void parse_position(struct spa_audio_info_raw *info, const char *val, siz
|
|||
}
|
||||
}
|
||||
|
||||
static int parse_audio_info(struct impl *impl)
|
||||
static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info)
|
||||
{
|
||||
struct pw_properties *props = impl->stream_props;
|
||||
struct spa_audio_info_raw *info = &impl->info;
|
||||
const char *str;
|
||||
|
||||
spa_zero(*info);
|
||||
|
||||
if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL)
|
||||
str = DEFAULT_FORMAT;
|
||||
info->format = format_from_name(str, strlen(str));
|
||||
switch (info->format) {
|
||||
case SPA_AUDIO_FORMAT_S8:
|
||||
case SPA_AUDIO_FORMAT_U8:
|
||||
impl->frame_size = 1;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_S16:
|
||||
impl->frame_size = 2;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_S24:
|
||||
impl->frame_size = 3;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_S24_32:
|
||||
case SPA_AUDIO_FORMAT_S32:
|
||||
case SPA_AUDIO_FORMAT_F32:
|
||||
impl->frame_size = 4;
|
||||
break;
|
||||
case SPA_AUDIO_FORMAT_F64:
|
||||
impl->frame_size = 8;
|
||||
break;
|
||||
default:
|
||||
pw_log_error("unsupported format '%s'", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, DEFAULT_RATE);
|
||||
if (info->rate == 0) {
|
||||
pw_log_error("invalid rate '%s'", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, DEFAULT_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) == NULL)
|
||||
str = DEFAULT_POSITION;
|
||||
parse_position(info, str, strlen(str));
|
||||
if (info->channels == 0) {
|
||||
pw_log_error("invalid channels '%s'", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
impl->frame_size *= info->channels;
|
||||
|
||||
return 0;
|
||||
info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate);
|
||||
if (info->rate == 0)
|
||||
info->rate = DEFAULT_RATE;
|
||||
|
||||
info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels);
|
||||
info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS);
|
||||
if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL)
|
||||
parse_position(info, str, strlen(str));
|
||||
if (info->channels == 0)
|
||||
parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION));
|
||||
}
|
||||
|
||||
static int calc_frame_size(struct spa_audio_info_raw *info)
|
||||
{
|
||||
int res = info->channels;
|
||||
switch (info->format) {
|
||||
case SPA_AUDIO_FORMAT_U8:
|
||||
case SPA_AUDIO_FORMAT_S8:
|
||||
case SPA_AUDIO_FORMAT_ALAW:
|
||||
case SPA_AUDIO_FORMAT_ULAW:
|
||||
return res;
|
||||
case SPA_AUDIO_FORMAT_S16:
|
||||
case SPA_AUDIO_FORMAT_S16_OE:
|
||||
case SPA_AUDIO_FORMAT_U16:
|
||||
return res * 2;
|
||||
case SPA_AUDIO_FORMAT_S24:
|
||||
case SPA_AUDIO_FORMAT_S24_OE:
|
||||
case SPA_AUDIO_FORMAT_U24:
|
||||
return res * 3;
|
||||
case SPA_AUDIO_FORMAT_S24_32:
|
||||
case SPA_AUDIO_FORMAT_S24_32_OE:
|
||||
case SPA_AUDIO_FORMAT_S32:
|
||||
case SPA_AUDIO_FORMAT_S32_OE:
|
||||
case SPA_AUDIO_FORMAT_U32:
|
||||
case SPA_AUDIO_FORMAT_U32_OE:
|
||||
case SPA_AUDIO_FORMAT_F32:
|
||||
case SPA_AUDIO_FORMAT_F32_OE:
|
||||
return res * 4;
|
||||
case SPA_AUDIO_FORMAT_F64:
|
||||
case SPA_AUDIO_FORMAT_F64_OE:
|
||||
return res * 8;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_props(struct impl *impl, struct pw_properties *props, const char *key)
|
||||
|
|
@ -1617,8 +1620,13 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
copy_props(impl, props, PW_KEY_NODE_VIRTUAL);
|
||||
copy_props(impl, props, PW_KEY_MEDIA_CLASS);
|
||||
|
||||
if ((res = parse_audio_info(impl)) < 0) {
|
||||
pw_log_error( "can't parse audio format");
|
||||
parse_audio_info(impl->stream_props, &impl->info);
|
||||
|
||||
impl->frame_size = calc_frame_size(&impl->info);
|
||||
if (impl->frame_size == 0) {
|
||||
pw_log_error("unsupported audio format:%d channels:%d",
|
||||
impl->info.format, impl->info.channels);
|
||||
res = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue