Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7a133b2 authored by Mattias Agren's avatar Mattias Agren Committed by Android Git Automerger
Browse files

am a0d63a9c: Stability fixes for a2dp hal control path

* commit 'a0d63a9c':
  Stability fixes for a2dp hal control path
parents e23c1dbf a0d63a9c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -237,6 +237,7 @@ void btif_a2dp_setup_codec(void);
void btif_a2dp_on_idle(void);
void btif_a2dp_on_open(void);
void btif_a2dp_on_started(tBTA_AV_START *p_av);
void btif_a2dp_ack_fail(void);
void btif_a2dp_on_stop_req(void);
void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av);
void btif_a2dp_on_suspend(void);
+43 −9
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ typedef enum {

#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
#define BTIF_AV_FLAG_REMOTE_SUSPEND        0x2
#define BTIF_AV_FLAG_PENDING_START         0x4
#define BTIF_AV_FLAG_PENDING_STOP          0x8

/*****************************************************************************
**  Local type definitions
@@ -401,6 +403,7 @@ static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data
            /* wait for audioflinger to stop a2dp */
            break;

        case BTA_AV_STOP_EVT:
        case BTIF_AV_STOP_STREAM_REQ_EVT:
              /* immediately flush any pending tx frames while suspend is pending */
              btif_a2dp_set_tx_flush(TRUE);
@@ -462,15 +465,19 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
    switch (event)
    {
        case BTIF_SM_ENTER_EVT:
            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
            btif_media_check_iop_exceptions(btif_av_cb.peer_bda.address);
             break;

        case BTIF_SM_EXIT_EVT:
            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
            break;

        case BTIF_AV_START_STREAM_REQ_EVT:
            btif_a2dp_setup_codec();
            BTA_AvStart();
            btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
            break;

        case BTA_AV_START_EVT:
@@ -478,6 +485,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
            BTIF_TRACE_EVENT3("BTA_AV_START_EVT status %d, suspending %d, init %d",
                p_av->start.status, p_av->start.suspending, p_av->start.initiator);

            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
            if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
                return TRUE;

@@ -502,6 +510,9 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)

        case BTA_AV_CLOSE_EVT:

            /* avdtp link is closed */
            btif_a2dp_on_stopped(NULL);

            /* inform the application that we are disconnected */
            HAL_CBACK(bt_av_callbacks, connection_state_cb,
                BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
@@ -509,6 +520,20 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
            break;

        case BTA_AV_RECONFIG_EVT:
            if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
                (p_av->reconfig.status == BTA_AV_SUCCESS))
            {
               APPL_TRACE_WARNING0("reconfig done BTA_AVstart()");
               BTA_AvStart();
            }
            else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
            {
               btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
               btif_a2dp_ack_fail();
            }
            break;

        CHECK_RC_EVENT(event, p_data);

        default:
@@ -551,6 +576,11 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data
        case BTIF_SM_EXIT_EVT:
            break;

        case BTIF_AV_START_STREAM_REQ_EVT:
            /* we were remotely started, just ack back the local request */
            btif_a2dp_on_started(NULL);
            break;

        /* fixme -- use suspend = true always to work around issue with BTA AV */
        case BTIF_AV_STOP_STREAM_REQ_EVT:
        case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
@@ -627,6 +657,8 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data

        case BTA_AV_STOP_EVT:

            btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;

            btif_a2dp_on_stopped(&p_av->suspend);

            HAL_CBACK(bt_av_callbacks, audio_state_cb,
@@ -640,6 +672,8 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data

        case BTA_AV_CLOSE_EVT:

             btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;

            /* avdtp link is closed */

            btif_a2dp_on_stopped(NULL);
@@ -854,8 +888,8 @@ BOOLEAN btif_av_stream_ready(void)
        return FALSE;
    }

    /* check if we are remotely suspended */
    if (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND)
    /* check if we are remotely suspended or stop is pending */
    if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
        return FALSE;

    return (state == BTIF_AV_STATE_OPENED);
@@ -878,9 +912,9 @@ BOOLEAN btif_av_stream_started_ready(void)
    BTIF_TRACE_DEBUG3("btif_av_stream_started : sm hdl %d, state %d, flags %x",
                btif_av_cb.sm_handle, state, btif_av_cb.flags);

    /* don't allow media task to start if we are suspending or
       remotely suspended (not yet changed state) */
    if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND))
    /* disallow media task to start if we have pending actions */
    if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
        | BTIF_AV_FLAG_PENDING_STOP))
        return FALSE;

    return (state == BTIF_AV_STATE_STARTED);
@@ -958,11 +992,11 @@ const btav_interface_t *btif_av_get_interface(void)

/*******************************************************************************
**
** Function         btif_av_is_rc_open_without_a2dp
** Function         btif_av_is_connected
**
** Description      Checks if GAVDTP Open notification to app is pending (2 second timer)
** Description      Checks if av has a connected sink
**
** Returns          boolean
** Returns          BOOLEAN
**
*******************************************************************************/
BOOLEAN btif_av_is_connected(void)
+75 −44
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <pthread.h>
#include <stdint.h>
#include <sys/time.h>
#include <errno.h>

#include "bt_target.h"
#include "gki.h"
@@ -51,11 +52,9 @@
#include "bta_av_ci.h"
#include "l2c_api.h"


#include "btif_av_co.h"
#include "btif_media.h"


#if (BTA_AV_INCLUDED == TRUE)
#include "sbc_encoder.h"
#endif
@@ -166,7 +165,7 @@ static UINT32 a2dp_media_task_stack[(A2DP_MEDIA_TASK_STACK_SIZE + 3) / 4];
#define BT_MEDIA_TASK A2DP_MEDIA_TASK

#define USEC_PER_SEC 1000000L
#define TPUT_STATS_INTERVAL_US (1000*1000)
#define TPUT_STATS_INTERVAL_US (3000*1000)

/*
 * CONGESTION COMPENSATION CTRL ::
@@ -234,11 +233,11 @@ typedef struct
} tBTIF_MEDIA_CB;

typedef struct {
    int rx;
    int rx_tot;
    int tx;
    int tx_tot;
    int ts_prev_us;
    long long rx;
    long long rx_tot;
    long long tx;
    long long tx_tot;
    long long ts_prev_us;
} t_stat;

/*****************************************************************************
@@ -256,6 +255,7 @@ static int media_task_running = MEDIA_TASK_STATE_OFF;
static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
static void btif_a2dp_encoder_update(void);
const char* dump_media_event(UINT16 event);

/*****************************************************************************
 **  Externs
@@ -286,8 +286,8 @@ static void tput_mon(int is_rx, int len, int reset)
    /* only monitor one connection at a time for now */
    static t_stat cur_stat;
    struct timespec now;
    unsigned int prev_us;
    unsigned int now_us;
    unsigned long long prev_us;
    unsigned long long now_us;

    if (reset == TRUE)
    {
@@ -309,14 +309,12 @@ static void tput_mon(int is_rx, int len, int reset)

    now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;

    //APPL_TRACE_DEBUG1("%d us", now_us - cur_stat.ts_prev_us);

    if ((now_us - cur_stat.ts_prev_us) < TPUT_STATS_INTERVAL_US)
        return;

    APPL_TRACE_WARNING4("tput rx:%d, tx:%d (kB/s)  (tot : rx %d, tx %d bytes)",
          (cur_stat.rx)/((now_us - cur_stat.ts_prev_us)/1000),
          (cur_stat.tx)/((now_us - cur_stat.ts_prev_us)/1000),
    APPL_TRACE_WARNING4("tput rx:%d, tx:%d (bytes/s)  (tot : rx %d, tx %d bytes)",
          (cur_stat.rx*1000000)/((now_us - cur_stat.ts_prev_us)),
          (cur_stat.tx*1000000)/((now_us - cur_stat.ts_prev_us)),
           cur_stat.rx_tot, cur_stat.tx_tot);

    /* stats dumped. now reset stats for next interval */
@@ -401,7 +399,8 @@ static void a2dp_cmd_acknowledge(int status)
{
    UINT8 ack = status;

    APPL_TRACE_EVENT2("## a2dp ack : %s, status %d ##", dump_a2dp_ctrl_event(btif_media_cb.a2dp_cmd_pending), status);
    APPL_TRACE_EVENT2("## a2dp ack : %s, status %d ##",
          dump_a2dp_ctrl_event(btif_media_cb.a2dp_cmd_pending), status);

    /* sanity check */
    if (btif_media_cb.a2dp_cmd_pending == A2DP_CTRL_CMD_NONE)
@@ -838,11 +837,17 @@ void btif_a2dp_on_open(void)

void btif_a2dp_on_started(tBTA_AV_START *p_av)
{
    tBTIF_AV_MEDIA_FEEDINGS media_feeding;
    tBTIF_STATUS status;

    APPL_TRACE_EVENT0("## ON A2DP STARTED ##");

    if (p_av == NULL)
    {
        /* ack back a local start request */
        a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
        return;
    }

    if (p_av->status == BTA_AV_SUCCESS)
    {
        if (p_av->suspending == FALSE)
@@ -868,6 +873,24 @@ void btif_a2dp_on_started(tBTA_AV_START *p_av)
}


/*****************************************************************************
**
** Function        btif_a2dp_ack_fail
**
** Description
**
** Returns
**
*******************************************************************************/

void btif_a2dp_ack_fail(void)
{
    tBTIF_STATUS status;

    APPL_TRACE_EVENT0("## A2DP_CTRL_ACK_FAILURE ##");
    a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
}

/*****************************************************************************
**
** Function        btif_a2dp_on_stopped
@@ -1182,7 +1205,8 @@ static void btif_media_flush_q(BUFFER_Q *p_q)
 *******************************************************************************/
static void btif_media_task_handle_cmd(BT_HDR *p_msg)
{
    VERBOSE("btif_media_task_handle_cmd : %d %s", p_msg->event, dump_media_event(p_msg->event));
    VERBOSE("btif_media_task_handle_cmd : %d %s", p_msg->event,
             dump_media_event(p_msg->event));

    switch (p_msg->event)
    {
@@ -1467,7 +1491,8 @@ static void btif_media_task_enc_update(BT_HDR *p_msg)
    /* Only update the bitrate and MTU size while timer is running to make sure it has been initialized */
    //if (btif_media_cb.is_tx_timer)
    {
        btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR))
        btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE -
                                      BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR))
                < pUpdateAudio->MinMtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
                - sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize;

@@ -1533,11 +1558,13 @@ static void btif_media_task_enc_update(BT_HDR *p_msg)
                s16BitPool = 0;
            }

            APPL_TRACE_EVENT2("bitpool candidate : %d (%d kbps)", s16BitPool, pstrEncParams->u16BitRate);
            APPL_TRACE_EVENT2("bitpool candidate : %d (%d kbps)",
                         s16BitPool, pstrEncParams->u16BitRate);

            if (s16BitPool > pUpdateAudio->MaxBitPool)
            {
                APPL_TRACE_WARNING1("btif_media_task_enc_update computed bitpool too large (%d)", s16BitPool);
                APPL_TRACE_DEBUG1("btif_media_task_enc_update computed bitpool too large (%d)",
                                    s16BitPool);
                /* Decrease bitrate */
                btif_media_cb.encoder.u16BitRate -= BTIF_MEDIA_BITRATE_STEP;
                /* Record that we have decreased the bitrate */
@@ -1592,7 +1619,6 @@ static void btif_media_task_pcm2sbc_init(tBTIF_MEDIA_INIT_AUDIO_FEEDING * p_feed
    APPL_TRACE_DEBUG1("num_channel:%d", p_feeding->feeding.cfg.pcm.num_channel);
    APPL_TRACE_DEBUG1("bit_per_sample:%d", p_feeding->feeding.cfg.pcm.bit_per_sample);


    /* Check the PCM feeding sampling_freq */
    switch (p_feeding->feeding.cfg.pcm.sampling_freq)
    {
@@ -1639,11 +1665,13 @@ static void btif_media_task_pcm2sbc_init(tBTIF_MEDIA_INIT_AUDIO_FEEDING * p_feed

    if (reconfig_needed != FALSE)
    {
        APPL_TRACE_DEBUG0("btif_media_task_pcm2sbc_init calls SBC_Encoder_Init");
        APPL_TRACE_DEBUG1("btif_media_task_pcm2sbc_init mtu %d", btif_media_cb.TxAaMtuSize);
        APPL_TRACE_DEBUG6("btif_media_task_pcm2sbc_init ch mode %d, nbsubd %d, nb blk %d, alloc method %d, bit rate %d, Smp freq %d",
                btif_media_cb.encoder.s16ChannelMode, btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks,
                btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate, btif_media_cb.encoder.s16SamplingFreq);
        APPL_TRACE_DEBUG1("btif_media_task_pcm2sbc_init :: mtu %d", btif_media_cb.TxAaMtuSize);
        APPL_TRACE_DEBUG6("ch mode %d, nbsubd %d, nb %d, alloc %d, rate %d, freq %d",
                btif_media_cb.encoder.s16ChannelMode,
                btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks,
                btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
                btif_media_cb.encoder.s16SamplingFreq);

        SBC_Encoder_Init(&(btif_media_cb.encoder));
    }
    else
@@ -1742,7 +1770,6 @@ static void btif_media_task_aa_start_tx(void)
    APPL_TRACE_DEBUG2("btif_media_task_aa_start_tx is timer %d, feeding mode %d",
             btif_media_cb.is_tx_timer, btif_media_cb.feeding_mode);


    /* Use a timer to poll the UIPC, get rid of the UIPC call back */
    // UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_CBACK, NULL);

@@ -1751,7 +1778,9 @@ static void btif_media_task_aa_start_tx(void)
    /* Reset the media feeding state */
    btif_media_task_feeding_state_reset();

    APPL_TRACE_EVENT2("starting timer %d ticks (%d)", GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TICKS_PER_SEC);
    APPL_TRACE_EVENT2("starting timer %d ticks (%d)",
                  GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TICKS_PER_SEC);

    GKI_start_timer(BTIF_MEDIA_AA_TASK_TIMER_ID, GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TRUE);
}

@@ -1790,8 +1819,6 @@ static void btif_media_task_aa_stop_tx(void)
 ** Returns          The number of media frames in this time slice
 **
 *******************************************************************************/


static UINT8 btif_get_num_aa_frame(void)
{
    UINT8 result=0;
@@ -1886,12 +1913,13 @@ BT_HDR *btif_media_aa_readbuf(void)
BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
{
    UINT16 event;
    /* coverity[SIGN_EXTENSION] False-positive: Parameter are always in range avoiding sign extension*/
    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * btif_media_cb.encoder.s16NumOfBlocks;
    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * \
                             btif_media_cb.encoder.s16NumOfBlocks;
    UINT32 read_size;
    UINT16 sbc_sampling = 48000;
    UINT32 src_samples;
    UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * sizeof(SINT16);
    UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * \
                          sizeof(SINT16);
    static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
            * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2];
    static UINT16 read_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
@@ -1992,7 +2020,7 @@ BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
            btif_media_cb.media_feeding.cfg.pcm.num_channel);

    /* re-sample read buffer */
    /* The output PCM buffer will be stereo, 16 bit per sec */
    /* The output PCM buffer will be stereo, 16 bit per sample */
    dst_size_used = bta_av_sbc_up_sample((UINT8 *)read_buffer,
            (UINT8 *)up_sampled_buffer + btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
            nb_byte_read,
@@ -2000,7 +2028,7 @@ BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
            &src_size_used);

#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
    APPL_TRACE_DEBUG3("btif_media_aa_read_feeding read_size:%d src_size_used:%d dst_size_used:%d",
    APPL_TRACE_DEBUG3("btif_media_aa_read_feeding readsz:%d src_size_used:%d dst_size_used:%d",
            read_size, src_size_used, dst_size_used);
#endif

@@ -2046,16 +2074,19 @@ BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)
{
    BT_HDR * p_buf;
    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * btif_media_cb.encoder.s16NumOfBlocks;
    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands *
                             btif_media_cb.encoder.s16NumOfBlocks;

#if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
    APPL_TRACE_DEBUG2("btif_media_aa_prep_sbc_2_send nb_frame %d, TxAaQ %d", nb_frame, btif_media_cb.TxAaQ.count);
    APPL_TRACE_DEBUG2("btif_media_aa_prep_sbc_2_send nb_frame %d, TxAaQ %d",
                       nb_frame, btif_media_cb.TxAaQ.count);
#endif
    while (nb_frame)
    {
        if (NULL == (p_buf = GKI_getpoolbuf(BTIF_MEDIA_AA_POOL_ID)))
        {
            APPL_TRACE_ERROR1 ("ERROR btif_media_aa_prep_sbc_2_send no buffer TxCnt %d ", btif_media_cb.TxAaQ.count);
            APPL_TRACE_ERROR1 ("ERROR btif_media_aa_prep_sbc_2_send no buffer TxCnt %d ",
                                btif_media_cb.TxAaQ.count);
            return;
        }

@@ -2069,7 +2100,6 @@ static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)
            /* Write @ of allocated buffer in encoder.pu8Packet */
            btif_media_cb.encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
            /* Fill allocated buffer with 0 */
            /* coverity[SIGN_EXTENSION] False-positive: Parameter are always in range avoiding sign extension*/
            memset(btif_media_cb.encoder.as16PcmBuffer, 0, blocm_x_subband
                    * btif_media_cb.encoder.s16NumOfChannels);

@@ -2100,11 +2130,12 @@ static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)

        if(p_buf->len)
        {
            btif_media_cb.timestamp += p_buf->layer_specific * blocm_x_subband;

            /* store the time stamp in the buffer to send */
            /* timestamp of the media packet header represent the TS of the first SBC frame
               i.e the timestamp before including this frame */
            *((UINT32 *) (p_buf + 1)) = btif_media_cb.timestamp;

            btif_media_cb.timestamp += p_buf->layer_specific * blocm_x_subband;

            VERBOSE("TX QUEUE NOW %d", btif_media_cb.TxAaQ.count);

            if (btif_media_cb.tx_flush)