// must be after decoder init
init_buffer(conn);
- debug(1, "Output frame bytes is %d.", conn->output_bytes_per_frame);
-
if (conn->stream.encrypted) {
#ifdef HAVE_LIBMBEDTLS
memset(&conn->dctx, 0, sizeof(mbedtls_aes_context));
break;
}
+ debug(1, "Output frame bytes is %d.", conn->output_bytes_per_frame);
+
// 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*) conn);
#ifndef _PLAYER_H
#define _PLAYER_H
+#include <arpa/inet.h>
+
#include "config.h"
#ifdef HAVE_LIBMBEDTLS
#include "audio.h"
#include "alac.h"
+#define time_ping_history 8
+#define time_ping_fudge_factor 100000
+
+typedef struct time_ping_record {
+ uint64_t local_to_remote_difference;
+ uint64_t dispersion;
+ uint64_t local_time;
+ uint64_t remote_time;
+} time_ping_record;
+
typedef uint16_t seq_t;
typedef struct audio_buffer_entry { // decoded audio packets
#ifdef HAVE_LIBSSL
AES_KEY aes;
#endif
+
+// RTP stuff
+// only one RTP session can be active at a time.
+int rtp_running;
+
+char client_ip_string[INET6_ADDRSTRLEN]; // the ip string pointing to the client
+char self_ip_string[INET6_ADDRSTRLEN]; // the ip string being used by this program -- it
+ // could be one of many, so we need to know it
+uint32_t self_scope_id; // if it's an ipv6 connection, this will be its scope
+short connection_ip_family; // AF_INET / AF_INET6
+uint32_t client_active_remote; // used when you want to control the client...
+
+SOCKADDR rtp_client_control_socket; // a socket pointing to the control port of the client
+SOCKADDR rtp_client_timing_socket; // a socket pointing to the timing port of the client
+int audio_socket; // our local [server] audio socket
+int control_socket; // our local [server] control socket
+int timing_socket; // local timing socket
+
+int64_t reference_timestamp;
+uint64_t reference_timestamp_time;
+uint64_t remote_reference_timestamp_time;
+
+// debug variables
+int request_sent;
+
+uint8_t time_ping_count;
+struct time_ping_record time_pings[time_ping_history];
+
+uint64_t departure_time; // dangerous -- this assumes that there will never be two timing
+ // request in flight at the same time
+
+pthread_mutex_t reference_time_mutex;
+
+uint64_t local_to_remote_time_difference; // used to switch between local and remote clocks
+
} rtsp_conn_info;
int player_play(pthread_t *thread, rtsp_conn_info* conn);
#include "player.h"
#include "rtp.h"
-/*
-// this does not compile properly with OpenWrt Barrier Breaker...
-#if defined(__linux__)
-#include <linux/in6.h>
-#endif
-*/
-typedef struct time_ping_record {
- uint64_t local_to_remote_difference;
- uint64_t dispersion;
- uint64_t local_time;
- uint64_t remote_time;
-} time_ping_record;
-
// only one RTP session can be active at a time.
-static int running = 0;
+static int rtp_running = 0;
static char client_ip_string[INET6_ADDRSTRLEN]; // the ip string pointing to the client
static char self_ip_string[INET6_ADDRSTRLEN]; // the ip string being used by this program -- it
// debug variables
static int request_sent;
-#define time_ping_history 8
-#define time_ping_fudge_factor 100000
-
static uint8_t time_ping_count;
struct time_ping_record time_pings[time_ping_history];
uint64_t static local_to_remote_time_difference; // used to switch between local and remote clocks
+void rtp_initialise(rtsp_conn_info* conn) {
+
+ rtp_running = 0;
+// initialise the timer mutex
+ int rc = pthread_mutex_init(&conn->reference_time_mutex, NULL);
+ if (rc)
+ debug(1, "Error initialising reference_time_mutex.");
+
+}
+
+void rtp_terminate(rtsp_conn_info* conn) {
+
+// destroy the timer mutex
+ int rc = pthread_mutex_destroy(&conn->reference_time_mutex);
+ if (rc)
+ debug(1, "Error destroying reference_time_mutex variable.");
+}
+
+
void *rtp_audio_receiver(void* arg) {
debug(2, "Audio receiver -- Server RTP thread starting.");
while (*stop == 0) {
// debug(1,"Send a timing request");
- if (!running)
+ if (!rtp_running)
die("rtp_timing_sender called without active stream!");
// debug(1, "Requesting ntp timestamp exchange.");
// we use the local stuff to specify the address we are coming from and
// we use the remote stuff to specify where we're goint to
- if (running)
+ if (rtp_running)
die("rtp_setup called with active stream!");
debug(2, "rtp_setup: cport=%d tport=%d.", cport, tport);
// pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, NULL);
// pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, NULL);
- running = 1;
+ rtp_running = 1;
request_sent = 0;
}
}
void rtp_shutdown(rtsp_conn_info *conn) {
- if (!running)
+ if (!rtp_running)
debug(1, "rtp_shutdown called without active stream!");
debug(2, "shutting down RTP thread");
// pthread_join(rtp_audio_thread, &retval);
// pthread_join(rtp_control_thread, &retval);
// pthread_join(rtp_timing_thread, &retval);
- running = 0;
+ rtp_running = 0;
}
void rtp_request_resend(seq_t first, uint32_t count, rtsp_conn_info *conn) {
- if (running) {
+ if (rtp_running) {
// if (!request_sent) {
debug(3, "requesting resend of %d packets starting at %u.", count, first);
// request_sent = 1;
}
void rtp_request_client_pause(rtsp_conn_info *conn) {
- if (running) {
+ if (rtp_running) {
if (client_active_remote == 0) {
debug(1, "Can't request a client pause: no valid active remote.");
} else {
#include "player.h"
+void rtp_initialise(rtsp_conn_info* conn);
+void rtp_terminate(rtsp_conn_info* conn);
+
void *rtp_audio_receiver(void *arg);
void *rtp_control_receiver(void *arg);
void *rtp_timing_receiver(void *arg);
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
rtsp_conn_info *conn = pconn;
+
+ rtp_initialise(conn);
rtsp_message *req, *resp;
char *hdr, *auth_nonce = NULL;
// debug(1, "This RTSP conversation thread doesn't think it's playing for a "
// "close RTSP connection.");
// }
+ rtp_terminate(conn);
debug(2, "RTSP conversation thread terminated.");
// please_shutdown = 0;
return NULL;