mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 12:37:01 +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)
|
struct in_addr peer; // IP of the iDevice (airplay sender)
|
||||||
bool running;
|
bool running;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
pthread_t thread, search_thread;
|
pthread_t thread;
|
||||||
#else
|
#else
|
||||||
TaskHandle_t thread, search_thread, joiner;
|
TaskHandle_t thread, joiner;
|
||||||
StaticTask_t *xTaskBuffer;
|
StaticTask_t *xTaskBuffer;
|
||||||
StackType_t xStack[RTSP_STACK_SIZE] __attribute__ ((aligned (4)));
|
StackType_t xStack[RTSP_STACK_SIZE] __attribute__ ((aligned (4)));
|
||||||
#endif
|
#endif
|
||||||
@@ -81,10 +81,11 @@ typedef struct raop_ctx_s {
|
|||||||
char DACPid[32], id[32];
|
char DACPid[32], id[32];
|
||||||
struct in_addr host;
|
struct in_addr host;
|
||||||
u16_t port;
|
u16_t port;
|
||||||
|
bool running;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
struct mDNShandle_s *handle;
|
struct mDNShandle_s *handle;
|
||||||
|
pthread_t thread;
|
||||||
#else
|
#else
|
||||||
bool running;
|
|
||||||
TaskHandle_t thread, joiner;
|
TaskHandle_t thread, joiner;
|
||||||
StaticTask_t *xTaskBuffer;
|
StaticTask_t *xTaskBuffer;
|
||||||
StackType_t xStack[SEARCH_STACK_SIZE] __attribute__ ((aligned (4)));;
|
StackType_t xStack[SEARCH_STACK_SIZE] __attribute__ ((aligned (4)));;
|
||||||
@@ -240,7 +241,7 @@ void raop_delete(struct raop_ctx_s *ctx) {
|
|||||||
|
|
||||||
rtp_end(ctx->rtp);
|
rtp_end(ctx->rtp);
|
||||||
|
|
||||||
shutdown(ctx->sock, SD_BOTH);
|
shutdown(ctx->sock, SD_BOTH);
|
||||||
closesocket(ctx->sock);
|
closesocket(ctx->sock);
|
||||||
|
|
||||||
// terminate search, but do not reclaim memory of pthread if never launched
|
// 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);
|
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, "DACP-ID")) != NULL) strcpy(ctx->active_remote.DACPid, buf);
|
||||||
if ((buf = kd_lookup(headers, "Active-Remote")) != NULL) strcpy(ctx->active_remote.id, 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")) {
|
} else if (!strcmp(method, "TEARDOWN")) {
|
||||||
|
|
||||||
rtp_end(ctx->rtp);
|
rtp_end(ctx->rtp);
|
||||||
|
|
||||||
ctx->rtp = NULL;
|
ctx->rtp = NULL;
|
||||||
|
|
||||||
// need to make sure no search is on-going and reclaim pthread memory
|
// 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);
|
LOG_INFO("[%p]: SET PARAMETER progress %d/%u %s", ctx, current, stop, p);
|
||||||
success = ctx->cmd_cb(RAOP_PROGRESS, max(current, 0), stop);
|
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")) {
|
} 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 = {
|
dmap_settings settings = {
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, on_dmap_string, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, on_dmap_string, NULL,
|
||||||
NULL
|
NULL
|
||||||
@@ -689,6 +690,10 @@ 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
|
// first stop RTP process
|
||||||
if (ctx->rtp) {
|
if (ctx->rtp) {
|
||||||
|
rtp_end(ctx->rtp);
|
||||||
|
ctx->rtp = NULL;
|
||||||
|
LOG_INFO("[%p]: RTP thread aborted", ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->active_remote.running) {
|
if (ctx->active_remote.running) {
|
||||||
#ifdef WIN32
|
#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
|
// need to make sure no search is on-going and reclaim task memory
|
||||||
ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
|
ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
|
||||||
ctx->active_remote.running = false;
|
ctx->active_remote.running = false;
|
||||||
|
|
||||||
xSemaphoreTake(ctx->active_remote.destroy_mutex, portMAX_DELAY);
|
xSemaphoreTake(ctx->active_remote.destroy_mutex, portMAX_DELAY);
|
||||||
vTaskDelete(ctx->active_remote.thread);
|
vTaskDelete(ctx->active_remote.thread);
|
||||||
|
vSemaphoreDelete(ctx->active_remote.thread);
|
||||||
|
|
||||||
heap_caps_free(ctx->active_remote.xTaskBuffer);
|
heap_caps_free(ctx->active_remote.xTaskBuffer);
|
||||||
#endif
|
#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);
|
abuf = ctx->audio_buffer + BUFIDX(seqno);
|
||||||
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)) {
|
||||||
|
seq_t i;
|
||||||
u32_t now;
|
u32_t now;
|
||||||
|
|
||||||
// newer than expected
|
// newer than expected
|
||||||
if (ctx->latency && seq_order(ctx->latency / ctx->frame_size, seqno - ctx->ab_write - 1)) {
|
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 (ctx->latency && seq_order(ctx->latency / ctx->frame_size, seqno - ctx->ab_read)) {
|
|
||||||
// if ab_read is lagging more than http latency, advance it
|
// need to request re-send and adjust timing of gaps
|
||||||
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;
|
|
||||||
rtp_request_resend(ctx, ctx->ab_write + 1, seqno-1);
|
rtp_request_resend(ctx, ctx->ab_write + 1, seqno-1);
|
||||||
for (now = gettime_ms(), i = ctx->ab_write + 1; seq_order(i, seqno); i++) {
|
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)].rtptime = rtptime - (seqno-i)*ctx->frame_size;
|
||||||
ctx->audio_buffer[BUFIDX(i)].last_resend = now;
|
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);
|
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) {
|
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++;
|
ctx->discarded++;
|
||||||
|
curframe->ready = 0;
|
||||||
} else if (playtime - now <= hold) {
|
} else if (playtime - now <= hold) {
|
||||||
if (curframe->ready) {
|
if (curframe->ready) {
|
||||||
ctx->data_cb((const u8_t*) curframe->data, curframe->len, playtime);
|
ctx->data_cb((const u8_t*) curframe->data, curframe->len, playtime);
|
||||||
curframe->ready = 0;
|
curframe->ready = 0;
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("[%p]: created zero frame (W:%hu R:%hu)", ctx, ctx->ab_write, ctx->ab_read);
|
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(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 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user