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

Commit fb1f7152 authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Update the A2DP MTU if the L2CAP MTU changes during codec reconfiguration

Previously, the MTU was saved inside the AVDTP module after the first
codec setup. However, the MTU wasn't updated after codec reconfiguration.
As a result, if a Sink device uses different (smaller) MTU for
a codec like SBC, then switching fron another codec to SBC will
result in generating SBC frames that are too large to transmit,
and there will be no audio.

Bug: b/35351216
Test: A2DP streaming and codec switch to various Sink devices.
Change-Id: Ieb3caf4ef7a30a7af31ceb2f6132807739829441
parent eb0f5a72
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -86,7 +86,8 @@ const tBTA_AV_CO_FUNCTS bta_av_a2dp_cos = {
    bta_av_co_audio_getconfig,     bta_av_co_audio_setconfig,
    bta_av_co_audio_open,          bta_av_co_audio_close,
    bta_av_co_audio_start,         bta_av_co_audio_stop,
    bta_av_co_audio_src_data_path, bta_av_co_audio_delay};
    bta_av_co_audio_src_data_path, bta_av_co_audio_delay,
    bta_av_co_audio_update_mtu};

/* ssm action functions for audio stream */
const tBTA_AV_SACT bta_av_a2dp_action[] = {
@@ -2557,12 +2558,20 @@ void bta_av_suspend_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
 * Returns          void
 *
 ******************************************************************************/
void bta_av_rcfg_str_ok(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
void bta_av_rcfg_str_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
  tBTA_AV_RECONFIG evt;

  p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle);
  APPL_TRACE_DEBUG("%s: l2c_cid: %d", __func__, p_scb->l2c_cid);

  p_scb->stream_mtu =
      p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE;
  uint16_t mtu = bta_av_chk_mtu(p_scb, p_scb->stream_mtu);
  APPL_TRACE_DEBUG("%s: l2c_cid: 0x%x stream_mtu: %d mtu: %d", __func__,
                   p_scb->l2c_cid, p_scb->stream_mtu, mtu);
  if (mtu == 0 || mtu > p_scb->stream_mtu) mtu = p_scb->stream_mtu;
  p_scb->p_cos->update_mtu(p_scb->hndl, mtu);

  /* rc listen */
  bta_av_st_rc_timer(p_scb, NULL);
  osi_free_and_reset((void**)&p_scb->p_cap);
+2 −0
Original line number Diff line number Diff line
@@ -180,6 +180,7 @@ typedef void (*tBTA_AV_CO_STOP)(tBTA_AV_HNDL hndl);
typedef void* (*tBTA_AV_CO_DATAPATH)(const uint8_t* p_codec_info,
                                     uint32_t* p_timestamp);
typedef void (*tBTA_AV_CO_DELAY)(tBTA_AV_HNDL hndl, uint16_t delay);
typedef void (*tBTA_AV_CO_UPDATE_MTU)(tBTA_AV_HNDL hndl, uint16_t mtu);

/* the call-out functions for one stream */
typedef struct {
@@ -193,6 +194,7 @@ typedef struct {
  tBTA_AV_CO_STOP stop;
  tBTA_AV_CO_DATAPATH data;
  tBTA_AV_CO_DELAY delay;
  tBTA_AV_CO_UPDATE_MTU update_mtu;
} tBTA_AV_CO_FUNCTS;

/* data type for BTA_AV_API_ENABLE_EVT */
+15 −0
Original line number Diff line number Diff line
@@ -197,4 +197,19 @@ void bta_av_co_audio_drop(tBTA_AV_HNDL hndl);
 ******************************************************************************/
void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, uint16_t delay);

/*******************************************************************************
 *
 * Function         bta_av_co_audio_update_mtu
 *
 * Description      This function is called by AV when the audio stream
 *                  connection MTU needs to be updated.
 *                  BTA-AV maintains the MTU of A2DP streams.
 *                  If this is the 2nd audio stream, mtu is the smaller of the 2
 *                  streams.
 *
 * Returns          void
 *
 ******************************************************************************/
void bta_av_co_audio_update_mtu(tBTA_AV_HNDL hndl, uint16_t mtu);

#endif /* BTA_AV_CO_H */
+14 −0
Original line number Diff line number Diff line
@@ -761,6 +761,20 @@ void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, uint16_t delay) {
  APPL_TRACE_ERROR("%s: handle: x%x, delay:0x%x", __func__, hndl, delay);
}

void bta_av_co_audio_update_mtu(tBTA_AV_HNDL hndl, uint16_t mtu) {
  tBTA_AV_CO_PEER* p_peer;

  APPL_TRACE_DEBUG("%s: handle: %d mtu: %d", __func__, hndl, mtu);

  /* Retrieve the peer info */
  p_peer = bta_av_co_get_peer(hndl);
  if (p_peer == NULL) {
    APPL_TRACE_ERROR("%s: could not find peer entry", __func__);
    return;
  }
  p_peer->mtu = mtu;
}

/*******************************************************************************
 **
 ** Function         bta_av_co_cp_is_scmst