Skip to content

Commit

Permalink
Tidy up dacp scanner -- stop scanning when audio source goes offline.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikebrady committed Feb 18, 2018
1 parent 3ca4d2c commit 3a4e29c
Show file tree
Hide file tree
Showing 7 changed files with 428 additions and 374 deletions.
615 changes: 323 additions & 292 deletions dacp.c

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions dacp.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@

#include "player.h"

static pthread_mutex_t dacp_server_information_lock;
static pthread_cond_t dacp_server_information_cv;

typedef struct dacp_speaker_stuff {
int64_t speaker_number;
int active;
Expand All @@ -24,11 +21,11 @@ uint32_t dacp_tlv_crawl(

int dacp_set_speaker_volume(int64_t machine_number, int32_t vo);

int dacp_get_speaker_list(dacp_spkr_stuff *speaker_array, int max_size_of_array);
int dacp_get_speaker_list(dacp_spkr_stuff *speaker_array, int max_size_of_array, int *actual_speaker_count);
void set_dacp_server_information(rtsp_conn_info *conn); // tell the DACP conversation thread that
// the dacp server information has been set
// or changed
int send_simple_dacp_command(const char *command);

void dacp_get_volume(void); // get the speaker volume information from the DACP source and store it
int dacp_get_volume(int32_t *the_actual_volume); // get the speaker volume information from the DACP source and store it
// in the metadata_hub
4 changes: 2 additions & 2 deletions mdns_avahi.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, Avah
avahi_threaded_poll_quit(tpoll);
break;
case AVAHI_BROWSER_NEW:
debug(3, "(Browser) NEW: service '%s' of type '%s' in domain '%s'.", name, type, domain);
debug(1, "(Browser) NEW: service '%s' of type '%s' in domain '%s'.", name, type, domain);
/* We ignore the returned resolver object. In the callback
function we free it. If the server is terminated before
the callback function is called the server will free
Expand All @@ -133,7 +133,7 @@ static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, Avah
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);
char *dacpid = strstr(name, "iTunes_Ctrl_");
if (dacpid) {
dacpid += strlen("iTunes_Ctrl_");
Expand Down
33 changes: 17 additions & 16 deletions metadata_hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,28 +78,29 @@ void add_metadata_watcher(metadata_watcher fn, void *userdata) {

void metadata_hub_modify_prolog(void) {
// always run this before changing an entry or a sequence of entries in the metadata_hub
debug(1, "locking metadata hub for writing");
// debug(1, "locking metadata hub for writing");
pthread_rwlock_wrlock(&metadata_hub_re_lock);
}

void run_metadata_watchers(void) {
int i;
debug(1, "locking metadata hub for reading");
// debug(1, "locking metadata hub for reading");
pthread_rwlock_rdlock(&metadata_hub_re_lock);
for (i = 0; i < number_of_watchers; i++) {
if (metadata_store.watchers[i]) {
metadata_store.watchers[i](&metadata_store, metadata_store.watchers_data[i]);
}
}
debug(1, "unlocking metadata hub for reading");
// debug(1, "unlocking metadata hub for reading");
pthread_rwlock_unlock(&metadata_hub_re_lock);
}

void metadata_hub_modify_epilog(void) {
void metadata_hub_modify_epilog(int modified) {
// always run this after changing an entry or a sequence of entries in the metadata_hub
debug(1, "unlocking metadata hub for writing");
// debug(1, "unlocking metadata hub for writing");
pthread_rwlock_unlock(&metadata_hub_re_lock);
run_metadata_watchers();
if (modified)
run_metadata_watchers();
}

char *metadata_write_image_file(const char *buf, int len) {
Expand Down Expand Up @@ -359,21 +360,21 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin
break;

case 'mdst':
debug(1, "MH Metadata stream processing start.");
// debug(1, "MH Metadata stream processing start.");
metadata_hub_modify_prolog();
break;
case 'mden':
metadata_hub_modify_epilog();
debug(1, "MH Metadata stream processing end.");
metadata_hub_modify_epilog(1);
// debug(1, "MH Metadata stream processing end.");
break;
case 'PICT':
if (length > 16) {
metadata_hub_modify_prolog();
debug(1, "MH Picture received, length %u bytes.", length);
// debug(1, "MH Picture received, length %u bytes.", length);
if (metadata_store.cover_art_pathname)
free(metadata_store.cover_art_pathname);
metadata_store.cover_art_pathname = metadata_write_image_file(data, length);
metadata_hub_modify_epilog();
metadata_hub_modify_epilog(1);
}
break;
case 'clip':
Expand All @@ -383,10 +384,10 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin
if (metadata_store.client_ip)
free(metadata_store.client_ip);
metadata_store.client_ip = strndup(data, length);
debug(1, "MH Client IP set to: \"%s\"", metadata_store.client_ip);
// debug(1, "MH Client IP set to: \"%s\"", metadata_store.client_ip);
metadata_store.client_ip_changed = 1;
metadata_store.changed = 1;
metadata_hub_modify_epilog();
metadata_hub_modify_epilog(1);
}
break;
case 'svip':
Expand All @@ -396,8 +397,8 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin
if (metadata_store.server_ip)
free(metadata_store.server_ip);
metadata_store.server_ip = strndup(data, length);
debug(1, "MH Server IP set to: \"%s\"", metadata_store.server_ip);
metadata_hub_modify_epilog();
// debug(1, "MH Server IP set to: \"%s\"", metadata_store.server_ip);
metadata_hub_modify_epilog(1);
}
break;
default: {
Expand All @@ -412,7 +413,7 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin
payload = strndup(data, length);
else
payload = NULL;
debug(1, "MH \"%s\" \"%s\" (%d bytes): \"%s\".", typestring, codestring, length, payload);
// debug(1, "MH \"%s\" \"%s\" (%d bytes): \"%s\".", typestring, codestring, length, payload);
if (payload)
free(payload);
}
Expand Down
2 changes: 1 addition & 1 deletion metadata_hub.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,4 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin
// these functions lock and unlock the read-write mutex on the metadata hub and run the watchers
// afterwards
void metadata_hub_modify_prolog(void);
void metadata_hub_modify_epilog(void);
void metadata_hub_modify_epilog(int modified); //set to true if modifications occured, 0 otherwise
121 changes: 68 additions & 53 deletions mpris-service.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "mpris-service.h"

void mpris_metadata_watcher(struct metadata_bundle *argc, void *userdata) {
debug(1, "MPRIS metadata watcher called");
// debug(1, "MPRIS metadata watcher called");
char response[100];
switch (argc->repeat_status) {
case RS_NONE:
Expand All @@ -33,74 +33,89 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, void *userdata) {
media_player2_player_set_loop_status(mprisPlayerPlayerSkeleton, response);

GVariantBuilder *dict_builder, *aa;
GVariant *trackname, *albumname, *trackid, *tracklength, *artUrl;

/* Build the metadata array */
// debug(1,"Build metadata");
dict_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));

// Make up the artwork URI if we have one
if (argc->cover_art_pathname) {
char artURIstring[1024];
sprintf(artURIstring, "file://%s", argc->cover_art_pathname);
// sprintf(artURIstring,"");
// debug(1,"artURI String: \"%s\".",artURIstring);
GVariant *artUrl = g_variant_new("s", artURIstring);
g_variant_builder_add(dict_builder, "{sv}", "mpris:artUrl", artUrl);
}

// Add the TrackID if we have one
// Build the Track ID from the 16-byte item_composite_id in hex prefixed by
// /org/gnome/ShairportSync

char st[33];
char *pt = st;
int it;
int non_zero = 0;
for (it = 0; it < 16; it++) {
if (argc->item_composite_id[it])
non_zero = 1;
sprintf(pt, "%02X", argc->item_composite_id[it]);
pt += 2;
}
*pt = 0;
// debug(1, "Item composite ID set to 0x%s.", st);

char artURIstring[1024];
char trackidstring[1024];
sprintf(trackidstring, "/org/gnome/ShairportSync/%s", st);

trackid = g_variant_new("o", trackidstring);

// Make up the track name and album name
trackname = g_variant_new("s", argc->track_name);
albumname = g_variant_new("s", argc->album_name);

// Make up the track length in microseconds as an int64

uint64_t track_length_in_microseconds = argc->songtime_in_milliseconds;

track_length_in_microseconds *= 1000; // to microseconds in 64-bit precision

// Make up the track name and album name
tracklength = g_variant_new("x", track_length_in_microseconds);

/* Build the artists array */
// debug(1,"Build artists");
aa = g_variant_builder_new(G_VARIANT_TYPE("as"));
g_variant_builder_add(aa, "s", argc->artist_name);
GVariant *artists = g_variant_builder_end(aa);
g_variant_builder_unref(aa);

/* Build the genre array */
// debug(1,"Build genre");
aa = g_variant_builder_new(G_VARIANT_TYPE("as"));
g_variant_builder_add(aa, "s", argc->genre);
GVariant *genres = g_variant_builder_end(aa);
g_variant_builder_unref(aa);

/* Build the metadata array */
// debug(1,"Build metadata");
dict_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
// Make up the artwork URI if we have one
if (argc->cover_art_pathname) {
sprintf(artURIstring, "file://%s", argc->cover_art_pathname);
// sprintf(artURIstring,"");
artUrl = g_variant_new("s", artURIstring);
g_variant_builder_add(dict_builder, "{sv}", "mpris:artUrl", artUrl);
if (non_zero) {
// debug(1, "Item composite ID set to 0x%s.", st);
char trackidstring[1024];
sprintf(trackidstring, "/org/gnome/ShairportSync/%s", st);
GVariant* trackid = g_variant_new("o", trackidstring);
g_variant_builder_add(dict_builder, "{sv}", "mpris:trackid", trackid);
}

// Add the track length if it's non-zero
if (argc->songtime_in_milliseconds) {
uint64_t track_length_in_microseconds = argc->songtime_in_milliseconds;
track_length_in_microseconds *= 1000; // to microseconds in 64-bit precision
// Make up the track name and album name
GVariant *tracklength = g_variant_new("x", track_length_in_microseconds);
g_variant_builder_add(dict_builder, "{sv}", "mpris:length", tracklength);
}
g_variant_builder_add(dict_builder, "{sv}", "mpris:trackid", trackid);
g_variant_builder_add(dict_builder, "{sv}", "mpris:length", tracklength);

g_variant_builder_add(dict_builder, "{sv}", "xesam:title", trackname);
g_variant_builder_add(dict_builder, "{sv}", "xesam:album", albumname);
g_variant_builder_add(dict_builder, "{sv}", "xesam:artist", artists);
g_variant_builder_add(dict_builder, "{sv}", "xesam:genre", genres);
// Add the track name if there is one
if (argc->track_name) {
GVariant *trackname = g_variant_new("s", argc->track_name);
g_variant_builder_add(dict_builder, "{sv}", "xesam:title", trackname);
}

// Add the album name if there is one
if (argc->album_name) {
GVariant *albumname = g_variant_new("s", argc->album_name);
g_variant_builder_add(dict_builder, "{sv}", "xesam:album", albumname);
}

// Add the artists if there are any (actually there will be at most one, but put it in an array)
if (argc->artist_name) {
/* Build the artists array */
// debug(1,"Build artist array");
aa = g_variant_builder_new(G_VARIANT_TYPE("as"));
g_variant_builder_add(aa, "s", argc->artist_name);
GVariant *artists = g_variant_builder_end(aa);
g_variant_builder_unref(aa);
g_variant_builder_add(dict_builder, "{sv}", "xesam:artist", artists);
}

// Add the genres if there are any (actually there will be at most one, but put it in an array)
if (argc->genre) {
// debug(1,"Build genre");
aa = g_variant_builder_new(G_VARIANT_TYPE("as"));
g_variant_builder_add(aa, "s", argc->genre);
GVariant *genres = g_variant_builder_end(aa);
g_variant_builder_unref(aa);
g_variant_builder_add(dict_builder, "{sv}", "xesam:genre", genres);
}

GVariant *dict = g_variant_builder_end(dict_builder);
g_variant_builder_unref(dict_builder);

// debug(1,"Set metadata");
media_player2_player_set_metadata(mprisPlayerPlayerSkeleton, dict);
}

Expand Down
20 changes: 15 additions & 5 deletions player.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
#ifdef HAVE_METADATA_HUB
metadata_hub_modify_prolog();
metadata_store.player_state = PS_PLAYING;
metadata_hub_modify_epilog();
metadata_hub_modify_epilog(1);
#endif
if (reference_timestamp) { // if we have a reference time
// debug(1,"First frame seen with timestamp...");
Expand Down Expand Up @@ -2501,7 +2501,17 @@ void player_volume_without_notification(double airplay_volume, rtsp_conn_info *c
void player_volume(double airplay_volume, rtsp_conn_info *conn) {
command_set_volume(airplay_volume);
#ifdef HAVE_DACP_CLIENT
dacp_get_volume();
int32_t actual_volume;
if (dacp_get_volume(&actual_volume)==200) {
metadata_hub_modify_prolog();
if (metadata_store.speaker_volume == actual_volume)
metadata_hub_modify_epilog(0); // no change
else {
metadata_store.speaker_volume = actual_volume;
metadata_hub_modify_epilog(1); // change
}
}

#endif

player_volume_without_notification(airplay_volume, conn);
Expand All @@ -2523,7 +2533,7 @@ void player_flush(int64_t timestamp, rtsp_conn_info *conn) {
#ifdef HAVE_METADATA_HUB
metadata_hub_modify_prolog();
metadata_store.player_state = PS_PAUSED;
metadata_hub_modify_epilog();
metadata_hub_modify_epilog(1);
#endif
}

Expand Down Expand Up @@ -2553,7 +2563,7 @@ int player_play(rtsp_conn_info *conn) {
#ifdef HAVE_METADATA_HUB
metadata_hub_modify_prolog();
metadata_store.player_state = PS_PLAYING;
metadata_hub_modify_epilog();
metadata_hub_modify_epilog(1);
#endif
return 0;
}
Expand All @@ -2573,7 +2583,7 @@ void player_stop(rtsp_conn_info *conn) {
#ifdef HAVE_METADATA_HUB
metadata_hub_modify_prolog();
metadata_store.player_state = PS_STOPPED;
metadata_hub_modify_epilog();
metadata_hub_modify_epilog(1);
#endif
} else {
debug(3, "player thread of RTSP conversation %d is already deleted.", conn->connection_number);
Expand Down

0 comments on commit 3a4e29c

Please sign in to comment.