diff --git a/android/hal-audio.c b/android/hal-audio.c
index a261871..3ff3b9d 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
#define MAX_FRAMES_IN_PAYLOAD 15
+#define MAX_DELAY 100000 /* 100ms */
+
static const uint8_t a2dp_src_uuid[] = {
0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb };
uint16_t seq;
uint32_t samples;
struct timespec start;
+
+ bool resync;
};
static struct audio_endpoint audio_endpoints[MAX_AUDIO_ENDPOINTS];
return false;
ep->samples = 0;
+ ep->resync = false;
return true;
}
audio_sent = ep->samples * 1000000ll / out->cfg.rate;
audio_passed = timespec_diff_us(¤t, &ep->start);
- /* if we're ahead of stream then wait for next write point */
+ /* if we're ahead of stream then wait for next write point
+ * if we're lagging more than 100ms then stop writing and just
+ * skip data until we're back in sync
+ */
if (audio_sent > audio_passed) {
struct timespec anchor;
+ ep->resync = false;
+
timespec_add(&ep->start, audio_sent, &anchor);
while (true) {
return false;
}
}
- }
+ } else if (!ep->resync) {
+ uint64_t diff = audio_passed - audio_sent;
- /* wait some time for socket to be ready for write,
- * but we'll just skip writing data if timeout occurs
- */
- if (!wait_for_endpoint(ep, &do_write))
- return false;
+ if (diff > MAX_DELAY) {
+ warn("lag is %jums, resyncing", diff / 1000);
+ ep->resync = true;
+ }
+ }
- if (do_write)
- if (!write_to_endpoint(ep, written))
+ /* in resync mode we'll just drop mediapackets */
+ if (!ep->resync) {
+ /* wait some time for socket to be ready for write,
+ * but we'll just skip writing data if timeout occurs
+ */
+ if (!wait_for_endpoint(ep, &do_write))
return false;
+ if (do_write)
+ if (!write_to_endpoint(ep, written))
+ return false;
+ }
+
/* AudioFlinger provides 16bit PCM, so sample size is 2 bytes
* multiplied by number of channels. Number of channels is
* simply number of bits set in channels mask.