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

Commit 7430f622 authored by Myles Watson's avatar Myles Watson Committed by Gerrit Code Review
Browse files

Merge "Fix A2dp encoder counter deviation."

parents d69ead3c 00409f08
Loading
Loading
Loading
Loading
+14 −27
Original line number Diff line number Diff line
@@ -56,9 +56,9 @@ typedef struct {
} tA2DP_AAC_ENCODER_PARAMS;

typedef struct {
  uint32_t counter;
  uint32_t bytes_per_tick;              // pcm bytes read each media task tick
  uint64_t last_frame_timestamp_100ns;  // values in 1/10 microseconds
  float counter;
  uint32_t bytes_per_tick; /* pcm bytes read each media task tick */
  uint64_t last_frame_us;
} tA2DP_AAC_FEEDING_STATE;

typedef struct {
@@ -517,7 +517,7 @@ void a2dp_aac_feeding_reset(void) {
}

void a2dp_aac_feeding_flush(void) {
  a2dp_aac_encoder_cb.aac_feeding_state.counter = 0;
  a2dp_aac_encoder_cb.aac_feeding_state.counter = 0.0f;
}

uint64_t a2dp_aac_get_encoder_interval_ms(void) {
@@ -555,29 +555,16 @@ static void a2dp_aac_get_num_frame_iteration(uint8_t* num_of_iterations,
      a2dp_aac_encoder_cb.feeding_params.bits_per_sample / 8;
  LOG_VERBOSE("%s: pcm_bytes_per_frame %u", __func__, pcm_bytes_per_frame);

  uint32_t hecto_ns_this_tick = a2dp_aac_encoder_interval_ms * 10000;
  uint64_t* last_100ns =
      &a2dp_aac_encoder_cb.aac_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_aac_encoder_cb.aac_feeding_state.bytes_per_tick *
      hecto_ns_this_tick / (a2dp_aac_encoder_interval_ms * 10000);
  a2dp_aac_encoder_cb.aac_feeding_state.counter += bytes_this_tick;
  // Without this erratum, there was a three microseocnd shift per tick which
  // would cause one frame mismatched after every 180 seconds
  uint32_t erratum_100ns =
      ceil(1.0f * bytes_this_tick * a2dp_aac_encoder_interval_ms * 10000 /
           a2dp_aac_encoder_cb.aac_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;
  }
  uint32_t us_this_tick = A2DP_AAC_ENCODER_INTERVAL_MS * 1000;
  uint64_t now_us = timestamp_us;
  if (a2dp_aac_encoder_cb.aac_feeding_state.last_frame_us != 0)
    us_this_tick =
        (now_us - a2dp_aac_encoder_cb.aac_feeding_state.last_frame_us);
  a2dp_aac_encoder_cb.aac_feeding_state.last_frame_us = now_us;

  a2dp_aac_encoder_cb.aac_feeding_state.counter +=
      (float)a2dp_aac_encoder_cb.aac_feeding_state.bytes_per_tick * us_this_tick /
      (A2DP_AAC_ENCODER_INTERVAL_MS * 1000);

  result = a2dp_aac_encoder_cb.aac_feeding_state.counter / pcm_bytes_per_frame;
  a2dp_aac_encoder_cb.aac_feeding_state.counter -= result * pcm_bytes_per_frame;
+13 −27
Original line number Diff line number Diff line
@@ -71,9 +71,9 @@ typedef struct {
  uint32_t aa_frame_counter;
  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_timestamp_100ns;  // values in 1/10 microseconds
  float counter;
  uint32_t bytes_per_tick; /* pcm bytes read each media task tick */
  uint64_t last_frame_us;
} tA2DP_SBC_FEEDING_STATE;

typedef struct {
@@ -389,7 +389,7 @@ void a2dp_sbc_feeding_reset(void) {
}

void a2dp_sbc_feeding_flush(void) {
  a2dp_sbc_encoder_cb.feeding_state.counter = 0;
  a2dp_sbc_encoder_cb.feeding_state.counter = 0.0f;
  a2dp_sbc_encoder_cb.feeding_state.aa_feed_residue = 0;
}

@@ -429,29 +429,15 @@ 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 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;
  }
  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 +=
      (float)a2dp_sbc_encoder_cb.feeding_state.bytes_per_tick * us_this_tick /
      (A2DP_SBC_ENCODER_INTERVAL_MS * 1000);

  /* Calculate the number of frames pending for this media tick */
  projected_nof =
+4 −4
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ typedef struct {
} tA2DP_LDAC_ENCODER_PARAMS;

typedef struct {
  uint32_t counter;
  float counter;
  uint32_t bytes_per_tick; /* pcm bytes read each media task tick */
  uint64_t last_frame_us;
} tA2DP_LDAC_FEEDING_STATE;
@@ -528,7 +528,7 @@ void a2dp_vendor_ldac_feeding_reset(void) {
}

void a2dp_vendor_ldac_feeding_flush(void) {
  a2dp_ldac_encoder_cb.ldac_feeding_state.counter = 0;
  a2dp_ldac_encoder_cb.ldac_feeding_state.counter = 0.0f;
}

uint64_t a2dp_vendor_ldac_get_encoder_interval_ms(void) {
@@ -587,8 +587,8 @@ static void a2dp_ldac_get_num_frame_iteration(uint8_t* num_of_iterations,
  a2dp_ldac_encoder_cb.ldac_feeding_state.last_frame_us = now_us;

  a2dp_ldac_encoder_cb.ldac_feeding_state.counter +=
      a2dp_ldac_encoder_cb.ldac_feeding_state.bytes_per_tick * (us_this_tick /
      (float) (A2DP_LDAC_ENCODER_INTERVAL_MS * 1000));
      (float)a2dp_ldac_encoder_cb.ldac_feeding_state.bytes_per_tick * us_this_tick /
      (A2DP_LDAC_ENCODER_INTERVAL_MS * 1000);

  result =
      a2dp_ldac_encoder_cb.ldac_feeding_state.counter / pcm_bytes_per_frame;