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

Commit bb6d57f3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "A2DP: SBC encoding counter errata"

parents 3948f16c c5eb109a
Loading
Loading
Loading
Loading
+26 −11
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "a2dp_sbc_encoder.h"

#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <string.h>

@@ -71,8 +72,8 @@ typedef struct {
  int32_t aa_feed_counter;
  int32_t aa_feed_residue;
  uint32_t counter;
  uint32_t bytes_per_tick; /* pcm bytes read each media task tick */
  uint64_t last_frame_us;
  uint32_t bytes_per_tick;              // pcm bytes read each media task tick
  uint64_t last_frame_timestamp_100ns;  // values in 1/10 microseconds
} tA2DP_SBC_FEEDING_STATE;

typedef struct {
@@ -429,15 +430,29 @@ static void a2dp_sbc_get_num_frame_iteration(uint8_t* num_of_iterations,
      a2dp_sbc_encoder_cb.feeding_params.bits_per_sample / 8;
  LOG_VERBOSE("%s: pcm_bytes_per_frame %u", __func__, pcm_bytes_per_frame);

  uint32_t us_this_tick = A2DP_SBC_ENCODER_INTERVAL_MS * 1000;
  uint64_t now_us = timestamp_us;
  if (a2dp_sbc_encoder_cb.feeding_state.last_frame_us != 0)
    us_this_tick = (now_us - a2dp_sbc_encoder_cb.feeding_state.last_frame_us);
  a2dp_sbc_encoder_cb.feeding_state.last_frame_us = now_us;

  a2dp_sbc_encoder_cb.feeding_state.counter +=
      a2dp_sbc_encoder_cb.feeding_state.bytes_per_tick * us_this_tick /
      (A2DP_SBC_ENCODER_INTERVAL_MS * 1000);
  uint32_t hecto_ns_this_tick = A2DP_SBC_ENCODER_INTERVAL_MS * 10000;
  uint64_t* last_100ns =
      &a2dp_sbc_encoder_cb.feeding_state.last_frame_timestamp_100ns;
  uint64_t now_100ns = timestamp_us * 10;
  if (*last_100ns != 0) {
    hecto_ns_this_tick = (now_100ns - *last_100ns);
  }
  *last_100ns = now_100ns;

  uint32_t bytes_this_tick = a2dp_sbc_encoder_cb.feeding_state.bytes_per_tick *
                             hecto_ns_this_tick /
                             (A2DP_SBC_ENCODER_INTERVAL_MS * 10000);
  a2dp_sbc_encoder_cb.feeding_state.counter += bytes_this_tick;
  // Without this erratum, there was a three microseocnd shift per tick which
  // would cause one SBC frame mismatched after every 20 seconds
  uint32_t erratum_100ns =
      ceil(1.0f * A2DP_SBC_ENCODER_INTERVAL_MS * 10000 * bytes_this_tick /
           a2dp_sbc_encoder_cb.feeding_state.bytes_per_tick);
  if (erratum_100ns < hecto_ns_this_tick) {
    LOG_VERBOSE("%s: hecto_ns_this_tick=%d, bytes=%d, erratum_100ns=%d",
                __func__, hecto_ns_this_tick, bytes_this_tick, erratum_100ns);
    *last_100ns -= hecto_ns_this_tick - erratum_100ns;
  }

  /* Calculate the number of frames pending for this media tick */
  projected_nof =