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

Commit 0f8006f1 authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Improve A2DP codec run-time debug-abilitity

Rename A2DP_DumpCodecInfo() to A2DP_CodecInfoString() and change
the usage. Previously, A2DP_DumpCodecInfo() would print the
the codec information only if LOG_VERBOSE() was enabled in compile time.
The new A2DP_CodecInfoString() now returns human-readable std::string
with the codec information.
That string can be used in debug log messages that can be enabled
in run-time.

Bug: 77525584
Test: Manual - Examine log messages when A2DP streaming with and
      without debug log messages enabled.

Change-Id: Idd440d6c9e908520132feeeb5388d3e6aefa26db
Merged-In: Idd440d6c9e908520132feeeb5388d3e6aefa26db
(cherry picked from commit 0ffadf70)
parent 9611b05b
Loading
Loading
Loading
Loading
+22 −11
Original line number Diff line number Diff line
@@ -950,7 +950,8 @@ void bta_av_config_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {

  APPL_TRACE_DEBUG("%s: peer %s handle:%d local_sep:%d", __func__,
                   p_scb->peer_addr.ToString().c_str(), p_scb->hndl, local_sep);
  A2DP_DumpCodecInfo(p_evt_cfg->codec_info);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_evt_cfg->codec_info).c_str());

  memcpy(p_scb->cfg.codec_info, p_evt_cfg->codec_info, AVDT_CODEC_SIZE);
  bta_av_save_addr(p_scb, p_data->str_msg.bd_addr);
@@ -1517,7 +1518,8 @@ void bta_av_save_caps(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
      "%s: peer %s handle:%d num_seps:%d sep_info_idx:%d wait:0x%x", __func__,
      p_scb->peer_addr.ToString().c_str(), p_scb->hndl, p_scb->num_seps,
      p_scb->sep_info_idx, p_scb->wait);
  A2DP_DumpCodecInfo(p_scb->peer_cap.codec_info);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_scb->peer_cap.codec_info).c_str());

  cfg = p_scb->peer_cap;
  /* let application know the capability of the SNK */
@@ -1528,7 +1530,8 @@ void bta_av_save_caps(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
  p_scb->sep_info_idx++;
  APPL_TRACE_DEBUG("%s: result: sep_info_idx:%d", __func__,
                   p_scb->sep_info_idx);
  A2DP_DumpCodecInfo(cfg.codec_info);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(cfg.codec_info).c_str());

  if (p_scb->num_seps > p_scb->sep_info_idx) {
    /* Some devices have seps at the end of the discover list, which is not */
@@ -1671,7 +1674,8 @@ void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
                   p_scb->peer_cap.num_codec);
  APPL_TRACE_DEBUG("%s: media type 0x%x, 0x%x", __func__, media_type,
                   p_scb->media_type);
  A2DP_DumpCodecInfo(p_scb->cfg.codec_info);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());

  /* if codec present and we get a codec configuration */
  if ((p_scb->peer_cap.num_codec != 0) && (media_type == p_scb->media_type) &&
@@ -1686,7 +1690,8 @@ void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {

    APPL_TRACE_DEBUG("%s: result: sep_info_idx=%d", __func__,
                     p_scb->sep_info_idx);
    A2DP_DumpCodecInfo(p_scb->cfg.codec_info);
    APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                     A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());

    APPL_TRACE_DEBUG("%s: initiator UUID = 0x%x", __func__, uuid_int);
    if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
@@ -1950,9 +1955,12 @@ void bta_av_reconfig(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
  APPL_TRACE_DEBUG(
      "%s: p_scb->sep_info_idx=%d p_scb->rcfg_idx=%d p_rcfg->sep_info_idx=%d",
      __func__, p_scb->sep_info_idx, p_scb->rcfg_idx, p_rcfg->sep_info_idx);
  A2DP_DumpCodecInfo(p_scb->peer_cap.codec_info);
  A2DP_DumpCodecInfo(p_scb->cfg.codec_info);
  A2DP_DumpCodecInfo(p_rcfg->codec_info);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_scb->peer_cap.codec_info).c_str());
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_rcfg->codec_info).c_str());

  p_cfg->num_protect = p_rcfg->num_protect;
  memcpy(p_cfg->codec_info, p_rcfg->codec_info, AVDT_CODEC_SIZE);
@@ -1975,7 +1983,8 @@ void bta_av_reconfig(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
    } else {
      // Reconfigure
      APPL_TRACE_DEBUG("%s: reconfig", __func__);
      A2DP_DumpCodecInfo(p_scb->cfg.codec_info);
      APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                       A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());
      AVDT_ReconfigReq(p_scb->avdt_handle, &p_scb->cfg);
      p_scb->cfg.psc_mask = p_scb->cur_psc_mask;
    }
@@ -2692,7 +2701,8 @@ void bta_av_suspend_cont(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
    APPL_TRACE_DEBUG("%s: calling AVDT_ReconfigReq", __func__);
    /* reconfig the stream */

    A2DP_DumpCodecInfo(p_scb->cfg.codec_info);
    APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                     A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());
    AVDT_ReconfigReq(p_scb->avdt_handle, &p_scb->cfg);
    p_scb->cfg.psc_mask = p_scb->cur_psc_mask;
  }
@@ -2778,7 +2788,8 @@ void bta_av_rcfg_open(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
                     BTA_AV_NUM_SEPS, &bta_av_proc_stream_evt);
  } else {
    APPL_TRACE_DEBUG("%s: calling AVDT_OpenReq()", __func__);
    A2DP_DumpCodecInfo(p_scb->cfg.codec_info);
    APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                     A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str());

    /* we may choose to use a different SEP at reconfig.
     * adjust the sep_idx now */
+12 −6
Original line number Diff line number Diff line
@@ -855,7 +855,8 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig(
  APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
                   __func__, *p_num_protect, p_protect_info[0],
                   p_protect_info[1], p_protect_info[2]);
  A2DP_DumpCodecInfo(p_codec_info);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_codec_info).c_str());

  // Find the peer
  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
@@ -946,7 +947,8 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,
  APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
                   __func__, *p_num_protect, p_protect_info[0],
                   p_protect_info[1], p_protect_info[2]);
  A2DP_DumpCodecInfo(p_codec_info);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_codec_info).c_str());

  // Find the peer
  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
@@ -1046,7 +1048,8 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,
  APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
                   __func__, num_protect, p_protect_info[0], p_protect_info[1],
                   p_protect_info[2]);
  A2DP_DumpCodecInfo(p_codec_info);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_codec_info).c_str());

  // Find the peer
  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
@@ -1846,7 +1849,8 @@ void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer,
                                 uint8_t num_protect,
                                 const uint8_t* p_protect_info) {
  APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
  A2DP_DumpCodecInfo(new_codec_config);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(new_codec_config).c_str());

  std::lock_guard<std::recursive_mutex> lock(codec_lock_);

@@ -1872,7 +1876,8 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,

  APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
                   p_peer->addr.ToString().c_str());
  A2DP_DumpCodecInfo(p_ota_codec_config);
  APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                   A2DP_CodecInfoString(p_ota_codec_config).c_str());

  *p_restart_output = false;

@@ -1913,7 +1918,8 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,

  if (restart_output) {
    APPL_TRACE_DEBUG("%s: restart output", __func__);
    A2DP_DumpCodecInfo(result_codec_config);
    APPL_TRACE_DEBUG("%s: codec: %s", __func__,
                     A2DP_CodecInfoString(result_codec_config).c_str());

    *p_restart_output = true;
    p_peer->p_sink = p_sink;
+21 −0
Original line number Diff line number Diff line
@@ -727,6 +727,8 @@ void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...);
#include <sstream>
#include <type_traits>

#include <base/logging.h>

/* Prints intergral parameter x as hex string, with '0' fill */
template <typename T>
std::string loghex(T x) {
@@ -738,4 +740,23 @@ std::string loghex(T x) {
  return tmp.str();
}

/**
 * Append a field name to a string.
 *
 * The field names are added to the string with "|" in between.
 *
 * @param p_result a pointer to the result string to add the field name to
 * @param append if true the field name will be added
 * @param name the field name to add
 * @return the result string
 */
inline std::string& AppendField(std::string* p_result, bool append,
                                const std::string& name) {
  CHECK(p_result != nullptr);
  if (!append) return *p_result;
  if (!p_result->empty()) *p_result += "|";
  *p_result += name;
  return *p_result;
}

#endif
+71 −73
Original line number Diff line number Diff line
@@ -562,84 +562,82 @@ bool A2DP_BuildCodecHeaderAac(UNUSED_ATTR const uint8_t* p_codec_info,
  return true;
}

bool A2DP_DumpCodecInfoAac(const uint8_t* p_codec_info) {
std::string A2DP_CodecInfoStringAac(const uint8_t* p_codec_info) {
  std::stringstream res;
  std::string field;
  tA2DP_STATUS a2dp_status;
  tA2DP_AAC_CIE aac_cie;

  LOG_VERBOSE(LOG_TAG, "%s", __func__);

  a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, true);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: A2DP_ParseInfoAac fail:%d", __func__, a2dp_status);
    return false;
  }

  LOG_VERBOSE(LOG_TAG, "\tobjectType: 0x%x", aac_cie.objectType);
  if (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG2_LC) {
    LOG_VERBOSE(LOG_TAG, "\tobjectType: (MPEG-2 AAC LC)");
  }
  if (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG4_LC) {
    LOG_VERBOSE(LOG_TAG, "\tobjectType: (MPEG-4 AAC LC)");
  }
  if (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG4_LTP) {
    LOG_VERBOSE(LOG_TAG, "\tobjectType: (MPEG-4 AAC LTP)");
  }
  if (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE) {
    LOG_VERBOSE(LOG_TAG, "\tobjectType: (MPEG-4 AAC Scalable)");
  }

  LOG_VERBOSE(LOG_TAG, "\tsamp_freq: 0x%x", aac_cie.sampleRate);
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_8000) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (8000)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_11025) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (11025)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_12000) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (12000)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_16000) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (16000)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_22050) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (22050)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_24000) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (24000)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_32000) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (32000)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_44100) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (44100)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_48000) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (48000)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_64000) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (64000)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_88200) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (88200)");
  }
  if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_96000) {
    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (96000)");
  }

  LOG_VERBOSE(LOG_TAG, "\tch_mode: 0x%x", aac_cie.channelMode);
  if (aac_cie.channelMode == A2DP_AAC_CHANNEL_MODE_MONO) {
    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Mono)");
  }
  if (aac_cie.channelMode == A2DP_AAC_CHANNEL_MODE_STEREO) {
    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Stereo)");
  }

  LOG_VERBOSE(LOG_TAG, "\tvariableBitRateSupport: %s",
              (aac_cie.variableBitRateSupport != 0) ? "true" : "false");

  LOG_VERBOSE(LOG_TAG, "\tbitRate: %u", aac_cie.bitRate);

  return true;
    res << "A2DP_ParseInfoAac fail: " << loghex(a2dp_status);
    return res.str();
  }

  res << "\tname: AAC\n";

  // Object type
  field.clear();
  AppendField(&field, (aac_cie.objectType == 0), "NONE");
  AppendField(&field, (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG2_LC),
              "(MPEG-2 AAC LC)");
  AppendField(&field, (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG4_LC),
              "(MPEG-4 AAC LC)");
  AppendField(&field, (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG4_LTP),
              "(MPEG-4 AAC LTP)");
  AppendField(&field,
              (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE),
              "(MPEG-4 AAC Scalable)");
  res << "\tobjectType: " << field << " (" << loghex(aac_cie.objectType)
      << ")\n";

  // Sample frequency
  field.clear();
  AppendField(&field, (aac_cie.sampleRate == 0), "NONE");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_8000),
              "8000");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_11025),
              "11025");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_12000),
              "12000");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_16000),
              "16000");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_22050),
              "22050");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_24000),
              "24000");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_32000),
              "32000");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_44100),
              "44100");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_48000),
              "48000");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_64000),
              "64000");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_88200),
              "88200");
  AppendField(&field, (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_96000),
              "96000");
  res << "\tsamp_freq: " << field << " (" << loghex(aac_cie.sampleRate)
      << ")\n";

  // Channel mode
  field.clear();
  AppendField(&field, (aac_cie.channelMode == 0), "NONE");
  AppendField(&field, (aac_cie.channelMode == A2DP_AAC_CHANNEL_MODE_MONO),
              "Mono");
  AppendField(&field, (aac_cie.channelMode == A2DP_AAC_CHANNEL_MODE_STEREO),
              "Stereo");
  res << "\tch_mode: " << field << " (" << loghex(aac_cie.channelMode) << ")\n";

  // Variable bit rate support
  res << "\tvariableBitRateSupport: " << std::boolalpha
      << (aac_cie.variableBitRateSupport != 0) << "\n";

  // Bit rate
  res << "\tbitRate: " << std::to_string(aac_cie.bitRate) << "\n";

  return res.str();
}

const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterfaceAac(
+5 −8
Original line number Diff line number Diff line
@@ -1410,22 +1410,19 @@ bool A2DP_InitCodecConfig(btav_a2dp_codec_index_t codec_index,
  return false;
}

bool A2DP_DumpCodecInfo(const uint8_t* p_codec_info) {
std::string A2DP_CodecInfoString(const uint8_t* p_codec_info) {
  tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);

  LOG_VERBOSE(LOG_TAG, "%s: codec_type = 0x%x", __func__, codec_type);

  switch (codec_type) {
    case A2DP_MEDIA_CT_SBC:
      return A2DP_DumpCodecInfoSbc(p_codec_info);
      return A2DP_CodecInfoStringSbc(p_codec_info);
    case A2DP_MEDIA_CT_AAC:
      return A2DP_DumpCodecInfoAac(p_codec_info);
      return A2DP_CodecInfoStringAac(p_codec_info);
    case A2DP_MEDIA_CT_NON_A2DP:
      return A2DP_VendorDumpCodecInfo(p_codec_info);
      return A2DP_VendorCodecInfoString(p_codec_info);
    default:
      break;
  }

  LOG_ERROR(LOG_TAG, "%s: unsupported codec type 0x%x", __func__, codec_type);
  return false;
  return "Unsupported codec type: " + loghex(codec_type);
}
Loading