mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
adapter: move adapter.auto-port-config to adapter
Move the handling of the default adapter port config to the adapter itself.
This commit is contained in:
parent
efd22efff8
commit
513e8fa56f
2 changed files with 114 additions and 115 deletions
|
|
@ -13,6 +13,7 @@
|
|||
#include <spa/utils/names.h>
|
||||
#include <spa/utils/result.h>
|
||||
#include <spa/utils/string.h>
|
||||
#include <spa/utils/json.h>
|
||||
#include <spa/buffer/alloc.h>
|
||||
#include <spa/pod/parser.h>
|
||||
#include <spa/pod/filter.h>
|
||||
|
|
@ -1689,6 +1690,115 @@ static const struct spa_node_methods impl_node = {
|
|||
.process = impl_node_process,
|
||||
};
|
||||
|
||||
static int do_auto_port_config(struct impl *this, const char *str)
|
||||
{
|
||||
uint32_t state = 0, i;
|
||||
uint8_t buffer[4096];
|
||||
struct spa_pod_builder b;
|
||||
#define POSITION_PRESERVE 0
|
||||
#define POSITION_AUX 1
|
||||
#define POSITION_UNKNOWN 2
|
||||
int res, position = POSITION_PRESERVE;
|
||||
struct spa_pod *param;
|
||||
uint32_t media_type, media_subtype;
|
||||
bool have_format = false, monitor = false, control = false;
|
||||
struct spa_audio_info format = { 0, };
|
||||
enum spa_param_port_config_mode mode = SPA_PARAM_PORT_CONFIG_MODE_none;
|
||||
struct spa_json it[2];
|
||||
char key[1024], val[256];
|
||||
|
||||
spa_json_init(&it[0], str, strlen(str));
|
||||
if (spa_json_enter_object(&it[0], &it[1]) <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
|
||||
if (spa_json_get_string(&it[1], val, sizeof(val)) <= 0)
|
||||
break;
|
||||
|
||||
if (spa_streq(key, "mode")) {
|
||||
mode = spa_debug_type_find_type_short(spa_type_param_port_config_mode, val);
|
||||
if (mode == SPA_ID_INVALID)
|
||||
mode = SPA_PARAM_PORT_CONFIG_MODE_none;
|
||||
} else if (spa_streq(key, "monitor")) {
|
||||
monitor = spa_atob(val);
|
||||
} else if (spa_streq(key, "control")) {
|
||||
control = spa_atob(val);
|
||||
} else if (spa_streq(key, "position")) {
|
||||
if (spa_streq(val, "unknown"))
|
||||
position = POSITION_UNKNOWN;
|
||||
else if (spa_streq(val, "aux"))
|
||||
position = POSITION_AUX;
|
||||
else
|
||||
position = POSITION_PRESERVE;
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
struct spa_audio_info info = { 0, };
|
||||
struct spa_pod *position = NULL;
|
||||
uint32_t n_position = 0;
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if ((res = spa_node_port_enum_params_sync(this->follower,
|
||||
this->direction, 0,
|
||||
SPA_PARAM_EnumFormat, &state,
|
||||
NULL, ¶m, &b)) != 1)
|
||||
break;
|
||||
|
||||
if ((res = spa_format_parse(param, &media_type, &media_subtype)) < 0)
|
||||
continue;
|
||||
|
||||
if (media_type != SPA_MEDIA_TYPE_audio ||
|
||||
media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
continue;
|
||||
|
||||
spa_pod_object_fixate((struct spa_pod_object*)param);
|
||||
|
||||
if (spa_pod_parse_object(param,
|
||||
SPA_TYPE_OBJECT_Format, NULL,
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(&info.info.raw.format),
|
||||
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(&info.info.raw.rate),
|
||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(&info.info.raw.channels),
|
||||
SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position)) < 0)
|
||||
continue;
|
||||
|
||||
if (position != NULL)
|
||||
n_position = spa_pod_copy_array(position, SPA_TYPE_Id,
|
||||
info.info.raw.position, SPA_AUDIO_MAX_CHANNELS);
|
||||
if (n_position == 0 || n_position != info.info.raw.channels)
|
||||
SPA_FLAG_SET(info.info.raw.flags, SPA_AUDIO_FLAG_UNPOSITIONED);
|
||||
|
||||
if (format.info.raw.channels >= info.info.raw.channels)
|
||||
continue;
|
||||
|
||||
format = info;
|
||||
have_format = true;
|
||||
}
|
||||
if (!have_format)
|
||||
return -ENOENT;
|
||||
|
||||
if (position == POSITION_AUX) {
|
||||
for (i = 0; i < format.info.raw.channels; i++)
|
||||
format.info.raw.position[i] = SPA_AUDIO_CHANNEL_START_Aux + i;
|
||||
} else if (position == POSITION_UNKNOWN) {
|
||||
for (i = 0; i < format.info.raw.channels; i++)
|
||||
format.info.raw.position[i] = SPA_AUDIO_CHANNEL_UNKNOWN;
|
||||
}
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
param = spa_format_audio_raw_build(&b, SPA_PARAM_Format, &format.info.raw);
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamPortConfig, SPA_PARAM_PortConfig,
|
||||
SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(this->direction),
|
||||
SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(mode),
|
||||
SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_Bool(monitor),
|
||||
SPA_PARAM_PORT_CONFIG_control, SPA_POD_Bool(control),
|
||||
SPA_PARAM_PORT_CONFIG_format, SPA_POD_Pod(param));
|
||||
impl_node_set_param(this, SPA_PARAM_PortConfig, 0, param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
|
||||
{
|
||||
struct impl *this;
|
||||
|
|
@ -1817,7 +1927,10 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
spa_node_add_listener(this->convert,
|
||||
&this->convert_listener, &convert_node_events, this);
|
||||
|
||||
configure_convert(this, SPA_PARAM_PORT_CONFIG_MODE_dsp);
|
||||
if (info && (str = spa_dict_lookup(info, "adapter.auto-port-config")) != NULL)
|
||||
do_auto_port_config(this, str);
|
||||
else
|
||||
configure_convert(this, SPA_PARAM_PORT_CONFIG_MODE_dsp);
|
||||
|
||||
link_io(this);
|
||||
|
||||
|
|
|
|||
|
|
@ -124,117 +124,6 @@ static int find_format(struct spa_node *node, enum pw_direction direction,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int do_auto_port_config(struct node *n, const char *str)
|
||||
{
|
||||
uint32_t state = 0, i;
|
||||
uint8_t buffer[4096];
|
||||
struct spa_pod_builder b;
|
||||
#define POSITION_PRESERVE 0
|
||||
#define POSITION_AUX 1
|
||||
#define POSITION_UNKNOWN 2
|
||||
int res, position = POSITION_PRESERVE;
|
||||
struct spa_pod *param;
|
||||
uint32_t media_type, media_subtype;
|
||||
bool have_format = false, monitor = false, control = false;
|
||||
struct spa_audio_info format = { 0, };
|
||||
enum spa_param_port_config_mode mode = SPA_PARAM_PORT_CONFIG_MODE_none;
|
||||
struct spa_json it[2];
|
||||
char key[1024], val[256];
|
||||
|
||||
spa_json_init(&it[0], str, strlen(str));
|
||||
if (spa_json_enter_object(&it[0], &it[1]) <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
|
||||
if (spa_json_get_string(&it[1], val, sizeof(val)) <= 0)
|
||||
break;
|
||||
|
||||
if (spa_streq(key, "mode")) {
|
||||
mode = spa_debug_type_find_type_short(spa_type_param_port_config_mode, val);
|
||||
if (mode == SPA_ID_INVALID)
|
||||
mode = SPA_PARAM_PORT_CONFIG_MODE_none;
|
||||
} else if (spa_streq(key, "monitor")) {
|
||||
monitor = spa_atob(val);
|
||||
} else if (spa_streq(key, "control")) {
|
||||
control = spa_atob(val);
|
||||
} else if (spa_streq(key, "position")) {
|
||||
if (spa_streq(val, "unknown"))
|
||||
position = POSITION_UNKNOWN;
|
||||
else if (spa_streq(val, "aux"))
|
||||
position = POSITION_AUX;
|
||||
else
|
||||
position = POSITION_PRESERVE;
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
struct spa_audio_info info = { 0, };
|
||||
struct spa_pod *position = NULL;
|
||||
uint32_t n_position = 0;
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if ((res = spa_node_port_enum_params_sync(n->follower,
|
||||
n->direction == PW_DIRECTION_INPUT ?
|
||||
SPA_DIRECTION_INPUT :
|
||||
SPA_DIRECTION_OUTPUT, 0,
|
||||
SPA_PARAM_EnumFormat, &state,
|
||||
NULL, ¶m, &b)) != 1)
|
||||
break;
|
||||
|
||||
if ((res = spa_format_parse(param, &media_type, &media_subtype)) < 0)
|
||||
continue;
|
||||
|
||||
if (media_type != SPA_MEDIA_TYPE_audio ||
|
||||
media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
continue;
|
||||
|
||||
spa_pod_object_fixate((struct spa_pod_object*)param);
|
||||
|
||||
if (spa_pod_parse_object(param,
|
||||
SPA_TYPE_OBJECT_Format, NULL,
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(&info.info.raw.format),
|
||||
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(&info.info.raw.rate),
|
||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(&info.info.raw.channels),
|
||||
SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position)) < 0)
|
||||
continue;
|
||||
|
||||
if (position != NULL)
|
||||
n_position = spa_pod_copy_array(position, SPA_TYPE_Id,
|
||||
info.info.raw.position, SPA_AUDIO_MAX_CHANNELS);
|
||||
if (n_position == 0 || n_position != info.info.raw.channels)
|
||||
SPA_FLAG_SET(info.info.raw.flags, SPA_AUDIO_FLAG_UNPOSITIONED);
|
||||
|
||||
if (format.info.raw.channels >= info.info.raw.channels)
|
||||
continue;
|
||||
|
||||
format = info;
|
||||
have_format = true;
|
||||
}
|
||||
if (!have_format)
|
||||
return -ENOENT;
|
||||
|
||||
if (position == POSITION_AUX) {
|
||||
for (i = 0; i < format.info.raw.channels; i++)
|
||||
format.info.raw.position[i] = SPA_AUDIO_CHANNEL_START_Aux + i;
|
||||
} else if (position == POSITION_UNKNOWN) {
|
||||
for (i = 0; i < format.info.raw.channels; i++)
|
||||
format.info.raw.position[i] = SPA_AUDIO_CHANNEL_UNKNOWN;
|
||||
}
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
param = spa_format_audio_raw_build(&b, SPA_PARAM_Format, &format.info.raw);
|
||||
param = spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_ParamPortConfig, SPA_PARAM_PortConfig,
|
||||
SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(n->direction),
|
||||
SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(mode),
|
||||
SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_Bool(monitor),
|
||||
SPA_PARAM_PORT_CONFIG_control, SPA_POD_Bool(control),
|
||||
SPA_PARAM_PORT_CONFIG_format, SPA_POD_Pod(param));
|
||||
pw_impl_node_set_param(n->node, SPA_PARAM_PortConfig, 0, param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct info_data {
|
||||
struct spa_hook listener;
|
||||
struct spa_node *node;
|
||||
|
|
@ -375,9 +264,6 @@ struct pw_impl_node *pw_adapter_new(struct pw_context *context,
|
|||
|
||||
pw_impl_node_add_listener(node, &n->node_listener, &node_events, n);
|
||||
|
||||
if ((str = pw_properties_get(props, "adapter.auto-port-config")) != NULL)
|
||||
do_auto_port_config(n, str);
|
||||
|
||||
spa_dict_for_each(it, &props->dict) {
|
||||
if (spa_strstartswith(it->key, "node.param.")) {
|
||||
if ((res = handle_node_param(node, &it->key[11], it->value)) < 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue