Merge stability changes to develoment branch and its convolution additions

This commit is contained in:
Mike Brady
2017-03-11 14:18:52 +00:00
6 changed files with 504 additions and 542 deletions
+2 -2
View File
@@ -24,7 +24,7 @@ typedef struct {
// "sr=44100", "vn=3", "txtvers=1", config.password ? "pw=true" : "pw=false"
#define MDNS_RECORD_WITH_METADATA \
"sf=0x4", "fv=76400.10", "am=AirPort4,107", "vs=105.1", "tp=TCP,UDP", "vn=65537", \
"sf=0x4", "fv=76400.10", "am=ShairportSync", "vs=105.1", "tp=TCP,UDP", "vn=65537", \
METADATA_EXPRESSION, "ss=16", "sr=44100", "da=true", "sv=false", "et=0,1", "ek=1", "cn=0,1", \
"ch=2", "txtvers=1", config.password ? "pw=true" : "pw=false"
@@ -35,7 +35,7 @@ typedef struct {
// "txtvers=1", config.password ? "pw=true" : "pw=false"
#define MDNS_RECORD_WITHOUT_METADATA \
"sf=0x4", "fv=76400.10", "am=AirPort4,107", "vs=105.1", "tp=TCP,UDP", "vn=65537", "ss=16", \
"sf=0x4", "fv=76400.10", "am=ShairportSync", "vs=105.1", "tp=TCP,UDP", "vn=65537", "ss=16", \
"sr=44100", "da=true", "sv=false", "et=0,1", "ek=1", "cn=0,1", "ch=2", "txtvers=1", \
config.password ? "pw=true" : "pw=false"
+396 -500
View File
File diff suppressed because it is too large Load Diff
+88 -9
View File
@@ -1,7 +1,38 @@
#ifndef _PLAYER_H
#define _PLAYER_H
#include "config.h"
#ifdef HAVE_LIBMBEDTLS
#include <mbedtls/aes.h>
#include <mbedtls/havege.h>
#endif
#ifdef HAVE_LIBPOLARSSL
#include <polarssl/aes.h>
#include <polarssl/havege.h>
#endif
#ifdef HAVE_LIBSSL
#include <openssl/aes.h>
#endif
#include "audio.h"
#include "alac.h"
typedef uint16_t seq_t;
typedef struct audio_buffer_entry { // decoded audio packets
int ready;
int64_t timestamp;
seq_t sequence_number;
signed short *data;
int length; // the length of the decoded data
} abuf_t;
// default buffer size
// needs to be a power of 2 because of the way BUFIDX(seqno) works
#define BUFFER_FRAMES 512
typedef struct {
int encrypted;
@@ -9,20 +40,68 @@ typedef struct {
int32_t fmtp[12];
} stream_cfg;
typedef uint16_t seq_t;
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;
// wrapped number between two seq_t.
int32_t seq_diff(seq_t a, seq_t b);
abuf_t audio_buffer[BUFFER_FRAMES];
int max_frames_per_packet,input_num_channels,input_bit_depth,input_rate;
int input_bytes_per_frame,output_bytes_per_frame,output_sample_ratio;
int max_frame_size_change;
int64_t previous_random_number;
alac_file *decoder_info;
uint32_t please_stop;
uint64_t packet_count;
int shutdown_requested;
int connection_state_to_output;
int player_thread_please_stop;
int64_t first_packet_time_to_play, time_since_play_started; // nanoseconds
// stats
uint64_t missing_packets, late_packets, too_late_packets, resend_requests;
int decoder_in_use;
// debug variables
int32_t last_seqno_read;
// mutexes and condition variables
pthread_cond_t flowcontrol;
pthread_mutex_t ab_mutex,flush_mutex;
pthread_mutex_t vol_mutex;
int fix_volume;
uint32_t timestamp_epoch, last_timestamp, maximum_timestamp_interval; // timestamp_epoch of zero means not initialised, could start at 2
// or 1.
int ab_buffering,ab_synced;
int64_t first_packet_timestamp;
int flush_requested;
int64_t flush_rtp_timestamp;
uint64_t time_of_last_audio_packet;
seq_t ab_read, ab_write;
int player_play(stream_cfg *cfg, pthread_t *thread);
void player_stop(pthread_t *thread);
#ifdef HAVE_LIBMBEDTLS
mbedtls_aes_context dctx;
#endif
void player_volume(double f);
void player_flush(int64_t timestamp);
#ifdef HAVE_LIBPOLARSSL
aes_context dctx;
#endif
void player_put_packet(seq_t seqno, int64_t timestamp, uint8_t *data, int len);
#ifdef HAVE_LIBSSL
AES_KEY aes;
#endif
} rtsp_conn_info;
int64_t monotonic_timestamp(uint32_t timestamp); // add an epoch to the timestamp. The monotonic
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, rtsp_conn_info* conn);
void player_flush(int64_t timestamp, rtsp_conn_info* conn);
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,rtsp_conn_info* conn); // add an epoch to the timestamp. The monotonic
// timestamp guaranteed to start between 2^32 2^33
// frames and continue up to 2^64 frames
// which is about 2*10^8 * 1,000 seconds at 384,000 frames per second -- about 2 trillion seconds.
+13 -13
View File
@@ -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();
@@ -129,7 +129,7 @@ void *rtp_audio_receiver(void *arg) {
stat_mean += stat_delta / stat_n;
stat_M2 += stat_delta * (time_interval_us - stat_mean);
if (stat_n % 2500 == 0) {
debug(2, "Packet reception interval stats: mean, standard deviation and max for the last "
debug(3, "Packet reception interval stats: mean, standard deviation and max for the last "
"2,500 packets in microseconds: %10.1f, %10.1f, %10.1f.",
stat_mean, sqrtf(stat_M2 / (stat_n - 1)), longest_packet_time_interval_us);
stat_n = 0;
@@ -164,7 +164,7 @@ void *rtp_audio_receiver(void *arg) {
// debug(3, "RTP: Packets out of sequence: expected: %d, got %d.", last_seqno, seqno);
last_seqno = seqno; // reset warning...
}
int64_t timestamp = monotonic_timestamp(ntohl(*(unsigned long *)(pktp + 4)));
int64_t timestamp = monotonic_timestamp(ntohl(*(unsigned long *)(pktp + 4)),conn);
// if (packet[1]&0x10)
// debug(1,"Audio packet Extension bit set.");
@@ -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);
@@ -234,8 +234,8 @@ void *rtp_control_receiver(void *arg) {
// debug(1,"Remote Sync Time: %0llx.",remote_time_of_sync);
rtp_timestamp_less_latency = monotonic_timestamp(ntohl(*((uint32_t *)&packet[4])));
sync_rtp_timestamp = monotonic_timestamp(ntohl(*((uint32_t *)&packet[16])));
rtp_timestamp_less_latency = monotonic_timestamp(ntohl(*((uint32_t *)&packet[4])),conn);
sync_rtp_timestamp = monotonic_timestamp(ntohl(*((uint32_t *)&packet[16])),conn);
if (config.use_negotiated_latencies) {
int64_t la = sync_rtp_timestamp - rtp_timestamp_less_latency + 11025;
@@ -274,14 +274,14 @@ void *rtp_control_receiver(void *arg) {
plen -= 4;
seq_t seqno = ntohs(*(unsigned short *)(pktp + 2));
int64_t timestamp = monotonic_timestamp(ntohl(*(unsigned long *)(pktp + 4)));
int64_t timestamp = monotonic_timestamp(ntohl(*(unsigned long *)(pktp + 4)),conn);
pktp += 12;
plen -= 12;
// 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);
-2
View File
@@ -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);
+5 -16
View File
@@ -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;
@@ -654,7 +643,7 @@ static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message
rtptime = uatoi(p + 1); // unsigned integer -- up to 2^32-1
rtptime--;
// debug(1,"RTSP Flush Requested by handle_record: %u.",rtptime);
player_flush(rtptime);
player_flush(rtptime,conn);
}
}
}
@@ -695,7 +684,7 @@ static void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
}
}
// debug(1,"RTSP Flush Requested: %u.",rtptime);
player_flush(rtptime);
player_flush(rtptime,conn);
resp->respcode = 200;
}
@@ -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;
@@ -859,7 +848,7 @@ static void handle_set_parameter_parameter(rtsp_conn_info *conn, rtsp_message *r
float volume = atof(cp + 8);
if (config.ignore_volume_control == 0) {
debug(2, "volume: %f\n", volume);
player_volume(volume);
player_volume(volume,conn);
}
#ifdef CONFIG_METADATA
else { // if ignore volume is on...
@@ -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);