Loading system/btif/src/btif_media_task.c +64 −18 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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) { Loading @@ -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; Loading @@ -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; } /******************************************************************************* Loading Loading @@ -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; } } } Loading @@ -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: Loading Loading @@ -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); Loading Loading
system/btif/src/btif_media_task.c +64 −18 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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) { Loading @@ -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; Loading @@ -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; } /******************************************************************************* Loading Loading @@ -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; } } } Loading @@ -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: Loading Loading @@ -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); Loading