mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2025-12-20 05:20:05 +01:00
Merge branch 'preferred-format-prop' into 'master'
si-linkables: add int format-preference-priority SI audio adapter property See merge request pipewire/wireplumber!665
This commit is contained in:
commit
c90dc1f184
2 changed files with 73 additions and 11 deletions
|
|
@ -33,6 +33,18 @@ struct _WpSiAudioAdapter
|
|||
WpDirection portconfig_direction;
|
||||
gboolean is_device;
|
||||
gboolean dont_remix;
|
||||
/* This is used during linking to pick the preferred format.
|
||||
* If the priority in both in- and output ports is the same,
|
||||
* the format of the input port is picked. If the priority
|
||||
* is not set, the default 0 is used.
|
||||
* Furthermore, if the priority is greater than 0, then in
|
||||
* si_audio_adapter_find_format (), a new format is always
|
||||
* picked, and in si_audio_adapter_enable_active (), the
|
||||
* adapter is configured immediately. This is because such
|
||||
* priorities indicate that this adapter's format is
|
||||
* preferred during negotiation.
|
||||
* Priorities lower than 0 are invalid. */
|
||||
gint format_preference_priority;
|
||||
gboolean is_autoconnect;
|
||||
gboolean have_encoded;
|
||||
gboolean encoded_only;
|
||||
|
|
@ -110,6 +122,7 @@ si_audio_adapter_reset (WpSessionItem * item)
|
|||
self->portconfig_direction = WP_DIRECTION_INPUT;
|
||||
self->is_device = FALSE;
|
||||
self->dont_remix = FALSE;
|
||||
self->format_preference_priority = 0;
|
||||
self->is_autoconnect = FALSE;
|
||||
self->have_encoded = FALSE;
|
||||
self->encoded_only = FALSE;
|
||||
|
|
@ -196,7 +209,15 @@ si_audio_adapter_find_format (WpSiAudioAdapter * self, WpNode * node)
|
|||
!spa_pod_copy_array(position, SPA_TYPE_Id, raw_format.position, SPA_AUDIO_MAX_CHANNELS))
|
||||
SPA_FLAG_SET(raw_format.flags, SPA_AUDIO_FLAG_UNPOSITIONED);
|
||||
|
||||
if (self->raw_format.channels < raw_format.channels) {
|
||||
/* Only use this new format if it has _more_ channels than the old one
|
||||
* to avoid unnecessary renegotiations and reconfigurations. By default,
|
||||
* it is preferable to open too many channels than too few, since the
|
||||
* extra channels can simply remain unused.
|
||||
* Exception: when format_preference_priority is >0, do use the new format
|
||||
* always. Such priorities indicate that the user wants the new format to
|
||||
* be picked over the current format in all cases. */
|
||||
if ((self->format_preference_priority > 0) ||
|
||||
(self->raw_format.channels < raw_format.channels)) {
|
||||
self->raw_format = raw_format;
|
||||
if (is_unpositioned(&raw_format))
|
||||
self->is_unpositioned = TRUE;
|
||||
|
|
@ -285,6 +306,14 @@ si_audio_adapter_configure (WpSessionItem * item, WpProperties *p)
|
|||
str = wp_properties_get (si_props, PW_KEY_STREAM_DONT_REMIX);
|
||||
self->dont_remix = str && pw_properties_parse_bool (str);
|
||||
|
||||
str = wp_properties_get (si_props, "stream.format-preference-priority");
|
||||
self->format_preference_priority = (str) ? pw_properties_parse_int (str) : 0;
|
||||
if (self->format_preference_priority < 0) {
|
||||
wp_critical_object (item, "stream.format-preference-priority value %d "
|
||||
"is invalid (must be >= 0)", self->format_preference_priority);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
str = wp_properties_get (si_props, PW_KEY_NODE_AUTOCONNECT);
|
||||
self->is_autoconnect = str && pw_properties_parse_bool (str);
|
||||
|
||||
|
|
@ -609,9 +638,12 @@ si_audio_adapter_enable_active (WpSessionItem *si, WpTransition *transition)
|
|||
self->params_changed_sigid = g_signal_connect_object (self->node,
|
||||
"params-changed", (GCallback) on_node_params_changed, self, 0);
|
||||
|
||||
/* If device node, enum available formats and set one of them */
|
||||
/* If device node, enum available formats and set one of them.
|
||||
* Also, if format_preference_priority is >0, do the same, since during
|
||||
* linking, the link will try to use the format as soon as possible. */
|
||||
if (!self->no_format && (self->is_device || self->dont_remix ||
|
||||
!self->is_autoconnect || self->disable_dsp || self->is_unpositioned))
|
||||
!self->is_autoconnect || self->disable_dsp || self->is_unpositioned ||
|
||||
(self->format_preference_priority > 0)))
|
||||
si_audio_adapter_configure_node (self, transition);
|
||||
|
||||
/* Otherwise just finish activating */
|
||||
|
|
|
|||
|
|
@ -428,10 +428,12 @@ on_adapters_ready (GObject *obj, GAsyncResult * res, gpointer p)
|
|||
struct adapter
|
||||
{
|
||||
WpSiAdapter *si;
|
||||
guint32 proxy_id;
|
||||
gboolean is_device;
|
||||
gboolean dont_remix;
|
||||
gboolean unpositioned;
|
||||
gboolean no_dsp;
|
||||
gint format_preference_priority;
|
||||
WpSpaPod *fmt;
|
||||
const gchar *mode;
|
||||
};
|
||||
|
|
@ -448,8 +450,14 @@ static void
|
|||
configure_adapter (WpSiStandardLink *self, WpTransition *transition,
|
||||
struct adapter *main, struct adapter *other)
|
||||
{
|
||||
/* configure other to have the same format with main, if necessary */
|
||||
if (!main->no_dsp && !other->dont_remix && !other->unpositioned && !main->unpositioned) {
|
||||
/* Configure other to have the same format with main, if necessary.
|
||||
* Do this only if both sides have valid channel positions, otherwise,
|
||||
* the channel mixers can't work properly.
|
||||
* main->preferred_format overrides this though, since then, the
|
||||
* format from main shall be used no matter what. */
|
||||
if (!main->no_dsp && !other->dont_remix &&
|
||||
((main->format_preference_priority > 0) || (!other->unpositioned &&
|
||||
!main->unpositioned))) {
|
||||
/* if formats are the same, no need to reconfigure */
|
||||
if (other->fmt && !g_strcmp0 (main->mode, other->mode)
|
||||
&& wp_spa_pod_equal (main->fmt, other->fmt))
|
||||
|
|
@ -539,6 +547,9 @@ configure_and_link_adapters (WpSiStandardLink *self, WpTransition *transition)
|
|||
out->si = g_steal_pointer (&si_out);
|
||||
in->si = g_steal_pointer (&si_in);
|
||||
|
||||
out->proxy_id = wp_session_item_get_associated_proxy_id (WP_SESSION_ITEM (out->si), WP_TYPE_NODE);
|
||||
in->proxy_id = wp_session_item_get_associated_proxy_id (WP_SESSION_ITEM (in->si), WP_TYPE_NODE);
|
||||
|
||||
str = wp_session_item_get_property (WP_SESSION_ITEM (out->si), "item.node.type");
|
||||
out->is_device = !g_strcmp0 (str, "device");
|
||||
str = wp_session_item_get_property (WP_SESSION_ITEM (in->si), "item.node.type");
|
||||
|
|
@ -559,19 +570,32 @@ configure_and_link_adapters (WpSiStandardLink *self, WpTransition *transition)
|
|||
str = wp_session_item_get_property (WP_SESSION_ITEM (in->si), "item.features.no-dsp");
|
||||
in->no_dsp = str && pw_properties_parse_bool (str);
|
||||
|
||||
wp_debug_object (self, "out [device:%d, dont_remix %d, unpos %d], "
|
||||
"in: [device %d, dont_remix %d, unpos %d]",
|
||||
out->is_device, out->dont_remix, out->unpositioned,
|
||||
in->is_device, in->dont_remix, in->unpositioned);
|
||||
str = wp_session_item_get_property (WP_SESSION_ITEM (out->si), "stream.format-preference-priority");
|
||||
out->format_preference_priority = (str) ? pw_properties_parse_int (str) : 0;
|
||||
str = wp_session_item_get_property (WP_SESSION_ITEM (in->si), "stream.format-preference-priority");
|
||||
in->format_preference_priority = (str) ? pw_properties_parse_int (str) : 0;
|
||||
|
||||
/* we always use out->si format, unless in->si is device */
|
||||
if (!out->is_device && in->is_device) {
|
||||
wp_debug_object (self, "out [proxy id %" G_GUINT32_FORMAT ", device %d, dont_remix %d, "
|
||||
"unpos %d format_preference_priority %d], in: [proxy id %" G_GUINT32_FORMAT
|
||||
", device %d, dont_remix %d, unpos %d format_preference_priority %d]", out->proxy_id,
|
||||
out->is_device, out->dont_remix, out->unpositioned, out->format_preference_priority,
|
||||
in->proxy_id, in->is_device, in->dont_remix, in->unpositioned,
|
||||
in->format_preference_priority);
|
||||
|
||||
/* If the format_preference_priority values of out and in are equal,
|
||||
* always use out->si format, unless in->si is device.
|
||||
* If instead one of the two values is higher, use the associated
|
||||
* adapter's format. */
|
||||
if ((out->format_preference_priority < in->format_preference_priority) ||
|
||||
((out->format_preference_priority == in->format_preference_priority) &&
|
||||
!out->is_device && in->is_device)) {
|
||||
main = in;
|
||||
other = out;
|
||||
} else {
|
||||
main = out;
|
||||
other = in;
|
||||
}
|
||||
wp_debug_object (self, "using %s adapter as main adapter", (main == in) ? "in" : "out");
|
||||
|
||||
/* always configure both adapters in passthrough mode
|
||||
if this is a passthrough link */
|
||||
|
|
@ -588,6 +612,12 @@ configure_and_link_adapters (WpSiStandardLink *self, WpTransition *transition)
|
|||
main->fmt = wp_si_adapter_get_ports_format (main->si, &main->mode);
|
||||
other->fmt = wp_si_adapter_get_ports_format (other->si, &other->mode);
|
||||
|
||||
/* Logging out and in formats instead of main and other ones on purpose,
|
||||
* since main and other can be swapped depending on the logic above,
|
||||
* while out and in always have the same unchanging meaning. */
|
||||
wp_debug_boxed (WP_TYPE_SPA_POD, out->fmt, "configured out adapter format");
|
||||
wp_debug_boxed (WP_TYPE_SPA_POD, in->fmt, "configured in adapter format");
|
||||
|
||||
if (main->fmt)
|
||||
/* ideally, configure other based on main */
|
||||
configure_adapter (self, transition, main, other);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue