Sound output issues when switching from A2DP to handsfree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi guys,

When switching from A2DP to handsfree, it will automatically switch to other ports 
and output audio for a short time, and then immediately switch to the handsfree output port.

How can we fix this issue? Thanks a lot.

In the following set_profile_cb function, this issue occurs after the stop_thread function calls 
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s) in pa_sink_unlink.
------------------------
static int set_profile_cb(pa_card *c, pa_card_profile *new_profile) {
    struct userdata *u;
    pa_bluetooth_profile_t *p;

    pa_assert(c);
    pa_assert(new_profile);
    pa_assert_se(u = c->userdata);

    p = PA_CARD_PROFILE_DATA(new_profile);

    if (*p != PA_BLUETOOTH_PROFILE_OFF) {
        const pa_bluetooth_device *d = u->device;

        if (!d->transports[*p] || d->transports[*p]->state <= PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED) {
            pa_log_warn("Refused to switch profile to %s: Not connected", new_profile->name);
            return -PA_ERR_IO;
        }
    }

    stop_thread(u);

    u->profile = "">

    if (u->profile != PA_BLUETOOTH_PROFILE_OFF)
        if (init_profile(u) < 0)
            goto off;

    if (u->sink || u->source)
        if (start_thread(u) < 0)
            goto off;

    return 0;

off:
    stop_thread(u);

    pa_assert_se(pa_card_set_profile(u->card, pa_hashmap_get(u->card->profiles, "off"), false) >= 0);

    return -PA_ERR_IO;
}

static void stop_thread(struct userdata *u) {
    pa_assert(u);

    if (u->sink || u->source)
        pa_proplist_unset(u->card->proplist, PA_PROP_BLUETOOTH_CODEC);

    if (u->sink)
        pa_sink_unlink(u->sink);

    /* Omitted */

}

void pa_sink_unlink(pa_sink* s) {
    bool linked;
    pa_sink_input *i, PA_UNUSED *j = NULL;

    pa_sink_assert_ref(s);
    pa_assert_ctl_context();

    /* Please note that pa_sink_unlink() does more than simply
     * reversing pa_sink_put(). It also undoes the registrations
     * already done in pa_sink_new()! */

    if (s->unlink_requested)
        return;

    s->unlink_requested = true;

    linked = PA_SINK_IS_LINKED(s->state);

    if (linked)
        pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);

    /* Omitted */
}
------------------

Thanks,
Chengyi

[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux