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

Commit 044c9a16 authored by Zhihai Xu's avatar Zhihai Xu Committed by Android (Google) Code Review
Browse files

Merge "implement flow control to avoid dropping packets in btif_media_task."

parents 6deb58ae ed5b3b47
Loading
Loading
Loading
Loading
+64 −18
Original line number Diff line number Diff line
@@ -177,8 +177,11 @@ static UINT32 a2dp_media_task_stack[(A2DP_MEDIA_TASK_STACK_SIZE + 3) / 4];
   but due to link flow control or thread preemption in lower
   layers we might need to temporarily buffer up data */

/* 24 frames is equivalent to 6.89*24*2.9 ~= 480 ms @ 44.1 khz, 20 ms mediatick */
#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 24
/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 18
#define A2DP_PACKET_COUNT_LOW_WATERMARK 5
#define MAX_PCM_FRAME_NUM_PER_TICK     40
#define RESET_RATE_COUNTER_THRESHOLD_MS    2000

//#define BTIF_MEDIA_VERBOSE_ENABLED

@@ -201,6 +204,10 @@ typedef struct
    INT32  aa_feed_residue;
    UINT32 counter;
    UINT32 bytes_per_tick;  /* pcm bytes read each media task tick */
    UINT32 max_counter_exit;
    UINT32 max_counter_enter;
    UINT32 overflow_count;
    BOOLEAN overflow;
} tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE;


@@ -1775,6 +1782,11 @@ static void btif_media_task_uipc_cback(BT_HDR *p_msg)
 *******************************************************************************/
static void btif_media_task_feeding_state_reset(void)
{
    APPL_TRACE_WARNING3("overflow %d, enter %d, exit %d",
        btif_media_cb.media_feeding_state.pcm.overflow_count,
        btif_media_cb.media_feeding_state.pcm.max_counter_enter,
        btif_media_cb.media_feeding_state.pcm.max_counter_exit);

    /* By default, just clear the entire state */
    memset(&btif_media_cb.media_feeding_state, 0, sizeof(btif_media_cb.media_feeding_state));

@@ -1855,7 +1867,7 @@ static void btif_media_task_aa_stop_tx(void)
 *******************************************************************************/
static UINT8 btif_get_num_aa_frame(void)
{
    UINT8 result=0;
    UINT32 result=0;

    switch (btif_media_cb.TxTranscoding)
    {
@@ -1868,11 +1880,24 @@ static UINT8 btif_get_num_aa_frame(void)

            btif_media_cb.media_feeding_state.pcm.counter +=
                                btif_media_cb.media_feeding_state.pcm.bytes_per_tick;
            if ((!btif_media_cb.media_feeding_state.pcm.overflow) ||
                (btif_media_cb.TxAaQ.count < A2DP_PACKET_COUNT_LOW_WATERMARK)) {
                if (btif_media_cb.media_feeding_state.pcm.overflow) {
                    btif_media_cb.media_feeding_state.pcm.overflow = FALSE;

                    if (btif_media_cb.media_feeding_state.pcm.counter >
                        btif_media_cb.media_feeding_state.pcm.max_counter_exit) {
                        btif_media_cb.media_feeding_state.pcm.max_counter_exit =
                            btif_media_cb.media_feeding_state.pcm.counter;
                    }
                }
                /* calculate nbr of frames pending for this media tick */
                result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
                if (result > MAX_PCM_FRAME_NUM_PER_TICK) result = MAX_PCM_FRAME_NUM_PER_TICK;
                btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;

            } else {
                result = 0;
            }
            VERBOSE("WRITE %d FRAMES", result);
        }
        break;
@@ -1888,7 +1913,7 @@ static UINT8 btif_get_num_aa_frame(void)
    APPL_TRACE_DEBUG1("btif_get_num_aa_frame returns %d", result);
#endif

    return result;
    return (UINT8)result;
}

/*******************************************************************************
@@ -2185,6 +2210,32 @@ static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)
        {
            GKI_freebuf(p_buf);
        }

        if (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ) {
            UINT32 reset_rate_bytes = btif_media_cb.media_feeding_state.pcm.bytes_per_tick *
                                (RESET_RATE_COUNTER_THRESHOLD_MS / BTIF_MEDIA_TIME_TICK);
            btif_media_cb.media_feeding_state.pcm.overflow = TRUE;
            btif_media_cb.media_feeding_state.pcm.counter += nb_frame *
                     btif_media_cb.encoder.s16NumOfSubBands *
                     btif_media_cb.encoder.s16NumOfBlocks *
                     btif_media_cb.media_feeding.cfg.pcm.num_channel *
                     btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;

            btif_media_cb.media_feeding_state.pcm.overflow_count++;
            if (btif_media_cb.media_feeding_state.pcm.counter >
                btif_media_cb.media_feeding_state.pcm.max_counter_enter) {
                btif_media_cb.media_feeding_state.pcm.max_counter_enter =
                    btif_media_cb.media_feeding_state.pcm.counter;
            }

            if (btif_media_cb.media_feeding_state.pcm.counter > reset_rate_bytes) {
                btif_media_cb.media_feeding_state.pcm.counter = 0;
                APPL_TRACE_WARNING0("btif_media_aa_prep_sbc_2_send:reset rate counter");
            }

            /* no more pcm to read */
            nb_frame = 0;
        }
    }
}

@@ -2204,13 +2255,6 @@ static void btif_media_aa_prep_2_send(UINT8 nb_frame)
    VERBOSE("btif_media_aa_prep_2_send : %d frames (queue %d)", nb_frame,
                       btif_media_cb.TxAaQ.count);

    while (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ)
    {
        APPL_TRACE_WARNING1("btif_media_aa_prep_2_send congestion buf count %d",
                             btif_media_cb.TxAaQ.count);
        GKI_freebuf(GKI_dequeue(&(btif_media_cb.TxAaQ)));
    }

    switch (btif_media_cb.TxTranscoding)
    {
    case BTIF_MEDIA_TRSCD_PCM_2_SBC:
@@ -2240,8 +2284,10 @@ static void btif_media_send_aa_frame(void)
    /* get the number of frame to send */
    nb_frame_2_send = btif_get_num_aa_frame();

    if (nb_frame_2_send != 0) {
        /* format and Q buffer to send */
        btif_media_aa_prep_2_send(nb_frame_2_send);
    }

    /* send it */
    VERBOSE("btif_media_send_aa_frame : send %d frames", nb_frame_2_send);