From 604bf450dc200ee15a8cb1158aa8130caa5b9e2e Mon Sep 17 00:00:00 2001 From: Martin Blanchard Date: Sun, 6 Nov 2016 12:54:01 -0600 Subject: [PATCH] raop: Do not send audio before RECORD response This patch prevents audio packets to be sent before the server respond to the RECORD command. --- src/modules/raop/module-raop-sink.c | 6 +++--- src/modules/raop/raop_client.c | 25 ++++++++++++++++++++++++- src/modules/raop/raop_client.h | 1 + 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/modules/raop/module-raop-sink.c b/src/modules/raop/module-raop-sink.c index ad19cadc3..a8a466d87 100644 --- a/src/modules/raop/module-raop-sink.c +++ b/src/modules/raop/module-raop-sink.c @@ -310,7 +310,7 @@ static int udp_sink_process_msg(pa_msgobject *o, int code, void *data, int64_t o pa_log_debug("RAOP: SUSPENDED"); pa_smoother_pause(u->smoother, pa_rtclock_now()); - if (pa_raop_client_udp_can_stream(u->raop)) { + if (pa_raop_client_udp_is_alive(u->raop)) { /* Issue a TEARDOWN if we are still connected. */ pa_raop_client_teardown(u->raop); } @@ -756,10 +756,10 @@ static void udp_thread_func(struct userdata *u) { continue; } - if (!pa_raop_client_udp_can_stream(u->raop)) - continue; if (u->sink->thread_info.state != PA_SINK_RUNNING) continue; + if (!pa_raop_client_udp_can_stream(u->raop)) + continue; if (u->encoded_memchunk.length <= 0) { if (u->encoded_memchunk.memblock != NULL) diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c index 9c31162e1..d17cc44ac 100644 --- a/src/modules/raop/raop_client.c +++ b/src/modules/raop/raop_client.c @@ -146,6 +146,8 @@ struct pa_raop_client { uint32_t udp_ssrc; + bool is_recording; + bool udp_first_packet; uint32_t udp_sync_interval; uint32_t udp_sync_count; @@ -950,6 +952,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist pa_log_debug("RAOP: RECORD"); + c->is_recording = true; + alt = pa_xstrdup(pa_headerlist_gets(headers, "Audio-Latency")); /* Generate a random synchronization source identifier from this session. */ pa_random(&rand, sizeof(rand)); @@ -976,6 +980,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist case STATE_FLUSH: { pa_log_debug("RAOP: FLUSHED"); + c->is_recording = false; + break; } @@ -984,6 +990,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist pa_assert(c->udp_disconnected_callback); pa_assert(c->rtsp); + c->is_recording = false; + pa_rtsp_disconnect(c->rtsp); if (c->udp_stream_fd > 0) { @@ -1084,6 +1092,8 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const char *host, pa_raop_prot else c->port = DEFAULT_RAOP_PORT; + c->is_recording = false; + c->udp_first_packet = true; ss = core->default_sample_spec; @@ -1151,6 +1161,8 @@ int pa_raop_client_connect(pa_raop_client *c) { else pa_rtsp_set_callback(c->rtsp, udp_rtsp_cb, c); + c->is_recording = false; + return pa_rtsp_connect(c->rtsp); } @@ -1177,7 +1189,7 @@ int pa_raop_client_teardown(pa_raop_client *c) { return rv; } -int pa_raop_client_udp_can_stream(pa_raop_client *c) { +int pa_raop_client_udp_is_alive(pa_raop_client *c) { int rv = 0; pa_assert(c); @@ -1188,6 +1200,17 @@ int pa_raop_client_udp_can_stream(pa_raop_client *c) { return rv; } +int pa_raop_client_udp_can_stream(pa_raop_client *c) { + int rv = 0; + + pa_assert(c); + + if (c->is_recording && c->udp_stream_fd > 0) + rv = 1; + + return rv; +} + int pa_raop_client_udp_handle_timing_packet(pa_raop_client *c, const uint8_t packet[], ssize_t size) { const uint32_t * data = NULL; uint8_t payload = 0; diff --git a/src/modules/raop/raop_client.h b/src/modules/raop/raop_client.h index 578e9d008..6ab6d325c 100644 --- a/src/modules/raop/raop_client.h +++ b/src/modules/raop/raop_client.h @@ -41,6 +41,7 @@ int pa_raop_client_connect(pa_raop_client *c); int pa_raop_client_flush(pa_raop_client *c); int pa_raop_client_teardown(pa_raop_client *c); +int pa_raop_client_udp_is_alive(pa_raop_client *c); int pa_raop_client_udp_can_stream(pa_raop_client *c); void pa_raop_client_set_encryption(pa_raop_client *c, int encryption);