<div>Hi Pali,</div><div> </div><div>To go away from the debate about "what's deprecated and what's not?" , and if yes or no : devices that don't implement a MANDATORY A2DP feature like DUAL CHANNEL, while FAKING that they DO IMPLEMENT IT (which is the only case where my algorithm fails) : have to be the main target, or not ...</div><div>... I have a proposal :</div><div> </div><div>IMHO : what could be a good compromise would be to keep the Automatic mode that you already implemented it as DEFAULT, calling it "Legacy Automatic" or so.</div><div> </div><div>AND add an alternative Automatic mode called "XQ Automatic" (following negotiation strategy similar to my patch). This secondary Automatic mode could replace "forced bitpool" modes.<div> </div><div>If you really want to keep forced bitpool modes, it doesn't hurt, btw.</div><div> </div><div>All the best</div><div>JP</div><div> </div><div> </div><div> </div><div>08.10.2019, 18:52, "Hyperion" <h1p8r10n@yandex.com>:</div><blockquote>I disagree. <div> </div><div>As an engineer you should know that an implementation should not be based on broken devices , but rarher on good standard specifications. </div><div> </div><div>Rare broken devices, and rare very old devices that don't follow A2DP specifications shouldn't be the main design target for Pulseaudio.</div><div> </div><div>Jp<br /> </div>18:29, 8 octobre 2019, "Pali Rohár" <<a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a>>:<blockquote><p>Automatic SBC profile is not going to be changed. It is there to support<br />all devices without any tweaks. ValdikSS already did more tests and<br />there are devices which do not work with higher SBC bitpool. So<br />increasing max value of bitpool in Automatic SBC profile would lead to<br />broken support for these devices and therefore regressions.<br /><br />As Automatic SBC profile is the only one available for systems where<br />codec switching is not supported, it would mean complete regression as<br />these devices completely stops working on those systems.<br /><br />Upgrading either pulseaudio or bluez must not lead to problem that some<br />bluetooth devices stop working (if they worked before upgrade).<br /><br />So no, there would not be any changes in Automatic SBC profile. This one<br />should stay untouched, to make it always working with all existing<br />devices without any regression.<br /><br />On Monday 07 October 2019 16:27:19 Hyperion wrote:</p><blockquote class="4b325df7ce76bb26f46b65c67ccdd4de55a01c29d183c86f9fcf094120928db2b4fd5cf2ec92bc68cb898700bb81355fwmi-quote"> I'm not talking about old Bluez versions : only about the current stable 5.51, and not talking about codec switchin either.<br /><br /> Just talking about improvement of MAX negociated values for SBC. Please take a look at my latest patch.<br /><br /> 07.10.2019, 16:22, "Pali Rohár" <<a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a>>:<br /> > Old bluez versions have bugs and different behavior. So not break<br /> > anything else and still have working audio playback, it is better to not<br /> > touch it and use what is currently supported / provided.<br /> ><br /> > New features like additional codec support, codec switching, etc...<br /> > needs new bluez API and new functionality which were introduced in 5.51<br /> > together with fixed more A2DP related bugs. Instead of workarounding<br /> > bluez bugs, just to use working one stable SBC codec like before OR<br /> > update bluez to new version and have new features.<br /> ><br /> > On Monday 07 October 2019 16:18:21 Hyperion wrote:<br /> >>  I disagree with "Also there would not be any feature/functional changes in pulseaudio when older bluez version is in use".<br /> >>  Tests prove that there's no reason for this, if only one mode/profile is used.<br /> >><br /> >>  JP<br /> >><br /> >>  07.10.2019, 15:36, "Pali Rohár" <<a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a>>:<br /> >>  > I will try to look what is the problem without --experimental. This<br /> >>  > should work correctly prior merging this PR.<br /> >>  ><br /> >>  > Need to --experimental is just temporary until support in bluez is not<br /> >>  > fully stable. I guess it would be non-experimental in next bluez<br /> >>  > version.<br /> >>  ><br /> >>  > Also there would not be any feature/functional changes in pulseaudio<br /> >>  > when older bluez version is in use. So also no change in automatic mode<br /> >>  > for older bluez versions.<br /> >>  ><br /> >>  > On Monday 07 October 2019 15:30:49 Hyperion wrote:<br /> >>  >>  Without the --experimental flag : negociation stops (see hcidump below) and device falls back to "Off" status.<br /> >>  >><br /> >>  >>  btw : if you implement my (simple) negociation algorithm for the "Automatic Quality" mode ; AND make it to work without --experimental Bluez flag : it woiuld be close to perfect.<br /> >>  >><br /> >>  >>  See my latest patch <a href="https://gitlab.freedesktop.org/Hyperion/pulseaudio/tree/SBC-XQ">https://gitlab.freedesktop.org/Hyperion/pulseaudio/tree/SBC-XQ</a><br /> >>  >><br /> >>  >>  jp<br /> >>  >><br /> >>  >>  07.10.2019, 15:25, "Pali Rohár" <<a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a>>:<br /> >>  >>  > And what happened without --experimental?<br /> >>  >>  ><br /> >>  >>  > Aim is to support all bluez versions also with and without<br /> >>  >>  > --experimental flag. Just for older versions (or without experimental)<br /> >>  >>  > it should behave like before this patch series -- only SBC codec in<br /> >>  >>  > automatic mode and no codec switching.<br /> >>  >>  ><br /> >>  >>  > On Monday 07 October 2019 15:20:35 Hyperion wrote:<br /> >>  >>  >>  Thanks, I forgot the "--experimental" param.<br /> >>  >>  >><br /> >>  >>  >>  Works as expected, like the previous v12 serie of patches<br /> >>  >>  >><br /> >>  >>  >>  JP<br /> >>  >>  >><br /> >>  >>  >>  07.10.2019, 15:15, "Pali Rohár" <<a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a>>:<br /> >>  >>  >>  > Can you check if you have Bluez 5.51 and bluetoothd daemon is running with --experimental param?<br /> >>  >>  >>  ><br /> >>  >>  >>  > And is not it possible to change profile from Off to Automatic Quality?<br /> >>  >>  >>  ><br /> >>  >>  >>  > On Monday 07 October 2019 15:08:59 Hyperion wrote:<br /> >>  >>  >>  >>  The 10 patches compile OK on PA master without warnings.<br /> >>  >>  >>  >><br /> >>  >>  >>  >>  But doesn't work (device is Off with "Automatic Quality unavailable" status).<br /> >>  >>  >>  >><br /> >>  >>  >>  >>  Tested on 2 devices.<br /> >>  >>  >>  >><br /> >>  >>  >>  >>  hcidump avdtp<br /> >>  >>  >>  >>  HCI sniffer - Bluetooth packet analyzer ver 5.51<br /> >>  >>  >>  >>  device: hci0 snap_len: 1500 filter: 0x400<br /> >>  >>  >>  >>  < AVDTP(s): Discover cmd: transaction 9 nsp 0x00<br /> >>  >>  >>  >>  > AVDTP(s): Discover rsp: transaction 9 nsp 0x00<br /> >>  >>  >>  >>      ACP SEID 1 - Audio Sink<br /> >>  >>  >>  >>      ACP SEID 2 - Audio Sink<br /> >>  >>  >>  >>      ACP SEID 3 - Audio Sink<br /> >>  >>  >>  >>  < AVDTP(s): Set config cmd: transaction 10 nsp 0x00<br /> >>  >>  >>  >>      ACP SEID 1 - INT SEID 2<br /> >>  >>  >>  >>      Media Transport<br /> >>  >>  >>  >>      Media Codec - SBC<br /> >>  >>  >>  >>        44.1kHz<br /> >>  >>  >>  >>        DualChannel<br /> >>  >>  >>  >>        16 Blocks<br /> >>  >>  >>  >>        8 Subbands<br /> >>  >>  >>  >>        Loudness<br /> >>  >>  >>  >>        Bitpool Range 38-38<br /> >>  >>  >>  >>  > AVDTP(s): Set config rsp: transaction 10 nsp 0x00<br /> >>  >>  >>  >>  < AVDTP(s): Open cmd: transaction 11 nsp 0x00<br /> >>  >>  >>  >>      ACP SEID 1<br /> >>  >>  >>  >>  > AVDTP(s): Open rsp: transaction 11 nsp 0x00<br /> >>  >>  >>  >><br /> >>  >>  >>  >>  06.10.2019, 19:59, "Pali Rohár" <<a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a>>:<br /> >>  >>  >>  >>  > Previously module-bluetooth-policy was switching from A2DP to HSP profile<br /> >>  >>  >>  >>  > when VOIP application started recording of source. Now it switch to profile<br /> >>  >>  >>  >>  > with the highest priority which has both sink and source. In most cases it<br /> >>  >>  >>  >>  > is HSP profile, but it can be also bi-directional A2DP profile (e.g.<br /> >>  >>  >>  >>  > FastStream codec) as it has better audio quality.<br /> >>  >>  >>  >>  > ---<br /> >>  >>  >>  >>  >  src/modules/bluetooth/module-bluetooth-policy.c | 123 ++++++++++++------------<br /> >>  >>  >>  >>  >  1 file changed, 62 insertions(+), 61 deletions(-)<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c<br /> >>  >>  >>  >>  > index 04313aa84..9652a91fe 100644<br /> >>  >>  >>  >>  > --- a/src/modules/bluetooth/module-bluetooth-policy.c<br /> >>  >>  >>  >>  > +++ b/src/modules/bluetooth/module-bluetooth-policy.c<br /> >>  >>  >>  >>  > @@ -59,7 +59,12 @@ struct userdata {<!-- --><br /> >>  >>  >>  >>  >      pa_hook_slot *card_init_profile_slot;<br /> >>  >>  >>  >>  >      pa_hook_slot *card_unlink_slot;<br /> >>  >>  >>  >>  >      pa_hook_slot *profile_available_changed_slot;<br /> >>  >>  >>  >>  > - pa_hashmap *will_need_revert_card_map;<br /> >>  >>  >>  >>  > + pa_hashmap *profile_switch_map;<br /> >>  >>  >>  >>  > +};<br /> >>  >>  >>  >>  > +<br /> >>  >>  >>  >>  > +struct profile_switch {<!-- --><br /> >>  >>  >>  >>  > + const char *from_profile;<br /> >>  >>  >>  >>  > + const char *to_profile;<br /> >>  >>  >>  >>  >  };<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  >  /* When a source is created, loopback it to default sink */<br /> >>  >>  >>  >>  > @@ -142,43 +147,57 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void *<br /> >>  >>  >>  >>  >      return PA_HOOK_OK;<br /> >>  >>  >>  >>  >  }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > -static void card_set_profile(struct userdata *u, pa_card *card, bool revert_to_a2dp)<br /> >>  >>  >>  >>  > -{<!-- --><br /> >>  >>  >>  >>  > +static void card_set_profile(struct userdata *u, pa_card *card, const char *revert_to_profile_name) {<!-- --><br /> >>  >>  >>  >>  > + pa_card_profile *iter_profile;<br /> >>  >>  >>  >>  >      pa_card_profile *profile;<br /> >>  >>  >>  >>  > + struct profile_switch *ps;<br /> >>  >>  >>  >>  > + char *old_profile_name;<br /> >>  >>  >>  >>  >      void *state;<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - /* Find available profile and activate it */<br /> >>  >>  >>  >>  > - PA_HASHMAP_FOREACH(profile, card->profiles, state) {<!-- --><br /> >>  >>  >>  >>  > - if (profile->available == PA_AVAILABLE_NO)<br /> >>  >>  >>  >>  > - continue;<br /> >>  >>  >>  >>  > -<br /> >>  >>  >>  >>  > - /* Check for correct profile based on revert_to_a2dp */<br /> >>  >>  >>  >>  > - if (revert_to_a2dp) {<!-- --><br /> >>  >>  >>  >>  > - if (!pa_startswith(profile->name, "a2dp_sink"))<br /> >>  >>  >>  >>  > + if (revert_to_profile_name) {<!-- --><br /> >>  >>  >>  >>  > + profile = pa_hashmap_get(card->profiles, revert_to_profile_name);<br /> >>  >>  >>  >>  > + } else {<!-- --><br /> >>  >>  >>  >>  > + /* Find highest priority profile with both sink and source */<br /> >>  >>  >>  >>  > + profile = NULL;<br /> >>  >>  >>  >>  > + PA_HASHMAP_FOREACH(iter_profile, card->profiles, state) {<!-- --><br /> >>  >>  >>  >>  > + if (iter_profile->available == PA_AVAILABLE_NO)<br /> >>  >>  >>  >>  >                  continue;<br /> >>  >>  >>  >>  > - } else {<!-- --><br /> >>  >>  >>  >>  > - if (!pa_streq(profile->name, "headset_head_unit"))<br /> >>  >>  >>  >>  > + if (iter_profile->n_sources == 0 || iter_profile->n_sinks == 0)<br /> >>  >>  >>  >>  >                  continue;<br /> >>  >>  >>  >>  > + if (!profile || profile->priority < iter_profile->priority)<br /> >>  >>  >>  >>  > + profile = iter_profile;<br /> >>  >>  >>  >>  >          }<br /> >>  >>  >>  >>  > + }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - pa_log_debug("Setting card '%s' to profile '%s'", card->name, profile->name);<br /> >>  >>  >>  >>  > + if (!profile) {<!-- --><br /> >>  >>  >>  >>  > + pa_log_warn("Could not find any suitable profile for card '%s'", card->name);<br /> >>  >>  >>  >>  > + return;<br /> >>  >>  >>  >>  > + }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - if (pa_card_set_profile(card, profile, false) != 0) {<!-- --><br /> >>  >>  >>  >>  > - pa_log_warn("Could not set profile '%s'", profile->name);<br /> >>  >>  >>  >>  > - continue;<br /> >>  >>  >>  >>  > - }<br /> >>  >>  >>  >>  > + old_profile_name = card->active_profile->name;<br /> >>  >>  >>  >>  > +<br /> >>  >>  >>  >>  > + pa_log_debug("Setting card '%s' from profile '%s' to profile '%s'", card->name, old_profile_name, profile->name);<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - /* When we are not in revert_to_a2dp phase flag this card for will_need_revert */<br /> >>  >>  >>  >>  > - if (!revert_to_a2dp)<br /> >>  >>  >>  >>  > - pa_hashmap_put(u->will_need_revert_card_map, card, PA_INT_TO_PTR(1));<br /> >>  >>  >>  >>  > + if (pa_card_set_profile(card, profile, false) != 0) {<!-- --><br /> >>  >>  >>  >>  > + pa_log_warn("Could not set profile '%s'", profile->name);<br /> >>  >>  >>  >>  > + return;<br /> >>  >>  >>  >>  > + }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - break;<br /> >>  >>  >>  >>  > + /* When not reverting, store data for future reverting */<br /> >>  >>  >>  >>  > + if (!revert_to_profile_name) {<!-- --><br /> >>  >>  >>  >>  > + ps = pa_xnew0(struct profile_switch, 1);<br /> >>  >>  >>  >>  > + ps->from_profile = old_profile_name;<br /> >>  >>  >>  >>  > + ps->to_profile = profile->name;<br /> >>  >>  >>  >>  > + pa_hashmap_put(u->profile_switch_map, card, ps);<br /> >>  >>  >>  >>  >      }<br /> >>  >>  >>  >>  >  }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  >  /* Switch profile for one card */<br /> >>  >>  >>  >>  > -static void switch_profile(pa_card *card, bool revert_to_a2dp, void *userdata) {<!-- --><br /> >>  >>  >>  >>  > +static void switch_profile(pa_card *card, bool revert, void *userdata) {<!-- --><br /> >>  >>  >>  >>  >      struct userdata *u = userdata;<br /> >>  >>  >>  >>  > + struct profile_switch *ps;<br /> >>  >>  >>  >>  > + const char *from_profile;<br /> >>  >>  >>  >>  > + const char *to_profile;<br /> >>  >>  >>  >>  >      const char *s;<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  >      /* Only consider bluetooth cards */<br /> >>  >>  >>  >>  > @@ -186,29 +205,25 @@ static void switch_profile(pa_card *card, bool revert_to_a2dp, void *userdata) {<!-- --><br /> >>  >>  >>  >>  >      if (!s || !pa_streq(s, "bluetooth"))<br /> >>  >>  >>  >>  >          return;<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - if (revert_to_a2dp) {<!-- --><br /> >>  >>  >>  >>  > - /* In revert_to_a2dp phase only consider cards with will_need_revert flag and remove it */<br /> >>  >>  >>  >>  > - if (!pa_hashmap_remove(u->will_need_revert_card_map, card))<br /> >>  >>  >>  >>  > + if (revert) {<!-- --><br /> >>  >>  >>  >>  > + /* In revert phase only consider cards which switched profile */<br /> >>  >>  >>  >>  > + if (!(ps = pa_hashmap_remove(u->profile_switch_map, card)))<br /> >>  >>  >>  >>  >              return;<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - /* Skip card if does not have active hsp profile */<br /> >>  >>  >>  >>  > - if (!pa_streq(card->active_profile->name, "headset_head_unit"))<br /> >>  >>  >>  >>  > - return;<br /> >>  >>  >>  >>  > + from_profile = ps->from_profile;<br /> >>  >>  >>  >>  > + to_profile = ps->to_profile;<br /> >>  >>  >>  >>  > + pa_xfree(ps);<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - /* Skip card if already has active a2dp profile */<br /> >>  >>  >>  >>  > - if (pa_startswith(card->active_profile->name, "a2dp_sink"))<br /> >>  >>  >>  >>  > + /* Skip card if does not have active profile to which was switched */<br /> >>  >>  >>  >>  > + if (!pa_streq(card->active_profile->name, to_profile))<br /> >>  >>  >>  >>  >              return;<br /> >>  >>  >>  >>  >      } else {<!-- --><br /> >>  >>  >>  >>  > - /* Skip card if does not have active a2dp profile */<br /> >>  >>  >>  >>  > - if (!pa_startswith(card->active_profile->name, "a2dp_sink"))<br /> >>  >>  >>  >>  > - return;<br /> >>  >>  >>  >>  > -<br /> >>  >>  >>  >>  > - /* Skip card if already has active hsp profile */<br /> >>  >>  >>  >>  > - if (pa_streq(card->active_profile->name, "headset_head_unit"))<br /> >>  >>  >>  >>  > + /* Skip card if already has both sink and source */<br /> >>  >>  >>  >>  > + if (card->active_profile->n_sources > 0 && card->active_profile->n_sinks > 0)<br /> >>  >>  >>  >>  >              return;<br /> >>  >>  >>  >>  >      }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - card_set_profile(u, card, revert_to_a2dp);<br /> >>  >>  >>  >>  > + card_set_profile(u, card, revert ? from_profile : NULL);<br /> >>  >>  >>  >>  >  }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  >  /* Return true if we should ignore this source output */<br /> >>  >>  >>  >>  > @@ -254,15 +269,15 @@ static unsigned source_output_count(pa_core *c, void *userdata) {<!-- --><br /> >>  >>  >>  >>  >  }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  >  /* Switch profile for all cards */<br /> >>  >>  >>  >>  > -static void switch_profile_all(pa_idxset *cards, bool revert_to_a2dp, void *userdata) {<!-- --><br /> >>  >>  >>  >>  > +static void switch_profile_all(pa_idxset *cards, bool revert, void *userdata) {<!-- --><br /> >>  >>  >>  >>  >      pa_card *card;<br /> >>  >>  >>  >>  >      uint32_t idx;<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  >      PA_IDXSET_FOREACH(card, cards, idx)<br /> >>  >>  >>  >>  > - switch_profile(card, revert_to_a2dp, userdata);<br /> >>  >>  >>  >>  > + switch_profile(card, revert, userdata);<br /> >>  >>  >>  >>  >  }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > -/* When a source output is created, switch profile a2dp to profile hsp */<br /> >>  >>  >>  >>  > +/* When a source output is created, switch profile to some which has both sink and source */<br /> >>  >>  >>  >>  >  static pa_hook_result_t source_output_put_hook_callback(pa_core *c, pa_source_output *source_output, void *userdata) {<!-- --><br /> >>  >>  >>  >>  >      pa_assert(c);<br /> >>  >>  >>  >>  >      pa_assert(source_output);<br /> >>  >>  >>  >>  > @@ -274,7 +289,7 @@ static pa_hook_result_t source_output_put_hook_callback(pa_core *c, pa_source_ou<br /> >>  >>  >>  >>  >      return PA_HOOK_OK;<br /> >>  >>  >>  >>  >  }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > -/* When all source outputs are unlinked, switch profile hsp back back to profile a2dp */<br /> >>  >>  >>  >>  > +/* When all source outputs are unlinked, switch to previous profile */<br /> >>  >>  >>  >>  >  static pa_hook_result_t source_output_unlink_hook_callback(pa_core *c, pa_source_output *source_output, void *userdata) {<!-- --><br /> >>  >>  >>  >>  >      pa_assert(c);<br /> >>  >>  >>  >>  >      pa_assert(source_output);<br /> >>  >>  >>  >>  > @@ -291,30 +306,16 @@ static pa_hook_result_t source_output_unlink_hook_callback(pa_core *c, pa_source<br /> >>  >>  >>  >>  >  }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  >  static pa_hook_result_t card_init_profile_hook_callback(pa_core *c, pa_card *card, void *userdata) {<!-- --><br /> >>  >>  >>  >>  > - struct userdata *u = userdata;<br /> >>  >>  >>  >>  > - const char *s;<br /> >>  >>  >>  >>  > -<br /> >>  >>  >>  >>  >      pa_assert(c);<br /> >>  >>  >>  >>  >      pa_assert(card);<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > + /* If there are not some source outputs do nothing */<br /> >>  >>  >>  >>  >      if (source_output_count(c, userdata) == 0)<br /> >>  >>  >>  >>  >          return PA_HOOK_OK;<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - /* Only consider bluetooth cards */<br /> >>  >>  >>  >>  > - s = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_BUS);<br /> >>  >>  >>  >>  > - if (!s || !pa_streq(s, "bluetooth"))<br /> >>  >>  >>  >>  > - return PA_HOOK_OK;<br /> >>  >>  >>  >>  > -<br /> >>  >>  >>  >>  > - /* Ignore card if has already set other initial profile than a2dp */<br /> >>  >>  >>  >>  > - if (card->active_profile &&<br /> >>  >>  >>  >>  > - !pa_startswith(card->active_profile->name, "a2dp_sink"))<br /> >>  >>  >>  >>  > - return PA_HOOK_OK;<br /> >>  >>  >>  >>  > -<br /> >>  >>  >>  >>  > - /* Set initial profile to hsp */<br /> >>  >>  >>  >>  > - card_set_profile(u, card, false);<br /> >>  >>  >>  >>  > + /* Set initial profile to some with source */<br /> >>  >>  >>  >>  > + switch_profile(card, false, userdata);<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - /* Flag this card for will_need_revert */<br /> >>  >>  >>  >>  > - pa_hashmap_put(u->will_need_revert_card_map, card, PA_INT_TO_PTR(1));<br /> >>  >>  >>  >>  >      return PA_HOOK_OK;<br /> >>  >>  >>  >>  >  }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > @@ -447,7 +448,7 @@ int pa__init(pa_module *m) {<!-- --><br /> >>  >>  >>  >>  >          goto fail;<br /> >>  >>  >>  >>  >      }<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - u->will_need_revert_card_map = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);<br /> >>  >>  >>  >>  > + u->profile_switch_map = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  >      u->source_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL,<br /> >>  >>  >>  >>  >                                           (pa_hook_cb_t) source_put_hook_callback, u);<br /> >>  >>  >>  >>  > @@ -512,7 +513,7 @@ void pa__done(pa_module *m) {<!-- --><br /> >>  >>  >>  >>  >      if (u->profile_available_changed_slot)<br /> >>  >>  >>  >>  >          pa_hook_slot_free(u->profile_available_changed_slot);<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > - pa_hashmap_free(u->will_need_revert_card_map);<br /> >>  >>  >>  >>  > + pa_hashmap_free(u->profile_switch_map);<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  >      pa_xfree(u);<br /> >>  >>  >>  >>  >  }<br /> >>  >>  >>  >>  > --<br /> >>  >>  >>  >>  > 2.11.0<br /> >>  >>  >>  >>  ><br /> >>  >>  >>  >>  > _______________________________________________<br /> >>  >>  >>  >>  > pulseaudio-discuss mailing list<br /> >>  >>  >>  >>  > <a href="mailto:pulseaudio-discuss@lists.freedesktop.org">pulseaudio-discuss@lists.freedesktop.org</a><br /> >>  >>  >>  >>  > <a href="https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss">https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss</a><br /> >>  >>  >>  >>  _______________________________________________<br /> >>  >>  >>  >>  pulseaudio-discuss mailing list<br /> >>  >>  >>  >>  <a href="mailto:pulseaudio-discuss@lists.freedesktop.org">pulseaudio-discuss@lists.freedesktop.org</a><br /> >>  >>  >>  >>  <a href="https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss">https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss</a><br /> >>  >>  >>  ><br /> >>  >>  >>  > --<br /> >>  >>  >>  > Pali Rohár<br /> >>  >>  >>  > <a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a><br /> >>  >>  ><br /> >>  >>  > --<br /> >>  >>  > Pali Rohár<br /> >>  >>  > <a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a><br /> >>  ><br /> >>  > --<br /> >>  > Pali Rohár<br /> >>  > <a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a><br /> ><br /> > --<br /> > Pali Rohár<br /> > <a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a><br /></blockquote><p> </p>--<br />Pali Rohár<br /><a href="mailto:pali.rohar@gmail.com">pali.rohar@gmail.com</a></blockquote><br /><br />--<br />Sent from Yandex.Mail for mobile</blockquote></div>