浏览代码

Ancient AirPlay issue fixed - release

philippe44 5 年之前
父节点
当前提交
b2d90d36c1
共有 2 个文件被更改,包括 39 次插入27 次删除
  1. 16 9
      components/raop/raop.c
  2. 23 18
      components/raop/rtp.c

+ 16 - 9
components/raop/raop.c

@@ -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) {
 	struct sockaddr addr;
 	socklen_t nlen = sizeof(struct sockaddr);
 #endif
-	
+
 	if (!ctx) return;
 
 #ifdef WIN32
@@ -240,7 +241,7 @@ void raop_delete(struct raop_ctx_s *ctx) {
 	// terminate search, but do not reclaim memory of pthread if never launched
 	if (ctx->active_remote.handle) {
 		close_mDNS(ctx->active_remote.handle);
-		pthread_join(ctx->search_thread, NULL);
+		pthread_join(ctx->active_remote.thread, NULL);
 	}
 
 	// stop broadcasting devices
@@ -515,7 +516,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
 
 #ifdef WIN32	
 		ctx->active_remote.handle = init_mDNS(false, ctx->host);
-		pthread_create(&ctx->search_thread, NULL, &search_remote, ctx);
+		pthread_create(&ctx->active_remote.thread, NULL, &search_remote, ctx);
 #else
 		ctx->active_remote.running = true;
 		ctx->active_remote.destroy_mutex = xSemaphoreCreateMutex();		
@@ -592,7 +593,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
 		// need to make sure no search is on-going and reclaim pthread memory
 #ifdef WIN32
 		if (ctx->active_remote.handle) close_mDNS(ctx->active_remote.handle);
-		pthread_join(ctx->search_thread, NULL);
+		pthread_join(ctx->active_remote.thread, NULL);
 #else
 		ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
 		ctx->active_remote.running = false;
@@ -640,7 +641,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
 				NULL
 			};
 
-			LOG_INFO("[%p]: received metadata");
+			LOG_INFO("[%p]: received metadata", ctx);
 			settings.ctx = &metadata;
 			memset(&metadata, 0, sizeof(struct metadata_s));
 			if (!dmap_parse(&settings, body, len)) {
@@ -686,9 +687,13 @@ void abort_rtsp(raop_ctx_t *ctx) {
 		rtp_end(ctx->rtp);
 		ctx->rtp = NULL;
 		LOG_INFO("[%p]: RTP thread aborted", ctx);
-	}	
+	}
 
 	if (ctx->active_remote.running) {
+#ifdef WIN32
+		pthread_join(ctx->active_remote.thread, NULL);
+		close_mDNS(ctx->active_remote.handle);
+#else
 		// need to make sure no search is on-going and reclaim task memory
 		ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
 		ctx->active_remote.running = false;
@@ -698,8 +703,10 @@ void abort_rtsp(raop_ctx_t *ctx) {
 		vSemaphoreDelete(ctx->active_remote.thread);
 
 		heap_caps_free(ctx->active_remote.xTaskBuffer);
+#endif
 		memset(&ctx->active_remote, 0, sizeof(ctx->active_remote));
 
+
 		LOG_INFO("[%p]: Remote search thread aborted", ctx);
 	}	
 

+ 23 - 18
components/raop/rtp.c

@@ -443,25 +443,23 @@ static void buffer_put_packet(rtp_t *ctx, seq_t seqno, unsigned rtptime, bool fi
 		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->audio_buffer[BUFIDX(i)].last_resend = now;
-			}
+
+		// 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);
 		abuf = ctx->audio_buffer + BUFIDX(seqno);
 		ctx->ab_write = seqno;
@@ -519,14 +517,21 @@ static void buffer_push_packet(rtp_t *ctx) {
 			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->silent_frames++;
-		} else break;
+		} else {
+			break;
+		}
 
 		ctx->ab_read++;
 		ctx->out_frames++;
@@ -637,7 +642,7 @@ static void *rtp_thread_func(void *arg) {
 				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);
-				
+
 				// something is wrong and if we are supposed to be NTP synced, better ask for re-sync
 				if (remote_gap > 10000) {
 					if (ctx->synchro.status & NTP_SYNC) rtp_request_timing(ctx);