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

Commit 723bef8e authored by Jack He's avatar Jack He
Browse files

Corrected default value assignments in Bluetooth A2DP Metrics

* In certain cases btif_a2dp_source_stop_audio_req() could be called before
  btif_a2dp_source_start_audio_req() is called, resulting in session_start_us
  to be 0. In this case, audio_duration_ms = time_get_os_boottime_us() - 0
  will be a very large number that is not the actual audio duration. This
  CL marks audio_duration_ms as -1 in the above situation so that we can
  differentiate between valid and invalid audio durations
* Set default timer and counter values to 0 when
  tx_queue_dequeue_stats.total_updates > 1
* Move update_scheduling_stats for tx_queue_enqueue_stats to
  btif_a2dp_source_audio_handle_timer as we intend to capture the time
  intervals for enqueue scheduling instead of time intervals between
  frame enqueue (i.e. one scheduling event can enqueue multiple frames)
* Use tx_queue_enqueue_stats for metrics instead of *dequeue* since only
  enqueue is triggered by timer event

Bug: 33694310
Test: Code compilation, BtFunhausMetricsTest
Change-Id: I10984920afd4d77f07a5ac75736f8dcd69b13af8
(cherry picked from commit aa79f0fb)
parent f33ade65
Loading
Loading
Loading
Loading
+26 −15
Original line number Diff line number Diff line
@@ -392,7 +392,12 @@ void btif_a2dp_source_start_audio_req(void) {
  p_buf->event = BTIF_MEDIA_AUDIO_TX_START;
  fixed_queue_enqueue(btif_a2dp_source_cb.cmd_msg_queue, p_buf);
  memset(&btif_a2dp_source_cb.stats, 0, sizeof(btif_media_stats_t));
  // Assign session_start_us to 1 when time_get_os_boottime_us() is 0 to
  // indicate btif_a2dp_source_start_audio_req() has been called
  btif_a2dp_source_cb.stats.session_start_us = time_get_os_boottime_us();
  if (btif_a2dp_source_cb.stats.session_start_us == 0) {
    btif_a2dp_source_cb.stats.session_start_us = 1;
  }
  btif_a2dp_source_cb.stats.session_end_us = 0;
}

@@ -657,6 +662,9 @@ static void btif_a2dp_source_audio_handle_timer(UNUSED_ATTR void* context) {
    CHECK(btif_a2dp_source_cb.encoder_interface != NULL);
    btif_a2dp_source_cb.encoder_interface->send_frames(timestamp_us);
    bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
    update_scheduling_stats(&btif_a2dp_source_cb.stats.tx_queue_enqueue_stats,
                            timestamp_us,
                            btif_a2dp_source_cb.encoder_interval_ms * 1000);
  } else {
    APPL_TRACE_ERROR("ERROR Media task Scheduled after Suspend");
  }
@@ -732,9 +740,6 @@ static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n) {
  btif_a2dp_source_cb.stats.tx_queue_max_frames_per_packet = std::max(
      frames_n, btif_a2dp_source_cb.stats.tx_queue_max_frames_per_packet);
  CHECK(btif_a2dp_source_cb.encoder_interface != NULL);
  update_scheduling_stats(&btif_a2dp_source_cb.stats.tx_queue_enqueue_stats,
                          now_us,
                          btif_a2dp_source_cb.encoder_interval_ms * 1000);

  fixed_queue_enqueue(btif_a2dp_source_cb.tx_audio_queue, p_buf);

@@ -1018,32 +1023,38 @@ void btif_a2dp_source_debug_dump(int fd) {

void btif_a2dp_source_update_metrics(void) {
  btif_media_stats_t* stats = &btif_a2dp_source_cb.stats;
  scheduling_stats_t* dequeue_stats = &stats->tx_queue_dequeue_stats;
  scheduling_stats_t* enqueue_stats = &stats->tx_queue_enqueue_stats;
  A2dpSessionMetrics metrics;
  // session_start_us is 0 when btif_a2dp_source_start_audio_req() is not called
  // mark the metric duration as invalid (-1) in this case
  if (stats->session_start_us != 0) {
    int64_t session_end_us = stats->session_end_us == 0
                                 ? time_get_os_boottime_us()
                                 : stats->session_end_us;
  metrics.audio_duration_ms = (session_end_us - stats->session_start_us) / 1000;
    metrics.audio_duration_ms =
        (session_end_us - stats->session_start_us) / 1000;
  }

  if (dequeue_stats->total_updates > 1) {
  if (enqueue_stats->total_updates > 1) {
    metrics.media_timer_min_ms =
        btif_a2dp_source_cb.encoder_interval_ms -
        (dequeue_stats->max_premature_scheduling_delta_us / 1000);
        (enqueue_stats->max_premature_scheduling_delta_us / 1000);
    metrics.media_timer_max_ms =
        btif_a2dp_source_cb.encoder_interval_ms +
        (dequeue_stats->max_overdue_scheduling_delta_us / 1000);
        (enqueue_stats->max_overdue_scheduling_delta_us / 1000);

    metrics.total_scheduling_count = dequeue_stats->overdue_scheduling_count +
                                     dequeue_stats->premature_scheduling_count +
                                     dequeue_stats->exact_scheduling_count;
    metrics.total_scheduling_count = enqueue_stats->overdue_scheduling_count +
                                     enqueue_stats->premature_scheduling_count +
                                     enqueue_stats->exact_scheduling_count;
    if (metrics.total_scheduling_count > 0) {
      metrics.media_timer_avg_ms = dequeue_stats->total_scheduling_time_us /
      metrics.media_timer_avg_ms = enqueue_stats->total_scheduling_time_us /
                                   (1000 * metrics.total_scheduling_count);
    }

    metrics.buffer_overruns_max_count = stats->tx_queue_max_dropped_messages;
    metrics.buffer_overruns_total = stats->tx_queue_total_dropped_messages;
    metrics.buffer_underruns_count = stats->media_read_total_underflow_count;
    metrics.buffer_underruns_average = 0;
    if (metrics.buffer_underruns_count > 0) {
      metrics.buffer_underruns_average =
          stats->media_read_total_underflow_bytes /
+10 −10
Original line number Diff line number Diff line
@@ -85,11 +85,11 @@ static int32_t combine_averages(int32_t avg_a, int64_t ct_a, int32_t avg_b,
}

void A2dpSessionMetrics::Update(const A2dpSessionMetrics& metrics) {
  if (metrics.audio_duration_ms > 0) {
  if (metrics.audio_duration_ms >= 0) {
    audio_duration_ms = std::max(static_cast<int64_t>(0), audio_duration_ms);
    audio_duration_ms += metrics.audio_duration_ms;
  }
  if (metrics.media_timer_min_ms > 0) {
  if (metrics.media_timer_min_ms >= 0) {
    if (media_timer_min_ms < 0) {
      media_timer_min_ms = metrics.media_timer_min_ms;
    } else {
@@ -97,11 +97,11 @@ void A2dpSessionMetrics::Update(const A2dpSessionMetrics& metrics) {
          std::min(media_timer_min_ms, metrics.media_timer_min_ms);
    }
  }
  if (metrics.media_timer_max_ms > 0) {
  if (metrics.media_timer_max_ms >= 0) {
    media_timer_max_ms =
        std::max(media_timer_max_ms, metrics.media_timer_max_ms);
  }
  if (metrics.media_timer_avg_ms > 0 && metrics.total_scheduling_count > 0) {
  if (metrics.media_timer_avg_ms >= 0 && metrics.total_scheduling_count >= 0) {
    if (media_timer_avg_ms < 0 || total_scheduling_count < 0) {
      media_timer_avg_ms = metrics.media_timer_avg_ms;
      total_scheduling_count = metrics.total_scheduling_count;
@@ -112,24 +112,24 @@ void A2dpSessionMetrics::Update(const A2dpSessionMetrics& metrics) {
      total_scheduling_count += metrics.total_scheduling_count;
    }
  }
  if (metrics.buffer_overruns_max_count > 0) {
  if (metrics.buffer_overruns_max_count >= 0) {
    buffer_overruns_max_count =
        std::max(buffer_overruns_max_count, metrics.buffer_overruns_max_count);
  }
  if (metrics.buffer_overruns_total > 0) {
  if (metrics.buffer_overruns_total >= 0) {
    buffer_overruns_total =
        std::max(static_cast<int32_t>(0), buffer_overruns_total);
    buffer_overruns_total += metrics.buffer_overruns_total;
  }
  if (metrics.buffer_underruns_average > 0 &&
      metrics.buffer_underruns_count > 0) {
  if (metrics.buffer_underruns_average >= 0 &&
      metrics.buffer_underruns_count >= 0) {
    if (buffer_underruns_average < 0 || buffer_underruns_count < 0) {
      buffer_underruns_average = metrics.buffer_underruns_average;
      buffer_underruns_count = metrics.buffer_underruns_count;
    } else {
      buffer_underruns_average = combine_averages(
          metrics.buffer_underruns_average, metrics.buffer_underruns_count,
          buffer_underruns_average, buffer_underruns_count);
          buffer_underruns_average, buffer_underruns_count,
          metrics.buffer_underruns_average, metrics.buffer_underruns_count);
      buffer_underruns_count += metrics.buffer_underruns_count;
    }
  }