Remove overflow rate limiting when reading A2DP frames

A2DP now supports adjusting the number of A2DP frames sent per timer
tick to adjust for timer drift and missed media task ticks. When the
signal to the headset/speakers becomes interrupted, the number of
packets to be read can queue up and rate limiting will not allow for the
queue to be cleared.

The overflow mechanism introduced in commit 4aebca4 will cause the media
task to stop sending packets completely, which can underflow the jutter
buffer on the remote device and lead to audio drop-outs.

This patch removes the overflow mechanism and also adds code do discard
audio frames that could not be sent to the remote device (weak signal
etc) to allow the device to stay in sync and not build up audio delays.

Also added additional debug logging and changed the UIPC flush mechanism
to address an issue where reading byte by byte causes an endless flush
loop if remote UIPC producer writes data faster than the flush loop
consumes it.

Bug: 18326405
Change-Id: I9a424984806bb2a464877399804b3355b2c439c3
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index 4b04e1e..e5ea51a 100644
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -208,9 +208,7 @@
 
 /* 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     10
-#define RESET_RATE_COUNTER_THRESHOLD_MS    2000
 
 //#define BTIF_MEDIA_VERBOSE_ENABLED
 /* In case of A2DP SINK, we will delay start by 5 AVDTP Packets*/
@@ -247,10 +245,6 @@
     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;
 
 
@@ -2356,11 +2350,6 @@
  *******************************************************************************/
 static void btif_media_task_feeding_state_reset(void)
 {
-    APPL_TRACE_WARNING("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));
 
@@ -2443,12 +2432,12 @@
  *******************************************************************************/
 static UINT8 btif_get_num_aa_frame(void)
 {
-    UINT32 result=0;
+    UINT8 result=0;
 
     switch (btif_media_cb.TxTranscoding)
     {
         case BTIF_MEDIA_TRSCD_PCM_2_SBC:
-           {
+        {
             UINT32 pcm_bytes_per_frame = btif_media_cb.encoder.s16NumOfSubBands *
                              btif_media_cb.encoder.s16NumOfBlocks *
                              btif_media_cb.media_feeding.cfg.pcm.num_channel *
@@ -2463,29 +2452,16 @@
             btif_media_cb.media_feeding_state.pcm.counter +=
                                 btif_media_cb.media_feeding_state.pcm.bytes_per_tick *
                                 us_this_tick / (BTIF_MEDIA_TIME_TICK * 1000);
-            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)
-                {
-                    APPL_TRACE_ERROR("%s() - Limiting frames to be sent from %d to %d"
-                        , __FUNCTION__, 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;
+            /* 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)
+            {
+                APPL_TRACE_WARNING("%s() - Limiting frames to be sent from %d to %d"
+                    , __FUNCTION__, 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;
 
             VERBOSE("WRITE %d FRAMES", result);
         }
@@ -2845,32 +2821,6 @@
         {
             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_WARNING("btif_media_aa_prep_sbc_2_send:reset rate counter");
-            }
-
-            /* no more pcm to read */
-            nb_frame = 0;
-        }
     }
 }
 
@@ -2887,8 +2837,16 @@
 
 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);
+    VERBOSE("%s() - frames=%d (queue=%d)", __FUNCTION__, nb_frame, btif_media_cb.TxAaQ.count);
+
+    while (btif_media_cb.TxAaQ.count >= (MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ-nb_frame))
+    {
+        APPL_TRACE_WARNING("%s() - TX queue buffer count %d",
+            __FUNCTION__, btif_media_cb.TxAaQ.count);
+        GKI_freebuf(GKI_dequeue(&(btif_media_cb.TxAaQ)));
+    }
+
+    if (btif_media_cb.TxAaQ.count) --nb_frame;
 
     switch (btif_media_cb.TxTranscoding)
     {
@@ -2919,7 +2877,8 @@
     /* get the number of frame to send */
     nb_frame_2_send = btif_get_num_aa_frame();
 
-    if (nb_frame_2_send != 0) {
+    if (nb_frame_2_send != 0)
+    {
         /* format and Q buffer to send */
         btif_media_aa_prep_2_send(nb_frame_2_send);
     }
diff --git a/udrv/ulinux/uipc.c b/udrv/ulinux/uipc.c
index b9caa1b..81ca7f8 100644
--- a/udrv/ulinux/uipc.c
+++ b/udrv/ulinux/uipc.c
@@ -69,6 +69,8 @@
 
 #define SAFE_FD_ISSET(fd, set) (((fd) == -1) ? FALSE : FD_ISSET((fd), (set)))
 
+#define UIPC_FLUSH_BUFFER_SIZE 1024
+
 /*****************************************************************************
 **  Local type definitions
 ******************************************************************************/
@@ -373,30 +375,40 @@
 
 static void uipc_flush_ch_locked(tUIPC_CH_ID ch_id)
 {
-    char buf;
+    char buf[UIPC_FLUSH_BUFFER_SIZE];
     struct pollfd pfd;
     int ret;
 
-    pfd.events = POLLIN|POLLHUP;
+    pfd.events = POLLIN;
     pfd.fd = uipc_main.ch[ch_id].fd;
 
     if (uipc_main.ch[ch_id].fd == UIPC_DISCONNECTED)
+    {
+        BTIF_TRACE_EVENT("%s() - fd disconnected. Exiting", __FUNCTION__);
         return;
+    }
 
     while (1)
     {
         ret = poll(&pfd, 1, 1);
-        BTIF_TRACE_EVENT("uipc_flush_ch_locked polling : fd %d, rxev %x, ret %d", pfd.fd, pfd.revents, ret);
+        BTIF_TRACE_VERBOSE("%s() - polling fd %d, revents: 0x%x, ret %d",
+                __FUNCTION__, pfd.fd, pfd.revents, ret);
 
         if (pfd.revents & (POLLERR|POLLHUP))
+        {
+            BTIF_TRACE_EVENT("%s() - POLLERR or POLLHUP. Exiting", __FUNCTION__);
             return;
+        }
 
         if (ret <= 0)
         {
-            BTIF_TRACE_EVENT("uipc_flush_ch_locked : error (%d)", ret);
+            BTIF_TRACE_EVENT("%s() - error (%d). Exiting", __FUNCTION__, ret);
             return;
         }
-        read(pfd.fd, &buf, 1);
+
+        /* read sufficiently large buffer to ensure flush empties socket faster than
+           it is getting refilled */
+        read(pfd.fd, &buf, UIPC_FLUSH_BUFFER_SIZE);
     }
 }