mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 12:37:01 +03:00
airplay buffer management correction
This commit is contained in:
@@ -413,6 +413,12 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(method, "OPTIONS")) {
|
if (!strcmp(method, "OPTIONS")) {
|
||||||
|
|
||||||
|
kd_add(resp, "Public", "ANNOUNCE, SETUP, RECORD, PAUSE, FLUSH, TEARDOWN, OPTIONS, GET_PARAMETER, SET_PARAMETER");
|
||||||
|
|
||||||
|
} else if (!strcmp(method, "ANNOUNCE")) {
|
||||||
|
char *padded, *p;
|
||||||
|
|
||||||
NFREE(ctx->rtsp.aeskey);
|
NFREE(ctx->rtsp.aeskey);
|
||||||
NFREE(ctx->rtsp.aesiv);
|
NFREE(ctx->rtsp.aesiv);
|
||||||
NFREE(ctx->rtsp.fmtp);
|
NFREE(ctx->rtsp.fmtp);
|
||||||
|
|||||||
@@ -211,9 +211,7 @@ rtp_resp_t rtp_init(struct in_addr host, int latency, char *aeskey, char *aesiv,
|
|||||||
ctx->rtp_host.sin_family = AF_INET;
|
ctx->rtp_host.sin_family = AF_INET;
|
||||||
ctx->rtp_host.sin_addr.s_addr = INADDR_ANY;
|
ctx->rtp_host.sin_addr.s_addr = INADDR_ANY;
|
||||||
pthread_mutex_init(&ctx->ab_mutex, 0);
|
pthread_mutex_init(&ctx->ab_mutex, 0);
|
||||||
ctx->flush_seqno = -1;
|
ctx->flush_seqno = -1;
|
||||||
ctx->latency = latency;
|
|
||||||
|
|
||||||
ctx->latency = latency;
|
ctx->latency = latency;
|
||||||
ctx->ab_read = ctx->ab_write;
|
ctx->ab_read = ctx->ab_write;
|
||||||
|
|
||||||
@@ -413,7 +411,7 @@ static void buffer_put_packet(rtp_t *ctx, seq_t seqno, unsigned rtptime, bool fi
|
|||||||
pthread_mutex_unlock(&ctx->ab_mutex);
|
pthread_mutex_unlock(&ctx->ab_mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seqno == (u16_t) (ctx->ab_write+1)) {
|
if (seqno == (u16_t) (ctx->ab_write+1)) {
|
||||||
// expected packet
|
// expected packet
|
||||||
@@ -421,20 +419,20 @@ static void buffer_put_packet(rtp_t *ctx, seq_t seqno, unsigned rtptime, bool fi
|
|||||||
ctx->ab_write = seqno;
|
ctx->ab_write = seqno;
|
||||||
LOG_SDEBUG("packet expected seqno:%hu rtptime:%u (W:%hu R:%hu)", seqno, rtptime, ctx->ab_write, ctx->ab_read);
|
LOG_SDEBUG("packet expected seqno:%hu rtptime:%u (W:%hu R:%hu)", seqno, rtptime, ctx->ab_write, ctx->ab_read);
|
||||||
|
|
||||||
} else if (seq_order(ctx->ab_write, seqno)) {
|
} else if (seq_order(ctx->ab_write, seqno)) {
|
||||||
// newer than expected
|
// newer than expected
|
||||||
if (seqno - ctx->ab_write - 1 > ctx->latency / ctx->frame_size) {
|
if (ctx->latency && seq_order(ctx->latency / ctx->frame_size, seqno - ctx->ab_write - 1)) {
|
||||||
// only get rtp latency-1 frames back (last one is seqno)
|
// only get rtp latency-1 frames back (last one is seqno)
|
||||||
LOG_WARN("[%p] too many missing frames %hu seq: %hu, (W:%hu R:%hu)", ctx, seqno - ctx->ab_write - 1, seqno, ctx->ab_write, ctx->ab_read);
|
LOG_WARN("[%p] too many missing frames %hu seq: %hu, (W:%hu R:%hu)", ctx, seqno - ctx->ab_write - 1, seqno, ctx->ab_write, ctx->ab_read);
|
||||||
ctx->ab_write = seqno - ctx->latency / ctx->frame_size;
|
ctx->ab_write = seqno - ctx->latency / ctx->frame_size;
|
||||||
}
|
}
|
||||||
if (seqno - ctx->ab_read + 1 > ctx->latency / ctx->frame_size) {
|
if (ctx->latency && seq_order(ctx->latency / ctx->frame_size, seqno - ctx->ab_read)) {
|
||||||
// if ab_read is lagging more than http latency, advance it
|
// if ab_read is lagging more than http latency, advance it
|
||||||
LOG_WARN("[%p] on hold for too long %hu (W:%hu R:%hu)", ctx, seqno - ctx->ab_read + 1, ctx->ab_write, ctx->ab_read);
|
LOG_WARN("[%p] on hold for too long %hu (W:%hu R:%hu)", ctx, seqno - ctx->ab_read + 1, ctx->ab_write, ctx->ab_read);
|
||||||
ctx->ab_read = seqno - ctx->latency / ctx->frame_size + 1;
|
ctx->ab_read = seqno - ctx->latency / ctx->frame_size + 1;
|
||||||
}
|
}
|
||||||
if (rtp_request_resend(ctx, ctx->ab_write + 1, seqno-1)) {
|
if (rtp_request_resend(ctx, ctx->ab_write + 1, seqno-1)) {
|
||||||
seq_t i;
|
seq_t i;
|
||||||
u32_t now = gettime_ms();
|
u32_t now = gettime_ms();
|
||||||
for (i = ctx->ab_write + 1; seq_order(i, seqno); i++) {
|
for (i = ctx->ab_write + 1; seq_order(i, seqno); i++) {
|
||||||
ctx->audio_buffer[BUFIDX(i)].rtptime = rtptime - (seqno-i)*ctx->frame_size;
|
ctx->audio_buffer[BUFIDX(i)].rtptime = rtptime - (seqno-i)*ctx->frame_size;
|
||||||
@@ -453,7 +451,7 @@ static void buffer_put_packet(rtp_t *ctx, seq_t seqno, unsigned rtptime, bool fi
|
|||||||
// too late
|
// too late
|
||||||
LOG_DEBUG("[%p]: packet too late seqno:%hu rtptime:%u (W:%hu R:%hu)", ctx, seqno, rtptime, ctx->ab_write, ctx->ab_read);
|
LOG_DEBUG("[%p]: packet too late seqno:%hu rtptime:%u (W:%hu R:%hu)", ctx, seqno, rtptime, ctx->ab_write, ctx->ab_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->in_frames++ > 1000) {
|
if (ctx->in_frames++ > 1000) {
|
||||||
LOG_INFO("[%p]: fill [level:%hu rec:%u] [W:%hu R:%hu]", ctx, ctx->ab_write - ctx->ab_read, ctx->resent_rec, ctx->ab_write, ctx->ab_read);
|
LOG_INFO("[%p]: fill [level:%hu rec:%u] [W:%hu R:%hu]", ctx, ctx->ab_write - ctx->ab_read, ctx->resent_rec, ctx->ab_write, ctx->ab_read);
|
||||||
ctx->in_frames = 0;
|
ctx->in_frames = 0;
|
||||||
@@ -496,6 +494,27 @@ static void buffer_push_packet(rtp_t *ctx) {
|
|||||||
|
|
||||||
if (now > playtime) {
|
if (now > playtime) {
|
||||||
LOG_DEBUG("[%p]: discarded frame now:%u missed by:%d (W:%hu R:%hu)", ctx, now, now - playtime, ctx->ab_write, ctx->ab_read);
|
LOG_DEBUG("[%p]: discarded frame now:%u missed by:%d (W:%hu R:%hu)", ctx, now, now - playtime, ctx->ab_write, ctx->ab_read);
|
||||||
|
ctx->discarded++;
|
||||||
|
} else if (curframe->ready) {
|
||||||
|
/*
|
||||||
|
// some dirty code to see if the click problem comes from i2s stage or decoder stage
|
||||||
|
static s16_t sin_data[200];
|
||||||
|
static bool gen = false;
|
||||||
|
|
||||||
|
if (!gen) {
|
||||||
|
for (i = 0; i < 200; i++) sin_data[i] = 1024 * sin((2*3.14159*220.5*i)/44100.);
|
||||||
|
gen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int c = 0;
|
||||||
|
int cnt = 0;
|
||||||
|
s16_t *p = (s16_t*) curframe->data;
|
||||||
|
|
||||||
|
while (cnt++ < 352) {
|
||||||
|
*p = sin_data[c++ % 200];
|
||||||
|
*(p+1) = *p;
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
curframe->len = 1408;
|
curframe->len = 1408;
|
||||||
*/
|
*/
|
||||||
ctx->data_cb((const u8_t*) curframe->data, curframe->len, playtime);
|
ctx->data_cb((const u8_t*) curframe->data, curframe->len, playtime);
|
||||||
@@ -507,8 +526,7 @@ static void buffer_push_packet(rtp_t *ctx) {
|
|||||||
} else break;
|
} else break;
|
||||||
|
|
||||||
ctx->ab_read++;
|
ctx->ab_read++;
|
||||||
ctx->out_frames++;
|
ctx->out_frames++;
|
||||||
|
|
||||||
|
|
||||||
} while (seq_order(ctx->ab_read, ctx->ab_write));
|
} while (seq_order(ctx->ab_read, ctx->ab_write));
|
||||||
|
|
||||||
@@ -520,7 +538,7 @@ static void buffer_push_packet(rtp_t *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG_SDEBUG("playtime %u %d [W:%hu R:%hu] %d", playtime, playtime - now, ctx->ab_write, ctx->ab_read, curframe->ready);
|
LOG_SDEBUG("playtime %u %d [W:%hu R:%hu] %d", playtime, playtime - now, ctx->ab_write, ctx->ab_read, curframe->ready);
|
||||||
|
|
||||||
// each missing packet will be requested up to (latency_frames / 16) times
|
// each missing packet will be requested up to (latency_frames / 16) times
|
||||||
for (i = 0; seq_order(ctx->ab_read + i, ctx->ab_write); i += 16) {
|
for (i = 0; seq_order(ctx->ab_read + i, ctx->ab_write); i += 16) {
|
||||||
abuf_t *frame = ctx->audio_buffer + BUFIDX(ctx->ab_read + i);
|
abuf_t *frame = ctx->audio_buffer + BUFIDX(ctx->ab_read + i);
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ void raop_sink_cmd_handler(raop_event_t event, void *param)
|
|||||||
error = (raop_sync.playtime - now) - ms;
|
error = (raop_sync.playtime - now) - ms;
|
||||||
LOG_INFO("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, error);
|
LOG_INFO("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, error);
|
||||||
LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process);
|
LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process);
|
||||||
|
//break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error < -10 && raop_sync.error < -10) {
|
if (error < -10 && raop_sync.error < -10) {
|
||||||
|
|||||||
Reference in New Issue
Block a user