From: Mike Brady Date: Tue, 7 Mar 2017 22:42:23 +0000 (+0000) Subject: Untested, probably not working X-Git-Tag: 3.1.d1~1^2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7d672bcf561f37e4711b6fe8b6547e9636b0d20d;p=thirdparty%2Fshairport-sync.git Untested, probably not working --- diff --git a/player.c b/player.c index 9b265279..9faa2031 100644 --- a/player.c +++ b/player.c @@ -76,11 +76,6 @@ #include "apple_alac.h" #endif -// parameters from the source -static unsigned char *aesiv; -#ifdef HAVE_LIBSSL -static AES_KEY aes; -#endif static int input_rate, input_bit_depth, input_num_channels, max_frames_per_packet; static uint32_t timestamp_epoch, last_timestamp, @@ -99,17 +94,8 @@ static int max_frame_size_change; // maximal resampling shift - conservative //#define OUTFRAME_BYTES(max_frames_per_packet) (4 * (max_frames_per_packet + 3)) -#ifdef HAVE_LIBMBEDTLS -static mbedtls_aes_context dctx; -#endif - -#ifdef HAVE_LIBPOLARSSL -static aes_context dctx; -#endif - // static pthread_t player_thread = NULL; static int please_stop; -static int encrypted; // Normally the audio is encrypted, but it may not be static int connection_state_to_output; // if true, then play incoming stuff; if false drop everything @@ -118,7 +104,6 @@ static alac_file *decoder_info; // debug variables static int late_packet_message_sent; -static uint64_t packet_count = 0; static int32_t last_seqno_read; static int decoder_in_use = 0; @@ -305,7 +290,7 @@ static inline int seq32_order(uint32_t a, uint32_t b) { return (C & 0x80000000) == 0; } -static int alac_decode(short *dest, int *destlen, uint8_t *buf, int len) { +static int alac_decode(short *dest, int *destlen, uint8_t *buf, int len, rtsp_conn_info* conn) { // parameters: where the decoded stuff goes, its length in samples, // the incoming packet, the length of the incoming packet in bytes // destlen should contain the allowed max number of samples on entry @@ -322,18 +307,18 @@ static int alac_decode(short *dest, int *destlen, uint8_t *buf, int len) { int outsize = input_bytes_per_frame * (*destlen); // the size the output should be, in bytes int toutsize = outsize; - if (encrypted) { + if (conn->stream.encrypted) { unsigned char iv[16]; int aeslen = len & ~0xf; - memcpy(iv, aesiv, sizeof(iv)); + memcpy(iv, conn->stream.aesiv, sizeof(iv)); #ifdef HAVE_LIBMBEDTLS - mbedtls_aes_crypt_cbc(&dctx, MBEDTLS_AES_DECRYPT, aeslen, iv, buf, packet); + mbedtls_aes_crypt_cbc(&conn->dctx, MBEDTLS_AES_DECRYPT, aeslen, iv, buf, packet); #endif #ifdef HAVE_LIBPOLARSSL - aes_crypt_cbc(&dctx, AES_DECRYPT, aeslen, iv, buf, packet); + aes_crypt_cbc(&conn->dctx, AES_DECRYPT, aeslen, iv, buf, packet); #endif #ifdef HAVE_LIBSSL - AES_cbc_encrypt(buf, packet, aeslen, &aes, iv, AES_DECRYPT); + AES_cbc_encrypt(buf, packet, aeslen, &conn->aes, iv, AES_DECRYPT); #endif memcpy(packet + aeslen, buf + aeslen, len - aeslen); #ifdef HAVE_APPLE_ALAC @@ -377,7 +362,7 @@ static int alac_decode(short *dest, int *destlen, uint8_t *buf, int len) { if (outsize > toutsize) { debug(2, "Output from alac_decode larger (%d bytes, not frames) than expected (%d bytes) -- " "truncated, but buffer overflow possible! Encrypted = %d.", - outsize, toutsize, encrypted); + outsize, toutsize, conn->stream.encrypted); reply = -1; // output packet is the wrong size } @@ -524,14 +509,14 @@ static void free_buffer(void) { free(audio_buffer[i].data); } -void player_put_packet(seq_t seqno, int64_t timestamp, uint8_t *data, int len) { +void player_put_packet(seq_t seqno, int64_t timestamp, uint8_t *data, int len, rtsp_conn_info *itr) { // all timestamps are done at the output rate int64_t ltimestamp = timestamp * output_sample_ratio; // ignore a request to flush that has been made before the first packet... - if (packet_count == 0) { + if (itr->packet_count == 0) { pthread_mutex_lock(&flush_mutex); flush_requested = 0; flush_rtp_timestamp = 0; @@ -539,7 +524,7 @@ void player_put_packet(seq_t seqno, int64_t timestamp, uint8_t *data, int len) { } pthread_mutex_lock(&ab_mutex); - packet_count++; + itr->packet_count++; time_of_last_audio_packet = get_absolute_time_in_fp(); if (connection_state_to_output) { // if we are supposed to be processing these packets @@ -603,7 +588,7 @@ void player_put_packet(seq_t seqno, int64_t timestamp, uint8_t *data, int len) { if (abuf) { int datalen = max_frames_per_packet; - if (alac_decode(abuf->data, &datalen, data, len) == 0) { + if (alac_decode(abuf->data, &datalen, data, len, itr) == 0) { abuf->ready = 1; abuf->length = datalen; abuf->timestamp = ltimestamp; @@ -1490,8 +1475,28 @@ typedef struct stats { // statistics for running averages } stats_t; static void *player_thread_func(void *arg) { - struct inter_threads_record itr; - itr.please_stop = 0; + + rtsp_conn_info *conn = (rtsp_conn_info *)arg; + + conn->please_stop = 0; + conn->packet_count = 0; + + if (conn->stream.encrypted) { +#ifdef HAVE_LIBMBEDTLS + memset(&conn->dctx, 0, sizeof(mbedtls_aes_context)); + mbedtls_aes_setkey_dec(&conn->dctx, conn->stream.aeskey, 128); +#endif + +#ifdef HAVE_LIBPOLARSSL + memset(&conn->dctx, 0, sizeof(aes_context)); + aes_setkey_dec(&conn->dctx, conn->stream.aeskey, 128); +#endif + +#ifdef HAVE_LIBSSL + AES_set_decrypt_key(conn->stream.aeskey, 128, &conn->aes); +#endif + } + timestamp_epoch = 0; // indicate that the next timestamp will be the first one. maximum_timestamp_interval = input_rate * 60; // actually there shouldn't be more than about 13v // seconds of a gap between successive rtptimes, at @@ -1522,9 +1527,9 @@ static void *player_thread_func(void *arg) { // 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 *)&itr); - pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, (void *)&itr); - pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, (void *)&itr); + pthread_create(&rtp_audio_thread, NULL, &rtp_audio_receiver, (void *)conn); + pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, (void *)conn); + pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, (void *)conn); session_corrections = 0; play_segment_reference_frame = 0; // zero signals that we are not in a play segment @@ -2211,7 +2216,7 @@ static void *player_thread_func(void *arg) { if (sbuf) free(sbuf); debug(1, "Shut down audio, control and timing threads"); - itr.please_stop = 1; + conn->please_stop = 1; pthread_kill(rtp_audio_thread, SIGUSR1); pthread_kill(rtp_control_thread, SIGUSR1); pthread_kill(rtp_timing_thread, SIGUSR1); @@ -2430,31 +2435,15 @@ void player_flush(int64_t timestamp) { #endif } -int player_play(stream_cfg *stream, pthread_t *player_thread) { +int player_play(pthread_t *player_thread, rtsp_conn_info *conn) { + +// need to use conn in place of streram below. Need to put the stream as a parameter to he // 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) die("specified buffer starting fill %d > buffer size %d", config.buffer_start_fill, BUFFER_FRAMES); - if (encrypted) { -#ifdef HAVE_LIBMBEDTLS - memset(&dctx, 0, sizeof(mbedtls_aes_context)); - mbedtls_aes_setkey_dec(&dctx, stream->aeskey, 128); -#endif - -#ifdef HAVE_LIBPOLARSSL - memset(&dctx, 0, sizeof(aes_context)); - aes_setkey_dec(&dctx, stream->aeskey, 128); -#endif - -#ifdef HAVE_LIBSSL - AES_set_decrypt_key(stream->aeskey, 128, &aes); -#endif - aesiv = stream->aesiv; - } - init_decoder(stream->fmtp); // this sets up incoming rate, bit depth, channels + init_decoder((int32_t *)&conn->stream.fmtp); // this sets up incoming rate, bit depth, channels // must be after decoder init init_buffer(); please_stop = 0; @@ -2482,12 +2471,12 @@ int player_play(stream_cfg *stream, pthread_t *player_thread) { 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, (void*)conn); pthread_attr_destroy(&tattr); return 0; } -void player_stop(pthread_t *player_thread) { +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 { diff --git a/player.h b/player.h index eba97e8e..8ffd153b 100644 --- a/player.h +++ b/player.h @@ -1,6 +1,22 @@ #ifndef _PLAYER_H #define _PLAYER_H +#include "config.h" + +#ifdef HAVE_LIBMBEDTLS +#include +#include +#endif + +#ifdef HAVE_LIBPOLARSSL +#include +#include +#endif + +#ifdef HAVE_LIBSSL +#include +#endif + #include "audio.h" typedef struct { @@ -9,18 +25,43 @@ typedef struct { int32_t fmtp[12]; } stream_cfg; +typedef struct { + int fd; + int authorized; // set if a password is required and has been supplied + stream_cfg stream; + SOCKADDR remote, local; + int stop; + int running; + pthread_t thread; + pthread_t player_thread; + + uint32_t please_stop; + uint64_t packet_count; +#ifdef HAVE_LIBMBEDTLS + mbedtls_aes_context dctx; +#endif + +#ifdef HAVE_LIBPOLARSSL + aes_context dctx; +#endif + +#ifdef HAVE_LIBSSL + AES_KEY aes; +#endif +} rtsp_conn_info; + + 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, pthread_t *thread); -void player_stop(pthread_t *thread); +int player_play(pthread_t *thread, rtsp_conn_info* conn); +void player_stop(pthread_t *thread, rtsp_conn_info* conn); void player_volume(double f); void player_flush(int64_t timestamp); - -void player_put_packet(seq_t seqno, int64_t timestamp, uint8_t *data, int len); +void player_put_packet(seq_t seqno, int64_t timestamp, uint8_t *data, int len, rtsp_conn_info* conn); int64_t monotonic_timestamp(uint32_t timestamp); // add an epoch to the timestamp. The monotonic // timestamp guaranteed to start between 2^32 2^33 diff --git a/rtp.c b/rtp.c index dcaf28d4..4f17e6e0 100644 --- a/rtp.c +++ b/rtp.c @@ -98,7 +98,7 @@ void *rtp_audio_receiver(void *arg) { debug(2, "Audio receiver -- Server RTP thread starting."); // we inherit the signal mask (SIGUSR1) - struct inter_threads_record *itr = arg; + rtsp_conn_info *conn = arg; int32_t last_seqno = -1; uint8_t packet[2048], *pktp; @@ -114,7 +114,7 @@ void *rtp_audio_receiver(void *arg) { float stat_M2 = 0.0; ssize_t nread; - while (itr->please_stop == 0) { + while (conn->please_stop == 0) { nread = recv(audio_socket, packet, sizeof(packet), 0); uint64_t local_time_now_fp = get_absolute_time_in_fp(); @@ -174,7 +174,7 @@ void *rtp_audio_receiver(void *arg) { // check if packet contains enough content to be reasonable if (plen >= 16) { - player_put_packet(seqno, timestamp, pktp, plen); + player_put_packet(seqno, timestamp, pktp, plen,conn); continue; } if (type == 0x56 && seqno == 0) { @@ -197,7 +197,7 @@ void *rtp_control_receiver(void *arg) { // we inherit the signal mask (SIGUSR1) debug(2, "Control receiver -- Server RTP thread starting."); - struct inter_threads_record *itr = arg; + rtsp_conn_info *conn = arg; reference_timestamp = 0; // nothing valid received yet uint8_t packet[2048], *pktp; @@ -205,7 +205,7 @@ void *rtp_control_receiver(void *arg) { uint64_t remote_time_of_sync, local_time_now, remote_time_now; int64_t sync_rtp_timestamp, rtp_timestamp_less_latency; ssize_t nread; - while (itr->please_stop == 0) { + while (conn->please_stop == 0) { nread = recv(control_socket, packet, sizeof(packet), 0); local_time_now = get_absolute_time_in_fp(); // clock_gettime(CLOCK_MONOTONIC,&tn); @@ -281,7 +281,7 @@ void *rtp_control_receiver(void *arg) { // check if packet contains enough content to be reasonable if (plen >= 16) { - player_put_packet(seqno, timestamp, pktp, plen); + player_put_packet(seqno, timestamp, pktp, plen, conn); continue; } else { debug(1, "Too-short retransmitted audio packet received in control port, ignored."); @@ -356,7 +356,7 @@ void *rtp_timing_receiver(void *arg) { debug(2, "Timing receiver -- Server RTP thread starting."); // we inherit the signal mask (SIGUSR1) - struct inter_threads_record *itr = arg; + rtsp_conn_info *conn = arg; uint8_t packet[2048], *pktp; ssize_t nread; @@ -374,7 +374,7 @@ 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 (itr->please_stop == 0) { + while (conn->please_stop == 0) { nread = recv(timing_socket, packet, sizeof(packet), 0); arrival_time = get_absolute_time_in_fp(); // clock_gettime(CLOCK_MONOTONIC,&att); diff --git a/rtp.h b/rtp.h index f4c8ab0b..4f6da117 100644 --- a/rtp.h +++ b/rtp.h @@ -5,8 +5,6 @@ #include "player.h" -typedef struct inter_threads_record { uint32_t please_stop; } inter_threads_record; - void *rtp_audio_receiver(void *arg); void *rtp_control_receiver(void *arg); void *rtp_timing_receiver(void *arg); diff --git a/rtsp.c b/rtsp.c index 59594019..164c8e8b 100644 --- a/rtsp.c +++ b/rtsp.c @@ -90,17 +90,6 @@ static pthread_mutex_t reference_counter_lock = PTHREAD_MUTEX_INITIALIZER; // static int please_shutdown = 0; // static pthread_t playing_thread = 0; -typedef struct { - int fd; - int authorized; // set is a password is required and has been supplied - stream_cfg stream; - SOCKADDR remote, local; - int stop; - int running; - pthread_t thread; - pthread_t player_thread; -} rtsp_conn_info; - static rtsp_conn_info *playing_conn = NULL; // the data structure representing the connection that has the player. static rtsp_conn_info **conns = NULL; @@ -819,7 +808,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 thread better be 0 + player_play(&conn->player_thread,conn); // the thread better be 0 char *resphdr = alloca(200); *resphdr = 0; @@ -1764,7 +1753,7 @@ static void *rtsp_conversation_thread_func(void *pconn) { debug(1, "Closing down RTSP conversation thread..."); if (rtsp_playing()) { - player_stop(&conn->player_thread); // might be less noisy doing this first + player_stop(&conn->player_thread,conn); // might be less noisy doing this first rtp_shutdown(); // usleep(400000); // let an angel pass... pthread_mutex_unlock(&play_lock);