Change behaviour when TEARDOWN is received -- don't close down the RTSP conversation, but wait for it to be closed. Add more debug messages.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user