From 060a0abc003fc893346905d5300b597d1b57034a Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Sat, 13 Dec 2025 12:30:20 -0500 Subject: [PATCH] fix timing issue when -nohold switches to new client fixes #481 --- lib/http_handlers.h | 2 +- lib/raop.c | 8 ++++---- lib/raop.h | 2 +- lib/raop_handlers.h | 4 ++-- lib/raop_rtp_mirror.c | 2 +- uxplay.cpp | 24 +++++++++++++++++++++--- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/http_handlers.h b/lib/http_handlers.h index b06f677..fd54ebe 100644 --- a/lib/http_handlers.h +++ b/lib/http_handlers.h @@ -356,7 +356,7 @@ http_handler_playback_info(raop_conn_t *conn, http_request_t *request, http_resp logger_log(conn->raop->logger, LOGGER_DEBUG, "playback_info not available (finishing)"); //httpd_remove_known_connections(conn->raop->httpd); http_response_set_disconnect(response,1); - conn->raop->callbacks.video_reset(conn->raop->callbacks.cls, true); + conn->raop->callbacks.video_reset(conn->raop->callbacks.cls, true, false); return; } else if (playback_info.position == -1.0) { logger_log(conn->raop->logger, LOGGER_DEBUG, "playback_info not available"); diff --git a/lib/raop.c b/lib/raop.c index f65938d..c5ea215 100644 --- a/lib/raop.c +++ b/lib/raop.c @@ -244,11 +244,11 @@ conn_request(void *ptr, http_request_t *request, http_response_t **response) { char ipaddr[40] = { '\0' }; utils_ipaddress_to_string(conn->remotelen, conn->remote, conn->zone_id, ipaddr, (int) (sizeof(ipaddr))); if (httpd_nohold(conn->raop->httpd)) { - logger_log(conn->raop->logger, LOGGER_INFO, "\"nohold\" feature: switch to new connection request from %s", ipaddr); - if (conn->raop->callbacks.video_reset) { - conn->raop->callbacks.video_reset(conn->raop->callbacks.cls, false); - } + logger_log(conn->raop->logger, LOGGER_INFO, "*****\"nohold\" feature: switch to new connection request from %s", ipaddr); httpd_remove_known_connections(conn->raop->httpd); + if (conn->raop->callbacks.video_reset) { + conn->raop->callbacks.video_reset(conn->raop->callbacks.cls, false, true); + } } else { logger_log(conn->raop->logger, LOGGER_WARNING, "rejecting new connection request from %s", ipaddr); *response = http_response_create(); diff --git a/lib/raop.h b/lib/raop.h index 42a111a..915e9f2 100644 --- a/lib/raop.h +++ b/lib/raop.h @@ -67,7 +67,7 @@ struct raop_callbacks_s { void (*video_resume)(void *cls); void (*conn_feedback) (void *cls); void (*conn_reset) (void *cls, int reason); - void (*video_reset) (void *cls, bool hls_shutdown); + void (*video_reset) (void *cls, bool hls_shutdown, bool nohold); /* Optional but recommended callback functions (probably not optional, check this)*/ diff --git a/lib/raop_handlers.h b/lib/raop_handlers.h index 054f638..8ff1dda 100644 --- a/lib/raop_handlers.h +++ b/lib/raop_handlers.h @@ -1265,7 +1265,7 @@ raop_handler_teardown(raop_conn_t *conn, } } } else if (teardown_110) { - conn->raop->callbacks.video_reset(conn->raop->callbacks.cls, false); + conn->raop->callbacks.video_reset(conn->raop->callbacks.cls, false, false); if (conn->raop_rtp_mirror) { /* Stop our video RTP session */ raop_rtp_mirror_stop(conn->raop_rtp_mirror); @@ -1283,7 +1283,7 @@ raop_handler_teardown(raop_conn_t *conn, /* shut down any HLS connections */ int hls_count = httpd_count_connection_type(conn->raop->httpd, CONNECTION_TYPE_HLS); if (hls_count) { - conn->raop->callbacks.video_reset(conn->raop->callbacks.cls, true); + conn->raop->callbacks.video_reset(conn->raop->callbacks.cls, true, false); } } if (conn->raop->callbacks.conn_teardown) { diff --git a/lib/raop_rtp_mirror.c b/lib/raop_rtp_mirror.c index 0a5627c..02a4f60 100644 --- a/lib/raop_rtp_mirror.c +++ b/lib/raop_rtp_mirror.c @@ -852,7 +852,7 @@ raop_rtp_mirror_thread(void *arg) if (unsupported_codec) { closesocket(raop_rtp_mirror->mirror_data_sock); raop_rtp_mirror_stop(raop_rtp_mirror); - raop_rtp_mirror->callbacks.video_reset(raop_rtp_mirror->callbacks.cls, false); + raop_rtp_mirror->callbacks.video_reset(raop_rtp_mirror->callbacks.cls, false, false); } return 0; diff --git a/uxplay.cpp b/uxplay.cpp index 73c5911..e320343 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -2054,14 +2054,32 @@ static bool check_blocked_client(char *deviceid) { // Server callbacks -extern "C" void video_reset(void *cls, bool hls_shutdown) { +extern "C" void video_reset(void *cls, bool hls_shutdown, bool nohold) { LOGD("video_reset"); - video_renderer_stop(); + if (use_video) { + video_renderer_stop(); + } if (hls_shutdown) { url.erase(); raop_destroy_airplay_video(raop, -1); raop_remove_hls_connections(raop); preserve_connections = true; + } else if (nohold) { + if (use_video) { + /* reset the video renderer immediately to avoid a timing issue if we wait for main_loop to reset */ + video_renderer_destroy(); + video_renderer_init(render_logger, server_name.c_str(), videoflip, video_parser.c_str(), rtp_pipeline.c_str(), + video_decoder.c_str(), video_converter.c_str(), videosink.c_str(), + videosink_options.c_str(), fullscreen, video_sync, h265_support, + render_coverart, playbin_version, NULL); + video_renderer_start(); + } + if (hls_support && !url.empty()) { + url.erase(); + raop_destroy_airplay_video(raop, -1); + } + close_window = false; // we already closed the window + preserve_connections = false; //we already closed all other connections } remote_clock_offset = 0; relaunch_video = true; @@ -2380,7 +2398,7 @@ extern "C" void audio_set_coverart(void *cls, const void *buffer, int buflen) { extern "C" void audio_stop_coverart_rendering(void *cls) { if (render_coverart) { - video_reset(cls, false); + video_reset(cls, false, false); } }