From: Martin Blanchard <tchaik@xxxxxxx> 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 1eadde2..8deb139 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 1c6c49e..11c871d 100644 --- a/src/modules/raop/raop_client.c +++ b/src/modules/raop/raop_client.c @@ -131,6 +131,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; @@ -932,6 +934,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)); @@ -958,6 +962,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; } @@ -966,6 +972,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) { @@ -1066,6 +1074,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; @@ -1133,6 +1143,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); } @@ -1159,7 +1171,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); @@ -1170,6 +1182,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 578e9d0..6ab6d32 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); -- 2.5.0