mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/fix_a2dp_sink_blocked' into 'master'
Bugfix/Fix a2dp Sink Blocked Bugs Closes IDFGH-4920, IDFGH-5348, and BT-1740 See merge request espressif/esp-idf!12776
This commit is contained in:
commit
9ee25986a8
@ -24,6 +24,7 @@
|
|||||||
#include "common/bt_defs.h"
|
#include "common/bt_defs.h"
|
||||||
#include "osi/allocator.h"
|
#include "osi/allocator.h"
|
||||||
#include "osi/mutex.h"
|
#include "osi/mutex.h"
|
||||||
|
#include "osi/semaphore.h"
|
||||||
#include "osi/thread.h"
|
#include "osi/thread.h"
|
||||||
#include "osi/fixed_queue.h"
|
#include "osi/fixed_queue.h"
|
||||||
#include "stack/a2d_api.h"
|
#include "stack/a2d_api.h"
|
||||||
@ -86,8 +87,8 @@ enum {
|
|||||||
layers we might need to temporarily buffer up data */
|
layers we might need to temporarily buffer up data */
|
||||||
|
|
||||||
/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
|
/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
|
||||||
#define JITTER_BUFFER_WATER_LEVEL (15)
|
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (25)
|
||||||
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (18 + JITTER_BUFFER_WATER_LEVEL)
|
#define JITTER_BUFFER_WATER_LEVEL (5)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t sig;
|
uint32_t sig;
|
||||||
@ -104,6 +105,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
BOOLEAN rx_flush; /* discards any incoming data when true */
|
BOOLEAN rx_flush; /* discards any incoming data when true */
|
||||||
UINT8 channel_count;
|
UINT8 channel_count;
|
||||||
|
osi_sem_t post_sem;
|
||||||
fixed_queue_t *RxSbcQ;
|
fixed_queue_t *RxSbcQ;
|
||||||
UINT32 sample_rate;
|
UINT32 sample_rate;
|
||||||
} tBTC_A2DP_SINK_CB;
|
} tBTC_A2DP_SINK_CB;
|
||||||
@ -153,7 +155,6 @@ static inline void btc_a2d_data_cb_to_app(const uint8_t *data, uint32_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Misc helper functions
|
** Misc helper functions
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -351,7 +352,9 @@ void btc_a2dp_sink_reset_decoder(UINT8 *p_av)
|
|||||||
static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
|
static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
|
||||||
{
|
{
|
||||||
tBT_SBC_HDR *p_msg;
|
tBT_SBC_HDR *p_msg;
|
||||||
|
int nb_of_msgs_to_process = 0;
|
||||||
|
|
||||||
|
osi_sem_give(&a2dp_sink_local_param.btc_aa_snk_cb.post_sem);
|
||||||
if (fixed_queue_is_empty(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ)) {
|
if (fixed_queue_is_empty(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ)) {
|
||||||
APPL_TRACE_DEBUG(" QUE EMPTY ");
|
APPL_TRACE_DEBUG(" QUE EMPTY ");
|
||||||
} else {
|
} else {
|
||||||
@ -359,18 +362,20 @@ static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
|
|||||||
btc_a2dp_sink_flush_q(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ);
|
btc_a2dp_sink_flush_q(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
nb_of_msgs_to_process = fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ);
|
||||||
while ((p_msg = (tBT_SBC_HDR *)fixed_queue_try_peek_first(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ)) != NULL ) {
|
APPL_TRACE_DEBUG("nb:%d", nb_of_msgs_to_process);
|
||||||
|
while (nb_of_msgs_to_process > 0) {
|
||||||
if (btc_a2dp_sink_state != BTC_A2DP_SINK_STATE_ON){
|
if (btc_a2dp_sink_state != BTC_A2DP_SINK_STATE_ON){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
btc_a2dp_sink_handle_inc_media(p_msg);
|
|
||||||
p_msg = (tBT_SBC_HDR *)fixed_queue_dequeue(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, 0);
|
p_msg = (tBT_SBC_HDR *)fixed_queue_dequeue(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, 0);
|
||||||
if ( p_msg == NULL ) {
|
if ( p_msg == NULL ) {
|
||||||
APPL_TRACE_ERROR("Insufficient data in que ");
|
APPL_TRACE_ERROR("Insufficient data in que ");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
btc_a2dp_sink_handle_inc_media(p_msg);
|
||||||
osi_free(p_msg);
|
osi_free(p_msg);
|
||||||
|
nb_of_msgs_to_process--;
|
||||||
}
|
}
|
||||||
APPL_TRACE_DEBUG(" Process Frames - ");
|
APPL_TRACE_DEBUG(" Process Frames - ");
|
||||||
}
|
}
|
||||||
@ -671,12 +676,11 @@ UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_pkt)
|
|||||||
p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
|
p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
|
||||||
APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
|
APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
|
||||||
fixed_queue_enqueue(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, p_msg, FIXED_QUEUE_MAX_TIMEOUT);
|
fixed_queue_enqueue(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, p_msg, FIXED_QUEUE_MAX_TIMEOUT);
|
||||||
|
if (fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ) >= JITTER_BUFFER_WATER_LEVEL) {
|
||||||
if (fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ) < JITTER_BUFFER_WATER_LEVEL) {
|
if (osi_sem_take(&a2dp_sink_local_param.btc_aa_snk_cb.post_sem, 0) == 0) {
|
||||||
return fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ);
|
btc_a2dp_sink_data_post();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
btc_a2dp_sink_data_post();
|
|
||||||
} else {
|
} else {
|
||||||
/* let caller deal with a failed allocation */
|
/* let caller deal with a failed allocation */
|
||||||
APPL_TRACE_WARNING("btc_a2dp_sink_enque_buf No Buffer left - ");
|
APPL_TRACE_WARNING("btc_a2dp_sink_enque_buf No Buffer left - ");
|
||||||
@ -711,7 +715,9 @@ static void btc_a2dp_sink_thread_init(UNUSED_ATTR void *context)
|
|||||||
memset(&a2dp_sink_local_param.btc_aa_snk_cb, 0, sizeof(a2dp_sink_local_param.btc_aa_snk_cb));
|
memset(&a2dp_sink_local_param.btc_aa_snk_cb, 0, sizeof(a2dp_sink_local_param.btc_aa_snk_cb));
|
||||||
|
|
||||||
btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_ON;
|
btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_ON;
|
||||||
|
if (!a2dp_sink_local_param.btc_aa_snk_cb.post_sem) {
|
||||||
|
osi_sem_new(&a2dp_sink_local_param.btc_aa_snk_cb.post_sem, 1, 1);
|
||||||
|
}
|
||||||
a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ = fixed_queue_new(QUEUE_SIZE_MAX);
|
a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ = fixed_queue_new(QUEUE_SIZE_MAX);
|
||||||
|
|
||||||
btc_a2dp_control_init();
|
btc_a2dp_control_init();
|
||||||
@ -728,6 +734,11 @@ static void btc_a2dp_sink_thread_cleanup(UNUSED_ATTR void *context)
|
|||||||
fixed_queue_free(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, osi_free_func);
|
fixed_queue_free(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, osi_free_func);
|
||||||
|
|
||||||
a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ = NULL;
|
a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ = NULL;
|
||||||
|
|
||||||
|
if (a2dp_sink_local_param.btc_aa_snk_cb.post_sem) {
|
||||||
|
osi_sem_free(&a2dp_sink_local_param.btc_aa_snk_cb.post_sem);
|
||||||
|
a2dp_sink_local_param.btc_aa_snk_cb.post_sem = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* BTC_AV_SINK_INCLUDED */
|
#endif /* BTC_AV_SINK_INCLUDED */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user