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

Commit 82fc8edc authored by Ajay Panicker's avatar Ajay Panicker Committed by Myles Watson
Browse files

Uprev to AVDTP 1.3 and Implement AVDTP delay reports

Implement receiving the delay report message which requires AVDTP 1.3.
Also start keeping track of total number of audio bytes sent over the
air. We now will report both of these values to the audio HAL so that
they can adjust audio playback using these values.

Bug: 32755225
Test: Manual test with a device that supports delay reporting
      Testtracker: 145280
Change-Id: I22c1c6401e4912efab06fa56fb582faae4b38eaf
parent ac19d422
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ cc_library {
    ],
    shared_libs: [
        "liblog",
        "libcutils",
    ],
    static_libs: ["libosi"],
}
+6 −2
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ typedef enum {
  A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG,
  A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG,
  A2DP_CTRL_CMD_OFFLOAD_START,
  A2DP_CTRL_GET_PRESENTATION_POSITION,
} tA2DP_CTRL_CMD;

typedef enum {
@@ -140,12 +141,15 @@ typedef uint8_t tA2DP_BITS_PER_SAMPLE;
//
// Returns the computed buffer size. If any of the input parameters is
// invalid, the return value is the default |AUDIO_STREAM_OUTPUT_BUFFER_SZ|.
extern size_t audio_a2dp_hw_stream_compute_buffer_size(
size_t audio_a2dp_hw_stream_compute_buffer_size(
    btav_a2dp_codec_sample_rate_t codec_sample_rate,
    btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample,
    btav_a2dp_codec_channel_mode_t codec_channel_mode);

// Returns whether the delay reporting property is set.
bool delay_reporting_enabled();

// Returns a string representation of |event|.
extern const char* audio_a2dp_hw_dump_ctrl_event(tA2DP_CTRL_CMD event);
const char* audio_a2dp_hw_dump_ctrl_event(tA2DP_CTRL_CMD event);

#endif /* A2DP_AUDIO_HW_H */
+76 −5
Original line number Diff line number Diff line
@@ -58,6 +58,13 @@
#define USEC_PER_SEC 1000000L
#define SOCK_SEND_TIMEOUT_MS 2000 /* Timeout for sending */
#define SOCK_RECV_TIMEOUT_MS 5000 /* Timeout for receiving */
#define SEC_TO_MS 1000
#define SEC_TO_NS 1000000000
#define MS_TO_NS 1000000
#define DELAY_TO_NS 100000

#define MIN_DELAY_MS 100
#define MAX_DELAY_MS 1000

// set WRITE_POLL_MS to 0 for blocking sockets, nonzero for polled non-blocking
// sockets
@@ -145,11 +152,14 @@ struct a2dp_stream_in {
 *  Static variables
 *****************************************************************************/

static bool enable_delay_reporting = false;

/*****************************************************************************
 *  Static functions
 *****************************************************************************/

static size_t out_get_buffer_size(const struct audio_stream* stream);
static uint32_t out_get_latency(const struct audio_stream_out* stream);

/*****************************************************************************
 *  Externs
@@ -729,6 +739,36 @@ static int a2dp_write_output_audio_config(struct a2dp_stream_common* common) {
  return 0;
}

static int a2dp_get_presentation_position_cmd(struct a2dp_stream_common* common,
                                              uint64_t* bytes, uint16_t* delay,
                                              struct timespec* timestamp) {
  if (a2dp_command(common, A2DP_CTRL_GET_PRESENTATION_POSITION) < 0) {
    return -1;
  }

  if (a2dp_ctrl_receive(common, bytes, sizeof(*bytes)) < 0) {
    return -1;
  }

  if (a2dp_ctrl_receive(common, delay, sizeof(*delay)) < 0) {
    return -1;
  }

  uint32_t seconds;
  if (a2dp_ctrl_receive(common, &seconds, sizeof(seconds)) < 0) {
    return -1;
  }

  uint32_t nsec;
  if (a2dp_ctrl_receive(common, &nsec, sizeof(nsec)) < 0) {
    return -1;
  }

  timestamp->tv_sec = seconds;
  timestamp->tv_nsec = nsec;
  return 0;
}

static void a2dp_open_ctrl_path(struct a2dp_stream_common* common) {
  int i;

@@ -803,6 +843,10 @@ static int start_audio_datapath(struct a2dp_stream_common* common) {
    }
  }
  common->state = (a2dp_state_t)AUDIO_A2DP_STATE_STARTED;

  /* check to see if delay reporting is enabled */
  enable_delay_reporting = delay_reporting_enabled();

  return 0;

error:
@@ -1286,17 +1330,44 @@ static int out_get_presentation_position(const struct audio_stream_out* stream,
  FNLOG();
  if (stream == NULL || frames == NULL || timestamp == NULL) return -EINVAL;

  int ret = -EWOULDBLOCK;
  std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);

  // bytes is the total number of bytes sent by the Bluetooth stack to a
  // remote headset
  uint64_t bytes = 0;

  // delay_report is the audio delay from the remote headset receiving data to
  // the headset playing sound in units of 1/10ms
  uint16_t delay_report = 0;

  // If for some reason getting a delay fails or delay reports are disabled,
  // default to old delay
  if (enable_delay_reporting &&
      a2dp_get_presentation_position_cmd(&out->common, &bytes, &delay_report,
                                         timestamp) == 0) {
    uint64_t delay_ns = delay_report * DELAY_TO_NS;
    if (delay_ns > MIN_DELAY_MS * MS_TO_NS &&
        delay_ns < MAX_DELAY_MS * MS_TO_NS) {
      *frames = bytes / audio_stream_out_frame_size(stream);

      timestamp->tv_nsec += delay_ns;
      if (timestamp->tv_nsec > 1 * SEC_TO_NS) {
        timestamp->tv_sec++;
        timestamp->tv_nsec -= SEC_TO_NS;
      }
      return 0;
    }
  }

  uint64_t latency_frames =
      (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
  if (out->frames_presented >= latency_frames) {
    clock_gettime(CLOCK_MONOTONIC, timestamp);
    *frames = out->frames_presented - latency_frames;
    clock_gettime(CLOCK_MONOTONIC,
                  timestamp);  // could also be associated with out_write().
    ret = 0;
    return 0;
  }
  return ret;

  return -EWOULDBLOCK;
}

static int out_get_render_position(const struct audio_stream_out* stream,
+5 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
 ******************************************************************************/

#include "audio_a2dp_hw.h"
#include "osi/include/properties.h"

#define CASE_RETURN_STR(const) \
  case const:                  \
@@ -39,3 +40,7 @@ const char* audio_a2dp_hw_dump_ctrl_event(tA2DP_CTRL_CMD event) {

  return "UNKNOWN A2DP_CTRL_CMD";
}

bool delay_reporting_enabled() {
  return osi_property_get_bool("persist.bluetooth.enabledelayreports", false);
}
 No newline at end of file
+4 −2
Original line number Diff line number Diff line
@@ -1127,6 +1127,7 @@ void BtaAvCo::ProcessClose(tBTA_AV_HNDL bta_av_handle,
                           const RawAddress& peer_address) {
  APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x", __func__,
                   peer_address.ToString().c_str(), bta_av_handle);
  btif_av_reset_audio_delay();

  // Find the peer
  BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
@@ -1218,9 +1219,10 @@ void BtaAvCo::DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle,
void BtaAvCo::ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle,
                                const RawAddress& peer_address,
                                uint16_t delay) {
  APPL_TRACE_ERROR("%s: peer %s bta_av_handle: 0x%x delay:0x%x", __func__,
  APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x delay:0x%x", __func__,
                   peer_address.ToString().c_str(), bta_av_handle, delay);
  // Nothing to do

  btif_av_set_audio_delay(delay);
}

void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle,
Loading