mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-06 19:47:02 +03:00
Ancient AirPlay issue fixed - release
This commit is contained in:
@@ -57,9 +57,9 @@ typedef struct raop_ctx_s {
|
||||
struct in_addr peer; // IP of the iDevice (airplay sender)
|
||||
bool running;
|
||||
#ifdef WIN32
|
||||
pthread_t thread, search_thread;
|
||||
pthread_t thread;
|
||||
#else
|
||||
TaskHandle_t thread, search_thread, joiner;
|
||||
TaskHandle_t thread, joiner;
|
||||
StaticTask_t *xTaskBuffer;
|
||||
StackType_t xStack[RTSP_STACK_SIZE] __attribute__ ((aligned (4)));
|
||||
#endif
|
||||
@@ -81,10 +81,11 @@ typedef struct raop_ctx_s {
|
||||
char DACPid[32], id[32];
|
||||
struct in_addr host;
|
||||
u16_t port;
|
||||
bool running;
|
||||
#ifdef WIN32
|
||||
struct mDNShandle_s *handle;
|
||||
pthread_t thread;
|
||||
#else
|
||||
bool running;
|
||||
TaskHandle_t thread, joiner;
|
||||
StaticTask_t *xTaskBuffer;
|
||||
StackType_t xStack[SEARCH_STACK_SIZE] __attribute__ ((aligned (4)));;
|
||||
@@ -218,7 +219,7 @@ void raop_delete(struct raop_ctx_s *ctx) {
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void raop_delete(struct raop_ctx_s *ctx) {
|
||||
void raop_delete(struct raop_ctx_s *ctx) {
|
||||
#ifdef WIN32
|
||||
int sock;
|
||||
struct sockaddr addr;
|
||||
@@ -240,7 +241,7 @@ void raop_delete(struct raop_ctx_s *ctx) {
|
||||
|
||||
rtp_end(ctx->rtp);
|
||||
|
||||
shutdown(ctx->sock, SD_BOTH);
|
||||
shutdown(ctx->sock, SD_BOTH);
|
||||
closesocket(ctx->sock);
|
||||
|
||||
// terminate search, but do not reclaim memory of pthread if never launched
|
||||
@@ -515,7 +516,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
|
||||
NFREE(p);
|
||||
}
|
||||
|
||||
// on announce, search remote
|
||||
// on announce, search remote
|
||||
if ((buf = kd_lookup(headers, "DACP-ID")) != NULL) strcpy(ctx->active_remote.DACPid, buf);
|
||||
if ((buf = kd_lookup(headers, "Active-Remote")) != NULL) strcpy(ctx->active_remote.id, buf);
|
||||
|
||||
@@ -592,7 +593,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
|
||||
} else if (!strcmp(method, "TEARDOWN")) {
|
||||
|
||||
rtp_end(ctx->rtp);
|
||||
|
||||
|
||||
ctx->rtp = NULL;
|
||||
|
||||
// need to make sure no search is on-going and reclaim pthread memory
|
||||
@@ -640,7 +641,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
|
||||
LOG_INFO("[%p]: SET PARAMETER progress %d/%u %s", ctx, current, stop, p);
|
||||
success = ctx->cmd_cb(RAOP_PROGRESS, max(current, 0), stop);
|
||||
} else if (body && ((p = kd_lookup(headers, "Content-Type")) != NULL) && !strcasecmp(p, "application/x-dmap-tagged")) {
|
||||
struct metadata_s metadata;
|
||||
struct metadata_s metadata;
|
||||
dmap_settings settings = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, on_dmap_string, NULL,
|
||||
NULL
|
||||
@@ -686,9 +687,13 @@ void abort_rtsp(raop_ctx_t *ctx) {
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void abort_rtsp(raop_ctx_t *ctx) {
|
||||
void abort_rtsp(raop_ctx_t *ctx) {
|
||||
// first stop RTP process
|
||||
if (ctx->rtp) {
|
||||
rtp_end(ctx->rtp);
|
||||
ctx->rtp = NULL;
|
||||
LOG_INFO("[%p]: RTP thread aborted", ctx);
|
||||
}
|
||||
|
||||
if (ctx->active_remote.running) {
|
||||
#ifdef WIN32
|
||||
@@ -698,8 +703,10 @@ void abort_rtsp(raop_ctx_t *ctx) {
|
||||
// need to make sure no search is on-going and reclaim task memory
|
||||
ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
|
||||
ctx->active_remote.running = false;
|
||||
|
||||
xSemaphoreTake(ctx->active_remote.destroy_mutex, portMAX_DELAY);
|
||||
vTaskDelete(ctx->active_remote.thread);
|
||||
vSemaphoreDelete(ctx->active_remote.thread);
|
||||
|
||||
heap_caps_free(ctx->active_remote.xTaskBuffer);
|
||||
#endif
|
||||
|
||||
@@ -443,25 +443,23 @@ static void buffer_put_packet(rtp_t *ctx, seq_t seqno, unsigned rtptime, bool fi
|
||||
abuf = ctx->audio_buffer + BUFIDX(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);
|
||||
|
||||
} else if (seq_order(ctx->ab_write, seqno)) {
|
||||
seq_t i;
|
||||
u32_t now;
|
||||
|
||||
// newer than expected
|
||||
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)
|
||||
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;
|
||||
}
|
||||
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
|
||||
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;
|
||||
}
|
||||
if (rtp_request_resend(ctx, ctx->ab_write + 1, seqno-1)) {
|
||||
seq_t i;
|
||||
u32_t now = gettime_ms();
|
||||
for (i = ctx->ab_write + 1; seq_order(i, seqno); i++) {
|
||||
ctx->audio_buffer[BUFIDX(i)].rtptime = rtptime - (seqno-i)*ctx->frame_size;
|
||||
ctx->ab_write = seqno - ctx->latency / ctx->frame_size;
|
||||
}
|
||||
|
||||
// need to request re-send and adjust timing of gaps
|
||||
rtp_request_resend(ctx, ctx->ab_write + 1, seqno-1);
|
||||
for (now = gettime_ms(), 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)].last_resend = now;
|
||||
}
|
||||
|
||||
LOG_DEBUG("[%p]: packet newer seqno:%hu rtptime:%u (W:%hu R:%hu)", ctx, seqno, rtptime, ctx->ab_write, ctx->ab_read);
|
||||
@@ -519,14 +517,21 @@ static void buffer_push_packet(rtp_t *ctx) {
|
||||
|
||||
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);
|
||||
ctx->discarded++;
|
||||
curframe->ready = 0;
|
||||
} else if (playtime - now <= hold) {
|
||||
if (curframe->ready) {
|
||||
ctx->data_cb((const u8_t*) curframe->data, curframe->len, playtime);
|
||||
curframe->ready = 0;
|
||||
} else {
|
||||
LOG_DEBUG("[%p]: created zero frame (W:%hu R:%hu)", ctx, ctx->ab_write, ctx->ab_read);
|
||||
ctx->data_cb(silence_frame, ctx->frame_size * 4, playtime);
|
||||
ctx->silent_frames++;
|
||||
}
|
||||
} else if (curframe->ready) {
|
||||
ctx->data_cb((const u8_t*) curframe->data, curframe->len, playtime);
|
||||
curframe->ready = 0;
|
||||
} else if (playtime - now <= hold) {
|
||||
LOG_DEBUG("[%p]: created zero frame (W:%hu R:%hu)", ctx, ctx->ab_write, ctx->ab_read);
|
||||
ctx->data_cb(silence_frame, ctx->frame_size * 4, playtime);
|
||||
ctx->data_cb((const u8_t*) curframe->data, curframe->len, playtime);
|
||||
curframe->ready = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -637,7 +642,7 @@ static void *rtp_thread_func(void *arg) {
|
||||
case 0x54: {
|
||||
u32_t rtp_now_latency = ntohl(*(u32_t*)(pktp+4));
|
||||
u64_t remote = (((u64_t) ntohl(*(u32_t*)(pktp+8))) << 32) + ntohl(*(u32_t*)(pktp+12));
|
||||
u32_t rtp_now = ntohl(*(u32_t*)(pktp+16));
|
||||
u32_t rtp_now = ntohl(*(u32_t*)(pktp+16));
|
||||
u16_t flags = ntohs(*(u16_t*)(pktp+2));
|
||||
u32_t remote_gap = NTP2MS(remote - ctx->timing.remote);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user