OSDN Git Service

Fix A2dp encoder counter deviation.
authorDaren Liao <daren.liao@mediatek.com>
Fri, 20 Nov 2020 06:23:17 +0000 (14:23 +0800)
committerMyles Watson <mylesgw@google.com>
Fri, 22 Jan 2021 18:08:57 +0000 (18:08 +0000)
[Description]
Fix A2dp encoder counter deviation.

[Test Report]
Pass

Bug: 176783467
Test: Measure audio/video latency before and after 7 hours of playback
Change-Id: I6116ca81a223d305128f6c75f262375fed2f90bc

stack/a2dp/a2dp_aac_encoder.cc
stack/a2dp/a2dp_sbc_encoder.cc
stack/a2dp/a2dp_vendor_ldac_encoder.cc

index bd87b70..b0f3dcb 100644 (file)
@@ -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;
index 373aeba..aab5523 100644 (file)
@@ -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 =
index 0a1deb9..62d2d9e 100644 (file)
@@ -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;