(snd_pcm_hw_params_set_access(alsa_handle, alsa_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) >=
0)) {
if (output_method_signalled == 0) {
- debug(1, "Output written using MMAP");
+ debug(3, "Output written using MMAP");
output_method_signalled = 1;
}
access = SND_PCM_ACCESS_MMAP_INTERLEAVED;
alsa_pcm_write = snd_pcm_mmap_writei;
} else {
if (output_method_signalled == 0) {
- debug(1, "Output written with RW");
+ debug(3, "Output written with RW");
output_method_signalled = 1;
}
access = SND_PCM_ACCESS_RW_INTERLEAVED;
int players_connection_thread_index; // the connection thread index when a player thread is
// associated with this, zero otherwise
int scan_enable; // set to 1 if if sacanning should be considered
+ char dacp_id[256]; // the DACP ID string
uint16_t port; // zero if no port discovered
short connection_family; // AF_INET6 or AF_INET
uint32_t scope_id; // if it's an ipv6 connection, this will be its scope id
char ip_string[INET6_ADDRSTRLEN]; // the ip string pointing to the client
uint32_t active_remote_id; // send this when you want to send remote control commands
+ void *port_monitor_private_storage;
} dacp_server_record;
pthread_t dacp_monitor_thread;
response.code = 497; // Can't establish a socket to the DACP server
} else {
struct timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = 250000;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv) == -1)
debug(1, "Error %d setting receive timeout for DACP service.", errno);
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof tv) == -1)
}
// this will be running on the thread of its caller, not of the conversation thread...
-void set_dacp_server_information(rtsp_conn_info *conn) { // tell the DACP conversation thread that
- // the port has been set or changed
+// tell the DACP conversation thread what DACP server we are listening to
+// if the active_remote_id is the same we don't change anything apart from
+// the conversation number
+// Thus, we can keep the DACP port that might have previously been discovered
+void set_dacp_server_information(rtsp_conn_info *conn) {
sps_pthread_mutex_timedlock(
&dacp_server_information_lock, 500000,
"set_dacp_server_information couldn't get DACP server information lock in 0.5 second!.", 1);
dacp_server.players_connection_thread_index = conn->connection_number;
- dacp_server.port = conn->dacp_port;
- dacp_server.connection_family = conn->connection_ip_family;
- dacp_server.scope_id = conn->self_scope_id;
- strncpy(dacp_server.ip_string, conn->client_ip_string, INET6_ADDRSTRLEN);
- dacp_server.active_remote_id = conn->dacp_active_remote;
- if (dacp_server.port)
- dacp_server.scan_enable = 1;
- else {
- debug(1, "DACP server port has been set to zero.");
+ if (strcmp(conn->dacp_id, dacp_server.dacp_id) != 0) {
+ strncpy(dacp_server.dacp_id, conn->dacp_id, sizeof(dacp_server.dacp_id));
+ dacp_server.port = 0;
dacp_server.scan_enable = 0;
+ dacp_server.connection_family = conn->connection_ip_family;
+ dacp_server.scope_id = conn->self_scope_id;
+ strncpy(dacp_server.ip_string, conn->client_ip_string, INET6_ADDRSTRLEN);
+ dacp_server.active_remote_id = conn->dacp_active_remote;
+
+ if (dacp_server.port_monitor_private_storage) // if there's is a monitor already active...
+ mdns_dacp_dont_monitor(dacp_server.port_monitor_private_storage); // let it go.
+ dacp_server.port_monitor_private_storage =
+ mdns_dacp_monitor(dacp_server.dacp_id); // create a new one for us
+
+ metadata_hub_modify_prolog();
+ int ch = metadata_store.dacp_server_active != dacp_server.scan_enable;
+ metadata_store.dacp_server_active = dacp_server.scan_enable;
+ if ((metadata_store.client_ip == NULL) ||
+ (strncmp(metadata_store.client_ip, conn->client_ip_string, INET6_ADDRSTRLEN) != 0)) {
+ if (metadata_store.client_ip)
+ free(metadata_store.client_ip);
+ metadata_store.client_ip = strndup(conn->client_ip_string, INET6_ADDRSTRLEN);
+ debug(3, "MH Client IP set to: \"%s\"", metadata_store.client_ip);
+ ch = 1;
+ }
+ metadata_hub_modify_epilog(ch);
}
- metadata_hub_modify_prolog();
- int ch = metadata_store.dacp_server_active != dacp_server.scan_enable;
- metadata_store.dacp_server_active = dacp_server.scan_enable;
-
- if ((metadata_store.client_ip == NULL) ||
- (strncmp(metadata_store.client_ip, conn->client_ip_string, INET6_ADDRSTRLEN) != 0)) {
- if (metadata_store.client_ip)
- free(metadata_store.client_ip);
- metadata_store.client_ip = strndup(conn->client_ip_string, INET6_ADDRSTRLEN);
- debug(1, "MH Client IP set to: \"%s\"", metadata_store.client_ip);
- metadata_store.client_ip_changed = 1;
- metadata_store.changed = 1;
- ch = 1;
- }
- metadata_hub_modify_epilog(ch);
-
pthread_cond_signal(&dacp_server_information_cv);
pthread_mutex_unlock(&dacp_server_information_lock);
}
+void dacp_monitor_port_update_callback(char *dacp_id, uint16_t port) {
+ debug(3, "dacp_monitor_port_update_callback with Remote ID \"%s\" and port number %d.", dacp_id,
+ port);
+ sps_pthread_mutex_timedlock(
+ &dacp_server_information_lock, 500000,
+ "dacp_monitor_port_update_callback couldn't get DACP server information lock in 0.5 second!.",
+ 1);
+ if (strcmp(dacp_id, dacp_server.dacp_id) == 0) {
+ dacp_server.port = port;
+ if (port == 0)
+ dacp_server.scan_enable = 0;
+ else
+ dacp_server.scan_enable = 1;
+ metadata_hub_modify_prolog();
+ int ch = metadata_store.dacp_server_active != dacp_server.scan_enable;
+ metadata_store.dacp_server_active = dacp_server.scan_enable;
+ metadata_hub_modify_epilog(ch);
+ pthread_cond_signal(&dacp_server_information_cv);
+ } else {
+ debug(1, "dacp port monitor reporting on and out-of-use remote.");
+ }
+ pthread_mutex_unlock(&dacp_server_information_lock);
+}
void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
int scan_index = 0;
// char server_reply[10000];
// debug(1, "DACP Server ID \"%u\" at \"%s:%u\", scan %d.", dacp_server.active_remote_id,
// dacp_server.ip_string, dacp_server.port, scan_index);
- if (result != 494) { // this just means that it couldn't send the query because something else
- // was sending a command
+ int transient_problem = (result == 494) || (result == 495);
+ if (!transient_problem) { // this just means that it couldn't send the query because something
+ // else
+ // was sending a command or something
int adv = (result == 200);
// a result of 200 means the advanced features of, e.g., iTunes, are available
// so, turn the advanced_dacp_server flag on or off and flag if it's changed.
void set_dacp_server_information(rtsp_conn_info *conn); // tell the DACP conversation thread that
// the dacp server information has been set
// or changed
+void dacp_monitor_port_update_callback(
+ char *dacp_id, uint16_t port); // a callback to say the port is no longer in use
int send_simple_dacp_command(const char *command);
int dacp_set_include_speaker_volume(int64_t machine_number, int32_t vo);
}
}
-void mdns_dacp_monitor(rtsp_conn_info *conn) {
+void *mdns_dacp_monitor(char *dacp_id) {
+ void *reply = NULL;
if ((config.mdns) && (config.mdns->mdns_dacp_monitor)) {
- int error = config.mdns->mdns_dacp_monitor(conn);
- if (error) {
+ reply = config.mdns->mdns_dacp_monitor(dacp_id);
+ if (reply == NULL) {
debug(1, "Error starting a DACP monitor.");
}
} else
- debug(1, "Can't start a DACP monitor.");
+ debug(1, "Can't start a DACP monitor -- none registered.");
+ return reply;
}
-void mdns_dacp_dont_monitor(rtsp_conn_info *conn) {
+void mdns_dacp_dont_monitor(void *userdata) {
if ((config.mdns) && (config.mdns->mdns_dacp_dont_monitor)) {
- config.mdns->mdns_dacp_dont_monitor(conn);
+ config.mdns->mdns_dacp_dont_monitor(userdata);
} else
- debug(1, "Can't stop a DACP monitor.");
+ debug(1, "Can't stop a DACP monitor -- none registered.");
}
void mdns_ls_backends(void) {
mdns_backend **b = NULL;
void mdns_unregister(void);
void mdns_register(void);
-void mdns_dacp_monitor(rtsp_conn_info *conn);
-void mdns_dacp_dont_monitor(rtsp_conn_info *conn);
+void *mdns_dacp_monitor(char *dacp_id);
+void mdns_dacp_dont_monitor(void *userdata);
void mdns_ls_backends(void);
char *name;
int (*mdns_register)(char *apname, int port);
void (*mdns_unregister)(void);
- int (*mdns_dacp_monitor)(rtsp_conn_info *conn);
- void (*mdns_dacp_dont_monitor)(rtsp_conn_info *conn);
+ void *(*mdns_dacp_monitor)(char *);
+ void (*mdns_dacp_dont_monitor)(void *);
} mdns_backend;
#ifdef CONFIG_METADATA
AvahiThreadedPoll *service_poll;
AvahiClient *service_client;
AvahiServiceBrowser *service_browser;
+ char *dacp_id;
} dacp_browser_struct;
// static AvahiServiceBrowser *sb = NULL;
__attribute__((unused)) AvahiLookupResultFlags flags, void *userdata) {
assert(r);
- rtsp_conn_info *conn = (rtsp_conn_info *)userdata;
- // dacp_browser_struct *dbs = (dacp_browser_struct *)conn->mdns_private_pointer;
+ dacp_browser_struct *dbs = (dacp_browser_struct *)userdata;
/* Called whenever a service has been resolved successfully or timed out */
switch (event) {
char *dacpid = strstr(name, "iTunes_Ctrl_");
if (dacpid) {
dacpid += strlen("iTunes_Ctrl_");
- if (strcmp(dacpid, conn->dacp_id) == 0) {
- if (conn->dacp_port != port) {
- debug(2, "Client's DACP port: %u.", port);
- conn->dacp_port = port;
+ if (strcmp(dacpid, dbs->dacp_id) == 0) {
+ debug(3, "Client's DACP port: %u.", port);
#ifdef HAVE_DACP_CLIENT
- set_dacp_server_information(conn);
+ dacp_monitor_port_update_callback(dacpid, port);
#endif
#ifdef CONFIG_METADATA
- char portstring[20];
- memset(portstring, 0, sizeof(portstring));
- sprintf(portstring, "%u", port);
- send_ssnc_metadata('dapo', strdup(portstring), strlen(portstring), 0);
+ char portstring[20];
+ memset(portstring, 0, sizeof(portstring));
+ sprintf(portstring, "%u", port);
+ send_ssnc_metadata('dapo', strdup(portstring), strlen(portstring), 0);
#endif
- }
}
} else {
debug(1, "Resolve callback: Can't see a DACP string in a DACP Record!");
AvahiBrowserEvent event, const char *name, const char *type,
const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
void *userdata) {
- rtsp_conn_info *conn = (rtsp_conn_info *)userdata;
- dacp_browser_struct *dbs = (dacp_browser_struct *)conn->mdns_private_pointer;
+ dacp_browser_struct *dbs = (dacp_browser_struct *)userdata;
assert(b);
/* Called whenever a new services becomes available on the LAN or is removed from the LAN */
switch (event) {
avahi_strerror(avahi_client_errno(dbs->service_client)));
break;
case AVAHI_BROWSER_REMOVE:
- debug(3, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'.", name, type, domain);
+ debug(1, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'.", name, type, domain);
+#ifdef HAVE_DACP_CLIENT
char *dacpid = strstr(name, "iTunes_Ctrl_");
if (dacpid) {
dacpid += strlen("iTunes_Ctrl_");
- if (strcmp(dacpid, conn->dacp_id) == 0) {
- if (conn->dacp_id != 0) {
- debug(3, "Client's DACP status withdrawn.");
- conn->dacp_port = 0;
- /*
- #ifdef HAVE_DACP_CLIENT
- // this might be in a race condition with another connection that could come into effect
- before this one has terminated.
- set_dacp_server_information(conn); // this will have the effect of telling the
- scanner
- // that the DACP server is no longer working
- #endif
- */
- }
- }
+ if (strcmp(dacpid, dbs->dacp_id) == 0)
+ dacp_monitor_port_update_callback(dbs->dacp_id, 0); // say the port is withdrawn
} else {
debug(1, "Browse callback: Can't see a DACP string in a DACP Record!");
}
-
+#endif
break;
case AVAHI_BROWSER_ALL_FOR_NOW:
case AVAHI_BROWSER_CACHE_EXHAUSTED:
static void service_client_callback(AvahiClient *c, AvahiClientState state, void *userdata) {
int err;
- rtsp_conn_info *conn = (rtsp_conn_info *)userdata;
- dacp_browser_struct *dbs = (dacp_browser_struct *)conn->mdns_private_pointer;
+ dacp_browser_struct *dbs = (dacp_browser_struct *)userdata;
switch (state) {
case AVAHI_CLIENT_S_REGISTERING:
service_name = NULL;
}
-int avahi_dacp_monitor(rtsp_conn_info *conn) {
-
+void *avahi_dacp_monitor(char *dacp_id) {
dacp_browser_struct *dbs = (dacp_browser_struct *)malloc(sizeof(dacp_browser_struct));
if (dbs == NULL)
die("can not allocate a dacp_browser_struct.");
- conn->mdns_private_pointer = (void *)dbs;
+ char *t = strdup(dacp_id);
+ if (t)
+ dbs->dacp_id = t;
+ else {
+ die("can not allocate a dacp_id string in dacp_browser_struct.");
+ }
// create the threaded poll code
int err;
if (!(dbs->service_poll = avahi_threaded_poll_new())) {
warn("couldn't create avahi threaded service_poll!");
- if (dbs) {
- free((char *)dbs);
- }
- conn->mdns_private_pointer = NULL;
- return -1;
+ free(dbs->dacp_id);
+ free((char *)dbs);
+ return NULL;
}
// create the service client
if (!(dbs->service_client =
avahi_client_new(avahi_threaded_poll_get(dbs->service_poll), AVAHI_CLIENT_NO_FAIL,
- service_client_callback, (void *)conn, &err))) {
+ service_client_callback, (void *)dbs, &err))) {
warn("couldn't create avahi service client: %s!", avahi_strerror(err));
- if (dbs) { // should free the threaded poll code
- avahi_threaded_poll_free(dbs->service_poll);
- free((char *)dbs);
- }
- conn->mdns_private_pointer = NULL;
- return -1;
+ avahi_threaded_poll_free(dbs->service_poll);
+ free(dbs->dacp_id);
+ free((char *)dbs);
+ return NULL;
}
/* Create the service browser */
if (!(dbs->service_browser =
avahi_service_browser_new(dbs->service_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
- "_dacp._tcp", NULL, 0, browse_callback, (void *)conn))) {
+ "_dacp._tcp", NULL, 0, browse_callback, (void *)dbs))) {
warn("Failed to create service browser: %s\n",
avahi_strerror(avahi_client_errno(dbs->service_client)));
- if (dbs) { // should free the threaded poll code and the service client
- avahi_client_free(dbs->service_client);
- avahi_threaded_poll_free(dbs->service_poll);
- free((char *)dbs);
- }
- conn->mdns_private_pointer = NULL;
- return -1;
+ avahi_client_free(dbs->service_client);
+ avahi_threaded_poll_free(dbs->service_poll);
+ free(dbs->dacp_id);
+ free((char *)dbs);
+ return NULL;
}
// start the polling thread
if (avahi_threaded_poll_start(dbs->service_poll) < 0) {
warn("couldn't start avahi service_poll thread");
- if (dbs) { // should free the threaded poll code and the service client and the service browser
- avahi_service_browser_free(dbs->service_browser);
- avahi_client_free(dbs->service_client);
- avahi_threaded_poll_free(dbs->service_poll);
- free((char *)dbs);
- }
- conn->mdns_private_pointer = NULL;
- return -1;
+ avahi_service_browser_free(dbs->service_browser);
+ avahi_client_free(dbs->service_client);
+ avahi_threaded_poll_free(dbs->service_poll);
+ free(dbs->dacp_id);
+ free((char *)dbs);
+ return NULL;
}
- return 0;
+ debug(3, "DACP monitor successfully started");
+ return (void *)dbs;
}
-void avahi_dacp_dont_monitor(rtsp_conn_info *conn) {
- dacp_browser_struct *dbs = (dacp_browser_struct *)conn->mdns_private_pointer;
- if (dbs) {
+void avahi_dacp_dont_monitor(void *userdata) {
+ if (userdata) {
+ dacp_browser_struct *dbs = (dacp_browser_struct *)userdata;
// stop and dispose of everything
if ((dbs)->service_poll)
avahi_threaded_poll_stop((dbs)->service_poll);
avahi_client_free((dbs)->service_client);
if ((dbs)->service_poll)
avahi_threaded_poll_free((dbs)->service_poll);
+ free(dbs->dacp_id);
free((char *)(dbs));
- conn->mdns_private_pointer = NULL;
+ debug(3, "DACP monitor successfully stopped");
} else {
debug(1, "DHCP Monitor is not running.");
}
// always run this before changing an entry or a sequence of entries in the metadata_hub
// debug(1, "locking metadata hub for writing");
if (pthread_rwlock_trywrlock(&metadata_hub_re_lock) != 0) {
- debug(1, "Metadata_hub write lock is already taken -- must wait.");
+ debug(2, "Metadata_hub write lock is already taken -- must wait.");
pthread_rwlock_wrlock(&metadata_hub_re_lock);
- debug(1, "Okay -- acquired the metadata_hub write lock.");
+ debug(2, "Okay -- acquired the metadata_hub write lock.");
}
}
#ifdef HAVE_APPLE_ALAC
if (config.use_apple_decoder) {
if (conn->decoder_in_use != 1 << decoder_apple_alac) {
- debug(1, "Apple ALAC Decoder used on encrypted audio.");
+ debug(2, "Apple ALAC Decoder used on encrypted audio.");
conn->decoder_in_use = 1 << decoder_apple_alac;
}
apple_alac_decode_frame(packet, len, (unsigned char *)dest, &outsize);
#endif
{
if (conn->decoder_in_use != 1 << decoder_hammerton) {
- debug(1, "Hammerton Decoder used on encrypted audio.");
+ debug(2, "Hammerton Decoder used on encrypted audio.");
conn->decoder_in_use = 1 << decoder_hammerton;
}
alac_decode_frame(conn->decoder_info, packet, (unsigned char *)dest, &outsize);
#ifdef HAVE_APPLE_ALAC
if (config.use_apple_decoder) {
if (conn->decoder_in_use != 1 << decoder_apple_alac) {
- debug(1, "Apple ALAC Decoder used on unencrypted audio.");
+ debug(2, "Apple ALAC Decoder used on unencrypted audio.");
conn->decoder_in_use = 1 << decoder_apple_alac;
}
apple_alac_decode_frame(buf, len, (unsigned char *)dest, &outsize);
#endif
{
if (conn->decoder_in_use != 1 << decoder_hammerton) {
- debug(1, "Hammerton Decoder used on unencrypted audio.");
+ debug(2, "Hammerton Decoder used on unencrypted audio.");
conn->decoder_in_use = 1 << decoder_hammerton;
}
alac_decode_frame(conn->decoder_info, buf, dest, &outsize);
reference_timestamp *= conn->output_sample_ratio;
if (conn->first_packet_timestamp == 0) { // if this is the very first packet
// debug(1,"First frame seen, time %u, with %d
-// frames...",curframe->timestamp,seq_diff(ab_read, ab_write));
-
-// say we have started playing here
-#ifdef CONFIG_METADATA
- send_ssnc_metadata('pffr', NULL, 0,
- 0); // "first frame received", but don't wait if the queue is locked
-#endif
+ // frames...",curframe->timestamp,seq_diff(ab_read, ab_write));
if (reference_timestamp) { // if we have a reference time
// debug(1,"First frame seen with timestamp...");
// supposed to start playing this
have_sent_prefiller_silence = 0;
+// say we have started playing here
+#ifdef CONFIG_METADATA
+ debug(1, "pffr");
+ send_ssnc_metadata(
+ 'pffr', NULL, 0,
+ 0); // "first frame received", but don't wait if the queue is locked
+#endif
// Here, calculate when we should start playing. We need to know when to allow the
// packets to be sent to the player.
// We will send packets of silence from now until that time and then we will send the
&conn->play_segment_reference_frame_remote_time, conn);
conn->play_segment_reference_frame *= conn->output_sample_ratio;
#ifdef CONFIG_METADATA
+ debug(1, "prsm");
send_ssnc_metadata('prsm', NULL, 0,
0); // "resume", but don't wait if the queue is locked
#endif
conn->fix_volume = 0x10000;
if (conn->latency == 0) {
- debug(1,
- "No latency has (yet) been specified. Setting 99225 (2.25 seconds) frames as a default.");
- conn->latency = 99225;
+ debug(3, "No latency has (yet) been specified. Setting 99,226 (2.25 seconds + 1 frame) frames "
+ "as a default.");
+ conn->latency = 99226;
}
int rc = pthread_mutex_init(&conn->ab_mutex, NULL);
conn->output_bytes_per_frame = 4;
}
- debug(1, "Output frame bytes is %d.", conn->output_bytes_per_frame);
+ debug(3, "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;
die("Unknown format choosing output bit depth");
}
- debug(1, "Output bit depth is %d.", output_bit_depth);
+ debug(3, "Output bit depth is %d.", output_bit_depth);
if (conn->input_bit_depth > output_bit_depth) {
debug(1, "Dithering will be enabled because the input bit depth is greater than the output bit "
#ifdef HAVE_DACP_CLIENT
set_dacp_server_information(conn); // this will start scanning when a port is registered by the
// code initiated by the mdns_dacp_monitor
-#endif
+#else
+ // this is only used for compatability, if dacp stuff isn't enabled.
// start an mdns/zeroconf thread to look for DACP messages containing our DACP_ID and getting the
// port number
- // mdns_dacp_monitor(conn->dacp_id, &conn->dacp_port, &conn->dacp_private);
- mdns_dacp_monitor(conn);
+ conn->dapo_private_storage = mdns_dacp_monitor(conn->dacp_id);
+#endif
conn->framesProcessedInThisEpoch = 0;
conn->framesGeneratedInThisEpoch = 0;
elapsedSec);
}
+#ifndef HAVE_DACP_CLIENT
// stop watching for DACP port number stuff
- mdns_dacp_dont_monitor(conn); // begin looking out for information about the client
- // as a remote control. Specifically we might need
- // the port number
+ // this is only used for compatability, if dacp stuff isn't enabled.
+ mdns_dacp_dont_monitor(conn->dapo_private_storage);
+#endif
if (config.output->stop)
config.output->stop();
conn->play_segment_reference_frame = 0;
conn->play_number_after_flush = 0;
#ifdef CONFIG_METADATA
- send_ssnc_metadata('pfls', NULL, 0, 1);
+ // only send a flush metadata message if the first packet has been seen -- it's a bogus message
+ // otherwise
+ if (conn->first_packet_timestamp) {
+ debug(1, "pfls");
+ send_ssnc_metadata('pfls', NULL, 0, 1);
+ }
#endif
}
BUFFER_FRAMES);
command_start();
#ifdef CONFIG_METADATA
+ debug(1, "pbeg");
send_ssnc_metadata('pbeg', NULL, 0, 1);
#endif
pthread_t *pt = malloc(sizeof(pthread_t));
pthread_kill(*conn->player_thread, SIGUSR1);
pthread_join(*conn->player_thread, NULL);
#ifdef CONFIG_METADATA
+ debug(1, "pend");
send_ssnc_metadata('pend', NULL, 0, 1);
#endif
command_stop();
// mdns to find it.
// at present, only avahi can do this
- char *dacp_id; // id of the client -- used to find the port to be used
- uint16_t dacp_port; // port on the client to send remote control messages to, else zero
+ char *dacp_id; // id of the client -- used to find the port to be used
+ // uint16_t dacp_port; // port on the client to send remote control messages to, else
+ // zero
uint32_t dacp_active_remote; // key to send to the remote controller
- void *mdns_private_pointer; // private storage (just a pointer) for the dacp_port resolver
-
+ void *dapo_private_storage; // this is used for compatibility, if dacp stuff isn't enabled.
} rtsp_conn_info;
int player_play(rtsp_conn_info *conn);
#include "common.h"
#include "player.h"
#include "rtp.h"
+#include "rtsp.h"
uint64_t local_to_remote_time_jitters;
uint64_t local_to_remote_time_jitters_count;
if (la != conn->latency) {
conn->latency = la;
- debug(1, "New latency: %lld, sync latency: %lld, minimum latency: %lld, maximum "
- "latency: %lld, fixed offset: %lld.",
- la, sync_rtp_timestamp - rtp_timestamp_less_latency, conn->minimum_latency,
- conn->maximum_latency, config.fixedLatencyOffset);
+ // debug(1, "New latency: %lld, sync latency: %lld, minimum latency: %lld, maximum "
+ // "latency: %lld, fixed offset: %lld.",
+ // la, sync_rtp_timestamp - rtp_timestamp_less_latency, conn->minimum_latency,
+ // conn->maximum_latency, config.fixedLatencyOffset);
}
}
conn->request_sent = 0;
conn->rtp_running = 1;
+
+#ifdef CONFIG_METADATA
+ send_ssnc_metadata('clip', strdup(conn->client_ip_string), strlen(conn->client_ip_string), 1);
+ send_ssnc_metadata('svip', strdup(conn->self_ip_string), strlen(conn->self_ip_string), 1);
+#endif
}
void get_reference_timestamp_stuff(int64_t *timestamp, uint64_t *timestamp_time,
char *ar = msg_get_header(req, "Active-Remote");
if (ar) {
- debug(1, "Active-Remote string seen: \"%s\".", ar);
+ debug(2, "Active-Remote string seen: \"%s\".", ar);
// get the active remote
char *p;
conn->dacp_active_remote = strtoul(ar, &p, 10);
ar = msg_get_header(req, "DACP-ID");
if (ar) {
- debug(1, "DACP-ID string seen: \"%s\".", ar);
+ debug(2, "DACP-ID string seen: \"%s\".", ar);
conn->dacp_id = strdup(ar);
#ifdef CONFIG_METADATA
send_metadata('ssnc', 'daid', ar, strlen(ar), req, 1);
// 'pfls' -- play stream flush. No arguments
// 'prsm' -- play stream resume. No arguments
// `pffr` -- the first frame of a play session has been received and has been validly
-//timed.
+// timed.
// 'pvol' -- play volume. The volume is sent as a string --
// "airplay_volume,volume,lowest_volume,highest_volume"
// volume, lowest_volume and highest_volume are given in dB.
}
hdr = msg_get_header(req, "User-Agent");
if (hdr) {
- debug(1, "Play connection from user agent \"%s\" on RTSP conversation thread %d.", hdr,
+ debug(2, "Play connection from user agent \"%s\" on RTSP conversation thread %d.", hdr,
conn->connection_number);
#ifdef CONFIG_METADATA
send_metadata('ssnc', 'snua', hdr, strlen(hdr), req, 1);
sa = (struct sockaddr_in *)&conn->remote;
inet_ntop(AF_INET, &(sa->sin_addr), remote_ip4, INET_ADDRSTRLEN);
unsigned short int rport = ntohs(sa->sin_port);
-#ifdef CONFIG_METADATA
- send_ssnc_metadata('clip', strdup(remote_ip4), strlen(remote_ip4), 1);
- send_ssnc_metadata('svip', strdup(ip4), strlen(ip4), 1);
-#endif
- debug(1, "New RTSP connection from %s:%u to self at %s:%u on conversation thread %d.",
+ debug(2, "New RTSP connection from %s:%u to self at %s:%u on conversation thread %d.",
remote_ip4, rport, ip4, tport, conn->connection_number);
}
#ifdef AF_INET6
sa6 = (struct sockaddr_in6 *)&conn->remote; // pretend this is loaded with something
inet_ntop(AF_INET6, &(sa6->sin6_addr), remote_ip6, INET6_ADDRSTRLEN);
u_int16_t rport = ntohs(sa6->sin6_port);
-#ifdef CONFIG_METADATA
- send_ssnc_metadata('clip', strdup(remote_ip6), strlen(remote_ip6), 1);
- send_ssnc_metadata('svip', strdup(ip6), strlen(ip6), 1);
-#endif
- debug(1, "New RTSP connection from [%s]:%u to self at [%s]:%u on conversation thread %d.",
+ debug(2, "New RTSP connection from [%s]:%u to self at [%s]:%u on conversation thread %d.",
remote_ip6, rport, ip6, tport, conn->connection_number);
}
#endif