From 21fb39d22f8ccf88eaf271d71a6dd595316c6f17 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Fri, 22 Jan 2016 17:47:25 +0000 Subject: [PATCH 1/7] Begin to clean up the 'stop' signalling among the threads -- try to remove as many globals as possible --- player.c | 60 ++++++++++++++++++++++++++++++++++-------------- player.h | 4 ++-- rtp.c | 70 +++++++++++++++++++++++++++++--------------------------- rtp.h | 4 ++++ rtsp.c | 25 ++++++++++---------- 5 files changed, 98 insertions(+), 65 deletions(-) diff --git a/player.c b/player.c index 0b24a67e..856b3142 100644 --- a/player.c +++ b/player.c @@ -81,7 +81,7 @@ static int sampling_rate, frame_size; static aes_context dctx; #endif -static pthread_t player_thread; +//static pthread_t player_thread = NULL; static int please_stop; static int encrypted; // Normally the audio is encrypted, but it may not be @@ -893,6 +893,13 @@ typedef struct stats { // statistics for running averages } stats_t; static void *player_thread_func(void *arg) { + int threads_stop = 0; + // create and start the timing, control and audio receiver threads + pthread_t rtp_audio_thread, rtp_control_thread, rtp_timing_thread; + pthread_create(&rtp_audio_thread, NULL, &rtp_audio_receiver, (void *)&threads_stop); + pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, (void *)&threads_stop); + pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, (void *)&threads_stop); + session_corrections = 0; play_segment_reference_frame = 0; // zero signals that we are not in a play segment // check that there are enough buffers to accommodate the desired latency and the latency offset @@ -1219,8 +1226,22 @@ static void *player_thread_func(void *arg) { } } } + if (config.output->stop) + config.output->stop(); free(outbuf); free(silence); + debug(1,"Shut down audio, control and timing threads"); + + pthread_kill(rtp_audio_thread, SIGUSR1); + pthread_kill(rtp_control_thread, SIGUSR1); + pthread_kill(rtp_timing_thread, SIGUSR1); + pthread_join(rtp_timing_thread, NULL); + debug(1,"timing thread joined"); + pthread_join(rtp_audio_thread, NULL); + debug(1,"audio thread joined"); + pthread_join(rtp_control_thread, NULL); + debug(1,"control thread joined"); + debug(1,"Player thread exit"); return 0; } @@ -1389,7 +1410,9 @@ void player_flush(uint32_t timestamp) { #endif } -int player_play(stream_cfg *stream) { +int player_play(stream_cfg *stream, pthread_t *player_thread) { + //if (*player_thread!=NULL) + // die("Trying to create a second player thread for this RTSP session"); packet_count = 0; encrypted = stream->encrypted; if (config.buffer_start_fill > BUFFER_FRAMES) @@ -1434,23 +1457,26 @@ int player_play(stream_cfg *stream) { rc = pthread_attr_setstacksize(&tattr, size); if (rc) debug(1, "Error setting stack size for player_thread: %s", strerror(errno)); - pthread_create(&player_thread, &tattr, player_thread_func, NULL); + pthread_create(player_thread, &tattr, player_thread_func, NULL); pthread_attr_destroy(&tattr); return 0; } -void player_stop(void) { - please_stop = 1; - pthread_cond_signal(&flowcontrol); // tell it to give up - pthread_join(player_thread, NULL); -#ifdef CONFIG_METADATA - send_ssnc_metadata('pend', NULL, 0, 1); -#endif - config.output->stop(); - command_stop(); - free_buffer(); - free_decoder(); - int rc = pthread_cond_destroy(&flowcontrol); - if (rc) - debug(1, "Error destroying condition variable."); +void player_stop(pthread_t *player_thread) { + //if (*thread==NULL) + // debug(1,"Trying to stop a non-existent player thread"); + // else { + please_stop = 1; + pthread_cond_signal(&flowcontrol); // tell it to give up + pthread_join(*player_thread, NULL); + #ifdef CONFIG_METADATA + send_ssnc_metadata('pend', NULL, 0, 1); + #endif + command_stop(); + free_buffer(); + free_decoder(); + int rc = pthread_cond_destroy(&flowcontrol); + if (rc) + debug(1, "Error destroying condition variable."); + // } } diff --git a/player.h b/player.h index b9cc900a..9012b0cb 100644 --- a/player.h +++ b/player.h @@ -14,8 +14,8 @@ typedef uint16_t seq_t; // wrapped number between two seq_t. int32_t seq_diff(seq_t a, seq_t b); -int player_play(stream_cfg *cfg); -void player_stop(void); +int player_play(stream_cfg *cfg, pthread_t *thread); +void player_stop(pthread_t *thread); void player_volume(double f); void player_flush(uint32_t timestamp); diff --git a/rtp.c b/rtp.c index baf95124..2870e612 100644 --- a/rtp.c +++ b/rtp.c @@ -61,7 +61,6 @@ typedef struct time_ping_record { // only one RTP session can be active at a time. static int running = 0; -static int please_shutdown; static char client_ip_string[INET6_ADDRSTRLEN]; // the ip string pointing to the client static short client_ip_family; // AF_INET / AF_INET6 @@ -72,7 +71,7 @@ static SOCKADDR rtp_client_timing_socket; // a socket pointing to the timing po static int audio_socket; // our local [server] audio socket static int control_socket; // our local [server] control socket static int timing_socket; // local timing socket -static pthread_t rtp_audio_thread, rtp_control_thread, rtp_timing_thread; +//static pthread_t rtp_audio_thread, rtp_control_thread, rtp_timing_thread; static uint32_t reference_timestamp; static uint64_t reference_timestamp_time; @@ -96,16 +95,16 @@ static pthread_mutex_t reference_time_mutex = PTHREAD_MUTEX_INITIALIZER; uint64_t static local_to_remote_time_difference; // used to switch between local and remote clocks -static void *rtp_audio_receiver(void *arg) { +void *rtp_audio_receiver(void *arg) { // we inherit the signal mask (SIGUSR1) + int *stop = arg; // when set to 1, we should stop + int32_t last_seqno = -1; uint8_t packet[2048], *pktp; ssize_t nread; - while (1) { - if (please_shutdown) - break; + while (*stop==0) { nread = recv(audio_socket, packet, sizeof(packet), 0); if (nread < 0) break; @@ -158,17 +157,18 @@ static void *rtp_audio_receiver(void *arg) { return NULL; } -static void *rtp_control_receiver(void *arg) { +void *rtp_control_receiver(void *arg) { // we inherit the signal mask (SIGUSR1) + + int *stop = arg; // when set to 1, we should stop + reference_timestamp = 0; // nothing valid received yet uint8_t packet[2048], *pktp; struct timespec tn; uint64_t remote_time_of_sync, local_time_now, remote_time_now; uint32_t sync_rtp_timestamp, rtp_timestamp_less_latency; ssize_t nread; - while (1) { - if (please_shutdown) - break; + while (*stop==0) { nread = recv(control_socket, packet, sizeof(packet), 0); local_time_now = get_absolute_time_in_fp(); // clock_gettime(CLOCK_MONOTONIC,&tn); @@ -259,7 +259,8 @@ static void *rtp_control_receiver(void *arg) { return NULL; } -static void *rtp_timing_sender(void *arg) { +void *rtp_timing_sender(void *arg) { + int *stop = arg; // the parameter points to this request to stop thing struct timing_request { char leader; char type; @@ -280,9 +281,8 @@ static void *rtp_timing_sender(void *arg) { time_ping_count = 0; // we inherit the signal mask (SIGUSR1) - while (1) { - if (please_shutdown) - break; + while (*stop==0) { + // debug(1,"Send a timing request"); if (!running) die("rtp_timing_sender called without active stream!"); @@ -314,12 +314,16 @@ static void *rtp_timing_sender(void *arg) { return NULL; } -static void *rtp_timing_receiver(void *arg) { +void *rtp_timing_receiver(void *arg) { // we inherit the signal mask (SIGUSR1) + + int *stop = arg; // when set to 1, we should stop + uint8_t packet[2048], *pktp; ssize_t nread; + int request_stop = 0; pthread_t timer_requester; - pthread_create(&timer_requester, NULL, &rtp_timing_sender, NULL); + pthread_create(&timer_requester, NULL, &rtp_timing_sender, (void *)&request_stop); // struct timespec att; uint64_t distant_receive_time, distant_transmit_time, arrival_time, return_time, transit_time, processing_time; @@ -331,9 +335,7 @@ static void *rtp_timing_receiver(void *arg) { uint64_t first_local_to_remote_time_difference = 0; uint64_t first_local_to_remote_time_difference_time; uint64_t l2rtd = 0; - while (1) { - if (please_shutdown) - break; + while (*stop==0) { nread = recv(timing_socket, packet, sizeof(packet), 0); arrival_time = get_absolute_time_in_fp(); // clock_gettime(CLOCK_MONOTONIC,&att); @@ -497,7 +499,8 @@ static void *rtp_timing_receiver(void *arg) { } } - debug(1, "Timing RTP thread interrupted. terminating."); + debug(1, "Timing thread interrupted. terminating."); + request_stop = 1; void *retval; pthread_kill(timer_requester, SIGUSR1); pthread_join(timer_requester, &retval); @@ -655,11 +658,10 @@ void rtp_setup(SOCKADDR *remote, int cport, int tport, uint32_t active_remote, i debug(2, "listening for audio, control and timing on ports %d, %d, %d.", *lsport, *lcport, *ltport); - please_shutdown = 0; reference_timestamp = 0; - pthread_create(&rtp_audio_thread, NULL, &rtp_audio_receiver, NULL); - pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, NULL); - pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, NULL); + //pthread_create(&rtp_audio_thread, NULL, &rtp_audio_receiver, NULL); + //pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, NULL); + //pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, NULL); running = 1; request_sent = 0; @@ -682,18 +684,18 @@ void clear_reference_timestamp(void) { void rtp_shutdown(void) { if (!running) - die("rtp_shutdown called without active stream!"); + debug(1,"rtp_shutdown called without active stream!"); debug(2, "shutting down RTP thread"); - please_shutdown = 1; - void *retval; - reference_timestamp = 0; - pthread_kill(rtp_audio_thread, SIGUSR1); - pthread_join(rtp_audio_thread, &retval); - pthread_kill(rtp_control_thread, SIGUSR1); - pthread_join(rtp_control_thread, &retval); - pthread_kill(rtp_timing_thread, SIGUSR1); - pthread_join(rtp_timing_thread, &retval); + clear_reference_timestamp(); +// 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); running = 0; } diff --git a/rtp.h b/rtp.h index 8045d2bb..cc0776da 100644 --- a/rtp.h +++ b/rtp.h @@ -5,6 +5,10 @@ #include "player.h" +void *rtp_audio_receiver(void *arg); +void *rtp_control_receiver(void *arg); +void *rtp_timing_receiver(void *arg); + void rtp_setup(SOCKADDR *remote, int controlport, int timingport, uint32_t active_remote, int *local_server_port, int *local_control_port, int *local_timing_port); void rtp_shutdown(void); diff --git a/rtsp.c b/rtsp.c index ac173b31..7d6063f0 100644 --- a/rtsp.c +++ b/rtsp.c @@ -92,6 +92,7 @@ typedef struct { SOCKADDR remote; int running; pthread_t thread; + pthread_t player_thread; } rtsp_conn_info; #ifdef CONFIG_METADATA @@ -426,7 +427,7 @@ static int msg_handle_line(rtsp_message **pmsg, char *line) { *p = 0; p += 2; msg_add_header(msg, line, p); - debug(2, " %s: %s.", line, p); + // debug(2, " %s: %s.", line, p); return -1; } else { char *cl = msg_get_header(msg, "Content-Length"); @@ -568,7 +569,7 @@ static void msg_write_response(int fd, rtsp_message *resp) { p += n; for (i = 0; i < resp->nheaders; i++) { - debug(2, " %s: %s.", resp->name[i], resp->value[i]); +// debug(3, " %s: %s.", resp->name[i], resp->value[i]); n = snprintf(p, pktfree, "%s: %s\r\n", resp->name[i], resp->value[i]); pktfree -= n; p += n; @@ -764,7 +765,7 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message * strcat(hdr, q); // should unsplice the timing port entry } - player_play(&conn->stream); + player_play(&conn->stream,&conn->player_thread); // the tread better be null char *resphdr = alloca(200); *resphdr = 0; @@ -1535,12 +1536,12 @@ static void *rtsp_conversation_thread_func(void *pconn) { int method_selected = 0; for (mh = method_handlers; mh->method; mh++) { if (!strcmp(mh->method, req->method)) { - //debug(1,"RTSP Packet received of type \"%s\":",mh->method), - //msg_print_debug_headers(req); + // debug(1,"RTSP Packet received of type \"%s\":",mh->method), + // msg_print_debug_headers(req); method_selected = 1; mh->handler(conn, req, resp); - //debug(1,"RTSP Response:"); - //msg_print_debug_headers(resp); + // debug(1,"RTSP Response:"); + // msg_print_debug_headers(resp); break; } } @@ -1557,20 +1558,20 @@ static void *rtsp_conversation_thread_func(void *pconn) { } } while (reply != rtsp_read_request_response_shutdown_requested); - debug(1, "closing RTSP connection."); + debug(1, "Now closing RTSP connection."); if (conn->fd > 0) close(conn->fd); if (rtsp_playing()) { + player_stop(&conn->player_thread); // might be less noisy doing this first rtp_shutdown(); - player_stop(); pthread_mutex_unlock(&play_lock); - please_shutdown = 0; pthread_mutex_unlock(&playing_mutex); } if (auth_nonce) free(auth_nonce); conn->running = 0; - debug(2, "terminating RTSP thread."); + debug(2, "Now terminating RTSP conversation thread."); + please_shutdown = 0; return NULL; } @@ -1699,7 +1700,7 @@ void rtsp_listen_loop(void) { memset(conn, 0, sizeof(rtsp_conn_info)); socklen_t slen = sizeof(conn->remote); - debug(1, "new RTSP connection."); + debug(1, "New RTSP connection on port %d",config.port); conn->fd = accept(acceptfd, (struct sockaddr *)&conn->remote, &slen); if (conn->fd < 0) { perror("failed to accept connection"); From 9a9c9842fcc79a8868d4e4df40d01eb1617ebc8c Mon Sep 17 00:00:00 2001 From: Mke Brady Date: Sat, 23 Jan 2016 17:50:36 +0000 Subject: [PATCH 2/7] Remove global signalling for stopping threads --- player.c | 2 +- rtsp.c | 46 +++++++++++++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/player.c b/player.c index 856b3142..d81c045e 100644 --- a/player.c +++ b/player.c @@ -1231,7 +1231,7 @@ static void *player_thread_func(void *arg) { free(outbuf); free(silence); debug(1,"Shut down audio, control and timing threads"); - + // usleep(1000000); pthread_kill(rtp_audio_thread, SIGUSR1); pthread_kill(rtp_control_thread, SIGUSR1); pthread_kill(rtp_timing_thread, SIGUSR1); diff --git a/rtsp.c b/rtsp.c index 7d6063f0..0a3d71cc 100644 --- a/rtsp.c +++ b/rtsp.c @@ -83,13 +83,14 @@ static pthread_mutex_t reference_counter_lock = PTHREAD_MUTEX_INITIALIZER; // only one thread is allowed to use the player at once. // it monitors the request variable (at least when interrupted) static pthread_mutex_t playing_mutex = PTHREAD_MUTEX_INITIALIZER; -static int please_shutdown = 0; +//static int please_shutdown = 0; static pthread_t playing_thread = 0; typedef struct { int fd; stream_cfg stream; SOCKADDR remote; + int stop; int running; pthread_t thread; pthread_t player_thread; @@ -134,6 +135,8 @@ typedef struct { rtsp_message *carrier; } metadata_package; +void ask_other_rtsp_conversation_threads_to_stop(pthread_t except_this_thread); + void pc_queue_init(pc_queue *the_queue, char *items, size_t item_size, uint32_t number_of_items) { the_queue->item_size = item_size; the_queue->items = items; @@ -240,8 +243,7 @@ static inline int rtsp_playing(void) { } void rtsp_request_shutdown_stream(void) { - please_shutdown = 1; - pthread_kill(playing_thread, SIGUSR1); + ask_other_rtsp_conversation_threads_to_stop(0); // i.e. ask all playing threads to stop } static void rtsp_take_player(void) { @@ -249,10 +251,8 @@ static void rtsp_take_player(void) { return; if (pthread_mutex_trylock(&playing_mutex)) { - debug(1, "shutting down playing thread."); - // XXX minor race condition between please_shutdown and signal delivery - please_shutdown = 1; - pthread_kill(playing_thread, SIGUSR1); + debug(1, "asking all other playing threads to stop."); + ask_other_rtsp_conversation_threads_to_stop(pthread_self()); // all threads apart from self pthread_mutex_lock(&playing_mutex); } playing_thread = pthread_self(); // make us the currently-playing thread (why?) @@ -290,6 +290,21 @@ static void cleanup_threads(void) { } } +// ask all rtsp_conversation threads to stop -- there should be at most one, but ya never know. + +void ask_other_rtsp_conversation_threads_to_stop(pthread_t except_this_thread) { + int i; + debug(2, "asking playing threads to stop"); + for (i = 0; i < nconns;i++) { + if (((except_this_thread==0) || (pthread_equal(conns[i]->thread,except_this_thread)==0)) && (conns[i]->running != 0)) { + conns[i]->stop = 1; + pthread_kill(conns[i]->thread,SIGUSR1); + } + } +} + + + // park a null at the line ending, and return the next line pointer // accept \r, \n, or \r\n static char *nextline(char *in, int inbuf) { @@ -443,7 +458,7 @@ fail: return 0; } -static enum rtsp_read_request_response rtsp_read_request(int fd, rtsp_message **the_packet) { +static enum rtsp_read_request_response rtsp_read_request(rtsp_conn_info *conn, rtsp_message **the_packet) { enum rtsp_read_request_response reply = rtsp_read_request_response_ok; ssize_t buflen = 512; char *buf = malloc(buflen + 1); @@ -455,12 +470,12 @@ static enum rtsp_read_request_response rtsp_read_request(int fd, rtsp_message ** int msg_size = -1; while (msg_size < 0) { - if (please_shutdown) { + if (conn->stop!=0) { debug(1, "RTSP shutdown requested."); reply = rtsp_read_request_response_shutdown_requested; goto shutdown; } - nread = read(fd, buf + inbuf, buflen - inbuf); + nread = read(conn->fd, buf + inbuf, buflen - inbuf); if (!nread) { debug(1, "RTSP connection closed."); reply = rtsp_read_request_response_shutdown_requested; @@ -525,7 +540,7 @@ static enum rtsp_read_request_response rtsp_read_request(int fd, rtsp_message ** ssize_t read_chunk = msg_size - inbuf; if (read_chunk > max_read_chunk) read_chunk = max_read_chunk; - nread = read(fd, buf + inbuf, read_chunk); + nread = read(conn->fd, buf + inbuf, read_chunk); if (!nread) { reply = rtsp_read_request_response_error; goto shutdown; @@ -627,7 +642,7 @@ static void handle_teardown(rtsp_conn_info *conn, rtsp_message *req, rtsp_messag return; resp->respcode = 200; msg_add_header(resp, "Connection", "close"); - please_shutdown = 1; + conn->stop = 1; } static void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { @@ -765,7 +780,7 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message * strcat(hdr, q); // should unsplice the timing port entry } - player_play(&conn->stream,&conn->player_thread); // the tread better be null + player_play(&conn->stream,&conn->player_thread); // the thread better be 0 char *resphdr = alloca(200); *resphdr = 0; @@ -1518,7 +1533,7 @@ static void *rtsp_conversation_thread_func(void *pconn) { enum rtsp_read_request_response reply; do { - reply = rtsp_read_request(conn->fd, &req); + reply = rtsp_read_request(conn, &req); if (reply == rtsp_read_request_response_ok) { resp = msg_init(); resp->respcode = 400; @@ -1571,7 +1586,7 @@ static void *rtsp_conversation_thread_func(void *pconn) { free(auth_nonce); conn->running = 0; debug(2, "Now terminating RTSP conversation thread."); - please_shutdown = 0; +// please_shutdown = 0; return NULL; } @@ -1712,6 +1727,7 @@ void rtsp_listen_loop(void) { die("Failed to create RTSP receiver thread!"); conn->thread = rtsp_conversation_thread; + conn -> stop = 0; conn->running = 1; track_thread(conn); } From 9f7a3ff4e1fc77bd0ea4d6cc998c8355f4980a20 Mon Sep 17 00:00:00 2001 From: Mke Brady Date: Sat, 23 Jan 2016 17:57:43 +0000 Subject: [PATCH 3/7] Ask for the correct number of packets to be resent -- it was asking for one too many in some situations. --- player.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/player.c b/player.c index d81c045e..2309eaa7 100644 --- a/player.c +++ b/player.c @@ -308,7 +308,7 @@ void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len) if ((flush_rtp_timestamp != 0) && ((timestamp == flush_rtp_timestamp) || seq32_order(timestamp, flush_rtp_timestamp))) { - debug(2, "Dropping flushed packet in player_put_packet, seqno %u, timestamp %u, flushing to " + debug(3, "Dropping flushed packet in player_put_packet, seqno %u, timestamp %u, flushing to " "timestamp: %u.", seqno, timestamp, flush_rtp_timestamp); } else { @@ -332,7 +332,7 @@ void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len) // if (ORDINATE(seqno)>(BUFFER_FRAMES*7)/8) // debug(1,"An interval of %u frames has opened, with ab_read: %u, ab_write: %u and seqno: // %u.",seq_diff(ab_read,seqno),ab_read,ab_write,seqno); - int32_t gap = seq_diff(ab_write, PREDECESSOR(seqno)) + 1; + int32_t gap = seq_diff(ab_write, (seqno); if (gap <= 0) debug(1, "Unexpected gap size: %d.", gap); int i; @@ -1398,7 +1398,7 @@ void player_volume(double airplay_volume) { } void player_flush(uint32_t timestamp) { - // debug(1,"Flush requested up to %u. It seems as if 0 is special.",timestamp); + debug(3,"Flush requested up to %u. It seems as if 0 is special.",timestamp); pthread_mutex_lock(&flush_mutex); flush_requested = 1; // if (timestamp!=0) From 28198c69841dfef0ef340df3e13f0d68fde3631e Mon Sep 17 00:00:00 2001 From: Mke Brady Date: Sat, 23 Jan 2016 17:58:03 +0000 Subject: [PATCH 4/7] Quieten some debug messages. --- rtp.c | 2 +- rtsp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtp.c b/rtp.c index 2870e612..6a1e35ff 100644 --- a/rtp.c +++ b/rtp.c @@ -702,7 +702,7 @@ void rtp_shutdown(void) { void rtp_request_resend(seq_t first, uint32_t count) { if (running) { if (!request_sent) { - debug(2, "requesting resend on %d packets starting at %u.", count, first); + debug(2, "requesting resend of %d packets starting at %u.", count, first); request_sent = 1; } diff --git a/rtsp.c b/rtsp.c index 0a3d71cc..fe53e658 100644 --- a/rtsp.c +++ b/rtsp.c @@ -442,7 +442,7 @@ static int msg_handle_line(rtsp_message **pmsg, char *line) { *p = 0; p += 2; msg_add_header(msg, line, p); - // debug(2, " %s: %s.", line, p); + debug(3, " %s: %s.", line, p); return -1; } else { char *cl = msg_get_header(msg, "Content-Length"); From 09d9905328c208fbc1d6a604afe199d570360106 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sat, 23 Jan 2016 18:00:45 +0000 Subject: [PATCH 5/7] Fix silly error --- player.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/player.c b/player.c index 2309eaa7..17b5477a 100644 --- a/player.c +++ b/player.c @@ -332,7 +332,7 @@ void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len) // if (ORDINATE(seqno)>(BUFFER_FRAMES*7)/8) // debug(1,"An interval of %u frames has opened, with ab_read: %u, ab_write: %u and seqno: // %u.",seq_diff(ab_read,seqno),ab_read,ab_write,seqno); - int32_t gap = seq_diff(ab_write, (seqno); + int32_t gap = seq_diff(ab_write, seqno); if (gap <= 0) debug(1, "Unexpected gap size: %d.", gap); int i; From 51ae68e0954d84bf9a15834c802328a9898b187a Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sat, 23 Jan 2016 19:02:49 +0000 Subject: [PATCH 6/7] Experiment with waiting a little while before sending resend requests. --- player.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/player.c b/player.c index 17b5477a..c35c6b99 100644 --- a/player.c +++ b/player.c @@ -344,8 +344,8 @@ void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len) } // debug(1,"N %d s %u.",seq_diff(ab_write,PREDECESSOR(seqno))+1,ab_write); abuf = audio_buffer + BUFIDX(seqno); - rtp_request_resend(ab_write, gap); - resend_requests++; +// rtp_request_resend(ab_write, gap); +// resend_requests++; ab_write = SUCCESSOR(seqno); } else if (seq_order(ab_read, seqno)) { // late but not yet played late_packets++; From 45061e993ed5014cdf8b3d415714667e8449769a Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 24 Jan 2016 13:36:16 +0000 Subject: [PATCH 7/7] Turn on extra debugging --- rtp.c | 12 ++++++------ rtsp.c | 10 +++++++--- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/rtp.c b/rtp.c index 6a1e35ff..bc40948d 100644 --- a/rtp.c +++ b/rtp.c @@ -701,10 +701,10 @@ void rtp_shutdown(void) { void rtp_request_resend(seq_t first, uint32_t count) { if (running) { - if (!request_sent) { + //if (!request_sent) { debug(2, "requesting resend of %d packets starting at %u.", count, first); - request_sent = 1; - } + // request_sent = 1; + //} char req[8]; // *not* a standard RTCP NACK req[0] = 0x80; @@ -723,10 +723,10 @@ void rtp_request_resend(seq_t first, uint32_t count) { perror("Error sendto-ing to audio socket"); } } else { - if (!request_sent) { + //if (!request_sent) { debug(2, "rtp_request_resend called without active stream!"); - request_sent = 1; - } + // request_sent = 1; + //} } } diff --git a/rtsp.c b/rtsp.c index fe53e658..6e8f1df7 100644 --- a/rtsp.c +++ b/rtsp.c @@ -243,6 +243,7 @@ static inline int rtsp_playing(void) { } void rtsp_request_shutdown_stream(void) { + debug(1,"Request to shut down all rtsp conversation threads"); ask_other_rtsp_conversation_threads_to_stop(0); // i.e. ask all playing threads to stop } @@ -251,7 +252,7 @@ static void rtsp_take_player(void) { return; if (pthread_mutex_trylock(&playing_mutex)) { - debug(1, "asking all other playing threads to stop."); + debug(1, "Request to all other playing threads to stop."); ask_other_rtsp_conversation_threads_to_stop(pthread_self()); // all threads apart from self pthread_mutex_lock(&playing_mutex); } @@ -639,7 +640,7 @@ 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) { if (!rtsp_playing()) - return; + debug(1,"This RTSP conversation thread doesn't think it's playing, but it's sending a response to teardown anyway"); resp->respcode = 200; msg_add_header(resp, "Connection", "close"); conn->stop = 1; @@ -647,7 +648,7 @@ static void handle_teardown(rtsp_conn_info *conn, rtsp_message *req, rtsp_messag static void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { if (!rtsp_playing()) - return; + debug(1,"This RTSP conversation thread doesn't think it's playing, but it's sending a response to flush anyway"); char *p; uint32_t rtptime = 0; char *hdr = msg_get_header(req, "RTP-Info"); @@ -1581,6 +1582,8 @@ static void *rtsp_conversation_thread_func(void *pconn) { rtp_shutdown(); pthread_mutex_unlock(&play_lock); pthread_mutex_unlock(&playing_mutex); + } else { + debug(1,"This RTSP conversation thread doesn't think it's playing for a close RTSP connection."); } if (auth_nonce) free(auth_nonce); @@ -1654,6 +1657,7 @@ void rtsp_listen_loop(void) { // one of the address families will fail on some systems that // report its availability. do not complain. + if (ret) { debug(1, "Failed to bind to address %s.", format_address(p->ai_addr)); continue;