Merge remote-tracking branch 'origin/master' into master-cmake

Conflicts:
	components/raop/raop.c
	components/raop/rtp.c
	main/cmd_squeezelite.c
This commit is contained in:
Sebastien
2020-03-08 09:54:50 -04:00
48 changed files with 951 additions and 481 deletions

View File

@@ -38,6 +38,7 @@
#include <sys/stat.h>
#include <stdint.h>
#include <fcntl.h>
#include <assert.h>
#include "platform.h"
#include "rtp.h"
@@ -48,11 +49,10 @@
#ifdef WIN32
#include <openssl/aes.h>
#include "alac_wrapper.h"
#include <assert.h>
#define MSG_DONTWAIT 0
#else
#include "esp_pthread.h"
#include "esp_system.h"
#include "assert.h"
#include <mbedtls/version.h>
#include <mbedtls/aes.h>
#include "alac_wrapper.h"
@@ -268,25 +268,25 @@ rtp_resp_t rtp_init(struct in_addr host, int latency, char *aeskey, char *aesiv,
// create http port and start listening
resp.cport = ctx->rtp_sockets[CONTROL].lport;
resp.tport = ctx->rtp_sockets[TIMING].lport;
resp.aport = ctx->rtp_sockets[DATA].lport;
resp.tport = ctx->rtp_sockets[TIMING].lport;
resp.aport = ctx->rtp_sockets[DATA].lport;
ctx->running = true;
ctx->running = true;
#ifdef WIN32
pthread_create(&ctx->thread, NULL, rtp_thread_func, (void *) ctx);
#else
// xTaskCreate((TaskFunction_t) rtp_thread_func, "RTP_thread", RTP_TASK_SIZE, ctx, CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT + 1 , &ctx->thread);
ctx->xTaskBuffer = (StaticTask_t*) heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
pthread_create(&ctx->thread, NULL, rtp_thread_func, (void *) ctx);
#else
ctx->xTaskBuffer = (StaticTask_t*) heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
ctx->thread = xTaskCreateStatic( (TaskFunction_t) rtp_thread_func, "RTP_thread", RTP_STACK_SIZE, ctx,
CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT + 1, ctx->xStack, ctx->xTaskBuffer );
CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT + 1, ctx->xStack, ctx->xTaskBuffer );
#endif
// cleanup everything if we failed
if (!rc) {
LOG_ERROR("[%p]: cannot start RTP", ctx);
rtp_end(ctx);
ctx = NULL;
}
rtp_end(ctx);
ctx = NULL;
}
resp.ctx = ctx;
return resp;
@@ -328,7 +328,7 @@ void rtp_end(rtp_t *ctx)
fclose(ctx->rtpOUT);
#endif
}
/*---------------------------------------------------------------------------*/
bool rtp_flush(rtp_t *ctx, unsigned short seqno, unsigned int rtptime, bool exit_locked)
{
@@ -341,7 +341,7 @@ bool rtp_flush(rtp_t *ctx, unsigned short seqno, unsigned int rtptime)
} else {
pthread_mutex_lock(&ctx->ab_mutex);
buffer_reset(ctx->audio_buffer);
ctx->playing = false;
ctx->playing = false;
ctx->flush_seqno = seqno;
if (!exit_locked) pthread_mutex_unlock(&ctx->ab_mutex);
}
@@ -350,8 +350,13 @@ bool rtp_flush(rtp_t *ctx, unsigned short seqno, unsigned int rtptime)
return rc;
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void rtp_flush_release(rtp_t *ctx) {
pthread_mutex_unlock(&ctx->ab_mutex);
}
/*---------------------------------------------------------------------------*/
void rtp_record(rtp_t *ctx, unsigned short seqno, unsigned rtptime) {
ctx->record.seqno = seqno;
@@ -444,25 +449,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);
@@ -520,14 +523,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;
}
@@ -572,7 +582,7 @@ static void *rtp_thread_func(void *arg) {
ntp_sent = rtp_request_timing(ctx);
}
while (ctx->running) {
while (ctx->running) {
ssize_t plen;
char type;
socklen_t rtp_client_len = sizeof(struct sockaddr_in);
@@ -585,14 +595,18 @@ static void *rtp_thread_func(void *arg) {
if (select(sock + 1, &fds, NULL, NULL, &timeout) <= 0) continue;
for (i = 0; i < 3; i++)
for (i = 0; i < 3; i++)
if (FD_ISSET(ctx->rtp_sockets[i].sock, &fds)) idx = i;
plen = recvfrom(ctx->rtp_sockets[idx].sock, packet, MAX_PACKET, MSG_DONTWAIT, (struct sockaddr*) &ctx->rtp_host, &rtp_client_len);
if (!ntp_sent) {
LOG_WARN("[%p]: NTP request not send yet", ctx);
ntp_sent = rtp_request_timing(ctx);
ntp_sent = rtp_request_timing(ctx);
}
if (plen <= 0) {
LOG_WARN("Nothing received on a readable socket %d", plen);
continue;
}
@@ -638,7 +652,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);
@@ -711,6 +725,11 @@ static void *rtp_thread_func(void *arg) {
LOG_DEBUG("[%p]: Timing references local:%llu, remote:%llx (delta:%lld, sum:%lld, adjust:%lld, gaps:%d)",
ctx, ctx->timing.local, ctx->timing.remote);
break;
}
default: {
LOG_WARN("Unknown packet received %x", (int) type);
break;
}
@@ -752,7 +771,7 @@ static bool rtp_request_timing(rtp_t *ctx) {
// no address from sender, need to wait for 1st packet to be received
if (host.sin_addr.s_addr == INADDR_ANY) return false;
host.sin_port = htons(ctx->rtp_sockets[TIMING].rport);
if (sizeof(req) != sendto(ctx->rtp_sockets[TIMING].sock, req, sizeof(req), MSG_DONTWAIT, (struct sockaddr*) &host, sizeof(host))) {
@@ -778,7 +797,7 @@ static bool rtp_request_resend(rtp_t *ctx, seq_t first, seq_t last) {
*(u16_t*)(req+2) = htons(1); // our seqnum
*(u16_t*)(req+4) = htons(first); // missed seqnum
*(u16_t*)(req+6) = htons(last-first+1); // count
ctx->rtp_host.sin_port = htons(ctx->rtp_sockets[CONTROL].rport);
if (sizeof(req) != sendto(ctx->rtp_sockets[CONTROL].sock, req, sizeof(req), MSG_DONTWAIT, (struct sockaddr*) &ctx->rtp_host, sizeof(ctx->rtp_host))) {