From 15ba732458b7768d8c67737639e7b8f023d9def5 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Fri, 25 Aug 2017 10:33:17 +0100 Subject: [PATCH] Change behaviour when TEARDOWN is received -- don't close down the RTSP conversation, but wait for it to be closed. Add more debug messages. --- player.c | 26 ++++++++++++++++---------- rtp.c | 19 +------------------ rtp.h | 1 - rtsp.c | 38 +++++++++++++++++--------------------- 4 files changed, 34 insertions(+), 50 deletions(-) diff --git a/player.c b/player.c index 438ae61c..03708510 100644 --- a/player.c +++ b/player.c @@ -443,7 +443,7 @@ static void init_buffer(rtsp_conn_info *conn) { ab_resync(conn); } -static void free_buffer(rtsp_conn_info *conn) { +static void free_audio_buffers(rtsp_conn_info *conn) { int i; for (i = 0; i < BUFFER_FRAMES; i++) free(conn->audio_buffer[i].data); @@ -2164,7 +2164,10 @@ static void *player_thread_func(void *arg) { debug(1, "audio thread joined"); pthread_join(rtp_control_thread, NULL); debug(1, "control thread joined"); - free_buffer(conn); + clear_reference_timestamp(conn); + conn->rtp_running = 0; + + free_audio_buffers(conn); terminate_decoders(conn); // remove flow control and mutexes rc = pthread_cond_destroy(&conn->flowcontrol); @@ -2179,6 +2182,7 @@ static void *player_thread_func(void *arg) { rc = pthread_mutex_destroy(&conn->vol_mutex); if (rc) debug(1, "Error destroying vol_mutex variable."); + debug(1, "Player thread exit"); if (outbuf) free(outbuf); @@ -2453,14 +2457,16 @@ int player_play(pthread_t *player_thread, rtsp_conn_info *conn) { } void player_stop(pthread_t *player_thread, rtsp_conn_info *conn) { - // if (*thread==NULL) - // debug(1,"Trying to stop a non-existent player thread"); - // else { - conn->player_thread_please_stop = 1; - pthread_cond_signal(&conn->flowcontrol); // tell it to give up - pthread_join(*player_thread, NULL); + if (player_thread) { + conn->player_thread_please_stop = 1; + pthread_cond_signal(&conn->flowcontrol); // tell it to give up + pthread_join(*player_thread, NULL); #ifdef CONFIG_METADATA - send_ssnc_metadata('pend', NULL, 0, 1); + send_ssnc_metadata('pend', NULL, 0, 1); #endif - command_stop(); + command_stop(); + player_thread = NULL; + } else { + debug(1,"Attempting to kill the non-existent player thread of RTSP conversation %d.",conn->connection_number); + } } diff --git a/rtp.c b/rtp.c index 7b4cc071..4dd75026 100644 --- a/rtp.c +++ b/rtp.c @@ -703,8 +703,8 @@ void rtp_setup(SOCKADDR *local, SOCKADDR *remote, int cport, int tport, uint32_t // pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, NULL); // pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, NULL); - conn->rtp_running = 1; conn->request_sent = 0; + conn->rtp_running = 1; } void get_reference_timestamp_stuff(int64_t *timestamp, uint64_t *timestamp_time, @@ -727,23 +727,6 @@ void clear_reference_timestamp(rtsp_conn_info *conn) { pthread_mutex_unlock(&conn->reference_time_mutex); } -void rtp_shutdown(rtsp_conn_info *conn) { - if (!conn->rtp_running) - debug(1, "rtp_shutdown called without active stream!"); - - debug(2, "shutting down RTP thread"); - clear_reference_timestamp(conn); - // debug(1,"Shut down audio, control and timing threads"); - // usleep(3000000); // hack - // pthread_kill(rtp_audio_thread, SIGUSR1); - // pthread_kill(rtp_control_thread, SIGUSR1); - // pthread_kill(rtp_timing_thread, SIGUSR1); - // pthread_join(rtp_audio_thread, &retval); - // pthread_join(rtp_control_thread, &retval); - // pthread_join(rtp_timing_thread, &retval); - conn->rtp_running = 0; -} - void rtp_request_resend(seq_t first, uint32_t count, rtsp_conn_info *conn) { if (conn->rtp_running) { // if (!request_sent) { diff --git a/rtp.h b/rtp.h index e0ebefa9..3da1c089 100644 --- a/rtp.h +++ b/rtp.h @@ -15,7 +15,6 @@ void *rtp_timing_receiver(void *arg); void rtp_setup(SOCKADDR *local, SOCKADDR *remote, int controlport, int timingport, uint32_t active_remote, int *local_server_port, int *local_control_port, int *local_timing_port, rtsp_conn_info *conn); -void rtp_shutdown(rtsp_conn_info *conn); void rtp_request_resend(seq_t first, uint32_t count, rtsp_conn_info *conn); void rtp_request_client_pause(rtsp_conn_info *conn); // ask the client to pause diff --git a/rtsp.c b/rtsp.c index a621132e..33e08074 100644 --- a/rtsp.c +++ b/rtsp.c @@ -487,7 +487,7 @@ static enum rtsp_read_request_response rtsp_read_request(rtsp_conn_info *conn, while (msg_size < 0) { memory_barrier(); if (conn->stop != 0) { - debug(1, "RTSP shutdown requested."); + debug(1, "RTSP conversation thread %d shutdown requested.",conn->connection_number); reply = rtsp_read_request_response_immediate_shutdown_requested; goto shutdown; } @@ -495,7 +495,7 @@ static enum rtsp_read_request_response rtsp_read_request(rtsp_conn_info *conn, if (nread == 0) { // a blocking read that returns zero means eof -- implies connection closed - debug(3, "RTSP connection closed."); + debug(1, "RTSP conversation thread %d -- connection closed.",conn->connection_number); reply = rtsp_read_request_response_channel_closed; goto shutdown; } @@ -622,7 +622,7 @@ static void msg_write_response(int fd, rtsp_message *resp) { } static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1,"Connection thread %d: RECORD",conn->connection_number); + debug(3,"Connection %d: RECORD",conn->connection_number); resp->respcode = 200; // I think this is for telling the client what the absolute minimum latency // actually is, @@ -653,10 +653,11 @@ static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message } } } + usleep(500000); } static void handle_options(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1, "Connection thread %d: OPTIONS",conn->connection_number); + debug(3, "Connection %d: OPTIONS",conn->connection_number); resp->respcode = 200; msg_add_header(resp, "Public", "ANNOUNCE, SETUP, RECORD, " "PAUSE, FLUSH, TEARDOWN, " @@ -664,26 +665,25 @@ static void handle_options(rtsp_conn_info *conn, rtsp_message *req, rtsp_message } static void handle_teardown(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1, "Connection thread %d: TEARDOWN",conn->connection_number); + debug(3, "Connection %d: TEARDOWN",conn->connection_number); if (!rtsp_playing()) debug(1, "This RTSP connection thread (%d) doesn't think it's playing, but " "it's sending a response to teardown anyway",conn->connection_number); resp->respcode = 200; msg_add_header(resp, "Connection", "close"); - debug(1, "Synchronous closing down of RTSP conversation thread %d (2).",conn->connection_number); + debug(1, "TEARDOWN: synchronous closing the player thread of RTSP conversation thread %d (2).",conn->connection_number); if (rtsp_playing()) { player_stop(&conn->player_thread, conn); // might be less noisy doing this first - rtp_shutdown(conn); - // usleep(400000); // let an angel pass... } - debug(1, "RTSP conversation thread %d synchronously closed (2).",conn->connection_number); - conn->stop = 1; + debug(1,"TEARDOWN leaving the conversation thread open..."); + //debug(1, "RTSP conversation thread %d synchronously closed (2).",conn->connection_number); + //conn->stop = 1; // usleep(1000000); } static void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1, "Connection thread %d: FLUSH",conn->connection_number); + debug(3, "Connection %d: FLUSH",conn->connection_number); if (!rtsp_playing()) debug(1, "This RTSP conversation thread (%d) doesn't think it's playing, but " "it's sending a response to flush anyway",conn->connection_number); @@ -713,7 +713,7 @@ static void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message * } static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1,"Connection %d: SETUP",conn->connection_number); + debug(3,"Connection %d: SETUP",conn->connection_number); int cport, tport; int lsport, lcport, ltport; uint32_t active_remote = 0; @@ -872,7 +872,7 @@ static void handle_set_parameter_parameter(rtsp_conn_info *conn, rtsp_message *r if (!strncmp(cp, "volume: ", 8)) { float volume = atof(cp + 8); - // debug(1, "AirPlay request to set volume to: %f\n", volume); + debug(3, "AirPlay request to set volume to: %f.", volume); player_volume(volume, conn); } else #ifdef CONFIG_METADATA @@ -1309,12 +1309,12 @@ static void handle_set_parameter_metadata(rtsp_conn_info *conn, rtsp_message *re #endif static void handle_get_parameter(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1,"Connection %d: GET_PARAMETER",conn->connection_number); + debug(3,"Connection %d: GET_PARAMETER",conn->connection_number); resp->respcode = 200; } static void handle_set_parameter(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1,"Connection %d: SET_PARAMETER",conn->connection_number); + debug(3,"Connection %d: SET_PARAMETER",conn->connection_number); // if (!req->contentlength) // debug(1, "received empty SET_PARAMETER request."); @@ -1401,12 +1401,11 @@ static void handle_set_parameter(rtsp_conn_info *conn, rtsp_message *req, rtsp_m } else { debug(1, "missing Content-Type header in SET_PARAMETER request."); } - resp->respcode = 200; } static void handle_announce(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { - debug(1,"Connection %d: ANNOUNCE",conn->connection_number); + debug(3,"Connection %d: ANNOUNCE",conn->connection_number); int have_the_player = 0; // interrupt session if permitted @@ -1785,7 +1784,6 @@ static void *rtsp_conversation_thread_func(void *pconn) { rtsp_conn_info *conn = pconn; rtp_initialise(conn); - conn->running = 1; rtsp_message *req, *resp; char *hdr, *auth_nonce = NULL; @@ -1833,8 +1831,6 @@ static void *rtsp_conversation_thread_func(void *pconn) { debug(1, "Synchronous closing down of RTSP conversation thread %d (1).",conn->connection_number); if (rtsp_playing()) { player_stop(&conn->player_thread, conn); // might be less noisy doing this first - rtp_shutdown(conn); - // usleep(400000); // let an angel pass... } debug(1, "RTSP conversation thread %d synchronously closed (1).",conn->connection_number); conn->stop = 1; @@ -2067,12 +2063,12 @@ void rtsp_listen_loop(void) { // conn->thread = rtsp_conversation_thread; // conn->stop = 0; // record's memory has been zeroed // conn->authorized = 0; // record's memory has been zeroed - ret = pthread_create(&conn->thread, NULL, rtsp_conversation_thread_func, conn); // also acts as a memory barrier if (ret) die("Failed to create RTSP receiver thread %d!",conn->connection_number); debug(1,"Successfully created RTSP receiver thread %d.",conn->connection_number); + conn->running = 1; // this must happen before the thread is tracked track_thread(conn); } }